Docker Compose 的基本使用
Warning
以下操作均在 root 用户下进行,否则请带上 sudo,或者是把用户加到 docker 用户组内。
为什么用 Docker Compose
实际项目的单宿主机 Docker 配置情况

如果用纯 Docker 命令来部署容器
这段命令是以前我自己的服务器上的启动命令,与上面的图无关
| docker run \
--name nginx \
-itd \
-p 80:80 \
-p 443:443 \
-v /root/nginx_conf/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /root/nginx_conf/cert_conf:/etc/nginx/cert_conf:ro \
-v /root/nginx_conf/website_conf:/etc/nginx/website_conf:ro \
-v /root/website:/usr/share/nginx/html:ro \
-v /root/acme.sh:/etc/acme.sh:ro \
-v /root/nginx_logs:/var/log/nginx \
--network ding-docker \
--restart=unless-stopped \
nginx
docker run -d \
--restart=unless-stopped \
--name verysync \
-v /root/verysync:/data \
--network ding-docker \
unwenliu/verysync:latest
docker run -dit --name code-server \
-v "$HOME/.config:/root/.config" \
-v "$PWD:/home/coder/project" \
-u "$(id -u):$(id -g)" \
--network ding-docker \
--restart=unless-stopped \
codercom/code-server:latest
docker run \
--name note \
-it -d \
-v ~/wizdata:/wiz/storage \
-e SEARCH=true \
--network ding-docker \
wiznote/wizserver
docker run -d \
--name aria2 \
--restart unless-stopped \
--log-opt max-size=1m \
-e PUID=0 \
-e PGID=0 \
-e RPC_SECRET=****** \
-p 6800:6800 \
-p 6888:6888 -p 6888:6888/udp \
--network ding-docker \
-v /root/cloudreve/aria2/config:/config \
-v /root/cloudreve/aria2/downloads:/downloads \
p3terx/aria2-pro
docker run -d \
--name cloudreve \
-e PUID=0 \
-e PGID=0 \
-e TZ="Asia/Shanghai" \
--network ding-docker \
--restart=unless-stopped \
-v /root/cloudreve/uploads:/cloudreve/uploads \
-v /root/cloudreve/aria2/downloads:/downloads \
-v /root/cloudreve/conf.ini:/cloudreve/conf.ini \
-v /root/cloudreve/cloudreve.db:/cloudreve/cloudreve.db \
-v /root/cloudreve/avater:/cloudreve/avatar \
xavierniu/cloudreve
docker run --name guacd --network ding-docker --restart=unless-stopped -d guacamole/guacd
docker run \
--name mysql \
-v /root/db/mysql:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=****** \
--restart unless-stopped \
--network ding-docker \
--privileged=true \
-p 3306:3306 \
-d mysql
docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --postgresql > initdb.sql
docker run \
--name guacamole \
--network ding-docker \
-e MYSQL_HOSTNAME=mysql \
-e MYSQL_DATABASE=****** \
-e MYSQL_USER=****** \
-e MYSQL_PASSWORD=****** \
-e GUACD_HOSTNAME=guacd \
--link guacd:guacd \
--link mysql:mysql \
-d \
-p 8080:8080 \
--restart=unless-stopped \
guacamole/guacamole
docker run -d \
--name rsshub \
-p 1200:1200 \
--restart always \
--network ding-docker \
diygod/rsshub:latest
docker run -d \
--restart unless-stopped \
--log-opt max-size=10m \
-v /root/freshrss_data:/var/www/FreshRSS/data \
-v /root/freshrss_extensions:/var/www/FreshRSS/extensions \
-e 'CRON_MIN=4,34' \
-e TZ=Asia/Shanghai \
--network ding-docker \
--link postgres:postgres \
--name freshrss \
freshrss/freshrss
docker run \
--name typecho \
-v /root/website/typecho:/app/usr \
--link mysql:mysql \
-e TYPECHO_SITE_URL=https://4ading.com \
-e TIMEZONE=Asia/Shanghai \
-e TYPECHO_INSTALL=1 \
-e TYPECHO_DB_ADAPTER=Pdo_Mysql \
-e TYPECHO_DB_HOST=mysql \
-e TYPECHO_DB_USER=****** \
-e TYPECHO_DB_PASSWORD=****** \
-e TYPECHO_DB_DATABASE=****** \
-e ******_NAME=billding \
-e ******_PASSWORD=****** \
-e ******_MAIL=dingjunyao0703@163.com \
--network=ding-docker \
-d joyqi/typecho:nightly-php7.4
docker run -d \
--name=myenigma \
--network=ding-docker \
myenigma-demo
docker run -d \
--name=wikijs \
--network=ding-docker \
--link mysql:mysql \
-e DB_TYPE=mysql \
-e DB_HOST=mysql \
-e DB_PORT=****** \
-e DB_USER=****** \
-e DB_PASS=****** \
-e DB_NAME=****** \
--restart unless-stopped \
requarks/wiki:latest
docker run -p 6379:6379 \
--name redis \
--restart always \
--network=ding-docker \
-v /root/redis/redis.conf:/etc/redis/redis.conf \
-v /root/redis/data:/data \
-d redis \
redis-server \
/etc/redis/redis.conf --appendonly yes --requirepass "******"
docker run -it \
--name postgres \
--network=ding-docker \
--restart always \
-e POSTGRES_PASSWORD='******' \
-e ALLOW_IP_RANGE=0.0.0.0/0 \
-v /root/db/postgres/data:/var/lib/postgresql \
-p 5432:5432 \
-d abcfy2/zhparser
|
- 如果更新容器,需要考虑依赖、顺序
- 脚本不易读,不易维护
- 如需构建镜像,更加麻烦(之后会讲)
Docker Compose 简介
Docker Compose
一个可以批量操作 Docker 容器的工具。
使用 YAML 格式的文件保存配置信息。
YAML
YAML Ain't Markup Language
- 扩展名是 yml 或 yaml
- 一种描述数据的语言(确切说是格式)
- 常用于做配置文件
- 人类可读性强
- 利用空格缩进区分层级
- 利用冒号分隔键值
- 支持列表和注释
例:
| YAML: YAML Ain't Markup Language™
What It Is:
YAML is a human-friendly data serialization
language for all programming languages.
YAML Resources:
YAML Specifications:
- YAML 1.2:
- Revision 1.2.2 # Oct 1, 2021 *New*
- Revision 1.2.1 # Oct 1, 2009
- Revision 1.2.0 # Jul 21, 2009
- YAML 1.1
- YAML 1.0
|
安装
Warning
安装方式不同,之后执行的命令也不同;这里会考虑公司内网的问题。
通过包管理器安装
以 Ubuntu 为例:
| apt install docker-compose
|
这种安装方式安装的版本较老,安装完后执行的命令为 docker-compose。
下载二进制文件安装
下载二进制文件
访问 https://github.com/docker/compose/releases/,在最新版或所需版本的 Assets 中找到对应系统、平台的文件,下载:

