Getting StartedRun it locally

Run it locally

The fastest way to see HiveCFM running is to clone both repos, start Docker, migrate the database, and run the Next.jsNext.jsReact framework used by HiveCFM Core. Handles routing, server rendering, and API routes in one bundle. app. This page walks through that in order. The reference numbers below match the ports you will actually see.

Prerequisites

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, Docker 24+, Git, and OpenSSL — plus Go 1.25+ only if you’ll run the HubHubThe Go service that owns background processing, integrations, and the admin API. Sibling to Core. natively. Each tool has its own install + verify steps:

Already have them? Confirm with: node -vv22.x.x · pnpm -v9.15.9 · docker compose versionv2.x.x.

Port map

ServicePortNotes
hivecfm-core (Next.jsNext.jsReact framework used by HiveCFM Core. Handles routing, server rendering, and API routes in one bundle.)3001Port 3000 is taken by another process on shared dev boxes; HiveCFM uses 3001.
Postgres5433Exposed via docker-compose.dev-ports.yml.
RedisRedisIn-memory key-value store used for caching, sessions, and rate limiting. Runs on port 6380 locally.6380Exposed via docker-compose.dev-ports.yml.
Superset3002Analytics.
hivecfm-dev-hub (this site)4100The site you are reading now.
HubHubThe Go service that owns background processing, integrations, and the admin API. Sibling to Core. API8090Go service for embeddings, sentiment, webhooks.
MinIOMinIOS3-compatible object storage for survey attachments and uploads. Runs locally; swaps for real S3 in prod. console9001S3-compatible object storageMinIOS3-compatible object storage for survey attachments and uploads. Runs locally; swaps for real S3 in prod. UI.

All ports bind to 127.0.0.1 only. Running on a remote VM (EC2)? See Running on AWS EC2 via SSH below for the tunnel commands.

Steps

Clone the repos

The three HiveCFM repos live on Azure DevOps. If you haven’t set up auth on this machine yet, do Authenticate with Azure DevOps first.

Pick either approach — they do the same thing. The CLI is the canonical reference; the VS Code GUI is faster on a remote dev box where the multi-line paste behaviour in the terminal can trip you up.

⚠️

A URL is not a command. Always run git clone <url> — pasting only the URL at a bash prompt produces No such file or directory. If you paste a multi-line block into the terminal and one line ends up as a bare URL, that line will fail; the others may run partially.

Make the working directory:

mkdir -p ~/AG-DEV
cd ~/AG-DEV

Clone the three repos:

git clone https://dev.azure.com/istnetworksrnd/HiveCFM/_git/hivecfm-core
git clone https://dev.azure.com/istnetworksrnd/HiveCFM/_git/hivecfm-hub
git clone https://dev.azure.com/istnetworksrnd/HiveCFM/_git/hivecfm-dev-hub

To check out a specific branch instead of the default (main), add -b <branch-name>:

git clone -b AG-hiveCoreMigrtorTool https://dev.azure.com/istnetworksrnd/HiveCFM/_git/hivecfm-core
  • Expected: ~30 s per clone. hivecfm-core is the largest (~150 MB).

  • Verify the folders exist:

    ls ~/AG-DEV

    Output should list hivecfm-core hivecfm-hub hivecfm-dev-hub.

  • Verify the branch (if you used -b):

    cd ~/AG-DEV/hivecfm-core && git branch --show-current

    Prints the active branch name.

  • If fatal: Authentication failed: PAT expired or wasn’t stored — see the auth steps in Prerequisites.

  • If bash says No such file or directory and echoes the URL: you forgot git clone in front, or VS Code’s terminal split a multi-line paste. Type the command on a single line.

  • search-hint: git clone azure devops authentication failed

Install dependencies

cd hivecfm-core
pnpm install

First install takes about 40 seconds and pulls shared toolchain into node_modules/.

Create your .env files

Both hivecfm-core and hivecfm-hub need a .env — copy from .env.example and generate local-only secrets with OpenSSL, or pull real values from 1Password. The full procedure with verify steps lives on its own page:

For a quick local-only setup, this is the minimum:

cp hivecfm-core/.env.example hivecfm-core/.env
cp hivecfm-hub/.env.example  hivecfm-hub/.env
# then append OpenSSL-generated values — see Secrets page

Start the stack

docker compose up -d

This brings up Postgres, Redis, MinIO, MailHog, Superset, and the Go Hub in background containers. First boot builds images — give it 10–20 minutes.

⚠️

If you want localhost:5433 and localhost:6380 exposed on the host (required for native dev), layer the dev-ports override: docker compose -f docker-compose.yml -f docker-compose.dev-ports.yml up -d.

Migrate the database

pnpm run db:migrate

Under the hood this runs pnpm --filter @hivecfm/database db:migrate:dev, which applies every migration in hivecfm-core/packages/database/migrations/ and regenerates the Prisma client.

Run the app

pnpm dev

The Next.js app starts on http://localhost:3001 with hot-reload. The underlying command is pnpm --filter @hivecfm/web dev — you can run that directly if you want to filter other workspaces off.

Verify

curl -s http://localhost:3001/health      # returns HTML or 200
curl -s http://localhost:8090/health      # {"status":"ok"} from the Go Hub
docker compose ps                         # every container should be "running" or "healthy"

