nottiago
By:
nottiago

How to bind multiple domains (ports 80 and 443) to docker contained applications

October 30, 2014 78.1k views

Hello,

i would like to know how to bind a domain when accessed through port 80 or 443 to specific ports of a droplet that are used by docker contained applications.

E.g: I have app1 and app2, each running in their own docker container, on a single droplet; and I have domain1.com and domain2.com which I would like to bind to app1 and app2 respectively.

Thanks in advance!

3 Answers

The most basic way to expose a web app running in a Docker container to the outside is to bind port 80 in the container to port 80 on the host system:

docker run -d -p 80:80 coreos/apache /usr/sbin/apache2ctl -D FOREGROUND

Though when you are running multiple app that you can't have them all listen on the same port. One way to get around this would be to set up an Nginx reverse proxy in front of the containers.

For example, say you have two different app. Bind them to a random port on the local host:

docker run -d -p 127.0.0.1:3000:80 coreos/apache /usr/sbin/apache2ctl -D FOREGROUND
docker run -d -p 127.0.0.1:5000:80 coreos/apache /usr/sbin/apache2ctl -D FOREGROUND

Then you can configure an Nginx sconfiguration that looks something like this:

upstream app-a {
    server 127.0.0.1:3000;
}

upstream app-b {
    server 127.0.0.1:5000;
}

server {
        listen 80;
        server_name test.com www.test.com;

        location / {
            proxy_pass         http://app-a;
            proxy_redirect     off;
            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-Host $server_name;

        }
}

server {
        listen 80;
        server_name example.com www.example.com;

        location / {
            proxy_pass         http://app-b;
            proxy_redirect     off;
            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-Host $server_name;

        }
}

This would direct all requests to test.com to the web app running in the first Docker container and all requests to example.com to the second Docker container.

by O.S Tezer
In this DigitalOcean article, our goal is to learn about creating a docker container from a base image and building it to run Nginx (layer by layer). Later, following the steps from the beginning, we create a Dockerfile to automate the process using a custom input file for configurations. In the end, using this Nginx docker image, it becomes possible to create self-contained sandboxes running Nginx, which can be used to serve "dockerised" applications.
  • Is this solution intended to proxy_pass on a local machine, or will this work on an external server as well? I had to modify your config so that my ports are open externally and proxy_pass to my-domain.com:port This solution works but I'd rather not open up external ports if there's a way to route this internally. My configuration looks something like this:

    upstream gogs {
      server my-domain:3030;
    }
    
    server {
            listen 80;
            server_name sub.my-domain.com;
    
            location / {
                proxy_pass         http://gogs;
                proxy_redirect     off;
                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-Host $server_name;
            }
    }
    
    

    Thank you!

  • @lethjakman It depends on what the you're proxying to. In the example I gave above, the containers running Apache are bound to the localhost. Nginx then makes the available externally. How are you launching the containers?

    This binds them to port 3000 on the localhost:

    docker run -d -p 127.0.0.1:3000:80 coreos/apache /usr/sbin/apache2ctl -D FOREGROUND
    

    while this would make them available externally on port 3000:

    docker run -d -p 3000:80 coreos/apache /usr/sbin/apache2ctl -D FOREGROUND
    
  • I don't know if anyone is reading this but this didn't work for me. However for anyone looking for a way to do what the OP wanted to do, the above snippet works as long as you change

    location / {
    

    to

    location \ {
    

    I don't know why, but it works.

    Hope this helps someone. :)

Hi,

I follow your guideline but failed to reach my website by name !
My first website: app-a can be reach by ip at http://104.131.164.193:8001
My 2nd website: app-b can be reach by ip at http://104.131.164.193:8002

I config my default.conf as following:

upstream app-a {
server 104.131.164.193:8001;
}

upstream app-b {
server 104.131.164.193:8002;
}

server {
listen 80;
server_name smartconsulting.asia www.smartconsulting.asia;

    location / {
        proxy_pass         http://app-a;
        proxy_redirect     off;
        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-Host $server_name;

    }

}

server {
listen 80;
server_name adalidda.net www.adalidda.net;

    location / {
        proxy_pass         http://app-b;
        proxy_redirect     off;
        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-Host $server_name;

    }

}

then I run the following command to start my nginx server:
docker run -d --name nginx-proxy -v $(pwd)/default.conf:/etc/nginx/conf.d/default.conf:ro -p 80:80 nginx

I did pointed my GoDaddy config to DigitalOcean DNS but still can't access my website by name.
What is wrong in the above ?

Thank You
Kosona

Have another answer? Share your knowledge.