安装
有两种方法。
方法 1 - 作为 Docker CLI 插件安装
创建目录 /usr/local/lib/docker/cli-plugins:
| mkdir -p /usr/local/lib/docker/cli-plugins
|
将下载的二进制文件放到这个目录下,命名为 docker-compose。
为其添加 x 权限:
| chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
|
这种方式安装完后执行的命令为 docker compose。
方法 2 - 作为单独的可执行文件安装
将下载的二进制文件放到 /usr/local/bin/ 下,命名为 docker-compose。
为其添加 x 权限:
| chmod +x /usr/local/bin/docker-compose
|
这种方式安装完后执行的命令为 docker-compose。
如果 /usr/local/bin 不在 PATH 下,或者是有冲突,可以建立链接:
| ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
|
验证安装是否成功
根据安装方式执行之前提到的命令,之后加 version 选项:
| root@ding-server:~# docker compose version # 下载二进制文件作为插件安装
Docker Compose version v2.6.0
root@ding-server:~# docker-compose version # 通过包管理器安装
docker-compose version 1.25.0, build unknown
docker-py version: 4.1.0
CPython version: 3.8.10
OpenSSL version: OpenSSL 1.1.1f 31 Mar 2020
|
Info
此后默认以 docker-compose 为准。
写配置文件
配置文件
文件名一般为 docker-compose.yml。
基本格式:
| version: "3.9" # 版本号
services: # 开始写需要的容器(服务)
web: # 第一个服务名称
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
redis: # 第二个服务名称
image: "redis:alpine" # 镜像
|
普通 Docker 脚本与 Docker Compose 配置的转换


依赖
通过配置依赖,可以控制容器的启停顺序,避免容器启动失败。
没有延时启停功能。
例:

| version: '3'
services:
mysql-srv:
image: mysql
# ...
nginx-srv:
image: nginx
# ...
typecho:
image: typecho
depends_on:
- nginx-srv
- mysql-srv
|
完整格式规范
Compose specification | Docker Documentation
运行配置文件
自定义配置文件路径
如果配置文件是当前目录下的 docker-compose.yml,则不需要自定义。否则,需自定义文件路径,才能使用大多数功能(包括与配置文件无关的功能):
| docker-compose [-f 文件路径] 操作 [选项] [服务 ...]
|
主要操作
- 与
docker 类似的:start、stop、restart、ps、rm、pull、help、exec、images...
- 有差别的:
logs...
- 新的:
up、down...
上马(up)
首先停止、删除此前存留的服务(只针对文件中的),之后按顺序启动:
| docker-compose [-f 文件路径] up [-d] [服务名 ...]
|
选项:
-d:后台运行(非常常用);如无该选项则会在前台启动所有服务,终止后即终止所有服务
服务名:只启动特定的服务,但也会启动依赖(如果依赖已启动,默认不会被销毁)
撤下(down)
停止并删除文件中的服务、网络(包括默认网络)等:
| docker-compose [-f 文件路径] down [--remove-orphans]
|
选项:
--remove-orphans:撤下不在文件里配置的容器
查看日志
| docker-compose [-f 文件路径] logs [选项] [服务名 ...]
|
查看的是所有服务的日志,而非文件中的。
选项:
服务名:只查看对应服务的日志
-f:滚动查看
-t:添加时间
--tail=数字:每项服务显示后几条数据
日志示例
日志前面会有服务名,不同服务名以颜色区分:

添加时间的效果:

参考资料