Polyglot microservices monorepo for my portfolio site. All services live in this repo as directories, connected by a Kafka event bus and orchestrated through Docker Compose.
portfolio_frontend/- Next.js frontendportfolio_bff/- Django BFF + admin dashboardportfolio_calendar/- C# .NET 8 minimal API (appointment producer)worker/- Kafka broker + notifier runtime
One command to run everything in Docker:
make docker-upThis spins up Kafka, MySQL, the BFF + consumer, calendar API, frontend, and
the notifier worker in one shot.
Port 3001 is reserved for the BFF admin UI.
Then open:
http://localhost:3100/(frontend)http://localhost:3001/(BFF admin UI)http://localhost:8001/(BFF API)
Seed the BFF once (if you haven't already):
make docker-bff-seedIf you keep private content in an ops repo at ../ntakemori-deploy/portfolio-content.json,
the seed command will use it automatically (no extra flags needed).
Stop everything:
make docker-downShort path for a local dev session (Docker for infra, local for app processes).
All local-*-up commands auto-stop their Docker counterpart, so you can freely
mix and match.
- Start infrastructure (Docker):
make docker-kafka-up
make docker-db-up- Start local app processes (separate terminals):
make local-calendar-up
make local-bff-up
make local-bff-seed
make local-bff-superuser # first time only
make local-bff-consumer-up
make local-frontend-up
make local-admin-ui-upIf you keep private content in an ops repo at ../ntakemori-deploy/portfolio-content.json,
the seed command will use it automatically (no extra flags needed).
- Optional email worker:
make local-notifier-upRequires worker/.env with Mailgun credentials (MAILGUN_API_KEY,
MAILGUN_DOMAIN, MAILGUN_FROM_EMAIL) and NOTIFICATIONS_OWNER_EMAIL.
Without credentials, use Docker with the sample env instead:
make docker-notifier-upAll host-side port defaults live in ports.env at the repo root. The Makefile
includes and exports them so every service compose file and local-dev target
picks them up automatically. Override any value inline:
PORTFOLIO_PORT=4000 make docker-frontend-upEvery service exposes up, down, and clean targets with docker-* and
local-* prefixes. Infrastructure (Kafka, MySQL) is docker-only.
local-*-up targets automatically stop the Docker counterpart first, so you
can switch from Docker to local without a separate step.
Run make help for the full command reference.
make docker-up
make docker-down
make docker-cleanmake docker-frontend-{up,down,clean}
make local-frontend-{up,down,clean}make docker-bff-{up,down,clean}
make docker-bff-seed
make docker-bff-up-seed
make docker-bff-superuser
make local-bff-{up,down,clean}
make local-bff-seed
make local-bff-up-seed
make local-bff-superusermake docker-admin-ui-{up,down,clean}
make local-admin-ui-{up,down,clean}Port reservation: 3001 is reserved for the BFF admin UI.
make docker-bff-consumer-{up,down,clean}
make local-bff-consumer-{up,down,clean}make docker-calendar-{up,down,clean}
make local-calendar-{up,down,clean}make docker-kafka-{up,down,clean}
make docker-db-{up,down,clean}make docker-notifier-{up,down,clean}
make local-notifier-{up,down,clean}local-notifier-up loads worker/.env automatically and sets
KAFKA_BOOTSTRAP_SERVERS=localhost:9092.
make status # git status -sb on the monorepo
make nuke # full teardown (requires NUKE=1)Host-specific deployment lives in ntakemori-deploy and is intentionally
separate from this portable stack repo.
Expected local ports (for ops reference):
- Frontend:
3100 - BFF Admin UI:
3001(reserved) - BFF API:
8001(container listens on8000) - Calendar API:
8002 - Kafka (host):
9092(internal:19092) - MySQL:
3307(container listens on3306) - Notifier worker: no inbound port