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 }}