使用Compose和Machine實現(xiàn)本地與云端的同步部署與管理
【前言】
Docker 1.6發(fā)布了,Compose和Machine都在更新之列。本文具體說明了如何使用這兩個組件來實現(xiàn)本地與云端的同步部署與管理。
Docker是個強大工具,用于啟動隔離的、可重復(fù)生產(chǎn)的應(yīng)用環(huán)境容器。本文側(cè)重講述如何為本地開發(fā)容器化Flask應(yīng)用,同時使用Docker Compose和Docker Machine將應(yīng)用交付到云主機提供商中。
本地設(shè)置
與Docker(v1.6.0)一起,我們將使用:
- Docker Compose(v1.2.0),即此前的fig,用于將一個多容器應(yīng)用編排成一個單一應(yīng)用。
- Docker Machine(v0.2.0)用于在本地和云端創(chuàng)建Docker主機。
檢驗一下安裝是否成功:
- $ docker-machine --version
- docker-machine version 0.2.0 (8b9eaf2)
- $ docker-compose --version
- docker-compose 1.2.0
然后,從此倉庫克隆項目,或按該倉庫的項目結(jié)構(gòu)創(chuàng)建你自己的項目:
- ├── copy.sh
- ├── docker-compose.yml
- ├── nginx
- │ ├── Dockerfile
- │ └── sites-enabled
- │ └── flask_project
- └── web
- ├── Dockerfile
- ├── app.py
- ├── config.py
- ├── create_db.py
- ├── models.py
- ├── requirements.txt
- ├── static
- │ ├── css
- │ │ ├── bootstrap.min.css
- │ │ └── main.css
- │ ├── img
- │ └── js
- │ ├── bootstrap.min.js
- │ └── main.js
- └── templates
- ├── _base.html
- └── index.html
這樣就為容器啟動和運行做好了準備?,F(xiàn)在進入Docker Machine。
#p#
Docker Machine
要啟動Docker Machine,只需簡單地運行:
- $ docker-machine create -d virtualbox dev;
- INFO[0000] Creating CA: /Users/michael/.docker/machine/certs/ca.pem
- INFO[0000] Creating client certificate: /Users/michael/.docker/machine/certs/cert.pem
- INFO[0001] Downloading boot2docker.iso to /Users/michael/.docker/machine/cache/boot2docker.iso...
- INFO[0035] Creating SSH key...
- INFO[0035] Creating VirtualBox VM...
- INFO[0043] Starting VirtualBox VM...
- INFO[0044] Waiting for VM to start...
- INFO[0094] "dev" has been created and is now the active machine.
- INFO[0094] To point your Docker client at it, run this in your shell: $(docker-machine env dev)
- $ $(docker-machine env dev)
- create命令為Docker開發(fā)設(shè)置了一臺“machine”(名為dev)。實際上,它下載了boot2docker,并啟動了一個運行Docker的虛擬機。
- 運行如下命令來查看當(dāng)前運行的Machine:
- $ docker-machine ls
- NAME ACTIVE DRIVER STATE URL SWARM
- dev * virtualbox Running tcp://192.168.99.100:2376
接下來,讓我們使用Docker Compose來啟動容器,讓Flask應(yīng)用及Postgres數(shù)據(jù)庫啟動并運行起來。
#p#
Docker Compose
來看一眼docker-compose.yml文件:
- web:
- restart: always
- build: ./web
- expose:
- - "8000"
- links:
- - postgres:postgres
- volumes:
- - /usr/src/app
- env_file: .env
- command: /usr/local/bin/gunicorn -w 2 -b :8000 app:app
- nginx:
- restart: always
- build: ./nginx/
- ports:
- - "80:80"
- volumes:
- - /www/static
- links:
- - web:web
- data:
- restart: always
- image: postgres:latest
- volumes:
- - /var/lib/postgresql
- command: true
- postgres:
- restart: always
- image: postgres:latest
- volumes_from:
- - data
- ports:
- - "5432:5432"
這里,我們定義了四個服務(wù):web、 nginx、 postgres和 data。
- 首先,web服務(wù)是通過Dockerfile的指令在“web”目錄中構(gòu)建的,在此設(shè)置了Python環(huán)境,安裝了必要軟件,并將Flask應(yīng)用運行于8000端口。這個端口會被轉(zhuǎn)發(fā)到宿主環(huán)境(比如Docker Machine)的80端口上。該服務(wù)還將.env文件中定義的環(huán)境變量添加到了容器里。
- nginx服務(wù)作為反向代理用于轉(zhuǎn)發(fā)請求到Flask應(yīng)用或靜態(tài)文件上。
- 下一個,postgres服務(wù)構(gòu)建于Docker Hub的官方PostgreSQL鏡像,安裝了Postgres并將服務(wù)器運行于默認的5432端口上。
- ***,請注意有一個單獨的卷容器data用于存儲數(shù)據(jù)庫數(shù)據(jù)。這確保了即便Postgres容器被完全地銷毀,數(shù)據(jù)仍然存在。
在構(gòu)建鏡像前,我們需要將靜態(tài)文件從“web/static”目錄復(fù)制到“nginx/static”中,因為nginx Dockerfile是從“nginx”目錄中添加靜態(tài)文件目錄的。要這么做,只需要簡單地運行copy.sh腳本:
- $ sh copy.sh
現(xiàn)在,要運行容器,只要構(gòu)建鏡像然后啟動服務(wù)即可:
- $ docker-compose build
- $ docker-compose up -d
去喝一杯咖啡?;蚴莾杀?**次運行時間會久一點。
我們還需要創(chuàng)建數(shù)據(jù)庫表:
- $ docker-compose run web /usr/local/bin/python create_db.py
打開瀏覽器并訪問與Docker Machine關(guān)聯(lián)的IP地址(docker-machine ip):
棒極了!
要查看web服務(wù)可用的環(huán)境變量,運行:
- $ docker-compose run web env
要查看日志:
- $ docker-compose logs
你也可以進入Postgres命令行,這是因為我們在docker-compose.yml文件中轉(zhuǎn)發(fā)了它的端口到宿主環(huán)境中,可以這樣添加用戶/角色及數(shù)據(jù)庫:
- $ psql -h 192.168.99.100 -p 5432 -U postgres --password
一旦完成,通過docker-compose stop停止所有進程。
#p#
部署
在應(yīng)用運行于本地的同時,我們可以使用Docker Machine將與之完全相同的環(huán)境推送到云主機提供商上。我們來部署到Digital Ocean的droplet里。
在Digital Ocean注冊完成后,生成一個“個人訪問令牌”,然后運行以下命令:
- $ docker-machine create \
- -d digitalocean \
- --digitalocean-access-token=你的令牌 \
- production
這將花費幾分鐘來準備droplet并設(shè)置一個名為production的新的Docker Machine:
- INFO[0000] Creating SSH key...
- INFO[0001] Creating Digital Ocean droplet...
- INFO[0133] "production" has been created and is now the active machine.
- INFO[0133] To point your Docker client at it, run this in your shell: eval "$(docker-machine env production)"
現(xiàn)在,我們運行了兩個Machine,一個本地的,一個在Digital Ocean上:
- $ docker-machine ls
- NAME ACTIVE DRIVER STATE URL SWARM
- dev * virtualbox Running tcp://192.168.99.100:2376
- production digitalocean Running tcp://104.131.107.8:2376
然后,設(shè)置production作為活動machine,并將Docker環(huán)境加載到命令行中:
- $ docker-machine active production
- $ eval "$(docker-machine env production)"
***,在云端再次構(gòu)建Flask應(yīng)用:
- $ docker-compose build
- $ docker-compose up -d
- $ docker-compose run web /usr/local/bin/python create_db.py
找到Digital Ocean賬號關(guān)聯(lián)的IP地址,并在瀏覽器中查看。如果所有東西都正確,應(yīng)該能看到應(yīng)用已經(jīng)運行起來了。