Home » Настройка обратного прокси Nginx для Node и Angular приложений
Настройка обратного прокси Nginx для Node и Angular приложений

Настройка обратного прокси Nginx для Node и Angular приложений

Настройка обратного прокси — это одна из тех вещей, которые каждый разработчик должен знать, но с которыми многие мучаются дольше, чем хотелось бы. Если у вас есть Angular-фронтенд и Node.js-бэкенд, то рано или поздно вам понадобится объединить их под одним доменом, настроить балансировку нагрузки или просто спрятать внутреннюю архитектуру от любопытных глаз. Nginx здесь — ваш лучший друг, и сегодня мы разберём, как заставить его работать именно так, как нужно.

Эта статья поможет вам понять принципы работы обратного прокси, быстро настроить продакшен-готовую конфигурацию и избежать типичных граблей, на которые наступают новички. Мы пройдём путь от базовой настройки до продвинутых кейсов с кешированием, SSL и балансировкой нагрузки.

Как работает обратный прокси Nginx

Обратный прокси — это посредник между клиентом и вашими приложениями. Представьте себе швейцара в отеле: он принимает запросы от гостей и направляет их к нужному сотруднику. Nginx работает похожим образом:

  • Принимает HTTP-запросы от клиентов
  • Анализирует URL, заголовки и другие параметры
  • Перенаправляет запрос к соответствующему приложению
  • Получает ответ и возвращает его клиенту

