askill
go-service-bootstrap

go-service-bootstrapSafety --Repository

Service bootstrap in Go: manual dependency injection, environment-based configuration, composition root wiring, graceful shutdown, and multi-environment conventions. Trigger: When wiring dependencies in main.go, setting up configuration, managing secrets, or configuring environment-specific behavior.

0 stars
1.2k downloads
Updated 2/9/2026

Package Files

Loading files...
SKILL.md

When to Use

  • Setting up main.go to wire all dependencies
  • Adding environment-based configuration
  • Managing secrets (DB passwords, API keys)
  • Deciding what changes between local/dev/staging/prod
  • Adding a new adapter/implementation swap
  • Setting up docker-compose profiles

Critical Patterns

PatternRule
Manual DINo DI frameworks (no Wire, no Dig) — Go's simplicity is the feature
Constructor injectionAll dependencies via NewXxx(deps...) constructors
Config from environmentAll configuration from env vars, no config files in production
Secrets via envSecrets injected via environment, never hardcoded or in repo
Wire in main.gocmd/server/main.go is the ONLY place that knows all concrete types
Same code, different configNever if env == "production" in domain — only in config and infra

Environments

EnvironmentAPP_ENVPurpose
locallocalDeveloper machine, docker-compose, fast feedback
devdevelopmentShared cloud environment for team integration
stagingstagingPre-production replica, QA and smoke tests
productionproductionLive, real users, real money

What Changes Per Environment

Logging

Settinglocaldevstagingproduction
FormattextJSONJSONJSON
Leveldebugdebuginfoinfo
Source locationyesyesnono

Database

Settinglocal (no Docker)local (Docker)devstagingproduction
Providermemorypostgrespostgrespostgrespostgres
HostN/AlocalhostCloud SQL / RDSCloud SQL / RDSCloud SQL / RDS
SSLN/Adisablerequirerequireverify-full
Max connectionsN/A5102025
Password sourceN/A.env fileSecret managerSecret managerSecret manager

The in-memory provider uses a pure Go map-based repository — zero external dependencies. See go-repository-pattern skill for implementation details.

Observability

Settinglocaldevstagingproduction
Tracingdisabled or Jaeger localOTel Collector → JaegerOTel Collector → Jaeger + S3OTel Collector → Jaeger + S3
Trace sampling100%100%50%10%
MetricsdisabledPrometheusPrometheusPrometheus + S3 export

Messaging

Settinglocaldevstagingproduction
ProviderNATS (docker-compose)NATS clusterNATS clusterNATS cluster
URLnats://localhost:4222Cloud endpointCloud endpointCloud endpoint

Object Storage

Settinglocaldevstagingproduction
ProviderMinIO (docker-compose)S3 / GCSS3 / GCSS3 / GCS
Endpointhttp://localhost:9000(default SDK)(default SDK)(default SDK)
Force path styletruefalsefalsefalse

Security

Settinglocaldevstagingproduction
CORS origins**.bastet.dev*.bastet.devbastet.cl
Rate limitingdisabledsoft limitsproduction limitsproduction limits
JWT validationmock / disabledrealrealreal
Swagger UIenabledenabledenableddisabled

Configuration

See assets/config.go — centralized config struct with typed helpers.

All configuration loaded once via config.Load(). Typed helpers: getEnv, requireEnv, getEnvInt, getEnvBool, getEnvDuration.


main.go — The Composition Root

See assets/main.go

The composition root follows a numbered sequence:

  1. Load config
  2. Setup logger
  3. Infrastructure — databases
  4. Infrastructure — messaging
  5. Infrastructure — storage
  6. Repositories (adapters)
  7. Application services (use cases)
  8. HTTP handlers
  9. Router
  10. Start server

Logger Setup

See assets/logger.go — environment-aware slog configuration (text for local, JSON for others).


Health Check Convention

Every service exposes two endpoints:

EndpointPurposeWhen it fails
GET /healthLiveness — is the process alive?Restart the container
GET /readyReadiness — can it serve traffic?Stop sending traffic

See assets/health_check.go


Graceful Shutdown

See assets/server.go — listens for context cancellation, 10-second shutdown timeout.


Environment Variable Files

api/{service}/
  .env.example        # Committed — all keys, safe defaults for local
  .env                 # NOT committed — developer's local overrides

See assets/env.example

NEVER commit .env — only .env.example.

Secrets (dev/staging/prod)

Secrets are NEVER in env files for non-local environments. Use:

ProviderTool
GCPGoogle Secret Manager
AWSAWS Secrets Manager / SSM Parameter Store
KubernetesSealed Secrets / External Secrets Operator

Secrets are injected as environment variables at runtime by the orchestrator.


Docker-Compose Profiles

See assets/docker-compose.example.yml

# Start everything
docker-compose --profile local up -d

# Start only infra (DB, NATS, MinIO) — run services natively
docker-compose --profile infra up -d

# Start only observability stack
docker-compose --profile observability up -d

Assets

FileDescription
assets/config.goCentralized config struct with typed env helpers
assets/main.goComposition root with numbered wiring sequence
assets/logger.goEnvironment-aware slog setup
assets/server.goGraceful HTTP server with shutdown
assets/health_check.goLiveness and readiness endpoints
assets/env.exampleEnvironment variable template for local dev
assets/docker-compose.example.ymlDocker-compose with profiles for local dev

Commands

# Local dev with .env
cp .env.example .env
docker-compose --profile infra up -d
go run ./cmd/server

# Or use direnv
echo 'dotenv' > .envrc && direnv allow

# Run with specific env
APP_ENV=development go run ./cmd/server

# Verify environment
curl http://localhost:8080/health

Anti-Patterns

Don'tDo
DI frameworks (Wire, Dig, fx)Manual constructor injection in main.go
Global variables for DB/configPass dependencies through constructors
Config files (YAML/TOML) in productionEnvironment variables only
Secrets in repo or config filesInject via env vars, use secret manager in CI/CD
Init functions with side effectsExplicit initialization in main.go
Scattered os.Getenv callsCentralized config.Load()
if env == "production" in domainEnvironment logic in config and infrastructure only
Different code paths per environmentSame code, different configuration
Skip SSL in stagingStaging mirrors production security
Disable rate limiting in stagingStaging mirrors production limits
Hardcode environment valuesAlways read from os.Getenv via config.Load()

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

AI review pending.

Metadata

Licenseunknown
Version-
Updated2/9/2026
Publisher333-333-333

Tags

apici-cddatabaseobservabilitysecurity