Production-ready Go template with Domain-Driven Design (DDD), PostgreSQL, code generation, OpenAPI, and three runnable apps: API, Web, and Admin.
- Clean DDD architecture (apps, domain, gateways, internal)
- PostgreSQL with migrations (golang-migrate) and type-safe queries (sqlc)
- OpenAPI docs and client SDK generation
- Web UI rendered with
templ - Solid DX: Makefile tasks, lint, tests, security checks
This repo follows DDD. Key folders:
cmd/ # Entrypoints and config for each app
service/ # API server (REST)
web/ # Web app (user-facing)
admin/ # Admin app
app/ # Application layer (HTTP, routing, views)
api/ # API routers, middleware, handlers
web/ # Web routes, pages (templ)
admin/ # Admin routes, pages (templ)
domain/ # Business logic (entities + use cases)
entities/ # Core types shared across the domain
user/, auth/, example/, settings/ # Use cases and interfaces
gateways/ # Adapters to 3rd-party systems
repository/pg # PostgreSQL repositories (sqlc)
auth/ # External auth providers
internal/ # Shared internal libs (e.g. jwt)
build/ # Compiled binaries
docs/ # Manual and generated OpenAPI docs
Concepts:
- Apps depend on use cases in
domain/and on adapters ingateways/. - Entities in
domain/entitiesare provider-agnostic. - Swap providers by changing only
gateways/.
- API (cmd/service): REST API on
API_ADDRESS(default 0.0.0.0:3000) - Web (cmd/web): user-facing app on
WEB_ADDRESS(default 0.0.0.0:8080) - Admin (cmd/admin): admin console on
ADMIN_ADDRESS(default 0.0.0.0:8081)
- Create your repo
git clone https://github.com/guilhermebr/go-template.git your-project
cd your-project
./change_repo.sh your-module-name # updates go.mod and imports- Tooling
make setup- Configure env
cp .env.example .envMinimum required variables (examples):
- DATABASE_HOST=localhost
- DATABASE_USER=postgres
- DATABASE_PASSWORD=postgres
- DATABASE_NAME=app
- API_ADDRESS=0.0.0.0:3000
- AUTH_SECRET_KEY=dev-secret-change-me
- AUTH_PROVIDER=supabase
- SUPABASE_URL=... (when using supabase)
- SUPABASE_API_KEY=...
- WEB_ADDRESS=0.0.0.0:8080 (prefix vars with WEB_ for Web app)
- ADMIN_ADDRESS=0.0.0.0:8081 (prefix vars with ADMIN_ for Admin app)
- Database
docker compose up -d db
export DATABASE_HOST=localhost \
DATABASE_USER=postgres \
DATABASE_PASSWORD=postgres \
DATABASE_NAME=app
make migration/up- Generate code and build
make generate # templ + sqlc + go generate
make build # builds service, web, admin into ./build- Run apps
./build/service # API
./build/web # Web
./build/admin # AdminService (no prefix):
- ENVIRONMENT=development
- API_ADDRESS=0.0.0.0:3000
- DATABASE_ENGINE=postgres
- DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD, DATABASE_NAME
- AUTH_SECRET_KEY, AUTH_TOKEN_TTL=24h
- AUTH_PROVIDER=supabase
- SUPABASE_URL, SUPABASE_API_KEY
Web (prefix: WEB_):
- WEB_ENVIRONMENT, WEB_ADDRESS=0.0.0.0:8080
- WEB_API_BASE_URL=http://localhost:3000
- WEB_COOKIE_MAX_AGE, WEB_COOKIE_SECURE, WEB_COOKIE_DOMAIN, WEB_SESSION_TIMEOUT
Admin (prefix: ADMIN_):
- ADMIN_ENVIRONMENT, ADMIN_ADDRESS=0.0.0.0:8081
- ADMIN_API_BASE_URL=http://localhost:3000
- ADMIN_COOKIE_MAX_AGE, ADMIN_COOKIE_SECURE, ADMIN_COOKIE_DOMAIN, ADMIN_SESSION_TIMEOUT
- Manual spec:
docs/openapi.yaml - Generated spec from code annotations:
make openapi-generate→docs/openapi-generated.{yaml,json} - View docs locally:
make docs
# Open docs/redoc.html or docs/swagger-ui.html in the browserGenerate client SDKs (from manual spec):
make sdks # all (Go, TS, Python, Java)
make sdk-go
make sdk-typescript
make sdk-python
make sdk-javaFrom generated spec:
make sdks-generatedCreate a migration:
make migration/create
# enter migration name when promptedApply/rollback:
make migration/up
make migration/downTesting and quality:
make test # unit tests (short)
make test-full # all tests with coverage
make coverage # HTML coverage report
make lint # golangci-lint
make gosec # security scan- Views are built with
templ. Runmake generateafter editing.templfiles. - PostgreSQL adapters are in
gateways/repository/pgand generated bysqlc. - Apps construct dependencies and wire use cases; business logic stays in
domain/.
MIT