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 {} \;

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.








