Quick Start: From Clone to Running in 5 Minutes

This is the fastest path from a fresh clone to a running Agency site with EN/FR/ES seeded content. If you prefer a deeper dive, read Architecture first, then come back.

Prerequisites

ToolWhyHow to check
Docker 24+ with Compose v2Runs the full stack (Next.js, Directus, Postgres, Redis)docker --version && docker compose version
Node.js 20+Frontend dev server and toolingnode --version
npmFrontend package manager (the frontend uses plain npm, not pnpm)npm --version
GitClone the repogit --version

You do not need Postgres, Redis, or Directus installed locally: they run in containers.

Step 1: Clone and configure

git clone <your-fork-url> saasforge-agency
cd saasforge-agency
cp .env.example .env

Open .env and change at minimum:

  • DIRECTUS_ADMIN_EMAIL / DIRECTUS_ADMIN_PASSWORD: your admin login.
  • POSTGRES_PASSWORD: database password.
  • DIRECTUS_KEY and DIRECTUS_SECRET: generate random UUIDs (uuidgen on macOS/Linux).

Local dev works with the defaults. Never ship the defaults to production.

Step 2: Boot the CMS stack

docker compose up -d --build

What happens on first boot:

  1. Postgres + Redis start and pass healthchecks.
  2. Directus builds from a custom Dockerfile that vendors @directus-labs/seo-plugin.
  3. A one-shot directus-init sidecar runs bootstrap.mjs (creates 18 collections, fields, relations, permissions, and the en / fr / es language rows), then seed.mjs (fills every collection with EN/FR/ES content).
  4. The sidecar exits; Directus keeps running.

Watch the init output:

docker compose logs -f directus-init

When you see Seed complete the CMS is ready. Log into the admin at http://localhost:8055.

Step 3: Boot the frontend

cd frontend
npm install
cp .env.local.example .env.local   # if present, otherwise create it

Create frontend/.env.local with:

NEXT_PUBLIC_DIRECTUS_URL=http://localhost:8055
NEXT_PUBLIC_SITE_URL=http://localhost:3000
NEXT_PUBLIC_DEFAULT_LOCALE=en

No token needed: the Directus Public role has read access on every content collection.

Start the dev server:

npm run dev

Open http://localhost:3000 → English homepage. /fr → French. /es → Spanish.

Step 4: Verify the loop works

  1. In Directus admin, open Marketing → Services and edit the first service's English title.
  2. Save.
  3. Wait up to 60 seconds (Next.js cache revalidation window) and refresh the frontend.
  4. Your edit appears without a rebuild.

If it does: your stack is wired correctly end-to-end.

Common first-run issues

SymptomFix
directus-init exits with ECONNREFUSEDDirectus wasn't healthy yet. docker compose up -d directus-init re-runs it.
Frontend shows fallback copy on every pageNEXT_PUBLIC_DIRECTUS_URL is wrong or Directus isn't reachable from the host. Check curl http://localhost:8055/server/health.
Collections exist but are emptyseed.mjs didn't run. Re-run it: docker compose run --rm directus-init.
CORS errors in the browserSet CORS_ORIGIN=http://localhost:3000 in .env, recreate Directus.
Ports 3000 / 8055 / 5432 busyStop the conflicting process, or change the port mappings in docker-compose.yml.

What to do next