commit 76811c4803e51703c6179f3af2c782fc9571e6e8 Author: Zhongwei Li Date: Sun Nov 30 08:52:07 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..63ea734 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "name": "stack-creator", + "description": "Create new GitLab stack projects with proper directory structure, git configuration (main branch, ff-only), validation hooks, and comprehensive documentation. Integrates stack-validator, secrets-manager, docker-validation, and config-generator. Complete only when all validations pass", + "version": "0.1.0", + "author": { + "name": "rknall", + "email": "zhongweili@tubi.tv" + }, + "skills": [ + "./" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..799c133 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# stack-creator + +Create new GitLab stack projects with proper directory structure, git configuration (main branch, ff-only), validation hooks, and comprehensive documentation. Integrates stack-validator, secrets-manager, docker-validation, and config-generator. Complete only when all validations pass diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..f039d89 --- /dev/null +++ b/SKILL.md @@ -0,0 +1,1102 @@ +--- +name: "GitLab Stack Creator" +description: "Create new GitLab stack projects from templates with proper directory structure, git configuration, validation hooks, and documentation. Use when initializing new Docker stack projects that follow GitLab stack patterns." +--- + +# 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 overview +``` + +**Actions**: +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 ` +- Or add remote: `git remote add origin ` +- 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: +```bash +# 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: +```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 +*.backup +``` + +#### 3.4 Create .dockerignore + +Generate .dockerignore: +```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**: +```bash +#!/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 0 +``` + +Make executable: `chmod +x scripts/validate-stack.sh` + +#### 4.2 Create scripts/pre-commit + +Generate pre-commit hook: +```bash +#!/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 0 +``` + +Make executable: `chmod +x scripts/pre-commit` + +#### 4.3 Create scripts/setup-hooks.sh + +Generate hook installation script: +```bash +#!/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: +```yaml +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: +```bash +# 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 secrets +``` + +### Phase 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// +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: +```markdown +# Setup Instructions + +## Prerequisites + +- Docker Engine 20.10+ +- Docker Compose V2 +- Git + +## Initial Setup + +1. Clone the repository: + ```bash + git clone + cd + ``` + +2. Copy environment template: + ```bash + 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: + ```bash + ./scripts/setup-hooks.sh + ``` + +6. Validate stack: + ```bash + ./scripts/validate-stack.sh + ``` + +7. Start services: + ```bash + docker compose up -d + ``` + +## Validation + +Always run validation before deploying: +```bash +./scripts/validate-stack.sh +``` + +This checks: +- Stack structure +- Secrets configuration +- Docker configuration +- File ownership +- Git exclusions +``` + +#### 8.2 Create docs/services.md + +Document all services: +```markdown +# 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: +```markdown +# 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 practices +``` + +#### 8.4 Create CLAUDE.md + +Generate Claude Code instructions for the project: +```markdown +# 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 Documentation +``` + +#### 8.5 Create README.md + +Generate project README: +```markdown +# Project Name + +Brief description of the project. + +## Quick Start + +```bash +# Clone repository +git clone +cd + +# 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: + +```bash +# 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: +```bash +find . -user root -not -path "./.git/*" +``` + +Fix ownership: +```bash +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: + +```bash +# Run validation script +./scripts/validate-stack.sh +``` + +This 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: + +```bash +# 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 main +``` + +If 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. diff --git a/SKILL_COMPLETION.md b/SKILL_COMPLETION.md new file mode 100644 index 0000000..e69de29 diff --git a/git-hooks-guide.md b/git-hooks-guide.md new file mode 100644 index 0000000..f6460a1 --- /dev/null +++ b/git-hooks-guide.md @@ -0,0 +1,735 @@ +# 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 installer +``` + +## Core 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` + +```bash +#!/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 0 +``` + +**Usage**: +```bash +# 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 + +```bash +#!/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 +fi +``` + +**Usage**: +```bash +# 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 + +```bash +#!/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" +fi +``` + +**Usage**: +```bash +# 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. + +```bash +#!/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) + +```yaml +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 + - main +``` + +### GitHub Actions (.github/workflows/validate.yml) + +```yaml +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 + +```bash +chmod +x scripts/*.sh +chmod +x scripts/pre-commit +``` + +### 2. Test Hooks Before Committing + +```bash +# Test pre-commit manually +./scripts/pre-commit + +# Test validation +./scripts/validate-stack.sh +``` + +### 3. Document Hook Behavior + +Include in README.md: +```markdown +## 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: +```bash +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 + +```bash +echo -e "${RED}✗ ERROR: Clear description${NC}" +echo " Explanation of what went wrong" +echo " How to fix it" +``` + +### 7. Exit Codes + +```bash +# Success +exit 0 + +# Failure +exit 1 + +# Always use set -e to catch errors +set -euo pipefail +``` + +--- + +## Troubleshooting + +### Hook Not Running + +```bash +# 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.sh +``` + +### Hook Fails Unexpectedly + +```bash +# Run hook manually to see output +./scripts/pre-commit + +# Check validation separately +./scripts/validate-stack.sh + +# Debug with set -x +bash -x scripts/pre-commit +``` + +### Skip Hook Temporarily + +```bash +# Skip pre-commit +git commit --no-verify -m "message" + +# Skip pre-push +git push --no-verify +``` + +### Permission Denied + +```bash +# 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`: + +```bash +# 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 +echo +``` + +### Adjusting Validation Strictness + +**Strict Mode** (recommended for production): +```bash +# Fail on any error +set -euo pipefail +``` + +**Lenient Mode** (development only): +```bash +# Continue on errors, just report +set -uo pipefail +``` + +### Environment-Specific Hooks + +```bash +# 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 diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..d4b492a --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,61 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:rknall/claude-skills:stack-creator", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "c70a6893224ba93b0a28130010973fba7245f209", + "treeHash": "6d8faf1c532b90a3373db5c888a10fffdf8410f7c1ff83728560c76b13d337ef", + "generatedAt": "2025-11-28T10:27:59.895342Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "stack-creator", + "description": "Create new GitLab stack projects with proper directory structure, git configuration (main branch, ff-only), validation hooks, and comprehensive documentation. Integrates stack-validator, secrets-manager, docker-validation, and config-generator. Complete only when all validations pass", + "version": "0.1.0" + }, + "content": { + "files": [ + { + "path": "SKILL_COMPLETION.md", + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + { + "path": "git-hooks-guide.md", + "sha256": "66c94275fe1c6f566d33231e2f23b7fda58c578f677d9bfdabeaefa78abaafc0" + }, + { + "path": "README.md", + "sha256": "b3998eac9e8449160b00792c37cf1ffb2d644c5894f7c87e0326d4a6e90fe8d6" + }, + { + "path": "SKILL.md", + "sha256": "22fd3394c4eccdc9846a96f028983116581a8791a31becd5ac7fb9c3d3173a3c" + }, + { + "path": "templates-reference.md", + "sha256": "31c1e5e5ac517e035e534c123faa5f9f2440ce87b1a2ce2334e589c94e2e7ce1" + }, + { + "path": "workflow-examples.md", + "sha256": "e4f0a59a3a31aa76ae3813c9225485ebb7b08f5428aba8f880ffc05d8601e1d3" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "4655e14dd9646d0206b1c5b55446acfb34943315588978253ecec2e5cbd761fc" + } + ], + "dirSha256": "6d8faf1c532b90a3373db5c888a10fffdf8410f7c1ff83728560c76b13d337ef" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/templates-reference.md b/templates-reference.md new file mode 100644 index 0000000..f9dd8d9 --- /dev/null +++ b/templates-reference.md @@ -0,0 +1,905 @@ +# Stack Templates Reference + +This document provides ready-to-use templates for common stack configurations. + +## Table of Contents + +1. [docker-compose.yml Templates](#docker-composeyml-templates) +2. [.env.example Templates](#envexample-templates) +3. [Service Configuration Templates](#service-configuration-templates) +4. [Documentation Templates](#documentation-templates) +5. [Git Configuration Templates](#git-configuration-templates) + +--- + +## docker-compose.yml Templates + +### Minimal Stack (Development) + +```yaml +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: bridge +``` + +### Web Stack (nginx + Application) + +```yaml +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: bridge +``` + +### Full Stack (nginx + App + PostgreSQL + Redis) + +```yaml +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_password +``` + +### Stack with Docker Secrets (Production) + +```yaml +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 + +```bash +# 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 values +``` + +### Web Stack with nginx + +```bash +# 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 configuration +``` + +### Full Stack (nginx + App + PostgreSQL + Redis) + +```bash +# 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` + +```nginx +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` + +```nginx +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` + +```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` + +```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 + +```markdown +# Setup Instructions + +## Prerequisites + +- Docker Engine 20.10+ +- Docker Compose V2 +- Git +- [Other prerequisites] + +## Quick Start + +\`\`\`bash +# Clone repository +git clone +cd + +# 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 +\`\`\` + +### 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 + +```markdown +# 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 + +```markdown +# 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 + +```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 + +```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.db +``` + +### CLAUDE.md Template + +```markdown +# 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. diff --git a/workflow-examples.md b/workflow-examples.md new file mode 100644 index 0000000..d5d51f4 --- /dev/null +++ b/workflow-examples.md @@ -0,0 +1,6 @@ +# Stack Creator - Additional Workflow Examples + +## Workflow 2: Creating a Full Application Stack + +``` +User: "Create a stack with nginx, PostgreSQL, and Redis" \ No newline at end of file