Docker 远程直连部署 (Windows -> Linux)
文档目标: 记录从本地 Windows (Docker Desktop) 环境,通过 Docker Context 机制直接操控远程 Ubuntu 服务器 (PVE) 的完整工作流。彻底告别传统 docker save 导出镜像、SCP 传输、再 docker load 导入的繁琐流程。
不使用远程直连部署(借助1Panel\宝塔) :
本地打包生成镜像:
docker buildx build --platform linux/amd64 -t app_name .将镜像保存在项目根目录
docker save -o app_name.tar app_name将镜像文件app_name.tar上传到服务器项目目录,另外同时上传docker-compose.yml和.env。 使用1Pannel容器编排,实例化容器并启动。
一、 核心原理解析
使用 Docker Context 远程直连的核心在于:代码在本地,算力在云端。 本地 Docker 客户端不再负责执行容器,而是将本地的构建上下文(代码、Dockerfile等)通过 SSH 通道流式传输给远程服务器,由服务器端的 Docker 引擎完成拉取、编译和运行。
二、 标准配置流程(最佳实践)
1. 配置 SSH 免密登录(⚠️ 极其关键)
Docker 的远程构建通道无法良好处理需要手动输入密码的交互提示。如果未配置免密,构建过程极易在 Transferring context 阶段卡死。
在 Windows 本地终端执行:
DOS
# 1. 生成密钥(一路回车即可)
ssh-keygen -t ed25519
# 2. 将公钥推送到远程服务器(替换为实际的用户名和 IP)
type C:\Users\Administrator\.ssh\id_ed25519.pub | ssh root@192.168.1.100 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
# 3. 测试免密登录(应该直接进入 Ubuntu,无需输入密码)
ssh root@192.168.1.1002. 创建并切换 Docker 远程上下文
告诉本地 Docker Desktop 接管远程服务器。
DOS
# 1. 创建远程 Context
docker context create root-remote --docker "host=ssh://root@192.168.1.100"
# 2. 切换当前使用的 Context
docker context use root-remote
# 3. 验证是否接管成功(查看 Operating System 是否变为 Ubuntu)或者 docker ps
docker info
# 切换回本地环境
docker context use default随着你管理的服务器变多,你可能会创建多个远程 Context。你可以随时使用下面这行命令来查看当前所有的环境列表:
docker context ls输出示例:
Plaintex
NAME TYPE DESCRIPTION DOCKER ENDPOINT
default * moby Current DOCKER_HOST based configuration npipe:////./pipe/docker_engine
root-remote moby ssh://root@192.168.1.100注意看:列表里带星号 * 的那个,就是你当前正在使用的环境。
3. 配置 .dockerignore 排除庞大文件
为了保证 SSH 传输极速,必须在项目根目录创建 .dockerignore,排除无关环境和打包文件,防止 SSH 通道因传输大文件而拥堵甚至崩溃。
Plaintext
.git
.env
*.tar
*.tar.gz
__pycache__/
.venv/
.uv/
data/
logs/4. 一键构建与部署
如果只有Dockerfile文件
现在你只需要像往常一样在本地执行命令,一切都会在远程服务器上发生:
Bash
# 在本地代码目录下执行,会将本地代码上下文发送到远程进行构建
docker build -t my-app:latest .
# 在远程服务器上启动容器
docker run -d -p 8080:8080 --name my-app-container my-app:latest推荐写好 ocker-compose.yml
在项目根目录下执行以下命令,Docker 会自动将代码同步至远端并启动服务:
DOS
docker-compose up -d --build(如果需要强制无缓存更新代码,可先执行 docker-compose build --no-cache)
docker build+docker run(命令驱动): 你需要把所有的配置(端口映射-p、数据卷挂载-v、环境变量-e、网络--network等)全部写在命令行里。如果配置很多,这行命令会变得又长又难记。一旦终端关了或者历史记录清了,下次启动你可能就忘了参数是什么。docker-compose(文件驱动/基础设施即代码): 所有的启动参数、环境配置都被固定写在了一个docker-compose.yml文件中。团队里的任何一个人拿到代码,只需要敲一行docker-compose up -d --build,就能保证跑出来的环境和你一模一样。
三、 常见踩坑与解决方案记录
坑 1:路径解析报错 invalid volume specification
现象:
docker-compose up时提示找不到D:\03_Code\Projects\...。原因:在
docker-compose.yml中使用了相对路径的“绑定挂载”(./data:/app/data)。在远程模式下,Windows 会将相对路径解析为 D 盘绝对路径传给 Ubuntu,导致 Linux 报错。解决方案:改用 Docker 命名卷(Named Volume),将数据存储的选址权交由远端 Docker 引擎接管。 YAML
services: app: volumes: - aqi_data:/app/data # 使用命名卷 volumes: aqi_data: # 底部声明命名卷
坑 2:构建卡死在 load metadata 阶段
现象:终端一直卡在
#3 [internal] load metadata for docker.io/library/python:3.13.0-slim。原因:服务器端的 Docker 镜像源失效或被墙,导致无法获取基础镜像信息。
解决方案:进入远程服务器,清理失效的镜像源,配置国内稳定源。 Bash
sudo bash -c 'cat > /etc/docker/daemon.json <<EOF { "registry-mirrors": [ "https://docker.m.daocloud.io", "https://docker.nju.edu.cn", "https://dockerproxy.com" ] } EOF' sudo systemctl restart docker
坑 3:特定镜像库(如 ghcr.io)下载龟速
现象:
docker.io的镜像拉取正常,但遇到ghcr.io(GitHub 容器库)时,每秒仅几十 KB。原因:常规国内 Docker 镜像源仅加速 Docker Hub,对 GitHub Packages 无效。
解决方案:修改
Dockerfile,将ghcr.io替换为国内的高校/代理镜像源(如南京大学源)。 Dockerfile# 修改前 # COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ # 修改后 COPY --from=ghcr.nju.edu.cn/astral-sh/uv:latest /uv /uvx /bin/
坑 4:Git 提交失败 does not have a commit checked out
现象:本地执行
git add .报错,拒绝添加子目录。原因:不小心在项目中创建了嵌套的
.git文件夹(套娃仓库),被识别为未初始化的 Submodule。解决方案:删除嵌套的
.git文件夹,清理缓存后重新提交。 Bashrm -rf service/.git git rm --cached service git add .