能实现,但“一键”不等于“零配置”。真正卡住的是容器间连不上、服务启不动、端口映射错;需显式定义自定义网络、严格匹配 service 名、配置 healthcheck 与重试逻辑,vscode 不等待健康检查完成。

能实现,但“一键”不等于“零配置”。真正卡住的从来不是命令行敲得够不够快,而是容器间连不上、服务启不动、端口映射错——这三个点没对齐,VSCode 点十次 Docker: Compose Up 都白搭。
docker-compose.yml 必须显式声明自定义网络
默认 bridge 网络下,容器之间只能靠 IP 通信,depends_on 只控制启动顺序,不保证 MySQL 进程已监听、Redis 已 ready。VSCode 启动 Dev Container 时若 app 容器立刻去连 mysql:3306,大概率报 Connection refused。
- 在
docker-compose.yml顶层加networks块,例如:networks: app-net: driver: bridge ipam: config: - subnet: 172.20.0.0/16 - 所有服务(
app、mysql、redis)都必须显式写networks: [app-net] - 别用
host或内置bridge,它们不支持容器名自动解析(即无法用mysql当 host)
devcontainer.json 的 service 字段必须严格匹配 services 键名
VSCode 读取 devcontainer.json 后,会把 service 字段值当作容器名,去匹配 docker-compose.yml 里的 services 下的键。填错一个字母,就报 Service 'xxx' not found。
使用 Python 脚本下载 Docker 镜像并打包为 tar 文件。用户说“下载镜像”“拉取镜像”“pull xxx”“帮我下载 nginx 镜像”等时触发。支持 SOCKS5 代理直连(推荐)和国内镜像站加速两种模式。
-
devcontainer.json中写"service": "app"→docker-compose.yml里必须有services: { app: { ... } } - 如果 compose 文件放在
.devcontainer/docker-compose.yml,devcontainer.json要配"dockerComposeFile": "docker-compose.yml"(路径是相对于.devcontainer/的) -
workspaceFolder路径要和 volume 挂载路径一致;比如volumes: ["../src:/workspace/src"],那workspaceFolder就该是/workspace
MySQL 和 Redis 必须加 healthcheck + 密码验证
VSCode 启动 Dev Container 时,只等容器状态变成 running,不会等 MySQL 初始化完表结构、Redis 加载完配置。哪怕 depends_on 生效,你的应用代码第一次连上去仍可能失败。
- 给
mysql加healthcheck:healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD"] timeout: 20s retries: 10
- 给
redis加command显式启用密码:command: redis-server --requirepass $$REDIS_PASSWORD
-
ports字段仅用于主机访问(比如本地用 DBeaver 连),容器间通信必须用服务名 + 默认端口(mysql:3306、redis:6379)
应用层仍需重试逻辑,不能全依赖 compose
这是最容易被忽略的一点:VSCode Dev Containers 不会等待 healthcheck 成功才让 app 容器启动。它只看 Docker 的 running 状态。也就是说,healthcheck 是给你自己查的,不是给 VSCode 用的。
- 你的应用代码里必须实现数据库连接重试(比如 Node.js 用
mysql2的connectTimeout+acquireTimeout,或手动轮询) - 或者在
devcontainer.json的postCreateCommand里加 shell 脚本,循环检查mysqladmin ping成功再启动主进程 - 别指望
depends_on+healthcheck组合就能让应用一上来就稳连——Docker 层面的依赖 ≠ 应用层面的就绪










