Claude Code Plugins

Community-maintained marketplace

Feedback

deployment-guide

@gizix/cc_projects
0
0

Production deployment guidance for Quart applications including Docker, Hypercorn configuration, environment management, monitoring, and performance tuning. Activates when deploying or optimizing for production.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name deployment-guide
description Production deployment guidance for Quart applications including Docker, Hypercorn configuration, environment management, monitoring, and performance tuning. Activates when deploying or optimizing for production.
allowed-tools Read, Write

Provide production deployment best practices and configurations for Quart applications.

Docker Configuration

Multi-Stage Dockerfile

# Build stage
FROM python:3.11-slim as builder

WORKDIR /app

# Install uv
RUN pip install uv

# Copy dependency files
COPY pyproject.toml ./

# Install dependencies
RUN uv pip install --system --no-cache .

# Runtime stage
FROM python:3.11-slim

WORKDIR /app

# Copy dependencies from builder
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin

# Copy application code
COPY src/ ./src/

# Create non-root user
RUN useradd --create-home appuser && \
    chown -R appuser:appuser /app

USER appuser

# Expose port
EXPOSE 8000

# Run with Hypercorn
CMD ["hypercorn", "src.app:app", "--bind", "0.0.0.0:8000", "--workers", "4", "--worker-class", "asyncio"]

docker-compose.yml

version: '3.8'

services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql+asyncpg://postgres:password@db:5432/quart_db
      - QUART_ENV=production
      - SECRET_KEY=${SECRET_KEY}
      - JWT_SECRET_KEY=${JWT_SECRET_KEY}
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=quart_db
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  postgres_data:

Hypercorn Production Configuration

# Recommended production settings
hypercorn src.app:create_app() \
    --bind 0.0.0.0:8000 \
    --workers 4 \
    --worker-class asyncio \
    --access-log - \
    --error-log - \
    --access-logformat '%(h)s %(r)s %(s)s %(b)s %(D)s' \
    --graceful-timeout 30 \
    --keep-alive 5 \
    --backlog 100

Environment Variables

# Production .env (never commit!)
SECRET_KEY=generate-with-secrets.token-hex-32
JWT_SECRET_KEY=generate-with-secrets.token-hex-32
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/db
QUART_ENV=production
CORS_ORIGINS=https://example.com,https://app.example.com
LOG_LEVEL=INFO

Nginx Reverse Proxy

upstream quart_app {
    server 127.0.0.1:8000;
}

server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;

    # WebSocket support
    location /ws {
        proxy_pass http://quart_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_read_timeout 86400;
    }

    # HTTP requests
    location / {
        proxy_pass http://quart_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;
    }
}

Monitoring & Logging

import logging
from quart.logging import default_handler

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

# Add request logging
@app.before_request
async def log_request():
    app.logger.info(f'{request.method} {request.path}')

@app.after_request
async def log_response(response):
    app.logger.info(f'{request.method} {request.path} - {response.status_code}')
    return response

Health Check Endpoint

@app.route('/health')
async def health_check():
    """Health check endpoint for load balancers."""
    # Check database
    try:
        async with get_session() as session:
            await session.execute('SELECT 1')
        db_status = 'healthy'
    except Exception:
        db_status = 'unhealthy'

    return {
        'status': 'healthy' if db_status == 'healthy' else 'degraded',
        'database': db_status,
        'version': app.config.get('API_VERSION')
    }

Performance Tuning

  • Workers: (CPU cores * 2) + 1
  • Database pool: 5-10 per worker
  • Connection timeout: 30s
  • Keep-alive: 5s
  • Backlog: 100-1000

Pre-Deployment Checklist

  • DEBUG=False
  • Strong SECRET_KEY set
  • Explicit CORS origins
  • HTTPS enforced
  • Database migrations applied
  • Static files served by CDN/nginx
  • Logging configured
  • Health checks implemented
  • Monitoring setup
  • Backups configured
  • Rate limiting enabled
  • Security headers set