跳至主要内容
五折优惠 全部方案,限时优惠。起价 $2.48/mo
14 min left
开发者工具与 DevOps

Stop Running Docker Desktop: Offload Your Builds to a VPS Instead

S 作者 Sajjad 14 分钟阅读
Diagram showing a local Docker CLI connecting over SSH to Docker Engine running on a remote VPS as a Docker Desktop alternative.

打开活动监视器或任务管理器,启动一个小容器,Docker Desktop 仍可能成为机器上最吵的那个。在 2026 年 2 月的一个 Docker Desktop issue中,一位用户报告说, com.docker.backend.exe 容器启动后 CPU 攀升到 100%,并且在容器停止之后仍然持续。

还有另一手:把守护进程彻底从你的笔记本上拿掉。本地只保留 Docker CLI,让 Docker Engine 跑在一台 Linux VPS 上,并把 docker context 通过 SSH 指向它。你的 docker build 命令不会变。构建只是在别处执行,在没有 VM 层的原生 Linux 上,由 VPS 的带宽去拉基础镜像,而不是你的咖啡馆 Wi-Fi,也没有需要追踪的 Docker Desktop 许可。

这就是那条路径的完整搭建:先决条件、准确的 docker context 命令、用远程 buildx 驱动做多架构构建、如何为机器定规格,以及远程做法在何处是错误的选择。

TL;DR(太长不看版)

  • 问题: Docker Desktop 拖着一台本地 VM,把文件 I/O 推过一层虚拟化,并且 需要付费订阅 用于较大组织中的专业使用,包括超出 Docker 免费额度上限的公司。
  • 解法: 移除 Docker Desktop。让 Docker Engine 跑在一台 Linux VPS 上,创建一个通过 SSH 指向它的 docker context ,于是你本地的 docker build 命令在 VPS 上执行,而你的 CLI 只做编排。
  • 成本框架: 一台不起眼的 VPS 就取代了按席位计的许可,并给你原生 Linux 的构建速度。整支团队可以共用一台构建机,而不是按每个开发者付费。
  • 诚实的告诫: VPS 必须可达(没法在飞机上构建),而且你需要对 .dockerignore 保持纪律,好让你不至于在每次运行时都上传一个数 GB 的构建上下文。

先决条件:你会需要什么

在第一条命令之前,把这些备齐。如果你已经每天都在用 Docker,这里没有什么稀奇的。

  • A Linux VPS 具有 root 或 sudo 访问权限。Ubuntu 22.04/24.04 或 Debian 12/13 都能很好地工作。
  • VPS 上的 Docker Engine。 docker context 通过 SSH 需要远程主机上有 Docker Engine 18.09 或更新,依据 Docker 的 context 文档。.
  • 本地的 Docker CLI 19.03 或更新。 那正是理解顶层 context 命令的客户端。
  • An 一对 SSH 密钥。 仅基于密钥的认证: 不支持密码认证 用于 docker context SSH 连接。
  • 那位 docker 组里的远程用户 docker,好让它在每次调用时都能不用 sudo 就与守护进程套接字对话。

Docker Desktop 实际让你付出了什么

这些成本并不神秘。它们落在三个地方,而一路搜索到这里的人,至少感受过其中之一。把它们准确地叫出名字才是要点。那种痛你已经知道了。

内存与 VM 开销。 Docker Desktop 仍然意味着一台本地 Linux VM。 Docker 的设置文档 说,Docker Desktop 可以限制 Docker Desktop VM 使用多少内存——这正是问题里安静的那部分:循环里始终有一台 VM。确切的占用因操作系统和项目而异,但失败模式是真实的。一个 Docker for Windows 的 issue 报告说,Docker Desktop 在没有任何容器运行时也消耗好几个 GB 的内存,而一个 WSL2 的 issue 描述了 Docker 构建在容器结束后仍未释放内存的情况。要点不是每台机器都在同一个数字上空转。要点是 Docker Desktop 把本地 VM 的开销留在了你的开发循环之内。

构建与文件 I/O 速度。 跨越 VM 边界的绑定挂载和文件操作,比原生的 Linux 文件系统访问要慢。 Docker 的已知问题文档 承认了虚拟化文件系统的成本。社区基准测试经常报告,穿过 VM 层的绑定挂载慢上大约 3-10x 的量级。第二个数字是社区经验,而非 Docker 公布的基准,但方向上没有谁在 Mac 上看过构建龟速爬行后还会有异议。

许可。 自 2021 年的变更以来,Docker Desktop 对员工超过 250 人或营收超过 1,000 万美元的公司要求付费订阅。 Docker 定价页 上的当前档位是 Personal($0)、Pro($11/mo 或每年 $9)、Team($16/mo 或每年 $15)和 Business($24/mo)。Team 档位在 2024 年 12 月从每年 $9 涨到 $15——这一跳把一项安静的开支变成一场与采购的对话,当你把它乘以三十个席位时,真正扎心的正是这一部分。

