在这个页面上,你能够建立一个简单的Python网络使用程序,运转在Docker Compose上。该使用运用Flask结构,并在Redis中维护一个点击计数器。虽然样本运用了Python,但即便你不熟悉它,这里展示的概念也应该是能够理解的。(官网教程翻译)

前提条件

请确保你已经装置了Docker Engine和Docker Compose。你不需求装置Python或Redis,因为两者都是由Docker镜像供给的。

第1步:设置

界说使用程序的依靠。

  1. 为该项目创立一个目录。
$ mkdir composetest
$ cd composetest
  1. 在你的项目目录下创立一个名为 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服务需求在使用程序的生命周期内随时重启,这也使咱们的使用程序更具弹性。在一个集群中,这也有助于处理节点之间的瞬间连接中断。

  1. 在你的项目目录下创立另一个名为 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 文件界说了两个服务:webredis

Web服务

web 服务运用一个从当时目录下的 Dockerfile 文件构建的镜像。然后它将容器和主机绑定到暴露的端口8000上。本例服务运用Flask网络服务器的默许端口,即5000。

Redis服务

redis 服务运用了一个从Docker Hub仓库中拉取的公共Redis镜像。

第4步:用Compose构建和运转你的使用

  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镜像,为你的代码构建一个镜像,并发动你界说的服务。在这种情况下,代码在构建时被静态地仿制到镜像中。

  1. 浏览器中输入http://localhost:8000/,能够看到使用程序正在运转。

假如你在本地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.

Docker Compose 搭建简单的Python网络应用程序
3. 改写页面。

这个数字应该是递加的。

Hello World! I have been seen 2 times.

Docker Compose 搭建简单的Python网络应用程序

  1. 切换到另一个终端窗口,并输入 docker image ls 来列出本地图画。

在这一点上,列出图画应该返回 redisweb

$ 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> 检查镜像。

  1. 中止使用程序,能够在第二个终端中的项目目录中运转 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)

在你的浏览器中改写该使用程序。问候语应该被更新,而计数器应该仍然在递加。

Docker Compose 搭建简单的Python网络应用程序

第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 是怎么作业的。