Skip to main content

Overview

Atlas is open source and designed to be self-hosted. This guide covers the recommended deployment topology and configuration.
Most users don’t need to self-host. The hosted version at atlas.rebuildingus.org is the easiest way to use Atlas. Self-hosting is for organizations that need full control over their data, want to run Atlas on their own infrastructure, or want to contribute to development.
The simplest production setup is:
  • Vercel for the web app (app/)
  • A small VM for the API (api/) running in Docker
  • SQLite on a persistent volume for data storage
This is the architecture Atlas uses in production. It’s cost-effective, easy to operate, and works well for a single operator. Why this split:
  • Vercel handles the frontend well and gives you automatic deploys and rollbacks
  • The API uses SQLite and runs background discovery work, which is better suited to a persistent VM
  • This is usually cheaper and simpler than putting everything on one platform

Quick start

1. Clone the repository

2. Run the bootstrap script

This creates your .env.production file, generates auth secrets, and sets up the initial configuration. Follow the prompts to fill in required values.

3. Configure Stripe billing

Atlas uses Stripe Checkout, Stripe Billing, coupons, and webhooks for Pro, Team, and Research Pass access. The bootstrap scripts create the canonical products, prices, discount coupons, and webhook endpoints, then write the generated Stripe catalog to the correct env files. Local development uses Stripe test mode. Keep Stripe’s webhook forwarder open while testing Checkout. The listener reads the local app origin from .env, defaults to https://atlas.localhost, and forwards Stripe billing events to /api/stripe/webhook:
Hosted staging uses Stripe test mode and Vercel Preview env vars:
Hosted production uses Stripe live mode and Vercel Production env vars:
To create the live key, open Stripe Dashboard in Live mode, go to Developers > API keys > Restricted keys, create a key named Atlas Production Billing, set these permissions, reveal the key once, and run setup with that rk_live_... value:
  • Read: Accounts v2, shown by Stripe errors as Basic Business Contact Information (accounts_kyc_basic_read)
  • Write: Products, Prices, Coupons, Customers, Checkout Sessions, Webhook Endpoints
Accounts v2: Read lets bootstrap show the friendly Stripe account name. If the restricted-key UI does not expose that permission, bootstrap can continue after Stripe returns the account ID and you confirm it is the intended account. A live secret key also works, but restricted keys are the default production path. Stripe CLI OAuth keys are enough for local and staging checks, but production bootstrap should use a Dashboard-created live API key. Test-mode IDs cannot be used in production. The catalog is intentionally small: Pro, Team, Team Seat, and Research Pass. Discounts are Pro-only coupons. Verified students pay $12.80 every four months; independent creators and journalists get 50% off Pro monthly or annual billing. Team pricing stays the same for every organization. The verification commands check products, prices, coupon scope, hosted Vercel env presence, and hosted webhook endpoint drift. See the repository’s docs/deployment/stripe-billing.md runbook for the exact product catalog, discount policy, and verification commands.

4. Choose a deployment path

Environment variables

Required

Authentication

Email

Discovery

Persistent storage

Both SQLite databases (content and auth) must live on persistent storage that survives container restarts. In Docker, this means a named volume or a mounted host directory.

Backups

At minimum:
  1. Copy or snapshot the SQLite files on a schedule
  2. Store backups somewhere other than the VM itself
  3. Test a restore into a fresh volume
If you skip the restore test, you don’t know whether your backup is useful.

Verification checklist

After every deployment, check these in order:
  1. GET /health returns 200
  2. The app loads and can list entities
  3. An entity detail page loads correctly
  4. Magic-link sign-in succeeds
  5. API key creation succeeds and X-API-Key access works
  6. Creating a discovery run succeeds
  7. Restarting the API does not lose data

Adapting for other hosts

The Vercel + Docker topology maps to most hosting providers: The key requirements:
  • The app needs ATLAS_PUBLIC_URL and ATLAS_SERVER_API_PROXY_TARGET
  • The API needs DATABASE_URL pointing to persistent SQLite storage
  • Both services need the same ATLAS_AUTH_INTERNAL_SECRET
  • The API container must support long-running background tasks (discovery pipeline)
Serverless platforms (AWS Lambda, Vercel Functions) are not suitable for the API because discovery runs are long-lived background tasks. Use a persistent container or VM.

What’s next

API guide

Understand the API you’re hosting.

Contributing

Help improve Atlas.