Рубрики
Uncategorized

Настройка обратной прокси с Nginx и Docker-Compose

Nginx-это отличная часть программного обеспечения, которое позволяет легко обернуть ваше приложение в обратную прокси, которая затем может обрабатывать связанные с сервером аспекты, такие как SSL и кэширование, полностью прозрачные для приложения, стоящего за ним. Tagged with Nginx, DockerCompose, Server, DevOps.

Nginx-это отличная часть программного обеспечения, которое позволяет легко обернуть ваше приложение в обратную прокси, которая затем может обрабатывать связанные с сервером аспекты, такие как SSL и кэширование, полностью прозрачные для приложения, стоящего за ним.

Это кросс-стой из моего личный сайт Анкет

Введение

Некоторые аспекты веб -приложений, такие как шифрование SSL, запрос кэширования и обнаружения услуг, могут управляться за пределами самого приложения. Реверс-прокси, такие как Nginx, могут выполнять многие из этих обязанностей, поэтому нам, разработчикам, не нужно думать об этом в нашем программном обеспечении.

Кроме того, некоторое программное обеспечение не предназначено для того, чтобы быть доступным через Интернет, поскольку не имеют надлежащих мер безопасности. Многие базы данных такие. И это хорошая практика в целом не делать внутренних услуг публичными, которые не должны быть.

Все это может быть достигнуто с помощью Docker-Compose и Nginx.

докер-состав

Docker-Compose это аккуратный маленький инструмент, который позволяет вам определить диапазон контейнеров Docker, которые следует запустить одновременно, и с конфигурацией, с которой они должны начинать. Это включает в себя экспортируемые порты, сети, к которым они принадлежат, объемы, отображаемые с ним, переменные среды и все остальное, что можно настроить с помощью Docker Run командование

В этом разделе я кратко объясню, как настроить функции Docker-Compose, используемые в этой статье. Для получения более подробной информации посмотрите на Документация Анкет

Основная точка входа — это Docker-compose.yml файл. Он настраивает все аспекты контейнеров, которые следует запустить вместе.

Вот пример Docker-compose.yml :

version: '3'
services:
  nginx: 
    image: nginx:latest
    container_name: production_nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 80:80
      - 443:443

  ismydependencysafe:
    image: ismydependencysafe:latest
    container_name: production_ismydependencysafe
    expose:
      - "80"

Как видите, указанное 2 изображения. Первый nginx , с именем Production_nginx . Он определяет том, который заменяет файл конфигурации NGINX по умолчанию. Также определено отображение портов хоста 80 и 443 с портами контейнера 80 и 443. Второе изображение — одно, которое я создал сам. Он обнажает порт 80. Разница в порты Конфигурация заключается в том, что они не публикуются в хост -машине. Вот почему он также может указать порт 80, хотя nginx уже сделал.

В этой статье используются несколько других параметров конфигурации, в частности, сети, объемы и переменные среды.

Сети

С сети возможно конкретно, какие контейнеры могут разговаривать друг с другом. Они указаны в виде новой записи корневой конфигурации и на конфигурациях контейнеров.

version: '3'
services:
  nginx:
    ...
    networks:
      - my-network-name

  ismydependencysafe:
    ...
    networks:
      - my-network-name

networks:
  my-network-name:

В корневом объекте Сети , сеть My-NetWork-name определено. Каждый контейнер назначается этой сети, добавив его в Сеть список.

Если не указана сеть, все контейнеры находятся в одной и той же сети, которая создается по умолчанию. Поэтому, если используется только одна сеть, вообще не должна быть указана сеть.

Удобная особенность сетей заключается в том, что контейнеры в одном и том же могут ссылаться друг на друга по имени. В примере выше, URL http://ismydependencysafe Согласится в контейнер ismydependencysafe .

Тома

Объемные определяют постоянное хранение для контейнеров Docker. Если приложение где -то записывает где -то ни одного тома, эти данные будут потеряны, когда контейнер останавливается.

Есть 2 типа томов. Те, которые отображают файл или каталог в один внутри контейнера, и те, которые просто делают файл или каталог постоянными (с именованными томами), не делая их доступными в файловой системе (конечно, они где -то есть , Но это специфичная для реализации Docker и не должно быть вмешательством).

Первый тип, объемы, которые отображают определенный файл или каталог в контейнер, мы уже видели в примере выше. Вот снова, с дополнительным томом, который также указывает каталог таким же образом:

