Configuration
Generated projects use a layered configuration strategy:
configs/config.yamlfor safe defaults..envfor local secrets and machine-specific values.- Real environment variables for production and CI/CD.
Environment variables take precedence over .env, and .env takes precedence over YAML defaults.
Files
configs/config.yaml
Committed to source control.
Use it for:
- application name
- host and port defaults
- log level defaults
- non-secret feature defaults
- database host/port/name defaults for local development
Do not put production secrets here.
.env.example
Committed to source control.
Use it as a template showing which environment variables a developer or deployment needs.
.env
Not committed.
Use it locally for:
- database passwords
- JWT secrets
- API keys
- local overrides
Create it from the example file:
cp .env.example .env
.crank.yaml
Committed to source control.
This is the crank project manifest. It is not application runtime configuration. It tells the CLI which features are enabled and what module path the project uses.
AI coding agents should also use .crank.yaml to detect Crank-generated projects and avoid assuming optional features are installed. See AI agent support.
Common application settings
A generated project commonly includes YAML like this:
app:
name: myapp
host: 0.0.0.0
port: 8080
env: development
logging:
level: debug
format: json
ORM-backed projects include database settings:
database:
host: localhost
port: 5432
user: postgres
password: postgres
name: myapp
sslmode: disable
Auth-backed projects include JWT settings:
jwt:
expiration: 24h
refresh_expiration: 168h
Secrets such as JWT_SECRET should come from .env or the environment.
Database URL resolution
crank migrate resolves the database URL in this order:
--database-urlDATABASE_URLdatabase:values fromconfigs/config.yaml
Examples:
crank migrate up --database-url postgres://postgres:postgres@localhost:5432/myapp?sslmode=disable
DATABASE_URL=postgres://postgres:postgres@localhost:5432/myapp?sslmode=disable crank migrate up
crank migrate up
Feature config injection
When you run:
crank add redis --project ./myapp
crank injects the Redis config fields and YAML/env sections into existing files. It uses marker comments such as:
// crank:config-fields
// crank:config-structs
// crank:config-defaults
and YAML/env markers such as:
# crank:config-section
# crank:env-section
This keeps additions idempotent and preserves your edits.
Adding validation rules
Generated projects include validator setup in:
internal/validator/validator.go
internal/validator/errors.go
To add a custom validation tag:
validate.RegisterValidation("notblank", func(fl validator.FieldLevel) bool {
return strings.TrimSpace(fl.Field().String()) != ""
})
Then use it in request structs:
type CreateOrderInput struct {
ProductID string `json:"product_id" validate:"required,uuid"`
Quantity int `json:"quantity" validate:"required,gt=0,lte=999"`
Notes string `json:"notes" validate:"max=500"`
}
Add a human-readable error message in internal/validator/errors.go so API clients receive clear feedback.
Production recommendations
- Set secrets as real environment variables or through your platformβs secret manager.
- Keep
configs/config.yamlfree of passwords and tokens. - Use a strong
JWT_SECRETin auth-enabled projects. - Set
APP_ENV=productionor the generated equivalent environment field. - Use
DATABASE_URLfor migrations in CI/CD. - Run
crank doctor,crank test, andcrank vetbefore deploying.