如何配置 NGINX 代理来对 Docker 容器进行端口转发?

如何配置 NGINX 代理来对 Docker 容器进行端口转发?

我正在尝试实现运行 Docker 容器的简单 HLS 流媒体服务。简而言之,每个服务都是 dockerized Apache 流媒体节点。一切正常。但有一个问题是每个容器都在自己的端口上运行,我必须像这样解决它:

http://localhost:端口/服务名称/*m3u8。

我需要做的是设置一个代理来执行此端口转发,这样就不需要在 URL 中使用端口号。

搜索这个主题时,我感觉 NGINX 可以完成这项工作。但是 Proxy_Pass 似乎无法将请求路由到容器。在 NGINX 错误日志中,我收到 (111: Connection denied) 错误。或者 404。我尝试了不同的方法,但没有成功。我不是 NGINX 专家,所以我不确定我做的是否正确。有人能至少给我指出正确的方向吗?

以下是我的工作流程:

我已经为 Apache 服务和 NGINX 代理构建了一个映像。然后使用 Docker compose 创建了 3 个容器(1 个 NGINX 代理和 2 个 Apache 流),全部位于一个默认网络中。

当我处理没有端口号的服务时,出现 505 错误。

这是我的 NGINX 服务器的 Dockerfile:

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

这是 Apache 服务的 Dockerfile:

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/; - that is IP of Docker continer. localhost produces 404 error

    }
}

这是 /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"

感谢您的任何提示!

更新2: 谢谢你的建议。

以下代码有效:

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;
}

}

我可以打开网址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

由于我不知道您设置的所有细节,因此您可以尝试几件事。

选项1:

从 nginx 配置文件中的 proxy_pass 语句中删除端口 :8003。端口 8003 是 docker 主机上的端口,该端口绑定到 stream1 容器的端口 80。由于您在 proxy_pass 语句中使用了 docker 容器 IP,因此容器可能没有打开端口 8003,它需要端口 80 上的连接。

server {
    listen 80;

    location /hls/ {
      proxy_pass http://172.20.0.2/hls/; - that is IP of Docker continer.
    }
}

选项 2:

出于与选项 1 相同的原因,另一个选项是您可以在 proxy_pass 语句中指定主机 IP 地址。这假设您在主机上有一个固定 IP。

server {
    listen 80;

    location /hls/ {
      proxy_pass http://<hostip>:8003/hls/; - that is IP of the host
    }
}

更新 2 的答案:

在更新 2 部分中,您收到一条错误,指出存在冲突的服务器名称。您可以在 nginx 配置中拥有多个服务器块,但它们必须都具有不同的名称。如果您未指定服务器名称,我相信它会默认为 $host。由于您使用位置来指定要重定向到的不同服务器,因此我建议在 1 个默认服务器块内使用多个位置块。通常,您会对不同的子域使用不同的服务器块。

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/; - that is IP of Docker continer.
      proxy_redirect        off;
      proxy_set_header        Host             $host;
      proxy_set_header        X-Real_IP        $remote_addr;
    }
}

相关内容