NAS上的Docker Compose是什么?我从一个个点装改成Compose后,容器再没乱过

我家飞牛上跑着九个容器,Jellyfin、qBittorrent、Immich这些。前八个都是我在飞牛Docker界面里装的:点新建容器,名字填一个,镜像填一个,端口映射加一条,目录挂载再加一条,环境变量再补两个,一路点下来,装完一个顺手把参数记在备忘录里。第九个装的时候我没忍住想:这一套动作我重复了八回,参数记的备忘录已经三页了,哪天飞牛升级界面改版,我连自己当时填了什么都对不上。
真正让我下决心换思路的是去年那次断电。来电以后容器全起来了,但Immich的网页一直转圈,查了一晚上才发现是它依赖的postgres数据库容器起晚了,Immich比数据库先跑,直接卡死在那。当时我一个个容器点重启才救回来,第二天就开始把所有容器改成Compose管理。这篇就把Compose到底解决了什么、yml怎么写不容易翻车、以及换机器时怎么搬家,按我的踩坑顺序写清楚。
先说人话:Compose就是给容器写一张配置单
Docker Compose不是什么新容器,它就是把你每次在界面里点的那些参数,写进一个叫compose.yml的文本文件里。端口映射几条、目录挂载几条、环境变量几个、重启策略开不开,全在文件里写着。你把这个文件交给Docker,它照着单子把容器拉起来。
这两个字最大的区别在哪?手动装的容器,参数只存在于Docker自己脑子里,界面上看一眼能瞥到一部分,但想整体搬走或者重新过一遍,得一个个翻。Compose装的容器,参数就在那份yml文件里,我打开文件,九个容器每个吃哪个端口、挂哪个目录,一分钟看完。这文件本身就是备份,我把docker目录整个拷进移动硬盘,机器炸了配置也不丢。
如果你对Docker里端口映射、目录挂载这几个词还发懵,先看这篇飞牛Docker入门,Compose只是把这些动作换了个写法,概念没变。哪些容器该用什么网络模式,bridge和host的区别我在装Home Assistant那篇里拆过,Compose里一样用得上。
我的compose.yml长什么样,三个地方别照抄错
飞牛的Docker管理里新建项目(Compose),把yml贴进去就行,群晖是Container Manager里的项目,一个意思。我拿自己跑的Immich给您剪了个骨架,长这样:
services: immich-server: image: ghcr.io/immich-app/immich-server:release container_name: immich-server restart: unless-stopped ports: - "2283:2283" volumes: - /vol1/1000/docker/immich/library:/usr/src/app/library environment: - DB_PASSWORD=改成你自己的 depends_on: - immich-db 三个最容易抄错的地方。一是目录挂载冒号左边的宿主机路径,用绝对路径写全,别写./library这种相对路径,飞牛上相对路径跟着当时点创建的位置走,哪天目录挪了或重建项目,照片库就挂到别的目录去了,这种错除了重挂没别的救法。二是restart: unless-stopped这行别省,容器崩了Docker会自己拉它起来,断电重启后也跟着开机走。三就是depends_on,这是我上次断电翻车的根源,写上它,Immich会等数据库容器先起来再启动。这套账跟内存那篇是同一路数,九个容器稳态才吃2个G,真正压垮机器的是峰值,感兴趣翻容器内存账。
还有个写yml的小习惯:密码别直接写进文件里。Compose支持把密码放同目录一个.env文件里,yml里只写变量名。我图省事前三个容器都是明文写的,后来想把这个目录同步到我妈家那台备份机才惊出一身汗——明文密码跟着同步走了。改成.env以后,同步时把这一个文件排除掉就行。
更新容器这件事,Compose比手点省一半步骤
手动装的容器想更新,得先停容器、删容器、拉新镜像、再照着备忘录把参数填一遍,填漏一条就是一场事故。我更新Jellyfin那次忘了重新挂转码目录,进去设置全灰了,找回来花了一小时。Compose的更新是三步:拉新镜像、重建容器、完事。
docker compose pull docker compose up -d 第二条命令的意思是「照着yml把该跑的容器都弄成运行状态」。镜像更新了它会把旧容器删掉、用新镜像和同一份配置重建,因为你的数据都在挂载的宿主机目录里不在容器里,重建完数据、账号、设置全在。这也就是为什么目录挂载那条从第一天就要写对——容器本身是随用随扔的,yml加挂载目录才是你真正的家底。容器升级时哪些细节还得手动盯,我在容器怎么升级更新那篇里有更细的清单。
顺带提一句watchtower这种自动更新容器的东西,我装过又卸了。半夜自动把容器全升级听起来爽,但 Immich 这种带数据库的服务一旦新版本改了表结构,自动升级翻车时你在睡觉,早上照片库已经打不开了。家用NAS上的容器,我的原则是重要服务的更新自己点,不重要的才交给自动化。
重启后容器起不来,先看是顺序问题还是路径问题
改成Compose以后断电重来过两次,一次啥事没有,一次又翻车了,正好把两类坑都集齐了。第一类是启动顺序:depends_on只保证「先启动谁」,不保证「等谁真正就绪」。数据库容器起来了但还在初始化,依赖它的容器照样会连不上卡死。Immich这种官方compose文件里数据库带健康检查,照官方的抄最稳。自己写简单服务的yml,没这么讲究,顶多开机后手动重启一下卡住的那个,比我当年一个个点八回强多了。
第二类是路径问题:挂载的宿主机目录在一块USB外接盘上,开机时盘还没挂好,容器先起来发现目录是空的,轻则报错重则把配置初始化一遍。这种情况要么把docker目录挪到内置盘,要么在系统里给外接盘的挂载加等待。USB盘当仓库盘的三个坑我在移动硬盘当仓库盘那篇里写过,靠外接盘跑容器的朋友务必看一眼。重启后容器起不来的完整排查顺序,还有一份三步清单在这篇。
换NAS那晚我才真正觉得Compose值:一晚上搬完九个容器
上个月我把容器从一台老机器迁到新的N100。以前想都不敢想,九个容器一个个点参数,起码一个周末。用Compose之后流程是这样的:新机器装好飞牛,建同样的docker目录结构,把整个docker目录(含各容器的compose.yml和数据)从旧机rsync过来,然后进每个项目目录跑一遍docker compose up -d,镜像自动拉、容器自动建、数据全在挂载目录里跟着来了。我晚上八点开始动手,十一点半九个容器全部在新机器上活了,中间还吃了个饭。
有两样东西Compose搬不走,得手动补。一是容器列表里看到的镜像tag,如果你当时手滑用了latest,新机器拉到的新版可能跟旧版行为有差异,重要服务我后来都改成钉死版本号,比如release改成具体版本。二是.env文件里的密码,如果你像我一样把它排除在同步外,记得单独拷。迁完之后挨个容器打开网页确认一遍,Jellyfin的转码设置、Immich的人脸索引这种存在数据库里的东西,跟着数据目录走,一般不会丢。两台机器之间传文件的几条路和速度对比,我测过记在这篇。
哪些人该换Compose,哪些人先别动
我的建议按人头分。容器三个以上、更新过至少一次、或者经历过断电后手忙脚乱重启的,值得花一个晚上换成Compose,回报是以后每次更新和搬家都省心。容器就一两个、装完再没动过的,别折腾,够用。纯小白先把Docker三个基础词搞明白再说,别跳级。手上跑着重要照片库的,换Compose那天先做一次快照或备份,yml贴错了挂载路径,Immich第一次启动会当自己是新装,把空目录当照片库用,虽然旧数据还在原目录里没丢,但当时吓得我不轻。
最后给个实在的总结:Compose不让你多跑一个容器,也不让机器变快,它只是把你散落在界面点击和备忘录里的配置,收进一份能看、能存、能拷贝的文本文件里。NAS这东西一跑就是几年,中途一定会遇到断电、升级、换机器,早一天把配置收进文件,那些日子就早一天不慌。

发表评论