九、Docker Compose

Compose 简介

Docker Compose项目是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。(需要下载)

Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。

Docker Compose将所管理的容器分为三层,分别是项目(project),服务(service)以及容器(container)

(Docker-Compose运行目录下的所有文件(docker-compose.yml,extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像,参数,依赖。一个服务当中可包括多个容器实例,Docker-Compose并没有解决负载均衡的问题,因此需要借助其它工具实现服务发现及负载均衡。 Docker-Compose的工程配置文件默认为docker-compose.yml,可通过环境变量COMPOSE_FILE或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器。 使用一个Dockerfile模板文件,可以让用户很方便的定义一个单独的应用容器。在工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个Web项目,除了Web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。 Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。 Docker-Compose项目由Python编写,调用Docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持Docker API,就可以在其上利用Compose来进行编排管理。)

Compose 使用的三个步骤:

1. 使用 Dockerfile 定义应用程序的环境。

2. 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。

3. 最后,执行 docker-compose up 命令来启动并运行整个应用程序。

 

docker-compose.yml 的配置案例如下:

# yaml 配置实例
version: "3.7"

 services:
   app:
     image: node:12-alpine
     command: sh -c "yarn install && yarn run dev"
     ports:
       - 3000:3000
     working_dir: /app
     volumes:
       - ./:/app
     environment:
       MYSQL_HOST: mysql
       MYSQL_USER: root
       MYSQL_PASSWORD: secret
       MYSQL_DB: todos

Compose 安装

# 直接使用软件仓库安装 docker-compose-plugin
[root@fedora ~]# yum install -y docker-compose-plugin
......
......
已安装:
  docker-compose-plugin-2.6.0-3.fc36.x86_64                                                                                                                                 
完毕!
# 测试安装
[root@fedora ~]# docker compose version
Docker Compose version v2.6.0

Compose 使用

构建一个在 Docker 上运行的简单 Python Web 应用

1、准备

# 1.为项目创建一个目录
[root@fedora ~]# mkdir composetest
[root@fedora ~]# cd composetest/
# 2.创建一个名为 app.py 文件
[root@fedora composetest]# touch app.py
# 将以下代码粘贴到 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)
# 3.创建一个名为 requirements.txt 文件
[root@fedora composetest]# vim  requirements.txt
[root@fedora composetest]# cat requirements.txt 
flask
redis

2、创建 Dockerfile 文件

在 composetest 目录中,创建一个名为 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"]

Dockerfile 内容解释:

  • FROM python:3.7-alpine: 从 Python 3.7 映像开始构建镜像。
  • WORKDIR /code: 将工作目录设置为 /code。
  • ENV FLASK_APP app.py
    ENV FLASK_RUN_HOST 0.0.0.0

    设置 flask 命令使用的环境变量。

  • RUN apk add --no-cache gcc musl-dev linux-headers: 安装 gcc,以便诸如 MarkupSafe 和 SQLAlchemy 之类的 Python 包可以编译加速。
  • COPY requirements.txt requirements.txt
    RUN pip install -r requirements.txt

    复制 requirements.txt 并安装 Python 依赖项。

  • COPY . .: 将 . 项目中的当前目录复制到 . 镜像中的工作目录。
  • CMD ["flask", "run"]: 容器提供默认的执行命令为:flask run。

3、创建 docker-compose.yml

在测试目录中创建一个名为 docker-compose.yml 的文件,然后粘贴以下内容:
version: "3.9"
services:
  web:
    build: .
    ports:
      - "8000:5000"
  redis:
    image: "redis:alpine"

该 Compose 文件定义了两个服务:web 和 redis。

  • web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。
  • redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。

4、使用 Compose 命令构建和运行您的应用

在测试目录中,执行以下命令来启动应用程序:

docker-compose up

如果你想在后台执行该服务可以加上 -d 参数:

docker-compose up -d
 
若执行时遇到以下错误
Step 5/9 : RUN apk add --no-cache gcc musl-dev linux-headers
 ---> [Warning] IPv4 forwarding is disabled. Networking will not work.
 ---> Running in 7b29f4df9539
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
WARNING: Ignoring http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz: temporary error (try again later)
WARNING: Ignoring http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz: temporary error (try again later)
ERROR: unsatisfiable constraints:
  gcc (missing):
    required by: world[gcc]
  linux-headers (missing):
    required by: world[linux-headers]
  musl-dev (missing):
    required by: world[musl-dev]
ERROR: Service 'web' failed to build: The command '/bin/sh -c apk add --no-cache gcc musl-dev linux-headers' returned a non-zero code: 3

我通过使用来自以下网址的博客部分解决了 Fedora 上的这个问题: https

启用旧 CGroups:

sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0"

防火墙中的白名单:(若出现异常,可关闭防火墙)

sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0
sudo firewall-cmd --permanent --zone=FedoraWorkstation --add-masquerade

为 docket-composer 安装依赖项:

sudo dnf install python3-attrs python3-bcrypt python3-cached_property python3-docker python3-docker-pycreds python3-dockerpty python3-docopt python3-fluidity-sm python3-invoke python3-jsonschema python3-lexicon python3-paramiko python3-pyasn1 python3-pynacl python3-pyrsistent python3-texttable python3-websocket-client
sudo reboot

测试是否部署成功
[root@fedora ~]# docker network ls
NETWORK ID     NAME                  DRIVER    SCOPE
cfe7a624b7d7   bridge                bridge    local
9082dd33ec54   composetest_default   bridge    local
652ac854120d   host                  host      local
# composetest_default
# 项目中的所有容器都在同一个网络内,可以通过域名访问

[root@fedora ~]# docker images
REPOSITORY        TAG          IMAGE ID       CREATED          SIZE
composetest_web   latest       ed2275100142   27 minutes ago   185MB
redis             alpine       3900abf41552   6 months ago     32.4MB
python            3.7-alpine   a1034fd13493   6 months ago     41.8MB

[root@fedora ~]# docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED         STATUS         PORTS                                       NAMES
c264f9403f6b   composetest_web   "flask run"              6 minutes ago   Up 5 minutes   0.0.0.0:8000->5000/tcp, :::8000->5000/tcp   composetest_web_1
0c7d14bf51b7   redis:alpine      "docker-entrypoint.s…"   6 minutes ago   Up 5 minutes   6379/tcp                                    composetest_redis_1
# 默认的容器名 : 文件名_服务名_number

[root@fedora ~]# curl localhost:8000
Hello World! I have been seen 1 times.
[root@fedora ~]# curl localhost:8000
Hello World! I have been seen 2 times.
[root@fedora ~]# curl localhost:8000
Hello World! I have been seen 3 times.

5、编辑 Compose 文件以添加绑定挂载

Edit docker-compose.yml in your project directory to add a bind mount for the web service:
version: "3.9"
services:
  web:
    build: .
    ports:
      - "8000:5000"
# 添加以下内容
# ---------------------------
    volumes:
      - .:/code
    environment:
      FLASK_ENV: development
# ---------------------------      
  redis:
    image: "redis:alpine"
The new volumes key mounts the project directory (current directory) on the host to /code inside the container, allowing you to modify the code on the fly, without having to rebuild the image. The environment key sets the FLASK_ENV environment variable, which tells flask run to run in development mode and reload the code on change. This mode should only be used in development.

6、使用 Compose 重新构建并运行应用程序

键入 docker-compose up使用更新的 Compose 文件构建应用程序并运行它。
[root@fedora ~]# docker-compose up
......
......
[root@fedora ~]# curl localhost:8000
Hello World! I have been seen 4 times.

7、更新应用程序

因为应用程序代码现在使用卷安装到容器中, 您可以对其代码进行更改并立即查看更改,而无需重新构建镜像。

更改问候语 app.py并保存它。 例如,更改 Hello World! 留言给 Hello from Docker!:

return 'Hello from Docker! I have been seen {} times.\n'.format(count)
[root@fedora ~]# curl localhost:8000
Hello from Docker! I have been seen 5 times.

8、尝试其他一些命令

# 后台运行服务
docker-compose up -d
# 查看正在运行的容器
docker-compose ps
# 查看哪些环境变量可用于 web服务
docker-compose run web env
# 查看该命令帮助信息
docker-compose --help
# 停止服务
docker-compose stop
# 删除服务,同时删除容器使用的数据卷
docker-compose down --volumes

yml 配置规则

docker-compose.yml 核心

# 分为3层

version: '' # 1.版本
services:   # 2.服务
   服务1: web
     # 服务配置
     images
     build
     network
     ......
   服务2: redis
     ......
   服务3: redis
     ......
# 3.其它配置
# 网络、卷、全局规则
networks:
volumes:
configs:

掌握规律,多写多看。

1. 官方文档

https://docs.docker.com/compose/reference/

2. 开源项目

 一键部署WordPress博客

使用 Docker Compose 在隔离环境中轻松运行 WordPress

# 创建并进入一个空的项目目录
[root@fedora ~]# mkdir my_wordpress
[root@fedora ~]# cd my_wordpress/
# 创建一个 docker-compose.yml
[root@fedora my_wordpress]# vim docker-compose.yml
[root@fedora my_wordpress]# cat docker-compose.yml

version: "3.9"
    
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    
  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: {}
  wordpress_data: {}

# 后台启动该项目
[root@fedora my_wordpress]# docker-compose up -d

在浏览器中打开 WordPress,地址:IP地址:8000

关闭和清理

docker compose down 
# 删除容器和默认网络,但保留您的 WordPress 数据库

docker compose down --volumes 
 # 删除容器、默认网络和 WordPress 数据库

小结

以前都是 docker run 启动单个容器。有了docker-compose,编写好 yaml 配置文件,可以通过 compose 一键启动、停止所有服务,以及更加轻松高效的管理容器。

posted @ 2022-06-27 00:25  CharlieBrown  阅读(166)  评论(1编辑  收藏  举报
标题