Local Development Setup Guide
A streamlined guide to setting up the full stack locally, from secret management with Infisical to running microservices with shared infrastructure.
When I first tried to onboard myself onto this project after a two-week vacation, I realized our setup instructions were scattered across Slack messages, a half-finished Notion page, and tribal knowledge that lived entirely in my own head. It took me over an hour to get a working dev environment running again — on my own project. That experience motivated me to write this guide and build the generate-env.sh script that reduces setup to three commands. The hybrid approach of running code locally but databases on the cluster was born out of necessity: my MacBook’s fan sounded like a jet engine whenever I tried to run PostgreSQL, NATS, and MinIO locally alongside the .NET processes.
Introduction
Onboarding to a microservice architecture can be daunting. In our project, we’ve invested heavily in “Developer Experience” (DevEx) to ensure you can go from git clone to a running application in under 15 minutes. We achieve this by hybridizing local compute (your laptop) with shared cluster infrastructure.
Why This Hybrid Approach Matters:
- Resource Efficiency: You don’t need to run Postgres, MinIO, Qdrant, and FalkorDB on your Mac. They run on the K8s homelab cluster.
- Speed:
.NET WatchandHot Reloadwork natively because the code runs locally. - Realism: You develop against real data services, not mocked in-memory alternatives.
What We’ll Build
You will set up the local development environment. You will:
- Authenticate: Connect to Infisical for secrets.
- Generate Config: Create the
.env.localfile. - Run: Launch the API, Web, and Workers simultaneously.
Architecture Overview
Network traffic flows from your local process to the data-layer services in the cluster via Tailscale.
flowchart TB
subgraph Local["💻 Local Workstation (Mac/PC)"]
Code["🖥️ Visual Studio Code"]
Infisical["🔐 Infisical CLI"]
DotNet["🟣 .NET Watch"]
end
subgraph K8s["☸️ Kubernetes Cluster (HomeLab)"]
PG[("🐘 PostgreSQL")]
NATS["⚡ NATS JetStream"]
MinIO["🪣 MinIO Storage"]
end
Infisical -->|Injects Secrets| DotNet
DotNet -->|Tailscale VPN| PG
DotNet -->|Tailscale VPN| NATS
DotNet -->|Tailscale VPN| MinIO
classDef primary fill:#7c3aed,color:#fff,stroke:#8b5cf6,stroke-width:2px
classDef secondary fill:#06b6d4,color:#fff,stroke:#22d3ee,stroke-width:2px
classDef db fill:#f43f5e,color:#fff,stroke:#fb7185,stroke-width:2px
classDef infra fill:#334155,color:#e2e8f0,stroke:#475569,stroke-width:2px
class DotNet primary
class Code,Infisical secondary
class PG,NATS,MinIO db
Implementation
1. Prerequisites
Ensure you have the following installed:
- .NET 10 SDK
- Node.js & NPM
- Infisical CLI
- Tailscale (Connected to
my-tailnettailnet)
2. Secret Injection
We do not commit configuration files. Instead, we generate them from our centralized secret store.
[The Twelve-Factor App: Config] — Adam Wiggins , 2017-01-30# Login to Infisical
infisical login
# Generate the .env.local file
./scripts/generate-env.sh This script fetches connection strings for the dev environment databases running on K8s and writes them to .env.local.
3. Launching the Stack
We use VS Code Tasks to orchestrate the startup. Open the Command Palette (Cmd+Shift+P) and run “Tasks: Run Task” -> “Start Local Dev”.
This parallels the execution of:
- Tailwind Watcher: Compiles CSS for the UI.
- API: Starts the FastEndpoints backend on port 5000.
- Web: Starts the Blazor Server frontend on port 5001.
- Workers: Starts the background job processor.
Conclusion
By treating infrastructure as a shared utility and code as a local concern, we get the best of both worlds. There is no docker-compose up waiting time, no fan noise from running 10 containers, just pure coding efficiency. Welcome!
The biggest lesson I learned building this setup is that developer experience is not a luxury — it is a multiplier. Every minute I spent automating the generate-env.sh script and configuring VS Code tasks paid itself back tenfold. When I can go from a fresh clone to a running application in under five minutes, I actually want to work on side features and experiments instead of dreading the setup ritual. If you take one thing from this guide, let it be this: invest in your inner loop, and everything else gets easier.
Next Steps
- Add a health check script that verifies Tailscale connectivity and database reachability before launching the stack
- Create a
devcontainer.jsonfor contributors who prefer a fully containerized workflow - Integrate the Infisical VS Code extension for inline secret browsing
- Set up automatic
.env.localregeneration on secret rotation via a file watcher