This post is about how I set up easy, fully-automatic SSL for my TrueNAS Apps and Docker containers. I'm assuming a home/small business deployment.
The official instructions and support are great, but only work with CloudFlare and Route53 domain providers. Everyone else is on their own. Some folks buy a certificate, some run CertBot on their own and upload the cert to TrueNAS, some do manual DNS challenges every few months.
An easier way is to just use a reverse proxy that acquires and manages certificates for you, using ACME. The two easiest are Caddy and Traefik. TrueCharts is well integrated with their Traefik chart, but that chart has no way to enable Traefik's ACME. So let's go with Caddy.
All we need is to run Caddy via Launch Docker image and :
I also use the "kill" scaling policy to avoid race conditions on the writable volumes.
Everything else is the default.
In my `etccaddy` directory I have the Caddyfile that configures Caddy. There are many tutorials out there on how to write this, but here's what mine looks like:
This uses the Let's Encrypt STAGING environment for testing. When you're done testing comment out the `acme_ca` line to get real certs.
This example shows how to put an app at a path (truenas.example.com/static, and truenas.example.com/syncthing/) as well as at a subdomain (pp.example.com). The ports you see here are the ones that each app has been configured to export to the node. Since TrueNAS won't let you use port numbers below 9000, you usually have to use a port number other than the app default.
The official instructions and support are great, but only work with CloudFlare and Route53 domain providers. Everyone else is on their own. Some folks buy a certificate, some run CertBot on their own and upload the cert to TrueNAS, some do manual DNS challenges every few months.
An easier way is to just use a reverse proxy that acquires and manages certificates for you, using ACME. The two easiest are Caddy and Traefik. TrueCharts is well integrated with their Traefik chart, but that chart has no way to enable Traefik's ACME. So let's go with Caddy.
All we need is to run Caddy via Launch Docker image and :
- use official 'caddy' image
- mount a /config volume (Caddy stores its own config here that persists between docker image restarts and upgrades)
- mount a /data volume (Caddy stores the certificates here)
- mount a directory with your Caddyfile to /etc/caddy
- Forward container ports 80 and 443 to the node. I used 9080 and 9443. Have your router forward ports 80 and 443 to your TrueNAS box's IP and ports 9080 and 9443.
- Configure your Caddyfile to reverse proxy the containers you want to expose to the outside.
I also use the "kill" scaling policy to avoid race conditions on the writable volumes.
Everything else is the default.
In my `etccaddy` directory I have the Caddyfile that configures Caddy. There are many tutorials out there on how to write this, but here's what mine looks like:
Code:
# TrueNAS Reverse Proxy setup. The TrueNAS host has IP 192.168.1.10 # Services have port forwarding configured for any service that needs to be accessible from outside # The Caddy container handles ports 80 and 443 as forwarded by the router and again by TrueNAS. # Configure ACME { # Test configuration using Let's Encrypt staging environment. # Comment out when happy with your config to get a real certificate: acme_ca https://acme-staging-v02.api.letsencrypt.org/directory email your@email.com } truenas.example.com { # Simple proxy example: # Static web server hosted by static-file-server Docker container handle_path /static* { reverse_proxy 192.168.1.10:11080 } # Syncthing (official docker image) # Based on https://docs.syncthing.net/users/reverseproxy.html handle_path /syncthing/* { # The syncthing docs include this line, but it does what handle_path already does #uri strip_prefix /syncthing reverse_proxy http://192.168.1.10:9384 { header_up Host {upstream_hostport} # Caddy warning message says this is unnecessary: #header_up X-Forwarded-Host {host} } } redir /syncthing /syncthing/ } # PhotoPrism served as a subdomain. Uses a CNAME record that points 'pp' to truenas.example.com to reuse the DDNS entry. pp.example.com { reverse_proxy 192.168.1.10:12342 }
This uses the Let's Encrypt STAGING environment for testing. When you're done testing comment out the `acme_ca` line to get real certs.
This example shows how to put an app at a path (truenas.example.com/static, and truenas.example.com/syncthing/) as well as at a subdomain (pp.example.com). The ports you see here are the ones that each app has been configured to export to the node. Since TrueNAS won't let you use port numbers below 9000, you usually have to use a port number other than the app default.