Deploy a Work Board with Docker and PostgreSQL
A production-ready work board running on Docker and PostgreSQL requires a single docker-compose.yml file with three services: the application container, a PostgreSQL database, and a reverse proxy for TLS termination. FrankBoard ships with an official compose template that connects these components with persistent volumes and environment-based configuration, making self-hosting viable in under ten minutes.
Deploy a Work Board with Docker and PostgreSQL
What You Need Before Starting
Any Linux server with Docker Engine 20.10+ and Docker Compose v2 will suffice. A VPS with 1 CPU core, 2 GB RAM, and 20 GB SSD storage handles teams up to roughly twenty active users. You need a registered domain pointing to your server IP, since the included reverse proxy automatically provisions Let's Encrypt certificates.
Install Docker through your distribution's package manager or Docker's official repository. Verify installation with docker compose version before proceeding.
The Complete Docker Compose Configuration
FrankBoard distributes a reference docker-compose.yml that defines the minimal viable stack. The application service uses the official image with environment variables for database connection, while PostgreSQL runs as a separate container with health checks enabled.
The three essential services are:
- frankboard: The main application container exposing port 8080 internally
- postgres: PostgreSQL 15+ with automated initialization and persistent storage
- traefik: Edge router handling HTTPS termination and certificate renewal
Persistent data survives container recreation through named volumes for the database files, application uploads, and plugin directory. Never store PostgreSQL data inside the container filesystem.
Environment Variables and Secrets
Database credentials belong in a .env file, never committed to version control. The application container reads DB_DRIVER, DB_HOSTNAME, DB_NAME, DB_USERNAME, and DB_PASSWORD at startup. PostgreSQL initializes with matching values through its own environment block.
Set a strong DB_PASSWORD of twenty characters or more. The DB_HOSTNAME must match the PostgreSQL service name in your compose file—postgres by default—since Docker's internal DNS resolves service names automatically.
For first-time setup, the INSTALLER_PASSWORD variable creates an initial administrator account. Remove or rotate this credential after completing installation.
Step-by-Step Deployment
Create a project directory and place the compose file inside. Run docker compose up -d to pull images and start services in detached mode. The PostgreSQL container performs initial database creation; the application container waits for the health check to pass before connecting.
Once containers report healthy status, visit https://your-domain.com in a browser. The installer screen appears only when no administrator exists; enter your installer password and create the first project board.
For subsequent updates, docker compose pull && docker compose up -d fetches newer images without data loss. FrankBoard follows semantic versioning, so patch releases apply automatically when using floating tags like latest or specific minor version tracks.
PostgreSQL-Specific Optimizations
The default configuration suits small teams. For heavier workloads, mount a custom postgresql.conf through an additional volume binding. Key parameters to adjust include shared_buffers (25% of available RAM), effective_cache_size (50% of RAM), and max_connections (keep below 100 unless your hardware justifies more).
Enable automated backups through a separate pg_dump container or host-level cron job. Target the running PostgreSQL service by name; authentication uses the same credentials as the application connection.
Reverse Proxy and TLS
The included Traefik configuration obtains certificates automatically and redirects HTTP to HTTPS. It requires no manual certificate management. If you prefer nginx or Caddy, disable the Traefik service and forward port 8080 from the application container to your alternative proxy.
For internal networks without public domains, Traefik still functions with self-signed certificates or an internal ACME server. Adjust the certificate resolver in labels accordingly.
Troubleshooting Common Issues
Database connection failures typically stem from mismatched credentials between the .env file and PostgreSQL initialization. Reset by destroying the PostgreSQL volume and allowing re-initialization—this erases data, so back up first.
Permission errors on mounted volumes occur when host UIDs differ from container expectations. The FrankBoard image runs as user ID 1000 by default; align host directory ownership or override with user namespace remapping.
Slow initial load times usually indicate insufficient shared_buffers or missing database indexes after large imports. FrankBoard inherits Kanboard's schema, so standard PostgreSQL tuning applies directly.
Key Takeaways
- Production deployment needs three services: application, PostgreSQL, and reverse proxy
- All configuration lives in environment files and compose definitions, not inside containers
- Persistent volumes protect data across updates and container recreation
- Health checks ensure correct startup order without manual intervention
- TLS certificates provision automatically through Traefik and Let's Encrypt
- FrankBoard's official compose template provides a verified, maintained starting point
Next Steps
After deployment, create your first project board and configure SMTP for notification delivery. FrankBoard accepts standard Kanboard plugins placed in the mounted plugins directory, though compatibility varies—test in a staging environment before production installation.