How to Self-Host AFFiNE with Docker Compose
What Is AFFiNE?
AFFiNE is an open-source knowledge management platform that combines documents, whiteboards, and databases in a single workspace. Think of it as Notion + Miro — you get rich text documents with block editing, infinite canvas whiteboards for visual thinking, and database views (table, kanban) for structured data. Pages can switch between document and whiteboard modes seamlessly.
Updated March 2026: Verified with AFFiNE v0.26+ Docker images and configurations.
AFFiNE is still pre-1.0 (currently v0.26.3) but is one of the most ambitious self-hosted Notion alternatives in active development, with 45,000+ GitHub stars.
Prerequisites
- A Linux server (Ubuntu 22.04+ recommended)
- Docker and Docker Compose installed (guide)
- 4 GB of RAM minimum (8 GB recommended)
- 20 GB of free disk space
- A domain name (required for remote access)
Docker Compose Configuration
Create a docker-compose.yml file:
services:
affine:
image: ghcr.io/toeverything/affine-graphql:stable
ports:
- "3010:3010"
- "5555:5555"
environment:
NODE_ENV: production
AFFINE_CONFIG_PATH: /root/.affine/config
REDIS_SERVER_HOST: redis
DATABASE_URL: postgresql://affine:${POSTGRES_PASSWORD}@postgres:5432/affine
AFFINE_SERVER_HOST: "0.0.0.0"
AFFINE_SERVER_PORT: "3010"
AFFINE_SERVER_HTTPS: "false"
AFFINE_SERVER_EXTERNAL_URL: ${AFFINE_URL}
volumes:
- affine-config:/root/.affine/config
- affine-storage:/root/.affine/storage
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
command: ['sh', '-c', 'node ./scripts/self-host-predeploy && node ./dist/index.js']
restart: unless-stopped
redis:
image: redis:7.4-alpine
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
restart: unless-stopped
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: affine
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: affine
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U affine -d affine"]
interval: 10s
timeout: 3s
retries: 3
restart: unless-stopped
volumes:
affine-config:
affine-storage:
redis-data:
postgres-data:
Create a .env file:
# PostgreSQL password — use a strong random password
POSTGRES_PASSWORD=change_me_strong_password
# The full external URL where AFFiNE is accessible (no trailing slash)
AFFINE_URL=https://affine.yourdomain.com
Start the stack:
docker compose up -d
Initial Setup
- Wait 1-2 minutes for database migrations to complete
- Navigate to your AFFiNE URL (e.g.,
https://affine.yourdomain.com) - Create an account with email and password
- The first user can access admin features
- Create your first workspace and start editing — toggle between document and whiteboard modes with a click
Configuration
Workspace Structure
AFFiNE organizes content as:
- Workspaces — isolated spaces for different projects or teams
- Pages — individual documents that can be docs or whiteboards
- Sub-pages — nested pages for hierarchical organization
- Databases — structured data views within pages
Document Features
- Block-based editing with slash commands
- Markdown shortcuts (type
#for headings,-for lists) - Code blocks with syntax highlighting
- Tables, callouts, dividers, images
- Inline databases (table, kanban views)
- Page links and backlinks
Whiteboard Features
- Infinite canvas with free-form drawing
- Shapes, connectors, text blocks
- Embed documents within whiteboards
- Real-time collaboration on the canvas
- Hand-drawn style option (Excalidraw-inspired)
Advanced Configuration (Optional)
Email Configuration
For password reset and email verification:
environment:
MAILER_HOST: smtp.example.com
MAILER_PORT: 587
MAILER_USER: your_smtp_user
MAILER_PASSWORD: your_smtp_password
MAILER_SENDER: [email protected]
OAuth Authentication
AFFiNE supports Google OAuth for login:
environment:
OAUTH_GOOGLE_CLIENT_ID: your_google_client_id
OAUTH_GOOGLE_CLIENT_SECRET: your_google_client_secret
Reverse Proxy
Set up a reverse proxy pointing to port 3010. AFFiNE uses WebSocket connections for real-time collaboration, so ensure WebSocket passthrough is enabled.
For detailed setup: Reverse Proxy Setup
Backup
Critical data to back up:
- PostgreSQL database:
docker compose exec postgres pg_dump -U affine affine > affine_backup.sql - Storage volume:
affine-storagecontains uploaded files and assets - Config volume:
affine-configcontains server configuration - Environment file: Your
.envwith credentials
For a complete backup strategy: Backup Strategy
Troubleshooting
”Migration failed” on startup
Symptom: AFFiNE container exits with migration errors.
Fix: This usually means PostgreSQL wasn’t ready when AFFiNE tried to connect. Ensure the health check is working: docker compose ps. Restart AFFiNE after PostgreSQL is healthy: docker compose restart affine.
Whiteboard performance is slow
Symptom: The whiteboard canvas lags or stutters. Fix: Whiteboards are rendered client-side using WebGL. This is a client browser performance issue, not a server issue. Use a modern browser (Chrome/Edge recommended). Reduce the number of elements on a single whiteboard.
WebSocket errors in browser console
Symptom: Real-time collaboration doesn’t work, browser console shows WebSocket errors.
Fix: Ensure your reverse proxy forwards WebSocket connections. For Nginx, add Upgrade and Connection headers. Verify AFFINE_SERVER_EXTERNAL_URL matches your actual URL.
Account creation fails
Symptom: Can’t create a new account.
Fix: Check AFFiNE logs: docker compose logs affine. If SMTP is not configured, some auth flows may fail. Check that PostgreSQL has space and the connection is healthy.
Frequently Asked Questions
Is AFFiNE stable enough for production use?
AFFiNE is pre-1.0 software (currently v0.26.3). It works well for personal use and small team experimentation, but expect occasional bugs and breaking changes between releases. For mission-critical team documentation, Outline or BookStack are more battle-tested. AFFiNE improves with every release and the team ships updates frequently.
How does AFFiNE compare to Notion?
AFFiNE covers the core Notion features — block-based documents, databases (table/kanban views), and workspace organization. Its unique advantage is the integrated whiteboard canvas (edgeless mode), which Notion doesn’t have. AFFiNE lacks some Notion features like formulas, rollups, and the breadth of integrations. The main trade-off is maturity: Notion is polished; AFFiNE is ambitious but rougher around the edges.
Does AFFiNE support real-time collaboration?
Yes. When self-hosted with the Docker Compose setup above, multiple users can edit the same page simultaneously with real-time sync via WebSocket connections. Ensure your reverse proxy forwards WebSocket traffic correctly. Each user creates their own account and gets invited to shared workspaces.
Can I import data from Notion?
AFFiNE supports importing Markdown files. For Notion exports, use Notion’s “Export all workspace content” as Markdown, then import the files into AFFiNE. Some formatting (databases, advanced blocks) may not transfer perfectly and needs manual adjustment.
Why does AFFiNE use the :stable Docker tag instead of a version number?
AFFiNE’s official self-hosted Docker image (ghcr.io/toeverything/affine-graphql:stable) tracks the latest stable release. They don’t publish individual version tags for the self-hosted image. The :stable tag is the recommended approach from the AFFiNE team. Pin your deployment by noting the digest (docker images --digests) if you need reproducibility.
How much storage does AFFiNE need?
The application itself uses about 500 MB. Storage grows with your content — primarily uploaded images, files, and database records stored in PostgreSQL. For a small team (5-10 users), plan for 5-10 GB. The affine-storage volume holds uploaded files and the postgres-data volume holds the database.
Can I use AFFiNE offline?
The desktop app supports offline editing with local-first architecture — changes sync when you reconnect. The self-hosted server acts as the sync hub. Web browser access requires an active connection to your server.
Resource Requirements
- RAM: 1-2 GB for AFFiNE + 500 MB for PostgreSQL + 100 MB for Redis = 2-3 GB total
- CPU: Moderate — Node.js server with database operations
- Disk: ~500 MB for the application, plus user data
Verdict
AFFiNE is the most visually ambitious self-hosted Notion alternative. The combination of documents and whiteboards in one app is unique — no other self-hosted tool does this. If you use Notion and Miro together, AFFiNE aims to replace both.
The caveat: AFFiNE is still pre-1.0 (v0.26.3 as of March 2026). Expect occasional bugs and breaking changes between versions. For production team documentation, Outline or BookStack are more stable. For personal use or teams comfortable with rapidly evolving software, AFFiNE is exciting and improving fast.
Choose AFFiNE if whiteboards are essential to your workflow. Choose AppFlowy for a more mature Notion clone. Choose Outline for stable team documentation.
Related
- Outline vs AFFiNE: Which Should You Self-Host?
- Outline vs Other Notion Alternatives: Compared
- Best Self-Hosted Note Taking
- AppFlowy vs AFFiNE
- Affine vs AppFlowy
- How to Self-Host AppFlowy
- How to Self-Host Outline
- How to Self-Host BookStack
- Replace Notion
- Docker Compose Basics
- Reverse Proxy Setup
- Backup Strategy
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