Then open http://localhost:3001 in your browser and sign up for the first account — the first user bootstraps the initial organisation.

Troubleshooting

Port 3000 already in use. HiveCFM Core already uses 3001 via HIVECFM_PORT=3001 in .env. If something else grabs 3001, stop it (sudo lsof -i :3001) or change the port in .env and in WEBAPP_URL / NEXTAUTH_URL together.

Port 5432 vs 5433. The Postgres container exposes 5433 on the host to avoid colliding with any system Postgres on 5432. .env.local points at postgresql://postgres:postgres@localhost:5433/hivecfm?schema=public. If pnpm run db:migrate cannot connect, check that the dev-ports override was applied.

Docker build runs out of memory. The Next.jsNext.jsReact framework used by HiveCFM Core. Handles routing, server rendering, and API routes in one bundle. build peaks around 8 GB. On small VMs, increase Docker’s memory limit or build the web app natively with pnpm --filter @hivecfm/web build.

PrismaPrismaThe TypeScript ORM HiveCFM uses to talk to Postgres. The schema lives at packages/database/schema.prisma. client is stale after pulling main. Re-run pnpm --filter @hivecfm/database db:migrate:dev. It will both migrate and regenerate.

HubHubThe Go service that owns background processing, integrations, and the admin API. Sibling to Core. container unhealthy. Check docker logs hivecfm-hub-api. The most common cause is hivecfm_hub Postgres database not initialised; the hivecfm-hub-db-init one-shot container handles that — inspect its logs.

Superset login fails. The admin password is set by SUPERSET_ADMIN_PASSWORD in .env. If you forgot to set it, regenerate with openssl rand -hex 32 and restart the Superset container.

More: Runbooks collect the longer debugging procedures.

Running on AWS EC2 via SSH

If your pnpm dev and Docker stack are on a remote EC2 instance (not your laptop), every port in the table above is bound to 127.0.0.1 inside the instance. You reach them from your laptop by forwarding the ports over SSH.

⚠️

Do not open these ports in the EC2 security group. They have no auth in dev mode — exposing them publicly would hand the database and admin UI to the internet. SSH tunneling is the only safe path.

One-shot tunnel (every port you need)

From your laptop, run:

ssh -N \
  -L 3001:localhost:3001 \
  -L 4100:localhost:4100 \
  -L 3002:localhost:3002 \
  -L 9001:localhost:9001 \
  -L 8090:localhost:8090 \
  -L 5433:localhost:5433 \
  -L 6380:localhost:6380 \
  -i ~/.ssh/your-ec2-key.pem \
  ubuntu@<ec2-public-dns>
  • Expected: Terminal hangs with no output — that means the tunnel is open. -N says “don’t run a remote command, just forward ports.”
  • Verify (on your laptop): open http://localhost:3001 in your browser — the HiveCFM login page loads. curl http://localhost:8090/health returns {"status":"ok"}.
  • If “bind: Address already in use”: another process on your laptop owns one of those ports. Find it with lsof -i :3001 (mac/Linux) or Get-NetTCPConnection -LocalPort 3001 (Windows) and stop it.
  • If “channel 3: open failed: connect failed: Connection refused”: the service isn’t listening yet on the EC2 side. SSH into the instance and check docker compose ps or that pnpm dev is running inside tmux.
  • If the tunnel drops every ~10 min: add ServerAliveInterval 30 to your ~/.ssh/config (next section).
  • search-hint: ssh -L multiple ports tunnel

Permanent setup via ~/.ssh/config

Tired of typing the full command every time? Add this to ~/.ssh/config on your laptop:

Host hive-ec2
  HostName <ec2-public-dns>
  User ubuntu
  IdentityFile ~/.ssh/your-ec2-key.pem
  ServerAliveInterval 30
  ServerAliveCountMax 3
  LocalForward 3001 localhost:3001
  LocalForward 4100 localhost:4100
  LocalForward 3002 localhost:3002
  LocalForward 9001 localhost:9001
  LocalForward 8090 localhost:8090
  LocalForward 5433 localhost:5433
  LocalForward 6380 localhost:6380

Then just: ssh -N hive-ec2 (or drop -N if you also want a shell).

  • Verify: ssh hive-ec2 connects without needing the long command, and forwarding still works.
  • If “Permissions 0644 for ‘…your-ec2-key.pem’ are too open”: chmod 600 ~/.ssh/your-ec2-key.pem.
  • search-hint: ssh config localforward example

Running pnpm dev so it survives SSH disconnects

A bare pnpm dev dies the moment your SSH session drops. Wrap it in tmux:

# inside EC2 over SSH
tmux new -s hive
# inside tmux:
cd ~/AG-DEV/hivecfm-core
pnpm dev
# Press Ctrl-B then D to detach. The dev server keeps running.
# Reattach next session: tmux attach -t hive

The Docker stack (docker compose up -d) doesn’t need tmux — the -d flag already detaches it.

Stopping the tunnel

The SSH process holds the tunnel. Stop it on the laptop with Ctrl-C, or kill the PID (pgrep -f "ssh.*hive-ec2"). Stopping the tunnel does not stop services on EC2.

Next

Once the stack is up, read the Dev loop page — it answers the question everyone asks on day two: “I changed a file, do I have to rebuild Docker?”