File Manager
    Open Source

    Deploy Filebrowser on a VPS

    A polished, single-binary web UI for uploading, sharing, previewing, and editing files — production-ready with hardened systemd, Nginx, Let's Encrypt, and fail2ban.

    At a Glance

    ProjectFilebrowser
    LicenseApache 2.0
    Recommended PlanRamNode Cloud VPS 1 GB+ (2 GB+ for many concurrent uploads)
    OSUbuntu 24.04 LTS / Debian 12
    Footprint~14 MB binary, 30–80 MB RAM idle
    Estimated Setup Time~20 minutes

    Prerequisites

    • A RamNode VPS with at least 1 GB RAM and 10 GB disk
    • Ubuntu 24.04 LTS or Debian 12 with root/sudo
    • A domain or subdomain (e.g. files.yourdomain.com) with an A record
    1

    Prepare the Server

    Create a service user and install packages
    adduser --system --group --home /var/lib/filebrowser \
      --shell /usr/sbin/nologin filebrowser
    
    apt update && apt upgrade -y
    apt install -y curl ufw nginx certbot python3-certbot-nginx fail2ban
    Configure UFW (verify SSH rule before enabling)
    ufw default deny incoming
    ufw default allow outgoing
    ufw allow OpenSSH
    ufw allow 'Nginx Full'
    ufw enable
    2

    Install the Filebrowser Binary

    Read then run the official installer
    curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh -o /tmp/fb-install.sh
    less /tmp/fb-install.sh
    bash /tmp/fb-install.sh
    
    filebrowser version   # expect v2.63.2 or newer
    3

    Create the Data Layout

    Create directories
    mkdir -p /srv/filebrowser
    mkdir -p /var/log/filebrowser
    chown -R filebrowser:filebrowser /var/lib/filebrowser /srv/filebrowser /var/log/filebrowser
    chmod 750 /var/lib/filebrowser /srv/filebrowser
    Initialize the database (as the filebrowser user)
    sudo -u filebrowser filebrowser config init \
      --database /var/lib/filebrowser/filebrowser.db \
      --address 127.0.0.1 \
      --port 8080 \
      --root /srv/filebrowser \
      --log /var/log/filebrowser/filebrowser.log \
      --auth.method json \
      --branding.name "RamNode Files" \
      --minimumPasswordLength 14
    Create the admin user
    sudo -u filebrowser filebrowser users add admin 'YourStrongPasswordHere' \
      --database /var/lib/filebrowser/filebrowser.db \
      --perm.admin
    4

    Create the systemd Service

    /etc/systemd/system/filebrowser.service
    [Unit]
    Description=Filebrowser Web File Manager
    Documentation=https://filebrowser.org
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=simple
    User=filebrowser
    Group=filebrowser
    ExecStart=/usr/local/bin/filebrowser \
      --database /var/lib/filebrowser/filebrowser.db \
      --log /var/log/filebrowser/filebrowser.log
    Restart=on-failure
    RestartSec=5
    
    # Hardening
    NoNewPrivileges=true
    PrivateTmp=true
    ProtectSystem=strict
    ProtectHome=true
    ReadWritePaths=/var/lib/filebrowser /srv/filebrowser /var/log/filebrowser
    ProtectKernelTunables=true
    ProtectKernelModules=true
    ProtectControlGroups=true
    RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
    RestrictNamespaces=true
    LockPersonality=true
    MemoryDenyWriteExecute=true
    RestrictRealtime=true
    SystemCallArchitectures=native
    SystemCallFilter=@system-service
    SystemCallFilter=~@privileged @resources
    
    LimitNOFILE=65536
    MemoryMax=512M
    TasksMax=512
    
    [Install]
    WantedBy=multi-user.target
    Enable and verify
    systemctl daemon-reload
    systemctl enable --now filebrowser
    ss -tlnp | grep 8080   # must be 127.0.0.1, never 0.0.0.0
    5

    Configure Nginx as a Reverse Proxy

    /etc/nginx/sites-available/filebrowser
    server {
        listen 80;
        listen [::]:80;
        server_name files.yourdomain.com;
        location / { return 301 https://$host$request_uri; }
    }
    
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name files.yourdomain.com;
    
        add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    
        client_max_body_size 10G;
        client_body_buffer_size 128k;
        client_body_timeout 600s;
    
        access_log /var/log/nginx/filebrowser-access.log;
        error_log /var/log/nginx/filebrowser-error.log warn;
    
        location / {
            proxy_pass http://127.0.0.1:8080;
            proxy_http_version 1.1;
            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;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
    
            proxy_connect_timeout 60s;
            proxy_send_timeout 600s;
            proxy_read_timeout 600s;
    
            # Critical for upload speed
            proxy_request_buffering off;
            proxy_buffering off;
        }
    }
    Enable and reload
    ln -s /etc/nginx/sites-available/filebrowser /etc/nginx/sites-enabled/
    rm -f /etc/nginx/sites-enabled/default
    nginx -t && systemctl reload nginx
    6

    Issue a Let's Encrypt Certificate

    certbot --nginx
    certbot --nginx -d files.yourdomain.com --redirect --agree-tos -m you@yourdomain.com

    Certbot fills in the cert paths and adds the redirect block. Renewals run automatically via the systemd timer (systemctl list-timers | grep certbot).

    7

    Brute-force Protection with fail2ban

    /etc/fail2ban/filter.d/filebrowser.conf
    [INCLUDES]
    before = common.conf
    
    [Definition]
    datepattern = ^%%Y/%%m/%%d %%H:%%M:%%S
    failregex   = /api/login: 403 <HOST>
    ignoreregex =
    /etc/fail2ban/jail.d/filebrowser.conf
    [filebrowser]
    enabled  = true
    port     = http,https
    filter   = filebrowser
    logpath  = /var/log/filebrowser/filebrowser.log
    maxretry = 5
    findtime = 10m
    bantime  = 1h
    banaction = iptables-multiport
    Apply
    systemctl restart fail2ban
    fail2ban-client status filebrowser
    8

    Create Non-Admin Users

    Never use the admin account day to day. Each user gets a scoped root directory.

    Add a scoped user
    mkdir -p /srv/filebrowser/users/alice
    chown filebrowser:filebrowser /srv/filebrowser/users/alice
    
    sudo -u filebrowser filebrowser users add alice 'AnotherStrongPassword' \
      --database /var/lib/filebrowser/filebrowser.db \
      --scope /users/alice \
      --perm.admin=false \
      --perm.share=true \
      --perm.create=true \
      --perm.delete=true \
      --perm.modify=true \
      --perm.download=true

    For read-only sharing, set the create/delete/modify/share perms to false and leave only --perm.download=true.

    9

    Tuning and Operational Hygiene

    /etc/logrotate.d/filebrowser
    /var/log/filebrowser/*.log {
        weekly
        rotate 8
        compress
        delaycompress
        missingok
        notifempty
        create 640 filebrowser filebrowser
        postrotate
            systemctl reload filebrowser > /dev/null 2>&1 || true
        endscript
    }
    Daily database backup
    cat > /usr/local/bin/filebrowser-backup.sh <<'EOF'
    #!/bin/bash
    set -euo pipefail
    BACKUP_DIR=/var/backups/filebrowser
    mkdir -p "$BACKUP_DIR"
    TIMESTAMP=$(date +%Y%m%d-%H%M%S)
    cp /var/lib/filebrowser/filebrowser.db "$BACKUP_DIR/filebrowser.db.$TIMESTAMP"
    find "$BACKUP_DIR" -name 'filebrowser.db.*' -mtime +30 -delete
    EOF
    chmod +x /usr/local/bin/filebrowser-backup.sh
    
    echo "0 3 * * * root /usr/local/bin/filebrowser-backup.sh" \
      | tee /etc/cron.d/filebrowser-backup
    Upgrade Filebrowser
    systemctl stop filebrowser
    curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash
    systemctl start filebrowser

    Common Issues

    • 413 Request Entity Too Large: raise client_max_body_size and reload nginx
    • Slow uploads: confirm proxy_request_buffering off
    • Login always 403: check the log; usually a corrupt DB after unclean shutdown — restore from backup
    • Blank pages in UI: missing proxy_set_header Host $host
    • Reset admin password: filebrowser users update admin --password 'New' --database ...