Wiki source code of NginX Server Key Configurations
Last modified by Eleni Cojocariu-testing account on 2026/08/18 15:04
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | [[NginX>>https://nginx.org/]] forwards requests to XWiki with the ##proxy_pass## directive of its [[proxy module>>https://nginx.org/en/docs/http/ngx_http_proxy_module.html]]. The directives below are the ones a wiki needs; [[Configure NginX Server as a Proxy on a Linux OS>>doc:documentation.xs.admin.installation.http-reverse-proxy.nginx-key-configurations.configure-nginx-server-linux.WebHome]] and [[Configure NginX Server as a Proxy on a Windows OS>>doc:documentation.xs.admin.installation.http-reverse-proxy.nginx-key-configurations.configure-nginx-server-windows.WebHome]] assemble them into a complete ##server## block, and [[Configure HTTPS for the NginX HTTP Proxy Server>>doc:documentation.xs.admin.installation.http-reverse-proxy.nginx-key-configurations.configure-https.WebHome]] adds the ##HTTPS## ones. The [[Apache Server Key Configurations>>doc:documentation.xs.admin.installation.http-reverse-proxy.apache-key-configurations.WebHome]] page documents the equivalent Apache HTTP Server directives. | ||
| 2 | |||
| 3 | == Server Block Directives == | ||
| 4 | |||
| 5 | These go in the ##server## block that serves the wiki. | ||
| 6 | |||
| 7 | |=Directive|=What it does | ||
| 8 | |##listen 80##|The port this server block answers on, ##80## being the default for plain ##HTTP##. See [[listen>>https://nginx.org/en/docs/http/ngx_http_core_module.html#listen]]. | ||
| 9 | |##server_name localhost##|The host name this block answers for. Set it to the wiki's public domain, for example {{code language="none"}}server_name wiki.example.com;{{/code}}. A request whose ##Host## header matches no ##server_name## reaches the server's default site instead, which is what answers with NginX's welcome page. See [[server_name>>https://nginx.org/en/docs/http/ngx_http_core_module.html#server_name]]. | ||
| 10 | |{{code language="none"}}access_log /var/log/nginx/xwiki-access.log;{{/code}} and {{code language="none"}}error_log /var/log/nginx/xwiki-error.log;{{/code}}|Optional per-wiki log files, so that proxy problems can be told apart from the rest of the server's traffic. See [[access_log>>https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log]]. | ||
| 11 | |##client_max_body_size 0##|Removes the limit on the size of a request body, ##1m## by default, which otherwise makes NginX answer ##413## for an attachment upload or a XAR import larger than that. See [[client_max_body_size>>https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size]]. | ||
| 12 | |{{code language="none"}}location = / { return 301 /xwiki/; }{{/code}}|Redirects the root URL to the wiki, so that {{code language="none"}}http://localhost{{/code}} reaches XWiki without ##/xwiki## being typed. The trailing slash matters: without it XWiki answers a second redirect to add it. See [[return>>https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return]]. | ||
| 13 | |{{code language="none"}}location /xwiki { ... }{{/code}}|Matches every request whose path starts with ##/xwiki## and applies the proxy directives below. See [[location>>https://nginx.org/en/docs/http/ngx_http_core_module.html#location]]. | ||
| 14 | |||
| 15 | == Proxy Directives == | ||
| 16 | |||
| 17 | These go inside the ##location /xwiki## block, except the ##map##, which belongs at ##http## level. | ||
| 18 | |||
| 19 | |=Directive|=What it does | ||
| 20 | |{{code language="none"}}proxy_pass http://localhost:8080;{{/code}}|Forwards the request to the Servlet Container. It is deliberately given **no path**: with one, for example {{code language="none"}}proxy_pass http://localhost:8080/xwiki;{{/code}}, NginX forwards the normalized path instead of the original one, so a page name containing an encoded slash (##%2F##), which XWiki page names can, silently reaches a different page. See [[proxy_pass>>https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass]]. | ||
| 21 | |##proxy_set_header Host $http_host##|Passes the client's ##Host## header on, so that XWiki builds URLs for the public domain rather than for ##localhost##. It has to be ##$http_host##, the header as the reader sent it, and not ##$host##, which NginX strips the port from: on a proxy listening anywhere other than ##80## or ##443##, ##$host## makes the wiki emit its own address without the port, and the redirects it answers with lead nowhere. See [[proxy_set_header>>https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header]]. | ||
| 22 | |##proxy_set_header X-Real-IP $remote_addr##|Sends the address NginX sees the request coming from, which a Servlet Container can be configured to log instead of the proxy's own address. | ||
| 23 | |##proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for##|Appends that address to the ##X-Forwarded-For## chain, so a request that already crossed another proxy keeps its history. NginX does not check what the client put in that chain and XWiki reads its first value, so it is not evidence of who sent the request; where this proxy is the only one in front of the wiki, send ##$remote_addr## instead. | ||
| 24 | |##proxy_set_header X-Forwarded-Proto $scheme##|Tells XWiki which protocol the reader used. It has to be the ##$scheme## variable and not a hard-coded ##http##: with the latter a wiki served over ##HTTPS## reports plain ##HTTP##, and XWiki builds every link with it. | ||
| 25 | |##proxy_set_header X-Forwarded-Host $http_host##|Replaces the ##X-Forwarded-Host## header a client may have sent with the real one, port included. NginX passes headers it does not set through untouched, and XWiki reads this one before anything else to build its URLs, so without this line a reader can choose the host of every link the wiki emits. | ||
| 26 | |{{code language="none"}}proxy_set_header Forwarded "";{{/code}}|Drops the ##Forwarded## header for the same reason: an empty value makes NginX send nothing at all, and it is the standard header XWiki looks at first. | ||
| 27 | |##proxy_http_version 1.1##|Uses ##HTTP/1.1## towards the container, which the WebSocket upgrade needs. See [[proxy_http_version>>https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version]]. | ||
| 28 | |{{code language="none"}}map $http_upgrade $connection_upgrade { default upgrade; "" ""; }{{/code}} with ##proxy_set_header Upgrade $http_upgrade## and ##proxy_set_header Connection $connection_upgrade##|Tunnels the WebSocket connections that realtime editing uses. The ##map## belongs at ##http## level, outside the ##server## block, and is what keeps ##Connection: upgrade## for the handshakes only: hard-coded, that header goes out on every request, including the ones upgrading nothing, and it rules out the connection reuse an ##upstream## block declaring ##keepalive## would otherwise bring. See [[map>>https://nginx.org/en/docs/http/ngx_http_map_module.html#map]]. | ||
| 29 | |##proxy_redirect off##|Leaves the ##Location## header of the container's redirects alone, which is what is wanted here: ##Host## is forwarded unchanged, so XWiki already redirects to the public address. See [[proxy_redirect>>https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect]]. | ||
| 30 | |||
| 31 | == HTTPS Directives == | ||
| 32 | |||
| 33 | These are added to the port ##443## block, on top of the proxy directives above. | ||
| 34 | |||
| 35 | |=Directive|=What it does | ||
| 36 | |{{code language="none"}}listen 443 ssl;{{/code}}|Opens the block that handles ##HTTPS## requests and turns TLS on for it. The block carries the same proxy directives as the port ##80## one, ##X-Forwarded-Proto## included: it is written ##$scheme##, so it reports ##https## here with nothing else to change. See [[listen>>https://nginx.org/en/docs/http/ngx_http_core_module.html#listen]]. | ||
| 37 | |##ssl_certificate /etc/ssl/certs/wiki.example.com.crt##|The certificate presented to browsers during the TLS handshake. NginX reads no separate chain file: an intermediate certificate goes in this same file, after the wiki's own. See [[ssl_certificate>>https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate]]. | ||
| 38 | |##ssl_certificate_key /etc/ssl/private/wiki.example.com.key##|The private key matching that certificate. See [[ssl_certificate_key>>https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key]]. | ||
| 39 | |||
| 40 | == Redirection Directives == | ||
| 41 | |||
| 42 | These make up the port ##80## block once ##HTTPS## serves the wiki: its body is replaced by them, so that a plain ##HTTP## request is redirected instead of proxied. | ||
| 43 | |||
| 44 | |=Directive|=What it does | ||
| 45 | |{{code language="none"}}location ^~ /.well-known/acme-challenge/ { root /var/www/html; }{{/code}}|Keeps the path an ACME client such as certbot answers the certificate challenge on reachable over plain ##HTTP##, so that automatic renewal keeps working. The ##^~#~# prefix is what makes NginX stop at this location instead of also trying the regular-expression ones the block may hold. See [[location>>https://nginx.org/en/docs/http/ngx_http_core_module.html#location]].## | ||
| 46 | |{{code language="none"}}return 301 https://$host$request_uri;{{/code}}|Redirects everything else to the ##HTTPS## address of the same URL. It is ##$host## here and not the ##$http_host## the proxy directives use, because ##$host## carries no port and the redirect must not put the port of the plain ##HTTP## listener into an {{code language="none"}}https://{{/code}} address. ##$request_uri## is the request as it arrived, so the ##%2F## an XWiki page name can contain crosses the redirect still encoded. See [[return>>https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return]]. |