Docker + NGINX,如何将配置文件从主机复制到容器中?

10

这是我基本的NGINX设置,可以正常工作!

web:
  image: nginx
  volumes:
   - ./nginx:/etc/nginx/conf.d
  ....
我通过将./nginx复制到/etc/nginx/conf.d,使用COPY ./nginx /etc/nginx/conf.d替换了volumes。问题是,使用值时,nginx.conf将引用主机上的日志文件,而不是容器中的文件。因此,我认为通过将配置文件硬拷贝到容器中,可以解决我的问题。
然而,在docker-compose up时,NGINX根本没有运行。出了什么问题?
编辑后的Dockerfile
FROM python:3-onbuild

COPY ./ /app
COPY ./nginx /etc/nginx/conf.d

RUN chmod +x /app/start_celerybeat.sh
RUN chmod +x /app/start_celeryd.sh
RUN chmod +x /app/start_web.sh

RUN pip install -r /app/requirements.txt
RUN python /app/manage.py collectstatic --noinput
RUN /app/automation/rm.sh

docker-compose.yml

version: "3"  
services:  
  nginx:
    image: nginx:latest
    container_name: nginx_airport
    ports:
      - "8080:8080"
  rabbit:
      image: rabbitmq:latest
      environment:
          - RABBITMQ_DEFAULT_USER=admin
          - RABBITMQ_DEFAULT_PASS=asdasdasd
      ports:
          - "5672:5672"
          - "15672:15672"
  web:
    build:
      context: ./
      dockerfile: Dockerfile
    command: /app/start_web.sh
    container_name: django_airport
    expose:
      - "8080"
    links:
      - rabbit
  celerybeat:
    build: ./
    command: /app/start_celerybeat.sh
    depends_on:
      - web
    links:
      - rabbit
  celeryd:
    build: ./ 
    command: /app/start_celeryd.sh
    depends_on:
      - web
    links:
      - rabbit

如果您已经用COPY替换了volumes标签,那么您应该粘贴您的Dockerfile以便全面查看您的问题。 - lifeisfoo
@lifeisfoo,抱歉我更新了我的回答。Dockerfile是用于“web”服务的Dockerfile。它在NGINX启动之前加载,所以我认为将其放在那里是合适的。 - notalentgeek
看起来你把 webnginx 搞混了。如果你想要一个自定义的 nginx 镜像,你需要为它准备一个单独的 Dockerfile-nginx 文件。 - schmunk
@schmunk,是吗?因为NGINX只需要COPY ./nginx /etc/nginx/conf.d,所以我认为我可以将其放在与web相同的Dockerfile中。因为无论如何web始终是第一个。 - notalentgeek
1
@notalentgeek 如果这个答案解决了你的问题,请接受它。这样未来的访问者就可以认识到它。 - lifeisfoo
1个回答

9

以下是可行的初始设置:

web:
  image: nginx
  volumes:
   - ./nginx:/etc/nginx/conf.d

这里有一个绑定卷,将容器内所有文件系统请求转发到主机的./nginx路径下的/etc/nginx/conf.d。因此不会有复制,只有绑定。 这意味着如果您更改./nginx文件夹中的文件,容器将实时看到更新后的文件。
从主机加载配置 在您的上次设置中,只需在nginx服务中添加一个volume即可。 您还可以从Web服务的Dockerfile中删除COPY ./nginx /etc/nginx/conf.d行,因为这是无用的。
在镜像中捆绑配置 相反,如果要将Nginx配置捆绑在Nginx映像中,则应构建自定义Nginx映像。创建一个Dockerfile.nginx文件:
FROM nginx
COPY ./nginx /etc/nginx/conf.d

然后更改您的docker-compose文件:

version: "3"  
services:  
  nginx:
    build:
      dockerfile: Dockerfile.nginx
      container_name: nginx_airport
      ports:
        - "8080:8080"
# ...

现在您的nginx容器将拥有内部配置,您无需使用卷。

不,那不是我的意思。我想把NGINX配置放在容器内部。不是通过挂载,因此使用了COPY。然而,使用COPY复制NGINX配置后,似乎我的容器中的NGINX根本无法运行,尽管挂载位置和复制位置都是相同的。 - notalentgeek
3
容器具有隔离的文件系统,因此如果您将nginx配置文件复制到Web服务镜像内部,nginx容器将无法“看到”它。只有在Web服务容器内部的进程才能看到它。 - lifeisfoo
@lifeisfoo所详细说明的内容与我在上面的评论中试图表达的相同。如果您在web镜像上有配置文件,则可以在nginx镜像中使用volumes_from: -web,但我强烈建议不要这样做,因为这会在尝试更新容器时产生许多奇怪的副作用。 - schmunk
在使用Docker Compose时,您不能将文件复制到容器中。这是因为维护者发现这种做法短视,因为每次创建容器时都需要重复执行COPY操作,例如运行docker-compose。这在社区中引起了很大争议,您可以在此处查看https://github.com/docker/compose/issues/5523。坦白地说,我认为维护者是“正确”的,但是...当我只想复制一个`nginx.conf`文件时,现在我需要在项目根目录下创建一个单独的`Dockerfile`。无所谓,我猜。 - Nick Brady
@lifeisfoo,我也有类似的要求,我使用“COPY ./nginx /etc/nginx/conf.d”将我的配置复制到nginx映像中,但是它失败并显示错误“Service 'nginx' failed to build: COPY failed: stat /var/lib/docker/tmp/docker-builder483163179/config/nginx/conf.d: no such file or directory”。我该如何解决?我的Dockerfile不在根目录中,但docker-compose在根目录中。这可能是原因吗? - Bharath

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接