github.com/drud/ddev@v1.21.5-alpha1.0.20230226034409-94fcc4b94453/containers/ddev-router/nginx.tmpl (about)

     1  
     2  {{ define "upstream" }}
     3      {{ if .Address }}
     4          {{ if .Network }}
     5              # Container={{ .Container.Name }} {{ .Network.IP }}:{{ .Address.Port }}
     6              server {{ .Container.Name }}:{{ .Address.Port }};
     7          {{ end }}
     8      {{ else if .Network }}
     9              # Container={{ .Container.Name }} (down)
    10          server {{ .Network.IP }} down;
    11      {{ end }}
    12  {{ end }}
    13  
    14  # If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
    15  # scheme used to connect to this server
    16  map $http_x_forwarded_proto $proxy_x_forwarded_proto {
    17    default $http_x_forwarded_proto;
    18    ''      $scheme;
    19  }
    20  
    21  # If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
    22  # server port the client connected to
    23  map $http_x_forwarded_port $proxy_x_forwarded_port {
    24    default $http_x_forwarded_port;
    25    ''      $server_port;
    26  }
    27  
    28  # If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
    29  # Connection header that may have been passed to this server
    30  map $http_upgrade $proxy_connection {
    31    default upgrade;
    32    '' close;
    33  }
    34  
    35  # Default dhparam
    36  # ssl_dhparam /etc/nginx/dhparam/dhparam.pem;
    37  
    38  # Set appropriate X-Forwarded-Ssl header
    39  map $scheme $proxy_x_forwarded_ssl {
    40    default off;
    41    https on;
    42  }
    43  
    44  gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    45  
    46  log_format vhost '$host $remote_addr - $remote_user [$time_local] '
    47                   '"$request" $status $body_bytes_sent '
    48                   '"$http_referer" "$http_user_agent"';
    49  
    50  access_log off;
    51  
    52  client_max_body_size 0;
    53  
    54  {{ if $.Env.RESOLVERS }}
    55  resolver {{ $.Env.RESOLVERS }};
    56  {{ end }}
    57  
    58  {{ if (exists "/etc/nginx/proxy.conf") }}
    59  include /etc/nginx/proxy.conf;
    60  {{ else }}
    61  # HTTP 1.1 support
    62  proxy_http_version 1.1;
    63  proxy_buffering off;
    64  proxy_set_header Host $http_host;
    65  proxy_set_header Upgrade $http_upgrade;
    66  proxy_set_header Connection $proxy_connection;
    67  proxy_set_header X-Real-IP $remote_addr;
    68  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    69  proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
    70  proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
    71  proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
    72  
    73  # Mitigate httpoxy attack (see README for details)
    74  proxy_set_header Proxy "";
    75  {{ end }}
    76  
    77  server {
    78      # Listen on all configured https ports + 80 + 443 (HTTPS_EXPOSE)
    79      # So that we can redirect any server_name that is invalid
    80      include /tmp/http_ports.conf;
    81      include /tmp/https_ports.conf;
    82  
    83      access_log /var/log/nginx/access.log vhost;
    84  
    85      error_page 503 @noupstream;
    86      location @noupstream {
    87          rewrite ^(.*)$ /503.html break;
    88          root /app;
    89      }
    90  
    91      location / {
    92          return 503;
    93      }
    94  
    95      ## provide a health check endpoint
    96      location = /healthcheck {
    97          access_log off;
    98          return 200;
    99      }
   100      ssl_session_tickets off;
   101      ssl_certificate /etc/nginx/certs/master.crt;
   102      ssl_certificate_key /etc/nginx/certs/master.key;
   103  }
   104  
   105  {{ range $host, $containers := groupByMulti $ "Env.VIRTUAL_HOST" "," }}
   106  
   107  {{ $host := trim $host }}
   108  
   109  {{ range $container := $containers }}
   110      {{/* HTTP_EXPOSE replaces the VIRTUAL_PORT var originally provided by jwilder/nginx-proxy. */}}
   111      {{/* HTTP_EXPOSE provides comma-separated ports to serve for container. Ports can be defined as hostPort:containerPort */}}
   112      {{ $ports := coalesce $container.Env.HTTP_EXPOSE "80" }}
   113      {{ $ports := split $ports "," }}
   114      # ports={{ $ports }}
   115      {{ range $port := $ports }}
   116          {{/* process values in hostPort:containerPort docker format, containerPort is upstream */}}
   117          {{ $container_ports := split $port ":" }}
   118          # container_ports={{ $container_ports }}
   119          {{ $upstream_port := last $container_ports }}
   120          {{ $bound_port := first $container_ports }}
   121          # bound_port={{$bound_port}}
   122          # upstream_port={{$upstream_port}}
   123  
   124          {{ $upstream_name := print $host "-" $container.Name "-" $upstream_port }}
   125  
   126          upstream {{ $upstream_name }} {
   127              keepalive 100;
   128          {{ $addrLen := len $container.Addresses }}
   129  
   130          {{/* jonaseberle/github-action-setup-ddev version */}}
   131          {{ range $containerNetwork := $container.Networks }}
   132              {{ if eq $containerNetwork.Name "ddev_default" }}
   133                  {{/* If only 1 port exposed, use that */}}
   134                  {{ if eq $addrLen 1 }}
   135                      {{ $address := index $container.Addresses 0 }}
   136                      {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
   137                      {{/* If more than one port exposed, use the one matching HTTP_EXPOSE env var, falling back to standard web port 80 */}}
   138                  {{ else }}
   139                      {{ $address := where $container.Addresses "Port" $upstream_port | first }}
   140                      {{/* $port := coalesce $container.Env.VIRTUAL_PORT "80" */}}
   141                      {{/* $address := where $container.Addresses "Port" $port | first */}}
   142                      {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }}
   143                 {{ end }}
   144              {{ end }}
   145          {{ end }}
   146          }
   147      {{ end }}
   148  {{ end }}
   149  
   150  {{ $default_host := or ($.Env.DEFAULT_HOST) "" }}
   151  {{ $default_server := index (dict $host "" $default_host "default_server") $host }}
   152  
   153  {{/* Get the VIRTUAL_PROTO defined by containers w/ the same vhost, falling back to "http" */}}
   154  {{ $proto := trim (or (first (groupByKeys $containers "Env.VIRTUAL_PROTO")) "http") }}
   155  
   156  {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}}
   157  {{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }}
   158  
   159  {{/* Get the NETWORK_ACCESS defined by containers w/ the same vhost, falling back to "external" */}}
   160  {{ $network_tag := or (first (groupByKeys $containers "Env.NETWORK_ACCESS")) "external" }}
   161  
   162  {{/* Get the VIRTUAL_ROOT By containers w/ use fastcgi root */}}
   163  {{ $vhost_root := or (first (groupByKeys $containers "Env.VIRTUAL_ROOT")) "/var/www/public" }}
   164  
   165  {{/* Use the master.crt by default */}}
   166  {{ $cert := "master" }}
   167  
   168  {{ range $container := whereExist $containers "Env.HTTP_EXPOSE" }}
   169      {{/* Get the HTTP_EXPOSE defined by containers w/ the same vhost, falling back to port 80 */}}
   170      {{ $ports := coalesce $container.Env.HTTP_EXPOSE "80" }}
   171      {{ $ports := split $ports "," }}
   172      {{ range $port := $ports }}
   173          {{/* process values in hostPort:containerPort docker format */}}
   174          {{ $container_ports := split $port ":" }}
   175          {{/* hostPort is port to listen on */}}
   176          {{ $listen_port := first $container_ports }}
   177          {{/* containerPort is upstream */}}
   178          {{ $bound_port := first $container_ports }}
   179          {{ $upstream_port := last $container_ports }}
   180          # container_ports={{$container_ports}}
   181          # bound_port={{$bound_port}}
   182          # upstream_port={{$upstream_port}}
   183          {{ $upstream_name := print $host "-" $container.Name "-" $upstream_port }}
   184  
   185          server {
   186              server_name {{ $host }};
   187              listen {{ $listen_port }} {{ $default_server }};
   188              access_log /var/log/nginx/access.log vhost;
   189  
   190              location @brokenupstream {
   191                  rewrite ^(.*)$ /502.html break;
   192                  root /app;
   193              }
   194  
   195              {{ if eq $network_tag "internal" }}
   196              # Only allow traffic from internal clients
   197              allow 127.0.0.0/8;
   198              allow 10.0.0.0/8;
   199              allow 192.168.0.0/16;
   200              allow 172.16.0.0/12;
   201              deny all;
   202              {{ end }}
   203  
   204              {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
   205              include {{ printf "/etc/nginx/vhost.d/%s" $host }};
   206              {{ else if (exists "/etc/nginx/vhost.d/default") }}
   207              include /etc/nginx/vhost.d/default;
   208              {{ end }}
   209  
   210              location / {
   211                  {{ if eq $proto "uwsgi" }}
   212                  include uwsgi_params;
   213                  uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }};
   214                  {{ else if eq $proto "fastcgi" }}
   215                  root   {{ trim $vhost_root }};
   216                  include fastcgi.conf;
   217                  fastcgi_pass {{ trim $upstream_name }};
   218                  {{ else }}
   219                  proxy_buffer_size   128k;
   220                  proxy_buffers   4 256k;
   221                  proxy_busy_buffers_size   256k;
   222                  proxy_read_timeout 10m;
   223                  proxy_http_version 1.1;
   224                  proxy_pass {{ trim $proto }}://{{ trim $upstream_name }};
   225                  {{ end }}
   226                  error_page 502 @brokenupstream;
   227                  {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
   228                  auth_basic	"Restricted {{ $host }}";
   229                  auth_basic_user_file	{{ (printf "/etc/nginx/htpasswd/%s" $host) }};
   230                  {{ end }}
   231                  {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }}
   232                  include {{ printf "/etc/nginx/vhost.d/%s_location" $host}};
   233                  {{ else if (exists "/etc/nginx/vhost.d/default_location") }}
   234                  include /etc/nginx/vhost.d/default_location;
   235                  {{ end }}
   236              }
   237          }
   238      {{ end }}
   239  
   240  {{ end }}
   241  
   242  {{/* HTTPS_EXPOSE works similarly to HTTP_EXPOSE, only no upstreams are created for HTTPS_EXPOSE ports. */}}
   243  {{/* Instead, an existing upstream for HTTP should be defined along with the port to listen for. e.g. 443:80 would listen on 443 and use an existing port 80 upstream */}}
   244  {{ range $container := whereExist $containers "Env.HTTPS_EXPOSE" }}
   245      {{/* Get the HTTPS_EXPOSE defined by containers w/ the same vhost, falling back to port 443:80 */}}
   246      {{ $ports := coalesce $container.Env.HTTPS_EXPOSE "443:80" }}
   247      {{ $ports := split $ports "," }}
   248      {{ range $port := $ports }}
   249          {{/* process values in hostPort:containerPort docker format */}}
   250          {{ $container_ports := split $port ":" }}
   251          {{/* hostPort is port to listen on */}}
   252          {{ $listen_port := first $container_ports }}
   253          {{/* containerPort is upstream */}}
   254          {{ $upstream_port := last $container_ports }}
   255          {{ $bound_port := first $container_ports }}
   256          # bound_port={{ $bound_port }}
   257          {{ $upstream_name := print $host "-" $container.Name "-" $upstream_port }}
   258  
   259          server {
   260              server_name {{ $host }};
   261              listen {{ $listen_port }} ssl {{ $.Env.HTTP2 }} {{ $default_server }};
   262              access_log /var/log/nginx/access.log vhost;
   263  
   264              location @brokenupstream {
   265                  rewrite ^(.*)$ /502.html break;
   266                  root /app;
   267              }
   268  
   269              {{ if eq $network_tag "internal" }}
   270              # Only allow traffic from internal clients
   271              allow 127.0.0.0/8;
   272              allow 10.0.0.0/8;
   273              allow 192.168.0.0/16;
   274              allow 172.16.0.0/12;
   275              deny all;
   276              {{ end }}
   277  
   278              ssl_prefer_server_ciphers on;
   279              ssl_session_timeout 5m;
   280              ssl_session_cache shared:SSL:50m;
   281              ssl_session_tickets off;
   282  
   283              {{ if (exists (printf "/mnt/ddev-global-cache/custom_certs/%s.crt" $host)) }}
   284                  ssl_certificate /mnt/ddev-global-cache/custom_certs/{{ (printf "%s.crt" $host) }};
   285                  ssl_certificate_key /mnt/ddev-global-cache/custom_certs/{{ (printf "%s.key" $host) }};
   286              {{ else if (exists (printf "/etc/letsencrypt/live/%s/fullchain.pem" $host)) }}
   287                  ssl_certificate /etc/letsencrypt/live/{{ $host }}/fullchain.pem;
   288                  ssl_certificate_key /etc/letsencrypt/live/{{ $host }}/privkey.pem;
   289              {{ else }}
   290                  ssl_certificate /etc/nginx/certs/{{ (printf "%s.crt" $cert) }};
   291                  ssl_certificate_key /etc/nginx/certs/{{ (printf "%s.key" $cert) }};
   292              {{ end }}
   293  
   294              {{ if (exists (printf "/etc/nginx/certs/%s.dhparam.pem" $cert)) }}
   295                  ssl_dhparam {{ printf "/etc/nginx/certs/%s.dhparam.pem" $cert }};
   296              {{ end }}
   297  
   298              {{ if (exists (printf "/etc/nginx/certs/%s.chain.crt" $cert)) }}
   299                  ssl_stapling on;
   300                  ssl_stapling_verify on;
   301                  ssl_trusted_certificate {{ printf "/etc/nginx/certs/%s.chain.crt" $cert }};
   302              {{ end }}
   303  
   304              {{/* if (ne $https_method "noredirect") */}}
   305              {{/* add_header Strict-Transport-Security "max-age=31536000"; */}}
   306              {{/* end */}}
   307  
   308              {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }}
   309                  include {{ printf "/etc/nginx/vhost.d/%s" $host }};
   310              {{ else if (exists "/etc/nginx/vhost.d/default") }}
   311                  include /etc/nginx/vhost.d/default;
   312              {{ end }}
   313  
   314              location / {
   315                  {{ if eq $proto "uwsgi" }}
   316                  include uwsgi_params;
   317                  uwsgi_pass {{ trim $proto }}://{{ trim $upstream_name }};
   318                  {{ else if eq $proto "fastcgi" }}
   319                  root   {{ trim $vhost_root }};
   320                  include fastcgi.conf;
   321                  fastcgi_pass {{ trim $upstream_name }};
   322                  {{ else }}
   323                  proxy_buffer_size   128k;
   324                  proxy_buffers   4 256k;
   325                  proxy_busy_buffers_size   256k;
   326                  proxy_read_timeout 10m;
   327                  proxy_http_version 1.1;
   328                  proxy_pass {{ trim $proto }}://{{ trim $upstream_name }};
   329                  {{ end }}
   330                  error_page 502 @brokenupstream;
   331  
   332                  {{ if (exists (printf "/etc/nginx/htpasswd/%s" $host)) }}
   333                  auth_basic	"Restricted {{ $host }}";
   334                  auth_basic_user_file	{{ (printf "/etc/nginx/htpasswd/%s" $host) }};
   335                  {{ end }}
   336                  {{ if (exists (printf "/etc/nginx/vhost.d/%s_location" $host)) }}
   337                  include {{ printf "/etc/nginx/vhost.d/%s_location" $host}};
   338                  {{ else if (exists "/etc/nginx/vhost.d/default_location") }}
   339                  include /etc/nginx/vhost.d/default_location;
   340                  {{ end }}
   341              }
   342          }
   343      {{ end }}
   344  
   345  {{ end }}
   346  
   347  {{ end }}