##
##  nginx.conf -- NGINX server configuration
##

user                                           @l_nusr@ @l_ngrp@;
error_log                                      @l_prefix@/var/nginx/log/nginx.log notice;
pid                                            @l_prefix@/var/nginx/run/nginx.pid;

worker_processes                               8;
worker_rlimit_nofile                           8192;

events {
    worker_connections                         1024;
}

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

    log_format main                            '$remote_addr - $remote_user [$time_local] $host "$request" '
                                               '$status $body_bytes_sent "$http_referer" '
                                               '"$http_user_agent" "$http_x_forwarded_for"';
    access_log                                 @l_prefix@/var/nginx/log/nginx.access.log main;

    sendfile                                   on;
    tcp_nopush                                 on;
    keepalive_timeout                          65;
    gzip                                       off;

    ssl_protocols                              TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers                                HIGH:!aNULL:!eNULL:!DES:!MD5:!EXPORT:!RC4;
    ssl_ecdh_curve                             secp384r1;
    ssl_prefer_server_ciphers                  on;
    ssl_session_cache                          shared:SSL:10m;
    ssl_session_tickets                        off;
    ssl_session_timeout                        10m;
    ssl_stapling                               on;
    ssl_stapling_verify                        on;

    proxy_http_version                         1.1;
    proxy_redirect                             off;
    proxy_buffering                            off;
    proxy_connect_timeout                      240;
    proxy_send_timeout                         240;
    proxy_read_timeout                         240;

    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }

    server {
        server_name                            _;

        listen                                 0.0.0.0:80 default_server;
        listen                                 0.0.0.0:443 default_server ssl http2;

        ssl_certificate                        @l_prefix@/etc/x509/example-server.crt.pem;
        ssl_certificate_key                    @l_prefix@/etc/x509/example-server.key.pem;
        ssl_trusted_certificate                @l_prefix@/etc/x509/example-ca.crt.pem;

        location / {
            root                               @l_prefix@/share/nginx/html;
            index                              index.html;
        }
    }

    {{ range $paramUrlHost, $containers := groupByMulti $ "Env.PROXY_URL_HOST" "," }}

    {{ $paramUrlHost := trim $paramUrlHost }}

    server {
        server_name                            {{ $paramUrlHost }};
        listen                                 0.0.0.0:80;

        {{ $paramCrtName  := or (first (groupByKeys $containers "Env.PROXY_CRT_NAME")) $paramUrlHost }}
        {{ $vhostCert := (closest (dir "/conf") (printf "%s.crt" $paramUrlHost)) }}
        {{ $vhostCert := trimSuffix ".crt" $vhostCert }}
        {{ $vhostCert := trimSuffix ".key" $vhostCert }}
        {{ $certName := (coalesce $paramCrtName $vhostCert) }}
        {{ $pathnameCrt := (printf "/conf/%s.crt" $certName) }}
        {{ $pathnameKey := (printf "/conf/%s.key" $certName) }}
        {{ $pathnameChn := (printf "/conf/%s.chn" $certName) }}
        {{ $withHTTPS := (and (ne $certName "") (exists $pathnameCrt) (exists $pathnameKey)) }}
        {{ if $withHTTPS }}
        listen                                 0.0.0.0:443 ssl http2;
        ssl_certificate                        {{ $pathnameCrt }};
        ssl_certificate_key                    {{ $pathnameKey }};
        {{ if (exists $pathnameChn) }}
        ssl_trusted_certificate                {{ $pathnameChn }};
        {{ end }}
        error_page 497                         https://$host$request_uri;
        {{ end }}

        location / {
            root                               @l_prefix@/share/nginx/html;
            index                              index.html;
        }

        {{ range $index, $container := $containers }}

        {{ $paramUrlPath := $container.Env.PROXY_URL_PATH }}
        {{ $paramDstPath := or $container.Env.PROXY_DST_PATH $paramUrlPath }}
        {{ $upstreamName := sha1 (printf "%s%s" $paramUrlHost $paramUrlPath) }}

        {{ $paramUrlScheme := or (first (groupByKeys $containers "Env.PROXY_URL_SCHEME")) "http" }}

        #   container: {{ $container.Name }}
        location {{ $paramUrlPath }} {
            {{ if (and $withHTTPS (eq $paramUrlScheme "https")) }}
            if ($scheme = "http") {
                rewrite                        ^ https://$http_host$request_uri? permanent;
            }
            {{ end }}
            {{ if (and $withHTTPS (eq $paramUrlScheme "http")) }}
            if ($scheme = "https") {
                rewrite                        ^ http://$http_host$request_uri? permanent;
            }
            {{ end }}
            proxy_pass                         http://{{ $upstreamName }}{{ $paramDstPath }};
            proxy_redirect                     default;
            proxy_set_header Host              $http_host;
            proxy_set_header Upgrade           $http_upgrade;
            proxy_set_header Connection        $connection_upgrade;
            proxy_set_header X-Real-IP         $remote_addr;
            proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }

        {{ end }}
    }

    {{ range $index, $container := $containers }}

    {{ $paramUrlPath := $container.Env.PROXY_URL_PATH }}
    {{ $upstreamName := sha1 (printf "%s%s" $paramUrlHost $paramUrlPath) }}

    {{ $network := index (where $container.Networks "Name" "proxy_proxy") 0 }}
    {{ $address := index $container.Addresses 0 }}
    {{ $paramDstPort := or $container.Env.PROXY_DST_PORT $address.Port }}

    #   container: {{ $container.Name }}
    upstream {{ $upstreamName }} {
        server {{ $network.IP }}:{{ $paramDstPort }};
    }

    {{ end }}

    {{ end }}
}

