chore: git cache cleanup

This commit is contained in:
GitHub Actions
2026-03-04 18:34:49 +00:00
parent c32cce2a88
commit 27c252600a
2001 changed files with 683185 additions and 0 deletions

50
.docker/compose/README.md Normal file
View File

@@ -0,0 +1,50 @@
# Docker Compose Files
This directory contains all Docker Compose configuration variants for Charon.
## File Descriptions
| File | Purpose |
|------|---------|
| `docker-compose.yml` | Main production compose configuration. Base services and production settings. |
| `docker-compose.dev.yml` | Development overrides. Enables hot-reload, debug logging, and development tools. |
| `docker-compose.local.yml` | Local development configuration. Standalone setup for local testing. |
| `docker-compose.remote.yml` | Remote deployment configuration. Settings for deploying to remote servers. |
| `docker-compose.override.yml` | Personal local overrides. **Gitignored** - use for machine-specific settings. |
## Usage Patterns
### Production Deployment
```bash
docker compose -f .docker/compose/docker-compose.yml up -d
```
### Development Mode
```bash
docker compose -f .docker/compose/docker-compose.yml \
-f .docker/compose/docker-compose.dev.yml up -d
```
### Local Testing
```bash
docker compose -f .docker/compose/docker-compose.local.yml up -d
```
### With Personal Overrides
Create your own `docker-compose.override.yml` in this directory for personal
configurations (port mappings, volume paths, etc.). This file is gitignored.
```bash
docker compose -f .docker/compose/docker-compose.yml \
-f .docker/compose/docker-compose.override.yml up -d
```
## Notes
- Always use the `-f` flag to specify compose file paths from the project root
- The override file is automatically ignored by git - do not commit personal settings
- See project tasks in VS Code for convenient pre-configured commands

View File

@@ -0,0 +1,46 @@
# Development override - use with: docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
services:
app:
# Override for local testing:
# CHARON_DEV_IMAGE=ghcr.io/wikid82/charon:dev
image: wikid82/charon:dev
# Development: expose Caddy admin API externally for debugging
ports:
- "80:80"
- "443:443"
- "443:443/udp"
- "8080:8080"
- "2019:2019" # Caddy admin API (dev only)
environment:
- CHARON_ENV=development
- CPM_ENV=development
- CHARON_HTTP_PORT=8080
- CPM_HTTP_PORT=80
# Generate with: openssl rand -base64 32
- CHARON_ENCRYPTION_KEY=your-32-byte-base64-key-here
- CHARON_DB_PATH=/app/data/charon.db
- CHARON_FRONTEND_DIR=/app/frontend/dist
- CHARON_CADDY_ADMIN_API=http://localhost:2019
- CHARON_CADDY_CONFIG_DIR=/app/data/caddy
# Security Services (Optional)
# 🚨 DEPRECATED: Use GUI toggle in Security dashboard instead
#- CPM_SECURITY_CROWDSEC_MODE=disabled # ⚠️ DEPRECATED
#- CPM_SECURITY_CROWDSEC_API_URL= # ⚠️ DEPRECATED
#- CPM_SECURITY_CROWDSEC_API_KEY= # ⚠️ DEPRECATED
#- CPM_SECURITY_WAF_MODE=disabled
#- CPM_SECURITY_RATELIMIT_ENABLED=false
#- CPM_SECURITY_ACL_ENABLED=false
- FEATURE_CERBERUS_ENABLED=true
# Docker socket group access: copy docker-compose.override.example.yml
# to docker-compose.override.yml and set your host's docker GID.
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # For local container discovery
- crowdsec_data:/app/data/crowdsec
# Mount your existing Caddyfile for automatic import (optional)
# - ./my-existing-Caddyfile:/import/Caddyfile:ro
# - ./sites:/import/sites:ro # If your Caddyfile imports other files
volumes:
crowdsec_data:
driver: local

View File

@@ -0,0 +1,4 @@
services:
charon-e2e:
environment:
- CHARON_SECURITY_CERBERUS_ENABLED=false

View File

