Effortless File Management on VPS with Docker

Running a web server on a VPS gives you flexibility, but managing files through SSH can be tedious. File Management on VPS with Docker provides a clean web interface to browse, edit, and manage your website files directly from your browser. This guide walks you through integrating File Browser into an existing Docker-based web stack running nginx and PHP-FPM.

Prerequisites

Before you begin, you should have:

  • A VPS with Docker and Docker Compose installed
  • An existing nginx + PHP-FPM setup running in Docker containers
  • Basic familiarity with Docker volumes and networking
  • Root or sudo access to your server

Understanding the Base Web Stack

Your foundation is a standard Docker setup with nginx and PHP-FPM sharing a common webroot. This architecture is the industry standard for serving PHP applications with Docker because it cleanly separates the web server from the PHP processor while allowing them to access the same files.

Here’s what the base docker-compose.yml looks like in /root/webserver:

services:
  nginx-webserver:
    image: nginx:alpine
    container_name: nginx-webserver
    restart: unless-stopped
    volumes:
      - ./www:/usr/share/nginx/html
      - ./conf.d:/etc/nginx/conf.d
    networks:
      - web
    depends_on:
      - php-fpm
        
  php-fpm:
    image: php:fpm-alpine
    container_name: php-fpm
    restart: unless-stopped
    volumes:
      - ./www:/usr/share/nginx/html
    networks:
      - web

networks:
  web:
    external: true

Both nginx and PHP-FPM mount the same ./www directory, which contains all your website files. The nginx container also mounts ./conf.d for virtual host configurations.

Adding File Management on VPS with Docker (Stack)

File Browser runs as a separate container but accesses the same directory structure. This allows you to manage your web files through a modern browser interface without disrupting your existing services.

Add this service definition to your docker-compose.yml:

  filebrowser:
    image: filebrowser/filebrowser:latest
    container_name: filebrowser
    restart: unless-stopped
    volumes:
      - ./www:/srv
      - ./filebrowser/database:/database
      - ./filebrowser/config:/config
    networks:
      - web
    expose:
      - "80"

The container mounts three critical paths:

  • ./www as /srv – This is your webroot, containing all site folders
  • ./filebrowser/database – Where File Browser stores its database
  • ./filebrowser/config – Where File Browser keeps its settings

Preparing the Host Directories

Create the necessary directories on your host system:

cd /root/webserver
mkdir -p filebrowser/database filebrowser/config

These directories must exist before starting the container, otherwise Docker will create them with incorrect permissions.

Launch the File Browser container:

docker compose up -d filebrowser

Configuring Permissions Correctly

Permission management is crucial when using bind mounts because Docker doesn’t automatically handle them. The container needs write access to its database and config directories, while nginx needs read access to your web files.

Setting Up File Browser Permissions

For initial setup, make File Browser’s directories fully writable:

cd /root/webserver
chmod -R 777 filebrowser

While this is permissive, it ensures File Browser can create its database and settings files. You can tighten these permissions later once everything works.

Configuring Web Directory Permissions

Your web files need appropriate permissions for nginx and PHP-FPM to read them while preventing unauthorized modifications. The standard approach uses the www-data group:

cd /root/webserver
chown -R your_user:www-data www/
find www/ -type d -exec chmod 755 {} \;
find www/ -type f -exec chmod 644 {} \;

This configuration means:

  • Directories are readable and executable by everyone but writable only by the owner
  • Files are readable by everyone but writable only by the owner
  • The www-data group can read everything nginx needs to serve

If you encounter 403 or 404 errors after changing permissions, you can safely restore them with:

cd /root/webserver
find www/ -type d -exec chmod 755 {} \;
find www/ -type f -exec chmod 644 {} \;
File Management on VPS with Docker

Tightening Security for Production

Once your setup is stable, you should implement more restrictive permissions. This prevents potential security issues while maintaining functionality.

Creating a Dedicated Web User

First, create a non-root user specifically for web operations:

adduser webuser
id webuser

Note the UID and GID from the id command (for example, 1001:1001).

Applying Restrictive Permissions

Set ownership of all web-related directories:

cd /root/webserver
chown -R 1001:1001 www filebrowser
find www/ -type d -exec chmod 755 {} \;
find www/ -type f -exec chmod 644 {} \;
chmod -R 750 filebrowser

Update your File Browser service to run as this user:

  filebrowser:
    image: filebrowser/filebrowser:latest
    container_name: filebrowser
    user: "1001:1001"
    restart: unless-stopped
    volumes:
      - ./www:/srv
      - ./filebrowser/database:/database
      - ./filebrowser/config:/config
    networks:
      - web
    expose:
      - "80"

The user directive ensures the container runs with the same UID and GID as your host user, maintaining consistent permissions.

Alternative: Root-Owned Setup

For single-tenant VPS environments where you’re the only administrator, you might prefer simpler root ownership:

chown -R 0:0 www filebrowser
chmod -R 755 www
chmod -R 750 filebrowser

Add this to your File Browser service:

    user: "0:0"

This approach is simpler and still avoids overly permissive 777 permissions.

Exposing File Browser Through Nginx Proxy Manager

Rather than exposing File Browser directly on a host port, route it through Nginx Proxy Manager for SSL termination and access control. Since both NPM and your web stack use the shared web Docker network, they can communicate using container names.

In Nginx Proxy Manager, create a new proxy host:

  • Domain: files.kamath.cloud (or your preferred subdomain)
  • Scheme: http
  • Forward Hostname/IP: filebrowser
  • Forward Port: 80
  • Network: web
  • SSL: Enable with Let’s Encrypt

Docker’s internal DNS resolves filebrowser to your container’s IP automatically. This setup keeps everything secure without exposing ports on your host machine.

