How to Self-Host WeKan with Docker Compose
When You Need More Than a Basic Kanban Board
If you’ve outgrown simple card-and-list tools but don’t want the overhead of full project management suites like Taiga, WeKan hits the middle ground. It’s a Kanban board with swimlanes, WIP limits, subtasks, custom fields, checklists, and a REST API — features that Trello locks behind paid plans. Built with Meteor.js and backed by MongoDB, WeKan has been under active development since 2015 and powers workflows for teams ranging from solo developers to enterprise organizations. Official site
WeKan’s feature list is vast: board templates, card voting, time tracking, calendar view, Gantt charts (experimental), import from Trello/Jira/CSV, and multi-language support. The trade-off is resource usage — Meteor.js and MongoDB are heavier than alternatives like Planka or Kanboard.
| Feature | Details |
|---|---|
| License | MIT |
| Language | JavaScript (Meteor.js) |
| Database | MongoDB |
| Latest Version | v8.35 |
| API | REST API with token auth |
| Import | Trello, Jira, CSV, TSV, Wekan JSON |
| Swimlanes | Yes |
| WIP Limits | Yes |
| Calendar View | Yes |
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 2 GB RAM minimum (MongoDB + Meteor is memory-hungry)
- 5 GB of free disk space
- A domain name (optional, for remote access)
| Requirement | Minimum | Recommended |
|---|---|---|
| RAM | 1 GB | 2 GB |
| CPU | 1 core | 2 cores |
| Disk | 2 GB | 10 GB+ |
| Network | LAN access | Domain with reverse proxy |
Docker Compose Configuration
Create a project directory:
mkdir -p /opt/wekan && cd /opt/wekan
Create a docker-compose.yml file:
services:
wekan-db:
image: mongo:7
container_name: wekan-db
restart: unless-stopped
command: mongod --logpath /dev/null --oplogSize 128 --quiet
volumes:
- wekan-db:/data/db
- wekan-db-dump:/dump
networks:
- wekan-net
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 30s
timeout: 10s
retries: 5
wekan-app:
image: ghcr.io/wekan/wekan:v8.35
container_name: wekan-app
restart: unless-stopped
ports:
- "8080:8080"
environment:
WRITABLE_PATH: /data # Persistent data path
MONGO_URL: mongodb://wekan-db:27017/wekan # MongoDB connection string
ROOT_URL: http://localhost:8080 # Change to your domain URL
WITH_API: "true" # Enable REST API
RICHER_CARD_COMMENT_EDITOR: "false" # Plain text comments (lighter)
BROWSER_POLICY_ENABLED: "true" # Browser security headers
BIGEVENTS_PATTERN: NONE # Disable analytics events
volumes:
- wekan-files:/data:rw
depends_on:
wekan-db:
condition: service_healthy
networks:
- wekan-net
volumes:
wekan-db:
wekan-db-dump:
wekan-files:
networks:
wekan-net:
Start the stack:
docker compose up -d
First startup takes about 30 seconds while MongoDB initializes.
Initial Setup
- Open
http://your-server-ip:8080in your browser - Click Register to create the first account
- The first registered user becomes the admin
- Log in and create your first board from the dashboard
Setting the admin after registration: If you need to promote a different user to admin later, use the API or MongoDB directly:
docker compose exec wekan-db mongosh wekan --eval \
'db.users.update({username: "your-username"}, {$set: {isAdmin: true}})'
Configuration
Essential Settings
After logging in as admin, go to Admin Panel (click your avatar → Administration):
| Setting | Location | Purpose |
|---|---|---|
| Registration | Admin → Registration | Open, invite-only, or disabled |
| Custom domain | ROOT_URL env var | Must match your actual access URL |
| Admin → Email | SMTP for notifications | |
| Layout | Admin → Layout | Custom logo, colors, hide elements |
Email Notifications
Add SMTP settings to the app service environment:
environment:
MAIL_URL: smtp://user:[email protected]:587
MAIL_FROM: "WeKan Notifications <[email protected]>"
Replace the SMTP credentials with your own. Restart the app container after changes:
docker compose restart wekan-app
LDAP Authentication
WeKan supports LDAP for enterprise single sign-on. Add to the app environment:
environment:
LDAP_ENABLE: "true"
LDAP_HOST: ldap.yourdomain.com
LDAP_PORT: "636"
LDAP_BASEDN: "ou=users,dc=yourdomain,dc=com"
LDAP_LOGIN_FALLBACK: "true"
LDAP_RECONNECT: "true"
LDAP_ENCRYPTION: ssl
For integration with self-hosted identity providers, see Authentik or Authelia.
OAuth2 / OIDC
WeKan also supports OAuth2 for SSO via environment variables:
environment:
OAUTH2_ENABLED: "true"
OAUTH2_LOGIN_STYLE: popup
OAUTH2_CLIENT_ID: your-client-id
OAUTH2_SECRET: your-client-secret
OAUTH2_SERVER_URL: https://auth.yourdomain.com
OAUTH2_AUTH_ENDPOINT: /authorize
OAUTH2_TOKEN_ENDPOINT: /token
OAUTH2_USERINFO_ENDPOINT: /userinfo
OAUTH2_ID_MAP: sub
OAUTH2_USERNAME_MAP: preferred_username
OAUTH2_FULLNAME_MAP: name
OAUTH2_EMAIL_MAP: email
Advanced Configuration
Board Templates
Create reusable board templates by designing a board with your standard lists (Backlog, In Progress, Review, Done) and card templates. Export it as JSON, then import into new projects for consistent workflows.
Webhooks
WeKan sends webhook notifications on board events. Configure per-board:
- Open a board → Board Settings → Webhooks
- Enter your webhook URL
- Select events to trigger on (card moved, created, commented, etc.)
Supported targets include Slack, Mattermost, n8n, and any endpoint accepting JSON POST.
Custom Fields
Add custom fields to cards for structured data: text, number, date, dropdown, and checkbox types. Useful for tracking priority levels, story points, or cost estimates beyond what labels provide.
REST API
Enable the API with WITH_API=true (already set in the config above). Authenticate with a bearer token:
# Login and get token
TOKEN=$(curl -s -X POST http://localhost:8080/users/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"yourpassword"}' | jq -r '.token')
# List all boards
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/boards
Reverse Proxy
For production use, put WeKan behind a reverse proxy with HTTPS.
Nginx Proxy Manager
Create a proxy host:
- Domain:
kanban.yourdomain.com - Forward hostname:
localhost - Forward port:
8080 - SSL: Request a new certificate
Update ROOT_URL in docker-compose.yml to match your domain:
ROOT_URL: https://kanban.yourdomain.com
For more options, see the Reverse Proxy Setup guide.
Websocket Support
WeKan uses WebSockets for real-time updates. Ensure your reverse proxy passes WebSocket connections. In Nginx:
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
Backup
What to Back Up
| Data | Location | Priority |
|---|---|---|
| MongoDB database | wekan-db volume | Critical |
| Uploaded files | wekan-files volume | Critical |
| Database dumps | wekan-db-dump volume | Useful for quick restores |
| docker-compose.yml | /opt/wekan/ | Important |
Backup Commands
# MongoDB dump
docker compose exec wekan-db mongodump --archive=/dump/wekan-$(date +%Y%m%d).archive --db=wekan
# Copy dump to host
docker compose cp wekan-db:/dump/wekan-$(date +%Y%m%d).archive ./backups/
# Restore from dump
docker compose exec wekan-db mongorestore --archive=/dump/wekan-YYYYMMDD.archive --db=wekan --drop
For automated strategies, see the Backup Strategy guide.
Troubleshooting
Cards Not Updating in Real-Time
Symptom: Changes by other users don’t appear until page refresh.
Fix: WebSocket connections are being blocked. If using a reverse proxy, ensure WebSocket upgrade headers are passed (see Reverse Proxy section above). Also verify ROOT_URL matches the URL users access WeKan from — mismatches break WebSocket negotiation.
MongoDB Connection Refused on Startup
Symptom: WeKan app container exits with MongoNetworkError: connect ECONNREFUSED.
Fix: MongoDB needs time to initialize. The healthcheck in the compose file should prevent this, but if it persists:
# Check MongoDB logs
docker compose logs wekan-db
# Restart just the app after DB is ready
docker compose restart wekan-app
Cannot Register First User
Symptom: Registration page shows “Registration is disabled.”
Fix: On fresh installs, registration should be open by default. If it’s disabled, set it via environment variable:
environment:
ACCOUNTS_OPEN: "true"
After creating the admin account, disable open registration from the admin panel.
High Memory Usage
Symptom: WeKan + MongoDB using 1+ GB of RAM combined.
Fix: This is normal for Meteor.js applications. To reduce MongoDB memory:
command: mongod --logpath /dev/null --oplogSize 128 --quiet --wiredTigerCacheSizeGB 0.25
This limits MongoDB’s WiredTiger cache to 256 MB. Adjust based on your available RAM.
Import from Trello Fails
Symptom: JSON import hangs or shows errors.
Fix: Export your Trello board as JSON from Trello’s menu (not the API). WeKan expects the exact format Trello exports produce. For large boards (1000+ cards), the import may time out — split into smaller boards or use the API for batch imports.
Resource Requirements
| Metric | Idle | Under Load |
|---|---|---|
| RAM (app) | ~300 MB | ~600 MB |
| RAM (MongoDB) | ~200 MB | ~500 MB |
| CPU | Low | Medium (during imports/exports) |
| Disk | 500 MB (app + db) | Grows with attachments |
WeKan is heavier than Planka (~150 MB) or Kanboard (~100 MB) due to the Meteor.js runtime and MongoDB. For resource-constrained servers (512 MB RAM or less), consider those alternatives instead.
Verdict
For teams that need swimlanes, WIP limits, and Trello-level board management without paying for Trello Premium, WeKan wins on feature completeness. It imports directly from Trello, has a working REST API, supports LDAP/OAuth2, and the 20K+ GitHub stars reflect a large, active community.
The practical choice between WeKan and its competitors: pick Planka for clean Kanban with minimal resources, Kanboard for a lightweight single-board tool, or WeKan when you need the full feature set — swimlanes, custom fields, calendar views, and enterprise authentication.
Frequently Asked Questions
Can I import my Trello boards?
Yes. Export your Trello board as JSON, then go to Import Board in WeKan and select the Trello JSON format. Most data transfers: cards, lists, labels, checklists, and due dates. Attachments are not imported — you’ll need to re-upload those.
Does WeKan support multiple boards per user?
Yes. Each user can create unlimited boards, be a member of boards created by others, and organize boards into collections. There’s no limit on the number of boards, lists, or cards.
Is there a mobile app?
There’s no dedicated mobile app, but WeKan’s web UI is responsive and works on mobile browsers. The PWA support allows you to add it to your home screen on Android and iOS for an app-like experience.
How does WeKan compare to Planka?
Planka is simpler and lighter (~150 MB RAM vs ~500 MB for WeKan). WeKan has more features: swimlanes, WIP limits, calendar view, custom fields, and import from Trello/Jira. Choose Planka for clean Kanban simplicity, WeKan for power features. See our Planka vs WeKan comparison.
Can WeKan integrate with other self-hosted tools?
Yes, through webhooks and the REST API. Common integrations include n8n for workflow automation, Slack/Mattermost for notifications, and LDAP/OAuth2 for SSO with Authentik or Keycloak.
Does WeKan require MongoDB?
Yes. WeKan uses MongoDB as its database backend — there is no alternative database option. The Docker Compose setup includes a MongoDB container. MongoDB’s memory usage (200-500 MB) adds to WeKan’s overall footprint. If you need a lighter Kanban tool, Planka uses PostgreSQL and Kanboard uses SQLite.
Related
Get self-hosting tips in your inbox
Get the Docker Compose configs, hardware picks, and setup shortcuts we don't put in articles. Weekly. No spam.
Comments