熟悉我的友友都知道我经常折腾NAS,而我属于也在NAS部署了很多自托管的服务,这其中Docker是必不可少的。不同的NAS系统针对Docker有不同的解决方案,而Docker Compose是目前适用性最广泛额一个。
标签说明
Docker Compose 配置文件是 YAML 格式的,通常是 docker-compose.yml 或 compose.yaml 文件。顶级标签定义了整个应用的服务、网络、存储卷等配置。以下是 Docker Compose 配置文件中常见且重要的顶级标签名称及其功能列表。这个列表是基于 Compose 规范(Compose Specification)的,它取代了旧版本的 v2 和 v3 格式,是现阶段推荐和广泛使用的标准。
version (已废弃) | (在较新的 Compose 规范中已不推荐使用) 在旧的 Compose 文件格式(v2 和 v3)中用于指定配置文件版本。现在使用 Compose 规范时,此字段通常被省略或仅用于向后兼容。 | 旧版本 |
services | 定义应用中的所有服务。 每个服务条目(如您提到的 image、container_name 等)都作为这个键下的子配置。这是 Compose 文件的核心部分。 | 必选 |
volumes | 定义命名存储卷(Named Volumes)。 这些存储卷可以在不同的服务之间共享,并且独立于容器的生命周期。 | 可选 |
networks | 定义自定义网络。 允许服务连接到特定的网络,以便相互通信或与外部网络通信。 | 可选 |
configs | 定义配置数据(Config Data)。 允许服务访问敏感或非敏感的配置数据,通常用于应用配置。 | 可选 |
secrets | 定义敏感数据(Secrets)。 允许服务安全地访问敏感信息,如密码或 API 密钥。 | 可选 |
include | 包含其他 Compose 文件。 允许将配置拆分为多个文件,便于管理和复用。 | 可选 |
name | 指定项目名称。 用于覆盖目录名称作为项目名称的默认行为。 | 可选 |
这些顶级标签中,服务标签(services) 是构建容器必不可少的,在其下也有很多常用的子标签。
image | 指定构建容器所使用的镜像。 可以是 Docker Hub 上的公共镜像,也可以是私有仓库或本地镜像。 |
build | 定义如何构建镜像。 如果不使用现有的 image,则用此指定 Dockerfile 路径和构建上下文。 |
container_name | 为容器指定一个固定的名称。 默认情况下 Compose 会生成一个名称(如 projectname-servicename-1)。 |
ports | 发布容器的端口到主机。 格式通常是 主机端口:容器端口。 |
volumes | 挂载存储卷或主机路径到容器。 用于数据持久化或共享主机文件。格式可以是 主机路径:容器路径 或 卷名称:容器路径。 |
environment | 设置容器中的环境变量。 可以是键值对列表或文件引用。 |
env_file | 从文件中添加环境变量。 |
networks | 指定服务应连接到哪些网络。 |
depends_on | 定义服务之间的依赖关系。 确保依赖的服务在当前服务启动前启动。 |
restart | 定义容器退出时的重启策略。 例如 always, on-failure, unless-stopped。 |
command | 覆盖容器启动时执行的默认命令。 |
entrypoint | 覆盖容器的默认入口点。 |
labels | 添加自定义元数据(标签)到容器。 |
healthcheck | 定义一个检查容器健康状态的命令。 |
logging | 配置服务的日志驱动和选项。 |
deploy | 指定部署和运行时约束(主要用于 Swarm 模式)。 |
样例
为了方便理解,我用两个样例来做说明。我会在每个标签旁边使用 # 符号添加注释(说明)。
以下这个示例展示了通过单个容器配置一个独立的 Web 服务器容器(使用 Nginx 镜像)的方案。
# Compose 文件的顶级配置键(标签)
# 推荐在新的 Compose 文件中省略 'version' 键,以遵循最新的 Compose 规范。
# 如果需要向后兼容,可以添加如下(但不再推荐):
# version: '3.8'
# 核心标签:定义应用中的所有服务
services:
# 服务名称:可以是任何你想要的名字,它作为网络别名
web_server:
# 服务子标签:
# 指定构建容器所使用的镜像
image: nginx:latest
# 为容器指定一个固定的名称
container_name: my_single_nginx_container
# 挂载存储卷或主机路径到容器
# 格式:[主机路径或卷名称]:[容器内部路径]
volumes:
# 挂载本地的 ./html 目录到容器的 Nginx 默认网页目录
- ./html:/usr/share/nginx/html:ro
# 发布容器的端口到主机
# 格式:[主机端口]:[容器端口]
ports:
# 将容器的 80 端口映射到主机的 8080 端口
- "8080:80"
# 设置容器中的环境变量
environment:
# 这是一个示例环境变量
- TIMEZONE=Asia/Shanghai
# 定义容器退出时的重启策略
# 'unless-stopped' 表示除非手动停止,否则容器退出时都会重启
restart: unless-stopped
# 添加自定义元数据(标签)到容器
labels:
- "com.example.description=Single Nginx Web Server"
# 顶级标签:定义命名存储卷(如果需要)
# 在这个单容器示例中,我们使用了主机挂载,所以 volumes 标签可以省略。
# volumes:
# my_data:
# 顶级标签:定义自定义网络(如果需要)
# 在这个单容器示例中,Compose 会使用默认的 bridge 网络。
# networks:
# default:
# driver: bridge
这个示例则是通过多个容器配置一个 Web 应用程序(使用 Node.js 示例)和一个数据库(使用 PostgreSQL),并配置它们之间的依赖和通信的方案。
# Compose 文件的顶级配置键(标签)
# 核心标签:定义应用中的所有服务
services:
# 服务一:Web 应用程序
app_service:
# 服务子标签:
# 指定如何构建镜像(从 Dockerfile 构建)
# 'context' 指定 Dockerfile 所在的目录,'dockerfile' 指定 Dockerfile 文件名
build:
context: .
dockerfile: Dockerfile.app
# 为容器指定一个固定的名称
container_name: web_app_container
# 发布容器的端口到主机
# 将容器的 3000 端口映射到主机的 3000 端口
ports:
- "3000:3000"
# 设置容器中的环境变量
environment:
# 连接数据库所需的环境变量
- DB_HOST=db_service # 使用服务名称作为主机名进行连接
- DB_PORT=5432
- DB_USER=user
- DB_PASSWORD=secret
# 定义服务之间的依赖关系
# 确保 db_service 容器启动并运行后才启动 app_service
depends_on:
db_service:
condition: service_started
# 指定服务应连接到哪些网络
networks:
- internal_network
- public_network
# 服务二:数据库服务
db_service:
# 服务子标签:
# 指定使用的数据库镜像
image: postgres:14-alpine
# 为容器指定一个固定的名称
container_name: postgres_db_container
# 挂载存储卷到容器
volumes:
# 使用命名存储卷进行数据持久化,确保数据在容器重启后不会丢失
- postgres_data:/var/lib/postgresql/data
# 从文件中添加环境变量(更安全的方式来管理密码)
# 假设存在一个名为 .env.db 的文件,包含 POSTGRES_USER 等变量
env_file:
- .env.db
# 定义容器退出时的重启策略
restart: always
# 指定服务应连接到哪些网络
# 注意:数据库服务通常不直接暴露到公网,只连接内部网络
networks:
- internal_network
# 顶级标签:定义命名存储卷
volumes:
# 定义一个名为 'postgres_data' 的卷
postgres_data:
# 可以指定驱动和选项,这里使用默认驱动
driver: local
# 顶级标签:定义自定义网络
networks:
# 定义一个内部使用的网络,供 app 和 db 通信
internal_network:
driver: bridge
# 定义一个可能需要对外连接的网络
public_network:
driver: bridge
NAS中使用
目前来说各个主流的NAS系统都支持Docker Compose,根据自己的需要找到对应项目的Docker Compose,复制粘贴到NAS中的Docker Compose,并根据自己的具体情况编辑一下中即可。
需要特别说明的是在自己的NAS中使用时,修改Docker Compose文件中的路径。前文中提到的 挂载标签volumes 和 变量文件env_file 标签都会涉及到路径设置。大部分NAS系统在添加Docker Compose时都需要设置路径,这个路径就是容器项目在NAS中储存文件的位置。

在Docker Compose文件中,每个标签下的项目用“:”来分割,第一个冒号前的是映射的宿主机端口或地址,第一个冒号后则是容器内的端口或地址,第二个冒号后则是读写权限等设置项。
根据不同的开发者编辑代码习惯不同,映射挂载地址时,有的开发者会写绝对地址,有的则是相对地址,以上面的样例参考:
绝对地址:/volume1/docker/Test/html
相对地址:./html
上面的例子中, html 文件夹是映射挂载的文件夹,前面的“ ./ ”则表示 html 这个文件夹是在 /docker/Test 目录下的。我个人是偏好使用相对路径的,如果容器或docker目录发生位置调整时,不会使容器因目录失联而失效。
另一个就是端口,上面的例子中,是将容器中的80端口映射到宿主机的8080端口上,如果在NAS中有多的Docker容器运行,一定要注意哪些端口已经被占用了,避免在不同的容器中映射了同样的端口,这样也会导致容器无效。