Как можно настроить сайт и VLESS для работы на одном порту с использованием Docker и NGINX?

Как я могу настроить nginx, чтобы он обрабатывал как VLESS, так и тестовый сайт через один порт, при этом используя docker compose? Я привел свой пример конфигурации docker compose ниже: <br/> <pre><code class="yaml">services:
  helloworld:
    container_name: helloworld-2
    image: crccheck/hello-world
    expose:
      - 8000
  nginx:
    image: nginx-stream
    container_name: nginx-stream
    ports:
      - 80:80
      - 443:443
    volumes:
      - ./http.conf.d:/opt/nginx/http.conf.d
      - ./stream.conf.d:/opt/nginx/stream.conf.d
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    restart: unless-stopped
  cerbot:
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    command: certonly --webroot -w /var/www/certbot --keep-until-expiring --email mail@test.ru --domain exemple.com --agree-tos
  x-ray:
    image: teddysun/xray  
    container_name: x-ray-nginx
    volumes:
      - /etc/xray2:/etc/xray2
      - ./certbot/conf:/etc/letsencrypt
    expose:
      - 9001
    restart: always</code></pre> <br/> Также я пересобрал контейнер nginx, чтобы включить поддержку stream таким образом: <br/> <pre><code>FROM debian:bookworm

RUN apt-get update &amp;&amp; apt-get -y upgrade &amp;&amp; \
    apt-get install -y wget libpcre3-dev build-essential libssl-dev zlib1g-dev &amp;&amp; \

    rm -rf /var/lib/apt/lists/*

WORKDIR /opt

RUN wget http://nginx.org/download/nginx-1.27.3.tar.gz &amp;&amp; \
    tar -zxvf nginx-1.*.tar.gz &amp;&amp; \
    cd nginx-1.* &amp;&amp; \
    ./configure --prefix=/opt/nginx --user=nginx --group=nginx --with-http_ssl_module --with-ipv6 --with-threads --with-stream --with-stream_ssl_module --with-h
  • 21 января 2025 г. 7:04
Ответы на вопрос 2
Чтобы настроить работу вашего VLESS-сервиса и тестового сайта через один порт с использованием NGINX и Docker, вам нужно будет настроить NGINX для обработки как HTTP-запросов (для вашего сайта), так и TCP/UDP-запросов (для VLESS) в режиме Stream. Обычно это делается с использованием разных местоположений в конфигурации NGINX.

Вот основные шаги, которые вам нужно выполнить:

### 1. Настройте NGINX

Создайте конфигурационные файлы для NGINX. Например, `http.conf.d/default.conf` для HTTP и `stream.conf.d/default.conf` для VLESS.

#### HTTP конфигурация (http.conf.d/default.conf)

```nginx
server {
    listen 80;
    server_name exemple.com;

    location / {
        proxy_pass http://helloworld: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;
    }
}
```

#### Stream конфигурация (stream.conf.d/default.conf)

```nginx
stream {
    upstream vless {
        server x-ray-nginx:9001;
    }

    server {
        listen 443;  # Порт, на котором будет работать VLESS
        proxy_pass vless;
    }
}
```

### 2. Обновите вашу конфигурацию Docker Compose

Ваш файл `docker-compose.yml` должен выглядеть примерно так:

```yaml
version: '3.8'

services:
  helloworld:
    container_name: helloworld-2
    image: crccheck/hello-world
    expose:
      - 8000

  nginx:
    image: nginx:latest  # Используйте официальный образ NGINX
    container_name: nginx-stream
    ports:
      - "80:80"   # HTTP
      - "443:443" # VLESS
    volumes:
      - ./http.conf.d:/etc/nginx/conf.d
      - ./stream.conf.d:/etc/nginx/conf.d/default.conf  # Замените путь к вашему Stream конфигу
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    restart: unless-stopped
  
  certbot:
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certbot/conf:/etc/letsencrypt
      - ./certbot/www:/var/www/certbot
    command: certonly --webroot -w /var/www/certbot --keep-until-expiring --email mail@test.ru --domain exemple.com --agree-tos
    
  x-ray:
    image: teddysun/xray
    container_name: x-ray-nginx
    volumes:
      - /etc/xray2:/etc/xray2
      - ./certbot/conf:/etc/letsencrypt
    expose:
      - 9001
    restart: always
```

### 3. Соберите и запустите ваши контейнеры

После того как вы все настроили, выполните команды:

```bash
docker-compose build
docker-compose up -d
```

### 4. SSL сертификаты

Убедитесь, что ваш `certbot` корректно создает сертификаты для вашего домена `exemple.com`. Убедитесь, что ваши DNS-записи уже настроены на ваш сервер.

Также, если вы используете протоколы TLS/SSL, добавьте необходимые SSL параметры, такие как `ssl_certificate` и `ssl_certificate_key` в соответствующие части конфигурации NGINX.

### Примечание

- Если у вас возникают проблемы с доступом к VLESS, убедитесь, что ваши порты открыты в фаерволе сервера.
- Также проверьте версию NGINX и убедитесь, что она поддерживает все необходимые модули для работы с `stream`.
В итоге нашел в чем была проблема - proxy_protocol. 
Чтобы заработало нужно из /opt/nginx/stream.conf.d/*.conf удалить строчку:
proxy_protocol on;
А из /opt/nginx/http.conf.d/*.conf удалить всё что связано с proxy_protocol (для наглядности закомментировал ненужное):
server_tokens off;
charset utf-8;
server {
    listen 80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}
server {
    listen 7443 ssl;
    # listen 7443 ssl proxy_protocol;
    # set_real_ip_from 127.0.0.1;
    # real_ip_header proxy_protocol;
    http2 on;
    ssl_certificate     /etc/letsencrypt/live/exemple.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/exemple.com/privkey.pem;
    server_name sandro.run;
    root /var/www/html;
    index index.php index.html index.htm;
    location ~ /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    location /test {
        proxy_pass http://helloworld:8000/;
    }
}

После этого заработал, но есть и проблема. Из-за отключения proxy_protocol в логах обращений к сайту IP посетителей пишутся как 127.0.0.1. Пример решения этой проблемы, вроде, есть, но буду заниматься этим чуть позже и если решу проблему, то дополню ответ.

P.S.
Спасибо автору статьи https://coyotle.ru/posts/xray-and-nginx/ из которой были взяты конфиги nginx, xray.
Похожие вопросы