What Docker Desktop costs you: local VM overhead, slower file I/O, and license tracking on the laptop, versus a remote VPS running Docker Engine with no local VM, fast remote I/O, and bring-your-own-license.

各种替代品,以及本地对远程的分岔

你会找到的几乎每一个 Docker Desktop 替代品,都是把一个本地守护进程换成另一个本地守护进程。那才是该留意的真正的轴:大多数人纠结的选择是在本地工具之间,而更有意思的分岔是本地对远程。只有远程这条路,才把 VM 从你的机器上拿掉。

这就是那幅并排放着的格局图。

路径平台本地 VM 开销成本形态关键限制
Docker DesktopMac, Windows, Linux因配置而异对团队收费 一旦超出 Docker 免费额度上限你正在离开的那个问题
OrbStackmacOS only空闲约 300 MB(厂商声称)个人免费,商用 $8/mo仅限 Mac,许可又回来了
ColimamacOS, LinuxM1 上约 400 MB免费不是直接替代
Podman DesktopMac, Windows, Linux基于 VM,rootless免费(Apache-2.0)Compose 需要 Docker 兼容套接字
Rancher DesktopMac, Windows, Linux基于 VM免费(Apache-2.0)Mac 上采用较少
Docker Offload经由 Docker Desktop 4.68+本地什么都没有,托管的云端会话Docker Business 加 Docker Offload 订阅需要 Docker Desktop,每用户一个会话,短暂环境
远程 VPS 上下文任意(本地只有 CLI)没有一台 VPS,无按席位许可VPS 必须可达

其中有几个值得一句诚实话:

  • OrbStack 确实为单打独斗的开发者解决了 Mac 的资源问题。它声称空闲约 300 MB 且容器启动最多快上 10x(OrbStack 的网站),两者都是厂商数字,而非独立基准。如果你是一位不想管理远程基础设施的 Mac 专属开发者,OrbStack 是更好的选择,而它 $8/mo 的商用档位(OrbStack 定价)压在 Docker Desktop 的 Team 档位之下。要害在于:它仅限 Mac,而商用许可又把你曾想逃离的那个东西原样带了回来。
  • Colima 是免费且以 CLI 为先的,但它“不是直接替代”的那些粗糙棱角有充分记录,一些团队在一次迁移卡住之后又回到了 Docker Desktop。
  • Podman DesktopRancher Desktop 两者都免费且跨平台。哪个都不是无声的替代,而 Podman 与 Compose 的兼容要经由它那个 Docker 兼容套接字。
  • Docker Offload 是 Docker 自家的托管式远程构建/运行服务,但它并不是一次干净地退出 Docker Desktop。当前的 Docker 文档把它列为需要 Docker Desktop 4.68 或更新、一份 Docker Business 订阅以及一份 Docker Offload 订阅。它在 Docker 托管的云主机上运行工作负载,但每个用户一次只有一个 Offload 会话,空闲会话在 5 分钟宽限期后终止,而环境是短暂的,所以会话结束时容器、镜像和卷都会消失。如果你想要 Docker Desktop 内部的托管式远程算力,那没问题。它跟一台持久的 VPS 构建机不是一回事——那台有你自己的缓存、磁盘、root 访问,而且不依赖 Desktop。

留在原地在一种情况下仍然合理:一个处在免费额度门槛以下、又没有构建速度之痛的个人,没有理由改变任何东西。其余所有人都有一个分岔要做。

本节要点:真正要紧的决定,不是选哪个本地工具。而是你到底要不要在笔记本上留一个守护进程。

The local-versus-remote fork: local paths keep a VM, daemon, and desktop tool on the laptop, while the remote path runs Docker Engine, a persistent cache, and an SSH context on a VPS with no local daemon.

docker context 如何经由 SSH 工作

要在一台远程服务器上经由 SSH 构建 Docker 镜像,就在那台服务器上运行 Docker Engine,用 docker context create name --docker "host=ssh://user@host"创建一个指向它的 docker context,然后运行 docker context use name。此后你平常的 docker build 就在远程主机上执行,而本地 CLI 只负责发送指令,由守护进程来干活。

一个上下文是给 Docker CLI 的一个具名、可切换的目标。与其每次都摆弄环境变量 DOCKER_HOST 或手工搭一条 SSH 隧道,你只定义一次远程,然后像换目录一样切到它。构建完全在远程主机上执行:基础镜像的拉取用的是 VPS 的上行带宽,层缓存在 VPS 的磁盘上,CPU 的活儿发生在 VPS 的核心上。唯一对延迟敏感的步骤是最初的 SSH 握手和你构建上下文的上传。此后的一切都在远程。

