Docker 系列之 Docker Compose
Docker-Compose 是一个用于定义和运行多容器 Docker 应用的工具。
通过一个 YAML 文件,您可以配置应用需要的所有服务。
然后,使用一个简单的命令就可以创建并启动所有服务。
Docker-Compose 的主要功能
多容器管理:可以在一个文件中定义多个容器,并使用一个命令同时启动和停止这些容器。
服务编排:可以指定容器之间的依赖关系、共享的网络和卷等配置。
环境隔离:可以通过不同的 Compose 文件和项目名来管理多个环境(如开发、测试、生产)。
简化的部署:可以将整个应用的定义版本控制,并在不同的环境中一致地部署。
Docker-Compose 常用命令
命令 | 作用 |
docker compose attach [SERVICE...] | 附加到正在运行的服务容器。 |
docker compose build [SERVICE...] | 构建或重建服务 |
docker compose config | 校验和查看 Compose 文件 |
docker compose create [SERVICE...] | 创建服务的容器。 |
docker compose down | 停止并删除容器、网络、卷和镜像。 |
docker compose events [SERVICE...] | 从容器中获取实时事件。 |
docker compose exec SERVICE COMMAND [ARGS...] | 在正在运行的容器中执行命令。 |
docker compose images | 列出 Compose 文件中使用的镜像 |
docker compose kill [SERVICE...] | 通过发送 SIGKILL 信号终止服务的容器。 |
docker compose logs [SERVICE...] | 显示容器的日志。 |
docker compose ls | 列出项目。 |
docker compose pause [SERVICE...] | 暂停容器服务。 |
docker compose unpause [SERVICE...] | 取消暂停服务的容器。 |
docker compose port SERVICE PORT | 显示服务的容器端口绑定到宿主机的哪个端口。 |
docker compose up -d | 后台启动容器。 |
docker compose restart [SERVICE...] | 重启服务的容器。 |
docker compose start [SERVICE...] | 启动服务的容器。 |
docker compose stop | 停止容器。 |
docker compose rm | 删除停止的容器。 |
docker compose top [SERVICE...] | 显示正在运行的容器进程。 |
docker compose scale SERVICE=NUM | 设置服务的容器数量。 |
docker compose run SERVICE COMMAND [ARGS...] | 运行一次性命令。 |
Docker-Compose 文件使用 YAML 语法,通常命名为 docker-compose.yml。
下面是一个简单的示例,定义了一个包含两个服务(Web 应用和数据库)的应用:
version: '3.8' # 定义 Docker Compose 文件的版本。不同版本支持不同的功能和语法。
services: # 定义所有容器服务
mysql: # 这是一个服务,代表一个 MySQL 数据库容器。
image: mysql:5.7 # 使用 mysql 5.7 镜像。
restart: always # 配置容器的重启策略。
environment: # 环境变量,用于配置 MySQL 数据库的初始化。
MYSQL_ROOT_PASSWORD: 123456 # MySQL root 用户的密码。
MYSQL_DATABASE: wordpress # 启动时创建的数据库名称。
MYSQL_USER: app # 要创建的普通用户的用户名。
MYSQL_PASSWORD: app123 # 要创建的普通用户的密码。
networks: # 将此服务连接到指定的网络
- mynetwork # 将此服务连接到名为 mynetwork 的网络。
volumes: # 挂载卷,用于持久化数据
- db:/var/lib/mysql # 将 Docker 卷 db 挂载到容器内的 /var/lib/mysql 目录,以存储 MySQL 数据。
wordpress: # 另一个服务,代表一个 WordPress 容器。
depends_on: # 指定服务依赖关系。
- mysql # 指定服务的依赖关系。这里表示 wordpress 服务依赖 mysql 服务,确保 mysql 服务先启动。
image: wordpress:latest # 使用最新版本的 wordpress 镜像。
environment: # 环境变量,用于配置 WordPress 连接 MySQL 数据库。
MYSQL_DB_HOST: mysql:3306 # MySQL 数据库主机和端口,因在同一网络下,所以可使用服务名称直接通信,在 WEB 页面初始化 WordPress 时,数据库地址也可以填写服务名称
MYSQL_DB_NAME: wordpress # WordPress 使用的数据库名称。
MYSQL_DB_USER: app # 连接数据库的用户名。
MYSQL_DB_PASSWORD: app123 # 连接数据库的用户密码。
ports:
- 80:80 # 将容器的 80 端口映射到主机的 80 端口。
volumes: # 挂载卷,用于持久化数据
- wordpress_data:/var/www/html # 将 Docker 卷 wordpress_data 挂载到容器内的 var/www/html 目录,以对 WordPress 文件进行持久化配置
networks:
- mynetwork # 将此服务连接到名为 mynetwork 的网络。
networks: # 定义自定义网络
mynetwork: # 自定义网络名称为 mynetwork
driver: bridge # 使用 bridge 网络驱动。
volumes: # 定义自定义卷。
db: # 名为 db 的卷,由 Docker 管理,通常在 /var/lib/docker/volumes/ 下。
wordpress_data: # 名为 wordpress_data 的卷,由 Docker 管理,通常在 /var/lib/docker/volumes/ 下。
启动
[root@docker01 wordpress]# docker compose up -d
WARN[0000] /root/dockercompose/wordpress/docker-compose.yaml: `version` is obsolete
[+] Running 5/5
✔ Network wordpress_mynetwork Created 0.1s
✔ Volume "wordpress_wordpress_db" Created 0.0s
✔ Volume "wordpress_wordpress_data" Created 0.0s
✔ Container wordpress-mysql-1 Started 0.2s
✔ Container wordpress-wordpress-1 Started 0.6s
[root@docker01 wordpress]# docker compose ps
WARN[0000] /root/dockercompose/wordpress/docker-compose.yaml: `version` is obsolete
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
wordpress-mysql-1 mysql:5.7 "docker-entrypoint.s…" mysql 10 seconds ago Up 9 seconds 3306/tcp
wordpress-wordpress-1 wordpress:latest "docker-entrypoint.s…" wordpress 10 seconds ago Up 9 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp
[root@docker01 wordpress]#
[root@docker01 wordpress]# docker volume ls | grep word
local wordpress_wordpress_data
local wordpress_wordpress_db
[root@docker01 wordpress]# ll -d /var/lib/docker/volumes/wordpress*
drwx-----x 3 root root 19 7月 3 12:11 /var/lib/docker/volumes/wordpress_wordpress_data
drwx-----x 3 root root 19 7月 3 12:11 /var/lib/docker/volumes/wordpress_wordpress_db
打开浏览器,访问 http://宿主机IP,将看到 WordPress 安装页面。
Redis + Python 最佳实践
准备 py 文件
from flask import Flask
from redis import Redis
import os
import socket
app = Flask(__name__)
redis = Redis(host=os.environ.get('REDIS_HOST', '127.0.0.1'), port=6379)
@app.route('/')
def hello():
redis.incr('hits')
return 'Hello Container World! website access %s count! and my hostname is %s.\n' % (redis.get('hits'),socket.gethostname())
if __name__ == "__main__":
app.run(host="0.0.0.0", port=80, debug=True)
准备 Dockerfile
FROM python:2.7
RUN pip install flask redis
ADD app.py /
EXPOSE 80
CMD [ "python", "/app.py" ]
准备 docker-compose.yaml
version: '3.8'
services:
redis:
image: redis:latest
restart: always
networks:
- mynetwork
python:
depends_on:
- redis
build: # 构建模式
context: . # 当前上下文
dockerfile: Dockerfile # 当前目录的Dockerfile
environment:
REDIS_HOST: redis
ports:
- 80:80
networks:
- mynetwork
networks:
mynetwork:
driver: bridge
启动 Docker Compose
[root@docker01 python]# docker compose up -d
WARN[0000] /root/dockercompose/python/docker-compose.yaml: `version` is obsolete
[+] Building 23.5s (4/4) FINISHED docker-container:mybuilder
=> [python internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 139B 0.0s
=> [python internal] load .dockerignore 0.0s
=> => transferring context: 2B
=> [1/3] FROM docker.io/library/python:3.9-alpine 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 462B 0.0s
=> [2/3] RUN pip install flask redis 9.3s
=> [3/3] ADD app.py / 0.0s
=> exporting to image 0.2s
=> => exporting layers 0.1s
=> => writing image sha256:ec8af7e9d6e68fa0d078e48a431059c564251f01d04056cb779ea0b5b51c5607 0.0s
=> => naming to docker.io/library/py:v1
✔ Network python_mynetwork Created 0.1s
✔ Container python-redis-1 Started 0.3s
✔ Container python-python-1 Started 0.5s
[root@docker01 python]# docker compose ps
WARN[0000] /root/dockercompose/python/docker-compose.yaml: `version` is obsolete
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
python-python-1 py:v1 "python /app.py" python 5 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp
python-redis-1 redis:latest "docker-entrypoint.s…" redis 5 seconds ago Up 4 seconds 6379/tcp
测试
[root@docker01 python]# curl localhost
Hello Container World! website access b'1' count! and my hostname is b25b22f7a6f7.
节点水平扩展
1. 修改 docker-compose.yml 中的端口为随机端口
2. 调整 python 副本数
[root@docker01 python]# docker compose up -d --scale python=3
WARN[0000] /root/dockercompose/python/docker-compose.yaml: `version` is obsolete
[+] Running 4/4
✔ Container python-redis-1 Running 0.0s
✔ Container python-python-1 Running 0.0s
✔ Container python-python-3 Started 0.3s
✔ Container python-python-2 Started 0.7s
[root@docker01 python]# docker compose ps
WARN[0000] /root/dockercompose/python/docker-compose.yaml: `version` is obsolete
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
python-python-1 py:v1 "python /app.py" python 17 seconds ago Up 16 seconds 0.0.0.0:32768->80/tcp, :::32768->80/tcp
python-python-2 py:v1 "python /app.py" python 8 seconds ago Up 7 seconds 0.0.0.0:32770->80/tcp, :::32770->80/tcp
python-python-3 py:v1 "python /app.py" python 8 seconds ago Up 8 seconds 0.0.0.0:32769->80/tcp, :::32769->80/tcp
python-redis-1 redis:latest "docker-entrypoint.s…" redis 5 minutes ago Up 16 seconds 6379/tcp
3. 接入负载均衡
接入负载均衡,目前三个副本的端口都是随机端口,无法实现自动负载。
接入 Haproxy 统一对外提供80端口,并负载均衡至后端的 3 个副本,实现轮询调度。
version: '3.8'
services:
redis:
image: redis:latest
restart: always
networks:
- mynetwork
python:
depends_on:
- redis
image: py:v1
restart: always
environment:
REDIS_HOST: redis
ports:
- 80
networks:
- mynetwork
haporxy:
depends_on:
- python
links:
- python
image: dockercloud/haproxy:latest
restart: always
ports:
- 80:80
- 1936:1936
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- mynetwork
networks:
mynetwork:
driver: bridge
4. 启动
[root@docker01 python]# docker compose up -d --scale python=3
WARN[0000] /root/dockercompose/python/docker-compose.yaml: `version` is obsolete
[+] Running 5/5
✔ haporxy Pulled 17.9s
✔ 1160f4abea84 Pull complete 1.0s
✔ b0df9c632afc Pull complete 1.1s
✔ a49b18c7cd3a Pull complete 2.1s
[+] Running 5/5
✔ Container python-redis-1 Running 0.0s
✔ Container python-python-1 Running 0.0s
✔ Container python-python-3 Started 0.3s
✔ Container python-python-2 Started 0.8s
✔ Container python-haporxy-1 Running 0.0s
[root@docker01 python]# docker compose ps
WARN[0000] /root/dockercompose/python/docker-compose.yaml: `version` is obsolete
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
python-haporxy-1 dockercloud/haproxy:latest "/sbin/tini -- docke…" haporxy About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:1936->1936/tcp, :::1936->1936/tcp, 443/tcp
python-python-1 py:v1 "python /app.py" python About a minute ago Up About a minute 0.0.0.0:32771->80/tcp, :::32771->80/tcp
python-python-2 py:v1 "python /app.py" python 9 seconds ago Up 8 seconds 0.0.0.0:32773->80/tcp, :::32773->80/tcp
python-python-3 py:v1 "python /app.py" python 9 seconds ago Up 8 seconds 0.0.0.0:32772->80/tcp, :::32772->80/tcp
python-redis-1 redis:latest "docker-entrypoint.s…" redis About a minute ago Up About a minute 6379/tcp
测试
[root@docker01 py_redis]# curl localhost
Hello Container World! website access 6 count! and my hostname is 427a5cf5a6df.
[root@docker01 py_redis]# curl localhost
Hello Container World! website access 7 count! and my hostname is 3cb3cc7ee9dd.
[root@docker01 py_redis]# curl localhost
Hello Container World! website access 8 count! and my hostname is ea4bd3fb2058.
上一条:自建docker镜像加速
品质保证
多年的生产力软件专家
专业实力
资深技术支持项目实施团队
安全无忧
多位认证安全工程师
多元服务
软件提供方案整合,项目咨询实施
购软平台-找企业级软件,上购软平台。平台提供更齐全的软件产品、更专业的技术服务,同时提供行业资讯、软件使用教程和技巧。购软平台打造企业级数字产品综合应用服务平台。用户体验和数字类产品的专业化服务是我们不断追求的目标。购软平台您身边的企业级数字产品优秀服务商。