发送文件到 Docker Remote

Docker

之前在 Docker for Windows Path Bind 中解决了 Windows Docker Desktop 使用 -v 参数的错误。
这次遇到了无法把本地文件传递到远程 Docker Host 上的问题,要么提示 invalid mode,要么提示 invalid volume specification

$ docker run -v "./Corefile:/root/Corefile" -it coredns/coredns
docker: Error response from daemon: invalid mode: /root/Corefile
 
$ docker run -v "./Corefile:/root/Corefile:ro" -it coredns/coredns
docker: Error response from daemon: invalid volume specification: 'G:\GitHub\Homelab\Service\CoreDNS\Corefile:/root/Corefile:ro'

其实错误符合预期,毕竟参数是 Host Path,而不是 Local Path。

$ docker run -v /HOST/PATH:/CONTAINER/PATH

回答里给出了好多方法,但只有少数可以用在 Remote 环境。

  1. 构建镜像,Docker BuildKit 会按需向 BuildX 请求文件,能实现本地向远程的传递。但这方式太重了,适合最终使用
  2. 手动上传,docker compose cp 早就可用了,直接复制本地文件到远程,再重启容器。不利于快速迭代,也不适合自动化
  3. 远程挂载,之前搞 Synology NFS 共享设置用户权限 已经吃一壶了,走 SMB 在多平台兼容性比 NFS 好

最后决定 Remote Development。先把本地文件挂载到 Docker Host,然后 Zed 打开远程目录,在那里作本地挂载😄

使用 Systemd 来管理 mount

对 Where 字段的要求真是奇怪,还必须匹配文件名,关键短横线 hyphen 还得转义,不然就报错 Where= setting doesn't match unit name. Refusing.

$ systemd-escape -p --suffix=mount "/mnt/pc/github/"  
mnt-pc-github.mount
[Unit]
Description=Windows 11 hosts on AMD 9700X
Requires=network-online.target
After=network-online.target systemd-resolved.service
Wants=network-online.target systemd-resolved.service
 
[Mount]
What=//amd-9700x-lan/GitHub
Where=/mnt/pc/github
Type=cifs
Options=credentials=/etc/private/samba/amd-9700x.cred,file_mode=0644,dir_mode=0755
TimeoutSec=10
 
[Install]
WantedBy=multi-user.target
[Automount]
Where=/mnt/pc/github
TimeoutIdleSec=300
 
[Install]
WantedBy=multi-user.target

别忘了写 credentials 文件,然后激活它

systemctl daemon-reload
systemctl enable mnt-pc-github.automount
systemctl start  mnt-pc-github.mount
 
ls /mnt/pc/github
systemctl status mnt-pc-github.automount
systemctl status mnt-pc-github.mount