远程DockerNAS部署Skill remote-docker-nas

这个技能用于通过SSH在远程NAS或服务器上运行和管理Docker容器,无需本地Docker守护进程。它使用crane工具拉取镜像为tar包,并支持在网络受限环境下的轻量级部署。关键词:Docker、NAS、SSH、crane、远程部署、DevOps、容器化、云计算。

Docker/K8s 0 次安装 0 次浏览 更新于 3/12/2026

name: remote-docker-nas description: 当在远程NAS或服务器上通过SSH运行Docker容器时使用,无需本地Docker守护进程,当远程主机无法从Docker Hub拉取镜像时,或当设置一个轻量级的笔记本电脑到NAS的Docker工作流程时使用crane。

远程Docker在NAS上

概述

通过SSH从您的笔记本电脑控制,在远程NAS/服务器上运行Docker——无需本地Docker守护进程。使用crane(约11MB)拉取镜像为tar包,并使用DOCKER_HOST=ssh://将命令发送到远程守护进程。

架构

笔记本电脑(控制平面)                NAS/服务器(执行)
──────────────────────                ────────────────────────
docker-compose.yml(本地)            Docker守护进程
Makefile(本地)              ──SSH──▶ 容器在此运行
源代码(本地)                   数据存储在此处
crane pull → .tar(本地)            docker load → 镜像在此处

前提条件

笔记本电脑:

  • crane — 轻量级镜像拉取器,无需守护进程
    brew install crane
    
  • docker 仅CLI(无需Docker Desktop / OrbStack)
  • SSH访问NAS(配置~/.ssh/config

NAS/服务器:

  • Docker守护进程运行中
  • 您的用户加入docker
    sudo usermod -aG docker <nas-user>
    # 注销并重新登录以使组生效
    # 验证:groups | grep docker
    

设置

设置DOCKER_HOST以通过SSH路由所有docker命令:

export DOCKER_HOST=ssh://<nas-host>

# 验证
docker info

添加到shell配置文件中以持久化:

# ~/.zshrc 或 ~/.bashrc
export DOCKER_HOST=ssh://<nas-host>

镜像工作流程

当NAS无法访问Docker Hub(防火墙/网络)时,在笔记本电脑上用crane拉取镜像并加载到NAS:

# 1. 拉取镜像为tar包(在笔记本电脑上运行,无需守护进程)
crane pull nginx:alpine /tmp/nginx-alpine.tar

# 2. 加载到NAS(DOCKER_HOST通过SSH路由此命令)
docker load -i /tmp/nginx-alpine.tar

# 3. 运行
docker run -d --name web -p 8080:80 nginx:alpine

关键注意事项

方面 行为
Compose文件 笔记本电脑读取(本地路径)
卷路径 NAS文件系统挂载(必须是NAS的绝对路径)
源文件 必须通过scp复制到NAS,然后运行compose up
端口绑定 端口绑定在NAS IP上,通过http://<nas-ip>:<port>访问

最常见的错误: 使用相对卷路径如./html:/usr/share/nginx/html。这在NAS上解析,而不是您的笔记本电脑。使用NAS的绝对路径。

Docker Compose模板

services:
  web:
    image: nginx:alpine
    ports:
      - "8888:80"
    volumes:
      - /home/<nas-user>/project/html:/usr/share/nginx/html:ro
    restart: unless-stopped

部署工作流程:

# 1. 复制源文件到NAS
scp -r ./html <nas-host>:/home/<nas-user>/project/

# 2. 拉取并加载镜像
crane pull nginx:alpine /tmp/nginx-alpine.tar
docker load -i /tmp/nginx-alpine.tar

# 3. 启动(compose文件本地,执行远程)
docker compose up -d

Makefile模板

DOCKER_HOST := ssh://<nas-host>
NAS_PROJECT := /home/<nas-user>/project
export DOCKER_HOST

IMAGES := nginx:alpine

.PHONY: pull load sync up down ps logs clean

pull:
	@for img in $(IMAGES); do \
		echo "Pulling $$img..."; \
		crane pull $$img /tmp/$$(echo $$img | tr '/:' '-').tar; \
	done

load:
	@for img in $(IMAGES); do \
		tarfile=/tmp/$$(echo $$img | tr '/:' '-').tar; \
		echo "Loading $$tarfile..."; \
		docker load -i $$tarfile; \
	done

sync:
	scp -r ./html <nas-host>:$(NAS_PROJECT)/

up: pull load sync
	docker compose up -d

down:
	docker compose down

ps:
	docker compose ps

logs:
	docker compose logs -f

clean: down
	docker compose rm -f
	docker image prune -f

参考堆栈

references/目录中的即用型compose文件。用您的值替换<nas-host><nas-user>

堆栈 文件 端口 描述
Nginx Proxy Manager nginx-reverse-proxy.yml 80, 443, 81 带有SSL终止和Web UI的反向代理
FreshRSS freshrss.yml 8280 带有PostgreSQL后端的RSS feed聚合器
BookLore booklore.yml 6060 用于EPUB/PDF/CBZ的数字图书馆,带自动元数据
Telegram Bot telegram-bot.yml 运行24/7的Python机器人,自定义Dockerfile

快速部署任何堆栈:

# 示例:部署FreshRSS
crane pull freshrss/freshrss:latest /tmp/freshrss.tar
crane pull postgres:16-alpine /tmp/postgres-16-alpine.tar
docker load -i /tmp/freshrss.tar
docker load -i /tmp/postgres-16-alpine.tar
docker compose -f references/freshrss.yml up -d

多服务架构(推荐用于生产):

Nginx Proxy Manager (:80/:443)
  ├── FreshRSS    → localhost:8280
  ├── BookLore    → localhost:6060
  └── 其他应用   → localhost:XXXX

故障排除

问题 原因 修复
docker套接字上permission denied 用户未加入docker sudo usermod -aG docker <user> + 重新登录
组已添加但仍拒绝 会话未刷新 注销并重新登录,或使用newgrp docker
拉取时connection reset by peer NAS无法访问Docker Hub 使用crane pull + docker load工作流程
卷上403 Forbidden NAS上文件不存在 先用scp复制文件到NAS
port already in use 该端口有其他服务 更改端口映射或停止冲突服务
通过SSH时sudo需要密码 未分配TTY 使用ssh -t进行交互式操作,或将用户加入docker组