Docker Compose 配置容器的工作目录(working_dir)

更新日期: 2025-12-10 阅读次数: 31 字数: 824 分类: docker

使用 Docker Compose 配置文件,新建了一个 alpine 镜像的容器。 里面运行了一个 golang gin 开发的 web 应用。没想到,又踩了一个 docker 配置的坑 🥲 我感觉踩的 docker 坑多得数不过来啦

相对目录问题

我发现了一个线上的 bug,线上服务器中,使用 golang 创建的相对路径的目录,结果发现目录创建在了根目录 / 下,而不是预期的 /app 目录下。

  • 本地开发机,没有使用 docker,目录位置都是正常的
  • 线上服务器,使用 docker 部署的,目录位置不对。全部到了根目录下。
  • 线上服务器,不使用 docker,使用 systemd 直接运行的,目录位置也是正常的。(后来发现是我设置了 systemd WorkingDirectory 参数)

查了一下,原来 docker 也是需要设置工作目录的。至少 alpine 镜像是这样的。

原 docker-compose.yml 配置

sunzhongwei.com:
  image: alpine:3.20.3
  restart: always
  ports:
    - "9000:9000"
  volumes:
    - /var/www/sunzhongwei.com:/app
  command: /app/main

确认当前的工作目录:

> docker compose exec sunzhongwei.com pwd
/

可以看到当前目录是 / 根目录,而不是 /app 目录。

修改后的 docker-compose.yml 配置

增加了 working_dir 参数:

sunzhongwei.com:
  image: alpine:3.20.3
  restart: always
  ports:
    - "9000:9000"
  volumes:
    - /var/www/sunzhongwei.com:/app
  working_dir: /app
  command: /app/main

数据目录备份

修改完配置,不要着急使配置生效。因为如果重新构建容器,容器内的数据目录会丢失。 即,没有映射到宿主机的目录数据,会丢失。例如,如果有两个目录 upload 和 sitemap,需要先备份出来。

docker compose exec sunzhongwei.com sh

# cp -R upload app/upload
# cp -R sitemap app/sitemap

因为原配置里,已经把 /var/www/sunzhongwei.com 映射到了 /app 目录下,所以备份到 /app/upload 和 /app/sitemap 下即可。

备份完成后,从宿主机的目录里就能看到 upload 和 sitemap 两个目录了。

如何使 working_dir 的配置生效

执行:

docker compose up -d <容器名>

即可。不需要先 stop,因为当你对正在运行的服务执行 docker compose up -d 时,Docker Compose 会自动按顺序执行以下操作:

  1. 构建上下文:检查镜像等依赖(如果配置了build)。
  2. 停止容器:自动停止指定服务(例如 sunzhongwei.com)当前正在运行的容器。
  3. 删除容器:移除刚才停止的旧容器。
  4. 创建新容器:根据 docker-compose.yml 中的最新配置(包含你新加的 working_dir)创建一个全新的容器。
  5. 启动容器:启动这个新容器。

所以只需执行一条命令即可。

需要注意的是:

docker compose restart <容器名>

只是重启现有容器,不会重新加载 docker-compose.yml 的变更。所以,如果只是执行 restart,新配置是不会生效的。

操作流程总结

完整且正确的操作步骤:

  1. 备份数据目录(如果有需要保留的数据目录)。
  2. 修改配置:在 docker-compose.yml 中为指定服务添加 working_dir: /app。
  3. 执行一条命令:在 docker-compose.yml 目录下运行 docker compose up -d <容器名>

验证

# docker compose exec sunzhongwei.com pwd
/app

或者进入容器:

docker compose exec sunzhongwei.com sh

会发现默认的目录已经不是 / 而变成了 /app.

并且之前存在 docker 中的那两个目录也消失了。

关于作者 🌱

我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式