本教程旨在通过指导您开发基本Python web应用程序来介绍Docker Compose的基本概念。
使用Flask框架,该应用程序在Redis中提供了一个命中计数器,提供了如何在web开发场景中应用Docker Compose的实际示例。
即使您不熟悉Python,这里演示的概念也应该是可以理解的。
这是一个非规范性的示例,仅强调了使用Compose可以做的关键事情。
一、前提条件
确保您具有:
- 已安装最新版本的Docker Compose
- 对Docker概念和Docker工作原理的基本理解
1、设置
1.1为项目创建目录:
mkdir composetest
cd composetest
1.2 在项目目录中创建名为app.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容器的主机名,使用默认端口6379。
1.3 在项目目录中创建另一个名为requirements.txt的文件,并将以下代码粘贴到中:
flask
redis
1.4 创建Dockerfile并将以下代码粘贴到中:
# syntax=docker/dockerfile:1
FROM python:3.10-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run", "--debug"]
代码解析:
这告诉Docker:
- 从Python 3.10映像开始构建映像。
- 将工作目录设置为/code。
- 设置烧瓶命令使用的环境变量。
- 安装gcc和其他依赖项
- 复制requirements.txt并安装Python依赖项。
- 将元数据添加到映像中,以描述容器正在侦听端口5000
- 复制当前目录。在项目中添加到workdir。在图像中。
- 将容器的默认命令设置为烧瓶运行--debug。
2、在Compose文件中定义服务
Compose简化了对整个应用程序堆栈的控制,使在单个可理解的YAML配置文件中管理服务、网络和卷变得容易。
在项目目录中创建一个名为compose.yaml的文件,并粘贴以下内容:
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
该Compose文件定义了两个服务:web和redis。
web服务使用从当前目录中的Dockerfile构建的映像。然后,它将容器和主机绑定到暴露的端口8000。此示例服务使用Flask web服务器的默认端口5000。
redis服务使用从Docker Hub注册表中提取的公共redis映像。
3、使用Compose构建和运行应用程序
使用单个命令,可以从配置文件中创建和启动所有服务。
3.1、从项目目录中,通过运行docker-compose-up来启动应用程序。
docker compose up
Creating network "composetest_default" with the default driver
Creating composetest_web_1 ...
Creating composetest_redis_1 ...
Creating composetest_web_1
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
web_1 | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
redis_1 | 1:C 17 Aug 22:11:10.480 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1 | 1:C 17 Aug 22:11:10.480 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1 | 1:C 17 Aug 22:11:10.480 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
web_1 | * Restarting with stat
redis_1 | 1:M 17 Aug 22:11:10.483 * Running mode=standalone, port=6379.
redis_1 | 1:M 17 Aug 22:11:10.483 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
web_1 | * Debugger is active!
redis_1 | 1:M 17 Aug 22:11:10.483 # Server initialized
redis_1 | 1:M 17 Aug 22:11:10.483 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
web_1 | * Debugger PIN: 330-787-903
redis_1 | 1:M 17 Aug 22:11:10.483 * Ready to accept connections
Compose提取Redis映像,为代码构建映像,并启动您定义的服务。在这种情况下,代码在构建时静态复制到映像中。
3.2、输入http://localhost:8000/在浏览器中查看应用程序的运行。
如果这不能解决,您也可以尝试http://127.0.0.1:8000.
您应该会在浏览器中看到一条消息,内容是:
Hello World! I have been seen 1 times.
3.3、刷新页面
数字应该递增。
Hello World! I have been seen 2 times.
3.4、切换到另一个终端窗口,并键入docker image ls以列出本地图像。
此时列出图像应该返回redis和web。
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
composetest_web latest e2c21aa48cc1 4 minutes ago 93.8MB
python 3.4-alpine 84e6077c7ab6 7 days ago 82.5MB
redis alpine 9d8fa9aa0e5b 3 weeks ago 27.5MB
您可以使用docker inspect<tag or id>检查镜像
3.5、通过在第二个终端的项目目录中运行docker compose down,或者在启动应用程序的原始终端中单击CTRL+C来停止应用程序。
4、用Compose Watch 编辑Compose file
编辑项目目录中的compose.yaml文件以使用watch,以便可以预览正在运行的compose服务,这些服务将在您编辑和保存代码时自动更新:
services:
web:
build: .
ports:
- "8000:5000"
develop:
watch:
- action: sync
path: .
target: /code
redis:
image: "redis:alpine"
无论何时更改文件,Compose都会将文件同步到容器内/code下的相应位置。复制后,绑定程序更新正在运行的应用程序,而不重新启动。
5、使用Compose重新构建并运行应用程序
在项目目录中,键入docker compose watch或docker compose up--watch以构建和启动应用程序,并启动文件监视模式。
docker compose watch
[+] Running 2/2
â Container docs-redis-1 Created 0.0s
â Container docs-web-1 Recreated 0.1s
Attaching to redis-1, web-1
⦿ watch enabled
...
6、更新应用程序
查看Compose Watch的操作:
6.1、在app.py中更改问候语并保存。例如,更改Hello World!Docker给Hello的消息:
return 'Hello from Docker! I have been seen {} times.\n'.format(count)
6.2、在浏览器中刷新应用程序。问候语应更新,计数器仍应递增。
6.3、完成后,运行docker compose。
7、拆分服务
使用多个Compose文件可以为不同的环境或工作流自定义Compose应用程序。这对于可能使用数十个容器的大型应用程序非常有用,所有权分布在多个团队中。
- 在您的项目文件夹中,创建一个名为 infra.yaml 的新 Compose 文件。
- 从你的 compose.yaml 文件中删除 Redis 服务,并将其粘贴到新的 infra.yaml 文件中。确保在文件的顶部添加了 services 顶级属性。你的 infra.yaml 文件现在应该看起来像这样:
services: redis: image: "redis:alpine"
- 在您的compose.yaml文件中,添加include顶级属性以及infra.yaml文件的路径。
include:
- infra.yaml
services:
web:
build: .
ports:
- "8000:5000"
develop:
watch:
- action: sync
path: .
target: /code
运行docker compose up以使用更新的compose文件构建应用程序,然后运行它。您应该会在浏览器中看到Hello world消息。
8、尝试其他一些命令
- 如果要在后台运行服务,可以将-d标志(用于“分离”模式)传递给docker compose-up,并使用docker compose-ps查看当前正在运行的内容:
docker compose up -d Starting composetest_redis_1... Starting composetest_web_1... docker compose ps Name Command State Ports ------------------------------------------------------------------------------------- composetest_redis_1 docker-entrypoint.sh redis ... Up 6379/tcp composetest_web_1 flask run Up 0.0.0.0:8000->5000/tcp
- 运行docker compose--help以查看其他可用命令。
- 如果启动Compose with docker Compose up-d,请在完成服务后停止服务:
docker compose stop
- 使用docker compose down命令,您可以删除所有内容,完全删除容器。