discourse/config/nginx.sample.conf

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

289 lines
9.3 KiB
Plaintext
Raw Normal View History

# Additional MIME types that you'd like nginx to handle go in here
types {
2014-05-14 13:08:29 +08:00
text/csv csv;
application/wasm wasm;
}
2013-02-06 03:16:51 +08:00
upstream discourse {
server unix:/var/www/discourse/tmp/sockets/nginx.http.sock;
server unix:/var/www/discourse/tmp/sockets/nginx.https.sock;
2013-02-06 03:16:51 +08:00
}
# inactive means we keep stuff around for 1440m minutes regardless of last access (1 week)
# levels means it is a 2 deep hierarchy cause we can have lots of files
# 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-15 08:30:27 +08: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
proxy_buffer_size 16k;
proxy_buffers 4 16k;
2017-12-11 06:29:47 +08:00
2013-11-18 12:53:36 +08:00
# If you are going to use Puma, use these:
#
# upstream discourse {
# server unix:/var/www/discourse/tmp/sockets/puma.sock;
2013-11-18 12:53:36 +08:00
# }
2014-01-09 13:39:30 +08:00
# attempt to preserve the proto, must be in http context
map $http_x_forwarded_proto $thescheme {
default $scheme;
https https;
}
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"';
# Allow bypass cache from localhost
geo $bypass_cache {
default 0;
127.0.0.1 1;
::1 1;
}
2013-02-06 03:16:51 +08:00
server {
access_log /var/log/nginx/access.log log_discourse;
2013-02-06 03:16:51 +08:00
listen 80;
gzip on;
gzip_vary on;
2013-02-06 03:16:51 +08:00
gzip_min_length 1000;
gzip_comp_level 5;
gzip_types application/json text/css text/javascript application/x-javascript application/javascript image/svg+xml application/wasm;
2018-01-09 10:28:05 +08:00
gzip_proxied any;
2013-02-06 03:16:51 +08: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;
#
server_name enter.your.web.hostname.here;
2014-05-14 13:08:29 +08:00
server_tokens off;
2013-02-06 03:16:51 +08:00
sendfile on;
keepalive_timeout 65;
# maximum file upload size (keep up to date when changing the corresponding site setting)
2015-02-23 07:50:09 +08:00
client_max_body_size 10m;
2013-02-06 03:16:51 +08:00
# path to discourse's public directory
set $public /var/www/discourse/public;
# 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;
# prevent direct download of backups
location ^~ /backups/ {
internal;
}
# bypass rails stack with a cheap 204 for favicon.ico requests
location /favicon.ico {
return 204;
2015-12-21 20:14:36 +08:00
access_log off;
log_not_found off;
}
2013-02-06 03:16:51 +08:00
location / {
root $public;
add_header ETag "";
# auth_basic on;
# auth_basic_user_file /etc/nginx/htpasswd;
location ~ ^/uploads/short-url/ {
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_pass http://discourse;
break;
}
location ~ ^/(secure-media-uploads/|secure-uploads)/ {
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_pass http://discourse;
break;
}
location ~* (fonts|assets|plugins|uploads)/.*\.(eot|ttf|woff|woff2|ico|otf)$ {
expires 1y;
2017-02-24 06:37:53 +08:00
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
location = /srv/status {
access_log off;
log_not_found off;
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_pass http://discourse;
break;
}
# some minimal caching here so we don't keep asking
# longer term we should increase probably to 1y
location ~ ^/javascripts/ {
expires 1d;
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
location ~ ^/assets/(?<asset_path>.+)$ {
expires 1y;
# asset pipeline enables this
brotli_static on;
gzip_static on;
2017-02-24 06:37:53 +08:00
add_header Cache-Control public,immutable;
# HOOK in asset location (used for extensibility)
# TODO I don't think this break is needed, it just breaks out of rewrite
break;
}
location ~ ^/plugins/ {
expires 1y;
2017-02-24 06:37:53 +08:00
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
}
2014-12-28 18:10:03 +08:00
# cache emojis
2017-07-21 06:22:59 +08:00
location ~ /images/emoji/ {
2014-12-28 18:10:03 +08:00
expires 1y;
2017-02-24 06:37:53 +08:00
add_header Cache-Control public,immutable;
add_header Access-Control-Allow-Origin *;
2014-12-28 18:10:03 +08:00
}
location ~ ^/uploads/ {
2014-07-14 12:26:25 +08:00
# NOTE: it is really annoying that we can't just define headers
# at the top level and inherit.
#
# proxy_set_header DOES NOT inherit, by design, we must repeat it,
# otherwise headers are not set correctly
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
2014-07-14 12:26:25 +08: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/;
2013-02-06 03:16:51 +08:00
expires 1y;
2017-02-24 06:37:53 +08:00
add_header Cache-Control public,immutable;
2013-02-06 03:16:51 +08:00
## optional upload anti-hotlinking rules
#valid_referers none blocked mysite.com *.mysite.com;
#if ($invalid_referer) { return 403; }
# custom CSS
2014-05-14 13:08:29 +08:00
location ~ /stylesheet-cache/ {
add_header Access-Control-Allow-Origin *;
2014-05-14 13:08:29 +08:00
try_files $uri =404;
}
2014-07-14 12:26:25 +08:00
# this allows us to bypass rails
location ~* \.(gif|png|jpg|jpeg|bmp|tif|tiff|ico|webp)$ {
add_header Access-Control-Allow-Origin *;
2014-05-14 13:08:29 +08:00
try_files $uri =404;
}
# SVG needs an extra header attached
location ~* \.(svg)$ {
}
# thumbnails & optimized images
location ~ /_?optimized/ {
add_header Access-Control-Allow-Origin *;
2014-05-14 13:08:29 +08:00
try_files $uri =404;
}
2013-02-06 03:16:51 +08:00
proxy_pass http://discourse;
break;
}
2014-09-24 14:51:14 +08:00
location ~ ^/admin/backups/ {
2014-07-15 08:30:27 +08:00
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
2014-07-15 08:30:27 +08: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/;
proxy_pass http://discourse;
break;
}
2014-07-14 12:26:25 +08:00
# This big block is needed so we can selectively enable
# acceleration for backups, avatars, sprites and so on.
2014-07-14 12:26:25 +08:00
# see note about repetition above
location ~ ^/(svg-sprite/|letter_avatar/|letter_avatar_proxy/|user_avatar|highlight-js|stylesheets|theme-javascripts|favicon/proxied|service-worker) {
2014-07-14 12:26:25 +08:00
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Request-Start "t=${msec}";
2014-07-14 12:26:25 +08:00
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $thescheme;
# 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";
proxy_hide_header "Set-Cookie";
2018-04-11 09:02:03 +08:00
proxy_hide_header "X-Discourse-Username";
proxy_hide_header "X-Runtime";
2014-07-15 08:30:27 +08:00
# note x-accel-redirect can not be used with proxy_cache
proxy_cache one;
2018-04-11 09:02:03 +08:00
proxy_cache_key "$scheme,$host,$request_uri";
2014-07-15 08:30:27 +08:00
proxy_cache_valid 200 301 302 7d;
proxy_cache_bypass $bypass_cache;
proxy_pass http://discourse;
break;
}
2016-01-04 13:13:44 +08:00
# we need buffering off for message bus
location /message-bus/ {
proxy_set_header X-Request-Start "t=${msec}";
2016-01-04 13:13:44 +08:00
proxy_set_header Host $http_host;
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 $thescheme;
proxy_http_version 1.1;
proxy_buffering off;
proxy_pass http://discourse;
break;
}
2014-07-14 12:26:25 +08:00
# this means every file in public is tried first
try_files $uri @discourse;
}
location /downloads/ {
internal;
alias $public/;
}
location @discourse {
proxy_set_header Host $http_host;
proxy_set_header X-Request-Start "t=${msec}";
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 $thescheme;
proxy_pass http://discourse;
2013-02-06 03:16:51 +08:00
}
}