NGINX Setup

Ports

Files

Docker Creation

Docker Compose
nginx-proxy:
  image: nginx
  restart: unless-stopped
  ports:
    - '80:80'
    - '443:443'
  volumes:
    - /data/services/nginx/conf.d:/etc/nginx/conf.d:ro
    - /data/services/letsencrypt:/etc/nginx/ssl:ro
    - /etc/localtime:/etc/localtime:ro

Note

Let’s Encrypt local mount should just point to the install location of let’s encrypt, typically /etc/letsencrypt. See Let’s Encrypt.

Send NGINX Logs to System

If using NGINX as a proxy for dockers, setup to log to system.

Docker Compose
nginx-proxy:
  volumes:
    - /var/log/nginx:/var/log/nginx

Note

Restart NGINX container. Logs should appear in /var/log/nginx/*.log on host. Logs will no longer be accessible via docker logs.

Setup Base Reverse Proxy

This will setup a basic reverse-proxy that:

  • Forces HTTP to HTTPS connections for IPv4/6 with a permenant redirect.

  • Serves traffic only over SSL (443).

  • Enables HTTP2 if the service behind the proxy supports it.

  • Ability to upgrade a connection to a websocket if a service requires it.

  • Direct requests to the proxy cannot contain data.

  • Import SSL certificate settings used in Let’s Encrypt for strong validation of certifcate usage.

Automatic generator to generate base configuration templates.

0644 root root /etc/nginx/conf.d/reverse-proxy.conf
# Forward all HTTP IPv4/6 traffic to HTTPS.
server {
  listen                 80 default_server;
  listen                 [::]:80 default_server;
  server_name            {SERVER DNS NAME};
  return                 301 https://$server_name$request_uri;
}

# Websockets: remap http_upgrade to 'upgrade' or 'close' based on
# connection_upgrade being set.
map $http_upgrade $connection_upgrade {
  default                upgrade;
  ''                     close;
}

server {
  listen                  443 ssl http2;

  # Import SSL certificate options from letsencrypt
  ssl_certificate         /etc/nginx/ssl/live/{DOMAIN NAME}/fullchain.pem;
  ssl_certificate_key     /etc/nginx/ssl/live/{DOMAIN NAME}/privkey.pem;
  ssl_trusted_certificate /etc/nginx/ssl/live/{DOMAIN NAME}/chain.pem;
  ssl_dhparam             /etc/nginx/ssl/ssl-dhparams.pem;
  include                 /etc/nginx/ssl/options-ssl-nginx.conf;

  # Enable OCSP stapling https://en.wikipedia.org/wiki/OCSP_stapling.
  ssl_stapling            on;
  ssl_stapling_verify     on;
  resolver                127.0.0.1;

  client_max_body_size    0;
}
  • The SERVER DNS NAME should be in the SSL certificate; a wildcard certificate will work.

  • ssl-dhparams.pem may be generated with openssl dhparam -out ssl-dhparams.pem 4096.

  • resolver should be set to a DNS resolver. localhost, gateway or pihole are all viable options. Check logs to ensure resolution works.

Setup Base Proxy Control

A proxy control template will enable complex proxy configurations to be consistenly applied to multiple proxy sites.

0644 root root /etc/nginx/conf.d/proxy-control.conf
client_max_body_size               10m;
client_body_buffer_size            128k;

#Timeout if the real server is dead
proxy_next_upstream                error timeout invalid_header http_500 http_502 http_503;

# Advanced Proxy Config
send_timeout                       5m;
proxy_read_timeout                 240;
proxy_send_timeout                 240;
proxy_connect_timeout              240;

# Basic Proxy Config
proxy_set_header Host              $host:$server_port;
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 https;
proxy_redirect                     http://  $scheme://;
proxy_http_version                 1.1;
proxy_set_header Connection        '';
proxy_cache_bypass                 $cookie_session;
proxy_no_cache                     $cookie_session;
proxy_buffers                      32 4k;

Reload Configuration

Reload nginx configuration while running.
docker exec -it nginx-proxy nginx -s reload

Note

If underlying services have changed expose or ports, those containers will need to be restarted.