Dev loop
The one question every new HiveCFM dev asks by their second day: “I changed a file — do I have to docker compose down and rebuild?”
Short answer: almost never. The recommended setup runs the
infrastructure (Postgres, Redis, MinIO, MailHog, Superset) in
Docker, and the apps (Next.js core, Go Hub) natively with
hot-reload. Code changes reload in under a second. You only rebuild
Docker when you touch Dockerfile, docker-compose.yml, or an
.env file consumed by a container.
The default mode
This is what you should run every morning. It matches what the Local development cheat sheet and Run it locally onboarding page both walk you through — same commands, same ports.
Bring infra up in Docker
cd ~/AG-DEV/hivecfm-core
docker compose -f docker-compose.yml -f docker-compose.dev-ports.yml up -dThe dev-ports overlay exposes Postgres on 5433 and Redis on
6380 so your native apps can reach them. Leave this running all
day — infrastructure changes are rare.
Run the Next.js core natively
pnpm devHot-reload at http://localhost:3001. Any change under
hivecfm-core/apps/web/ reloads automatically.
(Optional) Run the Go Hub natively
cd ~/AG-DEV/hivecfm-hub
go run ./cmd/apiServes http://localhost:8090. Restart the process manually after
Go code changes — or install air
for a watcher-based auto-restart. The Docker-Hub is fine for most
people; only run natively when you are actively editing Hub code.
Do I need to rebuild?
Use this as a lookup. “Native” means you are running the app with
pnpm dev / go run; “Docker” means the app is coming from
docker compose up.
| You changed… | Rebuild Docker? | What to do instead |
|---|---|---|
Next.jsNext.jsReact framework used by HiveCFM Core. Handles routing, server rendering, and API routes in one bundle. / ReactReactThe component-based UI library every HiveCFM frontend is written in. Components are TypeScript functions returning JSX. code under hivecfm-core/apps/web | No | pnpm dev auto-reloads |
Go code under hivecfm-hub/ (native mode) | No | Restart go run ./cmd/api — or use air for true hot-reload |
Go code under hivecfm-hub/ (Docker mode) | Yes | docker compose up -d --build hub |
.env.local / .env read by a native app | No | Restart the pnpm dev / go run process |
.env consumed by a Docker service | Yes | docker compose down && docker compose up -d |
docker-compose.yml | Yes | docker compose down && docker compose up -d --build |
Dockerfile for one service | Yes | docker compose up -d --build <service> |
PrismaPrismaThe TypeScript ORM HiveCFM uses to talk to Postgres. The schema lives at packages/database/schema.prisma. schema (schema.prisma) | No rebuild, but migrate | pnpm run db:migrate |
package.json / pnpm-lock.yaml (native) | No | pnpm install then restart the dev process |
go.mod / go.sum (native) | No | go mod tidy then restart |
Shared packages under hivecfm-core/packages/* | No | Turborepo re-bundles; pnpm dev picks it up |
Migration files under hivecfm-core/packages/database/migrations/ | No | pnpm run db:migrate |
The table assumes Mode 1 (infra-in-Docker, apps-native). If you chose Mode 2 (everything in Docker), treat all app-code rows as “rebuild required” — that is the price of Mode 2’s simplicity.
The three modes
Pick one per session. Most days you want Mode 1.
Mode 1 — infra in Docker, apps native (recommended)
When: daily development on Next.jsNext.jsReact framework used by HiveCFM Core. Handles routing, server rendering, and API routes in one bundle. or HubHubThe Go service that owns background processing, integrations, and the admin API. Sibling to Core. code. Fastest feedback loop.
# infrastructure
cd ~/AG-DEV/hivecfm-core
docker compose -f docker-compose.yml -f docker-compose.dev-ports.yml up -d
# core, in a second shell
pnpm dev # hot-reload on :3001
# hub (optional), in a third shell
cd ~/AG-DEV/hivecfm-hub && go run ./cmd/api # on :8090Caveat: you need Node 22 + pnpmpnpmThe package manager HiveCFM uses instead of npm or yarn. Faster, uses a single on-disk content store. 9.15.9 + (optionally) Go 1.25 installed locally. See Run it locally for the one-time install.
Mode 2 — everything in Docker
When: smoke-testing the full stack before a deploy, or working on a machine that does not have Node/Go installed.
cd ~/AG-DEV/hivecfm-core
docker compose up -d --build
# everything runs inside containers; apps at the same portsCaveat: every app-code change means docker compose up -d --build <service> (typically 30–120 s). Fine for integration checks, painful
for iterative work.
Mode 3 — everything native
When: profiling a hot path, debugging network stacks, or investigating a Docker-specific issue. Rare.
# Requires a system-level Postgres, Redis, and MinIO pre-configured
# with the ports / credentials from .env.local. Skip unless you know
# why you're here.Caveat: reproducing the exact data-plane setup by hand is the main cost. Do not use Mode 3 just to avoid Docker — use Mode 1.
Troubleshooting
My change didn’t reflect. In Mode 1 this almost always means you
edited a Docker-only file (.env read by a container, or a composeDocker ComposeThe YAML file and CLI that spin up Postgres, Redis, MinIO, MailHog locally with one command.
setting) expecting a hot-reload. Consult the
decision table — if the answer is “Yes, rebuild”,
do docker compose down && docker compose up -d.
Port already in use after down. Something else on the host is
bound to the port. See the Port conflicts runbook
for the step-by-step.
Env var change ignored. Env is read once at process start. Restart
the native process (Ctrl-C, then pnpm dev / go run again) or, if
the var lives in a Docker-service env, docker compose down && docker compose up -d so the container reloads its environment.
PrismaPrismaThe TypeScript ORM HiveCFM uses to talk to Postgres. The schema lives at packages/database/schema.prisma. client out of date. Run pnpm run db:migrate — it applies
pending migrations AND regenerates the client. If only the client is
stale (someone else’s migration, no schema change locally), run
pnpm --filter @hivecfm/database prisma generate for a faster path.
Related
- Run it locally — the one-time setup that gets you to the default mode.
- Local development — the operational cheat sheet for daily commands.
- Port conflicts — when a port is stuck after
down.