Docker on Windows: 部署、运行和修复
本技能是来之不易的运维知识,源自将 Docker Compose 应用一路部署至 Windows 11 桌面(位于中国大陆网络环境)的 无人值守、重启后可运行的生产环境 过程。下面的错误看起来神秘莫测,修复方法也反直觉——这正是将其记录下来的原因。请优先参考这些内容,而不是盲目猜测;每一个问题都耗费了真正的调试时间。
这里没有任何特定于应用的内容——示例是一个 Python/FastAPI + pgvector 技术栈,但这些陷阱(Docker Desktop 套接字、网络封锁、自动启动、PowerShell 编码)会影响 Windows 上的任何 Docker 化项目。
首先,在行动前先进行判断
快速检查,用于确定你需要哪个参考文件:
- Docker 是否已启动?
docker version(客户端+服务端),docker compose ps。服务端错误通常意味着 Docker Desktop 在启动时崩溃 → 查看crash-recovery.md。 - WSL2 后端是否正常?
wsl -l -v—— 发行版(例如docker-desktop)应为Running状态。 - 中国大陆网络环境? 如果拉取/下载超时或 TLS 失败,则假设网络被封锁,先 查看
china-network.md,而不是浪费时间去重试。 - 是否需要无人值守重启后存活? 这是一个完整的链条,而不是单一设置 → 查看
unattended-operation.md。
症状 → 参考文件
| 你看到的现象 | 阅读文件 |
|---|---|
Docker Desktop 无法启动、崩溃循环,或日志中出现 Inference manager / Secrets Engine / listening on unix://… / 系统无法访问文件 / 语法不正确 | references/crash-recovery.md |
docker pull 出现 EOF/TLS 握手超时;构建时 pip/apt 失败;wsl --install 挂起;winget 报错 0x8a15000f;HuggingFace/模型下载 302 跳转到被封锁的主机 | references/china-network.md |
| 必须在重启后无需人工干预运行(自动登录、自动启动、锁屏、重启策略),或者“我登录时没问题,但重启后不行” | references/unattended-operation.md |
.ps1 脚本乱码、报错 缺少 '}'、自行终止进程,或每个原生命令都显示恐怖的红色文本 | references/windows-scripting.md |
| 部署到新的 Windows 机器、恢复数据库卷,或者“我修改了代码但容器没有变化” | references/deploy-workflow.md |
可推广的原则(即使不打开参考文件,也请大致浏览)
-
Docker Desktop 在 Windows 上最严重的故障是孤立的 AF_UNIX 套接字,而非配置错误。 硬停止(崩溃/强制退出/断电)会在
%LOCALAPPDATA%\Docker\run\和%LOCALAPPDATA%\docker-secrets-engine\下留下无法删除的重解析点套接字文件。Docker 尝试在下次启动时删除并重新创建它们,导致崩溃循环。你无法删除这些文件(Remove-Item/.NETDelete均失败)——但你可以重命名父目录(这是一种元数据操作,可以绕过访问错误)。将其重命名后,Docker 会重建干净的套接字。切换EnableInference/EnableDockerAI无法解决此问题。请参见crash-recovery.md。 -
在中国大陆网络环境中,优先使用镜像,而非直连。 Docker Hub、
winget、在线wsl --install、deb.debian.org和 HuggingFace 大模型权重均被封锁或不稳定。注册表镜像、清华大学的 pip/apt 源、离线 WSL MSI 以及 ModelScope(用于模型权重)是可靠的路径。desktop.docker.com和 GitHub 发布版可以直接连接。请参见china-network.md。 -
在 Windows 自动登录下,
HKCU\...\Run自动启动条目会静默地不触发。 请改用登录时触发的任务计划程序任务。这是无人值守设置中最大的陷阱。请参见unattended-operation.md。 -
编写
.ps1文件时仅使用 ASCII。 PowerShell 5.1 将不带 BOM 的 UTF-8 文件读取为 GBK;任何非 ASCII 字符(例如中文注释)会破坏大括号匹配 →缺少 '}'→ 脚本立即终止且不留任何日志。保持脚本纯 ASCII;日志使用英文。请参见windows-scripting.md。 -
挂载代码 = 重启,而非重建。 如果
docker-compose.yml将源代码绑定挂载(./:/app),则代码编辑后执行docker compose restart <svc>即可生效——无需重建镜像。仅当依赖项/Dockerfile 更改时才重建。通过一次性的docker compose exec <svc> python …试运行验证逻辑更改,然后 再让真正的计划任务触发,这样你就永远不会通过在实时输出通道上发送乱码进行测试。请参见deploy-workflow.md。 -
遵守单一写入者约束。 如果应用按计划推送到外部通道,则一次只能有一台机器运行调度程序——两个副本会导致重复发送。在启动新实例之前,请先关闭旧实例(
docker compose down)。 -
Claude 无法静默获取管理员权限。 任何需要提升权限的系统更改都必须由操作人员在 UAC 提示中确认(
Start-Process -Verb RunAs会触发该提示)。明确将这些步骤标记为 "需手动操作 / manual step" —— 操作人员是中文使用者且基础架构经验有限,他们重视带有明确手动操作提示的逐步指导。自动权限模式也会阻止ExecutionPolicy Bypass + elevation,因此不要绕过该提示。
如何扩展本技能
当解决了一个新的、不明显的 Windows/Docker 故障时,请将其添加到相应的参考文件中(症状 → 根本原因 → 有效的确切修复方法,以及无效的方法)。"无效尝试" 这一行通常是最有价值的部分——它可以防止下一个人再次尝试死胡同。