搭建你的 VPS 构建机

整套搭建就是四条短命令加上一个 SSH 配置块。我会在有助于你确认每一步都落地的地方展示预期输出。

第 1 步:把 Docker Engine 弄到一台 Linux VPS 上。 配置好机器并安装 Docker Engine(远程端 18.09+ 是 context SSH 的下限;你本地的 CLI 需要 19.03+)。如果你宁可不自己跑安装,就部署一台已经自带它的 VPS(下面细说)。远程用户需要在 docker 组里:

sudo usermod -aG docker $USER

# log out and back in for the group change to take effect

第 2 步:设置 SSH 密钥认证和一个配置别名。 基于密钥的认证是必须的。在 ~/.ssh/config 里给主机起一个短别名,好让你不用反复敲 IP 和密钥路径:

# ~/.ssh/config
Host my-vps
  HostName 1.2.3.4
  User ubuntu
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes

第 3 步:创建上下文。 经由 SSH 把它指向远程守护进程。使用展开的写法:

docker context create my-vps --docker "host=ssh://[email protected]"

或者,使用第 2 步里的 SSH 配置别名:

docker context create my-vps --docker "host=ssh://my-vps"

第 4 步:验证。 列出你的上下文并检查远程引擎是否应答:

docker context ls

NAME        DESCRIPTION                               DOCKER ENDPOINT
default *   Current DOCKER_HOST based configuration   unix:///var/run/docker.sock
my-vps                                                ssh://my-vps

docker --context=my-vps version

如果它打印出远程守护进程的服务器版本,你的 CLI 就在和 VPS 对话。

第 5 步:切换并构建。 把 VPS 设为活动目标,然后照常构建:

docker context use my-vps

docker build -t myapp .

那次构建在 VPS 上执行。宁可不全局切换?瞄准单条命令:

docker --context=my-vps build -t myapp .

或者为这个 shell 会话设置它:

export DOCKER_CONTEXT=my-vps

当你想要回你笔记本的本地守护进程时(如果你留了一个),切回家:

docker context use default

专业提示:留意你的 .dockerignore。构建上下文会在构建开始之前上传到远程主机。一个迷路的 node_modules or .git 目录,意味着你在每次运行时都把好几 GB 发上线,而远程这条路会毫无理由地感觉比本地更慢。一个紧凑的 .dockerignore 才是最影响远程这条路是否让人感觉快的那一件事:把依赖、构建产物和 VCS 元数据排除在外,上传就变成一个舍入误差。

Four-step VPS build box setup: add an SSH key, create a Docker context pointing at the VPS, switch to the remote context, and build remotely on the remote Docker Engine over an encrypted SSH tunnel.

用远程 buildx 驱动做多架构构建

创建一个在远程 Docker 主机上于容器内运行 BuildKit 的 buildx 构建器,然后针对它构建:

docker buildx create --name remote-builder \
  --driver docker-container \
  --use \
  ssh://ubuntu@your-vps-ip

docker buildx inspect --bootstrap

docker buildx build \
  --builder remote-builder \
  --platform linux/amd64 \
  -t myapp:latest \
  --load .

那位 --load 这个标志对单平台的本地消费很重要:在 docker-container 驱动下, 构建出的镜像不会自动出现在你本地的镜像列表里。如果你在构建一个真正的多平台镜像,就改为把它推到一个 registry:

docker buildx build \
  --builder remote-builder \
  --platform linux/amd64,linux/arm64 \
  -t registry.example.com/myapp:latest \
  --push .

那个区别很重要。单平台的远程构建可以加载回你本地的镜像库。 多平台镜像通常会被推到一个 registry,因为它是一个针对每个目标架构都有单独变体的清单列表。本节是可选的:如果你的所有镜像都是单架构的,上面的上下文搭建就是全部工作。

Remote buildx factory diagram: your code and container layers feed a remote BuildKit builder that outputs either a single-platform image loaded to the local image store, or a multi-platform image pushed to a registry.

为构建机定规格并加以保护

两个问题决定这台机器是否好好服务于你:把它做多大,以及如何把守护进程锁好。Docker 构建受 CPU 约束,所以定规格的逻辑主要关乎核心数以及足以避免交换的内存。安全的逻辑主要关乎不把守护进程暴露给除你以外的任何人。

把它定成什么规格

