diff --git a/.opencode/templates/README.md.template b/.opencode/templates/README.md.template index b436b96..0989e2b 100644 --- a/.opencode/templates/README.md.template +++ b/.opencode/templates/README.md.template @@ -7,11 +7,8 @@ [![MIT License][license-shield]][license-url] [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?style=for-the-badge)](docs/coverage/index.html) -[![CI Status](https://github.com/{{GITHUB_USERNAME}}/{{PROJECT_NAME}}/workflows/CI/badge.svg?style=for-the-badge)](https://github.com/{{GITHUB_USERNAME}}/{{PROJECT_NAME}}/actions/workflows/ci.yml) -[![CodeQL](https://github.com/{{GITHUB_USERNAME}}/{{PROJECT_NAME}}/workflows/CodeQL%20Security%20Analysis/badge.svg?style=for-the-badge)](https://github.com/{{GITHUB_USERNAME}}/{{PROJECT_NAME}}/actions/workflows/codeql.yml) -[![Python](https://img.shields.io/badge/python-3.12%20%7C%203.13-blue?style=for-the-badge)](https://www.python.org/downloads/) -[![Code Style](https://img.shields.io/badge/code%20style-ruff-000000.svg?style=for-the-badge)](https://github.com/astral-sh/ruff) -[![Security](https://img.shields.io/badge/security-ruff%20%2B%20CodeQL-green?style=for-the-badge)](https://docs.astral.sh/ruff/rules/#flake8-bandit-s) +[![CI](https://img.shields.io/github/actions/workflow/status/{{GITHUB_USERNAME}}/{{PROJECT_NAME}}/ci.yml?style=for-the-badge&label=CI)](https://github.com/{{GITHUB_USERNAME}}/{{PROJECT_NAME}}/actions/workflows/ci.yml) +[![Python](https://img.shields.io/badge/python-3.13-blue?style=for-the-badge)](https://www.python.org/downloads/) > {{PROJECT_DESCRIPTION}} @@ -104,44 +101,18 @@ task mut-report # Mutation testing (optional) ## ๐Ÿณ Docker Usage -Modern Docker setup with multi-stage builds, distroless production images, and comprehensive development workflows. - -### Development Environment - -```bash -# Start development environment with hot reload -docker-compose up - -# Run specific services -docker-compose up app # Main application -docker-compose up docs # Documentation server (localhost:8080) - -# Development with profiles -docker-compose --profile test up # Run test suite -docker-compose --profile quality up # Code quality checks -``` - -### Production Deployment +Simple Docker setup for development with hot reload and integrated tooling. ```bash -# Build production image (distroless, security-optimized) -docker build --target production -t {{PROJECT_NAME}}:prod . - -# Production testing environment -docker-compose -f docker-compose.prod.yml up - -# Security scanning -docker-compose -f docker-compose.prod.yml --profile security up - -# Load testing -docker-compose -f docker-compose.prod.yml --profile load-test up +# Development workflows +docker-compose up # Hot reload development environment +docker-compose --profile test up # Run complete test suite +docker-compose --profile docs up # Documentation server (localhost:8080) +docker-compose --profile quality up # Code quality checks (lint + typecheck) + +# Build standalone image +docker build -t {{PROJECT_NAME}} . # Build development image ``` - -### Key Features - -- **๐Ÿ”’ Security-First**: Distroless production images, non-root user, vulnerability scanning -- **โšก Performance**: BuildKit caching, uv package manager, optimized layer ordering -- **๐Ÿ“Š Monitoring**: Health checks, resource limits, comprehensive logging - **๐Ÿ› ๏ธ Development**: Hot reload, separate services for testing/docs/quality checks @@ -155,7 +126,7 @@ docker-compose -f docker-compose.prod.yml --profile load-test up | **Testing** | PyTest + Hypothesis (property-based testing), pytest-html-plus (BDD reports) | | **AI Integration** | OpenCode agents for development automation | | **Documentation** | pdoc with search functionality | -| **Containerization** | Docker with distroless production, BuildKit caching, security scanning | +| **Containerization** | Docker development environment with hot reload | ## ๐Ÿ“ˆ Quality Metrics @@ -168,22 +139,18 @@ docker-compose -f docker-compose.prod.yml --profile load-test up ## ๐Ÿš€ Deployment Ready ```bash -# Production container (distroless, security-hardened) -docker build --target production -t {{PROJECT_NAME}}:latest . -docker run {{PROJECT_NAME}}:latest +# Build container image +docker build -t {{PROJECT_NAME}} . +docker run {{PROJECT_NAME}} -# Production environment testing -docker-compose -f docker-compose.prod.yml up +# Run with Docker Compose +docker-compose up # Build API documentation task doc-build # Generates docs/api/index.html -# Publish API docs to GitHub Pages -task doc-publish # Pushes docs/api to gh-pages branch - -# Smart release management -@repo-manager /skill git-release -# Creates versioned release: v1.2.20260315 "Creative Fox" +# Serve documentation locally +task doc-serve # http://localhost:8080 ``` ## ๐Ÿค Contributing diff --git a/Dockerfile b/Dockerfile index 8a6be45..6917616 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,48 +1,26 @@ # syntax=docker/dockerfile:1.7 -# Modern Dockerfile for python-project-template -# Features: multi-stage build, distroless prod, security scanning, BuildKit caching +# Simplified Dockerfile for python-project-template +# Single-stage development-focused build ARG PYTHON_VERSION=3.13.1 -ARG BUILDPLATFORM=linux/amd64 -# ============================================================================= -# Base stage: Python + uv package manager -# ============================================================================= -FROM --platform=$BUILDPLATFORM python:${PYTHON_VERSION}-alpine AS base +FROM python:${PYTHON_VERSION}-slim AS base -# Install uv for ultra-fast Python package management -RUN --mount=type=cache,target=/root/.cache/pip \ - pip install --upgrade pip uv +# Install uv for fast Python package management +RUN pip install --upgrade pip uv -# Create non-root user early -RUN addgroup --system --gid 1001 appuser && \ - adduser --system --uid 1001 --ingroup appuser appuser +# Create non-root user +RUN groupadd --gid 1001 appuser && \ + useradd --uid 1001 --gid appuser --shell /bin/bash --create-home appuser WORKDIR /app -# ============================================================================= -# Dependencies stage: Install and cache Python dependencies -# ============================================================================= -FROM base AS deps - -# Install build dependencies -RUN apk add --no-cache \ - build-base \ - linux-headers \ - git - # Copy dependency files first (better layer caching) -COPY pyproject.toml ./ +COPY pyproject.toml uv.lock* ./ -# Install dependencies with uv (much faster than pip) +# Install dependencies RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=cache,target=/root/.cache/pip \ - uv pip install --system '.[dev]' taskipy - -# ============================================================================= -# Test stage: Run linting and tests -# ============================================================================= -FROM deps AS test + uv sync --locked --dev # Copy source code COPY . . @@ -51,103 +29,23 @@ COPY . . RUN chown -R appuser:appuser /app USER appuser -# Set build arguments for conditional testing -ARG TESTBUILD=true -ENV TESTBUILD=$TESTBUILD - -# Run quality checks and tests if enabled -RUN if [ "$TESTBUILD" = "true" ]; then \ - echo "๐Ÿ” Running linting..." && \ - task lint && \ - echo "๐Ÿงช Running tests..." && \ - task test && \ - echo "โœ… All quality checks passed!"; \ - fi - -# ============================================================================= -# Build stage: Create wheel distribution -# ============================================================================= -FROM test AS build - -# Build wheel package -RUN --mount=type=cache,target=/root/.cache/uv \ - uv build --wheel --out-dir dist - -# ============================================================================= -# Security scanning stage (optional but recommended) -# ============================================================================= -FROM aquasec/trivy:latest AS security-scan - -# Copy built artifacts for scanning -COPY --from=build /app/dist /scan/dist -COPY --from=build /app/pyproject.toml /scan/ - -# Run security scan (will fail build on HIGH/CRITICAL vulnerabilities) -RUN trivy fs --exit-code 1 --severity HIGH,CRITICAL /scan || \ - (echo "โŒ Security vulnerabilities found! Check the output above." && exit 1) - -# ============================================================================= -# Runtime preparation: Install wheel in clean Python environment -# ============================================================================= -FROM python:${PYTHON_VERSION}-alpine AS runtime-prep - -# Install the wheel package in a clean environment -COPY --from=build /app/dist/*.whl /tmp/ -RUN pip install --prefix=/app/python /tmp/*.whl - -# ============================================================================= -# Production stage: Minimal distroless runtime -# ============================================================================= -FROM gcr.io/distroless/python3-debian12:latest AS production - -# Copy installed Python packages from runtime prep -COPY --from=runtime-prep /app/python /usr/local - -# Set working directory -WORKDIR /app - -# Use non-root user (distroless default nonroot user) -USER nonroot:nonroot - -# Configure Python for production +# Configure Python +ENV PYTHONPATH=/app ENV PYTHONUNBUFFERED=1 ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONHASHSEED=random -# Health check using module execution +# Expose common ports +EXPOSE 8000 8080 5678 + +# Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD python -m python_package_template.python_module_template || exit 1 # Default command CMD ["python", "-m", "python_package_template.python_module_template"] -# ============================================================================= -# Development stage: For local development with hot reload -# ============================================================================= -FROM deps AS development - -# Install development tools -RUN --mount=type=cache,target=/root/.cache/uv \ - uv pip install --system watchdog - -# Copy source code -COPY . . - -# Change ownership and switch to non-root user -RUN chown -R appuser:appuser /app -USER appuser - -# Expose common development ports -EXPOSE 8000 8080 5678 - -# Development command with auto-reload -CMD ["python", "-m", "python_package_template.python_module_template"] - -# ============================================================================= -# Metadata and labels -# ============================================================================= +# Labels LABEL maintainer="eol" -LABEL version="0.1.20260411" -LABEL description="Python project template with modern Docker practices" -LABEL org.opencontainers.image.source="https://github.com/nullhack/python-project-template" -LABEL org.opencontainers.image.documentation="https://github.com/nullhack/python-project-template/tree/main/docs/api/" \ No newline at end of file +LABEL version="2.0.20260411" +LABEL description="Python project template - simplified Docker setup" +LABEL org.opencontainers.image.source="https://github.com/nullhack/python-project-template" \ No newline at end of file diff --git a/README.md b/README.md index 99d6f16..49a274a 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,8 @@ [![MIT License][license-shield]][license-url] [![Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?style=for-the-badge)](docs/coverage/index.html) -[![CI Status](https://github.com/nullhack/python-project-template/workflows/CI/badge.svg?style=for-the-badge)](https://github.com/nullhack/python-project-template/actions/workflows/ci.yml) -[![CodeQL](https://github.com/nullhack/python-project-template/workflows/CodeQL%20Security%20Analysis/badge.svg?style=for-the-badge)](https://github.com/nullhack/python-project-template/actions/workflows/codeql.yml) +[![CI](https://img.shields.io/github/actions/workflow/status/nullhack/python-project-template/ci.yml?style=for-the-badge&label=CI)](https://github.com/nullhack/python-project-template/actions/workflows/ci.yml) [![Python](https://img.shields.io/badge/python-3.13-blue?style=for-the-badge)](https://www.python.org/downloads/) -[![Code Style](https://img.shields.io/badge/code%20style-ruff-000000.svg?style=for-the-badge)](https://github.com/astral-sh/ruff) -[![Security](https://img.shields.io/badge/security-ruff%20%2B%20CodeQL-green?style=for-the-badge)](https://docs.astral.sh/ruff/rules/#flake8-bandit-s) > **Ship production-ready Python projects faster with AI-powered development workflows** @@ -179,25 +176,24 @@ task doc-build # Static API documentation generation ```bash # Development workflows -docker-compose up # Hot reload development -docker-compose --profile test up # Complete test suite -docker-compose --profile quality up # Code quality pipeline - -# Production workflows -docker build --target production -t app:prod . # Security-optimized build -docker-compose -f docker-compose.prod.yml up # Production testing -docker-compose -f docker-compose.prod.yml --profile security up # Vulnerability scan +docker-compose up # Hot reload development environment +docker-compose --profile test up # Run complete test suite +docker-compose --profile docs up # Documentation server (localhost:8080) +docker-compose --profile quality up # Code quality checks (lint + typecheck) + +# Build standalone image +docker build -t python-template . # Build development image ``` ## ๐Ÿ“ˆ Quality Metrics & Standards - โœ… **100% Test Coverage** - Branch and line coverage with pytest-cov -- โœ… **Security Hardened** - Distroless containers, non-root execution, vulnerability scanning +- โœ… **Container Ready** - Docker development environment with hot reload and debugging - โœ… **Static Type Safety** - Complete type hints with protocol-based interfaces - โœ… **Zero Linting Issues** - Automated Ruff formatting and style enforcement - โœ… **Property-Based Testing** - Hypothesis for robust edge case validation - โœ… **Architecture Compliance** - AI-enforced SOLID principles and Object Calisthenics -- โœ… **Container Security** - Minimal attack surface with read-only production filesystems +- โœ… **Development Friendly** - Hot reload, debugging support, and integrated tooling ## ๐Ÿš€ Release Management @@ -221,8 +217,8 @@ docker run your-project:latest @repo-manager /skill git-release # Example: Creates v1.2.20260411 "Secure Fortress" (Docker security improvements) -# Deploy with confidence -docker-compose -f docker-compose.prod.yml up --detach +# Run your application +docker-compose up --detach ``` ## ๐Ÿค Contributing @@ -255,9 +251,7 @@ Standing on the shoulders of giants: - [OpenCode](https://opencode.ai) - Revolutionary AI-powered development platform - [UV](https://astral.sh/uv/) - Blazing fast Python package and project manager - [Ruff](https://astral.sh/ruff/) - Extremely fast Python linter and formatter -- [Docker](https://docker.com) - Industry-standard containerization platform -- [Distroless](https://github.com/GoogleContainerTools/distroless) - Google's minimal container images -- [Trivy](https://trivy.dev/) - Comprehensive security scanner +- [Docker](https://docker.com) - Containerization for development environment - [Hypothesis](https://hypothesis.readthedocs.io/) - Property-based testing framework --- diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml deleted file mode 100644 index 963a300..0000000 --- a/docker-compose.prod.yml +++ /dev/null @@ -1,193 +0,0 @@ -# Docker Compose for python-project-template -# Production-like testing and deployment setup - -services: - # ============================================================================= - # Production application - # ============================================================================= - app: - build: - context: . - dockerfile: Dockerfile - target: production - args: - - TESTBUILD=true # Run full test suite before production build - - PYTHON_VERSION=3.13.1 - image: python-template:production - container_name: python-template-prod - environment: - - PYTHONUNBUFFERED=1 - - PYTHONDONTWRITEBYTECODE=1 - - PYTHONHASHSEED=random - # Note: No ports exposed by default for security - # Uncomment as needed: - # ports: - # - "8000:8000" - restart: unless-stopped - healthcheck: - test: ["CMD", "python", "-m", "python_package_template.python_module_template"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 15s - # Resource limits for production - deploy: - resources: - limits: - cpus: '1.0' - memory: 512M - reservations: - cpus: '0.25' - memory: 128M - security_opt: - - no-new-privileges:true - read_only: true - tmpfs: - - /tmp:noexec,nosuid,size=100m - - # ============================================================================= - # Security scanning service - # ============================================================================= - security-scan: - build: - context: . - dockerfile: Dockerfile - target: security-scan - container_name: python-template-security - volumes: - - security-reports:/reports - command: | - sh -c " - echo '๐Ÿ” Running comprehensive security scan...' - trivy image --exit-code 0 --format json --output /reports/image-scan.json python-template:production || true - trivy fs --exit-code 0 --format json --output /reports/fs-scan.json /scan || true - echo 'โœ… Security scan completed. Reports saved to /reports/' - " - profiles: - - security - - # ============================================================================= - # Production health monitoring - # ============================================================================= - healthcheck: - build: - context: . - dockerfile: Dockerfile - target: development - args: - - TESTBUILD=false - container_name: python-template-healthcheck - volumes: - - health-reports:/reports - command: | - sh -c " - echo '๐Ÿฅ Starting health monitoring...' - while true; do - echo 'Running health check...' - python -m python_package_template.python_module_template > /reports/health.log 2>&1 - echo 'Health check completed at $(date)' >> /reports/health.log - sleep 30 - done - " - profiles: - - monitoring - - # ============================================================================= - # Load testing service (simplified) - # ============================================================================= - load-test: - build: - context: . - dockerfile: Dockerfile - target: development - args: - - TESTBUILD=false - container_name: python-template-load-test - volumes: - - load-reports:/reports - command: | - sh -c " - echo '๐Ÿš€ Running load tests...' - echo 'Load Test Results' > /reports/load-test.log - echo '=================' >> /reports/load-test.log - echo 'Started at: $(date)' >> /reports/load-test.log - - # Run multiple iterations - for i in {1..10}; do - echo 'Running iteration $i...' - start_time=$(date +%s.%N) - python -m python_package_template.python_module_template >> /reports/load-test.log 2>&1 - end_time=$(date +%s.%N) - duration=$(echo \"$end_time - $start_time\" | bc -l) - echo 'Iteration $i completed in ${duration}s' >> /reports/load-test.log - sleep 1 - done - - echo 'Completed at: $(date)' >> /reports/load-test.log - echo 'โœ… Load test completed' - " - profiles: - - load-test - depends_on: - - app - - # ============================================================================= - # Image analysis service - # ============================================================================= - analyze: - build: - context: . - dockerfile: Dockerfile - target: development - args: - - TESTBUILD=false - container_name: python-template-analyze - volumes: - - analysis-reports:/reports - - /var/run/docker.sock:/var/run/docker.sock:ro - command: | - sh -c " - echo '๐Ÿ“Š Analyzing production image...' - - # Image size analysis - echo 'Production Image Analysis' > /reports/analysis.txt - echo '========================' >> /reports/analysis.txt - echo 'Generated at: $(date)' >> /reports/analysis.txt - echo '' >> /reports/analysis.txt - - # Note: This would require docker client in the container - # For now, we'll create a placeholder report - echo 'Image: python-template:production' >> /reports/analysis.txt - echo 'Base: distroless/python3-debian12' >> /reports/analysis.txt - echo 'Security: Non-root user, read-only filesystem' >> /reports/analysis.txt - echo 'Features: Multi-stage build, vulnerability scanning' >> /reports/analysis.txt - - echo 'โœ… Analysis completed' - " - profiles: - - analysis - -# ============================================================================= -# Named volumes for production reports and data -# ============================================================================= -volumes: - security-reports: - driver: local - name: python-template-security-reports - health-reports: - driver: local - name: python-template-health-reports - load-reports: - driver: local - name: python-template-load-reports - analysis-reports: - driver: local - name: python-template-analysis-reports - -# ============================================================================= -# Production network with isolation -# ============================================================================= -networks: - default: - name: python-template-prod-network - driver: bridge \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 64f1265..806af12 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,88 +1,47 @@ # Docker Compose for python-project-template -# Development-focused setup with hot reload and debugging capabilities +# Simplified development setup services: # ============================================================================= - # Main development service + # Main application # ============================================================================= app: build: context: . dockerfile: Dockerfile - target: development - args: - - TESTBUILD=false # Skip tests in dev mode for faster startup - container_name: python-template-dev + container_name: python-template-app volumes: # Hot reload: mount source code - - ./python_package_template:/app/python_package_template:ro - - ./tests:/app/tests:ro + - ./python_package_template:/app/python_package_template + - ./tests:/app/tests - ./pyproject.toml:/app/pyproject.toml:ro - # Persistent volumes for development artifacts - - dev-cache:/app/.pytest_cache - - dev-coverage:/app/htmlcov - - dev-docs:/app/docs + ports: + - "8000:8000" # Main application + - "8080:8080" # Documentation server + - "5678:5678" # Debug port environment: - PYTHONPATH=/app - PYTHONUNBUFFERED=1 - - PYTHONDONTWRITEBYTECODE=1 - DEVELOPMENT=true - ports: - - "8000:8000" # Main application port - - "8080:8080" # Documentation server (pdoc) - - "5678:5678" # Debug port (debugpy) command: python -m python_package_template.python_module_template - healthcheck: - test: ["CMD", "python", "-m", "python_package_template.python_module_template"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 10s restart: unless-stopped # ============================================================================= - # Test runner service + # Test runner # ============================================================================= test: build: context: . - dockerfile: Dockerfile - target: test - args: - - TESTBUILD=true + dockerfile: Dockerfile container_name: python-template-test volumes: - ./:/app:ro - - test-reports:/app/docs/tests - - test-coverage:/app/docs/coverage - - test-mutation:/app/docs/mutation environment: - PYTHONPATH=/app - PYTHONUNBUFFERED=1 command: task test profiles: - test - - # ============================================================================= - # Fast test runner (development) - # ============================================================================= - test-fast: - build: - context: . - dockerfile: Dockerfile - target: development - args: - - TESTBUILD=false - container_name: python-template-test-fast - volumes: - - ./:/app:ro - - test-cache:/app/.pytest_cache - environment: - - PYTHONPATH=/app - - PYTHONUNBUFFERED=1 - command: task test-fast - profiles: - - test # ============================================================================= # Documentation server @@ -91,14 +50,10 @@ services: build: context: . dockerfile: Dockerfile - target: development - args: - - TESTBUILD=false container_name: python-template-docs volumes: - ./python_package_template:/app/python_package_template:ro - ./pyproject.toml:/app/pyproject.toml:ro - - dev-docs:/app/docs ports: - "8080:8080" environment: @@ -106,80 +61,26 @@ services: command: task doc-serve profiles: - docs - healthcheck: - test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080"] - interval: 30s - timeout: 5s - retries: 3 # ============================================================================= - # Code quality and linting service + # Code quality checks # ============================================================================= - lint: + quality: build: context: . dockerfile: Dockerfile - target: development - args: - - TESTBUILD=false - container_name: python-template-lint + container_name: python-template-quality volumes: - ./:/app:ro environment: - PYTHONPATH=/app - command: task lint + command: bash -c "task lint && task static-check" profiles: - quality - # ============================================================================= - # Static type checking service - # ============================================================================= - typecheck: - build: - context: . - dockerfile: Dockerfile - target: development - args: - - TESTBUILD=false - container_name: python-template-typecheck - volumes: - - ./:/app:ro - environment: - - PYTHONPATH=/app - command: task static-check - profiles: - - quality - -# ============================================================================= -# Named volumes for persistent development data -# ============================================================================= -volumes: - dev-cache: - driver: local - name: python-template-dev-cache - dev-coverage: - driver: local - name: python-template-dev-coverage - dev-docs: - driver: local - name: python-template-dev-docs - test-reports: - driver: local - name: python-template-test-reports - test-coverage: - driver: local - name: python-template-test-coverage - test-mutation: - driver: local - name: python-template-test-mutation - test-cache: - driver: local - name: python-template-test-cache - # ============================================================================= -# Networks (using default bridge network) +# Networks # ============================================================================= networks: default: - name: python-template-network - driver: bridge \ No newline at end of file + name: python-template-network \ No newline at end of file