diff --git a/docker/Dockerfile b/docker/Dockerfile index 8626752..aca9438 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,5 +1,5 @@ ARG IMAGE_HOST=python -ARG IMAGE_LABEL=3.11.1-slim-buster +ARG IMAGE_LABEL=3.11-slim-bullseye FROM ${IMAGE_HOST}:${IMAGE_LABEL} @@ -37,8 +37,16 @@ RUN mkdir -p /cache # Python mimetypes package is missing some common mappings COPY docker/mime.types /etc/mime.types + +# Configure nginx +COPY docker/nginx.conf /etc/nginx/ +COPY docker/default.conf.tpl /etc/nginx/conf.d + COPY . /takahe +# Sanity-test the nginx config +RUN nginx -t + WORKDIR /takahe RUN TAKAHE_DATABASE_SERVER="postgres://x@example.com/x" TAKAHE_SECRET_KEY="takahe" TAKAHE_MAIN_DOMAIN="static.test" python3 manage.py collectstatic --noinput diff --git a/docker/default.conf.tpl b/docker/default.conf.tpl new file mode 100644 index 0000000..4143b62 --- /dev/null +++ b/docker/default.conf.tpl @@ -0,0 +1,110 @@ +proxy_cache_path /cache/nginx levels=1:2 keys_zone=takahe:20m inactive=14d max_size=__CACHESIZE__; + +upstream takahe { + server "127.0.0.1:8001"; +} + +# access_log /dev/stdout; + +server { + listen 8000; + listen [::]:8000; + server_name _; + + root /takahe/static; + index index.html; + + ignore_invalid_headers on; + proxy_connect_timeout 900; + + client_max_body_size 100M; + client_body_buffer_size 128k; + charset utf-8; + + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_http_version 1.1; + + # Serve robots.txt from the non-collected dir as a special case. + location /robots.txt { + alias /takahe/static/robots.txt; + } + + # Serves static files from the collected dir + location /static/ { + # Files in static have cache-busting hashes in the name, thus can be cached forever + add_header Cache-Control "public, max-age=604800, immutable"; + + alias /takahe/static-collected/; + try_files $uri /static//static-real$uri; + } + + # Static fallback for dev mode + location /static-real/ { + internal; + proxy_pass http://takahe/; + } + + # Proxies media and remote media with caching + location ~* ^/(media|proxy) { + # Cache media and proxied resources + proxy_cache takahe; + proxy_cache_key $host$uri; + proxy_cache_valid 200 304 4h; + proxy_cache_valid 301 307 4h; + proxy_cache_valid 500 502 503 504 0s; + proxy_cache_valid any 1h; + add_header X-Cache $upstream_cache_status; + + # Signal to Takahē that we support full URI accel proxying + proxy_set_header X-Takahe-Accel true; + + proxy_pass http://takahe; + } + + # Internal target for X-Accel redirects that stashes the URI in a var + location /__takahe_accel__/ { + internal; + set $takahe_realuri $upstream_http_x_takahe_realuri; + rewrite ^/(.+) /__takahe_accel__/real/; + } + + # Real internal-only target for X-Accel redirects + location /__takahe_accel__/real/ { + # Only allow internal redirects + internal; + + # Reconstruct the remote URL + resolver 9.9.9.9 149.112.112.112 ipv6=off; + + # Unset Authorization and Cookie for security reasons. + proxy_set_header Authorization ''; + proxy_set_header Cookie ''; + + # Stops the local disk from being written to (just forwards data through) + proxy_max_temp_file_size 0; + + # Proxy the remote file through to the client + proxy_pass $takahe_realuri; + proxy_ssl_server_name on; + add_header X-Takahe-Accel "HIT"; + + # Cache these responses too + proxy_cache takahe; + # Cache after a single request + proxy_cache_min_uses 1; + proxy_cache_key $takahe_realuri; + proxy_cache_valid 200 304 720h; + proxy_cache_valid 301 307 12h; + proxy_cache_valid 500 502 503 504 0s; + proxy_cache_valid any 72h; + add_header X-Cache $upstream_cache_status; + } + + # Default config for all other pages + location / { + proxy_redirect off; + proxy_buffering off; + proxy_pass http://takahe; + } +} diff --git a/docker/nginx.conf b/docker/nginx.conf index f0a985d..aa90efc 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -7,116 +7,13 @@ events { http { + sendfile on; + tcp_nopush on; + types_hash_max_size 2048; + include /etc/nginx/mime.types; + gzip on; - proxy_cache_path /cache/nginx levels=1:2 keys_zone=takahe:20m inactive=14d max_size=__CACHESIZE__; + include /etc/nginx/conf.d/*.conf; - upstream takahe { - server "127.0.0.1:8001"; - } - - # access_log /dev/stdout; - - server { - listen 8000; - listen [::]:8000; - server_name _; - - root /takahe/static; - index index.html; - - ignore_invalid_headers on; - proxy_connect_timeout 900; - - client_max_body_size 100M; - client_body_buffer_size 128k; - charset utf-8; - - proxy_set_header Host $http_host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_http_version 1.1; - - # Serve robots.txt from the non-collected dir as a special case. - location /robots.txt { - alias /takahe/static/robots.txt; - } - - # Serves static files from the collected dir - location /static/ { - # Files in static have cache-busting hashes in the name, thus can be cached forever - add_header Cache-Control "public, max-age=604800, immutable"; - - alias /takahe/static-collected/; - try_files $uri /static//static-real$uri; - } - - # Static fallback for dev mode - location /static-real/ { - internal; - proxy_pass http://takahe/; - } - - # Proxies media and remote media with caching - location ~* ^/(media|proxy) { - # Cache media and proxied resources - proxy_cache takahe; - proxy_cache_key $host$uri; - proxy_cache_valid 200 304 4h; - proxy_cache_valid 301 307 4h; - proxy_cache_valid 500 502 503 504 0s; - proxy_cache_valid any 1h; - add_header X-Cache $upstream_cache_status; - - # Signal to Takahē that we support full URI accel proxying - proxy_set_header X-Takahe-Accel true; - - proxy_pass http://takahe; - } - - # Internal target for X-Accel redirects that stashes the URI in a var - location /__takahe_accel__/ { - internal; - set $takahe_realuri $upstream_http_x_takahe_realuri; - rewrite ^/(.+) /__takahe_accel__/real/; - } - - # Real internal-only target for X-Accel redirects - location /__takahe_accel__/real/ { - # Only allow internal redirects - internal; - - # Reconstruct the remote URL - resolver 9.9.9.9 149.112.112.112 ipv6=off; - - # Unset Authorization and Cookie for security reasons. - proxy_set_header Authorization ''; - proxy_set_header Cookie ''; - - # Stops the local disk from being written to (just forwards data through) - proxy_max_temp_file_size 0; - - # Proxy the remote file through to the client - proxy_pass $takahe_realuri; - proxy_ssl_server_name on; - add_header X-Takahe-Accel "HIT"; - - # Cache these responses too - proxy_cache takahe; - # Cache after a single request - proxy_cache_min_uses 1; - proxy_cache_key $takahe_realuri; - proxy_cache_valid 200 304 720h; - proxy_cache_valid 301 307 12h; - proxy_cache_valid 500 502 503 504 0s; - proxy_cache_valid any 72h; - add_header X-Cache $upstream_cache_status; - } - - # Default config for all other pages - location / { - proxy_redirect off; - proxy_buffering off; - proxy_pass http://takahe; - } - } } diff --git a/docker/run.sh b/docker/run.sh index 7f73e06..af3ebb6 100644 --- a/docker/run.sh +++ b/docker/run.sh @@ -2,10 +2,10 @@ # Set up cache size CACHE_SIZE="${TAKAHE_NGINX_CACHE_SIZE:-1g}" -sed s/__CACHESIZE__/${CACHE_SIZE}/g /takahe/docker/nginx.conf > /takahe/docker/nginx.rendered.conf +sed s/__CACHESIZE__/${CACHE_SIZE}/g /etc/nginx/conf.d/default.conf.tpl > /etc/nginx/conf.d/default.conf # Run nginx and gunicorn -nginx -c "/takahe/docker/nginx.rendered.conf" & +nginx & gunicorn takahe.wsgi:application -b 0.0.0.0:8001 $GUNICORN_EXTRA_CMD_ARGS &