Для Angular + Node.js связки типичная схема выглядит так:

  • /api/* — запросы идут к Node.js серверу (обычно порт 3000)
  • /* — остальные запросы идут к статическим файлам Angular
  • /socket.io/* — WebSocket соединения (если используются)

Пошаговая настройка базовой конфигурации

Начнём с установки Nginx и создания базовой конфигурации. Для начала вам понадобится сервер — можете взять VPS или выделенный сервер.

Установка Nginx

# Ubuntu/Debian
sudo apt update
sudo apt install nginx

# CentOS/RHEL
sudo yum install nginx

# Запуск и автозагрузка
sudo systemctl start nginx
sudo systemctl enable nginx

Создание конфигурационного файла

Создадим конфигурацию для нашего приложения:

sudo nano /etc/nginx/sites-available/myapp

Базовая конфигурация:

server {
    listen 80;
    server_name your-domain.com;
    
    # Путь к собранному Angular приложению
    root /var/www/myapp/dist;
    index index.html;
    
    # Проксирование API запросов к Node.js
    location /api {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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;
        proxy_cache_bypass $http_upgrade;
    }
    
    # Обслуживание статических файлов Angular
    location / {
        try_files $uri $uri/ /index.html;
    }
    
    # Кеширование статических ресурсов
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

Активация конфигурации

# Создание символической ссылки
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/

# Проверка конфигурации
sudo nginx -t

# Перезагрузка Nginx
sudo systemctl reload nginx

Продвинутые настройки и оптимизация

Балансировка нагрузки

Если у вас несколько инстансов Node.js приложения, настройте upstream:

upstream nodejs_backend {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
}

server {
    listen 80;
    server_name your-domain.com;
    
    location /api {
        proxy_pass http://nodejs_backend;
        # остальные настройки прокси...
    }
    
    # остальная конфигурация...
}

WebSocket поддержка

Для приложений с Socket.io или WebSocket:

location /socket.io/ {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    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;
}

SSL и HTTPS

Настройка SSL с Let’s Encrypt:

# Установка certbot
sudo apt install certbot python3-certbot-nginx

# Получение сертификата
sudo certbot --nginx -d your-domain.com

# Автоматическое обновление
sudo crontab -e
# Добавить строку:
# 0 12 * * * /usr/bin/certbot renew --quiet

Практические кейсы и примеры

Кейс 1: Микросервисная архитектура

Когда у вас несколько API сервисов:

server {
    listen 80;
    server_name api.your-domain.com;
    
    # User service
    location /api/users {
        proxy_pass http://localhost:3001;
        # proxy settings...
    }
    
    # Product service
    location /api/products {
        proxy_pass http://localhost:3002;
        # proxy settings...
    }
    
    # Order service
    location /api/orders {
        proxy_pass http://localhost:3003;
        # proxy settings...
    }
}

Кейс 2: Staging и Production окружения

# Production
server {
    listen 80;
    server_name app.your-domain.com;
    
    location /api {
        proxy_pass http://prod-nodejs:3000;
        # настройки...
    }
    
    root /var/www/app/prod/dist;
    # остальная конфигурация...
}

# Staging
server {
    listen 80;
    server_name staging.your-domain.com;
    
    location /api {
        proxy_pass http://staging-nodejs:3000;
        # настройки...
    }
    
    root /var/www/app/staging/dist;
    # остальная конфигурация...
}

Таблица сравнения различных подходов

Подход Плюсы Минусы Когда использовать
Один домен Простота настройки, нет CORS Может быть сложно масштабировать Малые и средние приложения
Поддомены Четкое разделение, легко масштабировать Нужно настраивать CORS Большие приложения, микросервисы
Разные порты Быстрая настройка для разработки Неудобно для пользователей Только для разработки

Типичные ошибки и их решения

Ошибка: 502 Bad Gateway

Самая частая проблема — Node.js сервер не запущен или недоступен:

# Проверка запущенных процессов
ps aux | grep node

# Проверка портов
sudo netstat -tlnp | grep :3000

# Проверка логов Nginx
sudo tail -f /var/log/nginx/error.log

Ошибка: Angular роутинг не работает

Проблема с try_files директивой. Правильная настройка:

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

Ошибка: WebSocket соединения обрываются

Нужно увеличить таймауты:

location /socket.io/ {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 86400;
    proxy_send_timeout 86400;
}

Мониторинг и логирование

Настройка логирования

http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for" '
                    'rt=$request_time uct="$upstream_connect_time" '
                    'uht="$upstream_header_time" urt="$upstream_response_time"';
    
    access_log /var/log/nginx/access.log main;
}

Мониторинг с помощью скриптов

#!/bin/bash
# check_nginx_status.sh

# Проверка статуса Nginx
if ! systemctl is-active --quiet nginx; then
    echo "Nginx is down! Restarting..."
    sudo systemctl restart nginx
fi

# Проверка доступности бэкенда
if ! curl -f http://localhost:3000/api/health > /dev/null 2>&1; then
    echo "Backend is down!"
    # Отправка уведомления или перезапуск
fi

Альтернативные решения

Apache HTTP Server

Классическая альтернатива Nginx с модулем mod_proxy:

<VirtualHost *:80>
    ServerName your-domain.com
    DocumentRoot /var/www/myapp/dist
    
    ProxyPreserveHost On
    ProxyPass /api http://localhost:3000/api
    ProxyPassReverse /api http://localhost:3000/api
</VirtualHost>

Traefik

Современное решение для контейнерных приложений. Настройка через Docker labels:

version: '3'
services:
  frontend:
    image: nginx:alpine
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.frontend.rule=Host(`your-domain.com`)"
      
  backend:
    image: node:alpine
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.backend.rule=Host(`your-domain.com`) && PathPrefix(`/api`)"

Сравнение производительности

Решение RPS (req/sec) Потребление RAM Сложность настройки
Nginx 100,000+ Низкое Средняя
Apache 50,000+ Высокое Низкая
Traefik 80,000+ Среднее Низкая (с Docker)

Автоматизация и CI/CD

Скрипт автоматического деплоя

#!/bin/bash
# deploy.sh

# Сборка Angular приложения
cd /var/www/myapp
npm run build

# Обновление Node.js приложения
pm2 restart myapp

# Проверка конфигурации Nginx
sudo nginx -t

# Перезагрузка Nginx
sudo systemctl reload nginx

# Проверка доступности
curl -f http://localhost/api/health || exit 1
echo "Deployment successful!"

Интеграция с GitHub Actions

name: Deploy to Production
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    
    - name: Deploy to server
      uses: appleboy/ssh-action@v0.1.4
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_KEY }}
        script: |
          cd /var/www/myapp
          git pull origin main
          npm ci
          npm run build
          pm2 restart myapp
          sudo nginx -t && sudo systemctl reload nginx

Интересные факты и нестандартные применения

Nginx как API Gateway

Nginx можно использовать для аутентификации и авторизации:

location /api/protected {
    auth_request /auth;
    proxy_pass http://localhost:3000;
}

location = /auth {
    internal;
    proxy_pass http://auth-service/verify;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
}

Кеширование API ответов

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=10g 
                 inactive=60m use_temp_path=off;

location /api/cache {
    proxy_cache api_cache;
    proxy_cache_valid 200 302 10m;
    proxy_cache_valid 404 1m;
    proxy_cache_key $scheme$proxy_host$uri$is_args$args;
    proxy_pass http://localhost:3000;
}

Rate limiting

http {
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
}

server {
    location /api {
        limit_req zone=api burst=20 nodelay;
        proxy_pass http://localhost:3000;
    }
}

Полезные ссылки

Заключение и рекомендации

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

Основные рекомендации:

  • Начинайте с простой конфигурации и постепенно добавляйте функциональность
  • Всегда проверяйте конфигурацию перед перезагрузкой: nginx -t
  • Используйте мониторинг и логирование для быстрого обнаружения проблем
  • Настройте автоматические бэкапы конфигурационных файлов
  • Не забывайте про безопасность — используйте HTTPS и настройте rate limiting

Для продакшена рекомендуется использовать VPS с достаточным объемом RAM (минимум 2GB) или выделенный сервер для высоконагруженных приложений.

Помните: хорошая конфигурация Nginx может значительно улучшить производительность вашего приложения и упростить его обслуживание. Потратьте время на правильную настройку — это окупится в будущем!


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

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

Leave a reply

Your email address will not be published. Required fields are marked