← Назад к вопросам

Можно ли делать несколько сайтов на одном порту в Nginx?

1.6 Junior🔥 201 комментариев
#Linux и администрирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Несколько сайтов на одном порту в Nginx

Да, абсолютно возможно! Это один из основных сценариев использования Nginx. Nginx использует Host header для differentiating between сайтов на одном IP:порте.

Как это работает

Клиент запрашивает:
  Host: example.com
  Port: 80
  
Nginx получает request
Проверяет Host header
Маршрутизирует в нужный server block
Отправляет ответ

Конфигурация Nginx (Virtual Hosts)

Несколько сайтов на порту 80:

# /etc/nginx/sites-available/multiple-sites

# Site 1: example.com
server {
    listen 80;
    server_name example.com www.example.com;
    
    root /var/www/example.com;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# Site 2: blog.local
server {
    listen 80;
    server_name blog.local;
    
    root /var/www/blog.local;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

# Site 3: api.example.com
server {
    listen 80;
    server_name api.example.com;
    
    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Ключевая директива: server_name

server_name example.com;           # Точное совпадение
server_name www.example.com;       # Another exact match
server_name *.example.com;         # Wildcard (any subdomain)
server_name ~^api\..*\.example\.com$;  # Regex
server_name example.com *.example.com;  # Multiple patterns

Порядок поиска server block

Nginx ищет в следующем порядке:

  1. Exact match - точное совпадение
  2. Leading wildcard - начинающаяся с *
  3. Trailing wildcard - заканчивающаяся на *
  4. Regex match - регулярное выражение
  5. Default server - если ничего не совпало
# Порядок важен!
server { server_name example.com; }     # 1-й match (exact)
server { server_name *.example.com; }   # 2-й match (wildcard)
server { server_name default_server; }  # fallback

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

Конфиг для 3 сайтов:

http {
    # Гдеча сжатие
    gzip on;
    gzip_types text/plain text/css application/json;
    
    # Site 1: Static HTML
    server {
        listen 80;
        listen [::]:80;  # IPv6
        
        server_name example.com www.example.com;
        
        root /var/www/example.com/public;
        index index.html index.htm;
        
        location / {
            try_files $uri $uri/ /index.html;
        }
        
        # Cache static files
        location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }
    
    # Site 2: PHP application
    server {
        listen 80;
        server_name app.example.com;
        
        root /var/www/app.example.com/public;
        index index.php;
        
        location ~ \.php$ {
            fastcgi_pass unix:/var/run/php-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
    
    # Site 3: Proxy to backend
    server {
        listen 80;
        server_name api.example.com;
        
        location / {
            proxy_pass http://localhost:8000;
            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;
        }
    }
}

HTTPS с несколькими сайтами

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # SSL config
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    root /var/www/example.com;
    # ... rest of config
}

server {
    listen 443 ssl http2;
    server_name app.example.com;
    
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # ... proxy config
}

Практические рекомендации

1. Используй Host header для маршрутизации

# Правильно - используем Host
set $upstream backend1;
if ($host = api.example.com) {
    set $upstream backend1;
}
if ($host = web.example.com) {
    set $upstream backend2;
}
proxy_pass http://$upstream;

2. Проверка конфига

# Проверить синтаксис
sudo nginx -t

# Увидеть loaded конфиг
sudo nginx -T

# Reload конфиг
sudo systemctl reload nginx

3. Логирование для разных сайтов

server {
    server_name example.com;
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
}

Количество сайтов

Вопрос: Сколько сайтов можно на одном порту?

Ответ: Практически unlimited (ограничено памятью и CPU).

На практике:

  • 10-50 сайтов - easy
  • 100+ сайтов - нужна оптимизация
  • 1000+ - consider load balancing

Разделение конфигов

# Структура
/etc/nginx/
  ├── nginx.conf              # main config
  ├── sites-available/
  │   ├── example.com
  │   ├── api.example.com
  │   └── blog.example.com
  └── sites-enabled/
      ├── example.com -> ../sites-available/example.com
      ├── api.example.com -> ../sites-available/api.example.com
      └── blog.example.com -> ../sites-available/blog.example.com

# Enable/disable sites
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/example.com  # disable

Тестирование

# Проверить какой сайт отвечает
curl -H "Host: example.com" http://localhost/
curl -H "Host: api.example.com" http://localhost/

# С указанием порта
curl -H "Host: example.com" http://localhost:8080/

# Real DNS
curl http://example.com/

Выводы

Да, можно - это основный механизм Nginx ✅ Использует Host header - для маршрутизации ✅ Scalable - до сотен сайтов на одном IP:port ✅ Efficient - мало overhead'а ✅ Best practice - именно так делают CDN и хостинг провайдеры

Это один из главных преимуществ Nginx перед Apache - эффективное управление virtual hosts на одном IP.