使用Compose和Machine来Docker化Flask:从本地到云端


【编者的话】Docker 1.6发布了,Compose和Machine都在更新之列。本文具体说明了如何使用这两个组件来实现本地与云端的同步部署与管理。

Docker是个强大工具,用于启动隔离的、可重复生产的应用环境容器。本文侧重讲述如何为本地开发容器化Flask应用,同时使用Docker Compose和Docker Machine将应用交付到云主机提供商中。

本地设置

与Docker(v1.6.0)一起,我们将使用:
  • Docker Compose(v1.2.0),即此前的fig,用于将一个多容器应用编排成一个单一应用。
  • Docker Machine(v0.2.0)用于在本地和云端创建Docker主机。


请依照这里这里的指示分别安装Docker Compose和Machine。

检验一下安装是否成功:
$ docker-machine --version
docker-machine version 0.2.0 (8b9eaf2)
$ docker-compose --version
docker-compose 1.2.0

然后,从此仓库克隆项目,或按该仓库的项目结构创建你自己的项目:
├── 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

这样就为容器启动和运行做好了准备。现在进入Docker Machine。

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开发设置了一台“machine”(名为dev)。实际上,它下载了boot2docker,并启动了一个运行Docker的虚拟机。

运行如下命令来查看当前运行的Machine:
$ docker-machine ls
NAME   ACTIVE   DRIVER       STATE     URL                         SWARM
dev    *        virtualbox   Running   tcp://192.168.99.100:2376

接下来,让我们使用Docker Compose来启动容器,让Flask应用及Postgres数据库启动并运行起来。

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"

这里,我们定义了四个服务:webnginxpostgresdata
  • 首先,web服务是通过Dockerfile的指令在“web”目录中构建的,在此设置了Python环境,安装了必要软件,并将Flask应用运行于8000端口。这个端口会被转发到宿主环境(比如Docker Machine)的80端口上。该服务还将.env文件中定义的环境变量添加到了容器里。
  • nginx服务作为反向代理用于转发请求到Flask应用或静态文件上。
  • 下一个,postgres服务构建于Docker Hub的官方PostgreSQL镜像,安装了Postgres并将服务器运行于默认的5432端口上。
  • 最后,请注意有一个单独的容器data用于存储数据库数据。这确保了即便Postgres容器被完全地销毁,数据仍然存在。


在构建镜像前,我们需要将静态文件从“web/static”目录复制到“nginx/static”中,因为nginx Dockerfile是从“nginx”目录中添加静态文件目录的。要这么做,只需要简单地运行copy.sh脚本:
$ sh copy.sh

现在,要运行容器,只要构建镜像然后启动服务即可:
$ docker-compose build
$ docker-compose up -d

去喝一杯咖啡。或是两杯。第一次运行时间会久一点。

我们还需要创建数据库表:
$ docker-compose run web /usr/local/bin/python create_db.py

打开浏览器并访问与Docker Machine关联的IP地址(docker-machine ip):

flask_app_docker.png


棒极了!

要查看web服务可用的环境变量,运行:
$ docker-compose run web env

要查看日志:
$ docker-compose logs

你也可以进入Postgres命令行,这是因为我们在docker-compose.yml文件中转发了它的端口到宿主环境中,可以这样添加用户/角色及数据库:
$ psql -h 192.168.99.100 -p 5432 -U postgres --password

一旦完成,通过docker-compose stop停止所有进程。

部署

在应用运行于本地的同时,我们可以使用Docker Machine将与之完全相同的环境推送到云主机提供商上。我们来部署到Digital Ocean的droplet里。

在Digital Ocean注册完成后,生成一个“个人访问令牌”,然后运行以下命令:
$ docker-machine create \
-d digitalocean \
--digitalocean-access-token=你的令牌 \
production

这将花费几分钟来准备droplet并设置一个名为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)"

现在,我们运行了两个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

然后,设置production作为活动machine,并将Docker环境加载到命令行中:
$ docker-machine active production
$ eval "$(docker-machine env production)"

最后,在云端再次构建Flask应用:
$ docker-compose build
$ docker-compose up -d
$ docker-compose run web /usr/local/bin/python create_db.py

找到Digital Ocean账号关联的IP地址,并在浏览器中查看。如果所有东西都正确,应该能看到应用已经运行起来了。

结语

祝贺你!
  • 从这个仓库获取代码(也请点赞!)
  • 在下面提交你的评论
  • 下一次,我们将扩展这个工作流以包括两个运行Flask应用的Docker容器,并加入负载均衡。敬请关注!


原文链接:Dockerizing Flask With Compose and Machine - From Localhost to the Cloud(翻译:梁晓勇

2 个评论

这样使用云服务的就太顺畅了,希望国内的云也能快点支持
感谢分享

要回复文章请先登录注册