本系列导航:
Docker基础知识请参考菜鸟教程,这里不再赘述。本章只讨论在NAS场景下使用Docker时需要了解的实践内容。
1. 使用Docker Compose管理容器
如果你曾经在命令行里用docker run启动过容器,你应该体验过那种痛苦——参数又长又多,每次都要翻历史记录才能拼出完整的启动命令。更麻烦的是,当你需要在一台新机器上重建这些容器时,如果没有把命令记录下来,几乎不可能还原出完全一致的配置。
Docker Compose解决的就是这个问题。它用一个YAML文件声明式地定义所有容器的配置——镜像、端口、挂载卷、环境变量、依赖关系等,然后通过docker compose up -d一条命令启动所有服务。相比纯命令行方式,它有几个明显的优势:
- 配置可读可维护:YAML文件结构清晰,一眼就能看出每个容器的配置
- 可版本控制:把compose文件放进Git仓库,配置的任何变更都有记录,随时可以回滚
- 一键启停:
docker compose up -d启动,docker compose down停止并清除,不再需要记住每条docker run命令 - 依赖管理:可以定义容器之间的启动顺序和依赖关系,确保服务按正确的顺序启动
在NAS上部署服务时,建议所有容器都通过Docker Compose来管理。为每个服务创建一个独立的目录,存放docker-compose.yml和相关配置文件,这样即使NAS重装了系统,只要把compose文件和挂载的数据目录备份好,就能快速恢复所有服务。
2. 数据持久化
Docker容器本身是临时的——容器被删除后,容器内部的所有数据都会丢失。因此,所有需要持久保存的数据都必须通过挂载卷(Volume)或绑定挂载(Bind Mount)映射到宿主机上。
两种方式的区别:
- 绑定挂载(Bind Mount):直接将宿主机的某个目录映射到容器内。比如把NAS上的
/data/nextcloud挂载到容器内的/var/www/html。优点是直观,你可以直接在NAS的文件系统中看到和管理这些文件 - Docker卷(Volume):由Docker管理存储,数据存放在
/var/lib/docker/volumes/下。优点是Docker帮你管理存储位置,移植时更方便,但文件在NAS的文件系统中不太容易直接找到
在NAS场景下,推荐使用绑定挂载,原因很简单:你能直接看到数据在哪里,备份和迁移都很方便。
需要注意的一个坑是文件权限问题。容器内运行的用户和宿主机上的用户可能不是同一个UID,导致容器内创建的文件在宿主机上没有读写权限。解决方法是在compose文件中通过user参数指定运行用户,或者在宿主机上调整挂载目录的权限。
3. 网络配置
Docker容器默认使用bridge网络,每个容器有自己独立的IP地址,容器之间通过容器名互相访问。但在NAS场景下,网络配置有几个容易踩的坑:
不要随意使用host网络模式
很多教程为了让配置简单,会推荐使用network_mode: host,让容器直接使用宿主机的网络栈。这样确实省去了端口映射的麻烦,但代价是容器失去了网络隔离——容器可以直接访问宿主机的所有网络端口,其他容器和服务的端口也可能被占用导致冲突。在同一个NAS上运行多个容器时,host网络模式很容易引发端口冲突问题。
正确做法是使用默认的bridge网络,通过ports参数只暴露需要外部访问的端口。容器间通信直接使用容器名即可,Docker内建的DNS会自动解析。
端口不要冲突
每个需要外部访问的容器都要映射一个宿主机端口。部署新容器前,先确认要映射的端口没有被其他服务占用,避免启动失败。建议为常用的服务约定固定的端口范围,避免后续冲突。
4. 安全与权限
不要使用–privileged
--privileged参数会赋予容器几乎等同于宿主机的完整权限——包括访问所有设备、修改系统配置等。这在很多教程中作为”万能解决方案”出现,但它完全打破了容器的隔离机制。如果一个容器被入侵,攻击者相当于直接拿到了你NAS的root权限。
如果某个容器确实需要访问特定设备(如USB设备),应该使用--device参数精确指定,而不是一上来就给全部权限。
以非root用户运行
默认情况下,容器内的进程以root身份运行。虽然容器有一定的隔离,但这仍然是不必要的安全风险。很多官方镜像都提供了非root运行的方式,在compose文件中通过user参数指定即可。
最小化端口暴露
只映射服务实际需要的端口,不要为了图方便把所有端口都暴露出来。内部服务(如数据库)不需要对外暴露,只允许同一网络内的其他容器访问即可。
5. 日志与资源管理
日志膨胀
Docker容器的日志默认没有大小限制,长期运行的容器日志会持续增长,最终可能撑满你的系统盘。这是NAS上非常常见的”磁盘空间神秘消失”的原因。
建议在compose文件中为每个容器配置日志驱动限制:
1 | services: |
这样每个容器的日志最多保留3个文件,每个文件最大10MB,不会无限增长。
资源限制
如果你的NAS同时运行多个容器,某个容器如果出现异常(比如内存泄漏),可能会占用大量系统资源,导致其他容器甚至NAS本身运行缓慢。建议在compose文件中为关键容器设置内存和CPU限制:
1 | services: |
这样即使容器失控,也不会影响NAS的整体运行。
6. 容器更新与维护
容器化部署的一个好处是更新方便,但也需要注意正确的方式:
更新镜像
1 | docker compose pull |
这两条命令会拉取最新镜像并重新创建容器。旧容器会被自动移除,但通过挂载卷持久化的数据不会丢失。
清理无用资源
长期运行后,Docker会积累大量无用的镜像、容器和网络:
1 | docker system prune -a |
这条命令会清理所有未被使用的镜像、容器、网络和构建缓存。建议定期执行,释放磁盘空间。-a参数会连同没有容器使用的镜像一起清理,如果你确定没有手动拉取的镜像需要保留,可以放心使用。
备份compose文件
所有容器的配置都写在docker-compose.yml里,这个文件就是你的”容器清单”。确保它和重要数据一起被备份——NAS重装系统后,只要恢复compose文件和挂载数据目录,所有服务就能快速重建。