Configuring Nginx
Configuration
Redirect HTTP to HTTPS via 301
server {
listen *:80;
server_name k3s.functionalbytes.com;
server_tokens off; ## Don't show the nginx version number
location / {
return 301 https://k3s.functionalbytes.com:443$request_uri;
}
}
Including SSL Certificate for HTTPS
ssl_certificate /secret/keys/proxy.functionalbytes.com.fullchain;
ssl_certificate_key /secret/keys/proxy.functionalbytes.com.key;
WebSocket Connections
See: [nginx Documentation] WebSocket proxying
location /web_socket_path/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Load Balancing
See: [nginx Documentation] HTTP Load Balancing
upstream k3s_servers {
# Round Robin by default - can add "weight=#" after each server for weighting, e.g.:
# server k3s-s1.functionalbytes.com:80 weight=3;
# With this set and nothing on k3s-s2 (default = 1), 3 out of 4 requests will be sent to k3s-s1
# Alternatively one of the following can be uncommented for other load balancing options
# Uncomment the line below to use the one with the fewest connections
# least_conn;
# Uncomment to send requests to the server based on a hash of the first 3 octets of their IP (guaranteeing requests go to the same server unless it is unavailable)
# ip_hash;
server k3s-s1.functionalbytes.com:80;
server k3s-s2.functionalbytes.com:80;
}
Basic Full Example
upstream k3s_servers {
server k3s-s1.functionalbytes.com:80;
server k3s-s2.functionalbytes.com:80;
}
server {
listen *:80;
server_name k3s.functionalbytes.com;
server_tokens off; ## Don't show the nginx version number, a security best practice
location / {
return 301 https://k3s.functionalbytes.com:443$request_uri;
}
}
server {
listen 443 ssl http2;
server_name k3s.functionalbytes.com;
server_tokens off; ## Don't show the nginx version number, a security best practice
ssl_certificate /secret/keys/proxy.functionalbytes.com.fullchain;
ssl_certificate_key /secret/keys/proxy.functionalbytes.com.key;
# Allow large attachments
client_max_body_size 128M;
location / {
proxy_pass http://k3s_servers;
proxy_set_header Host $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 $scheme;
}
}
Adding Custom Stream Configs
- Add an include directive to
/config/nginx/nginx.conf
File:
/config/nginx/nginx.conf
stream { include /config/nginx/stream-confs/*; }
- Add the stream configs in
/config/nginx/stream-confs/
, e.g.:File:
/config/nginx/stream-confs/k3s.conf
upstream k3s_servers { server k3s-s1.functionalbytes.com:6443; server k3s-s2.functionalbytes.com:6443; } server { listen *:6443; ssl_certificate /secret/keys/proxy.functionalbytes.com.fullchain; ssl_certificate_key /secret/keys/proxy.functionalbytes.com.key; proxy_pass k3s_servers; }
Commands
Reload the nginx config without any downtime (sends SIGHUP
signal):
nginx -s reload
Verify configuration is valid:
nginx -t
PID Issue on Some Alpine Linux Docker Images
Note: I am currently using nginx:1.21-alpine
(official) which does not have this issue, but do still see the issue with linuxserver/nginx:1.20.2
(linuxserver.io image that I was using this on Unraid)
There is an issue where the PID file isn't created in the alpine linux version of nginx docker image. Running the reload command will result in the following error:
> nginx -s reload
nginx: [error] open() "/run/nginx/nginx.pid" failed (2: No such file or directory)
Two options for fixing this:
- Create the required directory
File:
Dockerfile
... RUN mkdir -p /run/nginx ...
- Override the PID location
nginx -g 'pid /tmp/nginx.pid; daemon off;'