@@ -0,0 +1,66 @@
services:
charon:
image: charon:local
container_name: charon
restart: unless-stopped
ports:
- "80:80" # HTTP (Caddy proxy)
- "443:443" # HTTPS (Caddy proxy)
- "443:443/udp" # HTTP/3 (Caddy proxy)
- "8080:8080" # Management UI (Charon)
- "2345:2345" # Delve Debugger
environment:
- CHARON_ENV=development
- CHARON_DEBUG=1
- TZ=America/New_York
# Generate with: openssl rand -base64 32
- CHARON_ENCRYPTION_KEY=your-32-byte-base64-key-here
- CHARON_HTTP_PORT=8080
- CHARON_DB_PATH=/app/data/charon.db
- CHARON_FRONTEND_DIR=/app/frontend/dist
- CHARON_CADDY_ADMIN_API=http://localhost:2019
- CHARON_CADDY_CONFIG_DIR=/app/data/caddy
- CHARON_CADDY_BINARY=caddy
- CHARON_IMPORT_CADDYFILE=/import/Caddyfile
- CHARON_IMPORT_DIR=/app/data/imports
- CHARON_ACME_STAGING=false
- FEATURE_CERBERUS_ENABLED=true
# Emergency "break-glass" token for security reset when ACL blocks access
- CHARON_EMERGENCY_TOKEN=03e4682c1164f0c1cb8e17c99bd1a2d9156b59824dde41af3bb67c513e5c5e92
# Docker socket group access: copy docker-compose.override.example.yml
# to docker-compose.override.yml and set your host's docker GID.
extra_hosts:
- "host.docker.internal:host-gateway"
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined
volumes:
- charon_data:/app/data
- caddy_data:/data
- caddy_config:/config
- crowdsec_data:/app/data/crowdsec
- plugins_data:/app/plugins # Read-write for development/hot-loading
- /var/run/docker.sock:/var/run/docker.sock:ro # For local container discovery
- ./backend:/app/backend:ro # Mount source for debugging
# Mount your existing Caddyfile for automatic import (optional)
# - <PATH_TO_YOUR_CADDYFILE>:/import/Caddyfile:ro
# - <PATH_TO_YOUR_SITES_DIR>:/import/sites:ro # If your Caddyfile imports other files
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:8080/api/v1/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
volumes:
charon_data:
driver: local
caddy_data:
driver: local
caddy_config:
driver: local
crowdsec_data:
driver: local
plugins_data:
driver: local

View File

@@ -0,0 +1,26 @@
# Docker Compose override — copy to docker-compose.override.yml to activate.
#
# Use case: grant the container access to the host Docker socket so that
# Charon can discover running containers.
#
# 1. cp docker-compose.override.example.yml docker-compose.override.yml
# 2. Uncomment the service that matches your compose file:
# - "charon" for docker-compose.local.yml
# - "app" for docker-compose.dev.yml
# 3. Replace <GID> with the output of: stat -c '%g' /var/run/docker.sock
# 4. docker compose up -d
services:
# Uncomment for docker-compose.local.yml
charon:
group_add:
- "<GID>" # e.g. "988" — run: stat -c '%g' /var/run/docker.sock
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
# Uncomment for docker-compose.dev.yml
app:
group_add:
- "<GID>" # e.g. "988" — run: stat -c '%g' /var/run/docker.sock
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro

View File

