云原生 从Docker、Jenkins、Kubernetes从入门到精通系列
Docker实战系列
DockerCompose快速入门 掘金无法跳转,故【转载】快速入门文章
本教程旨在通过指导您完成基本 Python Web 应用程序的开发来介绍 Docker Compose 的基本概念。
该应用程序使用Flask框架,在Redis中设有一个点击计数器,提供了Docker Compose如何应用于Web开发场景的实际示例。
即使您不熟悉 Python,也应该能够理解这里演示的概念。
这是一个非规范性示例,仅突出显示了使用 Compose 可以执行的关键操作。
先决条件
确保您已拥有:
- 安装了最新版本的 Docker Compose
- 对 Docker 概念以及 Docker 工作原理的基本了解
步骤 1:设置
- 为项目创建目录:
mkdir composetest
cd composetest
- 在您的项目目录中创建一个名为的文件
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
笔记
请注意函数的编写方式
get_hit_count
。如果 Redis 服务不可用,此基本重试循环会多次尝试请求。这在应用程序上线时启动时很有用,但如果在应用程序的生命周期内需要随时重新启动 Redis 服务,也会使应用程序更具弹性。在集群中,这也有助于处理节点之间的瞬时连接断开。
- 在您的项目目录中创建另一个名为的文件
requirements.txt
并粘贴以下代码:
flask
redis
- 创建一个
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"]
了解 Dockerfile
这告诉 Docker:
- 从 Python 3.10 图像开始构建图像。
- 将工作目录设置为
/code
。- 设置命令使用的环境变量
flask
。- 安装 gcc 和其他依赖项
- 使用 Alpine Linux 的包管理工具
apk
安装了一些必要的软件包:
gcc
:GNU Compiler Collection,用于编译 C 和 C++ 程序。
musl-dev
:musl libc 的开发文件,用于编译依赖 musl libc 的软件。
linux-headers
:Linux 内核头文件,通常在构建时需要。- 复制
requirements.txt
并使用pip
安装其中列出的 Python 依赖库。- 声明容器将会监听的端口号为
5000
,这样外部网络可以访问该端口。.
将项目中的当前目录复制到.
镜像中的workdir。- 设置容器启动时默认执行的命令为
flask run --debug
,即启动 Flask 应用程序,并开启调试模式。
重要的
检查
Dockerfile
文件扩展名是否为.txt
。某些编辑器可能会自动附加此文件扩展名,从而导致运行应用程序时出现错误。
步骤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
。
build: .
指定使用当前目录 (.
表示当前目录,通常是包含 Dockerfile 的目录) 中的 Dockerfile 构建镜像。
步骤3:使用 Compose 构建并运行您的应用
使用单个命令,您可以从配置文件创建并启动所有服务。
- 从您的项目目录中,通过运行启动您的应用程序
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 镜像,为您的代码构建镜像,并启动您定义的服务。在这种情况下,代码会在构建时静态复制到镜像中。
http://localhost:8000/
在浏览器中输入即可看到应用程序正在运行。 如果这不能解决,您还可以尝试http://127.0.0.1:8000
。 你应该会在浏览器中看到一条消息:
Hello World! I have been seen 1 times.
- 刷新页面。 该数字应该会增加。
- 切换到另一个终端窗口,然后输入
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>
。
- 停止该应用程序,可以通过
docker compose down
在第二个终端中的项目目录中运行来停止,也可以通过点击CTRL+C
启动该应用程序的原始终端来停止。
步骤 4:编辑 Compose 文件以使用 Compose Watch
编辑compose.yaml
项目目录中要使用的文件watch
,以便您可以预览正在运行的 Compose 服务,这些服务会在您编辑和保存代码时自动更新:
services:
web:
build: .
ports:
- "8000:5000"
develop:
watch:
- action: sync
path: .
target: /code
redis:
image: "redis:alpine"
每当文件发生更改时,Compose 都会将文件同步到/code
容器内的相应位置。复制后,捆绑器会更新正在运行的应用程序,而无需重新启动。
有关 Compose Watch 如何工作的更多信息,请参阅 使用 Compose Watch。或者,请参阅 管理容器中的数据以了解其他选项。
笔记
为了使此示例正常运行,
--debug
将选项添加到Dockerfile
。--debug
Flask 中的选项启用自动代码重新加载,从而可以在无需重新启动或重建容器的情况下处理后端 API。更改文件后.py
,后续 API 调用将使用新代码,但在此小示例中,浏览器 UI 不会自动刷新。大多数前端开发服务器都包含与 Compose 配合使用的本机实时重新加载支持。
步骤 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
...
再次在网络浏览器中检查Hello World
消息,然后刷新以查看计数增量。
步骤 6:更新应用程序
要查看 Compose Watch 的实际操作,请执行以下操作:
-
更改问候语
app.py
并保存。例如,将Hello World!
消息更改为Hello from Docker!
:return 'Hello from Docker! I have been seen {} times.\n'.format(count)
-
在浏览器中刷新应用。问候语应该已更新,计数器仍应递增。
- 完成后,运行
docker compose down
。
步骤 7:拆分你的服务
使用多个 Compose 文件可让您针对不同的环境或工作流程自定义 Compose 应用程序。这对于可能使用数十个容器且所有权分布在多个团队的大型应用程序非常有用。
-
在您的项目文件夹中,创建一个名为 的新 Compose 文件
infra.yaml
。 -
从文件中剪切 Redis 服务
compose.yaml
并将其粘贴到新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
在浏览器中看到该消息。
这是一个简化的示例,但它演示了将复杂应用程序模块化为子 Compose 文件的基本原理include
以及如何更轻松地将其模块化为子 Compose 文件。有关include
如何使用多个 Compose 文件的更多信息,请参阅 使用多个 Compose 文件。
步骤 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
docker compose up -d
,请在使用完服务后停止它们:$ docker compose stop
-
您可以使用命令将所有内容放下来,彻底删除容器
docker compose down
。