Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。上一章DockersFile 是管理一个容器的技术,docker compose 相同于是管理多个容器的技术。现在项目多采用微服务的模式,一个项目中包含了多个服务,每个服务启动多个实例,一般采用docket compose来编排。
1 安装docker compose
有外网的同志按此教程
curl -SL https://github.com/docker/compose/releases/download/v2.26.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
无外网的同志按此教程
链接:百度网盘 请输入提取码 提取码:61jn
# windows上传到服务器
scp D:\docker-compose-linux-x86_64 root@192.168.1.116:/home
# 复制并改名/usr/local/bin/docker-compose
cp /home/docker-compose-linux-x86_64 /usr/local/bin/docker-compose
# 添加权限
chmod +x /usr/local/bin/docker-compose
docker-compose --version
能显示版本表示安装成功
2 docker compose 服务命令
docker-compose -h | 查看帮助 |
---|---|
docker-compose up | 创建并运行所有容器 |
docker-compose up -d | 创建并后台运行所有容器 |
docker-compose -f docker-compose.yml up -d | 根据模板启动容器 |
docker-compose -f docker-compose.yml -p <project> up -d | 根据模板与项目名称启动容器 |
docker-compose -f docker-compose.yml down | 根据指定文件名称停止并删除容器、网络、卷、镜像。 |
docker-compose -f docker-compose.yml -p <project> down | 根据指定文件名称与项目名称停止并删除容器、网络、卷、镜像。 |
docker-compose down | 停止并删除容器、网络、卷。 |
docker-compose down --rmi all | 停止并删除容器、网络、卷以及镜像。 |
docker-compose logs | 查看容器输出日志 |
docker-compose pull | 拉取依赖镜像 |
dokcer-compose config | 检查配置 |
dokcer-compose config -q | 检查配置,有问题才有输出 |
docker-compose restart | 重启服务 |
docker-compose start | 启动服务 |
docker-compose stop | 停止服务 |
3 docker compose 语法
1 version 指定本 yml 依从的 compose 哪个版本制定的。
# 示例,表示compose是哪个版本3.7
version: "3.7"
3、image 指定为镜像名称或镜像ID。
#示例
services:
web:
image: nginx
# image: ubuntu:14.04
# image: example-registry.com:4000/postgresql
# image: a4bc65fd # 镜像id
3、build 指定为构建镜像上下文路径。
# 示例1
version: "3.7"
services:
webapp:
build: ./dir
# 示例2
version: "3.7"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
target: prod
# context:上下文路径。
# dockerfile:指定构建镜像的 Dockerfile 文件名。
# args:添加构建参数,这是只能在构建过程中访问的环境变量。
# labels:设置构建镜像的标签。
# target:多层构建,可以指定构建哪一层。
4、command 覆盖容器启动后默认执行的命令。
# 示例
command: ["python", "manager.py", "runserver", "-p", "3000"]
5、links 链接到其他服务容器
# 示例
links:
- db
- db:database
- redis
6、external_links
链接到docker-compose.yml外部的容器,甚至并非是Compose管理的容器。参数格式和links类似。
# 示例
- redis_1
- project_db_1:mysql
- project_db_2:sqlserver
7、ports 暴露端口信息。
# 示例
ports:
- "3306"
- "8080:80"
- "127.0.0.1:8090:8001"
# 仅仅指定容器的端口(宿主机器将会随机分配端口)
8、expose 暴露端口,但不映射到宿主机,只被连接的服务访问。仅可以指定内部端口为参数:
# 示例
expose:
- "3000"
- "8000"
9、volumes 设置卷挂载的路径。可以设置宿主机路径:容器路径(host:container)或加上访问模式(host:container:ro)ro就是readonly的意思,只读模式。
# 示例
volumes:
- /var/lib/mysql:/var/lib/mysql
- /configs/mysql:/etc/configs/:ro
10、volunes_from 挂载另一个服务或容器的所有数据卷。
# 示例 volumes_from: - service_name - container_name
11、environment 添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。
# 示例
environment:
RACK_ENV: development
SHOW: 'true'
12、env_file
从文件中获取环境变量,可以为单独的文件路径或列表。 如果通过docker-compose -f FILE指定了模板文件,则env_file中路径会基于模板文件路径。 如果有变量名称与environment指令冲突,则以后者为准。
# 示例
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
环境变量文件中每一行都必须有注释,支持#开头的注释行。
# common.env: Set Rails/Rack environment
RACK_ENV=development
13、extends 基于已有的服务进行服务扩展。例如我们已经有了一个webapp服务,模板文件为common.yml.
# common.yml
webapp:
build: ./webapp
environment:
- DEBUG=false
- SEND_EMAILS=false
编写一个新的 development.yml 文件,使用 common.yml 中的 webapp 服务进行扩展。 development.yml
web:
extends:
file: common.yml
service:
webapp:
ports:
- "8080:80"
links:
- db
envelopment:
- DEBUG=true
db:
image: mysql:5.7
后者会自动继承common.yml中的webapp服务及相关的环境变量。
14、network_mode 设置网络模式。使用和docker client 的 --net 参数一样的值。
# 示例
network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
15、dns 自定义 DNS 服务器,可以是单个值或列表的多个值
# 示例
dns: 8.8.8.8
dns:
- 8.8.8.8
- 9.9.9.9
16、cap_add,cap_drop 添加或删除容器拥有的宿主机的内核功能。
# 示例
cap_add:
- ALL # 开启全部权限
cap_drop:
- SYS_PTRACE # 关闭 ptrace权限
17、dns_search 自定义 DNS 搜索域。可以是单个值或列表。
# 示例
dns_search: example.com
dns_search:
- dc1.example.com
- dc2.example.com
18、healthcheck 用于检测 docker 服务是否健康运行。
# 示例
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] # 设置检测程序
interval: 1m30s # 设置检测间隔
timeout: 10s # 设置检测超时时间
retries: 3 # 设置重试次数
start_period: 40s # 启动后,多少秒开始启动检测程序
19、depends_on 设置依赖关系
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
# docker-compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web。
# docker-compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中,docker-compose up web 还将创建并启动 db 和 redis。
# docker-compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。
# 注意:web 服务不会等待 redis db 完全启动 之后才启动。
20、deploy 指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。
version: "3.7"
services:
redis:
image: redis:alpine
deploy:
mode:replicated
replicas: 6
endpoint_mode: dnsrr
labels:
description: "This redis service label"
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
21 mode:指定服务提供的模式。
-
eplicated:复制服务,复制指定服务到集群的机器上。
-
global:全局服务,服务将部署至集群的每个节点。
# 示例
mode: eplicated
22 replicas:mode 为 replicated 时,需要使用此参数配置具体运行的节点数量。
# 示例
mode: eplicated
replicas: 3
# 表示开启3个容器
4 docker compose示例
设置MySQL的主从同步,读写分离
# 网桥 -> 方便相互通讯
networks:
mysql:
driver: bridge
services:
mysql-master:
image: mysql:5.6 # 原镜像`mysql:5.6`
container_name: mysql_master # 容器名为'mysql_master'
restart: unless-stopped # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
- "./master/conf:/etc/mysql/mysql.conf.d"
- "./master/data:/var/lib/mysql"
environment: # 设置环境变量,相当于docker run命令中的-e
TZ: Asia/Shanghai
LANG: en_US.UTF-8
MYSQL_ROOT_PASSWORD: root # 设置root用户密码
MYSQL_DATABASE: demo # 初始化的数据库名称
ports: # 映射端口
- "3306:3306"
networks:
- mysql
mysql-slave:
image: mysql:5.6 # 原镜像`mysql:5.6
container_name: mysql_slave # 容器名为'mysql_slave'
restart: unless-stopped # 指定容器退出后的重启策略为始终重启,但是不考虑在Docker守护进程启动时就已经停止了的容器
volumes: # 数据卷挂载路径设置,将本机目录映射到容器目录
- "./slave/conf:/etc/mysql/mysql.conf.d"
- "./slave/data:/var/lib/mysql"
environment: # 设置环境变量,相当于docker run命令中的-e
TZ: Asia/Shanghai
LANG: en_US.UTF-8
MYSQL_ROOT_PASSWORD: root # 设置root用户密码
MYSQL_DATABASE: demo # 初始化的数据库名称
ports: # 映射端口
- "3307:3306"
depends_on:
- mysql-master
networks:
- mysql
在服务器上执行如下命令
1 新建docker-compose.yml文件,将上面的内容复制到yml文件中
vim docker-compose.yml
2 生成配置文件 python3
# mysql.py
"""利用python脚本在docker上启动2个MySQL"""
import os
folderList = ['master', 'slave']
localPath = os.path.dirname(os.path.abspath(__file__))
def create_config():
for index, folder in enumerate(folderList):
folder_path = os.path.join(localPath, folder)
if not os.path.exists(folder_path):
os.makedirs(folder_path)
config_path = os.path.join(folder_path, 'conf')
if not os.path.exists(config_path):
os.makedirs(config_path)
data_path = os.path.join(folder_path, 'data')
if not os.path.exists(data_path):
os.makedirs(data_path)
config_data = """[mysqld]
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
datadir=/var/lib/mysql
log-error=/var/log/mysql/error.log
server-id={}
log-bin=/var/log/mysql/mysql-bin.log
expire_logs_days=30
max_binlog_size=256M
symbolic-links=0
# slow_query_log=ON
# slow_query_log_file=/var/log/mysql/slow.log
# long_query_time=1""".format(index+1)
config_file = os.path.join(config_path, 'mysqld.cnf')
with open(config_file, 'w') as f:
f.write(config_data)
if __name__ == '__main__':
create_config()
# 运行python 脚本
python3 mysql.py
3 执行docker-compose
docker-compose -f docker-compose.yml -p mysql-master-slave up -d
3 查看容器是否启动
docker ps
4 配置主从同步
#master, 进入容器中
docker exec -ti mysql_master bash
mysql -u root -proot
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
flush privileges;
show master status; #显示master上面的状态
#slave1
docker exec -ti mysql_slave bash
mysql -u root -proot
reset slave;
change master to master_host='192.168.1.116', master_port=3306, master_user='slave', master_password='123456', master_log_file='mysql-bin.000003', master_log_pos=590;
start slave;
# master_host 为master的IP, master_port为master的端口,master_user为通信用户名,master_password为密码,master_log_file为master的bin日志,master_log_pos为master的log_pos
show slave status \G #查看状态如果Slave_IO_Running: Yes Slave_SQL_Running: Yes 则表示开启成功
查看状态如果Slave_IO_Running: Yes Slave_SQL_Running: Yes 则表示开启成功