Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to host two Docker containers exposing port 80 on the same server

Tags:

docker

I have 2 websites that clients need to connect to on port 80. Each website runs in its own container. I want to run both containers on the same Docker host.

I understand that port 80 can only be exposed on the Host one time. What solutions exist that have minimal overhead/administration that will allow me to simply run both containers on the same host (while still allowing clients to reach each container on port 80) ?

Both website 1 and website 2 should appear to client the web browser on port 80 and have friendly URL's (ie: www.web1.com, www.web2.com)

like image 741
CraigH Avatar asked Aug 05 '15 03:08

CraigH


People also ask

Can multiple Docker containers expose same port?

Surprisingly or not, neither Docker nor Podman support exposing multiple containers on the same host's port right out of the box. Example: docker-compose failing scenario with "Service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash."

Can we expose 2 ports in Dockerfile?

The above line will instruct Docker that the container's service can be connected to via port 8080. You can also expose multiple ports: By default, the EXPOSE keyword specifies that the port listens on TCP protocol.

Can you run 2 Docker containers at the same time?

It's ok to have multiple processes, but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application. You can connect multiple containers using user-defined networks and shared volumes.


2 Answers

Use an nginx reverse proxy:

  1. install Nginx on the host. On Debian/Ubuntu: apt-get install nginx. Note: I've assumed you don't have apache or some other web server on the host already...
  2. For each site, write an nginx site file in directory /etc/nginx/sites-available that redirects that site to a docker container's http that will run on some other prearranged port (for example, 2001, 2002, ...). Each site gets its own file, like the one below, but with different prearranged ports for each site. External users will access these at port 80 of the same IP address but with different web site names, and from these names nginx will handle the necessary internal connections invisibly.
  3. symlink the site files so they show up in directory /etc/nginx/sites-enabled and restart nginx. Later, you can remove one of these links and restart nginx if you need to temporarily disable access to a site.
  4. start the containers on system restart by adding docker run commands to /etc/rc.local, and redirecting the prearranged host port (localhost:2001) to container port 80 e.g. docker run -d -p localhost:2001:80 imageA

If a container is down you will get a gateway error from nginx. This could be customized to show a custom HTML page. For more robustness, it might be better to manage the containers in supervisord or some other process manager that respawns dead processes.

Here is an example nginx site file for a redirection to port 2001:

upstream dockerA { 
         server localhost:2001;
}

server {
       listen 192.168.1.8:80;  // REPLACE WITH HOST NUMERIC IP ADDRESS
       root /var/web/siteAstaticfiles;
       index index.html;
       server_name www.siteA.com;

       location / {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_set_header X-NginX-Proxy true;
                proxy_pass http://dockerA;
        }               
}

In this example, although a local disk directory for HTML files is set up for site A, it is not used. Instead all requests are sent to the upstream. I haven't tested whether the root and index lines can be safely omitted.

like image 68
Paul Avatar answered Sep 28 '22 09:09

Paul


A more proper way to host multiple websites on a single host using docker, docker-compose and nginx-proxy: https://blog.florianlopes.io/host-multiple-websites-on-single-host-docker/

like image 29
Ales Rebec Avatar answered Sep 28 '22 09:09

Ales Rebec