2013-08-13 14:00:20 -04:00
|
|
|
# Additional MIME types that you'd like nginx to handle go in here
|
|
|
|
types {
|
2014-05-14 01:08:29 -04:00
|
|
|
text/csv csv;
|
2021-06-23 11:31:12 -04:00
|
|
|
application/wasm wasm;
|
2013-08-13 14:00:20 -04:00
|
|
|
}
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
upstream discourse {
|
2020-06-18 11:30:08 -04:00
|
|
|
server unix:/var/www/discourse/tmp/sockets/nginx.http.sock;
|
2020-09-30 11:59:46 -04:00
|
|
|
server unix:/var/www/discourse/tmp/sockets/nginx.https.sock;
|
2013-02-05 14:16:51 -05:00
|
|
|
}
|
|
|
|
|
2019-11-06 20:12:24 -05:00
|
|
|
# inactive means we keep stuff around for 1440m minutes regardless of last access (1 week)
|
2021-05-20 21:43:47 -04:00
|
|
|
# levels means it is a 2 deep hierarchy cause we can have lots of files
|
2019-11-06 20:12:24 -05:00
|
|
|
# max_size limits the size of the cache
|
|
|
|
proxy_cache_path /var/nginx/cache inactive=1440m levels=1:2 keys_zone=one:10m max_size=600m;
|
2014-07-14 20:30:27 -04:00
|
|
|
|
2022-10-11 10:33:07 -04:00
|
|
|
# Increased from the default value to acommodate large cookies during oAuth2 flows
|
|
|
|
# like in https://meta.discourse.org/t/x/74060 and large CSP and Link (preload) headers
|
2022-11-07 10:11:06 -05:00
|
|
|
proxy_buffer_size 32k;
|
|
|
|
proxy_buffers 4 32k;
|
|
|
|
|
|
|
|
# Increased from the default value to allow for a large volume of cookies in request headers
|
|
|
|
# Discourse itself tries to minimise cookie size, but we cannot control other cookies set by other tools on the same domain.
|
|
|
|
large_client_header_buffers 4 32k;
|
2017-12-10 17:29:47 -05:00
|
|
|
|
2014-01-09 00:39:30 -05:00
|
|
|
# attempt to preserve the proto, must be in http context
|
|
|
|
map $http_x_forwarded_proto $thescheme {
|
|
|
|
default $scheme;
|
2022-12-30 07:35:26 -05:00
|
|
|
"~https$" https;
|
2014-01-09 00:39:30 -05:00
|
|
|
}
|
|
|
|
|
2021-01-26 16:03:20 -05:00
|
|
|
log_format log_discourse '[$time_local] "$http_host" $remote_addr "$request" "$http_user_agent" "$sent_http_x_discourse_route" $status $bytes_sent "$http_referer" $upstream_response_time $request_time "$upstream_http_x_discourse_username" "$upstream_http_x_discourse_trackview" "$upstream_http_x_queue_time" "$upstream_http_x_redis_calls" "$upstream_http_x_redis_time" "$upstream_http_x_sql_calls" "$upstream_http_x_sql_time"';
|
2015-06-15 21:37:08 -04:00
|
|
|
|
2021-05-25 18:39:31 -04:00
|
|
|
# Allow bypass cache from localhost
|
|
|
|
geo $bypass_cache {
|
|
|
|
default 0;
|
|
|
|
127.0.0.1 1;
|
|
|
|
::1 1;
|
|
|
|
}
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
server {
|
|
|
|
|
2015-06-15 21:37:08 -04:00
|
|
|
access_log /var/log/nginx/access.log log_discourse;
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
listen 80;
|
|
|
|
gzip on;
|
2014-10-22 20:05:42 -04:00
|
|
|
gzip_vary on;
|
2013-02-05 14:16:51 -05:00
|
|
|
gzip_min_length 1000;
|
2014-07-08 02:45:18 -04:00
|
|
|
gzip_comp_level 5;
|
2021-06-23 11:31:12 -04:00
|
|
|
gzip_types application/json text/css text/javascript application/x-javascript application/javascript image/svg+xml application/wasm;
|
2018-01-08 21:28:05 -05:00
|
|
|
gzip_proxied any;
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2015-01-17 04:26:21 -05:00
|
|
|
# Uncomment and configure this section for HTTPS support
|
|
|
|
# NOTE: Put your ssl cert in your main nginx config directory (/etc/nginx)
|
|
|
|
#
|
|
|
|
# rewrite ^/(.*) https://enter.your.web.hostname.here/$1 permanent;
|
|
|
|
#
|
|
|
|
# listen 443 ssl;
|
|
|
|
# ssl_certificate your-hostname-cert.pem;
|
|
|
|
# ssl_certificate_key your-hostname-cert.key;
|
|
|
|
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
|
|
|
# ssl_ciphers HIGH:!aNULL:!MD5;
|
|
|
|
#
|
|
|
|
|
2013-05-29 00:07:26 -04:00
|
|
|
server_name enter.your.web.hostname.here;
|
2014-05-14 01:08:29 -04:00
|
|
|
server_tokens off;
|
2013-02-28 11:24:03 -05:00
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
sendfile on;
|
|
|
|
|
|
|
|
keepalive_timeout 65;
|
2013-09-06 13:18:42 -04:00
|
|
|
|
|
|
|
# maximum file upload size (keep up to date when changing the corresponding site setting)
|
2015-02-22 18:50:09 -05:00
|
|
|
client_max_body_size 10m;
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2013-09-06 13:18:42 -04:00
|
|
|
# path to discourse's public directory
|
|
|
|
set $public /var/www/discourse/public;
|
|
|
|
|
2014-07-10 01:18:31 -04:00
|
|
|
# without weak etags we get zero benefit from etags on dynamically compressed content
|
|
|
|
# further more etags are based on the file in nginx not sha of data
|
|
|
|
# use dates, it solves the problem fine even cross server
|
|
|
|
etag off;
|
2014-12-08 22:49:02 -05:00
|
|
|
|
2014-12-03 06:47:28 -05:00
|
|
|
# prevent direct download of backups
|
|
|
|
location ^~ /backups/ {
|
|
|
|
internal;
|
|
|
|
}
|
2014-07-10 01:18:31 -04:00
|
|
|
|
2015-12-21 07:13:56 -05:00
|
|
|
# bypass rails stack with a cheap 204 for favicon.ico requests
|
2015-11-17 03:34:05 -05:00
|
|
|
location /favicon.ico {
|
2015-12-21 07:13:56 -05:00
|
|
|
return 204;
|
2015-12-21 07:14:36 -05:00
|
|
|
access_log off;
|
|
|
|
log_not_found off;
|
2015-11-17 03:34:05 -05:00
|
|
|
}
|
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
location / {
|
2013-09-06 13:18:42 -04:00
|
|
|
root $public;
|
2014-07-10 01:18:31 -04:00
|
|
|
add_header ETag "";
|
2014-01-08 20:36:42 -05:00
|
|
|
|
2016-01-07 23:46:52 -05:00
|
|
|
# auth_basic on;
|
|
|
|
# auth_basic_user_file /etc/nginx/htpasswd;
|
|
|
|
|
2024-11-28 22:08:33 -05:00
|
|
|
# proxy_set_header directives are inherited from the previous configuration
|
|
|
|
# level if and only if there are no proxy_set_header directives defined on
|
|
|
|
# the current level.
|
|
|
|
proxy_set_header Host $http_host;
|
|
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
|
|
proxy_set_header X-Request-Start "t=${msec}";
|
|
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
|
|
proxy_set_header X-Forwarded-Proto $thescheme;
|
|
|
|
proxy_set_header X-Sendfile-Type "";
|
|
|
|
proxy_set_header X-Accel-Mapping "";
|
|
|
|
|
2019-05-29 06:18:17 -04:00
|
|
|
location ~ ^/uploads/short-url/ {
|
|
|
|
proxy_pass http://discourse;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-09-28 19:24:33 -04:00
|
|
|
location ~ ^/(secure-media-uploads/|secure-uploads)/ {
|
2020-01-30 21:45:02 -05:00
|
|
|
proxy_pass http://discourse;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-09-30 11:59:46 -04:00
|
|
|
location ~* (fonts|assets|plugins|uploads)/.*\.(eot|ttf|woff|woff2|ico|otf)$ {
|
2014-02-12 23:36:51 -05:00
|
|
|
expires 1y;
|
2017-02-23 17:37:53 -05:00
|
|
|
add_header Cache-Control public,immutable;
|
2021-02-24 16:27:37 -05:00
|
|
|
add_header Access-Control-Allow-Origin *;
|
2019-05-29 06:18:17 -04:00
|
|
|
}
|
2013-09-06 13:18:42 -04:00
|
|
|
|
2015-07-03 11:43:33 -04:00
|
|
|
location = /srv/status {
|
|
|
|
access_log off;
|
|
|
|
log_not_found off;
|
|
|
|
proxy_pass http://discourse;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-01-08 20:38:15 -05:00
|
|
|
# some minimal caching here so we don't keep asking
|
2021-05-20 21:43:47 -04:00
|
|
|
# longer term we should increase probably to 1y
|
2018-01-08 20:38:15 -05:00
|
|
|
location ~ ^/javascripts/ {
|
|
|
|
expires 1d;
|
|
|
|
add_header Cache-Control public,immutable;
|
2021-02-24 16:27:37 -05:00
|
|
|
add_header Access-Control-Allow-Origin *;
|
2018-01-08 20:38:15 -05:00
|
|
|
}
|
|
|
|
|
2017-03-20 12:11:14 -04:00
|
|
|
location ~ ^/assets/(?<asset_path>.+)$ {
|
2013-09-06 13:18:42 -04:00
|
|
|
expires 1y;
|
2014-07-10 01:18:31 -04:00
|
|
|
# asset pipeline enables this
|
2019-04-10 22:41:16 -04:00
|
|
|
brotli_static on;
|
2014-07-08 02:45:18 -04:00
|
|
|
gzip_static on;
|
2017-02-23 17:37:53 -05:00
|
|
|
add_header Cache-Control public,immutable;
|
2017-03-20 12:11:14 -04:00
|
|
|
# HOOK in asset location (used for extensibility)
|
2014-12-08 22:49:02 -05:00
|
|
|
# TODO I don't think this break is needed, it just breaks out of rewrite
|
2013-09-06 13:18:42 -04:00
|
|
|
break;
|
2013-08-14 06:20:05 -04:00
|
|
|
}
|
|
|
|
|
2014-12-08 22:49:02 -05:00
|
|
|
location ~ ^/plugins/ {
|
|
|
|
expires 1y;
|
2017-02-23 17:37:53 -05:00
|
|
|
add_header Cache-Control public,immutable;
|
2021-02-24 16:27:37 -05:00
|
|
|
add_header Access-Control-Allow-Origin *;
|
2014-12-08 22:49:02 -05:00
|
|
|
}
|
2015-01-17 04:26:21 -05:00
|
|
|
|
2014-12-28 05:10:03 -05:00
|
|
|
# cache emojis
|
2017-07-20 18:22:59 -04:00
|
|
|
location ~ /images/emoji/ {
|
2014-12-28 05:10:03 -05:00
|
|
|
expires 1y;
|
2017-02-23 17:37:53 -05:00
|
|
|
add_header Cache-Control public,immutable;
|
2021-02-24 16:27:37 -05:00
|
|
|
add_header Access-Control-Allow-Origin *;
|
2014-12-28 05:10:03 -05:00
|
|
|
}
|
2014-12-08 22:49:02 -05:00
|
|
|
|
2013-09-06 13:18:42 -04:00
|
|
|
location ~ ^/uploads/ {
|
2024-11-28 22:08:33 -05:00
|
|
|
# proxy_set_header directives are inherited from the previous configuration
|
|
|
|
# level if and only if there are no proxy_set_header directives defined on
|
|
|
|
# the current level.
|
2014-07-14 00:26:25 -04:00
|
|
|
proxy_set_header Host $http_host;
|
|
|
|
proxy_set_header X-Real-IP $remote_addr;
|
2018-03-26 01:29:20 -04:00
|
|
|
proxy_set_header X-Request-Start "t=${msec}";
|
2014-07-14 00:26:25 -04:00
|
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
|
|
proxy_set_header X-Forwarded-Proto $thescheme;
|
2014-07-11 04:47:55 -04:00
|
|
|
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
|
|
|
|
proxy_set_header X-Accel-Mapping $public/=/downloads/;
|
2024-11-28 22:08:33 -05:00
|
|
|
|
2013-02-05 14:16:51 -05:00
|
|
|
expires 1y;
|
2017-02-23 17:37:53 -05:00
|
|
|
add_header Cache-Control public,immutable;
|
2013-02-05 14:16:51 -05:00
|
|
|
|
2013-09-06 13:18:42 -04:00
|
|
|
## optional upload anti-hotlinking rules
|
|
|
|
#valid_referers none blocked mysite.com *.mysite.com;
|
2014-02-12 23:36:51 -05:00
|
|
|
#if ($invalid_referer) { return 403; }
|
2013-02-28 11:24:03 -05:00
|
|
|
|
2013-10-01 11:52:04 -04:00
|
|
|
# custom CSS
|
2014-05-14 01:08:29 -04:00
|
|
|
location ~ /stylesheet-cache/ {
|
2021-02-17 22:11:13 -05:00
|
|
|
add_header Access-Control-Allow-Origin *;
|
2014-05-14 01:08:29 -04:00
|
|
|
try_files $uri =404;
|
|
|
|
}
|
2014-07-14 00:26:25 -04:00
|
|
|
# this allows us to bypass rails
|
2024-12-02 17:26:13 -05:00
|
|
|
location ~* \.(gif|png|jpg|jpeg|bmp|tif|tiff|ico|webp|avif)$ {
|
2021-02-17 22:11:13 -05:00
|
|
|
add_header Access-Control-Allow-Origin *;
|
2014-05-14 01:08:29 -04:00
|
|
|
try_files $uri =404;
|
|
|
|
}
|
2020-07-08 23:31:48 -04:00
|
|
|
# SVG needs an extra header attached
|
|
|
|
location ~* \.(svg)$ {
|
|
|
|
}
|
2013-10-01 11:52:04 -04:00
|
|
|
# thumbnails & optimized images
|
2015-05-19 06:31:12 -04:00
|
|
|
location ~ /_?optimized/ {
|
2021-02-17 22:11:13 -05:00
|
|
|
add_header Access-Control-Allow-Origin *;
|
2014-05-14 01:08:29 -04:00
|
|
|
try_files $uri =404;
|
|
|
|
}
|
2013-02-05 14:16:51 -05:00
|
|
|
|
|
|
|
proxy_pass http://discourse;
|
|
|
|
break;
|
|
|
|
}
|
2013-02-28 11:24:03 -05:00
|
|
|
|
2014-09-24 02:51:14 -04:00
|
|
|
location ~ ^/admin/backups/ {
|
2024-11-28 22:08:33 -05:00
|
|
|
# proxy_set_header directives are inherited from the previous configuration
|
|
|
|
# level if and only if there are no proxy_set_header directives defined on
|
|
|
|
# the current level.
|
2014-07-14 20:30:27 -04:00
|
|
|
proxy_set_header Host $http_host;
|
|
|
|
proxy_set_header X-Real-IP $remote_addr;
|
2018-03-26 01:29:20 -04:00
|
|
|
proxy_set_header X-Request-Start "t=${msec}";
|
2014-07-14 20:30:27 -04:00
|
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
|
|
proxy_set_header X-Forwarded-Proto $thescheme;
|
|
|
|
proxy_set_header X-Sendfile-Type X-Accel-Redirect;
|
|
|
|
proxy_set_header X-Accel-Mapping $public/=/downloads/;
|
2024-11-28 22:08:33 -05:00
|
|
|
|
2014-07-14 20:30:27 -04:00
|
|
|
proxy_pass http://discourse;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-07-14 00:26:25 -04:00
|
|
|
# This big block is needed so we can selectively enable
|
2019-02-15 12:45:09 -05:00
|
|
|
# acceleration for backups, avatars, sprites and so on.
|
2014-07-14 00:26:25 -04:00
|
|
|
# see note about repetition above
|
2024-12-18 08:59:27 -05:00
|
|
|
location ~ ^/(svg-sprite/|letter_avatar/|letter_avatar_proxy/|user_avatar|highlight-js|stylesheets|theme-javascripts|favicon/proxied|service-worker|extra-locales/(mf|overrides)) {
|
2015-05-22 00:23:47 -04:00
|
|
|
# if Set-Cookie is in the response nothing gets cached
|
|
|
|
# this is double bad cause we are not passing last modified in
|
|
|
|
proxy_ignore_headers "Set-Cookie";
|
2015-05-22 01:57:32 -04:00
|
|
|
proxy_hide_header "Set-Cookie";
|
2018-04-10 21:02:03 -04:00
|
|
|
proxy_hide_header "X-Discourse-Username";
|
|
|
|
proxy_hide_header "X-Runtime";
|
2015-05-22 00:23:47 -04:00
|
|
|
|
2014-07-14 20:30:27 -04:00
|
|
|
# note x-accel-redirect can not be used with proxy_cache
|
|
|
|
proxy_cache one;
|
2018-04-10 21:02:03 -04:00
|
|
|
proxy_cache_key "$scheme,$host,$request_uri";
|
2014-07-14 20:30:27 -04:00
|
|
|
proxy_cache_valid 200 301 302 7d;
|
2021-05-25 18:39:31 -04:00
|
|
|
proxy_cache_bypass $bypass_cache;
|
2014-02-12 23:36:51 -05:00
|
|
|
proxy_pass http://discourse;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-01-04 00:13:44 -05:00
|
|
|
# we need buffering off for message bus
|
2016-01-03 17:56:30 -05:00
|
|
|
location /message-bus/ {
|
2016-01-04 00:13:44 -05:00
|
|
|
proxy_http_version 1.1;
|
2016-01-03 17:56:30 -05:00
|
|
|
proxy_buffering off;
|
|
|
|
proxy_pass http://discourse;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-07-14 00:26:25 -04:00
|
|
|
# this means every file in public is tried first
|
2013-09-06 13:18:42 -04:00
|
|
|
try_files $uri @discourse;
|
|
|
|
}
|
|
|
|
|
|
|
|
location /downloads/ {
|
|
|
|
internal;
|
|
|
|
alias $public/;
|
|
|
|
}
|
|
|
|
|
|
|
|
location @discourse {
|
|
|
|
proxy_pass http://discourse;
|
2013-02-05 14:16:51 -05:00
|
|
|
}
|
|
|
|
}
|