version: '3'
services:
  nginx: 
    image: nginx:latest
    container_name: production_nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - /etc/letsencrypt/:/etc/letsencrypt/
...

Именованные объемы указаны аналогично сетям, в виде отдельной записи конфигурации корня и непосредственно в конфигурации контейнера.

version: '3'
services:
  nginx:
    ...
    volumes:
      - "certificates:/etc/letsencrypt/"

    ...

volumes:
  certificates:
...

Переменные среды

Docker также может указать переменные среды для приложения в контейнере. В конфигурации Compose есть несколько способов сделать это, либо указав файл, который их содержит, либо объявив их непосредственно в Docker-compose.yml Анкет

version: '3'
services:
  nginx:
    ...
    env_file:
      - ./common.env
    environment:
      - ENV=development
      - APPLICATION_URL=http://ismydependencysafe
    ...

Как вы можете видеть, оба способа также могут быть использованы одновременно. Просто будьте в курсе эти переменные, установленные в среда перезаписывайте те, которые загружены из файлов.

Файлы среды должны иметь формат Var = val , одна переменная на каждой строке.

ENV=production
APPLICATION_URL=http://ismydependencysafe

Кли

Команды запуска и остановки контейнеров довольно просты.

Чтобы начать использовать Docker -Compose -u -d Анкет Указывает, что это должно быть запущено на заднем плане. Без этого контейнеры будут остановлены, когда командная строка закрыта.

Чтобы прекратить использование Docker-Compose Down Анкет

Обе команды ищут Docker-compose.yml Файл в текущем каталоге. Если это где -то еще, укажите это с -f Path/to/docker-compose.yml Анкет

Теперь, когда основы Docker-Compose ясны, давайте перейдем к Nginx.

Nginx

Nginx — это веб -сервер с широким спектром функций, включая обратное прокси, для чего он используется в этой статье. Он настроен с nginx.conf Анкет По умолчанию он ищет это в /etc/nginx/nginx.conf , но, конечно, можно указать другой файл.

В качестве обратного прокси -сервера он может провести проходное обращение с двумя очень важными аспектами веб -приложения, шифрования и кэширования. Но прежде чем подробно рассказывать об этом, давайте посмотрим, как настроена сама функция обратного прокси:

http {
  server {
    server_name your.server.url;

    location /yourService1 {
      proxy_pass http://localhost:80;
      rewrite ^/yourService1(.*)$ $1 break;
    }

    location /yourService2 {
      proxy_pass http://localhost:5000;
      rewrite ^/yourService1(.*)$ $1 break;
    }
  }

  server {
    server_name another.server.url;

    location /yourService1 {
      proxy_pass http://localhost:80;
      rewrite ^/yourService1(.*)$ $1 break;
    }

    location /yourService3 {
      proxy_pass http://localhost:5001;
      rewrite ^/yourService1(.*)$ $1 break;
    }
  }
}

Конфигурация Nginx организована в Контексты , которые определяют тот вид трафика, который они обрабатывают. http Контекст (очевидно) обрабатывает трафик HTTP. Другие контексты почта и ручей .

сервер Конфигурация указывает виртуальный сервер, где каждый может иметь свои собственные правила. server_name Директива определила, какие URL -адреса или IP -адреса отвечает виртуальный сервер.

Место Конфигурация определяет, куда маршрутируется входящий трафик. В зависимости от URL -адреса запросы могут быть переданы той или иной службе. В приведенном выше конфигурации начало маршрута указывают службу. proxy_pass Устанавливает новый URL и с Переписать URL -адрес переписан, чтобы он соответствовал услуге. В этом случае YourserVice {x} удален из URL.

Это был общий обзор, более поздние разделы объяснят, как можно настроить кэширование и SSL.

Для получения более подробной информации, проверьте Документы Анкет

Теперь, когда мы знаем кусочки, давайте начнем собирать их вместе.

Настройка nginx как обратная прокси внутри Docker

Для базовой настройки необходимы только 3 вещи:

1) Сопоставление портов хоста в контейнерные порты 2) Сопоставление файла конфигурации в файл конфигурации NGINX по умолчанию по адресу /etc/nginx/nginx.conf 3) Конфигурация NGINX

В файле Docker-Compose отображение порта может быть сделано с помощью порты Запись конфигурации, как мы видели выше.

    ...
    ports:
      - 80:80
      - 443:443
    ...

Картирование для конфигурации NGINX выполняется с томом, который мы также видели раньше:

    ...
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ...

Предполагается, что конфигурация NGINX находится в том же каталоге, что и Docker-compose.yml ( ./nginx.conf ), Но это может быть где -то, конечно.

Конфигурация кэша

Добавить кэширование в настройку довольно просто, только конфигурация Nginx должна быть изменена. В http контекст, добавьте proxy_cache_path Директива, которая определяет локальный путь файловой системы для кэшированного контента и имени и размер зоны памяти. Имейте в виду, что путь внутри Контейнер, а не в файловой системе хоста.

http {
    ...
    proxy_cache_path /data/nginx/cache keys_zone=one:10m;
}

В сервер или Место Контекст, для которого ответы должны быть кэшированы, добавьте proxy_cache Директива с указанием зоны памяти.

  ...
  server {
    proxy_cache one;
  ...

Этого достаточно, чтобы определить кэш с помощью конфигурации кэширования по умолчанию. Есть много других директив, которые указывают, какие ответы на кэш гораздо более подробно. Для получения более подробной информации об этом взгляните на Документы Анкет

Защита трафика HTTP с помощью SSL

К настоящему времени настройка сервера завершена. Docker-Compose запускает все контейнеры, а контейнер Nginx действует как обратная прокси для Сервисов. Остается только одна вещь, чтобы настроить, как это Сайт так красиво объясняет, шифрование.

Чтобы установить Certbot, клиент, который получает сертификаты из Let’s Encrypt, следуйте Установить инструкции Анкет

Создание сертификатов SSL с помощью CertBot

У Certbot есть множество способов получить сертификаты SSL. Существуют плагины для широко распространенных веб -серверов, таких как Apache и Nginx, один для использования автономного веб -сервера для проверки домена, и, конечно, ручным способом.

Мы будем использовать автономный плагин. Он запускает отдельный веб -сервер для конкурса сертификации, что означает, что порт 80 или 443 должен быть доступен. Чтобы это работало, NGINX WebServer должен быть отключен, поскольку он связывается с обоим портами, и сервер CertBot должен иметь возможность принимать входящие подключения, по крайней мере, на одном из них.

Чтобы создать сертификат, выполнить

certbot --standalone -d your.server.url

и следуйте инструкциям. Вы также можете создать сертификат для нескольких URL -адресов одновременно, добавив больше параметры, например, -d your.server1.url -Д your.server2.url Анкет

Автоматизация продления сертификата

Let’s Encrypt CA выпускают недолговечные сертификаты, они действительны только в течение 90 дней. Это делает автоматизацию процесса обновления важным. К счастью, Certbot упрощает команду Certbot rebene Анкет Он проверяет все установленные сертификаты и обновляет те, которые истекают менее чем за 30 дней.

Он будет использовать тот же плагин для обновления, который использовался при первоначальном получении сертификата. В нашем случае это автономный плагин.

Процесс задачи такой же, поэтому для обновления порты 80 или 443 должны быть бесплатными. Certbot предоставляет Pre and Post Hooks, которые мы используем для остановки и запуска WebServer во время обновления, чтобы освободить порты. Крюки выполняются только в том случае, если сертификат необходимо продлить, поэтому в ваших услугах нет ненужного простоя.

Поскольку мы используем Docker-Compose , вся команда выглядит так:

certbot renew --pre-hook "docker-compose -f path/to/docker-compose.yml down" --post-hook "docker-compose -f path/to/docker-compose.yml up -d"

Чтобы завершить автоматизацию, просто добавьте предыдущую команду как Cronjob. Откройте файл Cron с crontab -e Анкет В там добавьте новую линию с

@daily certbot renew --pre-hook "docker-compose -f path/to/docker-compose.yml down" --post-hook "docker-compose -f path/to/docker-compose.yml up -d"

Вот и все. Теперь команда Renew выполняется ежедневно, и вам не придется беспокоиться о дате истечения срока действия ваших сертификатов.

Использование сертификатов в контейнере Nginx Docker

К настоящему времени сертификаты запрашиваются и хранятся на сервере, но мы еще не используем их. Чтобы достичь этого, мы должны

1) Сделайте сертификаты доступными в контейнер Nginx и 2) изменить конфигурацию на их использование

Чтобы сделать сертификаты доступными для контейнера Nginx, просто укажите целое LetsEncrypt каталог как объем на нем.

  ...
  nginx: 
    image: nginx:latest
    container_name: production_nginx
    volumes:
      - /etc/letsencrypt/:/etc/letsencrypt/
  ...

