entrytwo

docs / getting-started / installation.md

Installation

This guide gets a self-hosted entrytwo instance running.

entrytwo is AI-native double-entry accounting with a Git-style data model. The AI posts real journal entries when confident. Full history, branches, blame. Self-hosted.


Deploy: Most production setups use a VPS with Docker and HTTPS. You can also install and run locally (e.g. on a Mac) for real use: same full app, like classic non-cloud accounting software. Runs on your VPS or locally.

Let AI install it for you

Not a terminal person? You can still get this running. Point an AI coding agent at this page (and the repo) and ask it to install entrytwo for you — for example Claude Code, OpenClaw, Hermes, Cursor, or a similar tool that can run commands on your machine or VPS. Share your goal (local Mac vs VPS + domain), paste errors back if something fails, and keep secrets (passwords, API keys) out of chats you do not trust. The steps below remain the source of truth; the agent just walks them with you.

Prerequisites

  • Node.js 20+
  • PostgreSQL 14+ (or use the included Docker Compose)
  • Git
  • Docker & Docker Compose (strongly recommended for production-like setups)

Optional but useful:

  • A domain + reverse proxy (Caddy, Nginx, Traefik) for HTTPS
  • SMTP for magic-link login (and invitation emails)
  • Google and/or Microsoft Entra ID OAuth apps for staff sign-in
  • LLM API key (OpenAI, Anthropic, xAI, etc.)

Quick Start (Recommended - Docker Compose)

  1. Clone and enter the directory:
git clone https://github.com/felixkrusch/entrytwo.git
cd entrytwo/entrytwo_v1
  1. Copy the example environment:
cp .env.example .env
  1. Edit .env and set at minimum:
  • DATABASE_URL (or use the compose defaults)
  • POSTGRES_PASSWORD (required by compose)
  • AUTH_SECRET - generate with: openssl rand -base64 48 (≥ 32 characters)
  • ENCRYPTION_KEY - generate with: openssl rand -hex 32 (64 hex chars; bank feeds / secrets)
  • JOB_RUNNER_SECRET - generate with: openssl rand -base64 48
  • UPDATER_TOKEN - generate with: openssl rand -base64 48 (for the updater sidecar)
  • At least one LLM key if you want AI/chat features (OPENAI_API_KEY, ANTHROPIC_API_KEY, etc.)
  • NEXT_LLM_PROVIDER and NEXT_LLM_MODEL (defaults are usually fine for development)
  1. Start the stack:
docker compose up -d

This starts:

  • app (Next.js on port 3000)
  • db (PostgreSQL)
  • worker (background jobs)
  • updater (isolated sidecar for signed updates - see Self-Hosted Updates)
  • redis
  1. Run migrations and seed:
docker compose exec app npx prisma migrate deploy
docker compose exec app npm run db:seed

(Local non-Docker development can use npx prisma migrate dev instead of deploy.)

  1. Open http://localhost:3000

On first visit with no admin users, you will be able to create the initial ADMIN account.


Environment Variables (Key Ones)

Copy .env.example and fill in:

Required (local or production)

  • DATABASE_URL
  • AUTH_SECRET (≥ 32 characters)
  • POSTGRES_PASSWORD (when using compose)

Required in production (app refuses to start / health stays degraded without these)

  • ENCRYPTION_KEY (64 hex chars)
  • JOB_RUNNER_SECRET
  • AUTH_URL (public origin, e.g. https://books.example.com)
  • AUTH_TRUST_HOST=true (behind nginx/caddy/traefik)
  • At least one real sign-in method:
    • SMTP: SMTP_HOST, SMTP_USER, SMTP_PASS (and ideally SMTP_FROM), and/or
    • Google: GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET, and/or
    • Microsoft: MICROSOFT_ENTRA_ID_ID + MICROSOFT_ENTRA_ID_SECRET (+ issuer)

Strongly recommended

  • UPDATER_TOKEN - shared secret for the updater sidecar
  • LLM key + NEXT_LLM_PROVIDER / NEXT_LLM_MODEL

For production / updates

  • UPDATE_MANIFEST_URL - points at your signed release manifest
  • Cosign settings (COSIGN_IDENTITY, COSIGN_PUBLIC_KEY, etc.)
  • STRIPE_WEBHOOK_SECRET / PayPal secrets (if using processor feeds)

Full list and explanations are in the app .env.example. Production auth go-live: app repo docs/VPS-Auth-Install.md.


Manual Postgres (without Docker)

  1. Create the database:
CREATE DATABASE entrytwo;
CREATE USER entrytwo WITH PASSWORD 'entrytwo_dev_password';
GRANT ALL PRIVILEGES ON DATABASE entrytwo TO entrytwo;
  1. Set in .env:
DATABASE_URL="postgresql://entrytwo:entrytwo_dev_password@localhost:5432/entrytwo"
  1. Install deps, migrate, seed:
npm install
npx prisma migrate dev
npm run db:seed
npm run dev

First Admin Bootstrap

entrytwo is designed so the very first user in a fresh installation becomes an ADMIN.

  • If no ADMIN exists, the sign-in / onboarding flow allows creating one (company language + standard chart of accounts).
  • After the first admin exists, further users join via invitation (Admin → Users). They must sign in with the exact invited email using Google, Microsoft, or magic link.
  • Roles: ADMIN, ACCOUNTANT, or VIEWER.
  • In production, ADMIN must enable TOTP (2FA) before using the app.

See First Steps for the first-login experience.


Authentication (summary)

EnvironmentHow you sign in
Local developmentInstant email (“Continue”) — no SMTP required
ProductionMagic link (SMTP) and/or Google OAuth and/or Microsoft Entra ID

Instant email is disabled when NODE_ENV=production. Configure OAuth redirect URIs to {AUTH_URL}/api/auth/callback/google and .../microsoft-entra-id.


Health and Basic Verification

  • App health: GET /api/health
  • Production should report "ready": true and auth.productionReady: true
  • After docker compose up -d, the app container has a healthcheck on this endpoint

Production VPS (short)

Do these before expecting a green production boot:

  1. SecretsAUTH_SECRET, ENCRYPTION_KEY, JOB_RUNNER_SECRET, POSTGRES_PASSWORD (fresh per install).
  2. Sign-in — full SMTP (SMTP_HOST + USER + PASS) and/or Google/Microsoft OAuth. Instant email is off in production.
  3. Public URLAUTH_URL=https://your.domain, AUTH_TRUST_HOST=true.
  4. DNS — A record for the hostname → VPS IP before HTTPS. If certificates failed while DNS was missing, restart Caddy/nginx after DNS works.
  5. Deploydocker compose up -d --build (entrypoint runs migrations). Confirm /api/healthready: true.
  6. First admin — bootstrap, then TOTP for ADMIN.

RAM: plan ≥ 2 GB for one stack; ~4 GB if you run multiple installs (separate compose projects, ports, and hostnames) on one machine.

Packaging details and troubleshooting: app repo docs/PRODUCTION.md and docs/VPS-Auth-Install.md.


Common Next Steps

  • Read First Steps
  • Set up at least one LLM key and test the chat
  • Configure SMTP and/or OAuth so teammates can sign in
  • (Production) HTTPS, strong secrets, and the VPS auth checklist in the app repo
  • (Later) Bank feeds, updates, and licensing

See also: