обратный прокси-сервер nginx и рельсы в отдельных контейнерах докеров - PullRequest
0 голосов
/ 29 ноября 2018

Здравствуйте, ребята. Я пытаюсь заставить мое приложение rails работать с nginx в качестве обратного прокси-сервера. Приложение rails и nginx находятся в отдельных контейнерах docker и работают через docker-compose services.До сих пор безуспешно.

Среда Rails production.rb => config.force_ssl = true

Мой файл docker-compose такой:

version: '3'

services: 
  nginx:
    image: reverse_nginx:latest
    ports:
      - '80:80'
    depends_on:
      - web

  web:
    image: production_my_app:latest
    command: rails s -p 3000 -b '0.0.0.0' -e production
    ports:
      - '3000:3000'
    depends_on:
      - postgres
      - redis
    env_file:
      - ...
    restart: always

Для сборки reverse_nginx: последние Я использую Dockerfile-nginx с этим:

# Base image: debian strech
FROM nginx:stable

RUN apt-get update -qq \
  && apt-get install -y ca-certificates

COPY ssl/server.crt /etc/ssl/certs/server.crt
COPY ssl/server.key /etc/ssl/private/server.key

RUN cd /etc/ssl/private \
  && chmod 600 server.* \
  && cd /etc/ssl/certs \
  && chmod 600 server.* \
  && update-ca-certificates --fresh

# establish where Nginx should look for files
ENV RAILS_ROOT /var/www/my_app/public

# Set working directory inside the image
WORKDIR $RAILS_ROOT

# create log directory
RUN mkdir log

# copy over static assets
COPY public .

# copy custom general nginx conf
COPY config/nginx.conf /etc/nginx/nginx.conf

# copy custom conf for my_app to sites-available folder
COPY config/my.app.conf /etc/nginx/sites-available/my.app.conf

# create sites-enabled folder and soft link custom conf for my_app
RUN mkdir -p /etc/nginx/sites-enabled/ \
  && cd /etc/nginx/sites-enabled/ \
  && ln -s /etc/nginx/sites-available/my.app.conf . \
  && ls -la \
  && nginx -c /etc/nginx/nginx.conf -t

EXPOSE 80

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

Файл /etc/nginx/nginx.conf:

user nginx;
worker_processes auto;
worker_rlimit_nofile 1024;

events {
    multi_accept on;
    worker_connections 1024;
}

http {
    # load configs
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*.conf;

    # MIME
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    # logging
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log warn;

    charset utf-8;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    server_tokens off;
    log_not_found off;
    types_hash_max_size 2048;
    client_max_body_size 16M;

    # SSL
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;

    # modern configuration
    ssl_protocols TLSv1.2;
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;
    ssl_prefer_server_ciphers on;

    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 208.67.222.222 208.67.220.220 valid=60s;
    # resolver_timeout 2s;
}

/ etc / nginx / sites-available / my_app.conf файл:

# HTTPS
server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  server_name my.app;
  root /var/www/myapp/public;

  ssl_certificate /etc/ssl/certs/server.crt;
  ssl_certificate_key /etc/ssl/private/server.key;

  # index.html fallback
  location / {
    try_files $uri $uri/ /index.html;
  }

  # reverse proxy
  location /var/www/myapp/public {

    # proxy_pass needs to be name of service on docker compose to connect with container?
    proxy_pass http://web:3000;

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}

# HTTP redirect to HTTPS
server {
  listen 80;
  listen [::]:80;

  server_name .my.app;

  return 301 https://my.app$request_uri;
}

Сценарии:

$ docker-compose up nginx_1 => сообщение (как и ожидалось):

nginx_1 | "ssl_stapling" ignored, issuer certificate not found for certificate "/etc/ssl/certs/server.crt"

сценарий 1: посещение 0.0.0.0 в браузере, URL-адрес изменяется на https://my.app браузер сообщает: ERR_SSL_PROTOCOL_ERROR

сценарий 2: посещение 0.0.0.0:80 в браузере, URL-адрес изменяется на https://my.appбраузер сообщает: ERR_SSL_PROTOCOL_ERROR

сценарий 3: посещение 0.0.0.0:3000 в браузере, URL-адрес изменяется на https://0.0.0.0:3000 журнал ошибок рельсов Ошибка синтаксического анализа HTTPS неверный синтаксический анализ HTTP-формата, браузер говорит: ERR_SSL_PROTOCOL_ERROR

сценарий 4: посещение https://0.0.0.0:80, URL остается прежним, nginx_1 символы броска журнала: 192.168.0.1 - - [28/Nov/2018:21:39:22 +0000] "\x16\x03\x01\x00\xB5\x01\x00\x00\xB1\x03\x03\xD3@kn" 400 166 "-" "-"

I-йчернила, что проблема в директиве proxy_pass в my_app.conf, но, если честно, я не знаю, что я делаю сейчас, я застрял.Вы можете помочь мне понять, что происходит?Я никогда не использовал nginx

1 Ответ

0 голосов
/ 29 ноября 2018

У вас есть несколько проблем:

  • Необходимо найти сертификат SSL, который необходимо исправить, чтобы избавиться от ошибок SSL

  • Местоположение должно ссылаться на URL, к которому вы обращаетесь (это регулярное выражение)

  • nginx не знает о докере

  • имена серверов настроены неправильно

передача прокси

Чтобы решить их в обратном порядке, не передавайте прокси на http://web, вместо этого переходите наадрес, по которому вы запускаете контейнер: http://0.0.0.0:3000.

Местоположение

Далее, похоже, что вы хотите проксировать весь веб-трафик, который попадает с обратного прокси на рельсы.Если это так, то сделайте его единственным блоком местоположения и укажите его location / { ... }.

Пример:

# reverse proxy
location / {
  # pass everything to rails
  proxy_pass http://0.0.0.0:3000;

  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
}

SSL

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

Имя сервера

Nginx позволит нескольким хостам подключаться к одному IP-адресу и маршрутизировать соответствующим образом,Это основано на директиве server_name.Похоже, вы хотите, чтобы весь трафик, ведущий к 0.0.0.0 (или к вашему возможному хосту), был проксирован к рельсам.Таким образом, лучшее, что нужно сделать, это просто добавить ловушку.В обоих серверных блоках :80 и :443 измените server_name my.app; на server_name _ my.app;.Там _ действует как шаблон.Без этого вам нужно отредактировать файл /etc/hosts и указать my.app на localhost, а затем получить к нему доступ, перейдя к https://my.app вместо 0.0.0.0.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...