Адаптация конфигурации и ее безопасность — немного больше работы. По умолчанию виртуальный сервер прослушивает порт 80, но с SSL он также должен прослушать порт 443. Это должно быть указано 2 Слушай Директивы. Кроме того, сертификат должен быть определен. Это делается с ssl_certificate и ssl_certificate_key Директивы.

  ...
  server {
    ...
    listen 80;
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/your.server.url/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your.server.url/privkey.pem;
  }
  ...

Эти небольшие изменения достаточно для настройки Nginx для SSL. Он использует настройки SSL по умолчанию Nginx, что в порядке, но можно улучшить.

Улучшение безопасности конфигурации Nginx

В начале этого раздела я должен упомянуть, что, если вы используете последнюю версию Nginx, его настройки SSL по умолчанию безопасны. Нет необходимости определять протоколы, шифры и другие параметры.

Тем не менее, есть несколько директив SSL, с которыми мы можем повысить безопасность еще дальше. Просто имейте в виду, что, установив их, вы несете ответственность за то, чтобы держать их в курсе себя. Изменения Nginx делает на настройки конфигурации по умолчанию, не повлияет на вас, поскольку вы их перезаписываете.

Сначала, установлен

ssl_protocols TLSv1.1 TLSv1.2;

Это отключает все протоколы SSL и TLSV1.0, которые считаются небезопасными ( TLSV1.0 , SSLV3 , Sslv2 ) TLSV1.1 и TLSV1.2 на момент написания (июль 2018 г.) считаются безопасными, но никто не может пообещать, что они не будут нарушены в будущем.

Далее, Set

ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DHE+AES128:!ADH:!AECDH:!MD5;

Сифы определяют, как делается шифрование. Эти значения скопированы из Эта статья , поскольку я не эксперт в этой области.

Это самые важные настройки. Чтобы повысить безопасность еще больше, следуйте этим статьям:

Вы можете проверить безопасность вашей конфигурации SSL с отличным Веб -сайт SSL Labs предоставляет.

Заворачивать

В этой статье мы рассмотрели, как настроить Docker-Compose, использовать его функцию сети и громкости и как установить переменные среды, как использовать NGINX в качестве обратного прокси, включая кэширование и безопасность SSL. Все, что нужно для размещения проекта.

Просто имейте в виду, что это не ужасно профессиональная настройка, любой важной сервисе потребуется более сложная установка, но для небольших проектов или боковых проектов это совершенно нормально.

Поправка

Вот полученное nginx.conf и Docker-compose.yml файлы Они включают в себя имена заполнителей, URL и пути для ваших приложений.

Docker-Compose.yml

version: '3'
services:
  nginx: 
    image: nginx:latest
    container_name: production_nginx
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./nginx/error.log:/etc/nginx/error_log.log
      - ./nginx/cache/:/etc/nginx/cache
      - /etc/letsencrypt/:/etc/letsencrypt/
    ports:
      - 80:80
      - 443:443

  your_app_1:
    image: your_app_1_image:latest
    container_name: your_app_1
    expose:
      - "80"

  your_app_2:
    image: your_app_2_image:latest
    container_name: your_app_2
    expose:
      - "80"

  your_app_3:
    image: your_app_3_image:latest
    container_name: your_app_3
    expose:
      - "80"

nginx.conf

events {

}

http {
  error_log /etc/nginx/error_log.log warn;
  client_max_body_size 20m;

  proxy_cache_path /etc/nginx/cache keys_zone=one:500m max_size=1000m;

  server {
    server_name server1.your.domain;

    location /your_app_1 {
      proxy_pass http://your_app_1:80;
      rewrite ^/your_app_1(.*)$ $1 break;
    }

    location /your_app_2 {
      proxy_pass http://your_app_2:80;
      rewrite ^/your_app_2(.*)$ $1 break;
    }
  }

  server {
    server_name server2.your.domain;
    proxy_cache one;
    proxy_cache_key $request_method$request_uri;
    proxy_cache_min_uses 1;
    proxy_cache_methods GET;
    proxy_cache_valid 200 1y;

    location / {
      proxy_pass http://your_app_3:80;
      rewrite ^/your_app_3(.*)$ $1 break;
    }

    listen 80;
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/server2.your.domain/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/server2.your.domain/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
  }
}

Следуй за мной на Twitter Для большего количества моих мыслей, статей, проектов и работы.

Оригинал: «https://dev.to/domysee/setting-up-a-reverse-proxy-with-nginx-and-docker-compose-29jg»