不会丢失;docker restart 仅热重启容器,端口映射、卷挂载、环境变量等配置均从持久化元数据中原样加载,保持不变。

不会改变——只要容器是用 -p 或 --publish 显式声明端口启动的,重启后映射关系完全保留。
docker restart 后端口映射是否丢失?
不会丢失。Docker Desktop(包括 WSL2 模式)中,docker restart 仅终止并重新启动容器进程,不重建容器对象本身。容器的网络配置(含 PortBindings)保存在宿主机的容器元数据中,重启时会原样加载。你执行 docker ps 看到的端口列,就是从这个持久化配置读出来的。
常见误解是把 restart 和 stop + rm + run 混为一谈:后者会彻底丢弃旧容器配置,必须重写 -p;前者只是“热重启”,所有绑定端口、挂载卷、环境变量都照旧。
- ✅ 正确操作:
docker restart my-nginx→ 8080:80 依然生效 - ❌ 错误预期:以为重启后要重新
-p,结果发现没变,怀疑配置没生效 - ⚠️ 注意:如果容器是用
docker run但没加-p,仅靠 iptables 手动转发的规则,restart后不会恢复——那不属于 Docker 管理的端口映射
Windows Docker Desktop 中修改 hostconfig.json 是否生效?
修改后必须重启 Docker Desktop(不是容器),且只对已停止的容器有效。WSL2 下,容器配置文件实际位于 /var/lib/docker/containers/[ID]/hostconfig.json,但该路径在 Windows 文件系统中不可直接访问,需进入 WSL2 发行版操作:
- 先
docker stop目标容器(不能运行中改) - 运行
wsl -d docker-desktop进入 WSL2 环境 - 编辑对应容器 ID 目录下的
hostconfig.json,修改PortBindings字段(格式如"8081/tcp": [{"HostIp": "0.0.0.0", "HostPort": "8081"}]) - 退出 WSL2,右键 Docker Desktop 图标 → “Restart”
- 再
docker start容器,新端口才会被加载并触发 iptables 更新
风险提示:手动改 JSON 容易格式错误导致容器无法启动;Docker Desktop 重启期间所有容器都会中断;该方式绕过 CLI,docker inspect 能看到新配置,但 docker ps 可能短暂不刷新,需等几秒。
为什么 iptables 规则有时“看起来没生效”?
因为 Docker Desktop(WSL2)的端口转发链路比纯 Linux 多一层:宿主机 Windows 的 portproxy 会先把流量转给 WSL2 的虚拟网卡,再由 WSL2 内的 iptables 转给容器。所以你在 Windows 上查不到 iptables 规则,必须进 WSL2 查:
- 在 PowerShell 中执行:
netsh interface portproxy show v4tov4→ 看 Windows 层转发 - 进 WSL2 后执行:
iptables -t nat -nvL DOCKER→ 看真正生效的容器转发规则 - 若只在 Windows 加了 portproxy 却没在 WSL2 加 iptables,流量会卡在 WSL2 边界,容器收不到
- 容器重启不触发 portproxy 更新,只有 Docker Desktop 全局重启或新建容器才会刷新 Windows 层代理
真正需要“动态改端口”的场景,该选什么方案?
如果你的容器已经跑了很久、有状态、不能停,又急需加一个端口,别碰配置文件——优先用系统级转发:
- Windows:用
netsh interface portproxy add v4tov4把宿主机新端口直连容器 IP+端口(需先docker inspect拿到容器当前 IP) - macOS:用
pfctl配置端口转发(需启用 pf) - Linux(非 Desktop):用
iptables -t nat -A PREROUTING补规则(注意加到 DOCKER 链之前,否则被跳过)
这类方案不依赖 Docker 管理,生效快,但规则不随容器生命周期自动清理——容器删了,转发还在,容易造成端口残留和冲突。最稳妥的长期解,仍是初始就用 -p 声明所有可能用到的端口,或者用 docker-compose.yml 固化配置。


















