Self Hosting Project Management Systems · FrankBoard

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

Original resource: Visit the source site