Configuration
A complete reference for every environment variable in your Grit project. All configuration is done through the .env file at the project root.
Environment Files
Every Grit project includes three environment files:
.env-- Your actual configuration. This file is gitignored and never committed..env.example-- Documented template with all variables and sensible defaults. Committed to git..env.cloud.example-- Template for cloud-only setups (Neon, Upstash, R2) when you do not have Docker.
The Go API loads these variables at startup using godotenv and parses them into a typed Config struct. Environment variables are read once at startup and are available throughout the application.
Application
General application settings that control the server behavior.
# App — General application settings APP_NAME=myapp # Application name (used in emails, logs) APP_ENV=development # Environment: development, staging, production APP_PORT=8080 # API server port APP_URL=http://localhost:8080
APP_NAMEProject nameUsed as the application title in email templates, log entries, and the admin panel header. Set to your project name during scaffolding.
APP_ENVdevelopmentControls logging verbosity, GORM Studio visibility, and error detail level. Set to production in deployed environments to disable debug features.
APP_PORT8080The port the Go API server listens on. The frontend apps proxy API requests to this port.
APP_URLhttp://localhost:8080The full URL of the API server. Used for generating absolute URLs in emails and file storage signed URLs.
Database
Grit uses PostgreSQL as its primary database, connected through GORM. The connection string follows the standard PostgreSQL URI format.
# Database — PostgreSQL connection DATABASE_URL=postgres://grit:grit@localhost:5432/myapp?sslmode=disable
DATABASE_URLPostgreSQL connection string. Format: postgres://user:password@host:port/database?sslmode=disable
For local development with Docker, the default credentials are grit:grit on port 5432. For cloud databases like Neon, use the connection string provided by your provider and set sslmode=require.
JWT Authentication
Grit uses JWT tokens for authentication with separate access and refresh tokens. The access token is short-lived (15 minutes) and the refresh token lasts 7 days.
# JWT — Authentication tokens JWT_SECRET=your-super-secret-jwt-key-change-in-production JWT_ACCESS_EXPIRY=15m # Access token lifetime JWT_REFRESH_EXPIRY=168h # Refresh token lifetime (7 days)
JWT_SECRETRandom stringThe secret key used to sign and verify JWT tokens. MUST be changed in production. Use a random string of at least 32 characters. Both access and refresh tokens use this same secret.
JWT_ACCESS_EXPIRY15mHow long access tokens are valid. Uses Go duration format: 15m (15 minutes), 1h (1 hour), etc. Keep short for security. The frontend automatically refreshes expired tokens.
JWT_REFRESH_EXPIRY168hHow long refresh tokens are valid. 168h is 7 days. Users must re-login after this period. Refresh tokens are single-use and rotated on each refresh.
Redis
Redis is used for response caching and background job queues (via Asynq). A single Redis instance handles both use cases.
# Redis — Cache and job queue REDIS_URL=redis://localhost:6379
REDIS_URLredis://localhost:6379Redis connection URL. For local Docker, uses port 6379 with no authentication. For cloud Redis (Upstash), use the rediss:// protocol (with double s) and include the password: rediss://default:password@endpoint:6379.
File Storage
Grit supports three S3-compatible storage providers: MinIO (local development), Cloudflare R2, and Backblaze B2. The STORAGE_DRIVER variable controls which provider is active.
# Storage — Active driver: minio, r2, or b2 STORAGE_DRIVER=minio # MinIO — Local S3-compatible storage (default for development) MINIO_ENDPOINT=http://localhost:9000 MINIO_ACCESS_KEY=minioadmin MINIO_SECRET_KEY=minioadmin MINIO_BUCKET=myapp-uploads MINIO_REGION=us-east-1 MINIO_USE_SSL=false # Cloudflare R2 — S3-compatible object storage R2_ENDPOINT=https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com R2_ACCESS_KEY= # R2 Access Key ID R2_SECRET_KEY= # R2 Secret Access Key R2_BUCKET=myapp-uploads R2_REGION=auto # Always "auto" for R2 # Backblaze B2 — S3-compatible object storage B2_ENDPOINT=https://s3.us-west-004.backblazeb2.com B2_ACCESS_KEY= # B2 keyID B2_SECRET_KEY= # B2 applicationKey B2_BUCKET=myapp-uploads B2_REGION=us-west-004 # Must match your bucket region
STORAGE_DRIVERminioWhich storage provider to use. Options: minio (local dev with Docker), r2 (Cloudflare R2), b2 (Backblaze B2). Only the variables for the active driver need to be set.
MINIO_ENDPOINThttp://localhost:9000MinIO server URL. The Docker Compose file starts MinIO on port 9000 with a web console on port 9001.
MINIO_ACCESS_KEY / MINIO_SECRET_KEYminioadminDefault MinIO credentials. These match the Docker Compose configuration. Change in production if running your own MinIO instance.
R2_ENDPOINT(your account)Your Cloudflare R2 endpoint. Get this from the Cloudflare Dashboard under R2 > Overview. Format: https://ACCOUNT_ID.r2.cloudflarestorage.com
R2_ACCESS_KEY / R2_SECRET_KEY(your keys)Cloudflare R2 API credentials. Create an API token in the Cloudflare Dashboard under R2 > Manage R2 API Tokens.
B2_ENDPOINT(your region)Backblaze B2 S3-compatible endpoint. Format depends on your bucket region. Find it in your B2 bucket settings.
Grit uses Resend for transactional emails -- welcome emails, password resets, and notifications. In development, emails are caught by Mailhog (accessible at http://localhost:8025).
# Email — Resend integration RESEND_API_KEY=re_your_api_key MAIL_FROM=noreply@myapp.dev
RESEND_API_KEYre_your_api_keyYour Resend API key. Get one at resend.com/api-keys. In development, emails are sent to Mailhog regardless of this key.
MAIL_FROMnoreply@myapp.devThe sender email address for all outgoing emails. Must be a verified domain in your Resend account for production use.
CORS
Cross-Origin Resource Sharing configuration. The Go API needs to know which frontend origins are allowed to make requests.
# CORS — Allowed frontend origins (comma-separated) CORS_ORIGINS=http://localhost:3000,http://localhost:3001
CORS_ORIGINShttp://localhost:3000,http://localhost:3001Comma-separated list of allowed origins. In development, port 3000 is the web app and port 3001 is the admin panel. In production, set this to your actual domain names (e.g., https://myapp.com,https://admin.myapp.com).
GORM Studio
The embedded visual database browser. Accessible at /studio on the API server.
# GORM Studio — Visual database browser GORM_STUDIO_ENABLED=true
GORM_STUDIO_ENABLEDtrueEnable or disable GORM Studio. Set to true in development for visual database browsing. Set to false in production to disable the database browser and prevent unauthorized access to your data.
AI Integration
Grit ships with built-in AI support for both Anthropic Claude and OpenAI. The AI service provides text completion and streaming endpoints.
# AI — Text generation (Claude or OpenAI) AI_PROVIDER=claude # "claude" or "openai" AI_API_KEY= # Your API key (sk-ant-... or sk-...) AI_MODEL=claude-sonnet-4-5-20250929
AI_PROVIDERclaudeWhich AI provider to use. Options: claude (Anthropic) or openai. The AI service uses the appropriate API format based on this setting.
AI_API_KEY(your key)Your AI provider API key. For Anthropic, starts with sk-ant-. For OpenAI, starts with sk-. Leave empty if you do not use AI features.
AI_MODELclaude-sonnet-4-5-20250929The model to use for completions. For Claude: claude-sonnet-4-5-20250929, claude-opus-4-6, etc. For OpenAI: gpt-4o, gpt-4o-mini, etc.
Frontend URLs
The frontend applications run on their own ports in development. These are configured in each app's package.json and referenced in the CORS configuration.
| Application | Dev URL | Port |
|---|---|---|
| Go API | http://localhost:8080 | 8080 |
| GORM Studio | http://localhost:8080/studio | 8080 |
| Web App (Next.js) | http://localhost:3000 | 3000 |
| Admin Panel (Next.js) | http://localhost:3001 | 3001 |
| PostgreSQL | localhost:5432 | 5432 |
| Redis | localhost:6379 | 6379 |
| MinIO | http://localhost:9000 | 9000 |
| MinIO Console | http://localhost:9001 | 9001 |
| Mailhog | http://localhost:8025 | 8025 |
Complete .env Reference
Here is every environment variable in a single block for quick copy-paste:
# App APP_NAME=myapp APP_ENV=development APP_PORT=8080 APP_URL=http://localhost:8080 # Database DATABASE_URL=postgres://grit:grit@localhost:5432/myapp?sslmode=disable # JWT JWT_SECRET=change-me-in-production JWT_ACCESS_EXPIRY=15m JWT_REFRESH_EXPIRY=168h # Redis REDIS_URL=redis://localhost:6379 # Storage STORAGE_DRIVER=minio MINIO_ENDPOINT=http://localhost:9000 MINIO_ACCESS_KEY=minioadmin MINIO_SECRET_KEY=minioadmin MINIO_BUCKET=myapp-uploads MINIO_REGION=us-east-1 MINIO_USE_SSL=false # Email RESEND_API_KEY=re_your_api_key MAIL_FROM=noreply@myapp.dev # CORS CORS_ORIGINS=http://localhost:3000,http://localhost:3001 # GORM Studio GORM_STUDIO_ENABLED=true # AI AI_PROVIDER=claude AI_API_KEY= AI_MODEL=claude-sonnet-4-5-20250929
Production Checklist
Before deploying to production, make sure you have addressed these configuration items:
- Change
JWT_SECRETto a strong random string (at least 32 characters) - Set
APP_ENV=productionto disable debug logging and GORM Studio - Set
GORM_STUDIO_ENABLED=falseto disable the database browser - Update
DATABASE_URLto point to your production database - Update
CORS_ORIGINSto your production domain names - Set
STORAGE_DRIVERtor2orb2and configure cloud credentials - Set
RESEND_API_KEYwith your production API key and verify your sender domain - Update
REDIS_URLto your production Redis instance - Set
APP_URLto your production API domain