本文将演示通过Docker Compose上构建一个简单的python web应用程序,该应用程序使用Flask框架并在Redis中维护一个计数器,用来记录该Web应用被访问的次数。
环境准备
只需在linux机器上(本文演示环境为CentOS)安装Docker(可参考《Docker在CentOS系统中的安装》)和 Docker Compose(可参考《如何安装Docker Compose》)即可。
开发过程
1.定义或配置该应用的依赖
1.1建立工程目录
# mkdir composeDemo
# cd composeDemo
1.2编写composeDemo.py文件,内容如下:
import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) def get_hit_count(): retries = 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route('/') def hello(): count = get_hit_count() return 'Hello World! I have been seen {} times.\n'.format(count)
在本例中,redis是redis容器的主机名,容器网络使用的是应用程序的网络。redis的默认端口6379。
1.3编写requirements.txt文件。内容如下:
flask redis
2.建立Dockerfile文件
编写Dockerfile文件,构建Python、composeDemo应用程序及其相关的依赖,内容如下:
#基础影像 FROM python:3.7-alpine #容器工作目录 WORKDIR /code #定义环境变量 ENV FLASK_APP composeDemo.py ENV FLASK_RUN_HOST 0.0.0.0 #安装gcc,以便加速编译 python包 RUN apk add --no-cache gcc musl-dev linux-headers #拷贝requirements.txt COPY requirements.txt requirements.txt #安装Python的依赖 RUN pip install -r requirements.txt #拷贝当前目录到容器的工作目录 COPY . . #容器启动时执行的命令 CMD ["flask", "run"]
3.在Compose文件中定义应用的服务
编写docker-compose.yml,定义了两个服务:web和 redis,内容如下:
version: '3' services: web: build: . #根据上述dockerfile的内容构建镜像 ports: #暴露容器端口5000 - "5000:5000" redis: image: "redis:alpine" #使用公共镜像redis
此处要注意docker-compose.yml文件的格式版本,详细可参见《Docker Compose简介》。
4.用Compose构建和运行应用
4.1使用命令docker-compose up构建composeDemo应用
上述命令在执行过程中,compose提取一个redis镜像,为composeDemo构建一个镜像,并启动了定义两个服务web和redis。
4.2访问http://宿主机IP:5000/ ,出现类似如下图的信息:
刷新页面,将会看到redis中的计数器+1了,类似如下图所示信息:
4.3查看Docker-compose管理的镜像和容器
打开另一个terminal窗口,列出镜像和容器如下:
4.4停止应用
在第一个terminal窗口按CTRL-C 或在第二个terminal窗口(注意:要切换当前目录为composeDemo),输入docker-compose down。
5.编辑Compose文件绑定装载宿主机卷到容器
在上述第4步中,暂停了composeDemo应用,目的是为重新编辑Compose文件为容器挂载存储卷,内容如下:
version: '3' services: web: build: . ports: - "5000:5000" volumes: #挂载项目的当前目录到容器的/code目录 - .:/code environment: #定义环境变量,申明为开发环境 FLASK_ENV: development redis: image: "redis:alpine"
6. 重新构建和运行应用
再次使用命令docker-compose up构建composeDemo应用
细心的同学可能已经发现,这次构建应用的时间大大缩短了,这也正体现了Docker-compose的特性之一:仅重新创建已更改的容器,详细参见《Docker Compose简介》
7.更新应用
由于应用程序代码已经装载到容器卷中,因此可以直接更改代码而不需要重新构建镜像。本文示例中,更改Hello World! 为 Hello from Docker-compose!
8.Compose编排的服务管理
细心的同学可能已经发现,在上述步骤4和步骤6中,采用命令docker-compose up构建composeDemo应用,这样并没有将服务作为后台守护进程运行,所以如果我们在上述步骤4和步骤6中的窗口按下CTRL+C时,服务即停止了。较常用的服务管理命令如下:
8.1后台运行服务
docker-compose up -d
8.2查看当前运行的服务
8.3为某一服务运行一次性的命令,如查看web服务的环境变量
docker-compose run web env
8.4停止服务
docker-compose stop
8.5卸载容器并删除挂载的数据卷
docker-compose down –volumes