Managing Nginx Configuration Files

You can extend File Browser’s access to include your nginx configuration directory, enabling you to edit virtual host configs directly from the web interface.

Updating Docker Compose

Modify the File Browser service to mount both directories:

  filebrowser:
    image: filebrowser/filebrowser:latest
    container_name: filebrowser
    user: "1001:1001"
    restart: unless-stopped
    volumes:
      - ./www:/srv/www
      - ./conf.d:/srv/conf.d
      - ./filebrowser/database:/database
      - ./filebrowser/config:/config
    networks:
      - web
    expose:
      - "80"

Each mount creates a separate top-level folder in File Browser. You’ll see both www and conf.d when browsing /srv.

Apply the changes:

docker compose up -d filebrowser
docker logs filebrowser | head

Setting Configuration Directory Permissions

Apply the same permission structure to your nginx configs:

cd /root/webserver
chown -R your_user:www-data conf.d/
find conf.d/ -type d -exec chmod 755 {} \;
find conf.d/ -type f -exec chmod 644 {} \;

Or if using a specific UID:

cd /root/webserver
adduser webuser                       # Creates UID 1001 typically
id webuser                            # Verify: uid=1001(webuser) gid=1001(webuser)
chown -R 1001:1001 conf.d/
find conf.d/ -type d -exec chmod 755 {} \;
find conf.d/ -type f -exec chmod 644 {} \;

# Deploy & get Password
docker compose up -d filebrowser
docker logs filebrowser | grep "password:"  # Shows: User 'admin' initialized with randomly generated password: XXXXXX

Applying Nginx Configuration Changes

After editing nginx configuration files through File Browser, test and reload nginx:

docker compose exec nginx-webserver nginx -t
docker compose restart nginx-webserver

The first command validates your configuration syntax. Only restart nginx if the test passes successfully.

Standard Maintenance Workflow

Here’s the typical sequence for updating File Browser and managing nginx configurations in this Docker environment.

Updating File Browser

Always back up your configuration before making changes:

cd ~/webserver/
cp docker-compose.yml docker-compose.yml.backup
nano docker-compose.yml
docker compose up -d filebrowser

Expected output:

[+] Running 1/1  
✔ Container filebrowser  Started

Verify the container started correctly:

docker logs filebrowser | head

You should see:

Using config file: /config/settings.json 
Using database: /database/filebrowser.db 
Listening on port 80

# get the password
docker logs filebrowser | grep "password:"  # Shows: User 'admin' initialized with randomly generated password: XXXXXX

Validating Nginx Configuration

Before restarting nginx, always test your configuration:

docker compose exec nginx-webserver nginx -t

Expected response:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok 
nginx: configuration file /etc/nginx/nginx.conf test is successful

Then restart nginx:

docker compose restart nginx-webserver

Output:

[+] Restarting  
✔ Container nginx-webserver  Started

Security Best Practices

Production deployments require additional security considerations beyond basic functionality.

File Browser Security

  • Always route File Browser through Nginx Proxy Manager rather than exposing it directly
  • Enable authentication in File Browser’s settings
  • Use HTTPS exclusively for File Browser access
  • Consider restricting File Browser access by IP address if your team has static IPs
  • Regularly review File Browser’s access logs for suspicious activity

Docker and System Security

  • Avoid running daily operations as root – create and use a sudo-enabled user
  • Keep versioned backups of docker-compose.yml before any modifications
  • Never publish full Docker logs publicly as they may contain sensitive information like IPs and usernames
  • Regularly update your Docker images to patch security vulnerabilities
  • Use Docker secrets for sensitive configuration values rather than environment variables

File System Security

  • Avoid 777 permissions in production environments
  • Regularly audit file ownership and permissions across your webroot
  • Implement file integrity monitoring for critical configuration files
  • Consider using read-only volumes for nginx configuration in production
  • Enable audit logging for file modifications through File Browser

Troubleshooting Common Issues

File Browser Won’t Start

Check that the database and config directories exist and are writable:

ls -la /root/webserver/filebrowser/
chmod -R 777 /root/webserver/filebrowser/
docker compose restart filebrowser
docker logs filebrowser

Nginx Returns 403 Forbidden

This typically indicates permission issues with your webroot:

cd /root/webserver
find www/ -type d -exec chmod 755 {} \;
find www/ -type f -exec chmod 644 {} \;
docker compose restart nginx-webserver

Changes in File Browser Don’t Appear

File Browser operates on bind mounts, so changes are immediate. If edits aren’t showing, check:

  • That you’re editing files in the correct directory
  • That the container mounts match your intended paths
  • That cached content isn’t being served (clear browser cache)

Nginx Configuration Changes Don’t Apply

Always test and reload nginx after configuration changes:

docker compose exec nginx-webserver nginx -t
docker compose restart nginx-webserver

Emergency Reset (When Messed Up)

cd /root/webserver
docker compose down filebrowser
rm -rf ./filebrowser/database/* ./filebrowser/config/*
chown -R 1001:1001 ./www ./conf.d ./filebrowser
docker compose up -d filebrowser
docker logs filebrowser | grep "password:" # New random password

Login: admin + new password from logs​

Conclusion

Integrating File Browser into your Docker-based web server stack provides a powerful, secure way to manage website files without SSH access. By following proper permission management, using Docker networking effectively, and implementing appropriate security measures, you create a maintainable system that’s both convenient and safe.

The key principles to remember are bind mount permissions, container networking, and the importance of testing configuration changes before applying them. With this foundation, you can confidently manage multiple websites from a single, user-friendly interface while maintaining the security and reliability your production environment demands.

Leave a Reply

Your email address will not be published. Required fields are marked *