- Вопрос или проблема
- Вот мой рабочий процесс:
- Вариант 1:
- Вариант 2:
- Ответ на обновление:
- Общие рекомендации:
- Ответ или решение
- Настройка Nginx в качестве прокси для пересылки портов на контейнер Docker
- 1. Корректировка конфигурации Nginx
- 2. Обновление docker-compose.yml
- 3. Перезапустите контейнеры
- 4. Тестирование
- Заключение
Вопрос или проблема
Я пытаюсь реализовать простой сервис потоковой передачи HLS, который работает на Docker-контейнерах. Вкратце, каждый сервис представляет собой контейнер Docker с узлом потоковой передачи Apache. Всё работает хорошо, за исключением того, что каждый контейнер работает на своем порту, и мне нужно обращаться к нему так:
http://localhost:Port/service_name/*m3u8.
Что мне нужно сделать, так это настроить прокси для перенаправления портов, чтобы не было необходимости использовать номер порта в URL.
Изучая эту тему, я получил впечатление, что Nginx может справиться с этой задачей. Однако, похоже, что Proxy_Pass не удается перенаправить запрос на контейнер. В журнале ошибок Nginx я получаю ошибку (111: Соединение отклонено) или 404. Я пытался настроить это несколькими способами, но безуспешно. Я не эксперт в Nginx, и поэтому не уверен, делаю ли я всё правильно. Может, кто-то подскажет мне, в каком направлении двигаться?
Вот мой рабочий процесс:
Я создал образ для сервиса Apache и образ для прокси Nginx. Затем, используя Docker Compose, я создаю 3 контейнера (1 прокси Nginx и 2 потока Apache), все в одной сети по умолчанию.
Когда я обращаюсь к сервису без номера порта, я получаю ошибку 505.
Это мой Dockerfile для сервера Nginx:
FROM ubuntu:14.04
RUN sudo apt-get update && sudo apt-get install -y nginx && sudo apt-get install nano && rm -rf /var/lib/apt/lists/*
EXPOSE 80
Это Dockerfile для сервиса Apache:
FROM ubuntu:14.04
RUN apt-get update && apt-get install -y apt-transport-https && apt-get install -y apache2 && \
apt-get install -y software-properties-common && add-apt-repository ppa:mc3man/trusty-media -y && \
apt-get update && apt-get install -y ffmpeg && mkdir /var/www/html/hls && chmod 777 -R /var/www/html/hls && \
rm -rf /var/lib/apt/lists/*
COPY apache2.conf /etc/apache2/apache2.conf
COPY mime.conf /etc/apache2/mods-available/mime.conf
RUN /etc/init.d/apache2 start
Это файл docker-compose.yml
:
version: '2'
services:
worker:
image: nginx
stdin_open: true
tty: true
ports:
- "80:80"
stream1:
image: server
ports:
- "8003:80"
command: >
sh -c "sudo /etc/init.d/apache2 start && cd /var/www/html/hls && ffmpeg -i http://b46785a2.iptvzone.me/iptv/GWXXRGQF9G38LU/828/index.m3u8 -c copy -hls_list_size 10 -hls_flags delete_segments live.m3u8 "
restart: always
stream2:
image: server
ports:
- "8004:80"
command: >
sh -c "sudo mkdir /var/www/html/stream && chmod 777 -R /var/www/html/stream && cd /var/www/html/stream && sudo /etc/init.d/apache2 start \
&& ffmpeg -i http://app.live.112.events/hls-ua/112hd_mid/index.m3u8 -c copy -hls_list_size 10 -hls_flags delete_segments live.m3u8 "
restart: always
Это файл конфигурации Nginx в /etc/nginx/sites-available/default
:
server {
listen 80;
location /hls/ {
proxy_pass http://172.20.0.2:8003/hls/; - это IP Docker-контейнера. localhost дает ошибку 404
}
}
А это вывод из /var/log/nginx/error.log:
2019/04/29 16:16:43 [error] 116#0: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.20.0.1, server: , request: "GET /hls/live.m3u8 HTTP/1.1", upstream: "http://127.0.0.1:8003/hls/live.m3u8", host: "localhost"
2019/04/29 16:16:46 [error] 116#0: *1 no live upstreams while connecting to upstream, client: 172.20.0.1, server: , request: "GET /hls/live.m3u8 HTTP/1.1", upstream: "http://localhost/hls/live.m3u8", host: "localhost"
Обновление: Следующий код сработал:
server {
listen 80;
location /hls/ {
allow all;
proxy_pass http://muze.cf:8003/hls/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
}
}
Я могу открыть URL http://muze.cf/hls/
без номера порта. Однако, когда я добавляю другой серверный блок, например:
server {
listen 80;
location /stream/ {
allow all;
proxy_pass http://muze.cf:8004/stream/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
}
}
Я получаю ошибку конфликта имени сервера:
2019/05/13 09:43:13 [warn] 42#0: conflicting server name "" on 0.0.0.0:80, ignored
2019/05/13 09:43:19 [error] 47#0: *1 open() "/usr/share/nginx/html/stream/live.m3u8" failed (2: No such file or directory), client: 83.134.167.52, server: , request: "GET /stream/live.m3u8 HTTP/1.1", host: "muze.cf"
2019/05/13 09:43:51 [error] 47#0: *1 open() "/usr/share/nginx/html/stream/live.m3u8" failed (2: No such file or directory), client: 83.134.167.52, server: , request: "GET /stream/live.m3u8 HTTP/1.1", host: "muze.cf"
2019/05/13 09:46:00 [warn] 66#0: conflicting server name "" on 0.0.0.0:80, ignored
2019/05/13 09:46:06 [error] 72#0: *3 open() "/usr/share/nginx/html/stream/live.m3u8" failed (2: No such file or directory), client: 83.134.167.52, server: , request: "GET /stream/live.m3u8 HTTP/1.1", host: "muze.cf"
2019/05/13 09:46:32 [error] 72#0: *3 open() "/usr/share/nginx/html/stream/live.m3u8" failed (2: No such file or directory), client: 83.134.167.52, server: , request: "GET /stream/live.m3u8 HTTP/1.1", host: "muze.cf"
2019/05/13 09:52:13 [warn] 94#0: server name "http://muze.cf/hls/" has suspicious symbols in /etc/nginx/sites-enabled/default:3
2019/05/13 09:52:13 [warn] 94#0: server name "http://muze.cf/stream/" has suspicious symbols in /etc/nginx/sites-enabled/default:16
2019/05/13 09:52:49 [error] 100#0: *6 open() "/usr/share/nginx/html/stream/live.m3u8" failed (2: No such file or directory), client: 83.134.167.52, server: http://muze.cf/hls/, request: "GET /stream/live.m3u8 HTTP/1.1", host: "muze.cf"
Теоретически я должен иметь возможность создать много серверных блоков в одном и том же домене?
Есть несколько вещей, которые вы могли бы попробовать, поскольку я не знаю всех деталей вашей настройки.
Вариант 1:
Удалите порт :8003 из оператора proxy_pass в вашем конфигурационном файле nginx. Порт 8003 – это порт на хосте Docker, который связан с портом 80 вашего контейнера stream1. Поскольку вы используете IP контейнера Docker в операторе proxy_pass, контейнер, вероятно, не имеет открытого порта 8003, он ожидает подключения на порту 80.
server {
listen 80;
location /hls/ {
proxy_pass http://172.20.0.2/hls/; - это IP Docker-контейнера.
}
}
Вариант 2:
Другой вариант по той же причине, что и вариант 1, вы можете указать IP-адрес хоста в операторе proxy_pass. Это предполагает, что у вас есть фиксированный IP на хосте.
server {
listen 80;
location /hls/ {
proxy_pass http://<hostip>:8003/hls/; - это IP хоста
}
}
Ответ на обновление:
В вашем разделе обновления вы получаете ошибку, которая сообщает о конфликтующих именах серверов. Вы можете иметь несколько серверных блоков в конфигурации nginx, но у всех них должны быть разные имена. Если вы не укажете имя сервера, оно по умолчанию принимается за $host, как я полагаю. Поскольку вы используете location для определения различных серверов для перенаправления, я рекомендую иметь несколько блоков location внутри одного блока сервера по умолчанию. Обычно для различных поддоменов используются разные блоки серверов.
server {
listen 80;
location /hls/ {
allow all;
proxy_pass http://muze.cf:8003/hls/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
}
location /stream/ {
allow all;
proxy_pass http://muze.cf:8004/stream/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
}
}
Общие рекомендации:
В вашем блоку сервера nginx есть несколько других опций, которые вы также можете настроить. Это гарантирует, что некоторая информация заголовка будет передана.
server {
listen 80;
location /hls/ {
allow all;
proxy_pass http://172.20.0.2/hls/; - это IP Docker-контейнера.
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
}
}
Ответ или решение
Настройка Nginx в качестве прокси для пересылки портов на контейнер Docker
Чтобы настроить Nginx как прокси-сервер для пересылки запросов к контейнерам Docker, вам нужно внести некоторые изменения как в конфигурацию Nginx, так и в docker-compose.yml
. Давайте рассмотрим шаги, которые могут помочь вам облегчить доступ к вашим контейнерам без указания номеров портов в URL.
1. Корректировка конфигурации Nginx
В вашей текущей конфигурации Nginx используются разные блоки серверов, однако лучше всего использовать один блок сервера с различными секциями location
. Это позволит избежать конфликта серверных имён и упростит маршрутизацию:
server {
listen 80;
location /hls/ {
allow all;
proxy_pass http://172.20.0.2/hls/; # IP-адрес контейнера stream1
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /stream/ {
allow all;
proxy_pass http://172.20.0.3/stream/; # IP-адрес контейнера stream2
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Обратите внимание, что здесь мы используем внутренние IP-адреса ваших контейнеров (172.20.0.2
и 172.20.0.3
), полученные из вашей сети Docker. Убедитесь, что эти адреса актуальны и соответствуют вашим контейнерам.
2. Обновление docker-compose.yml
Обязательно исчерпайте порты, которые уже задействованы. Например, чтобы избежать конфликтов, лучше использовать внутреннюю сеть Docker, где у вас будут только контейнеры, и вам не нужно открывать их порты на хосте. Убедитесь, что в вашем docker-compose.yml
файле контейнеры находятся в одной сети:
version: '2'
services:
worker:
image: nginx
ports:
- "80:80"
stream1:
image: server
expose:
- "80" # Используйте expose вместо ports, если порты не должны быть открыты на хосте
command: >
sh -c "service apache2 start && cd /var/www/html/hls && ffmpeg -i http://b46785a2.iptvzone.me/iptv/GWXXRGQF9G38LU/828/index.m3u8 -c copy -hls_list_size 10 -hls_flags delete_segments live.m3u8"
restart: always
stream2:
image: server
expose:
- "80"
command: >
sh -c "service apache2 start && mkdir -p /var/www/html/stream && ffmpeg -i http://app.live.112.events/hls-ua/112hd_mid/index.m3u8 -c copy -hls_list_size 10 -hls_flags delete_segments live.m3u8"
restart: always
3. Перезапустите контейнеры
После внесения изменений в конфигурацию Nginx и docker-compose.yml
выполните:
docker-compose down
docker-compose up -d
4. Тестирование
Теперь вы сможете получить доступ к вашим HLS стримам через URL:
- Для первого потока:
http://muze.cf/hls/live.m3u8
- Для второго потока:
http://muze.cf/stream/live.m3u8
Убедитесь, что все конфигурации сохранились, и вы можете открывать эти ссылки в браузере без проблем с номерами портов.
Заключение
Эта конфигурация упрощает доступ к вашему HLS сервису, устраняет необходимость в указании портов в URL и упрощает управление сервисами. Если возникнут ошибки, проверьте логи Nginx и Docker для выявления возможных проблем.