给它通用的规格。你可以把它们映射到你的服务商所提供的任何东西上。

  • 下限(单个开发者,轻量构建): 2 vCPU / 4 GB RAM / ~120 GB NVMe. This is the minimum that works, not what I'd reach for.
  • 我实际会部署的(面向大多数团队): 4 vCPU / 8-12 GB RAM / 240-300 GB NVMe. Four vCPUs stop your parallel build steps from serializing, 8-12 GB handles concurrent builds without touching swap, and the NVMe headroom keeps a healthy layer cache.
  • 团队或重度 CI: 8 vCPU / 16-24 GB RAM for several developers sharing one box or big multi-stage Dockerfiles.

因为构建受 CPU 约束,高频(面向 CPU 优化)的核心买给你的更快迭代,胜过越过交换阈值之后的额外内存。GPU 方案在这里无关紧要,因为镜像构建不碰 GPU。而数据中心的选择只影响 SSH 的响应性和上下文上传的时间,不影响构建速度:无论你坐在哪里,构建都在 VPS 上执行,所以挑一个离你近的位置以获得利落的握手,然后往前走。

保护远程守护进程

上面的搭建已经强制了正确的默认:SSH 密钥认证,没有对网络暴露的守护进程端口。就这么保持。你一旦把 BuildKit 或守护进程暴露到 SSH 之外(一个裸的 TCP 端点,一个开着的 BuildKit 端口),你就成了目标。 Hacker News 讨论帖 讲的是最先提出远程 VPS 这个点子的慢构建,它也警告了针对暴露在外的 BuildKit 端点的加密货币挖矿攻击。开放互联网上一个未认证的构建守护进程,就是一场免费的算力自助餐。

专业提示:不要暴露守护进程。如果只用 SSH 对你就够了(对大多数单机搭建都够), 那就永远不要开守护进程的 TCP 端口 。如果你确实需要 TCP 访问,就在它前面放上双向 TLS(mTLS),好让只有持有效证书的客户端才能连上。只用 SSH 或用 mTLS:对于一台可从互联网访问的构建机,没有可以接受的第三种选择。

机器一旦立起来,它就是一台通用 Linux 服务器,还有很多别的东西值得跑在上面。我们的 面向独立开发者的自托管技术栈指南 是关于还有什么值得在你的 VPS 上占一席之地的一篇合理的续读。

如果你宁可跳过 Docker Engine 的安装、直接去到 docker context create,我们的 Docker 应用市场应用 会部署一台已经配置好 Docker Engine、Compose V2 和 buildx 的 VPS。一键之后机器就已就绪可 SSH,所以上面的走查从第 2 步而非第 1 步开始。

常见问题

我能在一台远程服务器上运行 Docker 构建、同时用我本地的 CLI 吗?

能。在远程主机上运行 Docker Engine,创建一个经由 SSH 指向它的 docker context ,然后切到那个上下文。于是你本地的 docker build 命令就在远程服务器上执行,而你机器上的 CLI 只做编排,不需要任何本地守护进程。

docker context 和 DOCKER_HOST 有什么区别?

A docker context 是一个你定义一次、再用 docker context use. DOCKER_HOST 来选择的具名、可切换、持久的目标。是一个你为每个 shell 手工设置和取消的单一环境变量。上下文是那套老旧的“隧道加环境变量”做法的现代替代。

docker compose 能与远程上下文一起工作吗?

能。Compose V2 尊重当前活动的 Docker 上下文,所以 docker compose 命令会针对上下文所指向的那台主机执行。服务以及任何镜像构建都在远程主机上执行,就跟一条普通的 docker build.

Docker Offload 是什么,它免费吗?

Docker Offload 是 Docker 自家的托管式远程构建/运行服务,用于在保留 Docker Desktop 工作流的同时,把容器工作挪到 Docker 托管的云主机上。当前的 Docker 文档把它列为 需要 Docker Desktop 4.68 或更新,外加 Docker Business 和 Docker Offload 订阅。它还是基于会话的:每个用户拿到的是 一次一个 Offload 会话,空闲会话在 5 分钟宽限期后终止,而远程环境是短暂的。

我怎么让 Docker Desktop 别用那么多内存?

调 Docker Desktop 的资源上限只是把一个永远不会降到零的占用缩小,因为 VM 始终有一个下限。真正把内存成本去掉的路径,是把本地守护进程整个拿掉:让 Docker Engine 跑在一台 VPS 上,并经由 docker context 用 SSH 连接,好让你的机器上除了 CLI 什么都不跑。

我能改用 Podman 来做这件事吗?

能。Podman 作为一个 Docker 兼容引擎提供,而 docker context 可以指向一台远程 Podman 主机,但那需要 Podman 经由 SSH 暴露它那个 Docker 兼容套接字。命令的流程是一样的。远程那一侧的搭建有所不同。

分享

博客更多内容

继续阅读。

准备好部署了吗? 起价 $2.48/月。

独立云厂商,自 2008 年起。AMD EPYC、NVMe、40 Gbps。14 天退款保证。