Docker - 从另一个容器访问nginx容器,使用nginx server_name

3
我有一个使用node.js编写的Web应用程序,以及两个使用Lumen编写的应用程序(API和客户端API),由监听端口80的nginx容器进行负载均衡。
我的docker-compose.yml文件:
version: '2'
services:
  nginx:
    build:
      context: ../
      dockerfile: posbytz-docker/nginx/dockerfile
    volumes:
      - api
      - customer-api
    ports:
      - "80:80"
    networks:
      - network
    depends_on:
      - web-app
      - api
      - customer-api
  web-app:
    build:
      context: ../
      dockerfile: posbytz-docker/web-app-dockerfile
    volumes:
      - ../web-app:/posbytz/web-app
      - /posbytz/web-app/node_modules
    ports:
      - "3004:3004"
    networks:
      - network
  api:
    build:
      context: ../
      dockerfile: posbytz-docker/api-dockerfile
    volumes:
      - ../api:/var/www/api
    networks:
      - network
  customer-api:
    build:
      context: ../
      dockerfile: posbytz-docker/customer-api-dockerfile
    volumes:
      - ../customer-api:/var/www/customer-api
    networks:
      - network
  redis:
    image: redis
    ports:
      - "6379:6379"
    networks:
      - network
  memcached:
    image: memcached
    ports:
      - "11211:11211"
    networks:
      - network
  mysql:
    image: mysql:5.7
    volumes:
      - ./db-data:/var/lib/mysql
    ports:
      - "3306:3306"
    networks:
      - network
  adminer:
    image: adminer
    restart: always
    ports:
      - "9001:8080"
    networks:
      - network
networks:
  network:
    driver: bridge

由于我使用的是桥接网络,因此可以使用容器名称从一个容器访问另一个容器。但是我想要的是,使用其nginx配置文件的server_name访问容器。
以下是每个应用程序的nginx配置:

web-app.conf:

server {
  listen 80;
  server_name posbytz.local;
    resolver 127.0.0.11 valid=10s;

  location / {
    proxy_pass http://web-app:3004;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
}

api.conf:

server {
  listen 80;
  index index.php index.html;
  root /var/www/api/public;
  server_name api.posbytz.local;
    resolver 127.0.0.11 valid=10s;

  location / {
    try_files $uri /index.php?$args;
  }

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass api:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}

customer-api.conf

server {
  listen 80;
  index index.php index.html;
  root /var/www/customer-api/public;
  server_name customer-api.posbytz.local;
    resolver 127.0.0.11 valid=10s;

  location / {
    try_files $uri /index.php?$args;
  }

  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass customer-api:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
  }
}

问题

我想从web-app容器访问api和customer-api容器。问题在于,当我尝试使用curl http://nginx时,我只会从api容器获得响应。有没有办法通过nginx容器访问customer-api容器?

我尝试过的方法

当我手动将nginx容器的IP地址(172.21.0.9)与它们在web-app容器中的相应server_name映射到/etc/hosts文件中时,似乎可以正常工作。

我在web-app容器的/etc/hosts文件中添加的内容:

172.21.0.9  api.posbytz.local
172.21.0.9  customer-api.posbytz.local

有没有其他方法可以在不需要手动干预的情况下实现这一点?


1
你不能在web-app容器内使用http://apihttp://customer-api吗?(也许你应该在url中使用端口,即http://api:9000)。我认为通过服务名称作为主机从某个容器访问容器是一种常见的做法。而不是通过另一个容器反向代理。此外,我想知道为什么nginx容器将http://nginx解析为api应用程序... - Slava Nikulin
@SlavaNikulin,我想通过反向代理访问这两个API,因为它们都配置了nginx fastcgi转发到php-fpm,所以在这种情况下http://api:9000无法使用,而http://nginx会解析到API应用程序,因为它监听端口80并将其转发到http://api:9000 - Harish Mohan
2个回答

2

最终成功了,通过更改customer-api.conf上的nginx配置,将监听端口从80更改为81,即将listen 80;更改为listen 81;。现在http://nginx解析为http://api:9000,而http://nginx:81解析为http://customer-api:9000


2
基本上这不是一个答案,而是一个试探性的尝试。它不具备可扩展性。也许有人知道如何在Docker中处理这个问题的正确答案? - KorbenDallas

1
你可以使用别名:

networks:
  some-network:
    aliases:
      - api.posbytz.local
      - customer-api.posbytz.local

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