Deploying Focalboard
Introduction
Focalboard is an open-source, self-hosted alternative to tools like Trello, Notion, and Asana. Developed by Mattermost, Focalboard provides a powerful project management and team collaboration platform that helps organizations plan, track, and manage work across teams. With its intuitive kanban boards, table views, and calendar features, Focalboard offers a flexible workspace for organizing tasks, projects, and team activities while keeping all your data under your control.
Focalboard is known for its:
- Multiple Views: Switch seamlessly between board, table, gallery, and calendar views to visualize your work
- Self-Hosted: Complete control over your data with full self-hosting capabilities
- Real-Time Collaboration: Work together with your team in real-time with live updates
- Custom Properties: Define custom fields, tags, and properties to match your workflow
- Powerful Filtering: Advanced filtering and sorting to focus on what matters
- Database Integration: Built-in support for PostgreSQL and MySQL databases
- Open Source: Fully open-source with an active community and regular updates
- Privacy-Focused: No data mining or tracking - your information stays on your server
This comprehensive guide walks you through deploying Focalboard on Klutch.sh using Docker, including detailed installation steps, sample Dockerfile configurations, connection examples, and production-ready best practices for persistent storage.
Prerequisites
Before you begin, ensure you have the following:
- A Klutch.sh account
- A GitHub account with a repository for your Focalboard project
- Docker installed locally for testing (optional but recommended)
- Basic understanding of Docker and project management tools
Installation and Setup
Step 1: Create Your Project Directory
First, create a new directory for your Focalboard deployment project:
mkdir focalboard-klutchcd focalboard-klutchgit initStep 2: Create the Dockerfile
Create a Dockerfile in your project root directory. This will define your Focalboard container configuration:
FROM mattermost/focalboard:7.10.4
# Focalboard uses port 8000 internally in the containerEXPOSE 8000
# The official Focalboard image includes an entrypoint that starts the server# No CMD needed as it's inherited from the base imageNote: The official Focalboard Docker image comes with an embedded SQLite database for quick starts. For production deployments with persistent data, we’ll configure a volume mount and optionally use PostgreSQL or MySQL.
Step 3: Create Configuration File (Optional)
For advanced configurations, you can create a custom configuration file. Create a config.json file:
{ "serverRoot": "https://example-app.klutch.sh", "port": 8000, "dbtype": "sqlite3", "dbconfig": "/data/focalboard.db", "useSSL": false, "webpath": "./pack", "filespath": "/data/files", "telemetry": false, "session_expire_time": 2592000, "session_refresh_time": 18000, "localOnly": false, "enableLocalMode": true, "localModeSocketLocation": "/var/tmp/focalboard_local.socket"}Important Configuration Options:
serverRoot: The public URL where Focalboard will be accessibleport: Internal port (should be 8000 for Klutch.sh)dbtype: Database type (sqlite3,postgres, ormysql)dbconfig: Database connection string or file pathfilespath: Directory for uploaded files and attachments
Step 4: Create Docker Compose for Local Testing (Optional)
For local testing before deploying to Klutch.sh, create a docker-compose.yml file:
version: '3.8'
services: focalboard: build: . ports: - "8080:8000" volumes: - focalboard_data:/data - ./config.json:/opt/focalboard/config.json:ro environment: - FOCALBOARD_SERVER_ROOT=http://localhost:8080 restart: unless-stopped
volumes: focalboard_data: driver: localNote: This docker-compose file is for local development only. Klutch.sh does not support Docker Compose for deployment.
Step 5: Test Locally (Optional)
Before deploying to Klutch.sh, you can test your Focalboard setup locally:
# Using Docker Compose (local development only)docker-compose up -d
# Or build and run with Docker directlydocker build -t my-focalboard .
docker run -d \ --name focalboard-test \ -p 8080:8000 \ -v focalboard_data:/data \ -e FOCALBOARD_SERVER_ROOT=http://localhost:8080 \ my-focalboard
# Wait for Focalboard to start (about 10-20 seconds)# Check the logsdocker logs -f focalboard-test
# Once started, visit http://localhost:8080 in your browser
# Stop and remove the test container when donedocker stop focalboard-testdocker rm focalboard-testdocker volume rm focalboard_dataStep 6: Create Documentation File (Optional)
Create a .env.example file to document environment variables:
# .env.example - Document your Focalboard configuration# Do not commit actual secrets to git
# Public URL where Focalboard will be accessibleFOCALBOARD_SERVER_ROOT=https://example-app.klutch.sh
# Database configuration (for PostgreSQL or MySQL)# For SQLite, these are not needed# DATABASE_TYPE=postgres# DATABASE_URL=postgres://user:password@host:5432/focalboard
# Session configuration# SESSION_EXPIRE_TIME=2592000# SESSION_REFRESH_TIME=18000
# Feature flags# FOCALBOARD_TELEMETRY=false# FOCALBOARD_ENABLE_PUBLIC_SHARED_BOARDS=trueStep 7: Push to GitHub
Commit your Dockerfile and configuration files to your GitHub repository:
# Add a .gitignore to exclude local testing filesecho "docker-compose.yml" >> .gitignoreecho "*.local" >> .gitignoreecho ".env" >> .gitignore
git add Dockerfile .env.example .gitignore config.jsongit commit -m "Add Focalboard Dockerfile and configuration"git remote add origin https://github.com/yourusername/focalboard-klutch.gitgit push -u origin mainDeploying to Klutch.sh
Now that your Focalboard project is ready and pushed to GitHub, follow these steps to deploy it on Klutch.sh with persistent storage.
Deployment Steps
-
Log in to Klutch.sh
Navigate to klutch.sh/app and sign in to your account.
-
Create a New Project
Go to Create Project and give your project a meaningful name (e.g., “Focalboard Project Management”).
-
Create a New App
Navigate to Create App and configure the following settings:
-
Select Your Repository
- Choose GitHub as your Git source
- Select the repository containing your Dockerfile
- Choose the branch you want to deploy (usually
mainormaster)
-
Configure Traffic Type
- Traffic Type: Select HTTP (Focalboard is a web application that needs HTTP traffic)
- Internal Port: Set to
8000(the port your container listens on)
-
Set Environment Variables
Add the following environment variables for your Focalboard configuration:
FOCALBOARD_SERVER_ROOT: The public URL where your app will be accessible (e.g.,https://example-app.klutch.sh)
Optional environment variables (if using PostgreSQL or MySQL):
FOCALBOARD_DBTYPE: Database type (postgresormysql)FOCALBOARD_DBCONFIG: Database connection stringFOCALBOARD_TELEMETRY: Set tofalseto disable telemetry (recommended for privacy)FOCALBOARD_ENABLE_PUBLIC_SHARED_BOARDS: Set totrueif you want to enable public board sharing
Security Note: Always use strong, unique passwords for database connections in production deployments.
-
Attach a Persistent Volume
This is critical for ensuring your boards and data persist across deployments and restarts:
- In the Volumes section, click “Add Volume”
- Mount Path: Enter
/data(this is where Focalboard stores the database and uploaded files) - Size: Choose an appropriate size based on your expected data volume (e.g., 5GB for small teams, 20GB+ for larger deployments with many file attachments)
Important: Focalboard requires persistent storage to maintain your boards, cards, and uploaded files between container restarts. Without this volume, all data will be lost when the container restarts.
-
Configure Additional Settings
- Region: Select the region closest to your users for optimal latency
- Compute Resources: Choose CPU and memory based on your workload (minimum 512MB RAM recommended, 1GB+ for production)
- Instances: Start with 1 instance (you can scale later based on usage)
-
Deploy Your Application
Click “Create” to start the deployment. Klutch.sh will:
- Automatically detect your Dockerfile in the repository root
- Build the Docker image
- Attach the persistent volume
- Start your Focalboard container
- Assign a URL for accessing your application
-
Access Your Focalboard Instance
Once deployment is complete, you’ll receive a URL like
example-app.klutch.sh. Visit this URL in your browser to access Focalboard.On your first visit, you’ll be prompted to create an admin account. This will be your primary account for managing Focalboard and creating boards.
Getting Started with Focalboard
Creating Your First Board
After deploying and accessing your Focalboard instance:
- Create an Account: On first visit, register with your email and create a secure password
- Create a Workspace: Workspaces help organize related boards
- Create a Board: Click “Create new board” and choose a template or start from scratch
- Add Cards: Create cards for tasks, projects, or items to track
- Customize Properties: Add custom fields like status, priority, assignee, due dates, etc.
- Switch Views: Try different views (Board, Table, Gallery, Calendar) to find what works best
Sample Board Structure: Software Development
Here’s an example of a software development board structure:
Board: Sprint Planning├── Status Property (Select)│ ├── Backlog│ ├── To Do│ ├── In Progress│ ├── In Review│ └── Done├── Priority Property (Select)│ ├── Critical│ ├── High│ ├── Medium│ └── Low├── Assignee Property (Person)├── Story Points Property (Number)├── Due Date Property (Date)├── Tags Property (Multi-Select)└── Sprint Property (Select)
Sample Cards:├── Card: "Implement user authentication"│ ├── Status: In Progress│ ├── Priority: High│ ├── Assignee: John Doe│ ├── Story Points: 5│ └── Tags: Backend, Security├── Card: "Design homepage UI"│ ├── Status: To Do│ ├── Priority: Medium│ ├── Assignee: Jane Smith│ └── Tags: Frontend, Design└── Card: "Setup CI/CD pipeline" ├── Status: Done ├── Priority: High └── Tags: DevOpsUsing Different Views
Board View: Kanban-style columns for visual workflow management
- Great for: Sprint planning, task workflows, project stages
Table View: Spreadsheet-like interface with all properties visible
- Great for: Data analysis, bulk editing, detailed overviews
Gallery View: Card-based layout focusing on images
- Great for: Design reviews, product catalogs, visual planning
Calendar View: Date-based view showing cards with due dates
- Great for: Deadline tracking, scheduling, timeline planning
Connecting to Focalboard API
Focalboard provides a REST API for programmatic access. Here are examples of connecting to your Focalboard instance:
API Authentication
First, generate an API token from your Focalboard account:
- Log in to your Focalboard instance
- Click your profile icon
- Go to “Settings” → “API tokens”
- Create a new token with appropriate permissions
Example API Calls
JavaScript/Node.js:
const FOCALBOARD_URL = 'https://example-app.klutch.sh';const API_TOKEN = 'your_api_token_here';
// Fetch all boardsasync function getBoards() { const response = await fetch(`${FOCALBOARD_URL}/api/v1/teams/0/boards`, { headers: { 'Authorization': `Bearer ${API_TOKEN}`, 'Content-Type': 'application/json' } }); return await response.json();}
// Get cards from a boardasync function getCards(boardId) { const response = await fetch(`${FOCALBOARD_URL}/api/v1/boards/${boardId}/blocks`, { headers: { 'Authorization': `Bearer ${API_TOKEN}`, 'Content-Type': 'application/json' } }); return await response.json();}
// Create a new cardasync function createCard(boardId, cardData) { const response = await fetch(`${FOCALBOARD_URL}/api/v1/boards/${boardId}/blocks`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_TOKEN}`, 'Content-Type': 'application/json' }, body: JSON.stringify(cardData) }); return await response.json();}
// Update a cardasync function updateCard(boardId, blockId, updates) { const response = await fetch(`${FOCALBOARD_URL}/api/v1/boards/${boardId}/blocks/${blockId}`, { method: 'PATCH', headers: { 'Authorization': `Bearer ${API_TOKEN}`, 'Content-Type': 'application/json' }, body: JSON.stringify(updates) }); return await response.json();}
// Example usageasync function main() { try { // Get all boards const boards = await getBoards(); console.log('Available boards:', boards);
if (boards.length > 0) { const boardId = boards[0].id;
// Get cards from the first board const cards = await getCards(boardId); console.log('Cards in board:', cards);
// Create a new card const newCard = await createCard(boardId, { type: 'card', title: 'New Task from API', fields: { properties: { status: 'To Do', priority: 'High' } } }); console.log('Created card:', newCard); } } catch (error) { console.error('API Error:', error); }}
main();Python:
import requests
FOCALBOARD_URL = 'https://example-app.klutch.sh'API_TOKEN = 'your_api_token_here'
headers = { 'Authorization': f'Bearer {API_TOKEN}', 'Content-Type': 'application/json'}
# Get all boardsdef get_boards(): response = requests.get( f'{FOCALBOARD_URL}/api/v1/teams/0/boards', headers=headers ) return response.json()
# Get cards from a boarddef get_cards(board_id): response = requests.get( f'{FOCALBOARD_URL}/api/v1/boards/{board_id}/blocks', headers=headers ) return response.json()
# Create a new carddef create_card(board_id, card_data): response = requests.post( f'{FOCALBOARD_URL}/api/v1/boards/{board_id}/blocks', headers=headers, json=card_data ) return response.json()
# Update a carddef update_card(board_id, block_id, updates): response = requests.patch( f'{FOCALBOARD_URL}/api/v1/boards/{board_id}/blocks/{block_id}', headers=headers, json=updates ) return response.json()
# Example usagedef main(): try: # Get all boards boards = get_boards() print(f'Available boards: {boards}')
if boards: board_id = boards[0]['id']
# Get cards from the first board cards = get_cards(board_id) print(f'Cards in board: {cards}')
# Create a new card new_card = create_card(board_id, { 'type': 'card', 'title': 'New Task from Python API', 'fields': { 'properties': { 'status': 'To Do', 'priority': 'High' } } }) print(f'Created card: {new_card}') except Exception as e: print(f'API Error: {e}')
if __name__ == '__main__': main()cURL:
# Get all boardscurl -X GET https://example-app.klutch.sh/api/v1/teams/0/boards \ -H "Authorization: Bearer your_api_token_here" \ -H "Content-Type: application/json"
# Get cards from a boardcurl -X GET https://example-app.klutch.sh/api/v1/boards/{board_id}/blocks \ -H "Authorization: Bearer your_api_token_here" \ -H "Content-Type: application/json"
# Create a new cardcurl -X POST https://example-app.klutch.sh/api/v1/boards/{board_id}/blocks \ -H "Authorization: Bearer your_api_token_here" \ -H "Content-Type: application/json" \ -d '{ "type": "card", "title": "New Task", "fields": { "properties": { "status": "To Do", "priority": "High" } } }'
# Update a cardcurl -X PATCH https://example-app.klutch.sh/api/v1/boards/{board_id}/blocks/{block_id} \ -H "Authorization: Bearer your_api_token_here" \ -H "Content-Type: application/json" \ -d '{ "title": "Updated Task Title", "fields": { "properties": { "status": "In Progress" } } }'Production Best Practices
Security Recommendations
- Use Strong Passwords: Never use default or weak passwords. Use a password manager to generate strong credentials.
- Environment Variables: Store all sensitive credentials as environment variables in Klutch.sh, never in your Dockerfile or git repository.
- HTTPS Only: Always access Focalboard over HTTPS. Klutch.sh provides automatic HTTPS for all deployments.
- API Token Security: Rotate API tokens regularly and use tokens with minimal required permissions.
- Regular Backups: Implement a backup strategy for your persistent volume data to prevent data loss.
- Access Control: Use Focalboard’s built-in role-based access control to limit user permissions appropriately.
- Disable Telemetry: Set
FOCALBOARD_TELEMETRY=falseto prevent data collection. - Update Regularly: Keep your Focalboard Docker image updated to receive security patches and bug fixes.
Performance Optimization
- Resource Allocation: Monitor your application performance and adjust compute resources as needed. Start with at least 512MB RAM, scale to 1GB+ for production use.
- Database Choice: For small teams, SQLite works well. For larger deployments or high concurrency, consider using PostgreSQL or MySQL.
- Volume Size: Monitor disk usage on your persistent volume. Ensure adequate space for attachments and database growth.
- Caching: Focalboard includes built-in caching. Ensure adequate memory allocation for optimal performance.
- File Uploads: Monitor the size and number of file attachments. Consider implementing file size limits for uploads.
- Connection Pooling: If using external databases, configure appropriate connection pool settings.
Monitoring
Monitor your Focalboard deployment for:
- Response times and page load performance
- API request rates and errors
- Database query performance and size
- Disk usage on your persistent volume
- Memory and CPU utilization
- Number of concurrent users and active sessions
- Websocket connections for real-time updates
- Error logs for application issues
Scaling Considerations
- Vertical Scaling: Increase compute resources (CPU/RAM) as your user base grows
- Storage Growth: Monitor persistent volume usage and expand as needed for growing boards and attachments
- External Database: For deployments with 50+ users, consider migrating to PostgreSQL or MySQL for better performance
- Load Balancing: For high-traffic scenarios, consider running multiple instances behind a load balancer
- CDN: Use a CDN for serving static assets to reduce server load and improve global access speeds
Database Migration (SQLite to PostgreSQL)
If you start with SQLite and need to migrate to PostgreSQL for better performance:
- Export your SQLite data using Focalboard’s backup tools
- Set up a PostgreSQL database (external or on Klutch.sh)
- Update your environment variables:
FOCALBOARD_DBTYPE=postgresFOCALBOARD_DBCONFIG=postgres://user:password@host:5432/focalboard
- Restore your backup to the new database
- Redeploy your application with the new configuration
Troubleshooting
Cannot Access Focalboard Interface
- Verify that HTTP traffic type is selected and internal port is set to 8000
- Check that
FOCALBOARD_SERVER_ROOTenvironment variable matches your actual deployment URL - Ensure the deployment has completed successfully and the container is running
- Check deployment logs in Klutch.sh dashboard for startup errors
- Verify there are no firewall or network issues blocking access
Data Not Persisting
- Verify that the persistent volume is correctly attached at
/data - Check that the volume has sufficient space allocated
- Ensure the volume mount path is exactly
/data(case-sensitive) - Check logs for database write errors
- Verify file system permissions are correct
Performance Issues
- Check if you have adequate RAM (minimum 512MB, recommended 1GB+)
- Review concurrent user load and database query performance
- Monitor disk I/O if using SQLite (consider migrating to PostgreSQL)
- Check for large file attachments consuming resources
- Review browser console for client-side performance issues
- Consider increasing compute resources or optimizing database
API Connection Issues
- Verify your API token is valid and not expired
- Check that the token has appropriate permissions for the operation
- Ensure you’re using the correct URL format (include /api/v1/ in the path)
- Verify CORS settings if making requests from a web browser
- Check authentication headers are properly formatted
- Review API error messages for specific issues
Real-Time Updates Not Working
- Check that websocket connections are properly established
- Verify that no proxy or firewall is blocking websocket traffic
- Review browser console for websocket connection errors
- Ensure adequate server resources for maintaining websocket connections
- Check that multiple browser tabs are not causing connection issues
Database Connection Errors
- Verify database connection string format is correct
- Check database credentials are accurate
- Ensure database server is accessible from Klutch.sh
- Review database server logs for connection attempts
- Verify database has adequate connections available
- Check network connectivity between Focalboard and database
Additional Resources
- Klutch.sh Documentation
- Official Focalboard Documentation
- Focalboard User Guide
- Focalboard Admin Guide
- Focalboard GitHub Repository
- Focalboard Docker Image Documentation
- Klutch.sh Volumes Guide
- Klutch.sh Networking Guide
- Klutch.sh Deployments Guide
Conclusion
Deploying Focalboard to Klutch.sh with Docker provides a powerful, self-hosted project management platform with complete control over your team’s data. By following this guide, you’ve set up a production-ready Focalboard instance with proper data persistence, security configurations, and API access capabilities. Your Focalboard deployment is now ready to support your team’s collaboration needs, from simple task tracking to complex project management, all while maintaining privacy and data ownership.