
Gitlab Stack Creator
- 237 installs
- 56 repo stars
- Updated October 20, 2025
- rknall/claude-skills
Use gitlab stack creator for development tasks
About
gitlab stack creator: A skill for development. This provides functionality for development workflows.
- gitlab stack creator
Gitlab Stack Creator by the numbers
- 237 all-time installs (skills.sh)
- +9 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #1,657 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-creatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 237 |
|---|---|
| repo stars | ★ 56 |
| Last updated | October 20, 2025 |
| Repository | rknall/claude-skills ↗ |
What it does
Use gitlab stack creator for development tasks
Files
GitLab Stack Creator
Expert assistance for creating new GitLab stack projects with proper structure, git configuration, validation scripts, and comprehensive documentation.
When to Use This Skill
This skill should be triggered when:
- Creating a new GitLab stack project
- Initializing a Docker stack with proper structure
- Setting up a project with ./config, ./secrets, ./_temporary directories
- Configuring git repository for stack projects
- Setting up validation hooks and scripts
- Bootstrapping a stack project with best practices
Core Principles
This skill follows the GitLab Stack Management patterns:
1. Everything configured through docker-compose.yml and ./config 2. Secrets stored in ./secrets and Docker secrets 3. docker-entrypoint.sh scripts only when containers don't support native secrets 4. All container files owned by the user running docker (no root-owned files) 5. ./_temporary directory for transient setup files (cleaned up after use) 6. Complete validation before considering stack creation complete
Stack Creation is Complete When
A stack creation is considered COMPLETE only when:
1. ✅ stack-validator skill reports NO issues 2. ✅ secrets-manager skill is satisfied with NO open issues 3. ✅ docker-validation skill is satisfied with NO issues 4. ✅ All validation scripts execute successfully 5. ✅ Git repository is properly initialized and configured 6. ✅ Documentation is complete in ./docs
IMPORTANT: NEVER use workarounds. If the direct approach is not working, STOP and ask the user what to do instead.
Stack Creation Workflow
Phase 1: Project Initialization
1.1 Gather Requirements
Ask the user:
- Project name
- Primary services needed (nginx, PostgreSQL, Redis, etc.)
- Remote git repository URL (if any)
- Environment (development, staging, production)
- Special requirements
NEVER assume - always ask if information is missing.
1.2 Check Existing Setup
Before creating anything:
- Check if directory already exists
- Check if git repository exists
- Ask user how to proceed if conflicts exist
- NEVER overwrite without explicit permission
Phase 2: Directory Structure Creation
Create the standard directory structure:
project-name/
├── .git/ # Git repository
│ ├── hooks/ # Git hooks (validation scripts)
│ └── config # Git configuration
├── config/ # Service configurations
│ ├── nginx/ # Nginx configs (if needed)
│ ├── postgres/ # PostgreSQL configs (if needed)
│ └── redis/ # Redis configs (if needed)
├── secrets/ # Docker secrets files
│ └── .gitkeep # Keep directory in git
├── _temporary/ # Temporary files (gitignored)
├── scripts/ # Validation and utility scripts
│ ├── pre-commit # Pre-commit validation hook
│ ├── validate-stack.sh # Full stack validation
│ └── setup-hooks.sh # Hook installation script
├── docs/ # Project documentation
│ ├── decisions/ # Architecture decision records
│ ├── setup.md # Setup instructions
│ └── services.md # Service documentation
├── docker-compose.yml # Main compose file
├── .env.example # Environment template
├── .gitignore # Git exclusions
├── .dockerignore # Docker exclusions
├── CLAUDE.md # Claude Code instructions
└── README.md # Project overviewActions: 1. Create directories: mkdir -p config secrets _temporary scripts docs/decisions 2. Create placeholder files: touch secrets/.gitkeep 3. Set proper permissions: chmod 700 secrets
Phase 3: Git Repository Setup
3.1 Initialize or Connect Repository
If NO git repository exists:
- Strongly suggest creating a local repository
- Ask if remote repository should be added
- Initialize with
git init - Set main as default branch:
git config init.defaultBranch main
If remote repository URL provided:
- Clone repository:
git clone <url> <project-name> - Or add remote:
git remote add origin <url> - Verify remote connection:
git remote -v
If setup fails: STOP and ask user for guidance. NEVER attempt workarounds.
3.2 Configure Git
Set required git configuration:
# Set main as branch name
git config init.defaultBranch main
# Set ff-only merge strategy
git config pull.ff only
git config merge.ff only
# Ensure no rebase by default
git config pull.rebase false
# Set user info if not set globally
git config user.name "User Name"
git config user.email "user@example.com"If configuration fails: Ask user to set configuration manually or provide correct values.
3.3 Create .gitignore
Generate comprehensive .gitignore:
# Secrets - NEVER commit
secrets/*
!secrets/.gitkeep
*.key
*.pem
*.crt
*.p12
*.pfx
# Environment files
.env
.env.local
.env.*.local
# Temporary files
_temporary/
*.tmp
*.temp
.cache/
# Docker
.docker/
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
*.log
# Backup files
*.bak
*.backup3.4 Create .dockerignore
Generate .dockerignore:
.git
.gitignore
README.md
docs/
_temporary/
*.md
.env
.env.example
secrets/
.vscode/
.idea/Phase 4: Validation Scripts Setup
4.1 Create scripts/validate-stack.sh
Generate comprehensive validation script that:
- Calls stack-validator skill
- Calls secrets-manager skill validation
- Calls docker-validation skill
- Reports all issues
- Returns exit code 0 only if all pass
Template:
#!/usr/bin/env bash
set -euo pipefail
echo "=== GitLab Stack Validation ==="
echo
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
ERRORS=0
echo "1. Validating stack structure..."
if ! claude-code-cli run stack-validator; then
echo -e "${RED}✗ Stack validation failed${NC}"
((ERRORS++))
else
echo -e "${GREEN}✓ Stack validation passed${NC}"
fi
echo
echo "2. Validating secrets configuration..."
if ! claude-code-cli run secrets-manager --validate; then
echo -e "${RED}✗ Secrets validation failed${NC}"
((ERRORS++))
else
echo -e "${GREEN}✓ Secrets validation passed${NC}"
fi
echo
echo "3. Validating Docker configuration..."
if ! claude-code-cli run docker-validation; then
echo -e "${RED}✗ Docker validation failed${NC}"
((ERRORS++))
else
echo -e "${GREEN}✓ Docker validation passed${NC}"
fi
echo
if [ $ERRORS -gt 0 ]; then
echo -e "${RED}Validation failed with $ERRORS error(s)${NC}"
exit 1
fi
echo -e "${GREEN}All validations passed!${NC}"
exit 0Make executable: chmod +x scripts/validate-stack.sh
4.2 Create scripts/pre-commit
Generate pre-commit hook:
#!/usr/bin/env bash
set -euo pipefail
echo "Running pre-commit validation..."
# Check for secrets in staged files
if git diff --cached --name-only | grep -qE "secrets/.*[^.gitkeep]|\.env$"; then
echo "ERROR: Attempting to commit secrets or .env file!"
echo "Secrets should never be committed to git."
exit 1
fi
# Check for root-owned files
if find . -user root -not -path "./.git/*" 2>/dev/null | grep -q .; then
echo "ERROR: Root-owned files detected!"
echo "All files should be owned by the user running Docker."
exit 1
fi
# Run quick validation (if available)
if [ -x "./scripts/validate-stack.sh" ]; then
echo "Running stack validation..."
if ! ./scripts/validate-stack.sh; then
echo "ERROR: Stack validation failed!"
echo "Fix issues before committing, or use 'git commit --no-verify' to skip."
exit 1
fi
fi
echo "Pre-commit validation passed!"
exit 0Make executable: chmod +x scripts/pre-commit
4.3 Create scripts/setup-hooks.sh
Generate hook installation script:
#!/usr/bin/env bash
set -euo pipefail
echo "Installing git hooks..."
# Check if .git directory exists
if [ ! -d ".git" ]; then
echo "ERROR: Not a git repository!"
exit 1
fi
# Install pre-commit hook
if [ -f "scripts/pre-commit" ]; then
cp scripts/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
echo "✓ Installed pre-commit hook"
else
echo "✗ scripts/pre-commit not found"
exit 1
fi
echo "Git hooks installed successfully!"Make executable: chmod +x scripts/setup-hooks.sh
After creating scripts: Run ./scripts/setup-hooks.sh to install hooks.
Phase 5: Docker Configuration
5.1 Create docker-compose.yml Template
Generate initial docker-compose.yml based on user requirements:
IMPORTANT: Use the docker-validation skill to ensure the docker-compose.yml follows all best practices.
Basic template structure:
services:
# Services will be added based on requirements
# Example: nginx service
nginx:
image: nginx:alpine
container_name: ${PROJECT_NAME:-project}_nginx
restart: unless-stopped
ports:
- "${NGINX_PORT:-80}:80"
volumes:
- ./config/nginx:/etc/nginx/conf.d:ro
networks:
- app-network
networks:
app-network:
driver: bridge
# Secrets will be defined here when needed
secrets: {}
# Volumes for persistent data
volumes: {}Actions: 1. Generate docker-compose.yml with selected services 2. Use docker-validation skill to validate 3. Fix any issues reported 4. NEVER proceed if validation fails - ask user for guidance
5.2 Create .env.example
Generate environment template:
# Project Configuration
PROJECT_NAME=myproject
# Service Ports
NGINX_PORT=80
# Add more as needed
# Database Configuration (if applicable)
# POSTGRES_PORT=5432
# REDIS_PORT=6379
# IMPORTANT: Copy this file to .env and configure for your environment
# .env is gitignored and should contain actual secretsPhase 6: Configuration Files
Use the config-generator skill to create service-specific configuration files:
Actions: 1. For each service (nginx, PostgreSQL, Redis), invoke config-generator 2. Generate configs in ./config/<service-name>/ 3. Validate generated configs with config-generator validation 4. NEVER proceed with invalid configs - ask user for guidance
Example invocation:
- "Generate nginx production configuration for this stack"
- "Create PostgreSQL development configuration"
- "Generate Redis configuration with persistence"
Phase 7: Secrets Management
Use the secrets-manager skill to set up secrets:
Actions: 1. Identify services that require secrets 2. Use secrets-manager to create secure secrets 3. Configure docker-compose.yml with secret references 4. Generate docker-entrypoint.sh scripts ONLY if containers don't support native Docker secrets 5. Validate with secrets-manager that NO secrets are in .env or docker-compose.yml environment 6. NEVER proceed if secrets-manager reports issues - ask user for guidance
Example invocation:
- "Set up database password secret for PostgreSQL"
- "Create Redis password secret"
- "Generate secure random secret for JWT_SECRET"
Phase 8: Documentation Generation
8.1 Create docs/setup.md
Generate setup documentation:
# Setup Instructions
## Prerequisites
- Docker Engine 20.10+
- Docker Compose V2
- Git
## Initial Setup
1. Clone the repository:git clone <repository-url> cd <project-name>
2. Copy environment template:cp .env.example .env
3. Configure environment:
- Edit .env with your settings
- NEVER commit .env to git
4. Set up secrets:
- Follow secrets/README.md for secret creation
- Use `docker secret create` for each secret
5. Install git hooks:./scripts/setup-hooks.sh
6. Validate stack:./scripts/validate-stack.sh
7. Start services:docker compose up -d
## Validation
Always run validation before deploying:./scripts/validate-stack.sh
This checks:
- Stack structure
- Secrets configuration
- Docker configuration
- File ownership
- Git exclusions8.2 Create docs/services.md
Document all services:
# Services Documentation
## Service Overview
| Service | Port | Purpose | Configuration |
|---------|------|---------|---------------|
| nginx | 80 | Web server | ./config/nginx |
| ... | ... | ... | ... |
## Service Details
### Nginx
**Image**: nginx:alpine
**Purpose**: Web server and reverse proxy
**Configuration**: ./config/nginx/
**Secrets**: None
**Volumes**:
- ./config/nginx:/etc/nginx/conf.d:ro
### [Other Services]
Document each service similarly...8.3 Create docs/decisions/0001-stack-architecture.md
Create architecture decision record:
# 1. Stack Architecture
**Date**: YYYY-MM-DD
## Status
Accepted
## Context
This project uses GitLab Stack Management patterns to ensure:
- Consistent configuration management
- Secure secrets handling
- Proper file ownership
- Validated deployments
## Decision
We will follow these principles:
1. All configuration in docker-compose.yml and ./config
2. All secrets in ./secrets and Docker secrets
3. docker-entrypoint.sh only when necessary
4. No root-owned files
5. ./_temporary for transient files
6. Complete validation before deployment
## Consequences
**Positive**:
- Consistent structure across all stacks
- Automated validation prevents issues
- Secure by default
- Easy to maintain and update
**Negative**:
- Initial setup requires more steps
- Must follow strict patterns
- Validation gates can slow rapid iteration
## Compliance
- stack-validator: Ensures structure compliance
- secrets-manager: Ensures secure secrets
- docker-validation: Ensures Docker best practices8.4 Create CLAUDE.md
Generate Claude Code instructions for the project:
# CLAUDE.md
This file provides guidance to Claude Code when working with this stack project.
## Project Structure
This is a GitLab Stack project following strict patterns:
- Configuration: docker-compose.yml and ./config/
- Secrets: ./secrets/ and Docker secrets
- Temporary: ./_temporary/ (gitignored)
- Documentation: ./docs/
- Validation: ./scripts/
## Required Skills
This project uses these Claude Code skills:
- **stack-validator**: Validate entire stack structure
- **secrets-manager**: Manage Docker secrets securely
- **docker-validation**: Validate Docker configurations
- **config-generator**: Generate service configs
## Git Configuration
**Branch**: main
**Merge Strategy**: ff-only (fast-forward only)
**Hooks**: Pre-commit validation enabled
## Validation Requirements
BEFORE any git commit, ALL these must pass:
1. stack-validator reports NO issues
2. secrets-manager is satisfied
3. docker-validation is satisfied
4. No root-owned files exist
5. No secrets in .env or docker-compose.yml environment
## Making Changes
### Adding a Service
1. Update docker-compose.yml
2. Use config-generator to create configs
3. Use secrets-manager to handle secrets
4. Run ./scripts/validate-stack.sh
5. Fix ALL issues before committing
6. NEVER commit if validation fails
### Modifying Configuration
1. Edit configuration files
2. Validate with docker-validation
3. Run ./scripts/validate-stack.sh
4. Fix ALL issues before committing
### Working with Secrets
1. Use secrets-manager for ALL secret operations
2. NEVER put secrets in .env or docker-compose.yml
3. Use Docker secrets or ./secrets/ directory
4. Validate with secrets-manager before committing
## Commit Standards
**Pre-commit Hook**: Automatically validates before commit
**Skip Hook**: `git commit --no-verify` (emergency only)
**Commit Messages**: Use conventional commits format
Example:feat: add Redis service with persistence fix: correct nginx proxy configuration docs: update setup instructions
## Important Rules
1. NEVER commit secrets to git
2. NEVER create root-owned files
3. NEVER skip validation without asking
4. NEVER use workarounds - ask user instead
5. ALWAYS run validation before committing
6. ALWAYS document decisions in ./docs/decisions/
7. ALWAYS use ff-only merge strategy
8. ALWAYS use main as branch name
## Troubleshooting
### Validation Fails
1. Review validation output
2. Use respective skill to investigate (stack-validator, secrets-manager, docker-validation)
3. Fix reported issues
4. Re-run validation
5. Ask user if stuck - NEVER use workarounds
### Git Conflicts
1. NEVER use rebase without explicit permission
2. Use ff-only merges
3. Ask user how to resolve conflicts
### Permission Issues
1. Check file ownership: `find . -user root`
2. Fix with: `sudo chown -R $USER:$USER .`
3. Validate with stack-validator
## Resources
- Stack Validator Documentation
- Secrets Manager Documentation
- Docker Validation Documentation
- Config Generator Documentation8.5 Create README.md
Generate project README:
# Project Name
Brief description of the project.
## Quick Start
Clone repository
git clone <url> cd <project-name>
Copy environment template
cp .env.example .env
Configure environment (edit .env)
nano .env
Install git hooks
./scripts/setup-hooks.sh
Validate stack
./scripts/validate-stack.sh
Start services
docker compose up -d
## Documentation
- [Setup Instructions](./docs/setup.md)
- [Services Documentation](./docs/services.md)
- [Architecture Decisions](./docs/decisions/)
## Project Structure
. ├── config/ # Service configurations ├── secrets/ # Docker secrets (gitignored except .gitkeep) ├── _temporary/ # Temporary files (gitignored) ├── scripts/ # Validation and utility scripts ├── docs/ # Project documentation └── docker-compose.yml
## Validation
This project uses automated validation:
Full validation
./scripts/validate-stack.sh
Pre-commit validation (automatic)
git commit -m "message"
Validation checks:
- ✓ Stack structure (stack-validator)
- ✓ Secrets configuration (secrets-manager)
- ✓ Docker configuration (docker-validation)
- ✓ File ownership (no root files)
- ✓ Git exclusions (.gitignore)
## Git Workflow
**Branch**: main
**Merge Strategy**: ff-only (fast-forward only)
**Pre-commit Hook**: Enabled (validates before commit)
## Services
| Service | Port | Purpose |
|---------|------|---------|
| ... | ... | ... |
See [Services Documentation](./docs/services.md) for details.
## Development
### Prerequisites
- Docker Engine 20.10+
- Docker Compose V2
- Git
- Bash (for scripts)
### Adding a Service
1. Update docker-compose.yml
2. Generate configs: Use config-generator skill
3. Set up secrets: Use secrets-manager skill
4. Validate: `./scripts/validate-stack.sh`
5. Commit changes
### Making Changes
1. Make your changes
2. Run validation: `./scripts/validate-stack.sh`
3. Fix any issues reported
4. Commit (pre-commit hook will validate again)
## Troubleshooting
### Validation Fails
Run individual validators:
- `claude-code-cli run stack-validator`
- `claude-code-cli run secrets-manager --validate`
- `claude-code-cli run docker-validation`
### Permission Issues
Check for root-owned files:find . -user root -not -path "./.git/*"
Fix ownership:sudo chown -R $USER:$USER .
## License
[Your License]
## Contact
[Your Contact Info]Phase 9: Final Validation
9.1 Run Complete Validation
Execute full validation workflow:
# Run validation script
./scripts/validate-stack.shThis must check: 1. stack-validator: Full structure validation 2. secrets-manager: All secrets properly configured 3. docker-validation: Docker configs valid 4. File ownership: No root-owned files 5. Git setup: Proper .gitignore, hooks installed
9.2 Verification Checklist
Manually verify:
- [ ] All directories created
- [ ] Git repository initialized
- [ ] Git configured (main branch, ff-only)
- [ ] .gitignore and .dockerignore created
- [ ] Validation scripts created and executable
- [ ] Git hooks installed
- [ ] docker-compose.yml created and valid
- [ ] .env.example created
- [ ] Service configs generated (if applicable)
- [ ] Secrets properly configured (if applicable)
- [ ] All documentation created
- [ ] CLAUDE.md created
- [ ] README.md created
- [ ] stack-validator: ✓ NO issues
- [ ] secrets-manager: ✓ NO issues
- [ ] docker-validation: ✓ NO issues
9.3 Complete Stack Creation
ONLY mark stack creation as complete when:
- All validation passes with NO errors
- All documentation is complete
- Git repository is properly configured
- User confirms everything is correct
If ANY validation fails: 1. Report the issue clearly 2. Ask user how to proceed 3. NEVER use workarounds 4. Fix the issue properly 5. Re-validate
Phase 10: Initial Commit
Once all validation passes:
# Stage all files
git add .
# Commit (pre-commit hook will validate)
git commit -m "feat: initial stack setup
- Created directory structure
- Configured git with main branch and ff-only
- Set up validation scripts and hooks
- Generated docker-compose.yml
- Created service configurations
- Set up secrets management
- Added comprehensive documentation"
# Push to remote (if configured)
git push -u origin mainIf commit fails due to pre-commit hook: 1. Review validation output 2. Fix issues 3. Re-run validation 4. Try commit again 5. Ask user if issues persist
Communication Style
When creating a stack:
- Ask clarifying questions for missing information
- Explain each phase before executing
- Report validation results clearly
- NEVER proceed if validation fails
- Ask user for guidance when stuck
- Confirm important decisions before executing
- Document all decisions in ./docs/decisions/
- Provide clear next steps
Integration with Other Skills
stack-validator
- Call at the end of Phase 9 (Final Validation)
- Call in validation scripts
- Call in pre-commit hooks
- NEVER proceed if validation fails
secrets-manager
- Call during Phase 7 (Secrets Management)
- Use for ALL secret operations
- Validate secrets configuration
- NEVER proceed if secrets-manager reports issues
docker-validation
- Call during Phase 5 (Docker Configuration)
- Validate docker-compose.yml
- Validate Dockerfiles (if any)
- Call in validation scripts
- NEVER proceed if docker-validation fails
config-generator
- Call during Phase 6 (Configuration Files)
- Generate service-specific configs
- Use for nginx, PostgreSQL, Redis, etc.
- Validate generated configs
Error Handling
Validation Failure
DO NOT:
- Try workarounds
- Skip validation
- Proceed with errors
- Assume user wants to continue
DO:
- Stop immediately
- Report the issue clearly
- Show validation output
- Ask user how to proceed
- Document the decision
Git Issues
DO NOT:
- Force push
- Skip hooks without permission
- Use rebase without permission
- Modify git history without permission
DO:
- Ask user for guidance
- Explain the issue
- Provide options
- Document the solution
Permission Issues
DO NOT:
- Create root-owned files
- Use sudo without permission
- Skip permission checks
DO:
- Report permission issues
- Ask user to fix ownership
- Validate after fixing
- Document proper ownership
Example Workflows
Workflow 1: Creating a Simple Web Stack
User: "Create a new stack for a web application with nginx"
Assistant: "I'll create a new web stack with nginx. Let me gather some information first."
**Questions**:
1. "What's the project name?"
User: "mywebapp"
2. "Do you have a remote git repository URL?"
User: "https://gitlab.com/user/mywebapp.git"
3. "What environment is this for?"
User: "production"
**Actions**:
1. Create directory structure
2. Initialize git and connect to remote
3. Configure git (main branch, ff-only)
4. Create docker-compose.yml with nginx
5. Use docker-validation to validate
6. Use config-generator to create nginx config
7. Create validation scripts
8. Install git hooks
9. Generate all documentation
10. Run full validation
11. Report status
**Completion**:
"Stack creation complete! All validations passed:
✓ stack-validator: NO issues
✓ secrets-manager: NO issues (no secrets needed)
✓ docker-validation: NO issues
Next steps:
1. Review generated files
2. Customize .env from .env.example
3. Run: docker compose up -d"Workflow 2: Creating a Full Application Stack
User: "Create a stack with nginx, PostgreSQL, and Redis"
Assistant: "I'll create a full application stack. Let me gather information."
**Questions**:
1. "Project name?" → "myapp"
2. "Remote repository?" → "Yes, https://gitlab.com/user/myapp.git"
3. "Environment?" → "production"
**Actions**:
1. Create directory structure with config/{nginx,postgres,redis}
2. Initialize git, connect remote, configure (main, ff-only)
3. Create docker-compose.yml with all three services
4. Validate with docker-validation
5. Use config-generator for each service:
- nginx production config
- PostgreSQL production config
- Redis production config
6. Use secrets-manager for:
- PostgreSQL password
- Redis password
- Create Docker secrets
7. Create validation scripts and install hooks
8. Generate all documentation
9. Run full validation (stack-validator, secrets-manager, docker-validation)
10. Initial commit
**Completion**:
"Stack creation complete! All validations passed:
✓ stack-validator: NO issues
✓ secrets-manager: All secrets properly configured
✓ docker-validation: NO issues
Services configured:
- nginx (port 80)
- PostgreSQL (port 5432, password in Docker secret)
- Redis (port 6379, password in Docker secret)
Next steps:
1. Review secrets in ./secrets/
2. Customize .env from .env.example
3. Run: docker compose up -d"Summary
The stack-creator skill:
1. Integrates with stack-validator, secrets-manager, docker-validation, config-generator 2. Enforces complete validation before considering creation complete 3. NEVER uses workarounds - always asks user for guidance 4. Configures git properly (main branch, ff-only merges) 5. Installs validation hooks and scripts 6. Documents everything in ./docs/ 7. Creates production-ready stacks following GitLab Stack Management patterns
Stack creation is complete ONLY when all three validators pass with NO issues and all documentation is in place.
Git Hooks and Validation Scripts Guide
This guide provides comprehensive examples and guidelines for git hooks and validation scripts used in GitLab Stack projects.
Overview
Git hooks are scripts that run automatically at specific points in the git workflow. For GitLab Stack projects, we use hooks to ensure validation before commits.
Directory Structure
project-name/
├── .git/
│ └── hooks/
│ └── pre-commit # Installed hook
└── scripts/
├── pre-commit # Source hook script
├── validate-stack.sh # Full validation
└── setup-hooks.sh # Hook installerCore Scripts
1. scripts/pre-commit
The pre-commit hook runs before each commit to validate the stack.
Location: scripts/pre-commit Installed to: .git/hooks/pre-commit When it runs: Before git commit
#!/usr/bin/env bash
#
# Pre-commit hook for GitLab Stack validation
# Prevents commits that violate stack patterns
#
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo "========================================="
echo "Pre-commit validation"
echo "========================================="
echo
ERRORS=0
# Check 1: Secrets in staged files
echo "1. Checking for secrets in staged files..."
if git diff --cached --name-only | grep -qE "secrets/.*[^.gitkeep]|\.env$"; then
echo -e "${RED}✗ ERROR: Attempting to commit secrets or .env file!${NC}"
echo " Secrets should NEVER be committed to git."
echo " Files detected:"
git diff --cached --name-only | grep -E "secrets/.*[^.gitkeep]|\.env$" | sed 's/^/ /'
((ERRORS++))
else
echo -e "${GREEN}✓ No secrets in staged files${NC}"
fi
echo
# Check 2: Root-owned files
echo "2. Checking for root-owned files..."
if find . -user root -not -path "./.git/*" 2>/dev/null | grep -q .; then
echo -e "${RED}✗ ERROR: Root-owned files detected!${NC}"
echo " All files should be owned by the user running Docker."
echo " Files detected:"
find . -user root -not -path "./.git/*" 2>/dev/null | sed 's/^/ /'
echo
echo " Fix with: sudo chown -R \$USER:\$USER ."
((ERRORS++))
else
echo -e "${GREEN}✓ No root-owned files${NC}"
fi
echo
# Check 3: Secrets in file content (basic check)
echo "3. Checking for hardcoded secrets in code..."
SUSPICIOUS_PATTERNS=(
"password\s*=\s*['\"][^'\"]+['\"]"
"api[_-]?key\s*=\s*['\"][^'\"]+['\"]"
"secret\s*=\s*['\"][^'\"]+['\"]"
"token\s*=\s*['\"][^'\"]+['\"]"
)
FOUND_SECRETS=false
for pattern in "${SUSPICIOUS_PATTERNS[@]}"; do
if git diff --cached | grep -iE "$pattern" | grep -v "\.example" | grep -q .; then
if [ "$FOUND_SECRETS" = false ]; then
echo -e "${YELLOW}⚠ WARNING: Possible hardcoded secrets detected:${NC}"
FOUND_SECRETS=true
fi
git diff --cached | grep -iE "$pattern" | grep -v "\.example" | sed 's/^/ /'
fi
done
if [ "$FOUND_SECRETS" = true ]; then
echo
echo " Review these carefully. Use environment variables or Docker secrets instead."
echo " If these are false positives, you can proceed."
else
echo -e "${GREEN}✓ No obvious hardcoded secrets${NC}"
fi
echo
# Check 4: Full stack validation (if available)
if [ -x "./scripts/validate-stack.sh" ]; then
echo "4. Running full stack validation..."
if ! ./scripts/validate-stack.sh; then
echo -e "${RED}✗ ERROR: Stack validation failed!${NC}"
echo " Fix all issues before committing."
echo " Or use 'git commit --no-verify' to skip (NOT recommended)."
((ERRORS++))
else
echo -e "${GREEN}✓ Stack validation passed${NC}"
fi
else
echo -e "${YELLOW}⚠ Skipping stack validation (./scripts/validate-stack.sh not found)${NC}"
fi
echo
# Final result
echo "========================================="
if [ $ERRORS -gt 0 ]; then
echo -e "${RED}Pre-commit validation FAILED with $ERRORS error(s)${NC}"
echo "========================================="
echo
echo "To skip this validation (NOT recommended):"
echo " git commit --no-verify"
exit 1
fi
echo -e "${GREEN}Pre-commit validation PASSED!${NC}"
echo "========================================="
exit 0Usage:
# Automatic - runs on every commit
git commit -m "message"
# Skip validation (emergency only)
git commit --no-verify -m "message"---
2. scripts/validate-stack.sh
Comprehensive validation script that runs all validators.
Location: scripts/validate-stack.sh When to run: Before deployment, in CI/CD, or manually
#!/usr/bin/env bash
#
# Full GitLab Stack validation
# Runs all validators to ensure stack compliance
#
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo
echo -e "${BLUE}========================================"
echo "GitLab Stack Validation"
echo "========================================${NC}"
echo
ERRORS=0
WARNINGS=0
# Check if we're in a stack directory
if [ ! -f "docker-compose.yml" ]; then
echo -e "${RED}✗ ERROR: docker-compose.yml not found!${NC}"
echo " Are you in a stack directory?"
exit 1
fi
# Validation 1: Stack Validator
echo -e "${BLUE}[1/4] Running stack-validator...${NC}"
if command -v claude-code >/dev/null 2>&1; then
if claude-code run stack-validator 2>&1 | tee /tmp/stack-validator.log; then
echo -e "${GREEN}✓ Stack validation passed${NC}"
else
echo -e "${RED}✗ Stack validation failed${NC}"
echo " Review output above for details"
((ERRORS++))
fi
else
echo -e "${YELLOW}⚠ Claude Code not available, skipping stack-validator${NC}"
((WARNINGS++))
fi
echo
# Validation 2: Secrets Manager
echo -e "${BLUE}[2/4] Running secrets-manager validation...${NC}"
if command -v claude-code >/dev/null 2>&1; then
if claude-code run secrets-manager --validate 2>&1 | tee /tmp/secrets-manager.log; then
echo -e "${GREEN}✓ Secrets validation passed${NC}"
else
echo -e "${RED}✗ Secrets validation failed${NC}"
echo " Review output above for details"
((ERRORS++))
fi
else
echo -e "${YELLOW}⚠ Claude Code not available, running basic secrets check${NC}"
# Basic secrets check without Claude Code
if find secrets/ -type f ! -name ".gitkeep" 2>/dev/null | grep -q .; then
if grep -r "DOCKER_SECRET" docker-compose.yml >/dev/null 2>&1; then
echo -e "${GREEN}✓ Basic secrets check passed${NC}"
else
echo -e "${YELLOW}⚠ Secrets files found but not referenced in docker-compose.yml${NC}"
((WARNINGS++))
fi
else
echo -e "${GREEN}✓ No secrets configured${NC}"
fi
fi
echo
# Validation 3: Docker Validator
echo -e "${BLUE}[3/4] Running docker-validation...${NC}"
if command -v claude-code >/dev/null 2>&1; then
if claude-code run docker-validation 2>&1 | tee /tmp/docker-validation.log; then
echo -e "${GREEN}✓ Docker validation passed${NC}"
else
echo -e "${RED}✗ Docker validation failed${NC}"
echo " Review output above for details"
((ERRORS++))
fi
else
echo -e "${YELLOW}⚠ Claude Code not available, running basic Docker checks${NC}"
# Basic docker-compose syntax check
if docker compose config >/dev/null 2>&1; then
echo -e "${GREEN}✓ docker-compose.yml syntax valid${NC}"
else
echo -e "${RED}✗ docker-compose.yml syntax invalid${NC}"
((ERRORS++))
fi
fi
echo
# Validation 4: File Ownership
echo -e "${BLUE}[4/4] Checking file ownership...${NC}"
if find . -user root -not -path "./.git/*" 2>/dev/null | grep -q .; then
echo -e "${RED}✗ Root-owned files detected:${NC}"
find . -user root -not -path "./.git/*" 2>/dev/null | sed 's/^/ /'
echo
echo " Fix with: sudo chown -R \$USER:\$USER ."
((ERRORS++))
else
echo -e "${GREEN}✓ No root-owned files${NC}"
fi
echo
# Additional checks
echo -e "${BLUE}Additional checks:${NC}"
# Check .env vs .env.example sync
if [ -f ".env.example" ]; then
ENV_KEYS=$(grep -v '^#' .env.example 2>/dev/null | grep '=' | cut -d= -f1 | sort)
if [ -f ".env" ]; then
ACTUAL_KEYS=$(grep -v '^#' .env 2>/dev/null | grep '=' | cut -d= -f1 | sort)
if [ "$ENV_KEYS" != "$ACTUAL_KEYS" ]; then
echo -e "${YELLOW}⚠ .env and .env.example keys don't match${NC}"
((WARNINGS++))
else
echo -e "${GREEN}✓ .env synced with .env.example${NC}"
fi
else
echo -e "${YELLOW}⚠ .env file not found (expected from .env.example)${NC}"
((WARNINGS++))
fi
fi
# Check git setup
if [ -d ".git" ]; then
# Check default branch
DEFAULT_BRANCH=$(git config init.defaultBranch 2>/dev/null || echo "")
if [ "$DEFAULT_BRANCH" = "main" ]; then
echo -e "${GREEN}✓ Git default branch: main${NC}"
else
echo -e "${YELLOW}⚠ Git default branch not set to 'main'${NC}"
((WARNINGS++))
fi
# Check merge strategy
MERGE_FF=$(git config merge.ff 2>/dev/null || echo "")
if [ "$MERGE_FF" = "only" ]; then
echo -e "${GREEN}✓ Git merge strategy: ff-only${NC}"
else
echo -e "${YELLOW}⚠ Git merge strategy not set to 'ff-only'${NC}"
((WARNINGS++))
fi
else
echo -e "${YELLOW}⚠ Not a git repository${NC}"
((WARNINGS++))
fi
echo
# Final report
echo -e "${BLUE}========================================"
echo "Validation Summary"
echo "========================================${NC}"
if [ $ERRORS -gt 0 ]; then
echo -e "${RED}FAILED: $ERRORS error(s) found${NC}"
if [ $WARNINGS -gt 0 ]; then
echo -e "${YELLOW}$WARNINGS warning(s) found${NC}"
fi
echo "========================================${NC}"
exit 1
elif [ $WARNINGS -gt 0 ]; then
echo -e "${YELLOW}PASSED with $WARNINGS warning(s)${NC}"
echo "========================================${NC}"
exit 0
else
echo -e "${GREEN}ALL VALIDATIONS PASSED!${NC}"
echo "========================================${NC}"
exit 0
fiUsage:
# Run full validation
./scripts/validate-stack.sh
# In CI/CD
./scripts/validate-stack.sh || exit 1---
3. scripts/setup-hooks.sh
Script to install git hooks from scripts/ to .git/hooks/
Location: scripts/setup-hooks.sh When to run: After cloning, during stack creation
#!/usr/bin/env bash
#
# Install git hooks from scripts/ to .git/hooks/
#
set -euo pipefail
# Colors
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo "Installing git hooks..."
echo
# Check if .git exists
if [ ! -d ".git" ]; then
echo -e "${RED}✗ ERROR: Not a git repository!${NC}"
echo " Initialize git first: git init"
exit 1
fi
# Ensure hooks directory exists
mkdir -p .git/hooks
INSTALLED=0
FAILED=0
# Install pre-commit hook
if [ -f "scripts/pre-commit" ]; then
if cp scripts/pre-commit .git/hooks/pre-commit; then
chmod +x .git/hooks/pre-commit
echo -e "${GREEN}✓ Installed pre-commit hook${NC}"
((INSTALLED++))
else
echo -e "${RED}✗ Failed to install pre-commit hook${NC}"
((FAILED++))
fi
else
echo -e "${YELLOW}⚠ scripts/pre-commit not found, skipping${NC}"
fi
# Install pre-push hook (if exists)
if [ -f "scripts/pre-push" ]; then
if cp scripts/pre-push .git/hooks/pre-push; then
chmod +x .git/hooks/pre-push
echo -e "${GREEN}✓ Installed pre-push hook${NC}"
((INSTALLED++))
else
echo -e "${RED}✗ Failed to install pre-push hook${NC}"
((FAILED++))
fi
fi
echo
echo "========================================="
if [ $FAILED -gt 0 ]; then
echo -e "${RED}Installation completed with $FAILED error(s)${NC}"
echo "========================================="
exit 1
elif [ $INSTALLED -eq 0 ]; then
echo -e "${YELLOW}No hooks installed${NC}"
echo "========================================="
exit 0
else
echo -e "${GREEN}Successfully installed $INSTALLED hook(s)!${NC}"
echo "========================================="
echo
echo "Hooks will now run automatically:"
echo " - pre-commit: Before each commit"
echo
echo "To skip hooks (emergency only):"
echo " git commit --no-verify"
fiUsage:
# Install hooks
./scripts/setup-hooks.sh
# Verify installation
ls -la .git/hooks/---
Optional Hooks
scripts/pre-push (Optional)
Runs before git push to ensure remote-ready state.
#!/usr/bin/env bash
#
# Pre-push hook for GitLab Stack
# Runs before pushing to remote
#
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo "========================================="
echo "Pre-push validation"
echo "========================================="
echo
ERRORS=0
# Run full validation before push
echo "Running full stack validation..."
if [ -x "./scripts/validate-stack.sh" ]; then
if ! ./scripts/validate-stack.sh; then
echo -e "${RED}✗ Stack validation failed!${NC}"
echo " Fix issues before pushing."
((ERRORS++))
fi
else
echo -e "${YELLOW}⚠ ./scripts/validate-stack.sh not found${NC}"
fi
# Check for uncommitted changes
if ! git diff-index --quiet HEAD --; then
echo -e "${YELLOW}⚠ WARNING: You have uncommitted changes${NC}"
echo " Consider committing them before pushing."
fi
echo
if [ $ERRORS -gt 0 ]; then
echo -e "${RED}Pre-push validation FAILED${NC}"
echo "To skip: git push --no-verify"
exit 1
fi
echo -e "${GREEN}Pre-push validation PASSED${NC}"
exit 0---
CI/CD Integration
GitLab CI (.gitlab-ci.yml)
stages:
- validate
- build
- deploy
validate:
stage: validate
image: docker:latest
services:
- docker:dind
before_script:
- apk add --no-cache bash findutils
script:
- chmod +x ./scripts/validate-stack.sh
- ./scripts/validate-stack.sh
only:
- merge_requests
- mainGitHub Actions (.github/workflows/validate.yml)
name: Stack Validation
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run stack validation
run: |
chmod +x ./scripts/validate-stack.sh
./scripts/validate-stack.sh---
Best Practices
1. Always Make Scripts Executable
chmod +x scripts/*.sh
chmod +x scripts/pre-commit2. Test Hooks Before Committing
# Test pre-commit manually
./scripts/pre-commit
# Test validation
./scripts/validate-stack.sh3. Document Hook Behavior
Include in README.md:
## Git Hooks
This project uses git hooks for validation:
- **pre-commit**: Validates before each commit
- To skip: `git commit --no-verify` (emergency only)4. Provide Skip Option
Always allow users to skip in emergencies:
git commit --no-verify -m "emergency fix"5. Keep Hooks Fast
- Pre-commit should run in < 10 seconds
- Use quick checks when possible
- Defer expensive checks to CI/CD
6. Clear Error Messages
echo -e "${RED}✗ ERROR: Clear description${NC}"
echo " Explanation of what went wrong"
echo " How to fix it"7. Exit Codes
# Success
exit 0
# Failure
exit 1
# Always use set -e to catch errors
set -euo pipefail---
Troubleshooting
Hook Not Running
# Check if hook is installed
ls -la .git/hooks/pre-commit
# Check if executable
chmod +x .git/hooks/pre-commit
# Reinstall hooks
./scripts/setup-hooks.shHook Fails Unexpectedly
# Run hook manually to see output
./scripts/pre-commit
# Check validation separately
./scripts/validate-stack.sh
# Debug with set -x
bash -x scripts/pre-commitSkip Hook Temporarily
# Skip pre-commit
git commit --no-verify -m "message"
# Skip pre-push
git push --no-verifyPermission Denied
# Make script executable
chmod +x scripts/pre-commit
chmod +x scripts/validate-stack.sh
# Reinstall hooks
./scripts/setup-hooks.sh---
Customization
Adding Custom Checks
Edit scripts/pre-commit:
# Add custom check
echo "5. Running custom validation..."
if ! ./scripts/my-custom-check.sh; then
echo -e "${RED}✗ Custom validation failed${NC}"
((ERRORS++))
else
echo -e "${GREEN}✓ Custom validation passed${NC}"
fi
echoAdjusting Validation Strictness
Strict Mode (recommended for production):
# Fail on any error
set -euo pipefailLenient Mode (development only):
# Continue on errors, just report
set -uo pipefailEnvironment-Specific Hooks
# Check environment
if [ "${ENV:-}" = "production" ]; then
# Strict validation for production
./scripts/validate-stack.sh
else
# Lenient for development
echo "Development environment, skipping some checks"
fi---
Summary
Git hooks ensure:
- ✅ No secrets committed
- ✅ No root-owned files
- ✅ Full stack validation before commit
- ✅ Consistent code quality
- ✅ Automated validation in workflow
All scripts are:
- Executable (
chmod +x) - Well-documented
- Provide clear error messages
- Support emergency skip (
--no-verify) - Integrate with CI/CD
GitLab Stack Creator
Create new GitLab stack projects with proper directory structure, git configuration, validation hooks, and comprehensive documentation.
Overview
The Stack Creator skill automates the creation of new GitLab stack projects following strict best practices. It integrates with stack-validator, secrets-manager, and docker-validation skills to ensure complete, validated stack setups.
When to Use
Use this skill when you need to:
- Create a new GitLab stack project from scratch
- Initialize a Docker stack with proper directory structure
- Set up git repository with validation hooks
- Bootstrap a project with automated validation
- Create a stack following GitLab Stack Management patterns
Installation
/plugin install stack-creatorCore Principles
Stack Creator follows GitLab Stack Management patterns:
1. Everything in docker-compose.yml and ./config 2. Secrets in ./secrets and Docker secrets 3. docker-entrypoint.sh only when necessary 4. No root-owned files 5. ./_temporary for transient files 6. Complete validation before completion
Stack Creation is Complete When
A stack is considered complete ONLY when:
- ✅ stack-validator reports NO issues
- ✅ secrets-manager is satisfied (NO open issues)
- ✅ docker-validation is satisfied (NO issues)
- ✅ All validation scripts execute successfully
- ✅ Git repository properly initialized and configured
- ✅ Documentation complete in ./docs
IMPORTANT: This skill NEVER uses workarounds. If something fails, it stops and asks for user guidance.
Usage
Triggering the Skill
The skill activates when you mention:
- "Create a new stack"
- "Initialize a GitLab stack"
- "Set up a Docker stack project"
- "Create stack with [services]"
Example Prompts
1. Simple Web Stack:
Create a new stack for a web application with nginx2. Full Application Stack:
Create a stack with nginx, PostgreSQL, and Redis for production3. Development Stack:
Initialize a development stack with PostgreSQL and RedisGenerated Structure
project-name/
├── .git/ # Git repository
│ ├── hooks/ # Git hooks (validation)
│ └── config # Git configuration
├── config/ # Service configurations
│ ├── nginx/ # Nginx configs
│ ├── postgres/ # PostgreSQL configs
│ └── redis/ # Redis configs
├── secrets/ # Docker secrets files
│ └── .gitkeep # Keep directory in git
├── _temporary/ # Temporary files (gitignored)
├── scripts/ # Validation and utility scripts
│ ├── pre-commit # Pre-commit validation hook
│ ├── validate-stack.sh # Full stack validation
│ └── setup-hooks.sh # Hook installation script
├── docs/ # Project documentation
│ ├── decisions/ # Architecture decision records
│ ├── setup.md # Setup instructions
│ └── services.md # Service documentation
├── docker-compose.yml # Main compose file
├── .env.example # Environment template
├── .gitignore # Git exclusions
├── .dockerignore # Docker exclusions
├── CLAUDE.md # Claude Code instructions
└── README.md # Project overviewFeatures
Git Repository Setup
- Initializes or connects to remote repository
- Configures main branch as default
- Sets ff-only merge strategy
- Creates comprehensive .gitignore
- Installs pre-commit validation hooks
Docker Configuration
- Generates docker-compose.yml with best practices
- Validates with docker-validation skill
- Creates .env.example template
- Ensures proper service configuration
Secrets Management
- Integrates with secrets-manager skill
- Sets up ./secrets directory properly
- Ensures NO secrets in .env or docker-compose.yml
- Generates docker-entrypoint.sh only when needed
Service Configuration
- Uses config-generator for service configs
- Creates configs in ./config/<service-name>/
- Validates all generated configurations
- Supports nginx, PostgreSQL, Redis, and more
Validation Scripts
- validate-stack.sh: Complete stack validation
- pre-commit: Pre-commit validation hook
- setup-hooks.sh: Git hooks installation
All scripts executable and ready to use.
Documentation
- docs/setup.md: Setup instructions
- docs/services.md: Service documentation
- docs/decisions/: Architecture decision records
- CLAUDE.md: Claude Code project instructions
- README.md: Project overview
Workflow
Phase 1: Gather Requirements
Asks for:
- Project name
- Services needed
- Remote git repository URL (optional)
- Environment type
- Special requirements
Phase 2: Create Structure
Creates:
- Directory structure
- Git repository
- Git configuration (main, ff-only)
- .gitignore and .dockerignore
Phase 3: Docker Setup
Generates:
- docker-compose.yml
- .env.example
- Validates with docker-validation
Phase 4: Service Configuration
Uses config-generator to create:
- nginx configuration
- PostgreSQL configuration
- Redis configuration
- Other service configs
Phase 5: Secrets Setup
Uses secrets-manager to:
- Create secure secrets
- Configure Docker secrets
- Validate NO secrets in wrong places
- Generate entrypoint scripts if needed
Phase 6: Validation Scripts
Creates:
- scripts/validate-stack.sh
- scripts/pre-commit
- scripts/setup-hooks.sh
- Installs hooks
Phase 7: Documentation
Generates:
- docs/setup.md
- docs/services.md
- docs/decisions/0001-stack-architecture.md
- CLAUDE.md
- README.md
Phase 8: Final Validation
Runs complete validation:
- stack-validator
- secrets-manager
- docker-validation
- File ownership check
- Git setup verification
Phase 9: Initial Commit
Creates initial commit when validation passes.
Validation
Pre-Commit Hook
Automatically runs before each commit:
- Checks for secrets in staged files
- Checks for root-owned files
- Runs full stack validation
- Blocks commit if issues found
Can skip with: git commit --no-verify (emergency only)
Manual Validation
Run anytime:
./scripts/validate-stack.shValidates:
- Stack structure
- Secrets configuration
- Docker configuration
- File ownership
- Git exclusions
Git Configuration
Branch Strategy
- Default Branch: main
- Merge Strategy: ff-only (fast-forward only)
- No Rebase: Unless explicitly requested
Commit Standards
Example commit messages:
feat: add Redis service with persistence
fix: correct nginx proxy configuration
docs: update setup instructions
chore: update validation scriptsIntegration with Other Skills
stack-validator
- Called during final validation
- Called in validation scripts
- Called in pre-commit hooks
- Must pass with NO issues
secrets-manager
- Called during secrets setup
- Validates secret configuration
- Ensures NO secrets in .env
- Must be satisfied before completion
docker-validation
- Called during Docker setup
- Validates docker-compose.yml
- Validates Dockerfiles
- Must pass with NO issues
config-generator
- Called for each service
- Generates service configs
- Validates generated configs
- Creates configs in ./config/
Error Handling
Validation Failures
When validation fails: 1. Stops immediately 2. Reports issue clearly 3. Shows validation output 4. Asks user how to proceed 5. NEVER uses workarounds
Git Issues
When git operations fail: 1. Reports the error 2. Explains the issue 3. Asks for user guidance 4. Documents the solution
Permission Issues
When permission problems occur: 1. Reports root-owned files 2. Asks user to fix ownership 3. Validates after fixing 4. Documents proper ownership
Best Practices
1. Always validate before committing 2. Never skip hooks without good reason 3. Document decisions in ./docs/decisions/ 4. Use ff-only merges for clean history 5. Keep secrets secure - never commit 6. Fix ownership - no root files 7. Ask when stuck - no workarounds 8. Follow validation - fix all issues
Example: Creating a Web Stack
User: "Create a new stack for mywebapp with nginx"
Stack Creator Response:
"I'll create mywebapp stack with nginx. Let me ask a few questions..."
Result:
✓ Directory structure created
✓ Git repository initialized (main, ff-only)
✓ docker-compose.yml created and validated
✓ nginx configuration generated
✓ Validation scripts installed
✓ Git hooks configured
✓ Documentation complete
All validations passed!Troubleshooting
Stack Creation Fails
If stack creation stops: 1. Review the error message 2. Fix the reported issue 3. Ask the skill to continue 4. NEVER skip validation
Validation Won't Pass
If validation keeps failing: 1. Run validators individually:
claude-code run stack-validatorclaude-code run secrets-manager --validateclaude-code run docker-validation
2. Fix reported issues one by one 3. Re-run validation 4. Ask for help if stuck
Git Configuration Issues
If git setup fails: 1. Check git is installed: git --version 2. Check git config: git config --list 3. Set manually if needed:
git config init.defaultBranch main
git config merge.ff only
git config pull.ff onlyPermission Problems
If root-owned files appear:
# Find them
find . -user root -not -path "./.git/*"
# Fix ownership
sudo chown -R $USER:$USER .
# Re-validate
./scripts/validate-stack.shVersion History
- v0.1.0 (2025-10-20): Initial release
- Complete Phase 1 stack creation
- Integration with stack-validator, secrets-manager, docker-validation, config-generator
- Git repository setup with validation hooks
- Comprehensive documentation generation
- No-workaround policy
Resources
- stack-validator Documentation
- secrets-manager Documentation
- docker-validation Documentation
- config-generator Documentation
- Git Hooks Guide
License
This skill follows the same license as the Skills marketplace repository.
Stack Templates Reference
This document provides ready-to-use templates for common stack configurations.
Table of Contents
1. docker-compose.yml Templates 2. .env.example Templates 3. Service Configuration Templates 4. Documentation Templates 5. Git Configuration Templates
---
docker-compose.yml Templates
Minimal Stack (Development)
services:
app:
image: myapp:latest
container_name: ${PROJECT_NAME:-app}_main
restart: unless-stopped
environment:
- NODE_ENV=development
ports:
- "${APP_PORT:-3000}:3000"
networks:
- app-network
networks:
app-network:
driver: bridgeWeb Stack (nginx + Application)
services:
nginx:
image: nginx:alpine
container_name: ${PROJECT_NAME:-app}_nginx
restart: unless-stopped
ports:
- "${NGINX_HTTP_PORT:-80}:80"
- "${NGINX_HTTPS_PORT:-443}:443"
volumes:
- ./config/nginx:/etc/nginx/conf.d:ro
- ./ssl:/etc/nginx/ssl:ro
networks:
- app-network
depends_on:
- app
app:
image: myapp:latest
container_name: ${PROJECT_NAME:-app}_main
restart: unless-stopped
environment:
- NODE_ENV=production
networks:
- app-network
networks:
app-network:
driver: bridgeFull Stack (nginx + App + PostgreSQL + Redis)
services:
nginx:
image: nginx:alpine
container_name: ${PROJECT_NAME:-app}_nginx
restart: unless-stopped
ports:
- "${NGINX_HTTP_PORT:-80}:80"
- "${NGINX_HTTPS_PORT:-443}:443"
volumes:
- ./config/nginx:/etc/nginx/conf.d:ro
networks:
- app-network
depends_on:
- app
app:
image: myapp:latest
container_name: ${PROJECT_NAME:-app}_main
restart: unless-stopped
environment:
- NODE_ENV=production
- DB_HOST=postgres
- DB_PORT=5432
- DB_NAME=${POSTGRES_DB}
- REDIS_HOST=redis
- REDIS_PORT=6379
secrets:
- db_password
- redis_password
networks:
- app-network
depends_on:
- postgres
- redis
postgres:
image: postgres:16-alpine
container_name: ${PROJECT_NAME:-app}_postgres
restart: unless-stopped
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
secrets:
- source: db_password
target: /run/secrets/db_password
volumes:
- ./config/postgres:/docker-entrypoint-initdb.d:ro
- postgres_data:/var/lib/postgresql/data
networks:
- app-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: ${PROJECT_NAME:-app}_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
networks:
- app-network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
app-network:
driver: bridge
volumes:
postgres_data:
driver: local
redis_data:
driver: local
secrets:
db_password:
file: ./secrets/db_password
redis_password:
file: ./secrets/redis_passwordStack with Docker Secrets (Production)
services:
app:
image: myapp:latest
container_name: ${PROJECT_NAME:-app}_main
restart: unless-stopped
environment:
- NODE_ENV=production
- DB_HOST=postgres
- DB_USER=${DB_USER}
# NO PASSWORDS IN ENVIRONMENT!
secrets:
- db_password
- api_key
- jwt_secret
networks:
- app-network
postgres:
image: postgres:16-alpine
container_name: ${PROJECT_NAME:-app}_postgres
restart: unless-stopped
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
# Password via Docker secret, not environment!
secrets:
- source: db_password
target: /run/secrets/postgres-passwd
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
postgres_data:
driver: local
secrets:
db_password:
file: ./secrets/db_password
api_key:
file: ./secrets/api_key
jwt_secret:
file: ./secrets/jwt_secret---
.env.example Templates
Basic Application
# Project Configuration
PROJECT_NAME=myapp
# Application Settings
NODE_ENV=production
APP_PORT=3000
# IMPORTANT: Copy this file to .env and configure
# .env is gitignored and should contain actual valuesWeb Stack with nginx
# Project Configuration
PROJECT_NAME=mywebapp
# nginx Configuration
NGINX_HTTP_PORT=80
NGINX_HTTPS_PORT=443
# Application Settings
NODE_ENV=production
# IMPORTANT: Copy this file to .env and configure for your environment
# .env is gitignored and should contain actual configurationFull Stack (nginx + App + PostgreSQL + Redis)
# Project Configuration
PROJECT_NAME=myapp
# nginx Configuration
NGINX_HTTP_PORT=80
NGINX_HTTPS_PORT=443
# Application Settings
NODE_ENV=production
# PostgreSQL Configuration
POSTGRES_DB=myapp_db
POSTGRES_USER=myapp_user
# NOTE: Password stored in Docker secret, not here!
# Redis Configuration
REDIS_PORT=6379
# NOTE: Password stored in Docker secret, not here!
# IMPORTANT SECURITY NOTES:
# 1. Copy this file to .env for actual configuration
# 2. NEVER put secrets/passwords here - use Docker secrets in ./secrets/
# 3. .env is gitignored and should NEVER be committed
# 4. Keep .env and .env.example keys synchronized---
Service Configuration Templates
nginx - Simple Reverse Proxy
File: config/nginx/default.conf
upstream app {
server app:3000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://app;
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;
}
}nginx - Production with SSL
File: config/nginx/default.conf
upstream app {
server app:3000;
keepalive 64;
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
# HTTPS Server
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL Configuration
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 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;
# Logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
# Proxy Configuration
location / {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Static files caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
proxy_pass http://app;
expires 1y;
add_header Cache-Control "public, immutable";
}
}PostgreSQL - Initialization Script
File: config/postgres/init.sql
-- Initialize database
-- Create extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
-- Create schemas
CREATE SCHEMA IF NOT EXISTS app;
-- Create tables
CREATE TABLE IF NOT EXISTS app.users (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
email VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Create indexes
CREATE INDEX idx_users_email ON app.users(email);
-- Grant permissions
GRANT ALL PRIVILEGES ON SCHEMA app TO ${POSTGRES_USER};
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA app TO ${POSTGRES_USER};Redis - Production Configuration
File: config/redis/redis.conf
# Redis Production Configuration
# Network
bind 0.0.0.0
protected-mode yes
port 6379
# General
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
# Snapshotting
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
# Replication
replica-serve-stale-data yes
replica-read-only yes
# Security
# requirepass will be set via environment variable
# Use Docker secrets for password
# Limits
maxmemory 256mb
maxmemory-policy allkeys-lru
maxclients 10000
# Append Only Mode
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# Slow Log
slowlog-log-slower-than 10000
slowlog-max-len 128---
Documentation Templates
docs/setup.md
# Setup Instructions
## Prerequisites
- Docker Engine 20.10+
- Docker Compose V2
- Git
- [Other prerequisites]
## Quick Start
\`\`\`bash
# Clone repository
git clone <repository-url>
cd <project-name>
# Copy environment template
cp .env.example .env
# Configure environment
nano .env
# Set up Docker secrets (if applicable)
# Follow instructions in ./secrets/README.md
# Install git hooks
./scripts/setup-hooks.sh
# Validate stack
./scripts/validate-stack.sh
# Start services
docker compose up -d
# Check status
docker compose ps
\`\`\`
## Detailed Setup
### 1. Environment Configuration
Edit `.env` with your settings:
\`\`\`bash
PROJECT_NAME=myapp
# Add other variables from .env.example
\`\`\`
### 2. Secrets Configuration
Create required secrets in `./secrets/`:
\`\`\`bash
# Generate secure random password
openssl rand -base64 32 > ./secrets/db_password
# Set proper permissions
chmod 600 ./secrets/*
\`\`\`
### 3. Validation
Always validate before deploying:
\`\`\`bash
./scripts/validate-stack.sh
\`\`\`
### 4. Deployment
\`\`\`bash
docker compose up -d
\`\`\`
## Troubleshooting
### Services Won't Start
\`\`\`bash
# Check logs
docker compose logs
# Check specific service
docker compose logs <service-name>
\`\`\`
### Validation Fails
\`\`\`bash
# Run individual validators
claude-code run stack-validator
claude-code run secrets-manager --validate
claude-code run docker-validation
\`\`\`
### Permission Issues
\`\`\`bash
# Fix file ownership
sudo chown -R $USER:$USER .
# Re-validate
./scripts/validate-stack.sh
\`\`\`docs/services.md
# Services Documentation
## Service Overview
| Service | Port | Purpose | Configuration |
|---------|------|---------|---------------|
| nginx | 80, 443 | Web server & reverse proxy | ./config/nginx |
| app | 3000 (internal) | Application server | Environment variables |
| postgres | 5432 (internal) | Database | ./config/postgres |
| redis | 6379 (internal) | Cache & sessions | ./config/redis |
## Service Details
### nginx
**Image**: nginx:alpine
**Purpose**: Web server and reverse proxy
**Configuration**: ./config/nginx/default.conf
**Secrets**: None
**Volumes**:
- ./config/nginx:/etc/nginx/conf.d:ro
- ./ssl:/etc/nginx/ssl:ro (if using HTTPS)
**Health Check**: HTTP request to port 80
### Application
**Image**: myapp:latest
**Purpose**: Main application server
**Configuration**: Environment variables in .env
**Secrets**:
- db_password
- redis_password
- api_key
- jwt_secret
**Dependencies**:
- postgres (database)
- redis (cache)
### PostgreSQL
**Image**: postgres:16-alpine
**Purpose**: Primary database
**Configuration**: ./config/postgres/init.sql
**Secrets**:
- db_password
**Volumes**:
- postgres_data:/var/lib/postgresql/data (persistent)
- ./config/postgres:/docker-entrypoint-initdb.d:ro (init scripts)
**Health Check**: `pg_isready` command
**Backup**:
\`\`\`bash
docker compose exec postgres pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} > backup.sql
\`\`\`
### Redis
**Image**: redis:7-alpine
**Purpose**: Cache and session storage
**Configuration**: ./config/redis/redis.conf
**Secrets**:
- redis_password
**Volumes**:
- redis_data:/data (persistent)
- ./config/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro
**Health Check**: `redis-cli ping`
**Backup**:
\`\`\`bash
docker compose exec redis redis-cli SAVE
docker compose cp redis:/data/dump.rdb ./backup/
\`\`\`
## Service Dependencies
\`\`\`
nginx → app → postgres
↓
redis
\`\`\`
## Scaling
To scale the application:
\`\`\`bash
docker compose up -d --scale app=3
\`\`\`
Note: nginx configuration must support multiple backend servers.docs/decisions/0001-stack-architecture.md
# 1. Stack Architecture
**Date**: YYYY-MM-DD
**Status**: Accepted
**Deciders**: [Names]
## Context
We need a consistent, maintainable approach for deploying our application stack.
## Decision
We will use GitLab Stack Management patterns:
1. All configuration in docker-compose.yml and ./config
2. All secrets in ./secrets and Docker secrets
3. docker-entrypoint.sh only when containers don't support native Docker secrets
4. No root-owned files
5. ./_temporary for transient files
6. Complete validation before deployment
## Consequences
**Positive**:
- Consistent structure across all stacks
- Automated validation prevents deployment issues
- Secure by default (secrets properly managed)
- Easy to maintain and update
- Clear separation of config and secrets
**Negative**:
- Initial setup requires more steps
- Must follow strict patterns
- Validation gates can slow rapid iteration
- Learning curve for team members
## Compliance
Stack creation enforces:
- stack-validator: Structure compliance
- secrets-manager: Secure secrets handling
- docker-validation: Docker best practices
- git hooks: Pre-commit validation
## Alternatives Considered
1. **Manual setup**: Rejected due to inconsistency
2. **.env for everything**: Rejected due to security concerns
3. **No validation**: Rejected due to quality issues
## Implementation
- Use stack-creator skill for all new projects
- Validate with ./scripts/validate-stack.sh
- Document all deviations in new ADRs---
Git Configuration Templates
.gitignore
# Secrets - NEVER commit
secrets/*
!secrets/.gitkeep
!secrets/README.md
*.key
*.pem
*.crt
*.p12
*.pfx
id_rsa
id_ed25519
# Environment files
.env
.env.local
.env.*.local
!.env.example
# Temporary files
_temporary/
*.tmp
*.temp
.cache/
*.log
# Docker
.docker/
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
Thumbs.db
# Backup files
*.bak
*.backup
*.old
# Build artifacts
dist/
build/
node_modules/.dockerignore
.git
.gitignore
.github
.gitlab-ci.yml
README.md
LICENSE
docs/
_temporary/
*.md
.env
.env.example
.env.local
secrets/
.vscode/
.idea/
*.swp
*.swo
*.log
*.tmp
node_modules/
.DS_Store
Thumbs.dbCLAUDE.md Template
# CLAUDE.md
This file provides guidance to Claude Code when working with this GitLab Stack project.
## Project Type
This is a GitLab Stack project following strict management patterns.
## Directory Structure
- `config/`: Service configurations (nginx, postgres, redis)
- `secrets/`: Docker secrets (NEVER commit actual secrets!)
- `_temporary/`: Temporary files (gitignored)
- `scripts/`: Validation and utility scripts
- `docs/`: Project documentation
## Required Skills
This project requires these Claude Code skills:
- **stack-validator**: Validate structure
- **secrets-manager**: Manage Docker secrets
- **docker-validation**: Validate Docker configs
- **config-generator**: Generate service configs
## Git Configuration
- **Branch**: main
- **Merge Strategy**: ff-only (fast-forward only)
- **Hooks**: Pre-commit validation enabled
## Validation Requirements
BEFORE any commit, ALL must pass:
1. stack-validator: NO issues
2. secrets-manager: Satisfied
3. docker-validation: NO issues
4. No root-owned files
5. No secrets in .env or docker-compose.yml environment
## Making Changes
### Adding a Service
1. Update docker-compose.yml
2. Use config-generator for configs
3. Use secrets-manager for secrets
4. Run ./scripts/validate-stack.sh
5. Fix ALL issues
6. Commit
### Modifying Configuration
1. Edit config files
2. Validate with docker-validation
3. Run ./scripts/validate-stack.sh
4. Fix issues
5. Commit
### Working with Secrets
1. Use secrets-manager for ALL secret operations
2. NEVER put secrets in .env
3. Use Docker secrets or ./secrets/
4. Validate before committing
## Important Rules
1. NEVER commit secrets
2. NEVER create root-owned files
3. NEVER skip validation without asking
4. NEVER use workarounds - ask user
5. ALWAYS validate before committing
6. ALWAYS document decisions
7. ALWAYS use ff-only merges
8. ALWAYS use main as branch name
## Troubleshooting
- Validation fails → Fix issues, don't skip
- Git conflicts → Use ff-only, ask user
- Permission issues → Check ownership, fix with chown---
Summary
All templates follow GitLab Stack Management principles:
- ✅ Secrets in Docker secrets, never in .env
- ✅ Configuration in ./config directory
- ✅ Validated before deployment
- ✅ Documented thoroughly
- ✅ Git properly configured
Use these templates as starting points and customize for your specific needs.
Stack Creator - Additional Workflow Examples
Workflow 2: Creating a Full Application Stack
User: "Create a stack with nginx, PostgreSQL, and Redis"