VS Code 连接 Docker 容器并同步主机工作区
这次要解决什么问题
当时的工作流是:代码写在主机上,程序跑在 TensorFlow 容器里。每改一次 tf.py,都要手动执行:
docker exec tf python ./tf.py
能运行,但调试体验很差:编辑器不在真正的运行环境里,断点、解释器和依赖也容易对不上。于是这次尝试的目标很具体:
- 代码仍然放在主机工作区;
- Python 依赖和运行环境放在容器里;
- VS Code 能直接打开容器里的项目;
- 修改主机文件后,容器可以立即看到变化。
先理解文件是怎么同步的
这里并没有把文件“复制”两份,而是通过 Docker 的 bind mount 把主机目录挂载到容器目录:
主机 ~/Project ── bind mount ──> 容器 /root/Project
│ │
└── VS Code 编辑 └── Python 运行 / 调试
因此,代码修改会直接反映在两边。但依赖安装、容器内生成的缓存和编译产物不一定应该放在主机目录里。尤其是主机和容器的操作系统、文件权限或二进制格式不一致时,盲目共享整个目录会带来新的问题。
准备一个带挂载目录的容器
当时使用的是 TensorFlow GPU 镜像:
docker run --gpus all -itd \\
--name tf \\
--rm \\
-v ~/Project:/root/Project \\
tensorflow/tensorflow:latest-gpu-py3
参数的作用:
--gpus all:把可用 GPU 暴露给容器;没有 GPU 或未配置运行时的机器不应照搬;--name tf:给容器一个稳定名字,方便docker exec和 VS Code 查找;--rm:容器停止后自动删除容器本身,但挂载在主机上的代码不会因此删除;-v ~/Project:/root/Project:把主机目录挂载到容器目录。
启动后先不要急着连 VS Code,先确认挂载和 Python 环境:
docker ps
docker exec tf pwd
docker exec tf ls -la /root/Project
docker exec tf python --version
如果主机目录在容器里看不到,先解决挂载问题,不要把代码再复制一份到容器里继续排查。
用 VS Code 连接正在运行的容器
当时安装了两个扩展:
- Docker;
- Remote Development。

Docker 扩展可以确认 tf 容器是否正在运行,Remote Development 提供连接容器的入口。

选择正在运行的容器后,打开容器中的 /root/Project 目录:

连接成功后,VS Code 的终端、Python 解释器和调试进程都会运行在容器环境里。第一次进入时,编辑器可能会在容器中安装 VS Code Server 或相关组件,这部分属于远程编辑器运行环境,不等同于把项目依赖安装进镜像。
运行和调试一个最小文件
在主机的 ~/Project 下创建 tf.py:
import tensorflow as tf
print("hello tensorflow")
print(tf.__version__)
然后从容器内执行:
python /root/Project/tf.py
也可以在 VS Code 中选择容器内的 Python 解释器,再点击运行或调试按钮。

此时修改主机上的 tf.py,容器内的文件应立即变化:
printf '\nprint("changed")\n' >> ~/Project/tf.py
docker exec tf tail -n 3 /root/Project/tf.py

这就是“同步”真正发生的地方:两边访问的是同一份挂载内容,而不是 VS Code 替你做了一次隐式上传。
常见问题和边界
主机文件变成 root 所有
如果容器内用 root 用户创建文件,主机上可能看到 root 所有的文件。开发容器最好配置与主机用户对应的非 root 用户,或者在创建文件前明确检查 UID/GID。
依赖装了但重启后消失
如果只是把依赖安装在临时容器里,删除容器后自然会消失。应该把依赖写入 Dockerfile,或者使用新版 VS Code Dev Containers 的 devcontainer.json 配合 Dockerfile 管理开发环境。
挂载目录遮住镜像里的目录
如果镜像中 /root/Project 原本有文件,挂载主机目录后,主机目录会遮住容器里的原内容。需要区分“镜像内文件”和“挂载内容”,不要看到文件消失就直接重建镜像。
latest 不是稳定版本
原文使用了 latest-gpu-py3,这是当时为了快速验证的选择。长期项目应固定经过验证的镜像标签,并把 CUDA、Python、框架和驱动的兼容关系记录下来。否则镜像更新后,同一条命令可能得到不同环境。
现在更推荐的维护方式
手工启动容器适合快速验证;长期使用时,可以把这些信息写进项目文件:
- Dockerfile:记录基础镜像和依赖;
devcontainer.json:记录 VS Code 如何创建或连接开发容器;- Compose 文件:记录多个服务、挂载和端口;
- README:记录启动、调试和清理命令。
这样换机器时,开发环境可以重新创建,主机工作区仍然通过挂载进入容器,不需要依赖某个已经被手动改过的容器。
这次实践最终解决的是“主机编辑、容器运行、VS Code 调试”之间的摩擦。文件挂载很方便,但它只解决文件在哪里,不会自动解决依赖版本、权限和镜像可复现性。
参考资料
可用性说明:本文发布于 2020 年 1 月,距今已超过五年。文中涉及的软件版本、接口、下载地址、命令参数和操作界面可能已经发生变化,部分方案在当前环境下可能失效。请结合官方最新文档核对后再操作,生产环境使用前务必先行验证。
版权声明: 本文首发于 指尖魔法屋-VS Code 连接 Docker 容器并同步主机工作区(https://blog.thinkmoon.cn/post/692-guide-vscode-docker/) 转载或引用必须申明原指尖魔法屋来源及源地址!
评论
使用 GitHub 账号登录后即可留言,支持 Markdown。