最明确可靠的方式是在services下为服务显式声明working_dir字段,值设为容器启动时默认进入的路径(如/app),它优先级高于镜像workdir但低于docker run -w,且必须与volume映射路径一致以确保command等相对路径正常执行。

直接在 services 下为对应服务加上 working_dir 字段,值设为你希望容器启动时默认进入的路径(比如挂载目录或应用主目录),这是最明确、最可靠的方式。
working_dir 必须显式声明
Docker Compose 不会自动把 volumes 映射的目标路径当作工作目录。即使你把宿主机的 /var/www/myapp 挂载到了容器里的 /app,容器启动后 pwd 仍是 / —— 除非你主动指定 working_dir: /app。
- 不写 working_dir → 默认是 /,和镜像的 Dockerfile 中 WORKDIR 无关(除非镜像本身没设,且你也没覆盖)
-
写了 working_dir → 容器启动时自动 cd 进去,后续
command、entrypoint都基于这个路径执行 - 它优先级高于镜像内置的 WORKDIR,但低于 runtime 时用
docker run -w覆盖
推荐配置模式:与 volume 映射保持一致
多数 Web 或 CLI 类服务,应让 working_dir 和主 volume 的容器内路径一致。例如:
services:
api:
image: alpine:3.20
volumes:
- ./src:/app
working_dir: /app
command: sh -c "python main.py"
这样 python main.py 就能直接读到 /app/main.py,不用写绝对路径,也不依赖当前 shell 位置。
- 如果挂载多个目录(如
/app、/data、/config),优先选业务代码所在路径作为working_dir - 避免设成
/tmp或/root这类临时/特权路径,不利于可维护性和权限控制
配合 command 和 entrypoint 更清晰
当 working_dir 设置合理后,command 可以用相对路径,逻辑更直观:
-
command: ./start.sh(而不是/app/start.sh) -
command: node server.js(前提是server.js在/app下) - 如果用了自定义
entrypoint,它也会在working_dir下执行,方便做初始化操作(如 chown、chmod)
注意数据迁移和重建风险
修改 working_dir 后执行 docker compose up -d 会重建容器,未持久化的数据(比如容器内 /tmp/cache 或 /app/logs)会丢失。
- 若服务已有运行中状态且生成了本地数据,先
docker compose exec进去,把关键目录 cp 到已挂载路径下(如cp -r logs /app/logs) - 确认所有需要保留的数据都映射到了
volumes,再更新配置并重建 - 生产环境建议搭配
restart: unless-stopped和健康检查,减少重建影响











