NGINX Reverse Proxy
Created: 6 Jul 2025.

The NGINX reverse proxy fronts all incoming HTTP & HTTPS requests and forwards these to the appropriate IP addresses that are usually hosted in one of the containers.
It also requests and automatically renews the Let’s Encrypt certificate for all incoming HTTPS requests for the two domains we host - thomas-pk.com and philiptk.com
The integration with Authelia is such that any container that requires authentication by Authelia, would have its web request forwarded to Authelia. Authelia checks if the request has an active on-going session, if not, the request is sent back to the Authelia login page. If an existing authenticated session already exists, the request is forwarded to the destination container. See Authelia Architecture for more details.
The configuration to set this up with the NGINX reverse proxy can be seen in the nginx.conf listing below from line 31 onwards.
nginx.conf
Given that there were not many recent (July 2025) examples for the nginx proxy integration with Authelia, I decided to provide the full listing of my NGINX reverse proxy configuration and Authelia configurations for public reference. I’ve managed to get the first basic flow working on the weekend of the 29th of Jun 2025.
My reference used for this configuration is based on that found at NGINX Integration with Authelia
1worker_processes 1;
2
3events {
4 worker_connections 1024;
5}
6
7http {
8 include mime.types;
9 default_type application/octet-stream;
10 sendfile on;
11 keepalive_timeout 65;
12
13 server {
14 server_name thomas-pk.com www.thomas-pk.com;
15
16 location / {
17 proxy_pass http://192.168.1.6:80;
18 proxy_set_header Host $host;
19 proxy_set_header X-Real-IP $remote_addr;
20 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
21 proxy_set_header X-Forwarded-Proto $scheme;
22 }
23
24 listen 443 ssl; # managed by Certbot
25 ssl_certificate /usr/local/etc/letsencrypt/live/philiptk.com-0001/fullchain.pem; # managed by Certbot
26 ssl_certificate_key /usr/local/etc/letsencrypt/live/philiptk.com-0001/privkey.pem; # managed by Certbot
27 include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
28 ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
29 }
30
31 server {
32 if ($host = login.thomas-pk.com) {
33 return 301 https://$host$request_uri;
34 } # managed by Certbot
35
36 listen 80;
37 server_name login.thomas-pk.com;
38 return 301 https://$server_name$request_uri;
39 }
40
41 server {
42 server_name login.thomas-pk.com;
43 set $upstream http://192.168.1.21:9091;
44
45 location / {
46 include /usr/local/etc/nginx/snippets/proxy.conf;
47 proxy_pass $upstream;
48 }
49
50 location = /api/verify {
51 proxy_pass $upstream;
52 }
53
54 location /api/authz/ {
55 proxy_pass $upstream;
56 }
57
58 listen 443 ssl; # managed by Certbot
59 ssl_certificate /usr/local/etc/letsencrypt/live/philiptk.com-0001/fullchain.pem; # managed by Certbot
60 ssl_certificate_key /usr/local/etc/letsencrypt/live/philiptk.com-0001/privkey.pem; # managed by Certbot
61 include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
62 ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
63 }
64
65 server {
66 if ($host = history.thomas-pk.com) {
67 return 301 https://$host$request_uri;
68 } # managed by Certbot
69
70 listen 80;
71 server_name history.thomas-pk.com;
72 return 301 https://$server_name$request_uri;
73 }
74
75 server {
76 server_name history.thomas-pk.com;
77 include /usr/local/etc/nginx/snippets/authelia-location.conf;
78 set $upstream http://192.168.1.22;
79
80 location / {
81 include /usr/local/etc/nginx/snippets/proxy.conf;
82 include /usr/local/etc/nginx/snippets/authelia-authrequest.conf;
83 proxy_pass $upstream;
84 }
85
86 listen 443 ssl; # managed by Certbot
87 ssl_certificate /usr/local/etc/letsencrypt/live/philiptk.com-0001/fullchain.pem; # managed by Certbot
88 ssl_certificate_key /usr/local/etc/letsencrypt/live/philiptk.com-0001/privkey.pem; # managed by Certbot
89 include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
90 ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
91 }
92
93 server {
94 server_name philiptk.com www.philiptk.com;
95
96 location / {
97 proxy_pass http://192.168.1.15:80;
98 proxy_set_header Host $host;
99 proxy_set_header X-Real-IP $remote_addr;
100 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
101 proxy_set_header X-Forwarded-Proto $scheme;
102 }
103
104 listen 443 ssl; # managed by Certbot
105 ssl_certificate /usr/local/etc/letsencrypt/live/philiptk.com-0001/fullchain.pem; # managed by Certbot
106 ssl_certificate_key /usr/local/etc/letsencrypt/live/philiptk.com-0001/privkey.pem; # managed by Certbot
107 include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
108 ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
109 }
110
111 server {
112 server_name cal.philiptk.com;
113 location / {
114 proxy_pass http://192.168.1.23:5232/;
115 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
116 proxy_set_header X-Forwarded-Host $host;
117 proxy_set_header X-Real-IP $remote_addr;
118 proxy_set_header X-Forwarded-Port $server_port;
119 proxy_set_header X-Forwarded-Proto $scheme;
120 proxy_set_header Host $http_host;
121 proxy_pass_header Authorization;
122 }
123
124 listen 443 ssl; # managed by Certbot
125 ssl_certificate /usr/local/etc/letsencrypt/live/philiptk.com-0001/fullchain.pem; # managed by Certbot
126 ssl_certificate_key /usr/local/etc/letsencrypt/live/philiptk.com-0001/privkey.pem; # managed by Certbot
127 include /usr/local/etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
128 ssl_dhparam /usr/local/etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
129 }
130
131 server {
132 if ($host = philiptk.com) {
133 return 301 https://$host$request_uri;
134 } # managed by Certbot
135
136 listen 80;
137 server_name philiptk.com;
138 return 404; # managed by Certbot
139 }
140
141 server {
142 if ($host = thomas-pk.com) {
143 return 301 https://$host$request_uri;
144 } # managed by Certbot
145
146 listen 80;
147 server_name thomas-pk.com;
148 return 404; # managed by Certbot
149 }
150
151 server {
152 if ($host = cal.philiptk.com) {
153 return 301 https://$host$request_uri;
154 } # managed by Certbot
155
156 listen 80;
157 server_name cal.philiptk.com;
158 return 404; # managed by Certbot
159 }
160}
Being hosted on the FreeBSD MiniPC, the above configuration is found in the /usr/local/etc/nginx/nginx.conf
location. It is supported by code snippets under the snippets
folder containing the following 3 files which are also listed below.
proxy.conf
authelia-location.conf
authelia-authrequest.conf
Snippets
proxy.conf
I used the same copy of this snippet as on the Authelia NGINX integration website.
The original reference for this file can be found at proxy.conf. The file given below is an exact copy of that on the Authelia website.
1## Headers
2proxy_set_header Host $host;
3proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
4proxy_set_header X-Forwarded-Proto $scheme;
5proxy_set_header X-Forwarded-Host $http_host;
6proxy_set_header X-Forwarded-URI $request_uri;
7proxy_set_header X-Forwarded-Ssl on;
8proxy_set_header X-Forwarded-For $remote_addr;
9proxy_set_header X-Real-IP $remote_addr;
10
11## Basic Proxy Configuration
12client_body_buffer_size 128k;
13proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; ## Timeout if the real server is dead.
14proxy_redirect http:// $scheme://;
15proxy_http_version 1.1;
16proxy_cache_bypass $cookie_session;
17proxy_no_cache $cookie_session;
18proxy_buffers 64 256k;
19
20## Trusted Proxies Configuration
21## Please read the following documentation before configuring this:
22## https://www.authelia.com/integration/proxies/nginx/#trusted-proxies
23# set_real_ip_from 10.0.0.0/8;
24# set_real_ip_from 172.16.0.0/12;
25# set_real_ip_from 192.168.0.0/16;
26# set_real_ip_from fc00::/7;
27real_ip_header X-Forwarded-For;
28real_ip_recursive on;
29
30## Advanced Proxy Configuration
31send_timeout 5m;
32proxy_read_timeout 360;
33proxy_send_timeout 360;
34proxy_connect_timeout 360;
authelia-location.conf
This file is also mostly the same as that on the NGINX Integration page for Authelia, except for the first line where I specify the IP address for my Authelia server.
The original reference for this file can be found at authelia-location.conf. The file given below is an exact copy of that on the Authelia website.
1set $upstream_authelia http://192.168.1.21:9091/api/authz/auth-request;
2
3## Virtual endpoint created by nginx to forward auth requests.
4location /internal/authelia/authz {
5 ## Essential Proxy Configuration
6 internal;
7 proxy_pass $upstream_authelia;
8
9 ## Headers
10 ## The headers starting with X-* are required.
11 proxy_set_header X-Original-Method $request_method;
12 proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
13 proxy_set_header X-Forwarded-For $remote_addr;
14 proxy_set_header Content-Length "";
15 proxy_set_header Connection "";
16
17 ## Basic Proxy Configuration
18 proxy_pass_request_body off;
19 proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; # Timeout if the real server is dead
20 proxy_redirect http:// $scheme://;
21 proxy_http_version 1.1;
22 proxy_cache_bypass $cookie_session;
23 proxy_no_cache $cookie_session;
24 proxy_buffers 4 32k;
25 client_body_buffer_size 128k;
26
27 ## Advanced Proxy Configuration
28 send_timeout 5m;
29 proxy_read_timeout 240;
30 proxy_send_timeout 240;
31 proxy_connect_timeout 240;
32}
authelia-authrequest.conf
The original reference for this file can be found at authelia-authrequest.conf. The file given below is an exact copy of that on the Authelia website.
1## Send a subrequest to Authelia to verify if the user is authenticated and has permission to access the resource.
2auth_request /internal/authelia/authz;
3
4## Save the upstream metadata response headers from Authelia to variables.
5auth_request_set $user $upstream_http_remote_user;
6auth_request_set $groups $upstream_http_remote_groups;
7auth_request_set $name $upstream_http_remote_name;
8auth_request_set $email $upstream_http_remote_email;
9
10## Inject the metadata response headers from the variables into the request made to the backend.
11proxy_set_header Remote-User $user;
12proxy_set_header Remote-Groups $groups;
13proxy_set_header Remote-Email $email;
14proxy_set_header Remote-Name $name;
15
16## Configure the redirection when the authz failure occurs. Lines starting with 'Modern Method' and 'Legacy Method'
17## should be commented / uncommented as pairs. The modern method uses the session cookies configuration's authelia_url
18## value to determine the redirection URL here. It's much simpler and compatible with the mutli-cookie domain easily.
19
20## Modern Method: Set the $redirection_url to the Location header of the response to the Authz endpoint.
21auth_request_set $redirection_url $upstream_http_location;
22
23## Modern Method: When there is a 401 response code from the authz endpoint redirect to the $redirection_url.
24error_page 401 =302 $redirection_url;
25
26## Legacy Method: Set $target_url to the original requested URL.
27## This requires http_set_misc module, replace 'set_escape_uri' with 'set' if you don't have this module.
28# set_escape_uri $target_url $scheme://$http_host$request_uri;
29
30## Legacy Method: When there is a 401 response code from the authz endpoint redirect to the portal with the 'rd'
31## URL parameter set to $target_url. This requires users update 'auth.example.com/' with their external authelia URL.
32# error_page 401 =302 https://auth.example.com/?rd=$target_url;