Deploy AFFiNE — Self-Hosted Notion & Miro Alternative
Self-host AFFiNE — docs, whiteboards & databases in one canvas
pgvector
Just deployed
/var/lib/postgresql
Redis
Just deployed
/data
Affine
Just deployed
/root/.affine
Deploy and Host AFFiNE on Railway
AFFiNE is an open-source, all-in-one workspace that combines documents, whiteboards, and databases on a single canvas — a privacy-first, self-hostable alternative to Notion and Miro (with a bit of Linear). Write docs, sketch on an infinite whiteboard, and build databases and Kanban boards, all in one tool, on infrastructure you own. This template deploys AFFiNE with PostgreSQL, Redis, and the required migration step wired as a pre-deploy — so the database is migrated before the app starts and your workspace comes up clean on the first deploy.
What This Template Deploys
| Service | Purpose |
|---|---|
| AFFiNE Server | The workspace app — docs, whiteboards, and databases (NestJS) on port 3010 |
| PostgreSQL | Workspaces, documents, users, and all content |
| Redis | Caching and real-time collaboration state |
All connect over Railway's private network. A database migration runs as a pre-deploy step before the server boots, and persistent volumes hold uploaded files and configuration — so the workspace starts migrated and your data survives redeploys.
About Hosting
AFFiNE is a capable multi-service app, and a couple of specifics decide whether it deploys cleanly — both handled here.
The migration must run before the server — handled as a pre-deploy. AFFiNE ships a separate migration step (self-host-predeploy.js) that has to complete before the main server starts; if the server boots against an unmigrated database, it fails. This template runs that migration as Railway's pre-deploy command, so the schema is prepared first and the server comes up cleanly — this is the "auto migrations" that make upgrades and first deploys reliable instead of manual.
Three services, wired over the private network. AFFiNE needs PostgreSQL for data and Redis for caching and real-time collaboration, connected through DATABASE_URL and REDIS_SERVER_HOST. This template wires all three via Railway references — and uses a current Railway environment so Redis's internal networking resolves correctly (a known requirement for AFFiNE's backend to find Redis).
Set the external URL to your domain. AFFINE_SERVER_EXTERNAL_URL must be your Railway (or custom) public domain, or shared links, invitations, and internal navigation resolve to the wrong host. This template wires it to your domain so links and sharing work correctly from the start.
Create your admin at /admin. After deploy, open your Railway URL at /admin to create the first administrator account, which owns the instance. From there, invite your team and start creating workspaces, docs, and whiteboards.
Your data and uploads persist. Documents, workspaces, and users live in PostgreSQL, while uploaded files and configuration live on volumes at AFFiNE's storage and config paths — all surviving redeploys. PostgreSQL and blob storage are the components to back up.
One canvas, three tools. AFFiNE's edge is that docs, whiteboards, and databases aren't separate apps — a page can be a document, an infinite canvas, or a table view of the same content, so you plan, write, and diagram in one place, without switching tools or paying two subscriptions.
Typical cost: ~$10–15/month on Railway for the three services — a solo workspace fits comfortably in about 1 GB RAM, while teams with many concurrent editors should raise the server and Postgres memory. AFFiNE is free and open source.
How It Compares
| AFFiNE (self-hosted) | Notion | Miro | Obsidian | |
|---|---|---|---|---|
| Docs | Yes | Yes | Limited | Yes |
| Whiteboard | Yes (built-in) | Limited | Yes | Plugin |
| Databases | Yes | Yes | No | Plugin |
| Cost model | Flat infra | Per seat | Per seat | Free/local |
| Data ownership | Full — your infra | Vendor | Vendor | Local files |
| Self-hostable | Yes | No | No | Local only |
Notion is polished but per-seat and cloud-only, with a weak whiteboard. Miro is a great whiteboard but not a docs or database tool, and also per-seat. Obsidian is local-first but a single-user notes app without real-time collaboration or built-in boards. AFFiNE's edge is combining docs, whiteboards, and databases on one canvas — self-hosted, collaborative, and free of per-seat fees, with your entire workspace on infrastructure you own.
Deploy in Under 5 Minutes
- Click Deploy on Railway — AFFiNE, PostgreSQL, and Redis build, and the migration runs first (~4 minutes)
- Confirm
AFFINE_SERVER_EXTERNAL_URLis set to your Railway domain - Wait for the pre-deploy migration to finish and the server to come up
- Open your Railway URL at
/adminand create your administrator account - Create a workspace and start writing docs, drawing on whiteboards, and building databases
Invite your team from the admin panel — everyone works from one self-hosted URL.
Common Use Cases
- Team wiki and knowledge base — docs plus whiteboard-driven RFCs in one self-hosted workspace
- Product design hub — combine docs, diagrams, and feature databases in a single view
- Research and study notes — linked references and visual study maps on an infinite canvas
- Async team planning — docs, boards, and Kanban in one URL for distributed teams
Configuration
| Variable | Required | Description |
|---|---|---|
AFFINE_SERVER_EXTERNAL_URL | Required | Your public domain — so links, sharing, and navigation resolve |
DATABASE_URL | Auto-injected | PostgreSQL connection via Railway reference |
REDIS_SERVER_HOST | Auto-injected | Redis host for caching and collaboration |
AFFINE_INDEXER_ENABLED | Pre-set | Indexer setting per the official compose defaults |
| Storage volumes | Pre-set | Persistent volumes for uploads and configuration |
PORT | Pre-set | 3010 — the AFFiNE server |
Migration runs before the server — automatically. AFFiNE's migration step runs as Railway's pre-deploy command, so the database is prepared before the app starts. Without this ordering, the server fails against an unmigrated database — the template handles it.
Set the external URL and persist the volumes.
AFFINE_SERVER_EXTERNAL_URLmust be your domain or sharing breaks. Documents live in Postgres and uploads on volumes — back up both.
Dependencies for AFFiNE Hosting
- Railway account — ~$10–15/month for the three services, more for large teams
- PostgreSQL and Redis (both included and wired)
- Persistent volumes for uploaded files and configuration (included)
- A Railway environment recent enough for Redis internal networking (post-Oct 2025)
Deployment Dependencies
- AFFiNE GitHub Repository
- AFFiNE Self-Host Documentation
- AFFiNE Official Site
- Railway Private Networking
Implementation Details
The template mirrors AFFiNE's official Compose architecture on Railway: the AFFiNE server (ghcr.io/toeverything/affine:stable, a NestJS application on port 3010), a PostgreSQL database, and Redis, all connected over the private network through DATABASE_URL and REDIS_SERVER_HOST. Critically, AFFiNE requires a migration job (self-host-predeploy.js) to run to completion before the server starts — in Compose this is a dedicated affine_migration service, and here it is implemented as Railway's pre-deploy command, so the schema is prepared before the app boots rather than the server failing against an unmigrated database.
AFFINE_SERVER_EXTERNAL_URL is set to the Railway domain so shared links, invitations, and internal navigation resolve correctly. Because AFFiNE's backend locates Redis over internal networking, a current Railway environment (post-October 2025) is used so that connection resolves. Uploaded files and configuration persist on volumes at AFFiNE's storage and config locations, while workspaces, documents, and users persist in PostgreSQL; both Postgres and blob storage are the components to back up. Auto-updates are available but disabled by default so upgrades happen on your schedule around release notes.
Frequently Asked Questions
Why does AFFiNE need a migration step? AFFiNE's server must run against a migrated database, so a migration job has to complete before it starts. This template runs that as Railway's pre-deploy command, so first deploys and upgrades come up cleanly instead of failing against an unmigrated schema.
Does my data persist? Yes — documents, workspaces, and users live in PostgreSQL, and uploaded files on volumes. Both survive redeploys; back up Postgres and blob storage to preserve your whole workspace.
How do I create my admin account? Open your Railway URL at /admin after deploy to create the first administrator, who owns the instance. From there you invite your team and create workspaces.
Is it really a Notion and Miro replacement? Yes — AFFiNE combines docs, an infinite whiteboard, and databases on one canvas, so it covers Notion's writing and databases plus Miro's visual collaboration in a single self-hosted tool.
Why Deploy AFFiNE on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying AFFiNE on Railway you get an all-in-one workspace with the hard parts solved — PostgreSQL and Redis wired, the migration run as a pre-deploy so the app starts clean, the external URL set, and automatic HTTPS. Docs, whiteboards, and databases on one canvas, self-hosted on infrastructure you own.
Template Content
pgvector
pgvector/pgvector:pg18Redis
redis:8.2AFFINE_ADMIN_EMAIL
Create Bootstrap admin email
AFFINE_ADMIN_PASSWORD
Create Admin password (alteast 1 uppercase + 2 digits + 2 specials)