从 compose 容器访问 dockerfile 的卷

Access volume of dockerfile from compose container

我是 Docker 的新手,一直在努力实现以下目标,但似乎无法正常工作。

我想创建一个图像来保存一些静态文件。然后,我想从另一个容器访问包含静态文件的文件夹。

为此,我首先创建了一个包含以下信息的 docker 文件:

FROM alpine
WORKDIR /usr/local/apache2/htdocs
ADD static /usr/local/apache2/htdocs
VOLUME /usr/local/apache2/htdocs

然后我从该 docker 文件创建了一个图像 运行 宁以下命令:

docker build -t customimage .

然后在我的 docker-compose.yaml 中,我启动了两个这样的服务:

version: '3.7'
services:
    custom:
        image: customimage:latest
        tty: true
    apache:
        image: httpd:latest
        volumes:
            - /usr/local/apache2/htdocs
        ports: 
            - "80:80"

在完成 docker-compose 后,两个服务都启动了,但是我无法从 apache 容器访问来自自定义映像的卷。

我在这里错过了什么?我知道我可以使用 运行 命令,但我更喜欢使用 docker-compose,因为我将来会添加更多服务。

我建议您声明一个 docker 卷以在两个容器之间共享。然后可以使用卷路径中的一些数据预先构建其中一个容器。然后另一个容器可以装载相同的卷,并将看到相同的数据。

这里需要注意的一个非常重要的细节是 - 如果将卷中的文件绑定到其他容器的文件系统中的某个位置,则卷中的文件在安装容器中将不可见文件已经存在。 它需要是一个空位置!

为了使这项工作适合您,您需要为您的 httpd 映像创建一个 Dockerfile,因为我们需要在我们将绑定的卷中的文件可见之前清理目标位置。

解决方法

我建议这样的项目布局:

/
├─ data.Dockerfile
├─ docker-compose.yml
├─ httpd.Dockerfile
├─ index.html 

这是在 httpd 容器中 运行 最小网站的示例,它从主机安装的卷为网站提供服务。一个也安装到 sidekick "data container" 中的卷,它预先填充了网站(单个 index.html 文件,为了保持简洁)

文件内容如下:

data.Dockerfile

FROM alpine

# declare a volume at location /var/shared_volume
VOLUME /var/shared_volume
# copy your new great site into the volume location
COPY index.html /var/shared_volume/

# configure an entrypoint that does not terminate, to keep the container up
ENTRYPOINT [ "tail", "-f", "/dev/null" ]

httpd.Dockerfile

FROM httpd:latest

# remove any file and directory at the location where we wantt serve 
# the static content 
RUN rm -rf /usr/local/apache2/htdocs/*

# declare the path as a volume
VOLUME /usr/local/apache2/htdocs

docker-compose.yml

version: "3.7"

# declare the volume to share between the containers
volumes:
  shared_volume:

services:
  data:
    build:
      context: ./
      dockerfile: data.Dockerfile
    container_name: data
    volumes:
      - "shared_volume:/var/shared_volume"
  httpd:
    build:
      context: ./
      dockerfile: httpd.Dockerfile
    container_name: httpd
    volumes:
      - "shared_volume:/usr/local/apache2/htdocs"
    ports:
      - "80:80"

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Is this page visible in your httpd container?</title>
  </head>
  <body>
    <h1>I sure hope you can see this page?</h1>
  </body>
</html>

shared_volume 现在将成为在主机上管理的 docker 卷。两个容器都会将其挂载到各自文件系统中的路径。

运行例子

只是 docker-compose up,当这是 运行 访问 http://localhost

我创建了a gist with the solution here.


简要说明,直接从一个容器安装到另一个容器

如果您想将目录直接从 "data container" 挂载到您的 apache 容器中 - 那么您将 运行 陷入一堆问题。这些在这个问题的答案中得到了最好的解释: