user3142695
user3142695

Reputation: 17342

Nginx reverse proxy: How to get access to different container via subdomains?

This is how I configured my reverse proxy using nginx. There are docker container with nodeJS applications running (app1, app2, ...)

With this I point via localhost:8080 to the docker container app1 nodeJS application and with localhost:8081 to app2.

But I want to call the apps via subdomains without using the ports and I don't see how do get this. I also think I messed up the ports...

app1.localhost should point to app1 and app2.localhost should point to app2.

nginx.conf

http {
  sendfile on;

  upstream docker-app1 {
    server app1:80;
  }

  upstream docker-app2 {
    server app2:80;
  }

  server {
    listen 8080;
    server_name app1.localhost;
    location / {
      proxy_pass         http://docker-app1;
      proxy_redirect     off;
      proxy_buffering    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;
      #proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
    }
  }

  server {
    listen 8081;
    server_name app2.localhost;
    location / {
      proxy_pass         http://docker-app2;
      proxy_redirect     off;
      proxy_buffering    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;
      #proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
    }
  }
}

docker-compose.yml

version: '3.3'
services:
  nginx:
    container_name: 'nginx'
    image: 'nginx:1.13.5'
    restart: 'always'
    ports:
      - '80:80'
      - '8080:8080'
      - '8081:8081'
      - '443:443'
    volumes:
      - './nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro'

  app1:
    container_name: app1
    build: ./app1
    restart: always
    ports:
      - '3001:80'

  app2:
    container_name: app2
    build: ./app1
    restart: always
    ports:
      - '4200:80'

Update: As Sergiu provided a good link for reverse proxy, I updated the post with the new configuration; the question is still the same

Upvotes: 4

Views: 4347

Answers (2)

Jinna Baalu
Jinna Baalu

Reputation: 7829

Build and run doesn't work in version 3.x

create the docker images for your node applications.

Dockerfile for creating the images of node application

Dockerfile

FROM node:boron

# Create app directory
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json .
# For npm@5 or later, copy package-lock.json as well
# COPY package.json package-lock.json ./

RUN npm install

# Bundle app source
COPY . .

EXPOSE 8080
CMD [ "npm", "start" ]

Replcae the EXPOSE port accordingly

create the docker images

docker build -t app1 .

docker build -t app2 .

Create the hosts

sudo echo "127.0.0.1 app1.localhost" >> /etc/hosts

sudo echo "127.0.0.1 app2.localhost" >> /etc/hosts

nginx.conf

user root;

events {
    worker_connections  1024;
}

http {
    include            mime.types;
    default_type       application/octet-stream;
    sendfile           on;
    tcp_nopush         on;
    keepalive_timeout  65;
    gzip               on;
    gzip_types         text/plain text/css text/javascript
                       application/javascript application/json
                       application/xml;
    index              index.html index.htm;  

    server {
      listen 80;
      server_name server_name app1.localhost;;

      location / {
        proxy_pass http://172.31.42.174:8081/; 
        # Replace 172.31.42.174 with localhost if you are running reverse proxy in local server user private ip/public ip
        # Add other properties as required
      }
    }  

    server {
      listen 80;
      server_name server_name app2.localhost;;

      location / {
        proxy_pass http://172.31.42.174:8081/;
                # Replace 172.31.42.174 with localhost if you are running reverse proxy in local server user private ip/public ip
                # Add other properties as required
      }
    }  
}

docker-compose.yml

version: '3'
services:
    nginx:
        image: 'nginx:1.13.5'

        ports:
            - '80:80'
        volumes:
            - nginx-conf:/etc/nginx/nginx.conf:ro
        deploy:
            replicas: 1
            update_config:
                parallelism: 2
                delay: 10s
            restart_policy:
                condition: on-failure
            placement:
                constraints: [node.role == manager]

    app1:
        image: app1
        ports:
            - 8081:8081
        deploy:
            replicas: 1
            update_config:
                parallelism: 2
                delay: 10s
            restart_policy:
                condition: on-failure
    app2:
        image: app2
        ports:
            - 8081:8081
        deploy:
            replicas: 1
            update_config:
                parallelism: 2
                delay: 10s
            restart_policy:
                condition: on-failure

volumes:
  nginx-conf:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: /path/of/nginx/conf/nginx.conf

give full path of the nfginx.conf to the volume, as nginx is conf file dependent we need to run nginx at master node.

RUN

docker stack deploy -c docker-compose nodeapps

Status

docker stack ls

docker service ls

Upvotes: 1

Robert
Robert

Reputation: 36793

Instead of a custom nginx, using jwilder/nginx-proxy should be sufficient:

version: '3.3'
services:
  nginx:
    image: jwilder/nginx-proxy
    ports:
      - "80:80"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

  app1:
    container_name: app1
    build: ./app1
    restart: always
    environment:
      VIRTUAL_HOST: app1.localhost
    ports:
      - 80

  app2:
    container_name: app2
    build: ./app1
    restart: always
    environment:
      VIRTUAL_HOST: app2.localhost
    ports:
      - 80

Then put this in the /etc/host of your machine:

127.0.0.1 app1.localhost
127.0.0.1 app2.localhost

Use as this:

curl -i app1.localhost

jwilder/nginx-proxy will do the magic reading the VIRTUAL_HOST environment variable from each container (through the docket API), and then set up its config files accordingly.

Upvotes: 5

Related Questions