Self-host Joplin Server
updated Sep 2026deployed by usprices checked · Jul 2026Install verified on Ubuntu 26.04 · Sep 2026 · how we test
We earn commissions when you shop through the links below. Full disclosure →
The self-hosted sync server for the Joplin note-taking apps, storing notes in PostgreSQL and adding note sharing and multi-user accounts. It is free for personal, non-commercial use under its own license; commercial use needs a separate license.
Key facts
CategoryNotes
LicenseJoplin Server Personal Use License
StackTypeScript, Node.js, PostgreSQL
Min RAM1024 MB
Official imageyes
Measured idle RAM348 MB
Difficulty
What you need
- Any VPS with at least 1024 MB of RAM
- A domain you control — most self-hosted setups need HTTPS in front of them
- Under an hour if you've used Docker before
Where to host itaffiliate disclosure
Hetzner Cloudrun it on
From $23.59/mo · 2 vCPU / 4 GB / 80 GB · EU + USKamaterafree trial
From $4/mo · 1 vCPU / 1 GB / 20 GB · US + EU + AsiaDigitalOceanalso works on
From $6/mo · 1 vCPU / 1 GB / 25 GB · US + EU + AsiaPaid link — we earn a commission if you shop through it.
Install
Run these commands on your server:
# Joplin Server + PostgreSQL, trimmed from upstream's docker-compose.server.yml
mkdir joplin && cd joplin
# APP_BASE_URL must be the exact URL your browser and Joplin apps use: Joplin Server rejects requests from any other origin ("Invalid origin"). Replace SERVER_IP with your server's public IP or domain
cat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -hex 16)
APP_BASE_URL=http://SERVER_IP:22300
EOF
cat > docker-compose.yml <<'EOF'
services:
db:
image: postgres:16
restart: unless-stopped
volumes: ["./data/postgres:/var/lib/postgresql/data"]
environment: { POSTGRES_USER: joplin, POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}", POSTGRES_DB: joplin }
app:
image: joplin/server:latest
restart: unless-stopped
depends_on: [db]
ports: ["22300:22300"]
environment: { APP_PORT: 22300, APP_BASE_URL: "${APP_BASE_URL}", DB_CLIENT: pg, POSTGRES_HOST: db, POSTGRES_PORT: 5432, POSTGRES_USER: joplin, POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}", POSTGRES_DATABASE: joplin }
EOF
docker compose up -d
# open http://SERVER_IP:22300 — sign in as admin@localhost / admin and change the password immediatelyMore in Notes
Notes
AFFiNE
TypeScriptNode.jsRustPostgreSQLRedis
easyRead guide →
Notes
HedgeDoc
Node.jsTypeScriptPostgreSQL
easyRead guide →
Notes
Memos
GoReactSQLite
easyRead guide →
Notes
SilverBullet
RustTypeScriptLua
easyRead guide →