Docker Compose 搭建简单的Python网络应用程序(步骤详解)
目录
- 前提条件
- 第1步:设置
- 第2步:创建一个Dockerfile
- 第3步:在Compose文件中定义服务
- Web服务
- Redis服务
- 第4步:用Compose构建和运行你的应用
- 第5步:编辑Compose文件以添加绑定挂载
- 第6步:用Compose重新构建并运行应用程序
- 第7步:更新应用程序
- 第8步:试验一些其他命令
在这个页面上,你可以建立一个简单的Python网络应用程序,运行在Docker Compose上。该应用使用Flask框架,并在Redis中维护一个点击计数器。虽然样本使用了Python,但即使你不熟悉它,这里展示的概念也应该是可以理解的。(官网教程翻译)
前提条件
请确保你已经安装了Docker Engine和Docker Compose。你不需要安装Python或Redis,因为两者都是由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容器的主机名。我们使用Redis的默认端口,6379。
处理瞬时错误 注意
get_hit_count
函数的编写方式。这个基本的重试循环让我们在redis服务不可用时多次尝试我们的请求。这在应用程序上线的时候很有用,而且如果Redis服务需要在应用程序的生命周期内随时重启,这也使我们的应用程序更具弹性。在一个集群中,这也有助于处理节点之间的瞬间连接中断。
- 在你的项目目录下创建另一个名为
requirements.txt
的文件,并将以下内容粘贴进去:
flask redis
第2步:创建一个Dockerfile
在这一步,你要写一个Dockerfile来构建一个Docker镜像。这个镜像包含了Python应用程序所需的所有依赖项,包括Python本身。
在你的项目目录中,创建一个名为 Dockerfile
的文件并粘贴以下内容:
# syntax=docker/dockerfile:1 FROM python:3.7-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"]
这告诉Docker:
- 从Python 3.7镜像开始构建一个镜像。
- 设置工作目录为
/code
。 - 设置
flask
命令使用的环境变量。 - 安装gcc和其他依赖项
- 复制
requirements.txt
并安装Python依赖项。 - 给镜像添加元数据,描述容器在5000端口上监听
- 将项目中的当前目录.复制到镜像中的工作目录.。
- 将容器的默认命令设置为
flask run
。
第3步:在Compose文件中定义服务
在你的项目目录下创建一个名为 docker-compose.yml
的文件,并粘贴以下内容:
version: "3.9" services: web: build: . ports: - "8000:5000" redis: image: "redis:alpine"
这个 Compose 文件定义了两个服务:web
和 redis
。
Web服务
web
服务使用一个从当前目录下的 Dockerfile
文件构建的镜像。然后它将容器和主机绑定到暴露的端口8000上。本例服务使用Flask网络服务器的默认端口,即5000。
Redis服务
redis
服务使用了一个从Docker Hub仓库中拉取的公共Redis镜像。
第4步:用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镜像,为你的代码构建一个镜像,并启动你定义的服务。在这种情况下,代码在构建时被静态地复制到镜像中。
如果你在本地Linux上使用Docker、Docker Desktop for Mac或Docker Desktop for Windows,那么网络应用现在应该在你的Docker守护主机上监听8000端口。将你的网络浏览器指向http://localhost:8000,找到`Hello World` 消息。如果这还没有解决,你也可以试试http://127.0.0.1:8000。
你应该在你的浏览器中看到一条消息说:
Hello World! I have been seen 1 times.
3. 刷新页面。
这个数字应该是递增的。
Hello World! I have been seen 2 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。
第5步:编辑Compose文件以添加绑定挂载
在你的项目目录中编辑 docker-compose.yml
,为 web
服务添加一个绑定挂载。
version: "3.9" services: web: build: . ports: - "8000:5000" volumes: - .:/code environment: FLASK_ENV: development redis: image: "redis:alpine"
新的 volumes
键将主机上的项目目录(当前目录)挂载到容器内的 /code
,允许你即时修改代码,而不需要重建镜像。environment
键设置 FLASK_ENV
环境变量,它告诉 flask run
在开发模式下运行,并在代码变化时重新加载。这种模式只应在开发中使用。
第6步:用Compose重新构建并运行应用程序
在你的项目目录下,输入 docker-compose up
,用更新的Compose文件构建应用程序,并运行它。
$ 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) ...
再次在网络浏览器中检查 Hello World
消息,并刷新以看到计数的增加。
共享文件夹、卷和绑定挂载
- 如果你的项目在
Users
目录之外(cd ~
),那么你需要共享你正在使用的Dockerfile文件和volume的驱动器或位置。如果你得到运行时的错误,表明找不到应用文件,卷挂载被拒绝,或服务无法启动,请尝试启用文件或驱动器共享。卷挂载需要在C:\Users
(Windows)或/Users
(Mac)之外的项目共享驱动器,而且对于Docker Desktop for Windows上任何使用Linux容器的项目都是必需的。- 如果你在旧的Windows操作系统上使用Oracle VirtualBox,你可能会遇到这个VB故障单中描述的共享文件夹的问题。较新的Windows系统符合Docker Desktop for Windows的要求并且不需要VirtualBox。
第7步:更新应用程序
因为应用程序代码现在是用volume装入容器的,所以你可以对其代码进行修改,并立即看到变化,而不需要重建镜像。
改变 app.py
中的问候语,并保存它。例如,将 Hello World!
的信息改为 Hello from Docker!
。
return 'Hello from Docker! I have been seen {} times.\n'.format(count)
在你的浏览器中刷新该应用程序。问候语应该被更新,而计数器应该仍然在递增。
第8步:试验一些其他命令
如果你想在后台运行你的服务,你可以向 docker-compose up
传递 -d
标志(用于 "分离 "模式),并使用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
的运行命令允许你为你的服务运行一次性的命令。例如,看看 web
服务有哪些环境变量可用:
$ docker-compose run web env
参见 docker-compose --help
以查看其他可用的命令。
如果你用 docker-compose up -d
启动了Compose,一旦你完成了你的服务,就停止它们:
$ docker-compose stop
你可以用 down
命令来关闭一切,完全删除容器。通过 --volumes
,也可以删除Redis容器所使用的数据卷:
$ docker-compose down --volumes
在这一点上,你已经明白了 Compose 是如何工作的。
到此这篇关于Docker Compose 搭建简单的Python网络应用程序的详细步骤的文章就介绍到这了,更多相关Docker Compose 搭建Python网络应用程序内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!