使用nginx的Docker多容器设置Nginx无法识别主机(在上游找不到主机)

时间:2020-01-21 11:08:52

标签: docker nginx

因此,我正在学习Docker,以及如何将应用容器化为服务。不确定我是否能完全理解。

我有三项服务:

  1. web-server nginx服务器,将端口80和443绑定到外部。基本上是应用程序的“前端”。
  2. app1 NodeJS应用程序,可在端口3000上提供内容
  3. app2 NodeJS应用程序,在端口3000上提供内容,基本上是app1的克隆,我仅将其用于学习目的。

现在,我要在产品中运行此“应用程序”的想法是启动docker-compose up来启动所有服务。这是启动多容器应用程序的正确方法吗?

我的仓库结构是这样:

.
├── Dockerfile
├── app1
│   ├── Dockerfile
│   ├── index.js
│   ├── package-lock.json
│   └── package.json
├── app2
│   ├── Dockerfile
│   ├── index.js
│   ├── package-lock.json
│   └── package.json
├── docker-compose.yml
├── index.html
└── web-server.conf

Dockerfile用于web-server服务。我的docker-compose.yml看起来像这样:

version: '3'
services:
  web-server:
    container_name: web-server
    build: .
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - app1
      - app2
  app1:
    container_name: app1
    build: ./app1
    restart: always
  app2:
    container_name: app2
    build: ./app2
    restart: always

命令docker-compose up生成app1app2图像,但是在web-server图像上失败,因为nginx引发错误:

host not found in upstream "app1" in /etc/nginx/conf.d/default.conf:11
nginx: [emerg] host not found in upstream "app1" in /etc/nginx/conf.d/default.conf:11

web-server服务Dockerfile

FROM nginx:alpine
EXPOSE 80

COPY ./web-server.conf /etc/nginx/conf.d/default.conf
COPY ./index.html /var/www/html/

RUN apk add bash

RUN nginx

web-server.conf的内容:

server {
 listen *:80;
 server_name web_server;
 root /var/www/html;

 location / {
   index index.html;
 }

 location /app1 {
   proxy_pass http://app1:3000;
   proxy_redirect off;
 }

 location /app2 {
   proxy_pass http://app2:3000;
   proxy_redirect off;
 }
}

在我看来,nginx的配置在构建时无法识别http://app1主机名。我尝试进行实验,并将proxy_pass指令的值替换为localhost。这将构建可以与其他图像一起运行的图像。如果我执行bundle exec -it web-server-image /bin/bash并且尝试了curl http://app1:3000,那么它可以工作。如果我编辑nginx配置以指向这些URL,它将开始起作用。

所以我想我到了那里,但是运行docker-compose up时似乎无法识别主机名。

有什么想法吗?我的方法正确吗?

1 个答案:

答案 0 :(得分:1)

如果仅删除Web服务器RUN末尾的两行Dockerfile,则可以正常工作。

如果您查看nginx图片的Dockerfile,以

结尾
CMD ["nginx", "-g", "daemon off;"]

它将被您的图像继承;您无需执行任何特殊操作即可使Nginx在容器启动时启动。

同时,在Dockerfile运行时,构建序列在相当隔离的环境中运行:未设置Compose网络环境,未必在运行其他容器,未连接卷,等。唯一生效的自定义设置是docker-compose.yml文件中build:块中的特定设置。

因此:当Dockerfile运行RUN nginx时,它将尝试在构建环境中启动nginx,但是它没有连接到Compose网络,因此失败。但是您根本不需要这样做,因为基本图像已经具有CMD nginx ...设置,只需删除该行即可解决。