Skip to content

Local Development Workflow

Dmitrii Shmanatov edited this page May 17, 2026 · 5 revisions

Horse philosophy: I'm not a fan of running everything in Docker for local development. When PHP 8.4 is already on my machine, I want full control over the app code. But for infrastructure (NATS, Redis) and Go services β€” Docker Compose is magic. One command, and the whole backend wakes up.

Prerequisites

Tool Version Notes
PHP 8.4 (8.2 should work, but 8.4 is the horse's home) + Composer + Swoole extension
Node.js Any LTS + npm
Docker Any recent For NATS, Redis, and all Go services
Make Any For make build, make dev, and make app

🐎 Go is NOT required on your local machine. All Go services (Balancer, WebSocket Proxy, API) run inside Docker with hot-reload via Air.

Step-by-step

1. Clone & prepare

git clone https://github.com/centaur-vova/fast-atomic-flow.git
cd fast-atomic-flow
cp .env.example .env

2. Fix .env for local development

Change only 3 lines in your .env to connect the host machine to Docker services:

- NATS_HOST=deez-nutz
+ NATS_HOST=localhost

- API_URL=http://balancer:8090
+ API_URL=http://localhost:8090

- REDIS_URL=redis:6379
+ REDIS_URL=localhost:6379

Optional tweaks (open .env and go wild):

  • RATE_LIMITERS={} β€” empty JSON = no rate limiting. Perfect for hammering your local box.
  • SERVER_WORKER_NUM=2 β€” match your CPU cores, or just vibe.
  • QUEUE_PREFETCH_BATCH=16 β€” bigger batches = more throughput, less control.
  • LOG_LEVEL=debug β€” if you want to see everything.

3. Install dependencies & build frontend

composer install
npm install
make build

4. Start infrastructure + Go services (terminal 1)

make dev

This single command launches everything via Docker Compose:

  • NATS (Deez Nutz) with JetStream
  • Redis 8.0 β€” semaphore store for distributed semaphores
  • Go Balancer β€” auto-registration, health checks, round-robin
  • Go WebSocket Proxy β€” real-time updates to the frontend
  • Go API Γ— 2 β€” with hot-reload via Air

All Go services use Air: change .go files β†’ services rebuild and restart automatically. No manual restarts needed.

5. Run the PHP Swoole app (terminal 2)

make app

Expected output: Β» LISTEN : http://0.0.0.0:9501

The make app command passes local connection flags automatically:

  • --nats-host=localhost (connect to Docker NATS)
  • --api-url=http://localhost:8090 (connect to Docker Balancer)

6. Open browser

Go to http://localhost:9501

You should see the task board. If not β€” check that make dev (terminal 1) and make app (terminal 2) are both running.

Why this setup?

What Why
NATS + Redis + Go in Docker Infrastructure and Go services that rarely need manual tinkering. One make dev and they're up with hot-reload.
PHP natively Instant feedback. Change PHP β†’ refresh. No rebuild, no waiting.
Two terminals One for make dev (Docker), one for make app (PHP). That's it.
No Go on host Go runs in Docker. You only need PHP + Swoole locally.

Troubleshooting

Port already in use:

  • 4222 (NATS) β†’ change NATS_PORT in .env and docker-compose.dev.yaml
  • 6379 (Redis) β†’ change REDIS_URL in .env
  • 8080 (WS proxy) β†’ change WS_PORT in .env
  • 8090 (Balancer) β†’ change API_PORT in .env
  • 9501 (HTTP) β†’ change SERVER_PORT in .env

NATS connection refused: Wait a few seconds after make dev before starting PHP. NATS needs a moment to initialise.

Go API not registering with balancer: Check make logs-api. You should see πŸš€ Registration successful!. If not β€” check make logs-balancer for errors.

Makefile not found: You're either in the wrong directory or you don't have make. Install make or run the commands manually.

"But bro, I don't have PHP 8.4": Use Docker for everything then. That's what the GHCR images are for. This workflow is for horses who have PHP locally.


Koni ne brosayut koney. Even at 4 AM. Especially at 4 AM. πŸŽπŸ’™

Clone this wiki locally