
Gitlab Stack Config Generator
- 247 installs
- 56 repo stars
- Updated October 20, 2025
- rknall/claude-skills
Use gitlab stack config generator for development tasks
About
gitlab stack config generator: A skill for development. This provides functionality for development workflows.
- gitlab stack config generator
Gitlab Stack Config Generator by the numbers
- 247 all-time installs (skills.sh)
- +9 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #1,558 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/rknall/claude-skills --skill gitlab-stack-config-generatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 247 |
|---|---|
| repo stars | ★ 56 |
| Last updated | October 20, 2025 |
| Repository | rknall/claude-skills ↗ |
What it does
Use gitlab stack config generator for development tasks
Files
GitLab Stack Config Generator
This skill generates and manages service-specific configuration files for GitLab stack projects, ensuring configurations follow proper patterns, use .env for all variables, and never contain secrets.
When to Use This Skill
Activate this skill when the user requests:
- Generate configuration files for services (nginx, PostgreSQL, Redis, etc.)
- Create config templates for new services
- Set up ./config directory structure
- Validate existing configuration files
- Ensure configs use .env variables correctly
- Check that configs don't contain secrets
- Set up project meta files (CLAUDE.md, .gitignore, .dockerignore)
- Sync .env and .env.example
Core Configuration Principles
CRITICAL RULES:
1. ./env is Configuration Source: All configuration variables in .env (NOT in config files) 2. No Secrets in Configs: NEVER put secrets in configuration files (use secrets-manager) 3. Service Directories: Each service gets ./config/service-name/ directory 4. Flat Inside Service: Config files flat inside service directory 5. .env Sync: .env and .env.example MUST always match 6. Path Validation: All referenced paths must exist 7. Docker Validation: Use docker-validation skill for Docker configs 8. Project Meta Files: CLAUDE.md, .gitignore, .dockerignore required
Configuration Workflow
Phase 1: Understanding Requirements
Step 1: Determine What to Generate
Ask the user (or infer):
- Which services need configuration?
- New configs or updating existing?
- Production, development, or both?
- Which templates to use (if any)?
Step 2: Check Current State
1. Does ./config directory exist? 2. Does .env exist? 3. Does .env.example exist? 4. Do service directories already exist? 5. Are meta files present (CLAUDE.md, .gitignore, .dockerignore)?
Phase 2: Directory Structure Setup
Step 1: Create ./config Directory
mkdir -p ./config
chmod 755 ./configStep 2: Create Service Directories
For each service (e.g., nginx, postgres, redis):
mkdir -p ./config/nginx
mkdir -p ./config/postgres
mkdir -p ./config/redis
chmod 755 ./config/*Directory Structure:
./config/
├── nginx/
│ ├── nginx.conf
│ ├── ssl/
│ │ └── (SSL configs, not certificates)
│ └── conf.d/
│ └── default.conf
├── postgres/
│ ├── postgresql.conf
│ └── init.sql
├── redis/
│ └── redis.conf
└── app/
└── settings.ymlPrinciples:
- One directory per service
- Flat structure inside each service directory
- Subdirectories only when logically needed (e.g., nginx/ssl/, nginx/conf.d/)
Phase 3: Meta Files Generation
CRITICAL: Always ensure these files exist
Step 1: Generate CLAUDE.md
Create CLAUDE.md in project root:
# CLAUDE.md
This file provides guidance when working with code in this repository.
## Repository Purpose
[Brief description of the stack project]
## Stack Architecture
This is a GitLab stack project following these principles:
- **Configuration**: All variables in .env, configs in ./config
- **Secrets**: All secrets in ./secrets via Docker secrets
- **Structure**: Standard directories (./config, ./secrets, ./_temporary)
- **Docker**: Modern Docker Compose (no version field)
- **Ownership**: No root-owned files
## Working with This Stack
### Configuration Files
All service configurations are in `./config/[service-name]/` directories.
Configuration values are loaded from `.env` file.
### Environment Variables
- `.env` contains all configuration (NOT secrets)
- `.env.example` must match `.env` exactly (critical requirement)
- Update both files when adding new variables
### Secrets Management
All secrets are managed via Docker secrets:
- Location: `./secrets/` directory
- Never in .env or docker-compose.yml
- Use secrets-manager skill for secret operations
### Docker Commands
Start stack
docker compose up -d
View logs
docker compose logs -f
Stop stack
docker compose down
## Important Rules
### Git Commits
**CRITICAL**: When creating commit messages, NEVER mention "Claude" or "Claude Code" in the commit message.
Good commit messages:
- "Add nginx configuration for SSL termination"
- "Update PostgreSQL settings for production"
- "Fix Redis persistence configuration"
Bad commit messages:
- "Claude added nginx config" ❌
- "Asked Claude to update settings" ❌
### File Permissions
All files must be owned by the current user (not root):Check ownership
find . -user root -type f
Fix if needed
sudo chown -R $(id -u):$(id -g) .
### Validation
Before deployment, always run:Validate entire stack
[validation command]
Check secrets
[secrets validation command]
## Directory Structure
./ ├── docker-compose.yml # Main compose file (NO version field) ├── .env # Configuration variables ├── .env.example # Template (must match .env) ├── CLAUDE.md # This file ├── .gitignore # Git exclusions ├── .dockerignore # Docker build exclusions ├── config/ # Service configurations │ ├── nginx/ │ ├── postgres/ │ └── redis/ ├── secrets/ # Docker secrets (NOT in git) │ └── .gitkeep └── _temporary/ # Transient files (NOT in git)
## Skills Available
- **stack-validator**: Validate entire stack before deployment
- **secrets-manager**: Manage Docker secrets securely
- **config-generator**: Generate/update service configurations
- **docker-validation**: Validate Docker configs
---
*Last updated: [date]*Step 2: Generate/Update .gitignore
# Secrets - NEVER commit
/secrets/
/secrets/*
!secrets/.gitkeep
# Environment
.env
.env.local
.env.*.local
# Temporary
/_temporary/
/_temporary/*
# Docker
.dockerignore
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Logs
*.log
logs/
# Build artifacts
dist/
build/
node_modules/
vendor/
# Backup files
*.backup
*.old
*.bakStep 3: Generate .dockerignore
# Git
.git/
.gitignore
# Environment
.env
.env.*
# Secrets
secrets/
# Temporary
_temporary/
# Documentation
*.md
CLAUDE.md
# IDE
.vscode/
.idea/
# OS
.DS_Store
Thumbs.db
# Dependencies (if not needed in build)
node_modules/
vendor/
# Logs
*.log
logs/Phase 4: Service Configuration Generation
Common Services: nginx, PostgreSQL, Redis
For each service, follow this pattern:
Step 1: Determine Configuration Needs
Ask user:
- Use template or custom?
- Which features to enable?
- Production or development settings?
Step 2: Identify Required .env Variables
For each service, list all .env variables needed:
Example for nginx:
- NGINX_PORT
- NGINX_HOST
- NGINX_SSL_ENABLED
- APP_HOST
- APP_PORT
Step 3: Generate Configuration File
CRITICAL: Use environment variable placeholders (${VAR_NAME})
Example nginx.conf:
# Nginx Configuration
# Loads variables from .env
upstream app {
server ${APP_HOST}:${APP_PORT};
}
server {
listen ${NGINX_PORT};
server_name ${NGINX_HOST};
# SSL configuration
# SSL certificates loaded from Docker secrets
# ssl_certificate /run/secrets/ssl_cert;
# ssl_certificate_key /run/secrets/ssl_key;
location / {
proxy_pass http://app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Step 4: Update .env
Add all required variables:
# Nginx Configuration
NGINX_PORT=80
NGINX_HOST=localhost
NGINX_SSL_ENABLED=false
APP_HOST=app
APP_PORT=8080Step 5: Update .env.example
CRITICAL: Must match .env exactly:
# Nginx Configuration
NGINX_PORT=80
NGINX_HOST=localhost
NGINX_SSL_ENABLED=false
APP_HOST=app
APP_PORT=8080Step 6: Update docker-compose.yml
Add volume mount for config:
services:
nginx:
image: nginx:alpine
ports:
- "${NGINX_PORT}:80"
volumes:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
environment:
# Variables loaded from .env automatically
NGINX_HOST: ${NGINX_HOST}
APP_HOST: ${APP_HOST}
APP_PORT: ${APP_PORT}Phase 5: Configuration Validation
Step 1: Syntax Validation
For each config file type:
Nginx:
# Test nginx config
docker run --rm -v $(pwd)/config/nginx:/etc/nginx:ro nginx:alpine nginx -tPostgreSQL:
# Check SQL syntax
# Parse init.sql for syntax errorsRedis:
# Test redis config
docker run --rm -v $(pwd)/config/redis:/usr/local/etc/redis:ro redis:alpine redis-server --test-memory 1024Step 2: Secret Detection (CRITICAL)
Scan all config files for secrets:
# Check for common secret patterns
grep -r -iE "(password|secret|key|token|api_key)" ./config/
# If found, this is CRITICAL SECURITY ISSUE
# Must use secrets-manager to fixStep 3: Path Validation
Check that all referenced paths exist:
1. Config files reference other files? 2. Volume mounts in docker-compose.yml? 3. All paths exist?
Step 4: .env Synchronization (CRITICAL)
# Extract variable names from .env
env_vars=$(grep -E "^[A-Z_]+" .env | cut -d'=' -f1 | sort)
# Extract from .env.example
example_vars=$(grep -E "^[A-Z_]+" .env.example | cut -d'=' -f1 | sort)
# Compare
diff <(echo "$env_vars") <(echo "$example_vars")
# If any difference, this is CRITICAL ERRORStep 5: Docker Validation
CRITICAL: Use docker-validation skill:
"Validate docker-compose.yml using docker-validation skill"Address all findings before completing.
Phase 6: Template Selection
Step 1: Offer Templates
For nginx, PostgreSQL, Redis, offer these options:
Nginx Templates: 1. Simple Reverse Proxy (default)
- Basic proxy to backend service
- No SSL
- Minimal config
2. SSL Termination
- HTTPS enabled
- SSL certificates from Docker secrets
- HTTP to HTTPS redirect
3. Static + Proxy
- Serve static files
- Proxy API requests
- Caching headers
4. Custom
- User provides requirements
- Generate custom config
PostgreSQL Templates: 1. Basic (default)
- Standard settings
- Simple init.sql
- Development friendly
2. Production
- Optimized settings
- Connection pooling
- Performance tuning
3. With Extensions
- PostGIS, UUID, etc.
- Extension-specific config
- Init scripts for extensions
4. Custom
- User-specified
Redis Templates: 1. Cache (default)
- No persistence
- Memory-only
- Fast
2. Persistent
- RDB snapshots
- AOF logging
- Data durability
3. Pub/Sub
- Optimized for messaging
- No persistence
- High throughput
4. Custom
- User requirements
Step 2: Generate from Template
Based on user selection, generate appropriate config with:
- Required .env variables
- Proper docker-compose.yml integration
- README section documenting the config
Phase 7: Validation Report
After generation, provide comprehensive report:
📝 Configuration Generation Report
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Meta Files
✅ CLAUDE.md created
✅ .gitignore updated
✅ .dockerignore created
✅ Directory Structure
✅ ./config/nginx created
✅ ./config/postgres created
✅ ./config/redis created
📄 Generated Configurations
Nginx (Simple Reverse Proxy):
✅ ./config/nginx/nginx.conf
✅ Variables added to .env (3)
✅ .env.example synced
✅ docker-compose.yml updated
✅ Syntax validation: PASS
PostgreSQL (Basic):
✅ ./config/postgres/postgresql.conf
✅ ./config/postgres/init.sql
✅ Variables added to .env (5)
✅ .env.example synced
✅ docker-compose.yml updated
Redis (Cache):
✅ ./config/redis/redis.conf
✅ Variables added to .env (2)
✅ .env.example synced
✅ docker-compose.yml updated
🔐 Security Validation
✅ No secrets in config files
✅ All secrets in ./secrets (via secrets-manager)
✅ Configs use .env variables only
✅ Path Validation
✅ All referenced paths exist
✅ Volume mounts valid
✅ .env Synchronization
✅ .env and .env.example match (10 variables)
🐳 Docker Validation
✅ docker-compose.yml syntax valid
✅ All volume mounts exist
✅ No deprecated syntax
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Configuration generation complete!
Next Steps:
1. Review generated configurations
2. Customize as needed
3. Run: docker compose config (validate)
4. Run: docker compose up -dService-Specific Patterns
Nginx Configuration
Always include:
- Environment variable placeholders
- Upstream backend reference
- Basic security headers
- Logging configuration
Never include:
- Hardcoded IPs or hosts
- SSL certificate content (use Docker secrets)
- Passwords or tokens
Example variables:
NGINX_PORT=80
NGINX_HOST=localhost
NGINX_WORKER_PROCESSES=auto
NGINX_WORKER_CONNECTIONS=1024
APP_BACKEND_HOST=app
APP_BACKEND_PORT=8080PostgreSQL Configuration
Always include:
- Init scripts for database/user creation
- Basic performance tuning
- Connection limits
- Logging settings
Never include:
- Passwords (use Docker secrets)
- Production database names in dev
- Hardcoded connection strings
Example variables:
POSTGRES_DB=myapp_db
POSTGRES_USER=myapp_user
# POSTGRES_PASSWORD in ./secrets/db_password
POSTGRES_MAX_CONNECTIONS=100
POSTGRES_SHARED_BUFFERS=256MBRedis Configuration
Always include:
- Persistence settings
- Memory limits
- Network bindings
Never include:
- Passwords (use Docker secrets if needed)
- Hardcoded master/slave IPs
Example variables:
REDIS_PORT=6379
REDIS_MAXMEMORY=256mb
REDIS_MAXMEMORY_POLICY=allkeys-lru
REDIS_SAVE_ENABLED=falseIntegration with Companion Skills
secrets-manager
When to call:
- Secrets detected in config files → CRITICAL
- Need to reference secrets in configs
- SSL certificates or private keys needed
docker-validation
When to call:
- After updating docker-compose.yml (ALWAYS)
- Before completing generation
- User requests validation
stack-validator
When to call:
- After generation complete
- Validate entire stack
- Ensure all patterns followed
Important Notes
- No Secrets: NEVER put secrets in config files
- .env Source: All configuration from .env
- .env Sync: .env and .env.example must match
- Docker Validation: Always use docker-validation skill
- CLAUDE.md Rule: Must specify no "Claude" in commit messages
- Templates Optional: User chooses defaults or custom
- Path Validation: All paths must exist
Example Workflow
User: "Generate nginx and PostgreSQL configs"
1. Check current state
- ./config missing → create it
- .env exists
- .env.example exists
- CLAUDE.md missing → create it
2. Generate meta files
- Create CLAUDE.md
- Update .gitignore
- Create .dockerignore
3. Ask user for templates
"Which templates would you like?
- Nginx: [Simple Reverse Proxy], SSL Termination, Static + Proxy, Custom
- PostgreSQL: [Basic], Production, With Extensions, Custom"
4. User selects: Simple Reverse Proxy, Basic
5. Generate nginx config
- Create ./config/nginx/nginx.conf
- Add variables to .env
- Sync .env.example
- Update docker-compose.yml
- Validate syntax
6. Generate PostgreSQL config
- Create ./config/postgres/postgresql.conf
- Create ./config/postgres/init.sql
- Add variables to .env
- Sync .env.example
- Update docker-compose.yml
7. Run validations
- Secret detection: PASS
- Path validation: PASS
- .env sync check: PASS
- Docker validation (via docker-validation skill): PASS
8. Generate report
- Show all created files
- List .env variables added
- Confirmation that validations passed
9. Next steps
- Suggest testing: docker compose config
- Recommend: docker compose up -d---
This skill generates service configurations following GitLab stack patterns with strict validation.
GitLab Stack Config Generator
Generate service-specific configuration files for GitLab stack projects with .env as the primary configuration source
Overview
The Config Generator skill creates service configurations for GitLab stack projects, ensuring all configs use .env variables, never contain secrets, and follow proper patterns. It also generates essential project meta files (CLAUDE.md, .gitignore, .dockerignore).
Core Principle: .env is the single source of configuration truth.
Features
- Service Templates: Nginx, PostgreSQL, Redis (more services supported)
- Meta Files: CLAUDE.md, .gitignore, .dockerignore generation
- .env Management: All config from .env, strict .env/.env.example sync
- Security: No secrets in configs (uses secrets-manager)
- Validation: Syntax, paths, Docker configs (uses docker-validation)
- Directory Structure: Service-specific directories with flat configs
When to Use
- Generate configuration files for services
- Set up new stack configurations
- Create project meta files (CLAUDE.md, .gitignore)
- Ensure .env and .env.example are synchronized
- Validate existing configurations
Installation
/plugin marketplace add rknall/Skills
/plugin install config-generatorQuick Start
Generate Service Configs
# Generate nginx and PostgreSQL configs
claude "generate nginx and postgres configs"
# User will be prompted for template selectionGenerate Meta Files Only
# Create CLAUDE.md, .gitignore, .dockerignore
claude "generate project meta files"Available Templates
Nginx
1. Simple Reverse Proxy (default) - Basic proxy to backend 2. SSL Termination - HTTPS with certificates from Docker secrets 3. Static + API Proxy - Serve static files + proxy API 4. Custom - User-specified requirements
PostgreSQL
1. Basic (default) - Standard settings for development 2. Production - Optimized for production with monitoring 3. With Extensions - PostGIS, UUID, etc. 4. Custom - User-specified
Redis
1. Cache (default) - No persistence, memory-only 2. Persistent - RDB + AOF persistence 3. Pub/Sub - Optimized for messaging 4. Custom - User-specified
Configuration Principles
1. .env as Configuration Source
All configuration variables in .env:
# .env
NGINX_PORT=80
NGINX_HOST=localhost
POSTGRES_DB=myapp_db
REDIS_MAXMEMORY=256mb2. No Secrets in Configs
Secrets ONLY in ./secrets via Docker secrets:
# ❌ BAD - Secret in config
password: supersecret123
# ✅ GOOD - Reference to Docker secret
# Password loaded from /run/secrets/db_password3. .env and .env.example Sync
CRITICAL: Must always match:
# Both files must have identical variable names
# Values in .env.example can be defaults/examples4. Service Directory Structure
./config/
├── nginx/
│ └── nginx.conf # Flat inside service dir
├── postgres/
│ ├── postgresql.conf
│ └── init.sql
└── redis/
└── redis.confExample Usage
Complete Stack Setup
claude "Set up config for nginx, postgres, and redis"Workflow: 1. Checks current state 2. Creates ./config/ directories 3. Generates meta files (CLAUDE.md, .gitignore, .dockerignore) 4. Asks for template selection 5. Generates configs with .env variables 6. Syncs .env.example 7. Updates docker-compose.yml 8. Validates (secrets, paths, Docker) 9. Provides comprehensive report
Update Existing Config
claude "Update nginx config to use SSL"Validation
Automatic Checks
1. Secret Detection (CRITICAL)
- Scans all configs for secret patterns
- Uses secrets-manager if found
2. .env Sync (CRITICAL)
- Ensures .env and .env.example match
- Reports any mismatches
3. Path Validation
- All referenced paths exist
- Volume mounts are valid
4. Docker Validation
- Uses docker-validation skill
- Addresses all findings
5. Syntax Validation
- Nginx:
nginx -t - PostgreSQL: SQL syntax
- Redis: Config test
Meta Files Generated
CLAUDE.md
CRITICAL CONTENT:
- "NEVER mention Claude in commit messages"
- Stack architecture overview
- Configuration patterns
- Secrets management rules
- Directory structure
- Available skills
.gitignore
Excludes:
/secrets/*(except .gitkeep).env/_temporary/*- IDE files, OS files
- Logs, backups
.dockerignore
Excludes from Docker builds:
.git/,.env,secrets/- Documentation (
*.md) - IDE files
- Logs
Integration with Companion Skills
secrets-manager
Called when:
- Secrets detected in configs
- SSL certificates needed
- Any secret-related operations
docker-validation
Called for:
- docker-compose.yml validation (ALWAYS)
- Dockerfile validation if present
stack-validator
Used for:
- Complete stack validation after generation
- Ensure all patterns followed
Common Workflows
New Stack Setup
# 1. Generate configs
claude "generate nginx, postgres, redis configs with SSL for nginx"
# 2. Review generated files
ls -la config/
cat .env
cat CLAUDE.md
# 3. Validate
docker compose config
# 4. Start
docker compose up -dAdd Service to Existing Stack
claude "add redis config to my stack"Troubleshooting
Issue: .env and .env.example out of sync
Fix:
claude "sync .env.example with .env"Issue: Secret detected in config
Response:
❌ CRITICAL: Secret detected in ./config/nginx/nginx.conf
Line 15: password=abc123
Action: Use secrets-manager to move to Docker secretsIssue: Docker validation fails
Response: Address docker-validation findings before completing
Reference Documentation
- SKILL.md - Complete workflow and validation
- service-templates.md - All templates with examples
- validation-rules.md - Validation rules reference
Version History
v1.0.0 (2025-10-20)
- Initial release
- Nginx, PostgreSQL, Redis templates
- Meta files generation (CLAUDE.md, .gitignore, .dockerignore)
- Strict secret and .env validation
- Integration with secrets-manager and docker-validation
---
Generate secure, validated service configurations following GitLab stack patterns.
Service Configuration Templates
This document provides ready-to-use configuration templates for common services in GitLab stack projects.
Table of Contents
1. Nginx Templates 2. PostgreSQL Templates 3. Redis Templates 4. Template Variables Reference
---
Nginx Templates
Template 1: Simple Reverse Proxy (Default)
Use Case: Basic reverse proxy to backend application
Files:
./config/nginx/nginx.conf
nginx.conf:
# Nginx Configuration - Simple Reverse Proxy
# Variables loaded from .env
events {
worker_connections ${NGINX_WORKER_CONNECTIONS};
}
http {
# Basic settings
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
# Performance
sendfile on;
keepalive_timeout 65;
# Upstream backend
upstream backend {
server ${APP_BACKEND_HOST}:${APP_BACKEND_PORT};
}
server {
listen ${NGINX_PORT};
server_name ${NGINX_HOST};
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Proxy to backend
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Health check
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
}.env variables:
# Nginx - Simple Reverse Proxy
NGINX_PORT=80
NGINX_HOST=localhost
NGINX_WORKER_CONNECTIONS=1024
APP_BACKEND_HOST=app
APP_BACKEND_PORT=8080docker-compose.yml:
services:
nginx:
image: nginx:alpine
container_name: ${COMPOSE_PROJECT_NAME}-nginx
restart: unless-stopped
ports:
- "${NGINX_PORT}:80"
volumes:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- app
networks:
- app-network---
Template 2: SSL Termination
Use Case: HTTPS with SSL certificate from Docker secrets
Files:
./config/nginx/nginx.conf
nginx.conf:
# Nginx Configuration - SSL Termination
# SSL certificates from Docker secrets
events {
worker_connections ${NGINX_WORKER_CONNECTIONS};
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
sendfile on;
keepalive_timeout 65;
upstream backend {
server ${APP_BACKEND_HOST}:${APP_BACKEND_PORT};
}
# HTTP server - redirect to HTTPS
server {
listen 80;
server_name ${NGINX_HOST};
location / {
return 301 https://$server_name$request_uri;
}
}
# HTTPS server
server {
listen 443 ssl http2;
server_name ${NGINX_HOST};
# SSL certificates from Docker secrets
ssl_certificate /run/secrets/ssl_cert;
ssl_certificate_key /run/secrets/ssl_key;
# SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
}.env variables:
# Nginx - SSL Termination
NGINX_HOST=example.com
NGINX_WORKER_CONNECTIONS=1024
APP_BACKEND_HOST=app
APP_BACKEND_PORT=8080Required secrets (via secrets-manager):
ssl_cert- SSL certificatessl_key- SSL private key
docker-compose.yml:
services:
nginx:
image: nginx:alpine
container_name: ${COMPOSE_PROJECT_NAME}-nginx
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
secrets:
- ssl_cert
- ssl_key
depends_on:
- app
networks:
- app-network
secrets:
ssl_cert:
file: ./secrets/ssl_cert.pem
ssl_key:
file: ./secrets/ssl_key.pem---
Template 3: Static Files + API Proxy
Use Case: Serve static frontend, proxy API requests to backend
Files:
./config/nginx/nginx.conf
nginx.conf:
# Nginx Configuration - Static + API Proxy
events {
worker_connections ${NGINX_WORKER_CONNECTIONS};
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on;
gzip_vary on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
upstream api {
server ${API_BACKEND_HOST}:${API_BACKEND_PORT};
}
server {
listen ${NGINX_PORT};
server_name ${NGINX_HOST};
root ${NGINX_STATIC_ROOT};
index index.html;
# Static files
location / {
try_files $uri $uri/ /index.html;
expires 1h;
add_header Cache-Control "public, immutable";
}
# API proxy
location /api/ {
proxy_pass http://api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# No caching for API
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# Assets with long cache
location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
}.env variables:
# Nginx - Static + API Proxy
NGINX_PORT=80
NGINX_HOST=localhost
NGINX_WORKER_CONNECTIONS=1024
NGINX_STATIC_ROOT=/usr/share/nginx/html
API_BACKEND_HOST=api
API_BACKEND_PORT=3000docker-compose.yml:
services:
nginx:
image: nginx:alpine
container_name: ${COMPOSE_PROJECT_NAME}-nginx
restart: unless-stopped
ports:
- "${NGINX_PORT}:80"
volumes:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./frontend/dist:/usr/share/nginx/html:ro
depends_on:
- api
networks:
- app-network---
PostgreSQL Templates
Template 1: Basic (Default)
Use Case: Standard PostgreSQL for development
Files:
./config/postgres/postgresql.conf./config/postgres/init.sql
postgresql.conf:
# PostgreSQL Configuration - Basic
# Variables from .env where applicable
# Connection settings
listen_addresses = '*'
max_connections = 100
shared_buffers = 128MB
# Logging
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.log'
log_statement = 'all'
log_duration = on
# Performance
effective_cache_size = 256MB
maintenance_work_mem = 64MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100init.sql:
-- PostgreSQL Initialization Script
-- Creates database and user
-- Password loaded from Docker secrets
-- Note: POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD
-- are set via environment and Docker secrets
-- Create extensions if needed
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_USER};.env variables:
# PostgreSQL - Basic
POSTGRES_DB=myapp_db
POSTGRES_USER=myapp_user
# POSTGRES_PASSWORD in ./secrets/db_password
POSTGRES_PORT=5432docker-compose.yml:
services:
postgres:
image: postgres:16-alpine
container_name: ${COMPOSE_PROJECT_NAME}-postgres
restart: unless-stopped
secrets:
- db_password
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
volumes:
- ./config/postgres/postgresql.conf:/etc/postgresql/postgresql.conf:ro
- ./config/postgres/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
- postgres-data:/var/lib/postgresql/data
ports:
- "${POSTGRES_PORT}:5432"
networks:
- app-network
volumes:
postgres-data:
secrets:
db_password:
file: ./secrets/db_password---
Template 2: Production
Use Case: Optimized PostgreSQL for production
Files:
./config/postgres/postgresql.conf./config/postgres/init.sql
postgresql.conf:
# PostgreSQL Configuration - Production Optimized
# Connection settings
listen_addresses = '*'
max_connections = 200
superuser_reserved_connections = 3
# Memory settings (adjust based on available RAM)
shared_buffers = 256MB
effective_cache_size = 1GB
work_mem = 16MB
maintenance_work_mem = 128MB
wal_buffers = 16MB
# Checkpoints
checkpoint_timeout = 15min
checkpoint_completion_target = 0.9
max_wal_size = 2GB
min_wal_size = 1GB
# Performance
random_page_cost = 1.1
effective_io_concurrency = 200
default_statistics_target = 100
# Logging (production level)
log_destination = 'stderr'
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_rotation_age = 1d
log_rotation_size = 100MB
log_min_duration_statement = 1000 # Log slow queries > 1s
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
log_checkpoints = on
log_connections = on
log_disconnections = on
log_lock_waits = on
# Autovacuum (important for production)
autovacuum = on
autovacuum_max_workers = 3
autovacuum_naptime = 10s
# Statement timeout (prevent runaway queries)
statement_timeout = 60000 # 60 secondsinit.sql:
-- PostgreSQL Production Initialization
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
CREATE EXTENSION IF NOT EXISTS "btree_gin";
CREATE EXTENSION IF NOT EXISTS "btree_gist";
-- Performance monitoring
CREATE EXTENSION IF NOT EXISTS "pg_stat_statements";
-- Grant privileges
GRANT ALL PRIVILEGES ON DATABASE ${POSTGRES_DB} TO ${POSTGRES_USER};
-- Create schema
CREATE SCHEMA IF NOT EXISTS app AUTHORIZATION ${POSTGRES_USER};.env variables:
# PostgreSQL - Production
POSTGRES_DB=prod_db
POSTGRES_USER=app_user
# POSTGRES_PASSWORD in ./secrets/db_password
POSTGRES_PORT=5432
POSTGRES_MAX_CONNECTIONS=200---
Redis Templates
Template 1: Cache (Default)
Use Case: Redis as in-memory cache (no persistence)
Files:
./config/redis/redis.conf
redis.conf:
# Redis Configuration - Cache (No Persistence)
# Network
bind 0.0.0.0
port 6379
protected-mode no
# Memory
maxmemory 256mb
maxmemory-policy allkeys-lru
# Persistence disabled for cache
save ""
appendonly no
# Performance
tcp-backlog 511
timeout 0
tcp-keepalive 300
# Logging
loglevel notice
logfile ""
# Snapshotting disabled
stop-writes-on-bgsave-error no.env variables:
# Redis - Cache
REDIS_PORT=6379
REDIS_MAXMEMORY=256mb
REDIS_MAXMEMORY_POLICY=allkeys-lrudocker-compose.yml:
services:
redis:
image: redis:7-alpine
container_name: ${COMPOSE_PROJECT_NAME}-redis
restart: unless-stopped
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./config/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
ports:
- "${REDIS_PORT}:6379"
networks:
- app-network---
Template 2: Persistent
Use Case: Redis with data persistence
Files:
./config/redis/redis.conf
redis.conf:
# Redis Configuration - Persistent
# Network
bind 0.0.0.0
port 6379
protected-mode no
# Memory
maxmemory 512mb
maxmemory-policy allkeys-lru
# RDB Persistence
save 900 1 # Save after 900 sec if 1 key changed
save 300 10 # Save after 300 sec if 10 keys changed
save 60 10000 # Save after 60 sec if 10000 keys changed
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
# AOF Persistence
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# Performance
tcp-backlog 511
timeout 0
tcp-keepalive 300
# Logging
loglevel notice
logfile "".env variables:
# Redis - Persistent
REDIS_PORT=6379
REDIS_MAXMEMORY=512mb
REDIS_MAXMEMORY_POLICY=allkeys-lrudocker-compose.yml:
services:
redis:
image: redis:7-alpine
container_name: ${COMPOSE_PROJECT_NAME}-redis
restart: unless-stopped
command: redis-server /usr/local/etc/redis/redis.conf
volumes:
- ./config/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
- redis-data:/data
ports:
- "${REDIS_PORT}:6379"
networks:
- app-network
volumes:
redis-data:---
Template 3: Pub/Sub
Use Case: Redis for messaging/pub-sub (no persistence)
Files:
./config/redis/redis.conf
redis.conf:
# Redis Configuration - Pub/Sub
# Network
bind 0.0.0.0
port 6379
protected-mode no
# Memory (higher for message buffers)
maxmemory 1gb
maxmemory-policy noeviction
# No persistence for pub/sub
save ""
appendonly no
# Pub/Sub specific
client-output-buffer-limit pubsub 32mb 8mb 60
# Performance
tcp-backlog 511
timeout 0
tcp-keepalive 60
# Logging
loglevel notice
logfile "".env variables:
# Redis - Pub/Sub
REDIS_PORT=6379
REDIS_MAXMEMORY=1gb---
Template Variables Reference
Nginx Variables
| Variable | Default | Description |
|---|---|---|
| NGINX_PORT | 80 | Port nginx listens on |
| NGINX_HOST | localhost | Server name |
| NGINX_WORKER_CONNECTIONS | 1024 | Max connections per worker |
| NGINX_STATIC_ROOT | /usr/share/nginx/html | Static files root |
| APP_BACKEND_HOST | app | Backend service hostname |
| APP_BACKEND_PORT | 8080 | Backend service port |
| API_BACKEND_HOST | api | API service hostname |
| API_BACKEND_PORT | 3000 | API service port |
PostgreSQL Variables
| Variable | Default | Description |
|---|---|---|
| POSTGRES_DB | myapp_db | Database name |
| POSTGRES_USER | myapp_user | Database user |
| POSTGRES_PORT | 5432 | Port PostgreSQL listens on |
| POSTGRES_MAX_CONNECTIONS | 100 | Maximum connections |
Redis Variables
| Variable | Default | Description |
|---|---|---|
| REDIS_PORT | 6379 | Port Redis listens on |
| REDIS_MAXMEMORY | 256mb | Maximum memory |
| REDIS_MAXMEMORY_POLICY | allkeys-lru | Eviction policy |
---
Use these templates as starting points and customize based on specific requirements.
Configuration Validation Rules
Comprehensive validation rules for config-generator skill.
Critical Validation Rules
1. No Secrets in Config Files (CRITICAL)
Rule: Configuration files MUST NEVER contain secrets
Patterns to detect:
- PASSWORD, SECRET, KEY, TOKEN, API, AUTH, CREDENTIAL
- Long random strings (40+ chars)
- Base64-encoded values
- Private keys, certificates with keys
Action: If detected → Use secrets-manager skill immediately
---
2. .env and .env.example Synchronization (CRITICAL)
Rule: Files MUST have identical variable names
Validation:
diff <(grep -E "^[A-Z_]+" .env | cut -d'=' -f1 | sort) \
<(grep -E "^[A-Z_]+" .env.example | cut -d'=' -f1 | sort)Action: If mismatch → Fix synchronization before completing
---
3. Path Existence
Rule: All referenced paths must exist
Check:
- Volume mounts in docker-compose.yml
- File references in configs
- Directory references
---
4. Docker Validation
Rule: Always validate Docker configs
Action: Use docker-validation skill on docker-compose.yml
---
5. CLAUDE.md Requirements
Must contain:
- Statement: "NEVER mention Claude in commit messages"
- Stack architecture overview
- Configuration patterns
- Secrets management rules
---
Validation Checklist
- [ ] No secrets in config files
- [ ] .env and .env.example synced
- [ ] All paths exist
- [ ] Docker validation passed
- [ ] CLAUDE.md exists with commit rule
- [ ] .gitignore has secrets/* excluded
- [ ] .dockerignore exists
---
Strict validation ensures stack security and consistency.