1

I am trying to implement simple HLS streaming service that is running of Docker containers. In short, each service is dockerized Apache streaming node. Everything works fine. Except there is a problem is that every container runs on its own port and I have to address it like:

http://localhost:Port/service_name/*m3u8.

What I need to do is setup a proxy to do this port forwarding, so that there will be no need to use port number in URL.

Searching this topic, I got an impression that NGINX can do this job. However it seems that Proxy_Pass is failing to route request to container. In NGINX error log I get (111: Connection refused) error. Or 404. I tried tweaking it different ways without success. I am not expert in NGINX, so I am not sure if I am doing the right thing. Could someone at least point me in the right direction?

Here is my workflow:

I have built an image for Apache service and image for NGINX proxy. Then using Docker compose I create 3 containers (1 NGINX proxy an 2 Apache streams), all in one default network.

When I address the service without port number I get 505 error.

This is my Dockerfile for NGINX server:

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

This is Dockerfile for Apache service:

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

This is docker-compose.yml file:

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

This is NGINX config file in: /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

    }
}

And this is output from /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"

Thank you for any tips!

Update2: Thank you for advice.

The following code worked:

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

}

I can open URL http://muze.cf/hls/ without port number. However when I add another server block like this:

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

}

I get conflicting server name error:

    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"

Theoretically I should be able to make a lot of server blocks in the same domain ?

1 Answer 1

0

There are a couple of things you could try since I do not know all the details about your setup.

Option 1:

Remove the port :8003 from the proxy_pass statement in your nginx config file. Port 8003 is the port on the docker host that is bound to port 80 of your stream1 container. Since you are using the docker container IP in the proxy_pass statement, the container probably doesn't have port 8003 open, it wants a connection on port 80.

server {
    listen 80;

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

Option 2:

Another option for the same reason as option 1 is you could specify the host IP address in the proxy_pass statement. This assumes you have a fixed IP on the host.

server {
    listen 80;

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

Answer to Update 2:

In your update 2 section, you are getting an error that states there are conflicting server names. You can have multiple server blocks in an nginx configuration but they must all have different names. If you do not specify a server name, it defaults to $host I believe. Since you are using locations to specify different servers to redirect to, I recommend having multiple location blocks within 1 default server block. Generally you would use different server blocks for different subdomains.

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

General Advice:

In your nginx server block, there are a couple other options that you might want to set as well. This ensures that some of the header information gets passed along.

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;
    }
}
2
  • Thank you, I could not put code here. I updated the post instead!
    – PinPiguin
    May 13, 2019 at 10:45
  • @PinPiguin, you can't have multiple server blocks unless you give a different name to the server blocks. The name of the server block specifies the domain / subdomain that it would respond to. For example, domain.com or sub.domain.com. You want to use multiple location blocks in 1 subdomain block for your case. See my updated answer.
    – bzanchi
    May 14, 2019 at 11:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.