Hosting Domain via TrueNAS Best Practices: NGINX, Traefik, or Caddy

I’ve been going over old forum posts to determine the optimal method of reverse proxying onto a cheap domain I leased for easier access to backup and access files. NGINX has a community app available and looks simple to set up, but I’ve read that Traefik is highly recommended due to more security options such as geoblocking IP’s in all other countries, integration with Fail2Ban to prevent brute force connections and other seemingly useful functions described. Caddy was described as “set and forget”, which seems to have some use as well.

The post I was reading about Traefik was referring to using TrueCharts, which I understand no longer has compatibility, so some manual configuration is likely necessary which isn’t a dealbreaker if the functions are sufficiently better than NGINX somehow.

In essence, an explanation about which you use, why, and any issues you encountered would be greatly appreciated. I’m leaning towards NGINX currently due to the integration, but thought to ask for experiences and advice before committing. Also, do you use Cloudflare as part of your self-hosting process? I was reading that their ToS prohibits large video transfers, and my family have a more than a few multi-Gigabyte recordings on our phones- would this be an issue and what alternative measures would you recommend to mitigate the risks stemming from port forwarding if so?

If it makes any difference, the reason for a reverse proxy is to allow access to my hosted NextCloud for my family to save compared to Google Drive (breakeven price in just 3 1/2 years) and Immich for photo backups for everyone.

While I’ve worked with computers since I was young this is my first time setting up a server with port forwarding so my family can back up their computers and phones easily (I just used wireguard), so I apologize for the possibly basic question. I have read tutorials on how to set it up, but they don’t explain their choice about why they chose what they did and I would like to make an informed choice before exposing the server instead of blindly following a guide. Thank you for your guidance!

I took entirely different approach with tbis. Since I’m not providing public service for thousands of users, making the service accessible to entire Internet and then securing access feels counterproductive.

Instead, I’ve setup zerotier on the TrueNAS directly, and on every device that needs backup.

The same probably can be accomplished with TailScale — but i needed mDNS to work as well.

1 Like

I, for one, use swag. It is a combination of nginx, fail2ban and some other stuff like LE cert issuing or preconfigured reverse-proxy configurations for various services. It is not truenas specific (moreover, I do not run it on truenas). You can run it on any system with docker compose. While it has some annoying issues, it has been ok so far for the last several years I’ve been using it.

If I were starting from scratch, I would take a look into nginx proxy manager. Saw it a couple of times on YouTube. Looks more GUI friendly. Now that I have about half a dozen of swag instances on several different PCs/VMs I won’t migrate to anything else without a very strong reason.

That is very unlikely IMO that you can find a person who has experience with all reverse proxies (mb some tech-bloggers have). So you should just pick what looks good to you.

1 Like

I have tested many, including Nginx Proxy Manager, but since I needed something a little more professional, I am now using HestiaCP, and I can say that it has exceeded my expectations.

I used to use ispconfig for my domain server, but then I switched to Sentora (formerly Zpanel) along with Nginx Proxy Manager to manage my services with reverse proxy.

But now I only use HestiaCP, which does both services together. It is a little more complicated to configure, but if you need a complete domain server host, free and open source, it is unbeatable, it has an email server, FTP, database, firewalls and much more, practically a Cpanel, but in my opinion much better and more advanced.

Now if you just need a reverse proxy, you can go with Nginx Proxy Manager without fear, it is simple, easy to configure and even easier to understand, just don’t expect advanced configurations, which are more difficult to implement in it.

1 Like

Before I really get into what you’re asking about, how many family members are we talking about? If it’s just a few, consider whether Tailscale might meet your needs–that would allow your family members to access these resources without exposing services to the whole Internet, and thus would be considerably more secure. See:

and

Please don’t confuse Nginx Proxy Manager (NPM) with Nginx–the former does indeed have an app available and provides a relatively straightforward GUI to configure it; neither of these is true of the latter. There’s a guide for NPM here:

One of its drawbacks is that its logging is limited at best, making it difficult to debug when things (like issuing a certificate, for example) don’t work as expected.

I have some experience with Caddy and wouldn’t describe it that way, but it’s much more able to “do the right thing” out of the box than other web servers/RPs and thus needs much less (and much simpler) configuration.

Traefik is a very popular reverse proxy, of course. One of its more helpful features is that you can configure a proxy destination via labels in your Compose file, so you don’t directly need to edit Traefik’s configuration. Caddy can also be used this way, but it isn’t as common or well-documented. Traefik’s initial setup is probably the most complex, but it’s probably the easiest in day-to-day operation, particularly if you’re adding or removing apps.

So: Consider using Tailscale to avoid needing to open up your services to the Internet at all. Then, the RP recommendation would depend on how you’re going to be running your apps. If you’re doing everything via the “custom app” or pure Compose route (which is what I’m doing–installed Dockge from what they’re now calling the App Store, and then deal with the Compose files directly), I’d recommend (and am using) Traefik. All regular TrueNAS apps? NPM. Caddy if you want to prepare the config file yourself, as it’s the easiest to do this.

