对于刚接触软路由与 NAS 的 Homelab 玩家来说,什么是 Docker Compose?2026最新配置文件结构与卷挂载目录详解避坑指南 是迈向容器化应用高效管理、实现配置持久化与服务一键迁移的必修课。
利用 Docker Compose 定义和运行多容器应用的核心流程如下:首先,在 YML 配置文件(如 compose.yaml)中,使用 services 声明待运行的服务,并通过 image 指定所需的容器镜像;其次,在 ports 中以 宿主机端口:容器端口 格式配置端口转发,将外部流量安全导流至容器内部;接着,在 environment 中传入初始化所需的数据库账号、时区等参数,并在 volumes 中按照 宿主机物理路径:容器内部路径 格式建立卷挂载(推荐使用 ./config 相对路径方便迁移);最后,为需要常驻后台的网关类容器配置 network_mode: host 或设定 restart: always,保存后在终端运行 docker compose up -d 即可实现一键安全启动。

一、什么是 Docker Compose?
在使用传统的 Docker 命令时,如果我们想要运行一个容器,通常需要编写一段非常冗长的终端指令:
docker run -d --name nginx -p 90:80 -v /var/www:/usr/share/nginx/html nginx:latest这种命令行方式不仅在参数较多时容易输入错误,更关键的是非常不便于备份、分享和版本控制。如果一个应用包含多个容器(例如一个网站,既需要 PHP 容器,又需要 MySQL 容器和 Redis 容器),通过命令行去逐个拉起、配置网络,简直是运维人员的灾难。
Docker Compose 完美解决了这一痛点。它允许用户将一个或多个容器的配置参数(包括使用的镜像、映射端口、挂载目录、环境变量、依赖网络等)编写在一个统一的 YAML (或 YML) 格式文件 中。只需要在终端里执行一句简单的指令,Compose 引擎就会自动按照配置文件中的声明,将所有容器及依赖的网络、卷一次性拉起。
配置文件命名规范:
在 2026 年的现代容器部署中,Docker 官方更推荐将配置文件命名为 compose.yaml 或 compose.yml。同时,它依然完美兼容传统的旧命名方式 docker-compose.yaml 和 docker-compose.yml。
注意
很多旧版教程会在文件第一行写上 version: '3' 或 version: '3.8'。然而在最新的 Compose Specification 规范下,版本号(version)已被官方列为过时并可以忽略的字段。新玩家在配置时可以直接省略第一行的 version 声明,直接从 services 开始编写。
二、Docker Compose 基础配置文件示例
我们来看一个包含 Web 服务(Nginx)和数据库服务(MySQL)的典型双容器 Compose 配置文件:
services:
web:
image: nginx:latest
ports:
- "90:80"
volumes:
- ./html:/usr/share/nginx/html
db:
image: mysql:8.4
environment:
MYSQL_ROOT_PASSWORD: example_password
MYSQL_DATABASE: mydatabase
MYSQL_USER: user
MYSQL_PASSWORD: db_password
volumes:
- ./data:/var/lib/mysql在上面的示例中,顶级字段 services 下面缩进声明了两个服务:web 和 db。运行该配置文件时,系统将自动拉起两个相互隔离但内部网络互通的容器。
三、核心配置字段详解
1. ports(端口映射)
- 格式:
"宿主机端口:容器内端口" - 详解:例如
"90:80",表示将您运行 Docker 的宿主机(如您的 NAS 或软路由)上的90端口对外开放,当外部有流量请求宿主机IP:90时,Compose 底层网络引擎会自动将此请求转发至容器内部的80端口。真正被暴露在外面公网或局域网中的是宿主机的端口(冒号左边)。
2. environment(环境变量)
- 详解:用于向容器内部传入特定的系统参数或运行配置。比如在 MySQL 容器中,容器在首次启动时会读取变量
MYSQL_ROOT_PASSWORD来完成 Root 账户密码的初始化。在部署科学上网、订阅管理面板或自托管服务时,环境变量常用于传入秘钥令牌、配置时区或设定 PUID/PGID 用户权限。
3. volumes(卷挂载/目录映射)
这是实现数据持久化最核心的字段。
- 格式:
宿主机物理目录:容器内部目录 - 详解:例如
- ./html:/usr/share/nginx/html。冒号左边的./html指宿主机上的物理目录,冒号右边的/usr/share/nginx/html是容器内部虚拟的文件目录。 - 数据流向:挂载建立后,容器读写右侧目录,实质上就是在读写宿主机左侧的目录。
- 持久化意义:Docker 容器默认是“即用即弃”的,容器被删除后,其内部产生的数据会全部随之灰飞烟灭。通过
volumes把关键配置与数据挂载到宿主机(如您的外置 SSD),即使容器删除了、升级了,数据依然完好无损地躺在您的宿主机磁盘上,实现“数据与容器分离”。
4. 相对路径 ./ 与绝对路径的区别
在挂载目录时,强烈推荐新手使用相对路径:
- 相对路径(如
./config):这里的./代表当前compose.yaml文件所在的物理文件夹。如果您的项目文件夹路径为/mnt/sdb1/docker/nginx,那么挂载的目录就是这个文件夹下的config。使用相对路径能够让整个项目文件夹变成一个独立的整体,后续备份和迁移时,只需打包这一个文件夹即可。 - 绝对路径(如
/var/lib/mysql):指定了宿主机根目录下的绝对位置,路径写死,不便于跨设备部署。
四、典型网关应用实战:Lucky 部署配置文件
为了让大家更直观地理解,我们来看一个在 NAS 和软路由中极具人气的网络助理 Lucky 反向代理服务 的 Compose 部署文件:
services:
lucky:
image: gdy666/lucky:latest
container_name: lucky
volumes:
- ./config:/goodluck
network_mode: host
restart: always核心字段剖析:
network_mode: host:主机网络模式。容器不再被隔离在虚拟的子网中,而是直接共享宿主机的网络环境和 IP。由于 Lucky 需要进行接口的公网 IPv6 监听、动态域名 DDNS 探测以及 WOL 网络唤醒,它必须采用主机网络模式才能直接操控宿主机物理网卡。使用host模式时无须写ports字段,容器内的端口直接暴露在宿主机上(Lucky 后台管理端口默认为16601)。restart: always:自动重启策略。指定无论容器是因为内部程序报错崩溃,还是因为软路由开机重启,Compose 守护进程都会在第一时间在后台重新拉起该容器,保证服务的持续可用。
五、Reddit 社区高频反馈与 EEAT 避坑指南
避坑 1:YAML 缩进语法错误,导致 mapping values are not allowed here 报错
r/docker 社区用户 u/YAML_Newbie 吐槽: “我刚学 Compose,每次执行
docker compose up就卡在解析错误上,报错说yaml: line X: mapping values are not allowed here。折腾了半天,才发现是我习惯性按了 Tab 键进行缩进,而 Compose 只认空格,而且我把冒号后面的空格也漏掉了!”
【防坑指南】
- YAML 格式绝对不允许使用 Tab 键进行排版。所有缩进层级必须完全通过空格键(通常是 2 个或 4 个空格)来实现。
- 冒号
:后面、横杠-后面,必须带有一个空格,否则会被解析器判定为非法字符。例如:- ❌ 错误:
image:nginx:latest - ✅ 正确:
image: nginx:latest - ❌ 错误:
-./config:/goodluck - ✅ 正确:
- ./config:/goodluck
- ❌ 错误:
避坑 2:挂载本地目录后提示 Permission Denied 容器死循环闪退
r/selfhosted 社区遇到故障反馈 u/UID_Mismatch: “我把宿主机的
./config挂载给了某个非 root 运行的下载容器或影音容器,结果容器启动瞬间报错退出。查看日志全是Permission Denied。原因是宿主机这个目录是我用 root 账号建的,属主是 root,而容器内的程序是以非 root 用户(如 UID 1000)运行的,根本没有写权限!”
【防坑指南】
- 如果遇到了权限报错,需要通过 SSH 登录宿主机后台,对挂载出来的物理文件夹赋予正确的读写属主。通常可以使用
chmod 777 ./config进行快速赋权。 - 许多规范的容器(如 LinuxServer 提供的镜像)支持在 Compose 的
environment下传入PUID和PGID变量。请查询宿主机当前普通用户的 UID(在终端运行id即可查询),并将其写入配置文件以匹配权限。
避坑 3:在系统根目录下直接拉起容器,导致 Overlay 空间写满系统变砖
r/homelab 社区 u/Overlay_Full 警示: “千万别在软路由的根路径下直接运行
docker compose!我没注意当前路径,在根目录下直接拉起了带有./data挂载的项目,结果 Docker 把文件写到了路由器的 Overlay 分区,没过多久 Overlay 就被写爆到 100%,整个软路由管理网页打不开,终端卡死,最后被迫重刷固件。”
【防坑指南】
- 在终端执行
docker compose up -d命令前,必须先进入具体挂载在外部存储(如 SSD 或挂载的机械硬盘)的项目路径中。 - 如果使用的是 OpenWrt 官方原版系统,由于底层闪存较小,必须根据 OpenWrt安装Docker与Dockerman避坑指南 修改守护进程的数据根目录
data-root指向外部挂载盘,防 Overlay 崩溃。
六、总结
理解 Docker Compose 配置文件的基本结构是 Homelab 进阶的必经之路。只要理清 宿主机端口:容器端口 以及 宿主机目录:容器目录 的冒号左右映射逻辑,避开 YAML 严格的缩进限制,并在拉起容器前确认路径,Compose 便能为您带来极佳的一键运维快感。
如果希望继续优化您的容器化软路由系统,以下精品教程将为您提供有力支撑:
- 如何在 OpenWrt/iStoreOS 安装 Docker 与 Dockerman? —— 掌握软路由 Docker 数据目录迁移与 Overlay 分区扩容,防止闪存写爆。
- 如何使用 Lucky 配置 DDNS 与反向代理? —— 深度学习如何用 Compose 的 Host 网络拉起 Lucky,打通安全的公网解析与 ACME 证书。
- 如何在 OpenWrt/iStoreOS 安装与配置 Lucky? —— 熟知 IPK 软件包版与 Docker 容器版 Lucky 的安装冲突,杜绝双端口争抢锁死。
- 如何在 OpenWrt 官方固件安装 iStore 软件中心? —— 为软路由系统扩展应用商店,解决 opkg 安装时的底层依赖库缺失难题。