С jwilder nginx-proxy, как передать URL-адрес подкаталога в конкретный контейнер?

Я использую jwilder/nginx-proxy для создания обратного прокси. Я пытаюсь перенаправить http://localhost:8000/api на конкретную службу php.

Структура каталога:

.
+-- docker-compose.yml
+-- nginx
+-- nodejs
|   +-- index.js
|   +-- …
+-- php
|   +-- api

докер-compose.yml:

version: "3.1"

services:

  nginx-proxy:
    image: jwilder/nginx-proxy:alpine
    ports:
      - "8000:80"
    volumes:
      - ./php:/srv/www
      - /var/run/docker.sock:/tmp/docker.sock:ro

  nodejs:
    image: node:alpine
    environment: 
      - NODE_ENV=production
      - VIRTUAL_HOST=localhost
      - VIRTUAL_PORT=8080
    expose:
      - "8080"
    working_dir: /home/app
    restart: always
    volumes:
      - ./nodejs:/home/app
    command: ["node", "index.js"]

  php:
    image: php:apache
    environment:
      - VIRTUAL_HOST=localhost
    volumes:
      - ./php:/var/www/html

Это отлично работает для службы nodejs.

Теперь я хочу перенаправить вызовы с http://localhost:8000/api на службу php. Думаю, мне нужно добавить к nginx conf что-то вроде:

server {
  location /api {
    proxy_pass http://php:80/api;
    proxy_set_header Host $host;
  }
}

Эта функция не встроена в библиотеку. Итак, как я могу этого добиться?


person François Romain    schedule 07.07.2017    source источник


Ответы (1)


Один из подходов — предоставить приложению php собственный виртуальный хост:

  php:
    image: php:apache
    environment:
      - VIRTUAL_HOST=api.localhost
    volumes:
      - ./php:/var/www/html

Тогда он будет доступен следующим образом:

curl -H 'Host: api.localhost' http://localhost:8000/api

Настроить заголовок можно практически на любом языке. Или, чтобы не устанавливать собственный заголовок, вы можете добавить этот DNS в свой файл /etc/hosts:

127.0.0.1 api.localhost

Таким образом, вы можете свернуться так:

curl -H http://api.localhost:8000/api

Вот как установить пользовательские заголовки, например, в узле:

var request = require('request')

var formData = {}

request({
    headers: {
      'Host': 'api.localhost'
    },
    uri: 'http://localhost:8080',
    method: 'POST'
  }, function (err, res, body) {
      console.log("it works")
      console.log(res)
    }
)

Но я рекомендую вам использовать подход /etc/hosts, который должен иметь эквивалент в производственной среде (DNS-сервер). Так что вам не нужно трогать код узла.

person Robert    schedule 07.07.2017
comment
Не могли бы вы показать пример того, как/где я могу установить собственный заголовок, пожалуйста? - person François Romain; 07.07.2017
comment
Спасибо. Изменение DNS удаляет портативную логику Docker. Изменение заголовков в каждом запросе также не является легким. В конце концов, jwilder/nginx-proxy действительно усложняет вещи по сравнению с простой конфигурацией nginx в моем предыдущем вопросе… Я должен подумать об этом - person François Romain; 07.07.2017
comment
Имеет ли смысл изменять файл /etc/hosts внутри контейнера nginx? - person François Romain; 08.07.2017
comment
Нет, я не знаю. Nginx связывается с каждым контейнером по их IPS. Но для доступа к php API из узла просто сделайте следующее: http://php/api, нет необходимости проходить через nginx, если php не масштабируется - person Robert; 08.07.2017