Docker Community Forums

Share and learn in the Docker community.

Docker with DNS redirection

#1

I’m a beginner in Docker.

I have the following scenario:
I have a ubuntu server with docker and docker-compose installed, I installed two containers with PHP and apache, one on port 80 and the other on port 8080, as follows:
app1: “htp://10.10.10.251”
app2: htp://10.10.10.251:8080

I have a DNS server with two A entries: app1.mydomain and app2.mydomain both pointing to the address 10.10.10.251.

My question is, how do I get the address app1.mydomain to direct to the app1 container and the address app2.mydomain direct to the app2 container without port 8080.

Any idea?

(Gary Forghetti) #2

You can run a reverse proxy container which will do the “redirection”.
That requires you to build a custom nginx docker image and run that too in your docker-compose.yml file.

Here’s a full example

Example docker-compose.yml

I used httpd for app1 in your case and Tomcat for app2.
By default httpd listens on port 80 and Tomcat on port 8080.
The nginx container listens on port 80.

If the nginx container gets a request for app1.mydomain on port 80 it redirects to port 81.
The app1 service has a publish of 81:80.
So app1 will get the request on port 80 inside the container.

If the nginx container gets a request for app2.mydomain on port 80 it redirects to port 82.
The app2 service has a publish of 82:8080.
So app2 will get the request on port 8080 inside the container.

version: '3.4'

networks:
  app_network:
    driver: overlay  
           
services:

  nginx_proxy:
    image: gforghetti/nginx:latest 
    networks:
      app_network:
    ports:
      - "80:80"  

  app1:
    image: httpd:latest
    networks:
      app_network:
        aliases:
          - app1.mydomain
    ports:
      - "81:80"  

  app2:
    image: tomcat:latest
    networks:
      app_network:
        aliases:
          - app2.mydomain
    ports:
      - "82:8080"      

Here is the Dockerfile I used to build the custom nginx reverse proxy container.

FROM nginx:alpine
EXPOSE 80
COPY ./nginx.conf /etc/nginx/nginx.conf

Here 's the custom Nginx nginx.conf configuration file to do the “redirecta”.

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;

    sendfile        on;

    keepalive_timeout  65;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen 0.0.0.0:80;
        server_name app1.mydomain;
        location ~ / {
           rewrite ^/(.*) http://$server_name:81/$1 permanent;
        }
    }

    server{
        listen 0.0.0.0:80;
        server_name app2.mydomain;
        location ~ / {
           rewrite ^/(.*) http://$server_name:82/$1 permanent;
        }
    }
}

To build the custom Nginx docker image.

# docker image build --tag gforghetti/nginx:latest --no-cache .
Sending build context to Docker daemon  11.78kB
Step 1/3 : FROM nginx:alpine
 ---> b411e34b4606
Step 2/3 : EXPOSE 80
 ---> Running in 5bd40cdef8f9
Removing intermediate container 5bd40cdef8f9
 ---> cf8cff3f1f72
Step 3/3 : COPY ./nginx.conf /etc/nginx/nginx.conf
 ---> 15e41fd5d025
Successfully built 15e41fd5d025
Successfully tagged gforghetti/nginx:latest

Now bring up the 3 service stack with docker-compose.

# docker-compose up -d
WARNING: The Docker Engine you're using is running in swarm mode.

Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.

To deploy your application across the swarm, use `docker stack deploy`.

Creating nginx_proxy_nginx_proxy_1 ... done
Creating nginx_proxy_app2_1        ... done
Creating nginx_proxy_app1_1        ... done

If you point your web browser to app1.mydomain and your DNS server routes that to the Docker node, you will see the httpd page.

🐳  gforghetti:[~] $ curl -L app1.mydomain
<html><body><h1>It works!</h1></body></html>

If you point your web browser to app2.mydomain and your DNS server routes that to the Docker node, you will see the Tomcat page.

🐳  gforghetti:[~] $ curl -L app2.mydomain
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.5.37</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <link href="tomcat.css" rel="stylesheet" type="text/css" />
    </head>

    <body>
        <div id="wrapper">
            <div id="navigation" class="curved container">
                <span id="nav-home"><a href="https://tomcat.apache.org/">Home</a></sp

I did not show the entire Tomcat HTML.

1 Like
#3

I understood how it will work, and if I have in the future more independent containers for web applications, app3, app4 … how would I create it? Httpd or TomCAT?

(Gary Forghetti) #4

I used the httpd and tomcat containers just to show you an example on how to deploy your applications.
I obviously do not have your applications so I could not use them in the example.
I choose the the httpd and tomcat containers because they listen on the same ports as your app (port 80) and app2 (port 8080). So they were perfect choices to show you an example on how to deploy your apps.
And because of that I was able to show you a working example.

You substitute the httpd docker image with your app1 docker image in the example docker-compose.yml file and you substitute the tomcat docker image with your app2 docker image in the example docker-compose.yml file.

#5

Yes, the example was perfect and I was able to adjust for my applications, thank you !!!
Is there any way to hide the port? When I enter app1.mydomayn it appears app1.mydomain:81, I wish the port would not appear.
It is possible?