windows离线部署docker流程记录
最近接了个活,客户那边的服务器是完全断网的(内网隔离,出于安全考虑),又是windows电脑,所以考虑使用docker,平时都是联网直接 docker compose up 完事。头一次遇到要把整套 MySQL + 后端 + 前端服务打包带到一台”与世隔绝”的 Windows 机器上跑起来,中间踩了几个坑,记录一下完整流程,给同样场景的朋友们省点时间。
场景说明
项目是标准的三件套:
mysql—— 数据库backend—— Python/Flask 后端,跑在 gunicorn 里web—— Nginx 托管前端页面,反向代理 API
平时开发联网状态下,一条 docker compose up -d 就能起。但目标机器完全没有网络,连 apt、pip、npm 的源都碰不到,更别说 docker pull 了。思路很简单:在有网的电脑上把所有东西准备好,打包成文件,U 盘拷过去,离线机上直接加载。
第一步:有网电脑上把镜像打好包
先确保代码是最新的,然后照常构建:
1 | cd D:\你的项目目录 |
构建完了以后,把用到的几个镜像导出成一个 tar 包:
1 | docker save -o project-images.tar mysql:8.0 project-backend project-web |
这里有个小提醒:docker save 支持一次导出多个镜像到同一个 tar 里,不用一个个来。导出的文件通常几百 MB 到一两个 G,看你项目依赖装了多少东西。
第二步:把需要的文件都收集到一起
除了刚才导出的镜像包,U 盘里还得放这几样:
| 文件 | 用途 |
|---|---|
项目目录(含 docker-compose.yml、初始化 SQL 等) |
Compose 编排配置和数据库初始化脚本 |
project-images.tar |
打包好的镜像 |
WSL2 安装包(.msi) |
Docker Desktop 在 Windows 上跑的底层依赖 |
Docker Desktop 安装包(.exe) |
目标机上运行容器的工具 |
WSL2 安装包可以去 GitHub 的 WSL 发布页 下,注意看清楚机器架构,一般台式机/笔记本都是选 x64 那个。
如果目标机已经装过 WSL 和 Docker 了,后续再更新项目,就不用重新拷安装包了,只需要拷项目目录和新的镜像 tar。
第三步:离线机上装环境
这一步跟正常装 Docker Desktop 没什么区别,就是把在线下载的步骤换成了运行本地安装包:
- 双击装 WSL 的
.msi,装完重启一下电脑 - 装 Docker Desktop,安装过程中记得勾上 Use the WSL 2 based engine(不然容器跑不起来)
- 打开 Docker Desktop,确认它显示正常运行(左下角是绿色的)
如果项目里有挂载宿主机某个目录的配置(比如存图片、存文件的路径),记得提前把这个目录建好,不然容器起来的时候会因为挂载路径不存在报错。
第四步:导入镜像,启动项目
把项目目录和 tar 包拷到离线机上以后:
1 | cd D:\项目目录 |
注意这里加 --no-build,因为离线机没法联网拉依赖,docker compose up 默认如果发现镜像不存在会尝试构建,这在离线环境下必然失败。加了这个参数就是明确告诉它:别 build,直接用我导入的镜像跑。
跑起来以后用这条命令看看容器状态:
1 | docker compose ps |
都是 Up 状态就说明没问题,浏览器打开对应地址验证一下页面能不能访问。
后续更新怎么办
项目难免要迭代,更新流程也不复杂。有网的机器上重新 build 一遍,重新 save 出新的 tar,拷过去以后:
1 | docker load -i project-images.tar |
docker load 会覆盖同名的旧镜像,up -d 会用新镜像重建容器。这里有两个坑要注意:
- 不要手动删旧镜像再导入,一般没必要,
load本身会处理好覆盖逻辑 - 千万不要用
docker compose down -v去”清理一下”,这个-v会把数据卷一起删掉,数据库里的数据也会跟着没了。正常更新用不到删卷这个操作。
踩坑一:Docker Desktop 一直卡在 “Starting the Docker Engine”
这个坑基本每台离线机第一次装的时候都会遇到一次:WSL 装完、Docker Desktop 也装完了,打开之后界面一直转圈,提示 “Starting the Docker Engine”,等再久也不会变绿。
排查过一圈发现跟网络、镜像都没关系,纯粹是 WSL 这层的虚拟化环境没起来或者卡住了。解法很固定,照着下面顺序来一遍基本都能好:
先把 Docker Desktop 完全退出(右下角托盘图标右键 Quit Docker Desktop,别只是关窗口)
打开 PowerShell,执行:
1
wsl --shutdown
重启电脑(这一步不要跳过,单纯
wsl --shutdown有时候不够彻底)重启后重新打开 Docker Desktop,耐心等几分钟,让它把 WSL2 的虚拟机重新拉起来
如果重启电脑之后还是老样子,八成是 BIOS 里的虚拟化功能(Intel VT-x / AMD-V)没开,或者 Windows 的”虚拟机平台”、”适用于 Linux 的 Windows 子系统”这两个可选功能没勾上,去”启用或关闭 Windows 功能”里确认一下。
踩坑二:镜像莫名其妙很大
这个坑值得单独说一下。有一次发现后端镜像居然有 3 个多 G,用 docker history 镜像名 查了一下每一层的大小:
1 | COPY . . 1.04GB |
COPY . . 这一层正常情况下应该就是项目代码,几 MB 到几十 MB 都算合理,但它跑出了 1 个多 G,明显不对劲。查下来发现是 .dockerignore 没配全,构建的时候把一些不该打进镜像的大文件也一起 COPY 进去了。
排查思路很简单:先看 .dockerignore 里排除了哪些目录,再实际去项目目录里翻一遍,看排除规则之外还有没有大文件残留(比如临时生成的日志、缓存的第三方素材、之前调试留下的大数据文件)。把这些也加进 .dockerignore,重新 build 一次,这一层直接从 1G 掉到几 MB。
这里给个通用建议:如果你的镜像体积让你觉得”不对劲”,第一反应应该是跑一下 docker history 镜像名,一层一层看是哪个步骤占的空间大,而不是瞎猜。定位到具体层之后,问题基本就很好查了。
