How to Install FileBrowser on Ubuntu 24.04 — A Lightweight Web File Manager
FileBrowser is one of those tools that does one thing and does it well: it turns any directory on your Ubuntu server into a polished web interface for browsing, uploading, and sharing files. No sync client, no enterprise dashboard, no plugin marketplace — just a single 30 MB Go binary that you can drop in front of /srv/files and hand the URL to a client. This guide walks you through installing FileBrowser on Ubuntu 24.04, configuring it as a systemd service, putting it behind Nginx with Let's Encrypt, and hardening the default admin account before anyone else can log in.
Skip the setup? Deploy FileBrowser in one click with our pre-configured image. Launch a CloudCore Starter VPS now and have a shareable file URL live in under a minute.
Table of Contents
What is FileBrowser?
FileBrowser is an open-source, Apache 2.0 licensed web-based file manager that exposes a directory on your server through a clean browser UI. The entire application ships as a single self-contained Go binary (around 30 MB) with an embedded SQLite database and bundled assets — no runtime, no external services, no config database to manage. The upstream project at github.com/filebrowser/filebrowser has collected over 26,000 GitHub stars and is widely used to replace ageing SFTP GUIs for casual file sharing between teammates, clients, and contractors.
Out of the box, FileBrowser handles the things you actually need from a file manager. Multi-user accounts with scoped home directories let each user see only their own slice of the filesystem. Share links generate public URLs for any file or folder, optionally protected by a password and an expiry timestamp. Previews render images, videos, text files, PDFs, and Markdown directly in the browser, and a built-in code editor with syntax highlighting lets you make quick edits to small configuration files without SSHing in. Resumable uploads over the tus protocol survive flaky connections when you are pushing a 4 GB video across a hotel Wi-Fi. There is also a command runner that can execute predefined shell commands (for example, git pull in the current directory) — powerful but something you will want to disable unless you trust every user on the system.
Typical use cases include giving a client a login to drop design assets into a project folder, running a quick "upload your logs here" endpoint for support, acting as a landing pad for CI build artifacts, or simply replacing WinSCP for team members who cannot be bothered to install an SFTP client. It is not a Nextcloud or a Seafile — there is no desktop sync, no calendaring, no contacts — but for 90% of the "I just need a file URL" requests, FileBrowser is the right level of tool.
Why Self-Host FileBrowser?
If all you need is a place to drop a 200 MB ZIP for a client, Google Drive or WeTransfer will get the job done. Self-hosting FileBrowser makes sense in a narrower but common set of scenarios:
- Files stay where they live on disk -- Your build artifacts, backups, and media are already on the server. FileBrowser exposes them in place, without copying anything into a third-party bucket. Delete a file in the UI and it is gone from the filesystem — no sync lag, no tombstone entries.
- Predictable flat cost -- A CloudCore Starter VPS serves unlimited uploads and downloads for a fixed monthly fee. No per-GB egress, no 10 GB storage caps, no "upgrade to Pro" prompts when a client tries to download a 3 GB video.
- White-label friendly -- Change the brand name, logo, and theme in a single admin setting. No Google, Microsoft, or Dropbox logo anywhere in the user experience.
- Quick drop zone for clients -- Create a user scoped to
/srv/files/acme-corp/, send them the login, and you have an isolated share that looks and feels professional. Revoke access the moment the project ends. - No vendor data mining -- What a client uploads stays on your disk. No ML pipeline is reading their draft contracts for training data.
- Runs on a potato -- The binary uses about 20-40 MB of RAM idle. It will happily coexist with a dozen other services on a 4 GB VPS.
When FileBrowser is the right tool
| Scenario | FileBrowser | Nextcloud | SFTP only |
|---|---|---|---|
| Share one file with a 24h expiring link | Ideal | Overkill | No public links |
| Let 5 clients upload deliverables | Ideal | Works, heavy | Painful UX |
| Sync a laptop with a server folder | No | Ideal | rsync manually |
| Calendar, contacts, collaborative docs | No | Ideal | No |
| Preview PDFs and images in browser | Yes | Yes | No |
| RAM footprint | ~30 MB | ~500 MB+ | ~5 MB |
| Install time on a fresh VPS | ~5 minutes | ~30 minutes | Built-in |
Prerequisites
Before you begin, make sure you have:
- A VPS running Ubuntu 24.04 LTS with root or sudo access
- SSH access to the server
- 128 MB of free RAM — yes, really, the binary is tiny
- A domain name pointed at your server's public IP (required for the Nginx + SSL step)
- Ports 80 and 443 open in your cloud firewall (ports 22 for SSH is assumed)
Recommended Plan: CloudCore Starter>
FileBrowser runs comfortably on the smallest plan we offer. For serving moderate upload traffic and keeping a handful of user shares online, the CloudCore Starter plan is a perfect fit:>
- 2 vCPU cores
- 4 GB RAM
- 50 GB NVMe SSD
- Unmetered bandwidth>
If you plan to host large media libraries, pick a plan with more SSD. FileBrowser itself will not be the bottleneck.
Connect to your server via SSH to begin:
ssh root@your-server-ipStep 1: Update System Packages
Start with an up-to-date system so dependency resolution works cleanly and you are not missing any security patches.
sudo apt update && sudo apt upgrade -yExpected output (abbreviated):
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Reading package lists... Done
Building dependency tree... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.Install a couple of utilities we will use later:
sudo apt install -y curl ca-certificatesIf the kernel was upgraded, reboot and reconnect:
sudo rebootStep 2: Install the FileBrowser Binary
The upstream project maintains an install script that fetches the correct binary for your architecture (amd64 or arm64) and drops it at /usr/local/bin/filebrowser.
curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bashExpected output:
Getting the latest filebrowser...
Downloading filebrowser_linux-amd64.tar.gz...
filebrowser_linux-amd64.tar.gz [================>] 100%
Extracting...
Putting filebrowser in /usr/local/bin (may require password)...
Successfully installedVerify the install:
filebrowser versionExpected output:
v2.31.2(The exact version moves forward over time — any reasonably recent v2.x release works for this guide.)
If you prefer not to pipe the internet into bash, grab the latest release tarball directly from github.com/filebrowser/filebrowser/releases, extract the binary, and move it to /usr/local/bin/filebrowser.
Step 3: Create a System User and Directories
Running FileBrowser as root is a bad idea — if the binary has a bug or a share link misbehaves, you do not want the blast radius to include the entire filesystem. Create a dedicated system user and two directories: one for the SQLite database and config, and one that will be the root of what users can see.
sudo useradd --system --shell /usr/sbin/nologin --home /srv/filebrowser filebrowser
sudo mkdir -p /srv/filebrowser
sudo mkdir -p /srv/files
sudo chown -R filebrowser:filebrowser /srv/filebrowser /srv/filesThe layout:
/srv/filebrowser/-- Holds the SQLite databasefilebrowser.db. Users never see this directory./srv/files/-- The root that FileBrowser exposes. Every user gets scoped somewhere under here.
/var/www/shared or an NFS mount at /mnt/storage), use that path everywhere we write /srv/files below. Just make sure the filebrowser system user has read (and write, if users should be able to upload) access.Step 4: Initialize the Database and Defaults
FileBrowser stores all its state in a single SQLite file. Initialize it and bake in the defaults you want every new user to inherit.
sudo -u filebrowser filebrowser -d /srv/filebrowser/filebrowser.db config initExpected output:
Successfully initialized database at /srv/filebrowser/filebrowser.dbNow set the listening address, root directory, and auth method:
sudo -u filebrowser filebrowser -d /srv/filebrowser/filebrowser.db config set \
--address 127.0.0.1 \
--port 8080 \
--root /srv/files \
--auth.method=jsonExplanation of each flag:
--address 127.0.0.1-- Bind only to localhost. External traffic will reach FileBrowser through Nginx, which we set up in Step 7. Never expose port 8080 directly to the internet.--port 8080-- Standard Go-app HTTP port. Pick another if 8080 is already in use.--root /srv/files-- The top of the tree that users can ever see. No user can escape above this path.--auth.method=json-- Use FileBrowser's built-in username/password auth. Other methods (proxy,noauth,hook) are used when fronting with Authelia or similar — see Step 9.
Step 5: Create the Admin User
FileBrowser ships with a default admin/admin account on first boot. Do not leave it at the default — plenty of botnets specifically scan for open :8080 and try exactly that combination. Replace it now:
sudo -u filebrowser filebrowser -d /srv/filebrowser/filebrowser.db \
users add admin 'your-strong-password-here' --perm.adminExpected output:
User 'admin' added with ID 1If FileBrowser already seeded a default admin during init, delete it and recreate:
sudo -u filebrowser filebrowser -d /srv/filebrowser/filebrowser.db users rm admin
sudo -u filebrowser filebrowser -d /srv/filebrowser/filebrowser.db \
users add admin 'your-strong-password-here' --perm.adminPick a password you would be comfortable posting to a public bucket — because that is effectively the exposure model once you open port 443.
Step 6: Run as a systemd Service
You could launch FileBrowser in a tmux session, but the right answer is a systemd unit that starts on boot, restarts on crash, and logs to journalctl.
Create the unit file:
sudo tee /etc/systemd/system/filebrowser.service > /dev/null <<'EOF' [Unit] Description=FileBrowser — Web-based file manager After=network-online.target Wants=network-online.target[Service] Type=simple User=filebrowser Group=filebrowser ExecStart=/usr/local/bin/filebrowser -d /srv/filebrowser/filebrowser.db Restart=on-failure RestartSec=5
Hardening
NoNewPrivileges=true ProtectSystem=strict ProtectHome=true PrivateTmp=true ReadWritePaths=/srv/filebrowser /srv/files
[Install] WantedBy=multi-user.target EOF
Reload systemd, enable, and start:
sudo systemctl daemon-reload
sudo systemctl enable --now filebrowserVerify it is running:
sudo systemctl status filebrowserExpected output:
● filebrowser.service - FileBrowser — Web-based file manager
Loaded: loaded (/etc/systemd/system/filebrowser.service; enabled; preset: enabled)
Active: active (running) since Wed 2026-04-16 10:00:00 UTC; 3s ago
Main PID: 12345 (filebrowser)
Tasks: 7 (limit: 4915)
Memory: 24.3M
CPU: 120ms
CGroup: /system.slice/filebrowser.service
└─12345 /usr/local/bin/filebrowser -d /srv/filebrowser/filebrowser.dbTest the local endpoint:
curl -I http://127.0.0.1:8080Expected output:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8FileBrowser is now running, but only reachable from the server itself. Time to put it on the public internet — safely.
Step 7: Nginx Reverse Proxy + SSL
Serve FileBrowser over HTTPS via Nginx. If you have not installed Nginx yet, the full walkthrough is in our How to Install Nginx on Ubuntu guide. Quick version:
sudo apt install -y nginx certbot python3-certbot-nginxCreate the site configuration:
sudo tee /etc/nginx/sites-available/filebrowser > /dev/null <<'EOF' server { listen 80; server_name files.yourdomain.com; return 301 https://$host$request_uri; }server { listen 443 ssl http2; server_name files.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/files.yourdomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/files.yourdomain.com/privkey.pem;
# Security headers add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Allow large uploads — adjust to the biggest file you expect client_max_body_size 10g;
# Long timeouts for big uploads / slow clients proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 60s;
location / { proxy_pass http://127.0.0.1:8080; 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;
# WebSocket support — strictly optional, but needed if you enable # the live-reload features for the code editor proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
# Don't buffer streams so tus resumable uploads work cleanly proxy_request_buffering off; proxy_buffering off; } } EOF
Enable the site, obtain a certificate, and reload:
sudo ln -s /etc/nginx/sites-available/filebrowser /etc/nginx/sites-enabled/
sudo certbot --nginx -d files.yourdomain.com
sudo nginx -t && sudo systemctl reload nginxLock down UFW so only SSH and HTTPS are reachable:
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw deny 8080
sudo ufw enableBrowse to https://files.yourdomain.com, log in with the admin credentials you created in Step 5, and you should land in the FileBrowser UI showing /srv/files.
Step 8: Branding, Users, and Shares
Click the gear icon (top-right) → Settings to hit the admin area. The essentials:
Global settings
- Branding -- Set the instance name (replaces "File Browser" in the header), upload a logo, and pick a custom theme (light, dark, or a per-user preference).
- User defaults -- Defines what permissions new users inherit. For a client-drop-zone deployment, a sensible baseline is:
create,rename,modify,delete,download,share— but notexecute(which gates the command runner) and notadmin. - Rules -- Deny patterns for hidden files. Blocking
.git/,.env, andnode_modules/is a good default.
Adding users
Settings → Users → New User:
- Username and password — per user.
- Scope — the user's home directory relative to the global root. Setting scope to
/acme-corpmeans that user can only see/srv/files/acme-corp/and below, no matter how hard they try to path-traverse. - Permissions — per-user overrides. Turn off
deletefor read-only shares. - Lock password — useful when you want a service account whose password you seeded programmatically.
Share links
Inside the UI, right-click any file or folder → Share. You get a public URL like https://files.yourdomain.com/share/AbCdEfGh. Options:
- Password — anyone with the URL still needs the password to view.
- Expiration — the link auto-revokes after hours, days, weeks, or a custom timestamp.
- Multiple links per item — each with its own password/expiry — so you can hand a 24h link to one partner and a 7-day link to another without re-uploading anything.
The command runner — turn it off
The execute permission lets users run a predefined list of shell commands (for example, git pull) inside the current directory. It is genuinely useful if you are the only admin on a trusted server, but it is a remote-code-execution vector the moment you add a user you do not fully trust. Unless you explicitly need it, leave "Execute commands" disabled in both user defaults and every individual user profile. If you do enable it, lock the allowed command list at Settings → Global Settings → Commands to a short whitelist.
Preview and editor
No configuration required — previews and the code editor Just Work. FileBrowser renders images, videos (via the browser's built-in <video> element, so codec support follows the browser), PDFs, text files, and Markdown. The editor handles syntax highlighting for hundreds of languages and is fine for tweaking a .env file or a short script — do not use it to refactor a Rails app.
Uploads
Uploads flow through the tus protocol, which means they survive dropped connections: the client resumes where it left off rather than restarting from zero. This matters enormously for the "upload a 4 GB database dump over tethered mobile" scenario. Nothing to configure — it is on by default.
Step 9: 2FA and Extra Hardening
FileBrowser does not ship with built-in two-factor authentication. If you need 2FA — and for any production deployment with real clients, you should — the idiomatic approach is to put an auth proxy in front.
Option A: Authelia or Authentik as auth proxy
Run Authelia or Authentik in front of Nginx, configure FileBrowser with --auth.method=proxy, and let the proxy handle login, TOTP, and WebAuthn. The proxy forwards an authenticated username header to FileBrowser, which trusts it. Setup is out of scope here, but the flow is:
location / block to Nginx that first calls the auth proxy via auth_request.X-Remote-User set.filebrowser -d /srv/filebrowser/filebrowser.db config set --auth.method=proxy --auth.header=X-Remote-User.Option B: Only reachable over SSH tunnel
If FileBrowser is just for you, skip 2FA and never expose the Nginx site publicly. Leave FileBrowser bound to 127.0.0.1:8080 and access it over an SSH tunnel:
ssh -L 8080:127.0.0.1:8080 user@your-server-ipBrowse to http://localhost:8080 on your laptop. Zero public attack surface.
Other hardening
- Fail2ban — rate-limit login attempts at the Nginx layer. Our Fail2ban guide covers the jail configuration.
- IP allowlist — if only one office should ever see FileBrowser, add
allow 203.0.113.0/24; deny all;inside the Nginxlocation /block. - CrowdSec — community-driven IP blocklist that pairs well with Nginx. See the CrowdSec install guide.
Docker Compose Alternative
If you already run your stack in Docker, the official filebrowser/filebrowser image is a one-file deploy. Create docker-compose.yml:
services:
filebrowser:
image: filebrowser/filebrowser:latest
container_name: filebrowser
restart: unless-stopped
user: "1000:1000"
ports:
- "127.0.0.1:8080:80"
volumes:
- ./data:/database
- ./config:/config
- /srv/files:/srv
environment:
- FB_DATABASE=/database/filebrowser.db
- FB_ROOT=/srvBring it up:
docker compose up -dInitial admin login is still admin/admin; change it immediately from the UI or with docker compose exec filebrowser filebrowser users update admin --password 'new-password'.
Point the same Nginx config from Step 7 at http://127.0.0.1:8080 and you are done. The main trade-off vs. the bare-metal install: Docker adds ~50 MB of base image and a container runtime to manage, but you get identical behaviour across Ubuntu, Debian, Fedora, and macOS dev machines.
Backup and Updates
Backup
The entire FileBrowser state lives in one SQLite file: /srv/filebrowser/filebrowser.db. Back it up with everything else in /srv/:
sudo cp /srv/filebrowser/filebrowser.db /backup/filebrowser-$(date +%F).dbFor a consistent snapshot while FileBrowser is running, use SQLite's online backup:
sudo -u filebrowser sqlite3 /srv/filebrowser/filebrowser.db ".backup '/backup/filebrowser-$(date +%F).db'"Run it nightly from cron. File contents under /srv/files/ are just regular files — back them up with rsync, restic, or whichever tool you already use.
Updating
New FileBrowser release? Re-run the install script and restart:
curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
sudo systemctl restart filebrowserThe binary at /usr/local/bin/filebrowser is overwritten; the database and files are untouched. Check the release notes at github.com/filebrowser/filebrowser/releases before major version jumps — v3 will likely require a DB migration.
Troubleshooting
| Problem | Cause | Solution |
|---|---|---|
Default admin/admin still works | You skipped Step 5 | Run sudo -u filebrowser filebrowser -d /srv/filebrowser/filebrowser.db users update admin --password 'new-password' now |
413 Request Entity Too Large on upload | Nginx client_max_body_size too small | Raise it in the server block: client_max_body_size 10g; then sudo systemctl reload nginx |
permission denied when uploading | filebrowser system user does not own /srv/files | sudo chown -R filebrowser:filebrowser /srv/files |
Share links show http:// even though the site is HTTPS | Missing X-Forwarded-Proto header | Add proxy_set_header X-Forwarded-Proto $scheme; to the Nginx location / block (already in the Step 7 config) |
Can't reach :8080 after install | FileBrowser bound to 127.0.0.1 (correct) and no reverse proxy | Either finish Step 7, or SSH-tunnel with ssh -L 8080:127.0.0.1:8080 user@server |
| Login loop — redirected back to sign-in | Database locked or wrong auth method | Check sudo journalctl -u filebrowser -n 50. If the auth method got switched, reset it: config set --auth.method=json |
| Preview fails for large videos | Browser codec mismatch | FileBrowser hands the raw file to the browser's <video> element; transcode to H.264/AAC for universal playback |
| Upload stalls at 99% behind Cloudflare | Cloudflare 100 MB body limit on free plan | Bypass Cloudflare proxy for the upload subdomain (grey-cloud), or upgrade to a paid plan |
Viewing logs
sudo journalctl -u filebrowser -fPress Ctrl+C to stop the stream. For the last 50 lines:
sudo journalctl -u filebrowser -n 50 --no-pagerFAQ
How does FileBrowser compare to Nextcloud?
Nextcloud is a full collaboration suite — file sync, calendar, contacts, office document editing, end-to-end encryption, a plugin marketplace. It is the right tool when you are replacing Google Workspace. FileBrowser is a web file manager and nothing else: no sync client, no calendars, no office docs. It installs in 5 minutes and uses 30 MB of RAM vs. Nextcloud's 500 MB+. If you need "share a folder with 5 people" pick FileBrowser. If you need "replace Google Drive for a 50-person company", pick Nextcloud. Many teams run both: Nextcloud for employees, FileBrowser for ad-hoc client shares.
How does FileBrowser compare to Nginx autoindex?
Nginx's built-in autoindex on; gives you a read-only directory listing — no upload, no auth, no previews, no share links, no user accounts. It is a useful 30-second hack for "here is a folder of ISO images, help yourself". The moment you need any of: uploads, per-user access, password-protected shares, link expiry, or a preview nicer than raw text, you want FileBrowser.
How does FileBrowser compare to the file manager in cPanel, CyberPanel, or Webmin?
Those are control-panel features bundled into larger server-admin suites. If you are already running cPanel, use its file manager — no need for FileBrowser. If you are not, installing a full control panel just to get a file UI is massive overkill: cPanel costs real money per month, CyberPanel and Webmin each ship hundreds of megabytes of features you will never use. FileBrowser is 30 MB, has a better uploader (tus resumable), and does not try to manage your DNS or your MySQL users as a side effect.
Is it safe to expose FileBrowser to the public internet?
Yes, with caveats. The application itself has a clean security record, but any auth endpoint exposed to the internet will be attacked. Minimum hardening: (1) change the default admin/admin immediately, (2) use a strong admin password (24+ characters), (3) front it with Nginx + Let's Encrypt so credentials do not cross the wire in plaintext, (4) add Fail2ban or CrowdSec to rate-limit brute-force attempts, (5) for anything sensitive, add 2FA via Authelia/Authentik in front. If you skip step 1, assume compromise within days of going live — botnets scan for the default credentials continuously.
Can I enforce per-user storage quotas?
Not natively — FileBrowser does not track per-user disk usage. If you need hard quotas, enforce them at the filesystem layer with Linux disk quotas (quota, setquota) against each user's scoped directory, or use ZFS/Btrfs subvolume quotas. For most small-team use cases, informally agreeing on a "keep it under 10 GB" limit and monitoring with du -sh /srv/files/* is sufficient.
Can I use an external auth source like LDAP or OAuth?
Not directly — FileBrowser supports json (built-in), proxy (trust a header), noauth, and hook (call an external script) auth methods. For LDAP, OAuth, OIDC, or SAML, use proxy mode behind Authelia or Authentik and let the auth proxy speak those protocols. This is the same pattern you would use for 2FA.
Does FileBrowser support WebDAV?
No. If you need WebDAV (for mounting the share as a drive in Finder, Windows Explorer, or on iOS), pair FileBrowser with a separate WebDAV server (Apache mod_dav, or Nextcloud for a richer experience), or use SFTP which Ubuntu enables by default via OpenSSH.
Next Steps
Now that FileBrowser is serving files over HTTPS, these are the usual follow-ups:
- Add monitoring -- Drop a Uptime Kuma HTTP monitor against
https://files.yourdomain.com/healthto get an email/Telegram ping the moment the service goes down. - Automate backups -- Nightly
resticorborgbackup of/srv/filebrowser/filebrowser.dband/srv/files/to off-site storage (S3, Backblaze B2, or another VPS). - Add rate limiting -- Install Fail2ban using the Fail2ban install guide and write a jail that tails Nginx access logs for repeated 401s on
/api/login. - Put it behind Authelia -- If the share is going to handle anything sensitive, add 2FA before you hand out URLs.
- Combine with Nextcloud -- Use Nextcloud for your team's day-to-day files and FileBrowser as a lightweight public drop-zone for clients. They happily coexist on the same VPS.
- White-label the UI -- Upload a logo, set the brand name, pick a theme, and nobody ever needs to know what FileBrowser is.
Skip the Manual Install -- Get FileBrowser Pre-Configured>
Our CloudCore Starter plan can ship with FileBrowser, Nginx, Let's Encrypt, and Fail2ban already configured. Deploy in under a minute and start handing out share links immediately.>
- FileBrowser v2 latest pre-installed as a systemd service
- Nginx reverse proxy with auto-renewing Let's Encrypt SSL
- Custom admin credentials generated on first boot (noadmin/admindisaster)
- UFW firewall locked to ports 22, 80, 443
- Optional Authelia 2FA bundle on larger plans>
Deploy Your FileBrowser VPS Now — CloudCore Starter plans from just a few euros per month.