Реверс-прокси Docker-compose: nginx + ssl + nodered + grafana + mosquitto + influxdb. Пытаюсь заставить это работать.

Вопрос или проблема

Я думаю, что система Docker с nginx + ssl + nodered + grafana + mosquitto + influxdb достаточно распространена, надеюсь, это поможет другим.

У меня идеально работают nginx и ssl (certbot), и если я захожу на http://example.com:1880 или http://example.com:1880/ui или http://example.com:3000, я могу без проблем получить доступ к потокам nodered, ui и grafana.

Но мне нужно “больше”.

Я хочу иметь “подпапки”, как это:

  1. grafana будет перенаправляться на example.com/grafana
  2. редактирование потоков nodered должно идти на example.com/nodered
  3. ui nodered (dashboard или flowfuse, что угодно) должно идти на example.com

Я пробовал сотни конфигураций, редактируя docker-compose.yml, nginx.conf, settings.js и grafana.ini, но… без успеха.

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

Это мои на данный момент (я удалил свои “неудачные попытки конфигураций”)

server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    location /.well-known/acme-challenge {
        allow all;
        root /var/www/certbot;
    }
    location / {
#        rewrite ^ https://$host$request_uri? permanent;
        return 301 https://$server_name$request_uri;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;

    #STATIC index index.php index.html index.htm;
    #STATIC root /var/www/html;

    server_tokens off; #Отключение версии Nginx в заголовках для безопасности       

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

#linuxserver.io
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m; # около 40000 сессий
    ssl_session_tickets off;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    # Логи доступа и ошибок Nginx
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    location ~ /\.ht { deny all; }

    location = /favicon.ico { log_not_found off; access_log off; }
    location = /robots.txt { log_not_found off; access_log off; allow all; }
    location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ { expires max; log_not_found off; }    
}

Docker-compose.yml

services:
  mosquitto:
    image: eclipse-mosquitto:2
    container_name: mosquitto
    ports:
      - "1883:1883"
      #- "8883:8883"
      #- "9001:9001" # Websocket опционально
    volumes:
      - ./mosquitto-data:/mosquitto
    restart: unless-stopped
    #environment:
    #  - 'TZ='Europe/Brussels'

  influxdb:
    image: influxdb:2.7
    container_name: influxdb
    ports:
      - "8086:8086"
    volumes:
      - ./influxdb-data:/var/lib/influxdb2
      - ./influxdb-config:/etc/influxdb2
    environment:
      - DOCKER_INFLUXDB_INIT_MODE=setup
      - DOCKER_INFLUXDB_INIT_USERNAME=user
      - DOCKER_INFLUXDB_INIT_PASSWORD=password
      - DOCKER_INFLUXDB_INIT_ORG=org
      - DOCKER_INFLUXDB_INIT_BUCKET=buck
      - DOCKER_INFLUXDB_INIT_RETENTION=0
    restart: unless-stopped

  grafana:
    image: grafana/grafana:11.4.0
    container_name: grafana
    ports:
      - "3000:3000"
    volumes:
      - ./grafana-data:/var/lib/grafana
      - ./grafana-config:/etc/grafana
    #user: "0"
    environment:
      - GF_SECURITY_ADMIN_USER=user
      - GF_SECURITY_ADMIN_PASSWORD=password
      #- GF_SERVER_ROOT_URL=https://example.com/grafana
      #- GF_SERVER_DOMAIN=https://example.com/
      #- GF_INSTALL_PLUGINS 
    restart: unless-stopped

  nodered:
    image: nodered/node-red:4.0
    container_name: nodered
    ports:
      - "1880:1880"
    volumes:
      - ./nodered-data:/data
    restart: unless-stopped

  nginx:
    image: nginx:1.27.3-bookworm
    container_name: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx-data:/etc/nginx/conf.d
      - ./nginx-logs:/var/log/nginx
      - ./letsencrypt-data:/etc/letsencrypt
      - ./certbot-data:/var/www/certbot
    depends_on:
      - nodered
      - grafana
      - influxdb
    restart: unless-stopped

  certbot:
    image: certbot/certbot
    container_name: certbot
    depends_on:
      - nginx
    volumes:
      - ./letsencrypt-data:/etc/letsencrypt
      - ./certbot-data:/var/www/certbot
    #restart: unless-stopped
