文章目录
更多 Docker 的使用技巧可以查看 Docker 专栏: Docker
1. DockerCompose简介
1.1 DockerCompose是什么
DockerCompose 是一个用于定义和运行多容器 Docker 应用程序的工具。它使用 YAML 文件来配置应用程序的服务,这些服务可以是运行在 Docker 容器中的单个服务,也可以是由多个容器组成的服务
DockerCompose 允许用户通过一个简单的命令来启动、停止和重建应用程序中的所有服务
1.2 DockerCompose的作用
Docker 容器本身只是一个特殊进程,如果我们想部署多个容器,而且对这些容器的执行顺序有一定的要求呢?
例如一个博客系统,需要先启动数据库容器,接着启动身份验证容器,最后启动博客 Web 服务容器。当然,挨个执行 docker run 指令是没问题的,那有没有更优雅的解决方案呢?
没错,DockerCompose 正是为了解决多容器的编排问题。我们只需要在一个 yaml 文件中写清楚要部署哪些容器,容器的部署顺序,最后执行 docker-compose up 命令,就能一键部署多个容器了
2. docker-compose.yml文件的基本结构
2.1 版本(version)
在新版本的docker-compose 中,version 属性已经被标为启用(
version
is obsolete)
version: "3.8" # 指定docker-compose文件的版本
2.2 服务(services)
services: # 定义所有服务的配置
# 自定义服务名称,例如 web
web:
image: nginx:1.26.2 # 指定服务的镜像
ports:
- "80:80" # 将容器的端口映射到宿主机
volumes:
- ./html:/usr/share/nginx/html # 将宿主机的目录挂载到容器中
networks:
- webnet # 将服务连接到指定的网络
# 另一个服务,例如 db
db:
image: postgres:latest # 指定服务的镜像
environment:
POSTGRES_DB: mydb # 设置环境变量
POSTGRES_USER: user
POSTGRES_PASSWORD: example
volumes:
- db_data:/var/lib/postgresql/data # 使用命名卷持久化数据
networks:
- webnet
2.2.1 image
在 docker-compose.yml
文件中,image
关键字用于指定要启动的容器的镜像
services:
web: # 定义一个服务,名称为 web
image: nginx:1.27.3 # 指定该服务使用的 Docker 镜像为 1.27.3 版本的 nginx
ports:
- "80:80" # 将容器的 80 端口映射到宿主机的 80 端口
2.2.2 build
在 docker-compose.yml
文件中,build
关键字用于指定 Docker Compose 应该通过一个 Dockerfile
构建服务的镜像,而不是直接使用一个已经存在的镜像
services:
webapp:
build:
context: ./path/to/build/directory
dockerfile: Dockerfile-alternate
image: mycustomimage:1.0.0
ports:
- "5000:5000"
在这个例子中:
build
指定了 Docker Compose 应该使用 Dockerfile 来构建服务的镜像context
是 Dockerfile 所在的路径,默认是docker-compose.yml
文件所在的目录dockerfile
(可选)指定了要使用的 Dockerfile 文件名。如果不指定,Docker Compose 默认会查找名为Dockerfile
的文件image
指定了构建后镜像的名称和标签。如果不指定image
,Docker Compose 会为构建的镜像生成一个默认名称,通常是<projectname>_<servicename>
2.2.3 container_name
默认情况下,如果没有为启动的容器指定名称,Docker Compose 会自动为每个容器生成一个唯一的名称,格式通常是
<projectname>_<servicename>_<num>
<projectname>
是 Docker Compose 项目名称(默认是当前目录名)<servicename>
是在docker-compose.yml
文件中定义的服务名称<num>
是一个序号,用于区分同一服务启动的多个实例
在 docker-compose.yml
文件中,container_name
关键字用于为启动的容器指定一个自定义名称
services:
web:
image: nginx:1.27.3
container_name: my_custom_nginx
ports:
- "80:80"
关于 container_name
的注意事项:
- 如果指定了
container_name
,则不能在同一个 Docker Compose 项目中启动该服务的多个实例,因为容器名称必须是唯一的 - 使用
container_name
会使你的 Docker Compose 项目不那么可移植,因为如果其他人在相同的主机上运行相同的项目,可能会遇到容器名称冲突的问题 - 使用
container_name
时要小心,并确保它适用于你的特定场景。在大多数情况下,让 Docker Compose 自动生成容器名称是更好的做法
2.2.4 restart
在 docker-compose.yml
文件中,restart
配置选项用于指定容器重启的策略。当容器退出时,Docker Compose 会根据这个策略决定是否重启容器。以下是 restart
的一些常见值:
no
: 是默认值,表示容器退出后不会自动重启always
: 无论容器退出状态如何,总是重启容器on-failure
: 只有当容器以非0状态码退出时才重启容器。可以指定重启的次数unless-stopped
: 只有当容器被手动停止时才不会重启,否则总是重启容器
services:
web:
image: nginx:1.27.3
ports:
- "80:80"
restart: always
在这个例子中,无论 Nginx 容器何时退出,它都会被 Docker Compose 自动重启
如果你想要容器在失败时尝试重启,但不超过一定的次数,可以这样配置:
services:
web:
image: nginx:1.27.3
ports:
- "80:80"
restart: on-failure:10
在这个例子中,如果 Nginx 容器以非0状态码退出,Docker Compose 将尝试重启它,但最多不超过10次
2.2.5 ports
在 docker-compose.yml
文件中,ports
关键字用于配置容器与宿主机之间的端口映射
services:
web:
image: nginx:1.27.3
ports:
- "80:80" # 将宿主机的80端口映射到容器的80端口
2.2.6 depends_on
- 需要注意的是,
depends_on
只确保依赖的服务在当前服务之前启动,而不会等待依赖的服务“就绪”才启动当前服务- 这意味着,即使依赖的服务已经启动,它们可能还没有完全准备好接受连接或处理请求
depends_on
是 docker-compose.yml
文件中的一个指令,用于指定服务之间的依赖关系
当定义一个服务时,可以使用 depends_on
来告诉 Compose 某一个服务应该在哪一个启动之后再启动
services:
app:
image: myapp:latest
depends_on:
- db
networks:
- mynetwork
db:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: rootpassword
networks:
- mynetwork
networks:
mynetwork:
2.2.7 environment&env_file
在 docker-compose.yml
文件中,environment
关键字用于定义服务运行时的环境变量。这些环境变量可以在容器内部被应用程序读取,以影响其行为
2.2.7.1 使用列表形式
services:
web: # 定义一个服务名称为 web
image: nginx:1.27.3 # 指定服务使用的镜像
environment: # 定义环境变量
- NGINX_HOST=example.com # 设置单个环境变量
- NGINX_PORT=8080 # 设置另一个环境变量
- DEBUG=true # 设置布尔值环境变量
2.2.7.2 使用字面量字典形式
services:
web:
image: nginx:1.27.3
environment:
NGINX_HOST: example.com
NGINX_PORT: "8080"
DEBUG: "true"
2.2.7.3 使用环境文件(env_file)
如果你有大量的环境变量,可以将它们放在一个环境变量文件中,并在 docker-compose.yml
中引用该文件:
services:
web:
image: nginx:1.27.3
env_file:
- web.env # 引用名为 web.env 的环境变量文件
web.env
文件的内容如下:
NGINX_HOST=example.com
NGINX_PORT=8080
DEBUG=true
2.2.7.4 结合使用 environment 和 env_file
可以同时使用 environment
和 env_file
来设置环境变量,其中 environment
中的变量会覆盖 env_file
中的同名变量
services:
web:
image: nginx:latest
environment:
- DEBUG=true
env_file:
- web.env
在这个例子中,如果 web.env
文件中也定义了 DEBUG
变量,那么 environment
中的 DEBUG
变量将覆盖它
2.3 网络(networks)
如果不需要为网络指定任何特殊配置,可以简单地列出网络名称,网络将会使用默认的
bridge
驱动
网络(networks
)部分是 docker-compose.yml
文件的可选配置项之一,它允许你定义和配置自定义网络,这些网络可以被你的服务(services)使用
networks:
- some-network
- another-network
在服务定义中,可以通过 networks
选项指定服务应该连接到哪些网络
services:
web:
image: nginx:1.27.3
networks:
- some-network
- another-network
2.4 数据卷(volumes)
在 docker-compose.yml
文件中,volumes
部分用于定义 Docker 数据卷,这些数据卷可以用于持久化容器中的数据
volumes:
web-data:
logs:
在服务定义中,可以通过 volumes
选项指定服务哪个目录需要挂载哪个数据卷
services:
web:
image: nginx:1.27.3
volumes:
- web-data:/var/www/html
- logs:/var/log/nginx
3. 常用的DockerCompose命令
3.1 启动服务(docker-compose up)
docker-compose up
- 启动所有定义在
docker-compose.yml
文件中的服务 - 默认情况下,该命令会在前台运行,并显示日志输出
后台运行:如果你想让服务在后台运行,可以加上 -d
参数:
docker-compose up -d
3.2 停止服务(docker-compose down)
docker-compose down
停止并移除所有由 docker-compose up
启动的容器
3.3 查看正在运行的服务(docker-compose ps)
docker-compose ps
列出所有由 docker-compose
管理的容器及其状态
3.4 查看日志(docker-compose logs)
docker-compose logs
查看所有服务的日志输出
如果只想查看某个特定服务的日志,可以指定服务名称:
docker-compose logs <service_name>
实时查看日志:使用 -f
参数可以实时跟踪日志输出:
docker-compose logs -f
3.5 停止正在运行的容器(docker-compose stop)
docker-compose stop
停止正在运行的容器,但不会删除它们。可以使用 docker-compose start
再次启动这些容器
如果想停止某个特定服务,可以指定服务名称:
docker-compose stop <service_name>
3.6 启动已经停止的容器(docker-compose start)
启动已经停止的容器
docker-compose start
如果想启动某个特定服务,可以指定服务名称:
docker-compose start <service_name>
3.7 重启服务(docker-compose restart)
重启所有服务
docker-compose restart
如果你想重启某个特定服务,可以指定服务名称:
docker-compose restart <service_name>
3.8 列出所有服务(docker-compose images)
列出所有由 docker-compose
管理的镜像
docker-compose images
4. 完整的docker-compose.yml示例
基于 WordPress 和 MySQL 搭建一个博客系统
4.1 编写docker-compose.yml文件
services:
# WordPress 服务
wordpress-6.7.2:
image: wordpress:6.7.2
container_name: wordpress-6.7.2
restart: always
ports:
- "9090:80" # 将主机的 9090 端口映射到容器的 80 端口
environment:
WORDPRESS_DB_HOST: mysql-8.0.32:3306 # 数据库主机地址(使用服务名)
WORDPRESS_DB_USER: wp_user # 数据库用户名
WORDPRESS_DB_PASSWORD: wp_password # 数据库密码
WORDPRESS_DB_NAME: wp_database # 数据库名称
volumes:
- wordpress_data:/var/www/html # 挂载 WordPress 的数据目录
networks:
- wordpress_network # 加入自定义网络
depends_on: # 确保 MySQL 先启动
- mysql-8.0.32
# MySQL 数据库服务
mysql-8.0.32:
image: mysql:8.0.32 # 使用 MySQL 8.0.32 版本
container_name: mysql-8.0.32
restart: always
environment:
MYSQL_ROOT_PASSWORD: root_password # MySQL root 用户密码
MYSQL_DATABASE: wp_database # 创建的数据库名称
MYSQL_USER: wp_user # 创建的数据库用户
MYSQL_PASSWORD: wp_password # 数据库用户的密码
volumes:
- mysql_data:/var/lib/mysql # 挂载 MySQL 数据目录
networks:
- wordpress_network # 加入自定义网络
# 定义卷
volumes:
wordpress_data: # 用于存储 WordPress 的数据
mysql_data: # 用于存储 MySQL 的数据
# 定义网络
networks:
wordpress_network: # 自定义网络,用于连接 WordPress 和 MySQL
driver: bridge # 使用桥接网络
4.2 启动服务
wordpress
镜像和mysql
镜像较大,下载耗时可能较长
docker-compose up -d
4.3 开放防火墙的 9090 端口
- 如果你使用的是云服务器,请在安全组中放行 9090 端口
- 如果你安装了宝塔,除了在安全组中放行 9090 端口,可能还要在宝塔中放行 9090 端口
4.4 访问博客系统
不得不说,WordPress 不仅界面丑,而且用起来也很不顺手
在浏览器输入以下地址,就可以访问博客系统了(记得更改 IP 地址)
http://127.0.0.1:9090
填写完一些必要的信息后点击安装WordPress
(默认界面是英文的,可以使用浏览器的翻译功能)
最后点击Log in
输入刚才填写的用户名和密码
看到以下界面,就说明成功了
4.4.1 修改默认语言
界面默认是英文的,我们可以改成中文
选择完语言后,点击保存配置,页面就会变成中文了
4.4.2 修改时区
在设置的常规项中找到时区
选择上海
最后点击保存更改