1 Like

Are you using all 3 at the moment?

I’m using Traefik and Caddy, though in different applications. I don’t use NPM.

Since I have a residential internet connection, I use DDNS Updater with Cloudflare to keep my DNS address updated, and the Nginx Reverse Proxy (along with the necessary port forwarding from 80/443 to the Nginx Reverse Proxy ports in TrueNAS) with Let’s Encrypt certificates to provide external access to services such as Audiobookshelf, Kavita, Linkding, Uptime Kuma, Immich, and Joplin.

Why Traefik isn’t offered as a direct TrueNAS App… I have no idea.

2 Likes

I suspect the fact that there’s no GUI to configure it is a big factor. And adding labels to an app (which is IMO the best way to use Traefik in this application) is outright painful.

1 Like

I use Caddy as I’ve always used it and finds it does everything pretty good and simple. I host a web server with it., and it provides the front end SSL (reverse proxcy) for my SSL apps. I use Caddy with labels, and works with my DNS provider (porkbun)

Just for the record, swag also supports exposing services via labels (there is a mod for this). But it’s only for docker services, ofc. And I personally don’t use it, because usually I have 2 RPs on the exposed node – internal and external. And I wasn’t persistent enough to find out whether it is possible to configure exposure for 2 different instances.


Regarding the DDNS, there is a ddns-updater which supports many popular DNS hosters. Again, it’s not truenas but a docker-specific one.

And you also can forward the port on your router directly from docker/docker-compose via UPnP (needs UPnP to be enabled on the router; usually enabled by default on consumer models). Most IT-savvy people unfairly hate UPnP, though.

NPM + DDNS Updater :ok_hand:

DDNS Updater has no GUI, and is still offered. Quite frankly, anyone who is running a TrueNAS configuration and who is somewhat active in this forum has some technical know-how.

1 Like

Thank you for your insightful responses so far. HestiaCP and Swag hadn’t come up in my search before, so I gave them a look. Dan had some good insight into Traefik and it likely isn’t necessary for my use case as there won’t be much adding or removing of apps if at all after initial setup. It does seem quite versatile for testing new apps and has some nice to haves on top.

After consulting with “web expert” ChatGPT about if NGINX could gain similar functionality, it recommended some plugins to provide comparable functionality as fail2ban and the built-in geoblocking.

Specifically, it recommended:

  • NGINX + GeoIP2 support
  • MaxMind’s GeoLite2 Country DB (requires account)
  • CrowdSec for automatic banning

It even spat out some sample config files:

DockerFile if I decide not to use the community app

File: Dockerfile

FROM nginx:stable

Install dependencies