#    command: certonly --webroot --webroot-path=/var/www/certbot/ --email [email protected] --agree-tos --no-eff-email --staging -d example.com
    #command: certonly --webroot --webroot-path=/var/www/certbot/ --email [email protected] --agree-tos --no-eff-email --force-renewal -d example.com

volumes:
  mosquitto-data:
  influxdb-data:
  influxdb-config:
  grafana-data:
  grafana-config:
  nodered-data:
  letsencrypt-data:
  nginx-data:
  certbot-data:

Что мне нужно изменить/добавить в эти файлы?:

  1. nodered: docker-compose, nginx и settings.js
  2. grafana: docker-compose, nginx и grafana.ini

Большое спасибо.

Ответ или решение

Чтобы реализовать требуемую конфигурацию с использованием Nginx в качестве реверс-прокси для маршрутизации доступа к различным сервисам (Node-RED, Grafana и другим) с поддержкой SSL через Docker-Compose, необходимо учесть несколько ключевых моментов. Давайте подробно разберем, как можно это организовать.

Теория

  1. Реверс-прокси через Nginx:
    Реверс-прокси используется для распределения запросов между различными сервисами, работающими в одном домене, но на разных виртуальных путях (например, /grafana, /nodered).

  2. Docker Compose:
    Позволяет легко конфигурировать и управлять многоконтейнерной средой Docker. Вы можете описать все ваши сервисы и зависимости между ними в одном YAML файле.

  3. SSL/TLS:
    Использование Certbot для получения и управления SSL сертификатами от Let’s Encrypt. Это позволяет зашифровать трафик между пользователем и вашим сервером.

Пример

  1. Конфигурация Nginx:

    Добавьте в nginx.conf секции для маршрутизации на поддиректории сервиса:

    server {
       listen 443 ssl http2;
       server_name example.com;
    
       ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
       ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
       location /grafana/ {
           proxy_pass http://grafana:3000/;
           rewrite ^/grafana(/.*)$ $1 break;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $scheme;
       }
    
       location /nodered/ {
           proxy_pass http://nodered:1880/;
           rewrite ^/nodered(/.*)$ $1 break;
           proxy_set_header Host $host;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto $scheme;
       }
    }
  2. Docker Compose и Сервисы:

    Убедитесь, что каждый сервис настроен на правильную работу с реверс-прокси. Добавьте переменные окружения в docker-compose.yml.

    services:
     grafana:
       image: grafana/grafana:11.4.0
       container_name: grafana
       environment:
         - GF_SERVER_ROOT_URL=https://example.com/grafana/
         - GF_SERVER_SERVE_FROM_SUB_PATH=true
       volumes:
         - ./grafana-data:/var/lib/grafana
       restart: unless-stopped
    
     nodered:
       image: nodered/node-red:4.0
       container_name: nodered
       environment:
         - NODE_RED_EDITOR_URL=https://example.com/nodered/
       volumes:
         - ./nodered-data:/data
       restart: unless-stopped
  3. Настройки Grafana и Node-RED:

    Для Grafana добавьте в grafana.ini:

    [server]
    root_url = https://example.com/grafana/
    serve_from_sub_path = true

    Для Node-RED настройте settings.js, если необходимо изменить путь к редактору или другим ресурсам.

Применение

Чтобы проверить работоспособность конфигурации, перезапустите ваши контейнеры с помощью docker-compose up -d и убедитесь, что каждый сервис доступен по своему пути (/grafana, /nodered). Следует изучать логи как Nginx, так и каждого сервиса для выявления проблем. Применение этих настроек должно привести к корректной маршрутизации и защищенному доступу к вашим приложениям.

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

Оцените материал
Добавить комментарий

Капча загружается...