个人NAS全方位攻略--容器化部署

  • ~2.92K 字

本系列导航:

  1. 需求分析
  2. 安全配置
  3. 容器化部署(当前)
  4. 常用软件

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
2
3
4
5
6
7
services:
your-service:
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"

这样每个容器的日志最多保留3个文件,每个文件最大10MB,不会无限增长。

资源限制

如果你的NAS同时运行多个容器,某个容器如果出现异常(比如内存泄漏),可能会占用大量系统资源,导致其他容器甚至NAS本身运行缓慢。建议在compose文件中为关键容器设置内存和CPU限制:

1
2
3
4
5
6
7
services:
your-service:
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'

这样即使容器失控,也不会影响NAS的整体运行。

6. 容器更新与维护

容器化部署的一个好处是更新方便,但也需要注意正确的方式:

更新镜像

1
2
docker compose pull
docker compose up -d

这两条命令会拉取最新镜像并重新创建容器。旧容器会被自动移除,但通过挂载卷持久化的数据不会丢失。

清理无用资源

长期运行后,Docker会积累大量无用的镜像、容器和网络:

1
docker system prune -a

这条命令会清理所有未被使用的镜像、容器、网络和构建缓存。建议定期执行,释放磁盘空间。-a参数会连同没有容器使用的镜像一起清理,如果你确定没有手动拉取的镜像需要保留,可以放心使用。

备份compose文件

所有容器的配置都写在docker-compose.yml里,这个文件就是你的”容器清单”。确保它和重要数据一起被备份——NAS重装系统后,只要恢复compose文件和挂载数据目录,所有服务就能快速重建。

分享
分享提示信息