Skip to content

Architecture

Forge is a control plane that runs on your server and manages a Docker-based deployment runtime alongside a transactional email platform.

  • The Forge app stores projects, services, deployments, domains, environment variables, email identities, automations, recipient lists, forwarding rules, backup metadata, import sources, and users — all in SQLite.
  • Docker runs application containers, worker containers, database containers, and short-lived helper containers for builds, backups, imports, restores, and updates.
  • BuildKit builds source services through Railpack.
  • Caddy routes HTTP traffic, handles certificates, serves the control plane hostname, serves generated service hostnames (from global or per-project root domains), and routes custom domains.
  • The runtime network lets app services and database services talk privately inside Docker.
  • DATA_DIR stores Forge state such as static sites, database backups, Postgres TLS assets, email logs, system settings, update history, maintenance history, and generated Caddy config.

Forge Email runs as an integrated subsystem sharing the same SQLite database and auth layer:

  • Outbound SMTP uses nodemailer to send via any SMTP server — Gmail, Postfix, Mailcow, or your own.
  • Automation scheduler polls every 5 seconds, picks up due drip-sequence runs, renders merge templates, and sends via the SMTP engine.
  • Broadcast worker processes recipient lists in batches with configurable concurrency and throttling.
  • Inbound SMTP server (smtp-server + mailparser) listens on port 25 (or 2525), receives mail for verified domains, applies spam filtering, matches forwarding rules, and relays to destinations via the outbound engine.

All email features are gated behind FORGE_EMAIL_ENABLED and can run independently of the deployment features.

For a web service, public traffic reaches Caddy first. Caddy routes the request to the service’s active container port. Forge updates that active port during successful deployments, then reloads Caddy.

For static output, Caddy serves files from Forge’s static site directory.

For workers, there is no public route. Forge starts the container and checks that the process stays running.

Git services are cloned from GitHub or a direct Git URL. Forge passes the selected branch, root directory, install command, build command, start command, runtime mode, internal port, and static output setting into the build and deployment flow.

Source services use BuildKit and Railpack. Docker image services skip the source build and pull the configured image directly.

Database services run as Docker containers with persistent Docker volumes. Forge provisions PostgreSQL, TimescaleDB, MySQL, Redis, MongoDB, ClickHouse, Qdrant (vector database), and MinIO (S3-compatible object storage). Forge creates connection variables, generated public hostnames when a root domain exists, and Caddy routes for public database access where supported.

PostgreSQL-family services can enable logical replication. Forge also creates Postgres TLS assets for public database hostnames.

Database backups are created locally first. Depending on the selected storage target, Forge then keeps the local disk file, uploads it to Cloudflare R2, or does both.

Enabled automatic schedules run in the background for daily, weekly, or monthly backups. Manual backups run from the database Backups tab.

Forge supports two migration paths:

  • Railway import, which reads Railway projects and recreates supported services in Forge.
  • Forge migration bundles, which export a whole Forge instance into an encrypted bundle and restore it into another server.

Those paths solve different problems. Railway import translates a Railway project into Forge services. Forge bundles move a Forge instance between servers.