@@ -0,0 +1,160 @@
# Playwright E2E Test Environment for CI/CD
# ==========================================
# This configuration is specifically designed for GitHub Actions CI/CD pipelines.
# Environment variables are provided via GitHub Secrets and generated dynamically.
#
# DO NOT USE env_file - CI provides variables via $GITHUB_ENV:
# - CHARON_ENCRYPTION_KEY: Generated with openssl rand -base64 32 (ephemeral)
# - CHARON_EMERGENCY_TOKEN: From repository secrets (secure)
#
# Usage in CI:
# export CHARON_ENCRYPTION_KEY=$(openssl rand -base64 32)
# export CHARON_EMERGENCY_TOKEN="${{ secrets.CHARON_EMERGENCY_TOKEN }}"
# docker compose -f .docker/compose/docker-compose.playwright-ci.yml up -d
#
# Profiles:
# # Start with security testing services (CrowdSec)
# docker compose -f .docker/compose/docker-compose.playwright-ci.yml --profile security-tests up -d
#
# # Start with notification testing services (MailHog)
# docker compose -f .docker/compose/docker-compose.playwright-ci.yml --profile notification-tests up -d
#
# The setup API will be available since no users exist in the fresh database.
# The auth.setup.ts fixture will create a test admin user automatically.
services:
# =============================================================================
# Charon Application - Core E2E Testing Service
# =============================================================================
charon-app:
# CI provides CHARON_E2E_IMAGE_TAG=charon:e2e-test (retagged from shared digest)
# Local development uses the default fallback value
image: ${CHARON_E2E_IMAGE_TAG:-charon:e2e-test}
container_name: charon-playwright
restart: "no"
# CI generates CHARON_ENCRYPTION_KEY dynamically in GitHub Actions workflow
# and passes CHARON_EMERGENCY_TOKEN from GitHub Secrets via $GITHUB_ENV.
# No .env file is used in CI as it's gitignored and not available.
ports:
- "8080:8080" # Management UI (Charon)
- "127.0.0.1:2019:2019" # Caddy admin API (IPv4 loopback)
- "[::1]:2019:2019" # Caddy admin API (IPv6 loopback)
- "2020:2020" # Emergency tier-2 API (all interfaces for E2E tests)
- "80:80" # Caddy proxy (all interfaces for E2E tests)
- "443:443" # Caddy proxy HTTPS (all interfaces for E2E tests)
environment:
# Core configuration
- CHARON_ENV=test
- CHARON_DEBUG=0
- TZ=UTC
# E2E testing encryption key - 32 bytes base64 encoded (not for production!)
# Encryption key - MUST be provided via environment variable
# Generate with: export CHARON_ENCRYPTION_KEY=$(openssl rand -base64 32)
- CHARON_ENCRYPTION_KEY=${CHARON_ENCRYPTION_KEY:?CHARON_ENCRYPTION_KEY is required}
# Emergency reset token - for break-glass recovery when locked out by ACL
# Generate with: openssl rand -hex 32
- CHARON_EMERGENCY_TOKEN=${CHARON_EMERGENCY_TOKEN:-test-emergency-token-for-e2e-32chars}
- CHARON_EMERGENCY_SERVER_ENABLED=true
- CHARON_SECURITY_TESTS_ENABLED=${CHARON_SECURITY_TESTS_ENABLED:-true}
# Emergency server must bind to 0.0.0.0 for Docker port mapping to work
# Host binding via compose restricts external access (127.0.0.1:2020:2020)
- CHARON_EMERGENCY_BIND=0.0.0.0:2020
# Emergency server Basic Auth (required for E2E tests)
- CHARON_EMERGENCY_USERNAME=admin
- CHARON_EMERGENCY_PASSWORD=changeme
# Server settings
- CHARON_HTTP_PORT=8080
- CHARON_DB_PATH=/app/data/charon.db
- CHARON_FRONTEND_DIR=/app/frontend/dist
# Caddy settings
- CHARON_CADDY_ADMIN_API=http://localhost:2019
- CHARON_CADDY_CONFIG_DIR=/app/data/caddy
- CHARON_CADDY_BINARY=caddy
# ACME settings (staging for E2E tests)
- CHARON_ACME_STAGING=true
# Security features - disabled by default for faster tests
# Enable via profile: --profile security-tests
# FEATURE_CERBERUS_ENABLED deprecated - Cerberus enabled by default
- CHARON_SECURITY_CROWDSEC_MODE=disabled
# SMTP for notification tests (connects to MailHog when profile enabled)
- CHARON_SMTP_HOST=mailhog
- CHARON_SMTP_PORT=1025
- CHARON_SMTP_AUTH=false
volumes:
# Named volume for test data persistence during test runs
- playwright_data:/app/data
- playwright_caddy_data:/data
- playwright_caddy_config:/config
- /var/run/docker.sock:/var/run/docker.sock:ro # For container discovery in tests
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8080/api/v1/health"]
interval: 5s
timeout: 3s
retries: 12
start_period: 10s
networks:
- playwright-network
# =============================================================================
# CrowdSec - Security Testing Service (Optional Profile)
# =============================================================================
crowdsec:
image: crowdsecurity/crowdsec:latest@sha256:63b595fef92de1778573b375897a45dd226637ee9a3d3db9f57ac7355c369493
container_name: charon-playwright-crowdsec
profiles:
- security-tests
restart: "no"
environment:
- COLLECTIONS=crowdsecurity/nginx crowdsecurity/http-cve
- BOUNCER_KEY_charon=test-bouncer-key-for-e2e
# Disable online features for isolated testing
- DISABLE_ONLINE_API=true
volumes:
- playwright_crowdsec_data:/var/lib/crowdsec/data
- playwright_crowdsec_config:/etc/crowdsec
- /var/run/docker.sock:/var/run/docker.sock:ro # For container discovery in tests
healthcheck:
test: ["CMD", "cscli", "version"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
- playwright-network
# =============================================================================
# MailHog - Email Testing Service (Optional Profile)
# =============================================================================
mailhog:
image: mailhog/mailhog:latest@sha256:8d76a3d4ffa32a3661311944007a415332c4bb855657f4f6c57996405c009bea
container_name: charon-playwright-mailhog
profiles:
- notification-tests
restart: "no"
ports:
- "1025:1025" # SMTP server
- "8025:8025" # Web UI for viewing emails
networks:
- playwright-network
# =============================================================================
# Named Volumes
# =============================================================================
volumes:
playwright_data:
driver: local
playwright_caddy_data:
driver: local
playwright_caddy_config:
driver: local
playwright_crowdsec_data:
driver: local
playwright_crowdsec_config:
driver: local
# =============================================================================
# Networks
# =============================================================================
networks:
playwright-network:
driver: bridge

View File

@@ -0,0 +1,59 @@
# Docker Compose for Local E2E Testing
#
# This configuration runs Charon with a fresh, isolated database specifically for
# Playwright E2E tests during local development. Uses .env file for credentials.
#
# Usage:
# docker compose -f .docker/compose/docker-compose.playwright-local.yml up -d
#
# Prerequisites:
# - Create .env file in project root with CHARON_ENCRYPTION_KEY and CHARON_EMERGENCY_TOKEN
# - Build image: docker build -t charon:local .
#
# The setup API will be available since no users exist in the fresh database.
# The auth.setup.ts fixture will create a test admin user automatically.
services:
charon-e2e:
image: charon:local
container_name: charon-e2e
restart: "no"
env_file:
- ../../.env
ports:
- "8080:8080" # Management UI (Charon) - E2E tests verify UI/UX here
- "127.0.0.1:2019:2019" # Caddy admin API (read-only status; keep loopback only)
- "[::1]:2019:2019" # Caddy admin API (IPv6 loopback)
- "2020:2020" # Emergency tier-2 API (all interfaces for E2E tests)
# Port 80/443: NOT exposed - middleware testing done via integration tests
environment:
- CHARON_ENV=e2e # Enable lenient rate limiting (50 attempts/min) for E2E tests
- CHARON_DEBUG=0
- TZ=UTC
# Encryption key and emergency token loaded from env_file (../../.env)
# DO NOT add them here - env_file takes precedence and explicit entries override with empty values
# Emergency server (Tier 2 break glass) - separate port bypassing all security
- CHARON_EMERGENCY_SERVER_ENABLED=true
- CHARON_EMERGENCY_BIND=0.0.0.0:2020 # Bind to all interfaces in container (avoid Caddy's 2019)
- CHARON_EMERGENCY_USERNAME=admin
- CHARON_EMERGENCY_PASSWORD=${CHARON_EMERGENCY_PASSWORD:-changeme}
- CHARON_HTTP_PORT=8080
- CHARON_DB_PATH=/app/data/charon.db
- CHARON_FRONTEND_DIR=/app/frontend/dist
- CHARON_CADDY_ADMIN_API=http://localhost:2019
- CHARON_CADDY_CONFIG_DIR=/app/data/caddy
- CHARON_CADDY_BINARY=caddy
- CHARON_ACME_STAGING=true
# FEATURE_CERBERUS_ENABLED deprecated - Cerberus enabled by default
tmpfs:
# True tmpfs for E2E test data - fresh on every run, in-memory only
# mode=1777 allows any user to write (container runs as non-root)
- /app/data:size=100M,mode=1777
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # For container discovery in tests
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:8080/api/v1/health || exit 1"]
interval: 5s
timeout: 5s
retries: 10
start_period: 10s

View File

@@ -0,0 +1,19 @@
version: '3.9'
services:
# Run this service on your REMOTE servers (not the one running Charon)
# to allow Charon to discover containers running there (legacy: CPMP).
docker-socket-proxy:
image: alpine/socat:latest
container_name: docker-socket-proxy
restart: unless-stopped
ports:
# Expose port 2375.
# ⚠️ SECURITY WARNING: Ensure this port is NOT accessible from the public internet!
# Use a VPN (Tailscale, WireGuard) or a private local network (LAN).
- "2375:2375"
volumes:
# Give the proxy access to the host's Docker socket
- /var/run/docker.sock:/var/run/docker.sock:ro
# Forward TCP traffic from port 2375 to the internal Docker socket
command: tcp-listen:2375,fork,reuseaddr unix-connect:/var/run/docker.sock

View File

@@ -0,0 +1,71 @@
services:
charon:
# Override for local testing:
# CHARON_IMAGE=ghcr.io/wikid82/charon:latest
image: wikid82/charon:latest
container_name: charon
restart: unless-stopped
ports:
- "80:80" # HTTP (Caddy proxy)
- "443:443" # HTTPS (Caddy proxy)
- "443:443/udp" # HTTP/3 (Caddy proxy)
- "8080:8080" # Management UI (Charon)
# Emergency server port - ONLY expose via SSH tunnel or VPN for security
# Uncomment ONLY if you need localhost access on host machine:
# - "127.0.0.1:2020:2020" # Emergency server Tier-2 (localhost-only, avoids Caddy's 2019)
environment:
- CHARON_ENV=production # CHARON_ preferred; CPM_ values still supported
- TZ=UTC # Set timezone (e.g., America/New_York)
# Generate with: openssl rand -base64 32
- CHARON_ENCRYPTION_KEY=your-32-byte-base64-key-here
# Emergency break glass configuration (Tier 1 & Tier 2)
# Tier 1: Emergency token for Layer 7 bypass within application
# Generate with: openssl rand -hex 32
# - CHARON_EMERGENCY_TOKEN=${CHARON_EMERGENCY_TOKEN} # Store in secrets manager
# Tier 2: Emergency server on separate port (bypasses Caddy/CrowdSec entirely)
# - CHARON_EMERGENCY_SERVER_ENABLED=false # Disabled by default
# - CHARON_EMERGENCY_BIND=127.0.0.1:2020 # Localhost only (port 2020 avoids Caddy admin API)
# - CHARON_EMERGENCY_USERNAME=admin
# - CHARON_EMERGENCY_PASSWORD=${EMERGENCY_PASSWORD} # Store in secrets manager
- CHARON_HTTP_PORT=8080
- CHARON_DB_PATH=/app/data/charon.db
- CHARON_FRONTEND_DIR=/app/frontend/dist
- CHARON_CADDY_ADMIN_API=http://localhost:2019
- CHARON_CADDY_CONFIG_DIR=/app/data/caddy
- CHARON_CADDY_BINARY=caddy
- CHARON_IMPORT_CADDYFILE=/import/Caddyfile
- CHARON_IMPORT_DIR=/app/data/imports
# Paste your CrowdSec API details here to prevent auto reregistration on startup
# Obtained from your CrowdSec settings on first setup
- CHARON_SECURITY_CROWDSEC_API_URL=http://localhost:8085
- CHARON_SECURITY_CROWDSEC_API_KEY=<your-crowdsec-api-key-here>
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- cpm_data:/app/data # existing data (legacy name); charon will also use this path by default for backward compatibility
- caddy_data:/data
- caddy_config:/config
- crowdsec_data:/app/data/crowdsec
- plugins_data:/app/plugins:ro # Read-only in production for security
- /var/run/docker.sock:/var/run/docker.sock:ro # For local container discovery
# Mount your existing Caddyfile for automatic import (optional)
# - ./my-existing-Caddyfile:/import/Caddyfile:ro
# - ./sites:/import/sites:ro # If your Caddyfile imports other files
healthcheck:
test: ["CMD-SHELL", "curl -fsS http://localhost:8080/api/v1/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
volumes:
cpm_data:
driver: local
caddy_data:
driver: local
caddy_config:
driver: local
crowdsec_data:
driver: local
plugins_data:
driver: local