Self-Hosting Filebrowser with Nginx Proxy Manager, Docker, and Cloudflare

Welcome to a complete walkthrough of how I set up a secure, user-friendly self-hosted Filebrowser instance using Docker, Portainer, Nginx Proxy Manager (NPM), and Cloudflare DNS. This guide includes pitfalls, permissions issues, volume struggles, and what I learned along the way.

We wanted two separate users with access to their own folders β€” one for private storage and another for sharing files with friends. Everything had to be controllable via Portainer Web GUI, with minimal CLI interaction where possible (except DietPi).

πŸ”§ Objectives

  • Run Filebrowser with separate folders for two users: user1 and user2
  • Secure the setup with HTTPS via Cloudflare and Nginx Proxy Manager
  • Access via CNAME: ftp.muminkis.com
  • Use DietPi for CLI work and Portainer for web GUI container management

βœ… Initial DietPi Prep

I used DietPi as my lightweight OS and did most system-level tasks via SSH:

sudo mkdir -p /srv/user1 /srv/user2
sudo chown -R 1002:1002 /srv
sudo chmod -R 775 /srv

This ensured each user folder was owned by the right UID/GID (1002 in my case). I skipped creating Linux users since Filebrowser manages its own access.

πŸ“ Docker Volume Setup β€” The Real Struggle

This was by far the most frustrating part.

❌ What Went Wrong

  • Mixing up bind mounts and Docker-managed volumes in Portainer
  • Accidentally mounting /filebrowser.db directly instead of using /database
  • Getting permission denied and is a directory errors when creating users
  • Leaving behind orphaned anonymous volumes

βœ… The Fix

I wiped it clean and used the CLI:

docker volume rm $(docker volume ls -qf dangling=true)

Then ran the container:

docker run -d \
  --name filebrowser \
  -v /srv:/srv \
  -v filebrowser_data:/database \
  -p 8088:80 \
  filebrowser/filebrowser:latest

This way, Filebrowser stores its DB in /database/filebrowser.db β€” persistent and accessible.

πŸ‘€ Adding Filebrowser Users (from a temporary container)

docker run --rm -it \
  --entrypoint sh \
  -v /srv:/srv \
  -v filebrowser_data:/database \
  filebrowser/filebrowser:latest

Then:

filebrowser -d /database/filebrowser.db config init
filebrowser -d /database/filebrowser.db users add user1  --scope /srv/user1
filebrowser -d /database/filebrowser.db users add user2  --scope /srv/user2
filebrowser -d /database/filebrowser.db users update user1 --perm.admin

🌐 Domain & Reverse Proxy Setup (NPM + Cloudflare)

  1. Cloudflare CNAME: Pointed ftp.muminkis.com to my public IP
  2. Nginx Proxy Manager:
    - Scheme: http
    - Forward Hostname/IP: dietpi
    - Forward Port: 8088
    - Cache Assets: ❌ Off
    - Websockets Support: βœ… On
    - Block Common Exploits: βœ… On

SSL tab:

  • Force SSL: βœ… On
  • HTTP/2 Support: βœ… On
  • HSTS Enabled: βœ… On
  • HSTS Subdomains: βœ… On (since all subdomains are also covered)

πŸ”’ Security Extras

  • Didn't use an Access List for Vaultwarden since my IP changes
  • Did not enable SSL passthrough since the containers don’t have intern

βœ… Final Thoughts

While setting up Filebrowser should be simple, doing it properly with volumes, secure access, user scoping, and proper cleanup was not trivial. But now:

  • I can securely access two isolated folders via HTTPS
  • I manage it easily via Portainer
  • Everything is reproducible

Tip: Always test things manually in DietPi CLI when the web UI doesn’t work as expected.

Next steps:

  • Add backups for /database volume
  • Consider auto-renewal and alerts for SSL certs
  • Monitor logs via Portainer or DietPi journal

Happy hosting! πŸŽ‰