https://github.com/krishgok/localdevstack
Instantly scaffold a containerised local development environment for any service and database — with a single command.
https://github.com/krishgok/localdevstack
cli-tool dev-environment developer-tools docker kotlin
Last synced: about 1 month ago
JSON representation
Instantly scaffold a containerised local development environment for any service and database — with a single command.
- Host: GitHub
- URL: https://github.com/krishgok/localdevstack
- Owner: krishgok
- License: apache-2.0
- Created: 2026-05-21T02:39:08.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2026-05-28T02:39:39.000Z (about 2 months ago)
- Last Synced: 2026-05-31T17:25:20.386Z (about 1 month ago)
- Topics: cli-tool, dev-environment, developer-tools, docker, kotlin
- Language: Kotlin
- Homepage:
- Size: 3.84 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Roadmap: docs/roadmap.md
Awesome Lists containing this project
README
LocalDevelopmentStack
Spin up a production-shaped local stack in 30 seconds.
One command generates a Dockerised service + database + hot-reload. Nine languages, eight databases, no JVM required.
brew install krishgok/localdevstack/localdevstack · localdevstack --service go --database postgres
Every new project means writing docker-compose.yml from scratch, picking a hot-reload tool, wiring a DB connection string, and chasing healthcheck timing.
LocalDevelopmentStack does all of that for you — deterministically, across 9 languages and 8 databases.
---
## Before / After
Before — hand-roll the stack
After — one command
```yaml
# docker-compose.yml — write from scratch
services:
service:
build:
context: ./service
dockerfile: Dockerfile.dev
ports: ["8080:8080"]
environment:
DATABASE_URL: postgresql://...
volumes: [".:/app"]
depends_on:
db: { condition: service_healthy }
db:
image: postgres:16
# ... env, ports, volume, healthcheck...
```
Plus: write `Dockerfile.dev` with the right hot-reload tool, manage `.env`, add `.gitignore` rules, debug compose healthcheck timing — repeat for every new project.
```bash
localdevstack \
--service go \
--database postgres \
--output ./my-api
```
```text
my-api/
├── service/
│ ├── main.go
│ └── Dockerfile.dev
├── docker-compose.yml
├── .env / .env.example
└── .gitignore
```
```bash
cd my-api && docker-compose up --build
curl http://localhost:8080/health
# → {"status":"ok"}
```
---
## Features
| | |
|---|---|
| ✦ **Hot-reload, everywhere** | Edit source, see it live — no rebuild |
| ✦ **9 service generators** | Go · Node · Python · Rust · Java · Spring Boot · .NET · PHP · Ruby |
| ✦ **8 database generators** | Postgres · MySQL · MongoDB · CockroachDB · Redis · MariaDB · SQL Server · Elasticsearch |
| ✦ **Optional migrations** | Flyway · Liquibase · migrate-mongo · golang-migrate |
| ✦ **Optional companions** | MailHog (SMTP catcher) · MinIO (S3-compatible store) |
| ✦ **Native binary** | No JVM, no Docker-in-Docker — one self-contained executable |
| ✦ **Battle-tested in CI** | Each release runs `docker compose up --build` + `curl /health` across **72 service × database combinations** before binaries ship |
---
## Quickstart
### Install
macOS / Linux — Homebrew
```bash
brew tap krishgok/localdevstack
brew install localdevstack
```
> Pre-built bottles for **macOS arm64**, **Linux x64**, and **Windows x64**. Intel macOS users: clone the repo and run `./gradlew nativeCompile` (requires GraalVM 21).
Windows — Scoop
```powershell
scoop bucket add localdevstack https://github.com/krishgok/localdevstack
scoop install localdevstack
```
macOS / Linux — curl
```bash
curl -fsSL https://raw.githubusercontent.com/krishgok/localdevstack/main/scripts/install.sh | bash
```
Windows — PowerShell
```powershell
irm https://raw.githubusercontent.com/krishgok/localdevstack/main/scripts/install.ps1 | iex
```
### First stack in three steps
```bash
# 1. Generate
localdevstack --service go --database postgres --output ./my-api --name my-api
# 2. Run
cd my-api && docker-compose up --build
# 3. Verify
curl http://localhost:8080/health
# → {"status":"ok"}
```
Edit any file under `service/` — the watcher inside the container picks it up and reloads automatically.
**Two modes:**
```bash
# New service — generates source code + Dockerfile.dev + docker-compose.yml
localdevstack --service go --database postgres --output ./my-api
# Existing service — auto-detects language, generates Dockerfile.dev + docker-compose.yml
localdevstack --existing-dir ./my-existing-api --database postgres
```
**More combinations:**
```bash
# Python (FastAPI) + MongoDB + migrate-mongo migrations
localdevstack --service python --database mongodb --migration migrate-mongo --output ./api
# Rust (Axum) + Redis + MinIO (S3-compatible object store)
localdevstack --service rust --database redis --with minio --output ./cache-svc
# Spring Boot + SQL Server + Liquibase changelogs + MailHog (SMTP catcher)
localdevstack --service springboot --database sqlserver --migration liquibase --with mailhog --output ./platform-api
# Preview only — print the resolved plan without writing files
localdevstack --service node --database mariadb --with mailhog --output ./api --dry-run
```
→ Full walkthrough: **[New service](docs/usage-new-service.md)** · **[Existing service](docs/usage-existing-service.md)**
---
## Architecture
```mermaid
flowchart LR
User([Developer]) --> CLI[localdevstack
native binary]
CLI --> Gen[Generators
service · db · migration · companion]
Gen --> Out[docker-compose.yml
Dockerfile.dev
.env / .env.example]
Out --> Run[docker-compose up --build]
Run --> Stack[(Running stack:
service · db · migrate · companions)]
```
`LocalDevStackCli` dispatches via three registry maps — `SERVICES`, `DATABASES`, `COMPANIONS` — and runs each generator into the chosen output directory. Volume-mounted source means **edits hot-reload without rebuilding**.
---
## Who it's for
- **Solo developers prototyping** — skip the docker-compose boilerplate; get a working stack on a new project in 30 seconds.
- **Teams onboarding new hires** — commit `docker-compose.yml` + `.env.example`; new joiners run one command and have the full local stack.
- **Platform / DevEx teams** — standardise local environments across repos without writing a custom CLI or yet-another-internal-template.
---
## Why this over the alternatives
| Tool | Scope | Host-side toolchain? | K8s required? | Hot-reload baked in? | One command brings up DB + service? |
|-------------------------------------------------|--------------------------------|------------------------------|---------------|---------------------------|-------------------------------------|
| **LocalDevelopmentStack** | docker-compose dev stacks | No — service runs in container | No | Yes — per language | Yes |
| Hand-rolled compose | docker-compose | Up to you | No | DIY per language | No |
| `docker init` | single Dockerfile (no DB) | No | No | Sometimes | No |
| Tilt / Skaffold | Kubernetes dev loops | Yes (`kubectl`) | Yes | Yes | Yes (different scope) |
| Nix / devbox / mise | host-side env management | Replaces it (no Docker) | No | N/A | N/A |
| `create-t3-app`, `cookiecutter`, framework CLIs | language-specific scaffolds | Yes | No | Varies | No (files only; no DB) |
The differentiator: **compose-native, no Kubernetes, no host language toolchain required.** The 72-combo CI sweep (noted in [Features](#features) above) means every supported `(language, database)` pair has been built and `/health`-checked at least once per release.
---
## Showcase
### Service support — 9 languages, one CLI
Every generated service exposes `GET /health` → `{"status":"ok"}` and ships with the right hot-reload tooling baked in — `air` for Go, `nodemon` for Node, `uvicorn --reload` for Python, `cargo-watch` for Rust, `dotnet watch run` for .NET, and so on.
→ **[Sentinel files, framework details, full table](docs/usage-new-service.md)**
### Database support — 8 engines, zero config
Every database container ships with a healthcheck and injects its connection string into your service via a single environment variable. Your code reads one variable; the same code works locally and in production.
→ **[Per-language connection examples](docs/db-connections.md)**
### Migrations — opt-in, one flag
| `--migration` | Tool | Best for |
|-------------------|------------------|-----------------------------------------------------------------------|
| `flyway` | Flyway 10 | Versioned SQL on Postgres, MySQL, MariaDB, SQL Server, CockroachDB |
| `liquibase` | Liquibase 4.27 | Richer changelog format, multiple SQL dialects |
| `migrate-mongo` | migrate-mongo 11 | MongoDB collection migrations |
| `golang-migrate` | migrate v4 | One tool, six engines (incl. MongoDB) |
```bash
localdevstack --service go --database postgres --migration flyway
docker-compose run --rm migrate # manual run — uses the `migrations` compose profile
```
→ **[docs/migrations.md](docs/migrations.md)**
### Companions — drop-in dev services
| Companion | What you get |
|-------------|---------------------------------------------------------------------------------------------------------------|
| **MailHog** | SMTP catcher + web UI on `:8025`. Capture outgoing mail. Auto-injects `SMTP_HOST`, `SMTP_PORT`. |
| **MinIO** | S3-compatible object store + console on `:9001`. Auto-injects `S3_ENDPOINT`, `S3_ACCESS_KEY`, `S3_SECRET_KEY`. |
```bash
localdevstack --service node --database postgres --with mailhog,minio
```
→ **[docs/companions.md](docs/companions.md)**
### Power-user flags
| | |
|--------------------------|-------------------------------------------------------------------------------------------------------|
| **Env file management** | `.env` (gitignored) + `.env.example` (commit-safe) written on every invocation |
| **Dry-run mode** | `--dry-run` prints the resolved plan and would-be file list without touching the filesystem |
| **Multi-database** | One DB per invocation by default; copy the second `db:` block into your existing compose file |
| **`--force`** | Overwrite existing migrations / compose files when regenerating into the same directory |
| **`--port`** | Pin the service port (default auto-selects 8080 → 8081 → 8082 if lower ports are occupied) |
→ **[docs/advanced.md](docs/advanced.md)**
---
## Roadmap
- **More companions** — Redis-as-cache, Prometheus + Grafana, OpenTelemetry collector + Jaeger
- **Vector databases** — pgvector, Qdrant, Weaviate
- **Bigger bets** — Kubernetes output, multi-service composition, interactive `init` wizard
→ Full list: **[docs/roadmap.md](docs/roadmap.md)**
---
## Contributing & support
- **Using with an AI assistant?** → see [AGENTS.md](AGENTS.md) for invocation patterns and canned prompts
- **Issues / feature requests** → [github.com/krishgok/LocalDevelopmentStack/issues](https://github.com/krishgok/LocalDevelopmentStack/issues) (templates for bug reports, feature requests, and new-type requests)
- **Pull requests** → see [CONTRIBUTING.md](CONTRIBUTING.md)
- **Security vulnerabilities** → see [SECURITY.md](SECURITY.md) (private reporting via the GitHub Security tab)
- **Code of Conduct** → see [CONTRIBUTING.md § Code of conduct](CONTRIBUTING.md#code-of-conduct)
- **Disclaimers & limitations** → see [docs/disclaimers.md](docs/disclaimers.md)
Licensed under the [Apache License, Version 2.0](LICENSE).