Start · Product guide

Self-host with Docker Compose

Run the supported community topology, check readiness, close bootstrap signup, and recover safely from an upgrade.

12 min readSource on GitHub ↗

Supported topology

Docker Compose is the canonical v0.1 installation. It runs web, API and local MCP endpoint, PostgreSQL, MinIO, migrations, and a bounded six-hour scheduler in your infrastructure.

A running Community instance does not call blogfactory.io. Content and credentials go only to the AI, CMS, and Google integrations you configure. Until the first versioned GHCR release is published, install and update BlogFactory by building from the public source repository.

Docker Compose
Canonical supported installation
Railway
Guided topology; use the Railway runbook and acceptance path
Vercel
Expert topology only; not guided self-hosting
Netlify
Unsupported: it cannot provide the complete API, worker, and data topology

Install and start

You need Docker Engine with Compose v2, at least 4 GB RAM for a small instance, and an HTTPS reverse proxy before exposing a public domain. Set BLOGFACTORY_URL to that public origin and ADMIN_EMAILS to the first administrator address.

Terminal
git clone https://github.com/BlogFactoryHQ/blogfactory.git
cd blogfactory
cp .env.self-host.example .env
# Fill each required blank and set ADMIN_EMAILS
docker compose config --quiet
docker compose build --pull api web
docker compose up -d
curl --fail http://localhost:8080/api/ready

Close bootstrap signup

Create the first account with an address in ADMIN_EMAILS. Once that administrator can sign in, turn off signup. To add a later isolated user, enable signup temporarily, approve the pending account in the admin UI, then disable it again.

After the first administrator signs in
# Set BLOGFACTORY_ALLOW_SIGNUP=false in .env
docker compose up -d --no-deps --force-recreate api
curl --fail http://localhost:8080/api/auth/config

Health, readiness, and upgrade recovery

/api/health is process liveness. /api/ready returns 200 only when PostgreSQL and the S3 bucket are reachable; it returns a generic 503 without exposing dependency details.

Before every upgrade, back up PostgreSQL and MinIO. Application rollback can restore a prior image, but it cannot safely reverse an incompatible schema: restore the matching PostgreSQL dump and object-store copy instead.

Acceptance checks
curl --fail http://localhost:8080/api/health
curl --fail http://localhost:8080/api/ready
curl -i http://localhost:8080/mcp
docker compose ps
docker compose logs --tail=100 api scheduler