You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Dockerfile访问Docker Compose创建的卷并复制文件?

问题

在Docker Compose中创建了一个卷,希望将文件复制到该卷中,需要编写对应的Dockerfile,但不清楚如何通过Dockerfile访问Docker Compose里创建的卷,请问该如何操作?

提供的配置文件如下:

docker-compose.yml

version: '3'
services:
  postgres:
    image: postgres
    hostname: postgres
    restart: always
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: test
      POSTGRES_USER: test
      POSTGRES_PASSWORD: test
 
  pgadmin:
    image: dpage/pgadmin4
    restart: always
    ports:
      - "5433:80"
    environment:
      PGADMIN_DEFAULT_EMAIL: test@gmail.com
      PGADMIN_DEFAULT_PASSWORD: test
    depends_on: 
      - postgres

  web:
    build:
      context: ../
      dockerfile: spring/Dockerfile
    ports:
      - "8080:8080"
    depends_on:
      - postgres
    volumes:
      - ./test-volume:/opt/_LIB/

Dockerfile

FROM ...

RUN rm -rf /var/lib/jetty/webapps/*
COPY spring/target/*.war /var/lib/jetty/webapps/

EXPOSE 8080
#CMD ["java", "-jar", "$JETTY_HOME/start.jar"]
解决方案

首先明确:Dockerfile构建镜像的阶段无法直接访问Docker Compose定义的卷,因为镜像构建是独立于容器运行的流程,挂载卷是容器启动时才会执行的操作。下面提供几种可行的实现方式:

方式一:容器启动时复制文件到卷目录

利用容器启动命令,先将镜像内的目标文件复制到卷挂载的目录(/opt/_LIB/),再启动应用。

修改Dockerfile的CMD指令,添加复制步骤:

FROM ...

RUN rm -rf /var/lib/jetty/webapps/*
COPY spring/target/*.war /var/lib/jetty/webapps/

EXPOSE 8080
CMD ["sh", "-c", "cp /var/lib/jetty/webapps/*.war /opt/_LIB/ && java -jar $JETTY_HOME/start.jar"]

如果需要更复杂的启动逻辑,可以编写一个启动脚本:

  1. 在项目目录下创建startup.sh脚本:
#!/bin/sh
# 复制文件到卷目录
cp /var/lib/jetty/webapps/*.war /opt/_LIB/
# 启动Jetty服务
java -jar $JETTY_HOME/start.jar
  1. 修改Dockerfile,将脚本复制到镜像并设置执行权限:
FROM ...

RUN rm -rf /var/lib/jetty/webapps/*
COPY spring/target/*.war /var/lib/jetty/webapps/
# 复制并配置启动脚本
COPY spring/startup.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/startup.sh

EXPOSE 8080
CMD ["startup.sh"]

方式二:提前将文件复制到宿主机绑定目录

你当前使用的是绑定挂载(将宿主机./test-volume目录挂载到容器/opt/_LIB/),可以直接在宿主机上将需要的文件复制到./test-volume目录,容器启动后会自动读取该目录下的文件。

比如在构建镜像的脚本中添加一步:

cp spring/target/*.war ./test-volume/

方式三:改用命名卷利用自动初始化特性

如果将绑定挂载改为Docker命名卷,当卷为空时,Docker会自动将镜像中对应挂载目录的内容复制到卷中。

修改docker-compose.yml:

version: '3'
services:
  # ... 其他服务保持不变
  web:
    build:
      context: ../
      dockerfile: spring/Dockerfile
    ports:
      - "8080:8080"
    depends_on:
      - postgres
    volumes:
      - test-volume:/opt/_LIB/
# 添加命名卷定义
volumes:
  test-volume:

此时需要确保镜像中/opt/_LIB/目录有需要的文件,所以可以修改Dockerfile将war包复制到该目录:

FROM ...

RUN rm -rf /var/lib/jetty/webapps/*
COPY spring/target/*.war /var/lib/jetty/webapps/
# 同时复制到/opt/_LIB/,供命名卷初始化使用
COPY spring/target/*.war /opt/_LIB/

EXPOSE 8080
CMD ["java", "-jar", "$JETTY_HOME/start.jar"]

注意:这个特性仅在命名卷第一次创建且为空时生效,后续启动不会覆盖卷内已有内容。


内容的提问来源于stack exchange,提问作者user19763876

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 06:40:35