How to bring up a reverse proxy using the jwilder/nginx-proxy

    Introduction

    Exalate on-premise (such as Azure DevOps, ServiceNow) is deployed as Docker images. There is no built-in ssl support as it is much simpler to bring up a reverse proxy which can terminate SSL connections.

    Our preference is the jwilder/Nginx-proxy image which is a customization of the Nginx proxy.

    Note: A detailed tutorial is available here 

    The following steps provide a quick start-up.

    Setting up jwilder/nginx-proxy with the letsencrypt SSL configuration

    docker-compose.yml
    1 version: "2"
    2
    3 services:
    4  nginx-proxy:
    5    image: jwilder/nginx-proxy
    6    container_name: nginx-proxy
    7    ports:
    8      - "80:80"
    9      - "443:443"
    10    volumes:
    11      - /etc/nginx/vhost.d
    12      - /etc/nginx/certs
    13      - /usr/share/nginx/html
    14      - /var/run/docker.sock:/tmp/docker.sock:ro
    15    networks:
    16      - proxy
    17
    18  ssl-generator:
    19    image: jrcs/letsencrypt-nginx-proxy-companion
    20    volumes_from:
    21      - nginx-proxy
    22    volumes:
    23      - /var/run/docker.sock:/var/run/docker.sock:ro
    24    networks:
    25      - proxy
    26       
    27 networks:
    28  proxy:
    
    

    Using it in the container

    The next step is to configure a DNS name which points to the host which has the jwilder container running - assume exalate.acme.com

    In the service definition of the exalate configure the following environment variables, and then cycle the container:

     Expand source
    ...
        environment:
          - LETSENCRYPT_HOST=exalate.acme.com
          - VIRTUAL_HOST=exalate.acme.com
    ...

    The jwilder proxy will detect that the container has the VIRTUAL_HOST environment variable. This will automatically add in the nginx configuration

     Expand source
    # exalate.acme.com
    upstream exalate.acme.com {
                                    # Cannot connect to network of this container
                                    server 127.0.0.1 down;
                                    ## Can be connected with "nginx-proxy" network
                            # francisexalatenet_bluejira_1
                            server 172.18.0.8:8080;
    }
    server {
            server_name exalate.acme.com;
            listen 80 ;
            access_log /var/log/nginx/access.log vhost;
            return 301 https://$host$request_uri;
    }
    server {
            server_name exalate.acme.com;
            listen 443 ssl http2 ;
            access_log /var/log/nginx/access.log vhost;
            ssl_protocols TLSv1.2 TLSv1.3;
            ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:!DSS';
            ssl_prefer_server_ciphers on;
            ssl_session_timeout 5m;
            ssl_session_cache shared:SSL:50m;
            ssl_session_tickets off;
            ssl_certificate /etc/nginx/certs/exalate.acme.com.crt;
            ssl_certificate_key /etc/nginx/certs/exalate.acme.com.key;
            ssl_dhparam /etc/nginx/certs/exalate.acme.com.dhparam.pem;
            ssl_stapling on;
            ssl_stapling_verify on;
            ssl_trusted_certificate /etc/nginx/certs/exalate.acme.com.chain.pem;
            add_header Strict-Transport-Security "max-age=31536000" always;
            include /etc/nginx/vhost.d/default;
            location / {
                    proxy_pass http://exalate.acme.com;
            }
    }
    
    

    The letsencrypt integration will automatically generate a LetEncrypt SSL certificate and add it into the configuration. 

    Warning: It is important that the letsencrypt service has a clear path to exalate.acme.com as it will check if that service does exist with the right settings.