迁移Jellyfin Docker Volume 并打开硬件加速
之前为了方便迁移,Docker Compose部署的Application都尽量采用了 Volume 而不是 Binding的方式处理persistent storage。以为Portainer上面有UI可以方便的迁移Volume。谁知Portainer上面的Stack Migration并不会一并Copy Volume到新的主机。合着似乎只是把Docker compose的内容copy到新主机上面然后部署运行。不过既然用了Volume,那好歹也要用正确的方法迁移文件,而不是直接copy paste。于是就有了一篇日志。(Portainer太让人失望了。)
这里用的例子是 Jellyfin。因为之前在一台主机上面部署了GPU,于是想着先把Jellyfin硬解以及HDR的问题解决了。GPU直通详见:Proxmox 7.4 GPU Passthrough 显卡直通。
首先,在原主机上Jellyfin的部署如下 (stack name: jellyfin
):
version: "3"
volumes:
jellyfin_config:
name: jellyfin_config
media:
external: true
services:
jellyfin:
image: nyanmisaka/jellyfin:230305-amd64
container_name: jellyfin
environment:
- PUID=1000
- PGID=1000
- TZ=America/Vancouver
volumes:
- jellyfin_config:/config
- media:/mnt/media
ports:
- 8096:8096
# - 8920:8920 #optional, for https
#- 7359:7359/udp #optional, local discovery
#- 1900:1900/udp #optional, DLNA
restart: unless-stopped
tty: true
其中 Volume: Media
实际上是一个 Samba share,存实际的媒体文件。而volume: jellyfin_config
是Jellyfin的配置文件以及各种metadata。这里需要迁移的就是这个jellyfin_config
volume。这里 jellyfin_config
实际是给了一个特定的 name
的。这导致这个volume的全名就是 jellyfin_config
而不是 jellyfin_jellyfin_config
(aka <stack_name>_<volumes_key_in_yaml>)。通常这个应该是需要在多个service或者app之间共享volume才需要的。不过这里已经是这样了,就不去纠结了。
sudo docker volume ls
# Should show "jellyfin_config" volume
sudo docker volume inspect jellyfin_config
# Details of the volume, including:
# * Mountpoint: the absolute path of the volume on the docker host machine:
# * /var/lib/docker/volumes/jellyfin_config/_data
# * Labels: should contains the label: '"com.docker.compose.project": "jellyfin"'
单纯使用SCP迁移Volume可能遇到的问题是Permission可能会乱掉,新的文件的ownership以及ACL都有可能因为SCP而被破坏,这在目标机上面重新部署Docker container的时候可能造成很多麻烦。目前来讲比较干净又简单的方式是使用 rsync
。但是因docker volume所在的位置一般都是 /var/lib/docker/volumes/,通常需要root权限,rsync
远程直接从Ubuntu上面搞还真不一定成。这个时候就会想念Debian上面可以打开SSH的Root用户。这里采用的方法是 busybox
。Docker官方的方法太过Heavy,[直接用Ubuntu image](https://docs.docker.com/storage/volumes/#back-up-a-volume),其实用busybox就足够了。
# 假设把backup.tar放在$HOME
sudo docker run --rm \
-v jellyfin_config:/volume-backup-source \
-v $HOME:/volume-backup-target \
busybox sh -c \
'cd /volume-backup-source && tar cf /volume-backup-target/backup.tar . '
# Result: A 'backup.tar' file in $HOME
之后SCP到目标机。目标机上面需要创建这个Volume。因为之前一直用的Portainer,所以这里依旧用Portainer来创建。也可以用 docker create volume <volume_full_name>
来创建。因为Jellyfin用了SAMBA share挂载Media文件,所以这里也需要创建相应的Media volume。
最后用 busybox
container 再把 backup.tar 展开到目标 Volume 上面。
# Assume 'backup.tar' is at $HOME
sudo docker run \
--rm \
-v jellyfin_config:/volume-backup-target \
-v $HOME:/volume-backup-source \
busybox \
sh -c 'cd /volume-backup-target && tar xf /volume-backup-source/backup.tar .'
在新的server上面,还有几个设置需要搞定,是关于Nvidia Docker的支持的。详见“关于Nvidia的Docker支持”章节
之后再在Jellyfin上面把 Jellyfin stack 跑起来就可以了。这次可以添加GPU加速了。(这里假定服务器是 Ubuntu,所以UID GID用的是1000。如果是Debian,一般默认的GID应该是100)