RUN apt-get update &&
apt-get install -y libmaxminddb0 libmaxminddb-dev mmdb-bin geoipupdate
nginx-module-geoip2 certbot python3-certbot-nginx &&
rm -rf /var/lib/apt/lists/*

Copy custom config files later (bind-mount or COPY in docker-compose)

Enable GeoIP2 module

RUN echo “load_module modules/ngx_http_geoip2_module.so;” >> /etc/nginx/nginx.conf

Set up GeoIP2 data directory

RUN mkdir -p /etc/nginx/geoip

Expose ports

EXPOSE 80 443

Config File

File: /etc/nginx/conf.d/nextcloud.conf

geoip2 /etc/nginx/geoip/GeoLite2-Country.mmdb {
$geoip2_data_country_code country iso_code;
}

map $geoip2_data_country_code $allowed_country {
default no;
US yes;
CA yes;
}

server {
listen 443 ssl;
server_name yourdomain.com;

ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

if ($allowed_country = no) {
    return 403;
}

location / {
    proxy_pass http://nextcloud:80;
    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;
}

}

YAML file for adding CrowdSec

version: “3”
services:
nginx:
build: .
container_name: nginx-geoip
ports:
- “80:80”
- “443:443”
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./geoip:/etc/nginx/geoip
- /etc/letsencrypt:/etc/letsencrypt:ro
- /var/log/nginx:/var/log/nginx

crowdsec:
image: crowdsecurity/crowdsec
container_name: crowdsec
volumes:
- ./crowdsec-data:/var/lib/crowdsec/data
- /var/log/nginx:/var/log/nginx:ro
ports:
- “8080:8080”

Obviously I’m not going to take it at its word without consulting a human. Have you worked with said plugins/sidecars before and, if so, how do they compare to fail2ban and the built-in geoblock found in the alternative? Also, is setting up certbot the best way of managing Let’s Encrypt certificate renewal for NGINX or is there something better out there as some alternatives have renewal built in.
DDNS-Updater seems rather handy. I had been looking at DuckDNS and will likely update the plan since you’ve pointed it out.

While somewhat off topic, regarding DNS hosts, given the supposed cloudflare large video backup issue- which may very well be a non-issue and just too much caution about ToS, which have you experienced success with besides cloudflare?

Thank you again for sharing your personal experiences with the options.
Experience may be a great teacher, but learning from others experiences allows for avoiding potentially major mistakes like the reddit thread I read about someone with a default configuration NAS (Synology, not TrueNAS) that got hit with a ransomware attack. No, it’s best to understand what’s going on behind the hood and make sure things are set right to minimize any risk.

Keep in mind, at most, this would be relevant only if you were using Cloudflare as a proxy. So if you’re using Cloudflare Tunnels? Yeah, it’d matter.[1] If you’re using their CDN service? It could matter. If you’re just using them for DNS? No data other than DNS transits their network, so nothing for them to track, much less enforce.


  1. to the extent it’s a factor at all ↩︎

2 Likes

Traefik + Docker-Socket-Proxy + Crowdsec to start, and then any Traefik plugins as necessary (GeoIP, etc)

People who are lazy can use Nginx-Proxy-Manager/NPM Plus with a fail2ban or SWAG

Didn’t work with them. But wanna add some points:

  1. As I’ve said, swag has built-in fail2ban, which works ok out of the box.
  2. It also has built-in LE cert issuing/renewing.
  3. It has some mod/plugin for geoblocking. I didn’t use it, though. Just saying that it exists.
  4. Linuxserver has a separate image for duckdns ip updates. IMO, you should go for ddns-update, though. It would be easier to upgrade to a full-fledged domain when the time comes.
  5. In case you decide to pull the trigger with nginx (other options sound very solid as well), I strongly recommend you go swag-way. Especially if you never dealt with nginx before. The linuxserver team did a great job writing services/nginx configs for homelabbers and “glueing” them together. Moreover, they are maintaining these configs, and doing it yourself would be a PITA.

Bonus:

My old parameterized compose file for the duckdns RP

Should work after specifying variables A_RECORD (as your duckdns record), DUCKDNS_TOKEN and REVERSE_PROXY_PORT. NB! Swag needs some initial post-installation steps. They described in the docs.

networks:
  default:
    name: ${A_RECORD}.duckdns.org
    driver: bridge
  sso: # authentik network. The other services networks also should be there.
    external: true

volumes:
  swag:
    driver: local

services:

  ## There was UPnP IGD service. Usually, people don't trust it. So I removed it.

  duckdns:
    # https://github.com/linuxserver/docker-duckdns#versions
    image: lscr.io/linuxserver/duckdns:latest
    restart: always
    
    environment:
      - PUID=1000 #optional
      - PGID=1000 #optional
      ##- TZ=Europe/London
      - SUBDOMAINS=$A_RECORD
      - TOKEN=$DUCKDNS_TOKEN
      - LOG_FILE=false #optional
    volumes:
      - "/etc/localtime:/etc/localtime:ro"
    healthcheck:
      test: [ "CMD-SHELL", "nslookup -type=A $${SUBDOMAINS}.duckdns.org || exit 1" ]
      start_period: 30s
      interval: 10s
      timeout: 10s
      retries: 3

  swag:
    # https://github.com/linuxserver/docker-swag/tree/master#versions
    # https://hub.docker.com/r/linuxserver/swag/tags
    image: linuxserver/swag:latest
    restart: always
    networks:
      - default
      - sso
    cap_add:
      - NET_ADMIN
    environment:
      - PUID=1000
      - PGID=1000
      #- TZ=Europe/London
      - TOKEN=$DUCKDNS_TOKEN
      - URL=${A_RECORD}.duckdns.org
      - VALIDATION=dns
      - SUBDOMAINS=wildcard #optional
      - CERTPROVIDER= #optional
      - DNSPLUGIN=duckdns #optional
      - PROPAGATION= #optional
      #- EMAIL= #optional
      #- ONLY_SUBDOMAINS=true #optional
      - EXTRA_DOMAINS= #optional
      - STAGING=false #optional
    volumes:
      - swag:/config
      - "/etc/localtime:/etc/localtime:ro"
      - "/etc/timezone:/etc/timezone:ro"
    ports:
      - ${REVERSE_PROXY_PORT:-443}:443
      #- 80:80 #optional
    # there were some tweaks for entrypoint, but they are highly discouraged
    healthcheck:
      test: [ "CMD-SHELL", "nc -z localhost 443 || exit 1" ]
      start_period: 60s
      interval: 5s
      timeout: 10s
      retries: 3
1 Like

Hi,

Just thought I’d share my own experience in this area. I ended up using Cloudflare’s Zero Trust service, and for me, it significantly simplified the configuration process while also providing a level of security I was more comfortable with compared to other approaches I’d considered for remote access.

It might be worth looking into if ease of setup and robust security are high on your list.

Cheers!

does anyone know why only Nginx Proxy Manager is available in the Apps Catalog ?

I assume you mean it’s the only reverse proxy available there (because there are lots of other apps)–and the reason is that nobody has bothered to package any of the others. The likely reason for that IMO is that something like Traefik is going to take enough configuration with its own config files, Docker labels, and the like that it just isn’t a good fit for the point-and-click installation method of the Apps catalog.

2 Likes