[{"data":1,"prerenderedAt":123},["ShallowReactive",2],{"$fn1i9cpzrd5qi":3},{"site":4,"app":16,"alternatives":74,"compose":118,"log":119,"changelog":120},{"hourly_rate_usd":5,"break_even_window_mo":6,"reference_env":7,"attribution":8},20,18,"Fresh Debian 12, Docker + Compose preinstalled, 2 GB RAM \u002F 2 vCPU ($5-class VPS)",{"caniselfhostit":9},{"name":10,"url":11,"repo":12,"license":13,"author":14,"note":15},"caniselfhostit.com","https:\u002F\u002Fcaniselfhostit.com","https:\u002F\u002Fgithub.com\u002Fcaniselfhostit\u002Fcaniselfhostit","MIT","Jashanpreet Singh","Capability data (app → replacement pairings, pricing snapshots) seeded from this dataset. They answer 'can you run it, and how' — go there for guided installs.",{"id":17,"name":18,"domain":19,"category":20,"price_usd_mo":21,"price_plan":22,"price_unit":23,"price_source":24,"price_checked":25,"jobs":26,"verdict":33,"verdict_reason":34,"what_you_lose":35,"alternatives":40,"economics":43,"hardware_tier":47,"provenance":48,"verified":51,"compose":59,"links":63,"notes":65,"derived":66},"notion","Notion","notion.com","notes-wikis",12,"Plus","per-seat","https:\u002F\u002Fwww.notion.com\u002Fpricing","2026-08-05",[27,28,29,30,31,32],"docs & wiki with nested pages","full-text search","real-time collaboration","databases with views, relations and rollups","mobile apps","public sharing links","KINDA","The docs half moves in an evening and the math is per-seat — but Notion's databases and mobile apps don't move at all. Worth it if you write more than you rollup.",[36,37,38,39],"Databases: views, relations, rollups — Outline has none of it, and that's half of many workspaces","Native mobile apps (Outline's mobile web is fine, not great)","Notion AI and the template ecosystem","Sign-in needs an auth provider you run or configure (magic-link SMTP or OIDC)",[41,42],"outline","docmost",{"vps_share_usd_mo":44,"storage_usd_mo":45,"maint_min_mo":46},1.5,0.2,30,"old-laptop",{"capability_seed":49,"decision_layer":50},"caniselfhostit","original",{"by":52,"at":53,"protocol":54,"setup_min":55,"assistant":56,"evidence":57,"what_broke":60},"zernonia","2026-08-10","v1",75,"claude-code",[58,59],"logs\u002Fnotion-outline.md","compose\u002Fnotion-outline.yml",[61,62],"maildev (the first mail catcher we tried) crash-loops wherever IPv6 is disabled — it insists on binding '::'; swapped to mailpit","Outline boots healthy without SMTP but magic-link sign-in silently goes nowhere — the compose ships mailpit so the workflow is completable locally",{"caniselfhostit":64},"https:\u002F\u002Fcaniselfhostit.com\u002Fnotion","At one seat the time cost eats the saving; at 3+ seats (Plus is per-seat) the math flips fast. The database gap is the real decision, not the money.",{"hourly_rate_usd":5,"self_host_cost_usd_mo":67,"net_saving_usd_mo":68,"setup_cost_usd":69,"break_even_months":70,"break_even_date":71,"markup_index":72,"primary_abandoned":73,"verdict_stale":73},11.7,0.3,25,83.33,"2033-07-21",1.03,false,[75,100],{"id":41,"name":76,"tagline":77,"repo":78,"site":79,"docker_image":80,"license":81,"category":20,"resources":82,"provenance":87,"notes":89,"metrics":90},"Outline","A fast, collaborative wiki that covers the half of Notion most teams actually live in.","outline\u002Foutline","https:\u002F\u002Fwww.getoutline.com","outlinewiki\u002Foutline","BUSL-1.1",{"ram_min_mb":83,"disk_gb":84,"arm64":85,"containers":86,"external_db":85},1024,10,true,3,{"capability_seed":88,"decision_layer":50},null,"Requires an auth provider: OIDC\u002FSlack\u002FGoogle, or magic-link email via SMTP. Our compose ships maildev so the workflow is completable locally.",{"id":41,"stars":91,"last_commit":92,"latest_release":93,"docker_pulls":97,"open_issues":98,"fetched_at":99},40072,"2026-08-11T02:46:02Z",{"tag":94,"published_at":95,"url":96},"v1.9.2","2026-07-21T01:34:44Z","https:\u002F\u002Fgithub.com\u002Foutline\u002Foutline\u002Freleases\u002Ftag\u002Fv1.9.2",13848755,71,"2026-08-11T03:55:28.837Z",{"id":42,"name":101,"tagline":102,"repo":103,"site":104,"license":105,"category":20,"resources":106,"provenance":108,"metrics":109},"Docmost","Spaces, nested pages and an editor two people can type in at once, with every word in a Postgres you can dump.","docmost\u002Fdocmost","https:\u002F\u002Fdocmost.com","AGPL-3.0",{"ram_min_mb":107,"disk_gb":84,"arm64":85,"containers":86,"external_db":85},2048,{"capability_seed":49,"decision_layer":50},{"id":42,"stars":110,"last_commit":111,"latest_release":112,"docker_pulls":88,"open_issues":116,"fetched_at":117},21316,"2026-08-11T00:45:09Z",{"tag":113,"published_at":114,"url":115},"v0.95.0","2026-07-03T11:47:42Z","https:\u002F\u002Fgithub.com\u002Fdocmost\u002Fdocmost\u002Freleases\u002Ftag\u002Fv0.95.0",316,"2026-08-11T03:55:19.156Z","# Outline — the docs\u002Fwiki half of Notion. THE worked example (see logs\u002Fnotion-outline.md).\n# Sign-in is magic-link email: mailpit catches the mail locally so the core workflow is\n# completable without any external SMTP or OIDC provider. In production point SMTP_* at a real\n# mailbox (or configure OIDC) and put the whole thing behind TLS.\n# Secrets below are throwaway test values — generate your own: openssl rand -hex 32\nservices:\n  outline:\n    image: outlinewiki\u002Foutline:latest\n    container_name: outline\n    restart: unless-stopped\n    depends_on:\n      postgres:\n        condition: service_healthy\n      redis:\n        condition: service_healthy\n    environment:\n      NODE_ENV: production\n      URL: http:\u002F\u002Flocalhost:3000\n      PORT: \"3000\"\n      SECRET_KEY: 5f31f5ad9e6f6ff0c1b52c11a03f5f4b7b1b4a4f3f2ce9d6be2c8f4d7a91d2e3\n      UTILS_SECRET: 8d2b1f9c4a7e6d5b3c2a1f0e9d8c7b6a5f4e3d2c1b0a9f8e7d6c5b4a3f2e1d0c\n      DATABASE_URL: postgres:\u002F\u002Foutline:outline@postgres:5432\u002Foutline\n      PGSSLMODE: disable\n      REDIS_URL: redis:\u002F\u002Fredis:6379\n      FILE_STORAGE: local\n      FILE_STORAGE_LOCAL_ROOT_DIR: \u002Fvar\u002Flib\u002Foutline\u002Fdata\n      SMTP_HOST: mailpit\n      SMTP_PORT: \"1025\"\n      SMTP_FROM_EMAIL: outline@localhost.test\n      SMTP_SECURE: \"false\"\n    ports:\n      - \"3000:3000\"\n    volumes:\n      - outline-data:\u002Fvar\u002Flib\u002Foutline\u002Fdata\n    healthcheck:\n      test: [\"CMD-SHELL\", \"node -e \\\"fetch('http:\u002F\u002Flocalhost:3000\u002F_health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\\\"\"]\n      interval: 5s\n      timeout: 5s\n      retries: 36\n      start_period: 30s\n\n  postgres:\n    image: postgres:16-alpine\n    restart: unless-stopped\n    environment:\n      POSTGRES_USER: outline\n      POSTGRES_PASSWORD: outline\n      POSTGRES_DB: outline\n    volumes:\n      - outline-pg:\u002Fvar\u002Flib\u002Fpostgresql\u002Fdata\n    healthcheck:\n      test: [\"CMD-SHELL\", \"pg_isready -U outline\"]\n      interval: 5s\n      timeout: 5s\n      retries: 12\n\n  redis:\n    image: redis:7-alpine\n    restart: unless-stopped\n    healthcheck:\n      test: [\"CMD-SHELL\", \"redis-cli ping | grep PONG\"]\n      interval: 5s\n      timeout: 5s\n      retries: 12\n\n  mailpit:\n    # (maildev crashes where IPv6 is disabled — it insists on binding \"::\". Mailpit doesn't.)\n    image: axllent\u002Fmailpit:latest\n    restart: unless-stopped\n    ports:\n      - \"1080:8025\" # web UI to read the magic-link mail\n    healthcheck:\n      test: [\"CMD\", \"\u002Fmailpit\", \"readyz\"]\n      interval: 5s\n      timeout: 5s\n      retries: 12\n\nvolumes:\n  outline-data:\n  outline-pg:\n","# Timed setup log: Notion → Outline\n\n**Protocol:** v1 · **Verified by:** zernonia · **Date:** 2026-08-10\n**Assistant:** claude-code (allowed & stated — protocol v1 assumes an AI sysadmin)\n**Environment:** containerized runner, 2 vCPU class, Debian-based, Docker 29.3 \u002F Compose v5.1 preinstalled\n\n> This is THE worked example — the template every contributor copies. Format: environment,\n> timeline, measurements, what broke. Honest numbers or nothing.\n\n## Timeline (wall clock)\n\n| Step | Time |\n|---|---|\n| Read Outline's docker docs, draft compose (postgres + redis + outline + mail catcher) | 22 min |\n| Generate secrets (`openssl rand -hex 32` × 2), first `docker compose up` | 4 min |\n| **Boot #1 failed** — mail catcher crash-looping (see What broke) | 12 min to diagnose |\n| Swap maildev → mailpit, re-up | 3 min |\n| **Boot #2: all 4 services healthy in 44 s (measured, `compose up --wait`)** | 1 min |\n| Core workflow: magic-link sign-in via mailpit UI, create doc, edit, search finds it | 18 min |\n| Cleanup, re-run from scratch to confirm reproducibility | 15 min |\n| **Total: ~75 min** | |\n\n## Measurements\n\n- `docker compose up --wait` → healthy: **44 s** (clean volumes, images cached)\n- Containers: 4 (outline, postgres:16, redis:7, mailpit)\n- Idle RAM after sign-in: outline ~480 MB + postgres ~40 MB + redis ~5 MB — 2 GB box is comfortable, 1 GB is not with anything else running\n\n## What broke\n\n1. **maildev crashes where IPv6 is disabled** (`listen EAFNOSUPPORT: address family not\n   supported :::1025`). Many CI runners and some VPS images disable IPv6; maildev insists on\n   binding `::`. Swapped to **mailpit**, which binds IPv4 fine and has a `readyz` probe.\n2. **Outline without SMTP is a locked door**: it boots healthy but magic-link sign-in silently\n   goes nowhere until SMTP_* points somewhere real. The compose ships mailpit so the workflow\n   is completable locally; in production use a real mailbox or OIDC.\n\n## Verdict-relevant notes\n\n- The docs\u002Fwiki\u002Fsearch\u002Fcollab jobs all work. There is no databases feature — Notion's\n  views\u002Frelations\u002Frollups have no equivalent here. That gap, not the setup, drives the KINDA.\n- Notion import exists (Markdown\u002FHTML export → import) but attachments need re-linking.\n",[121],{"date":53,"app":17,"from":88,"to":33,"reason":122},"Initial verdict: docs half moves in an evening, databases and mobile don't move at all.",1786459422051]