diff --git a/Dockerfile b/Dockerfile index 6d5ce9b..0b19a3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,6 +26,9 @@ RUN wget https://github.com/jwilder/docker-gen/releases/download/$DOCKER_GEN_VER COPY . /app/ WORKDIR /app/ +# Add nginx.conf +ADD nginx.conf /etc/nginx/nginx.conf + ENV DOCKER_HOST unix:///tmp/docker.sock VOLUME ["/etc/nginx/certs"] diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..4469c30 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,34 @@ +user nginx; +worker_processes 1; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + server_names_hash_bucket_size 128; + proxy_read_timeout 10m; + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; +} +daemon off; diff --git a/nginx.tmpl b/nginx.tmpl index 9eb9520..3057348 100644 --- a/nginx.tmpl +++ b/nginx.tmpl @@ -37,7 +37,6 @@ log_format vhost '$host $remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent"'; -access_log off; {{ if (exists "/etc/nginx/proxy.conf") }} include /etc/nginx/proxy.conf; @@ -51,16 +50,24 @@ proxy_set_header Connection $proxy_connection; 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 $proxy_x_forwarded_proto; - +client_max_body_size 30M; # Mitigate httpoxy attack (see README for details) proxy_set_header Proxy ""; + {{ end }} server { server_name _; # This is just an invalid value which will never trigger on a real hostname. listen 80; - access_log /var/log/nginx/access.log vhost; - return 503; + access_log /var/log/nginx/access.log; + error_page 500 501 502 503 504 /custom_50x.html; + location / { + return 503; + } + location = /custom_50x.html{ + internal; + root /usr/share/nginx/html; + } } {{ if (and (exists "/etc/nginx/certs/default.crt") (exists "/etc/nginx/certs/default.key")) }} @@ -68,7 +75,14 @@ server { server_name _; # This is just an invalid value which will never trigger on a real hostname. listen 443 ssl http2; access_log /var/log/nginx/access.log vhost; - return 503; + error_page 500 501 502 503 504 /custom_50x.html; + location / { + return 503; + } + location = /custom_50x.html{ + internal; + root /usr/share/nginx/html; + } ssl_session_tickets off; ssl_certificate /etc/nginx/certs/default.crt; @@ -103,6 +117,50 @@ upstream {{ $host }} { {{ end }} } +{{ $websocket := or (first (groupByKeys $containers "Env.WEBSOCKET")) "nowebsocket" }} + +{{if eq $websocket "true" }} +upstream ws.{{ $host }} { +{{ range $container := $containers }} + {{ $addrLen := len $container.Addresses }} + + {{ range $knownNetwork := $CurrentContainer.Networks }} + {{ range $containerNetwork := $container.Networks }} + {{ if eq $knownNetwork.Name $containerNetwork.Name }} + ## Can be connect with "{{ $containerNetwork.Name }}" network + + {{/* If only 1 port exposed, use that */}} + {{ if eq $addrLen 1 }} + {{ $address := index $container.Addresses 0 }} + {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }} + {{/* If more than one port exposed, use the one matching SOCKET_PORT env var, falling back to standard web port 80 */}} + {{ else }} + {{ $port := coalesce $container.Env.SOCKET_PORT "80" }} + {{ $address := where $container.Addresses "Port" $port | first }} + {{ template "upstream" (dict "Container" $container "Address" $address "Network" $containerNetwork) }} + {{ end }} + {{ end }} + {{ end }} + {{ end }} +{{ end }} +} + +server { + server_name ws.{{ $host }}; + listen 80; + access_log /var/log/nginx/access.log; + + + + location / { + proxy_pass http://ws.{{ trim $host }}/websocketmobile/; + proxy_redirect $host /websocketmobile/; + } +} + +{{ end }} + + {{ $default_host := or ($.Env.DEFAULT_HOST) "" }} {{ $default_server := index (dict $host "" $default_host "default_server") $host }} @@ -142,6 +200,17 @@ server { server_name {{ $host }}; listen 443 ssl http2 {{ $default_server }}; access_log /var/log/nginx/access.log vhost; + error_page 404 /custom_404.html; + error_page 403 /custom_403.html; + location = /custom_404.html{ + internal; + root /usr/share/nginx/html; + } + location = /custom_403.html{ + internal; + root /usr/share/nginx/html; + } + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 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:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; @@ -195,6 +264,16 @@ server { server_name {{ $host }}; listen 80 {{ $default_server }}; access_log /var/log/nginx/access.log vhost; + error_page 404 /custom_404.html; + error_page 403 /custom_403.html; + location = /custom_403.html{ + internal; + root /usr/share/nginx/html; + } + location = /custom_404.html{ + internal; + root /usr/share/nginx/html; + } {{ if (exists (printf "/etc/nginx/vhost.d/%s" $host)) }} include {{ printf "/etc/nginx/vhost.d/%s" $host }};