Axon
Axon

Reputation: 271

Docker nginx multiple apps on one host

I'm confused by how I should manage reverse proxy (nginx) with multiple independent webapps on the same host. I know that i can use https://github.com/jwilder/nginx-proxy and configure VIRTUAL_HOST per app but then I wont be able to have nginx visible as a service in every app docker-compose.yml.

I want to do it this way because I want to clearly define all services needed to run app in production and replicate it easy in development.

In other words: I have two webapps that I need to run on the same host and I want to define nginx as a service dependency in docker-compose.yml in both apps but share that service with both as only one nginx can forward port 80.

Upvotes: 24

Views: 34186

Answers (3)

zerone
zerone

Reputation: 71

Had the same issue with django on production, turns out solving it is fairly straightforward.

The hack was to simply take the docker-compose.yml definition up a directory few levels. Making my file structure look something like this:

CodeRepo:
  app_0
  app_1
  app_2
  docker:
    docker-compose.yml
    config/nginx/conf:
      app_0.conf
      app_1.conf
      app_2.conf

Then the actual docker-compose file is defined as follows:

services:
      db:
        container_name: db
        image: postgres
        hostname: db
        env_file:
          - ../app_0/docker/.env.prod.db
        volumes:
          - app_0_data:/var/lib/postgresql/data
        networks:
          - app_0_backend
    
      app_0:
        build:
          context: ../app_0
          dockerfile: ../app_0/docker/Dockerfile.prod
        hostname: app_0_web
        env_file:
          - ../app_0/docker/.env.prod
        command: gunicorn --bind 0.0.0.0:8000 app_0.wsgi --workers=4
        volumes:
          - static_volume_app_0:/app_0/static
          - media_volume_app_0:/app_0/media
        expose:
          - "8000"
        links:
          - db:db
        depends_on:
          - db
        networks:
          - nginx_network
          - app_1
        restart: on-failure
    
    
      app_1:
        build:
          context: ../app_1
          dockerfile: ../app_1/docker/Dockerfile.prod
        hostname: app_1_web
        env_file:
          - ../app_1/docker/.env.prod
        command: gunicorn --bind 0.0.0.0:8001 app_1.wsgi --workers=4
        volumes:
          - static_volume_app_1:/app_1/static
          - media_volume_app_1:/app_1/media
        expose:
          - "8001"
        networks:
          - nginx_network
        restart: on-failure
    
      app_2:
        build:
          context: ../app_2
          dockerfile: ../app_2/docker/Dockerfile.prod
        hostname: app_2_web
        env_file:
          - ../app_2/docker/.env.prod
        command: gunicorn --bind 0.0.0.0:8002 django_project.wsgi --workers=4
        volumes:
          - static_volume_app_2:/app_2/static
          - media_volume_app_2:/app_2/media
        expose:
          - "8002"
        networks:
          - nginx_network
        restart: on-failure
    
      nginx:
        container_name: nginx
        image: nginx:1.13
        ports:
          - "80:80"
          - "443:443"

Upvotes: 0

Deki Jovic
Deki Jovic

Reputation: 169

You should also be able to open two ports in the same container

services:
web:
    image: your_image
    container_name: web
    ports:
        - 8080:80
        - 8081:81

And the add new config file for second app in nginx site-enabled (or conf.d) that will listen 81 port.

First App

server {
listen 80;
server_name localhost;
root /app/first;
}

Second App

server {
listen 81;
server_name localhost;
root /app/second;
}

So that:

  • first app access on localhost:8080
  • second app access on localhost:8081

Upvotes: 5

Oleh Vasylyev
Oleh Vasylyev

Reputation: 714

Dockerfile:

FROM ubuntu:14.04
MAINTAINER Test ([email protected])
# install nginx
RUN apt-get update -y
RUN apt-get install -y python-software-properties
RUN apt-get install -y software-properties-common
RUN add-apt-repository -y ppa:nginx/stable
RUN apt-get update -y
RUN apt-get install -y nginx
# deamon mode off
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
RUN chown -R www-data:www-data /var/lib/nginx
# volume
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/var/log/nginx"]
# expose ports
EXPOSE 80 443
# add nginx conf
ADD nginx.conf /etc/nginx/conf.d/default.conf
WORKDIR /etc/nginx
CMD ["nginx"]

nginx.conf:

server {
    listen          80;
    server_name     test1.com www.test1.com;
    location / {
        proxy_pass  http://web1:81/;
    }
}
server {
    listen          80;
    server_name     test2.com www.test2.com;
    location / {
        proxy_pass  http://web1:82/;
    }
}

** where web1 and web2 - container names

docker-compose.yml:

version: "2"
services:
    web1:
        image: your_image
        container_name: web1
        ports:
            - 81:80
    web2:
        image: your_image
        container_name: web2
        ports:
            - 82:80
    nginx:
        build: .
        container_name: nginx
        ports:
            - 80:80
            - 443:443
        links:
            - web1
            - web2

How to run:

docker-compose up -d

When you call test1.com - nginx forwards your request to container web1:81, when test2.com - to container web2:82

P.S.: your question was about NGINX-reverse-proxy. But better and easier do this with TRAEFIK https://traefik.io

Upvotes: 16

Related Questions