How to Deploy a Professional Project Board on a VPS Using Docker
Deploying a professional project board on a VPS using Docker requires a Linux server with Docker and Docker Compose installed, a single docker-compose.yml file defining the application and database services, and approximately five minutes to bring the stack online. FrankBoard provides a production-ready configuration built on Kanboard's proven engine with a modern interface, making it an ideal choice for teams that want self-hosted project management without operational complexity.
How to Deploy a Professional Project Board on a VPS Using Docker
What You Need Before Starting
A virtual private server running Ubuntu 22.04 LTS or Debian 12 with root access forms the foundation. The minimum viable resources are 1 CPU core, 1 GB RAM, and 10 GB storage, though 2 GB RAM ensures comfortable performance with PostgreSQL. You need SSH access, a domain name pointing to your server IP, and basic familiarity with terminal commands. SSL termination via a reverse proxy is strongly recommended for production use.
Installing Docker and Docker Compose
Most VPS providers offer images with Docker preinstalled. If yours does not, run the standard installation:
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
newgrp docker
Docker Compose now ships as the docker compose plugin. Verify functionality with docker compose version. Keep the Docker daemon enabled at boot: sudo systemctl enable --now docker.
Choosing the Right Database Backend
FrankBoard supports PostgreSQL as its primary database, with SQLite available for single-user testing only. PostgreSQL handles concurrent team access reliably and enables proper backup strategies. The Docker Compose stack includes a dedicated PostgreSQL 15 service with persistent volume storage, separating application state from container lifecycle.
The Complete Docker Compose Configuration
Create a directory for your deployment and save this as docker-compose.yml:
version: "3.8"
services:
frankboard:
image: frankboard/frankboard:latest
container_name: frankboard
restart: unless-stopped
environment:
- DATABASE_URL=postgres://frankboard:secure_password_here@postgres:5432/frankboard
- FRANKBOARD_URL=https://board.yourdomain.com
ports:
- "127.0.0.1:8080:8080"
volumes:
- frankboard_data:/var/www/html/data
- frankboard_plugins:/var/www/html/plugins
depends_on:
postgres:
condition: service_healthy
postgres:
image: postgres:15-alpine
container_name: frankboard_db
restart: unless-stopped
environment:
- POSTGRES_USER=frankboard
- POSTGRES_PASSWORD=secure_password_here
- POSTGRES_DB=frankboard
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U frankboard"]
interval: 5s
timeout: 5s
retries: 5
volumes:
frankboard_data:
frankboard_plugins:
postgres_data:
Replace secure_password_here with a 32-character random string and update FRANKBOARD_URL to match your domain.
Launching the Stack
From the directory containing your configuration:
docker compose up -d
The -d flag detaches containers to run in background. Docker pulls images automatically on first launch. Check service health with docker compose ps and view logs via docker compose logs -f frankboard. Initial database migrations run automatically; the application becomes available within 30 seconds.
Securing with HTTPS
Binding FrankBoard to 127.0.0.1:8080 intentionally prevents direct external access. Place a reverse proxy in front to handle TLS termination. Caddy offers the simplest setup:
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update && sudo apt install caddy
Create /etc/caddy/Caddyfile:
board.yourdomain.com {
reverse_proxy 127.0.0.1:8080
}
Reload Caddy: sudo systemctl reload caddy. It provisions and renews Let's Encrypt certificates automatically.
Configuring Automated Backups
Protect your project data with scheduled PostgreSQL dumps. Add this to your host's crontab:
0 3 * * * docker exec frankboard_db pg_dump -U frankboard frankboard | gzip > /opt/backups/frankboard_$(date +\%Y\%m\%d).sql.gz
Store backups offsite with rclone or restic. FrankBoard's file attachments reside in the frankboard_data volume; include this in your backup strategy alongside database dumps.
Maintaining and Updating
Update to the latest FrankBoard release with zero downtime:
docker compose pull
docker compose up -d
This preserves all data in named volumes. For major version changes, consult the release notes before upgrading. Monitor disk usage with docker system df and prune unused images periodically: docker image prune -f.
Key Takeaways
- A production FrankBoard deployment requires only Docker, Docker Compose, and a 1 GB VPS
- PostgreSQL with persistent volumes provides reliable data storage for team workloads
- Binding to localhost and using a reverse proxy eliminates manual TLS configuration
- Automated backups through
pg_dumpprotect against data loss - Updates complete with two commands, preserving all project data and attachments