使用docker context无法将本地目录复制到远程容器的解决方法
问题根因
本地运行无异常是因为./:/app这个绑定挂载会把你本地存放项目代码的目录映射到容器内/app路径,本地目录下有完整项目文件,所以npm可以正常找到package.json。
切换到远程docker context执行部署时,两个阶段的路径解析规则不一样:
- 镜像构建阶段:docker会自动把你本地执行命令目录下的构建上下文(排除
.dockerignore匹配的文件)通过SSH传输到远程Docker守护进程,完成镜像构建,此时构建出的镜像内部本身是包含完整/app目录代码和依赖的 - 容器启动阶段:绑定挂载的路径解析是在远程Docker守护进程所在的主机上执行的,不会自动同步你本地的文件到远程宿主机。远程宿主机上对应
./的路径下没有任何项目文件,空目录挂载进容器后直接覆盖了镜像内原本的/app目录,最终触发找不到package.json的报错。
另外你描述里的文件名有两处笔误,顺手修正避免后续踩坑:配置文件正确名是docker-compose.yml不是docker-compose.ylm,构建文件名是Dockerfile不是Dokerfile。
修复方案
根据你的部署场景二选一即可:
方案1:远程开发调试场景(需要热更新)
如果需要和本地运行一样,修改代码后容器内服务自动重启更新,先打通本地到远程主机的项目文件同步:
- 用
rsync/scp或者VS Code Remote、Mutagen这类同步工具,把本地整个项目目录完整同步到远程主机上,路径要和你compose文件里相对路径的层级对应 - 同步完成后保持现有compose配置不变,在远程context下执行
docker compose up --build即可正常启动 - 注意后续本地修改代码后要同步到远程主机,才能触发容器内的热更新,不会自动同步。
方案2:生产部署场景(不需要热更新)
生产环境不需要把宿主机代码挂载进容器,直接删除会覆盖镜像内代码的绑定挂载项即可,完全用镜像构建阶段打包好的代码运行:
修改compose配置的volumes段,删除- ./:/app这一行,修改后配置如下:
... app: build: context: . dockerfile: Dockerfile container_name: app restart: always image: nodeapp ports: - 5000:5000 volumes: - /app/node_modules # 这行也可以删掉,构建阶段已经把依赖装到镜像内了,保留是为了避免npm install重复执行 networks: - pnet ...
修改完成后执行docker compose up --build -d即可正常启动。这种模式下不需要提前把代码传到远程主机,构建时本地的上下文会自动传到远程完成镜像打包,容器启动直接用镜像内的文件,不会出现空目录覆盖的问题。
内容的提问来源于stack exchange,提问作者dark
相关产品推荐
相关产品推荐

