Nginx in Docker with Local Let's Encrypt Certs¶
Docker Project folder
├── docker
│ ├── nginx
│ │ ├── docker-compose.yml
│ │ ├── cloudflare.ini
│ │ ├── nginx.conf
│ └── └── (any additional confs for server blocks)
└────────────
docker-compose.yml
services:
nginx:
image: nginx:latest
container_name: nginx
network_mode: "host"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./websocket.conf:/etc/nginx/conf.d/websocket.conf
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
# ports: # Expose ports 80 and 443 if not running in host mode
# - "80:80"
# - "443:443"
depends_on:
- certbot
certbot:
image: certbot/dns-cloudflare # Certbot with Cloudflare DNS plugin
container_name: certbot
network_mode: "host"
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
- ./cloudflare.ini:/etc/letsencrypt/cloudflare.ini # Cloudflare credentials
entrypoint: > # Right off the bat we'll request certs of our domains
/bin/sh -c "
certbot certonly --non-interactive --quiet --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
--email ${EMAIL} --agree-tos --no-eff-email --expand \
--domains '*.local.mydomain.com' --domains '*.tail.mydomain.com';
# Here we'll sleep 24 hours and call the renew function
while :; do
sleep 24h;
certbot renew --non-interactive --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini;
done"
nginx.conf
# Set the user that runs the Nginx worker processes.
user nginx;
# Automatically determine the number of worker processes based on available CPU cores.
worker_processes auto;
# Define the file where the master process ID is stored.
pid /run/nginx.pid;
# Include any additional module configurations located in /etc/nginx/modules-enabled/.
include /etc/nginx/modules-enabled/*.conf;
events {
# Maximum number of simultaneous connections per worker process.
worker_connections 1024;
}
http {
# Hide Nginx version information in responses for security.
server_tokens off;
# SSL settings: Allow only secure TLS versions.
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# Logging: Store access and error logs in default locations.
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Define a global proxy settings block to avoid duplication in individual servers.
# This helps ensure consistency across all proxy hosts.
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;
# Prevent clickjacking by denying the ability to embed this site in iframes.
add_header X-Frame-Options DENY;
# Prevent MIME-sniffing to avoid security risks.
add_header X-Content-Type-Options nosniff;
# set timeout
proxy_read_timeout 600s;
proxy_send_timeout 600s;
send_timeout 600s;
# ------------- PROXY HOSTS -----------------------------
# Redirect HTTP to HTTPS hosts for ALL *.local.thomasjwilde.com & *.tail.thomasjwilde.com
server {
listen 80;
listen [::]:80;
server_name *.local.thomasjwilde.com *.tail.thomasjwilde.com;
return 301 https://$host$request_uri;
}
# immich.local
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name immich.local.thomasjwilde.com;
# Let's Encrypt Certs generated by certbot container
ssl_certificate /etc/letsencrypt/live/local.thomasjwilde.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/local.thomasjwilde.com/privkey.pem;
# Enable HTTP Strict Transport Security (HSTS) for one year, including subdomains.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# enable websockets: http://nginx.org/en/docs/http/websocket.html
include /etc/nginx/conf.d/websocket.conf;
# Proxy settings for different subdomains
location / {
proxy_pass http://127.0.0.1:2283;
}
}
# Vaultwarden tail
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name vault.tail.thomasjwilde.com;
# Let's Encrypt Certs generated by certbot container
# Note that the `local.thomasjwilde.com` cert included the *.tail.thomasjwilde.com domain
ssl_certificate /etc/letsencrypt/live/local.thomasjwilde.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/local.thomasjwilde.com/privkey.pem;
# Enable HTTP Strict Transport Security (HSTS) for one year, including subdomains.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# Proxy settings for different subdomains
location / {
proxy_pass http://127.0.0.1:1776;
}
}
}
So I did try adding a task to the nginx
container to perform a hot reload every 48h or so, however, wheven I tried this using entrypoint
or command
, this prevented docker logs from occuring. However, I can just create a Timer
on the host to run the reload via a command,
To tail the logs: