diff --git a/DOCKER.md b/.docker/README.md similarity index 56% rename from DOCKER.md rename to .docker/README.md index c904d85e..ae05f2d0 100644 --- a/DOCKER.md +++ b/.docker/README.md @@ -2,6 +2,20 @@ Charon is designed for Docker-first deployment, making it easy for home users to run Caddy without learning Caddyfile syntax. +## Directory Structure + +```text +.docker/ +├── compose/ # Docker Compose files +│ ├── docker-compose.yml # Main production compose +│ ├── docker-compose.dev.yml # Development overrides +│ ├── docker-compose.local.yml # Local development +│ ├── docker-compose.remote.yml # Remote deployment +│ └── docker-compose.override.yml # Personal overrides (gitignored) +├── docker-entrypoint.sh # Container entrypoint script +└── README.md # This file +``` + ## Quick Start ```bash @@ -9,13 +23,31 @@ Charon is designed for Docker-first deployment, making it easy for home users to git clone https://github.com/Wikid82/charon.git cd charon -# Start the stack -docker-compose up -d +# Start the stack (using new location) +docker compose -f .docker/compose/docker-compose.yml up -d # Access the UI open http://localhost:8080 ``` +## Usage + +When running docker-compose commands, specify the compose file location: + +```bash +# Production +docker compose -f .docker/compose/docker-compose.yml up -d + +# Development +docker compose -f .docker/compose/docker-compose.yml -f .docker/compose/docker-compose.dev.yml up -d + +# Local development +docker compose -f .docker/compose/docker-compose.local.yml up -d + +# With personal overrides +docker compose -f .docker/compose/docker-compose.yml -f .docker/compose/docker-compose.override.yml up -d +``` + ## Architecture Charon runs as a **single container** that includes: @@ -26,7 +58,7 @@ Charon runs as a **single container** that includes: This unified architecture simplifies deployment, updates, and data management. -``` +```text ┌──────────────────────────────────────────┐ │ Container (charon / cpmp) │ │ │ @@ -59,8 +91,8 @@ Configure the application via `docker-compose.yml`: | Variable | Default | Description | |----------|---------|-------------| - | `CHARON_ENV` | `production` | Set to `development` for verbose logging (`CPM_ENV` supported for backward compatibility). | - | `CHARON_HTTP_PORT` | `8080` | Port for the Web UI (`CPM_HTTP_PORT` supported for backward compatibility). | +| `CHARON_ENV` | `production` | Set to `development` for verbose logging (`CPM_ENV` supported for backward compatibility). | +| `CHARON_HTTP_PORT` | `8080` | Port for the Web UI (`CPM_HTTP_PORT` supported for backward compatibility). | | `CHARON_DB_PATH` | `/app/data/charon.db` | Path to the SQLite database (`CPM_DB_PATH` supported for backward compatibility). | | `CHARON_CADDY_ADMIN_API` | `http://localhost:2019` | Internal URL for Caddy API (`CPM_CADDY_ADMIN_API` supported for backward compatibility). | @@ -71,31 +103,31 @@ Configure the application via `docker-compose.yml`: 1. **Prepare Folders**: Create a folder `docker/charon` (or `docker/cpmp` for backward compatibility) and subfolders `data`, `caddy_data`, and `caddy_config`. 2. **Download Image**: Search for `ghcr.io/wikid82/charon` in the Registry and download the `latest` tag. 3. **Launch Container**: - * **Network**: Use `Host` mode (recommended for Caddy to see real client IPs) OR bridge mode mapping ports `80:80`, `443:443`, and `8080:8080`. - * **Volume Settings**: - * `/docker/charon/data` -> `/app/data` (or `/docker/cpmp/data` -> `/app/data` for backward compatibility) - * `/docker/charon/caddy_data` -> `/data` (or `/docker/cpmp/caddy_data` -> `/data` for backward compatibility) - * `/docker/charon/caddy_config` -> `/config` (or `/docker/cpmp/caddy_config` -> `/config` for backward compatibility) - * **Environment**: Add `CHARON_ENV=production` (or `CPM_ENV=production` for backward compatibility). + - **Network**: Use `Host` mode (recommended for Caddy to see real client IPs) OR bridge mode mapping ports `80:80`, `443:443`, and `8080:8080`. + - **Volume Settings**: + - `/docker/charon/data` -> `/app/data` (or `/docker/cpmp/data` -> `/app/data` for backward compatibility) + - `/docker/charon/caddy_data` -> `/data` (or `/docker/cpmp/caddy_data` -> `/data` for backward compatibility) + - `/docker/charon/caddy_config` -> `/config` (or `/docker/cpmp/caddy_config` -> `/config` for backward compatibility) + - **Environment**: Add `CHARON_ENV=production` (or `CPM_ENV=production` for backward compatibility). 4. **Finish**: Start the container and access `http://YOUR_NAS_IP:8080`. ### Unraid 1. **Community Apps**: (Coming Soon) Search for "charon". 2. **Manual Install**: - * Click **Add Container**. - * **Name**: Charon - * **Repository**: `ghcr.io/wikid82/charon:latest` - * **Network Type**: Bridge - * **WebUI**: `http://[IP]:[PORT:8080]` - * **Port mappings**: - * Container Port: `80` -> Host Port: `80` - * Container Port: `443` -> Host Port: `443` - * Container Port: `8080` -> Host Port: `8080` - * **Paths**: - * `/mnt/user/appdata/charon/data` -> `/app/data` (or `/mnt/user/appdata/cpmp/data` -> `/app/data` for backward compatibility) - * `/mnt/user/appdata/charon/caddy_data` -> `/data` (or `/mnt/user/appdata/cpmp/caddy_data` -> `/data` for backward compatibility) - * `/mnt/user/appdata/charon/caddy_config` -> `/config` (or `/mnt/user/appdata/cpmp/caddy_config` -> `/config` for backward compatibility) + - Click **Add Container**. + - **Name**: Charon + - **Repository**: `ghcr.io/wikid82/charon:latest` + - **Network Type**: Bridge + - **WebUI**: `http://[IP]:[PORT:8080]` + - **Port mappings**: + - Container Port: `80` -> Host Port: `80` + - Container Port: `443` -> Host Port: `443` + - Container Port: `8080` -> Host Port: `8080` + - **Paths**: + - `/mnt/user/appdata/charon/data` -> `/app/data` (or `/mnt/user/appdata/cpmp/data` -> `/app/data` for backward compatibility) + - `/mnt/user/appdata/charon/caddy_data` -> `/data` (or `/mnt/user/appdata/cpmp/caddy_data` -> `/data` for backward compatibility) + - `/mnt/user/appdata/charon/caddy_config` -> `/config` (or `/mnt/user/appdata/cpmp/caddy_config` -> `/config` for backward compatibility) 3. **Apply**: Click Done to pull and start. ## Troubleshooting @@ -107,7 +139,7 @@ Configure the application via `docker-compose.yml`: **Solution**: Since both run in the same container, this usually means Caddy failed to start. Check logs: ```bash -docker-compose logs app +docker compose -f .docker/compose/docker-compose.yml logs app ``` ### Certificates not working @@ -118,7 +150,7 @@ docker-compose logs app 1. Port 80/443 are accessible from the internet 2. DNS points to your server -3. Caddy logs: `docker-compose logs app | grep -i acme` +3. Caddy logs: `docker compose -f .docker/compose/docker-compose.yml logs app | grep -i acme` ### Config changes not applied @@ -131,7 +163,7 @@ docker-compose logs app curl http://localhost:2019/config/ | jq # Check Charon logs -docker-compose logs app +docker compose -f .docker/compose/docker-compose.yml logs app # Manual config reload curl -X POST http://localhost:8080/api/v1/caddy/reload @@ -142,8 +174,8 @@ curl -X POST http://localhost:8080/api/v1/caddy/reload Pull the latest images and restart: ```bash -docker-compose pull -docker-compose up -d +docker compose -f .docker/compose/docker-compose.yml pull +docker compose -f .docker/compose/docker-compose.yml up -d ``` For specific versions: @@ -152,7 +184,7 @@ For specific versions: # Edit docker-compose.yml to pin version image: ghcr.io/wikid82/charon:v1.0.0 -docker-compose up -d +docker compose -f .docker/compose/docker-compose.yml up -d ``` ## Building from Source @@ -199,9 +231,16 @@ services: memory: 256M ``` +## Important Notes + +- **Override Location Change**: The `docker-compose.override.yml` file has moved from + the project root to `.docker/compose/`. Update your local workflows accordingly. +- Personal override files (`.docker/compose/docker-compose.override.yml`) are gitignored + and should contain machine-specific configurations only. + ## Next Steps -* Configure your first proxy host via UI -* Enable automatic HTTPS (happens automatically) -* Add authentication (Issue #7) -* Integrate CrowdSec (Issue #15) +- Configure your first proxy host via UI +- Enable automatic HTTPS (happens automatically) +- Add authentication (Issue #7) +- Integrate CrowdSec (Issue #15) diff --git a/.docker/compose/README.md b/.docker/compose/README.md new file mode 100644 index 00000000..fcb7a990 --- /dev/null +++ b/.docker/compose/README.md @@ -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 diff --git a/docker-compose.dev.yml b/.docker/compose/docker-compose.dev.yml similarity index 100% rename from docker-compose.dev.yml rename to .docker/compose/docker-compose.dev.yml diff --git a/docker-compose.local.yml b/.docker/compose/docker-compose.local.yml similarity index 100% rename from docker-compose.local.yml rename to .docker/compose/docker-compose.local.yml diff --git a/docker-compose.remote.yml b/.docker/compose/docker-compose.remote.yml similarity index 100% rename from docker-compose.remote.yml rename to .docker/compose/docker-compose.remote.yml diff --git a/docker-compose.yml b/.docker/compose/docker-compose.yml similarity index 100% rename from docker-compose.yml rename to .docker/compose/docker-compose.yml diff --git a/docker-entrypoint.sh b/.docker/docker-entrypoint.sh similarity index 100% rename from docker-entrypoint.sh rename to .docker/docker-entrypoint.sh diff --git a/.dockerignore b/.dockerignore index 6e504097..c3be57d0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -138,6 +138,8 @@ docs/ # ----------------------------------------------------------------------------- docker-compose*.yml **/Dockerfile.* +.docker/compose/ +docs/implementation/ # ----------------------------------------------------------------------------- # GoReleaser & dist artifacts diff --git a/.github/instructions/structure.instructions.md b/.github/instructions/structure.instructions.md new file mode 100644 index 00000000..777f4bf7 --- /dev/null +++ b/.github/instructions/structure.instructions.md @@ -0,0 +1,94 @@ +--- +applyTo: '*' +description: 'Repository structure guidelines to maintain organized file placement' +--- + +# Repository Structure Guidelines + +## Root Level Rules + +The repository root should contain ONLY: + +- Essential config files (`.gitignore`, `.pre-commit-config.yaml`, `Makefile`, etc.) +- Standard project files (`README.md`, `CONTRIBUTING.md`, `LICENSE`, `CHANGELOG.md`) +- Go workspace files (`go.work`, `go.work.sum`) +- VS Code workspace (`Chiron.code-workspace`) +- Primary `Dockerfile` (entrypoint and compose files live in `.docker/`) + +## File Placement Rules + +### Implementation/Feature Documentation + +- **Location**: `docs/implementation/` +- **Pattern**: `*_SUMMARY.md`, `*_IMPLEMENTATION.md`, `*_COMPLETE.md`, `*_FEATURE.md` +- **Never** place implementation docs at root + +### Docker Compose Files + +- **Location**: `.docker/compose/` +- **Files**: `docker-compose.yml`, `docker-compose.*.yml` +- **Override**: Local overrides go in `.docker/compose/docker-compose.override.yml` (gitignored) +- **Exception**: `docker-compose.override.yml` at root is allowed for backward compatibility + +### Docker Support Files + +- **Location**: `.docker/` +- **Files**: `docker-entrypoint.sh`, Docker documentation (`README.md`) + +### Test Artifacts + +- **Never commit**: `*.sarif`, `*_test.txt`, `*.cover` files at root +- **Location**: Test outputs should go to `test-results/` or be gitignored + +### Debug/Temp Config Files + +- **Never commit**: Temporary JSON configs like `caddy_*.json` at root +- **Location**: Use `configs/` for persistent configs, gitignore temp files + +### Scripts + +- **Location**: `scripts/` for general scripts +- **Location**: `.github/skills/scripts/` for agent skill scripts + +## Before Creating New Files + +Ask yourself: + +1. Is this a standard project file? → Root is OK +2. Is this implementation documentation? → `docs/implementation/` +3. Is this Docker-related? → `.docker/` or `.docker/compose/` +4. Is this a test artifact? → `test-results/` or gitignore +5. Is this a script? → `scripts/` +6. Is this runtime config? → `configs/` + +## Directory Structure Reference + +``` +/ +├── .docker/ # Docker configuration +│ ├── compose/ # All docker-compose files +│ └── docker-entrypoint.sh # Container entrypoint +├── .github/ # GitHub workflows, agents, instructions +├── .vscode/ # VS Code settings and tasks +├── backend/ # Go backend source +├── configs/ # Runtime configurations +├── docs/ # Documentation +│ ├── implementation/ # Implementation/feature docs archive +│ ├── plans/ # Planning documents +│ └── ... # User-facing documentation +├── frontend/ # React frontend source +├── scripts/ # Build/test scripts +├── test-results/ # Test outputs (gitignored) +├── tools/ # Development tools +└── [standard files] # README, LICENSE, Makefile, etc. +``` + +## Enforcement + +This structure is enforced by: + +- `.gitignore` patterns preventing commits of artifacts at root +- Code review guidelines +- These instructions for AI assistants + +When reviewing PRs or generating code, ensure new files follow these placement rules. diff --git a/.github/skills/docker-start-dev-scripts/run.sh b/.github/skills/docker-start-dev-scripts/run.sh index a524f285..b1ff27ac 100755 --- a/.github/skills/docker-start-dev-scripts/run.sh +++ b/.github/skills/docker-start-dev-scripts/run.sh @@ -18,4 +18,4 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" cd "$REPO_ROOT" # Start development environment with Docker Compose -exec docker compose -f docker-compose.dev.yml up -d +exec docker compose -f .docker/compose/docker-compose.dev.yml up -d diff --git a/.github/skills/docker-start-dev.SKILL.md b/.github/skills/docker-start-dev.SKILL.md index afe391f5..98e07e96 100644 --- a/.github/skills/docker-start-dev.SKILL.md +++ b/.github/skills/docker-start-dev.SKILL.md @@ -41,13 +41,13 @@ metadata: ## Overview -Starts the Charon development Docker Compose environment in detached mode. This brings up all required services including the application, database, CrowdSec, and any other dependencies defined in `docker-compose.dev.yml`. +Starts the Charon development Docker Compose environment in detached mode. This brings up all required services including the application, database, CrowdSec, and any other dependencies defined in `.docker/compose/docker-compose.dev.yml`. ## Prerequisites - Docker Engine installed and running - Docker Compose V2 installed -- `docker-compose.dev.yml` file in repository root +- `.docker/compose/docker-compose.dev.yml` file in repository - Network access (for pulling images) - Sufficient system resources (CPU, memory, disk) @@ -71,13 +71,13 @@ Use the task: **Docker: Start Dev Environment** ## Parameters -This skill accepts no parameters. Services are configured in `docker-compose.dev.yml`. +This skill accepts no parameters. Services are configured in `.docker/compose/docker-compose.dev.yml`. ## Environment Variables This skill uses environment variables defined in: - `.env` (if present) -- `docker-compose.dev.yml` environment section +- `.docker/compose/docker-compose.dev.yml` environment section - Shell environment ## Outputs @@ -99,7 +99,7 @@ This skill uses environment variables defined in: ## What Gets Started -Services defined in `docker-compose.dev.yml`: +Services defined in `.docker/compose/docker-compose.dev.yml`: 1. **charon-app**: Main application container 2. **charon-db**: SQLite or PostgreSQL database 3. **crowdsec**: Security bouncer @@ -123,7 +123,7 @@ Docker Compose respects `depends_on` directives: .github/skills/docker-start-dev-scripts/run.sh # Verify services are running -docker compose -f docker-compose.dev.yml ps +docker compose -f .docker/compose/docker-compose.dev.yml ps ``` ### Example 2: Start and View Logs @@ -133,7 +133,7 @@ docker compose -f docker-compose.dev.yml ps .github/skills/docker-start-dev-scripts/run.sh # Follow logs from all services -docker compose -f docker-compose.dev.yml logs -f +docker compose -f .docker/compose/docker-compose.dev.yml logs -f ``` ### Example 3: Start and Test Application @@ -155,18 +155,18 @@ After starting, verify services are healthy: ```bash # Check service status -docker compose -f docker-compose.dev.yml ps +docker compose -f .docker/compose/docker-compose.dev.yml ps # Check specific service logs -docker compose -f docker-compose.dev.yml logs app +docker compose -f .docker/compose/docker-compose.dev.yml logs app # Execute command in running container -docker compose -f docker-compose.dev.yml exec app /bin/sh +docker compose -f .docker/compose/docker-compose.dev.yml exec app /bin/sh ``` ## Port Mappings -Default development ports (check `docker-compose.dev.yml`): +Default development ports (check `.docker/compose/docker-compose.dev.yml`): - **8080**: Application HTTP - **8443**: Application HTTPS (if configured) - **9000**: Admin panel (if configured) @@ -213,7 +213,7 @@ After starting, verify: 1. **All Services Running**: ```bash - docker compose -f docker-compose.dev.yml ps + docker compose -f .docker/compose/docker-compose.dev.yml ps ``` 2. **Application Accessible**: @@ -223,7 +223,7 @@ After starting, verify: 3. **No Error Logs**: ```bash - docker compose -f docker-compose.dev.yml logs --tail=50 + docker compose -f .docker/compose/docker-compose.dev.yml logs --tail=50 ``` ## Related Skills @@ -246,9 +246,9 @@ After starting, verify: ### Services Won't Start 1. Check Docker daemon: `docker info` -2. Validate compose file: `docker compose -f docker-compose.dev.yml config` +2. Validate compose file: `docker compose -f .docker/compose/docker-compose.dev.yml config` 3. Check available resources: `docker stats` -4. Review logs: `docker compose -f docker-compose.dev.yml logs` +4. Review logs: `docker compose -f .docker/compose/docker-compose.dev.yml logs` ### Slow Startup @@ -266,4 +266,4 @@ After starting, verify: **Last Updated**: 2025-12-20 **Maintained by**: Charon Project -**Compose File**: `docker-compose.dev.yml` +**Compose File**: `.docker/compose/docker-compose.dev.yml` diff --git a/.github/skills/docker-stop-dev-scripts/run.sh b/.github/skills/docker-stop-dev-scripts/run.sh index d7fd029f..beb9ac19 100755 --- a/.github/skills/docker-stop-dev-scripts/run.sh +++ b/.github/skills/docker-stop-dev-scripts/run.sh @@ -18,4 +18,4 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)" cd "$REPO_ROOT" # Stop development environment with Docker Compose -exec docker compose -f docker-compose.dev.yml down +exec docker compose -f .docker/compose/docker-compose.dev.yml down diff --git a/.github/skills/docker-stop-dev.SKILL.md b/.github/skills/docker-stop-dev.SKILL.md index 39fd754b..ca5e3314 100644 --- a/.github/skills/docker-stop-dev.SKILL.md +++ b/.github/skills/docker-stop-dev.SKILL.md @@ -49,7 +49,7 @@ Stops and removes all containers defined in the Charon development Docker Compos - Docker Engine installed and running - Docker Compose V2 installed - Development environment previously started -- `docker-compose.dev.yml` file in repository root +- `.docker/compose/docker-compose.dev.yml` file in repository ## Usage @@ -96,7 +96,7 @@ This skill requires no environment variables. ## What Gets Stopped -Services defined in `docker-compose.dev.yml`: +Services defined in `.docker/compose/docker-compose.dev.yml`: 1. **Application Containers**: Charon main app 2. **Database Containers**: SQLite/PostgreSQL services 3. **Security Services**: CrowdSec bouncer @@ -110,7 +110,7 @@ The `down` command preserves: - **Images**: Docker images remain cached - **Configs**: Configuration files unchanged -To remove volumes, use `docker compose -f docker-compose.dev.yml down -v` +To remove volumes, use `docker compose -f .docker/compose/docker-compose.dev.yml down -v` ## Shutdown Order @@ -129,14 +129,14 @@ Docker Compose stops services in reverse dependency order: .github/skills/docker-stop-dev-scripts/run.sh # Verify services are stopped -docker compose -f docker-compose.dev.yml ps +docker compose -f .docker/compose/docker-compose.dev.yml ps ``` ### Example 2: Stop and Remove Volumes ```bash # Stop services and remove data volumes -docker compose -f docker-compose.dev.yml down -v +docker compose -f .docker/compose/docker-compose.dev.yml down -v ``` ### Example 3: Stop and Verify Cleanup @@ -269,4 +269,4 @@ docker rmi $(docker images -q "*charon*") **Last Updated**: 2025-12-20 **Maintained by**: Charon Project -**Compose File**: `docker-compose.dev.yml` +**Compose File**: `.docker/compose/docker-compose.dev.yml` diff --git a/.gitignore b/.gitignore index 063c2c57..96576515 100644 --- a/.gitignore +++ b/.gitignore @@ -212,5 +212,24 @@ import/ test-results/charon.hatfieldhosted.com.har test-results/local.har .cache -trivy-scan-output.txt -trivy-image-scan.txt + +# ----------------------------------------------------------------------------- +# Test artifacts at root +# ----------------------------------------------------------------------------- +/block*.txt +/final_block_test.txt + +# ----------------------------------------------------------------------------- +# Debug/temp config files at root +# ----------------------------------------------------------------------------- +/caddy_*.json + +# ----------------------------------------------------------------------------- +# Trivy scan outputs at root +# ----------------------------------------------------------------------------- +/trivy-*.txt + +# ----------------------------------------------------------------------------- +# Docker Overrides (new location) +# ----------------------------------------------------------------------------- +.docker/compose/docker-compose.override.yml diff --git a/.vscode/tasks.json b/.vscode/tasks.json index e406942d..229618bd 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -173,21 +173,21 @@ { "label": "Docker: Start Local Environment", "type": "shell", - "command": "docker compose -f docker-compose.local.yml up -d", + "command": "docker compose -f .docker/compose/docker-compose.local.yml up -d", "group": "none", "problemMatcher": [] }, { "label": "Docker: Stop Local Environment", "type": "shell", - "command": "docker compose -f docker-compose.local.yml down", + "command": "docker compose -f .docker/compose/docker-compose.local.yml down", "group": "none", "problemMatcher": [] }, { "label": "Docker: View Logs", "type": "shell", - "command": "docker compose logs -f", + "command": "docker compose -f .docker/compose/docker-compose.yml logs -f", "group": "none", "problemMatcher": [], "isBackground": true diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d65ad23..1e1e2ad1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- **Repository Structure Reorganization**: Cleaned up root directory for better navigation + - Moved docker-compose files to `.docker/compose/` + - Moved `docker-entrypoint.sh` to `.docker/` + - Moved 16 implementation docs to `docs/implementation/` + - Deleted test artifacts (`block_test.txt`, `caddy_*.json`, etc.) + - Added `.github/instructions/structure.instructions.md` for ongoing structure enforcement + ### Added - **Bulk Apply Security Header Profiles**: Apply or remove security header profiles from multiple proxy hosts simultaneously via the Bulk Apply modal diff --git a/Dockerfile b/Dockerfile index 7d6bfa93..2bffcc14 100644 --- a/Dockerfile +++ b/Dockerfile @@ -308,7 +308,7 @@ COPY --from=backend-builder /go/bin/dlv /usr/local/bin/dlv COPY --from=frontend-builder /app/frontend/dist /app/frontend/dist # Copy startup script -COPY docker-entrypoint.sh /docker-entrypoint.sh +COPY .docker/docker-entrypoint.sh /docker-entrypoint.sh RUN chmod +x /docker-entrypoint.sh # Copy utility scripts (used for DB recovery and maintenance) diff --git a/Makefile b/Makefile index 7db14981..633f4564 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,7 @@ clean: # Build Docker image docker-build: - docker-compose build + docker compose -f .docker/compose/docker-compose.yml build # Build Docker image with version docker-build-versioned: @@ -99,19 +99,19 @@ docker-build-versioned: # Run Docker containers (production) docker-run: - docker-compose up -d + docker compose -f .docker/compose/docker-compose.yml up -d # Run Docker containers (development) docker-dev: - docker-compose -f docker-compose.yml -f docker-compose.dev.yml up + docker compose -f .docker/compose/docker-compose.yml -f .docker/compose/docker-compose.dev.yml up # Stop Docker containers docker-stop: - docker-compose down + docker compose -f .docker/compose/docker-compose.yml down # View Docker logs docker-logs: - docker-compose logs -f + docker compose -f .docker/compose/docker-compose.yml logs -f # Development mode (requires tmux) dev: diff --git a/block_test.txt b/block_test.txt deleted file mode 100644 index 0982cdcd..00000000 --- a/block_test.txt +++ /dev/null @@ -1,103 +0,0 @@ -* Host localhost:80 was resolved. -* IPv6: ::1 -* IPv4: 127.0.0.1 - % Total % Received % Xferd Average Speed Time Time Time Current - Dload Upload Total Spent Left Speed - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying [::1]:80... -* Connected to localhost (::1) port 80 -> GET / HTTP/1.1 -> Host: localhost -> User-Agent: curl/8.5.0 -> Accept: */* -> X-Forwarded-For: 10.255.255.254 -> -< HTTP/1.1 200 OK -< Accept-Ranges: bytes -< Alt-Svc: h3=":443"; ma=2592000 -< Content-Length: 2367 -< Content-Type: text/html; charset=utf-8 -< Etag: "deyx3i1v4dks1tr" -< Last-Modified: Mon, 15 Dec 2025 16:06:17 GMT -< Server: Caddy -< Vary: Accept-Encoding -< Date: Mon, 15 Dec 2025 17:40:48 GMT -< -{ [2367 bytes data] - 100 2367 100 2367 0 0 828k 0 --:--:-- --:--:-- --:--:-- 1155k -* Connection #0 to host localhost left intact - - - - - - Site Not Configured | Charon - - - -
- -

Site Not Configured

-

- The domain you are trying to access is pointing to this server, but no proxy host has been configured for it yet. -

-

- If you are the administrator, please log in to the Charon dashboard to configure this host. -

- Go to Dashboard -
- - - - diff --git a/blocking_test.txt b/blocking_test.txt deleted file mode 100644 index ac344be8..00000000 --- a/blocking_test.txt +++ /dev/null @@ -1,102 +0,0 @@ -* Host localhost:80 was resolved. -* IPv6: ::1 -* IPv4: 127.0.0.1 - % Total % Received % Xferd Average Speed Time Time Time Current - Dload Upload Total Spent Left Speed - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying [::1]:80... -* Connected to localhost (::1) port 80 -> GET / HTTP/1.1 -> Host: localhost -> User-Agent: curl/8.5.0 -> Accept: */* -> X-Forwarded-For: 10.50.50.50 -> -< HTTP/1.1 200 OK -< Accept-Ranges: bytes -< Content-Length: 2367 -< Content-Type: text/html; charset=utf-8 -< Etag: "deyz8cxzfqbt1tr" -< Last-Modified: Mon, 15 Dec 2025 17:46:40 GMT -< Server: Caddy -< Vary: Accept-Encoding -< Date: Mon, 15 Dec 2025 19:50:03 GMT -< -{ [2367 bytes data] - 100 2367 100 2367 0 0 320k 0 --:--:-- --:--:-- --:--:-- 330k -* Connection #0 to host localhost left intact - - - - - - Site Not Configured | Charon - - - -
- -

Site Not Configured

-

- The domain you are trying to access is pointing to this server, but no proxy host has been configured for it yet. -

-

- If you are the administrator, please log in to the Charon dashboard to configure this host. -

- Go to Dashboard -
- - - - diff --git a/caddy_config_qa.json b/caddy_config_qa.json deleted file mode 100644 index 80c24a1c..00000000 --- a/caddy_config_qa.json +++ /dev/null @@ -1 +0,0 @@ -{"admin":{"listen":"0.0.0.0:2019"},"apps":{"http":{"servers":{"charon_server":{"automatic_https":{},"listen":[":80",":443"],"logs":{"default_logger_name":"access_log"},"routes":[{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"handler":"headers","request":{"set":{"X-Forwarded-Host":["{http.request.host}"],"X-Plex-Client-Identifier":["{http.request.header.X-Plex-Client-Identifier}"],"X-Real-IP":["{http.request.remote.host}"]}}},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"],"X-Forwarded-Host":["{http.request.host}"],"X-Plex-Client-Identifier":["{http.request.header.X-Plex-Client-Identifier}"],"X-Plex-Device":["{http.request.header.X-Plex-Device}"],"X-Plex-Device-Name":["{http.request.header.X-Plex-Device-Name}"],"X-Plex-Platform":["{http.request.header.X-Plex-Platform}"],"X-Plex-Platform-Version":["{http.request.header.X-Plex-Platform-Version}"],"X-Plex-Product":["{http.request.header.X-Plex-Product}"],"X-Plex-Token":["{http.request.header.X-Plex-Token}"],"X-Plex-Version":["{http.request.header.X-Plex-Version}"],"X-Real-IP":["{http.request.remote.host}"]}}},"upstreams":[{"dial":"100.99.23.57:32400"}]}],"match":[{"host":["plex.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.98.12.109:5055"}]}],"match":[{"host":["seerr.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.99.23.57:8989"}]}],"match":[{"host":["sonarr.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.99.23.57:7878"}]}],"match":[{"host":["radarr.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.99.23.57:6789"}]}],"match":[{"host":["nzbget.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.98.12.109:9925"}]}],"match":[{"host":["mealie.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.99.23.57:6767"}]}],"match":[{"host":["bazarr.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.99.23.57:4848"}]}],"match":[{"host":["tubesync.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.98.12.109:8181"}]}],"match":[{"host":["tautulli.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.98.12.109:9696"}]}],"match":[{"host":["prowlarr.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.98.12.109:3000"}]}],"match":[{"host":["homepage.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.98.12.109:6868"}]}],"match":[{"host":["profilarr.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.99.23.57:19200"}]}],"match":[{"host":["fileflows.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"headers","response":{"set":{"Strict-Transport-Security":["max-age=31536000; includeSubDomains"]}}},{"handler":"vars"},{"flush_interval":-1,"handler":"reverse_proxy","headers":{"request":{"set":{"Connection":["{http.request.header.Connection}"],"Upgrade":["{http.request.header.Upgrade}"]}}},"upstreams":[{"dial":"100.99.23.57:9999"}]}],"match":[{"host":["dockwatch.hatfieldhosted.com"]}],"terminal":true},{"handle":[{"handler":"rewrite","uri":"/unknown.html"},{"handler":"file_server","root":"/app/frontend/dist"}],"terminal":true}]}}},"tls":{"automation":{"policies":[{"issuers":[{"email":"jhatfield82@proton.me","module":"acme"},{"module":"zerossl"}]}]}}},"logging":{"logs":{"access":{"encoder":{"format":"json"},"include":["http.log.access.access_log"],"level":"INFO","writer":{"filename":"/var/log/caddy/access.log","output":"file","roll":true,"roll_keep":5,"roll_keep_days":7,"roll_size_mb":10}}}},"storage":{"module":"file_system","root":"/app/data/caddy/data"}} diff --git a/caddy_crowdsec_config.json b/caddy_crowdsec_config.json deleted file mode 100644 index 19765bd5..00000000 --- a/caddy_crowdsec_config.json +++ /dev/null @@ -1 +0,0 @@ -null diff --git a/AGENT_SKILLS_MIGRATION_SUMMARY.md b/docs/implementation/AGENT_SKILLS_MIGRATION_SUMMARY.md similarity index 100% rename from AGENT_SKILLS_MIGRATION_SUMMARY.md rename to docs/implementation/AGENT_SKILLS_MIGRATION_SUMMARY.md diff --git a/BULK_ACL_FEATURE.md b/docs/implementation/BULK_ACL_FEATURE.md similarity index 100% rename from BULK_ACL_FEATURE.md rename to docs/implementation/BULK_ACL_FEATURE.md diff --git a/I18N_IMPLEMENTATION_SUMMARY.md b/docs/implementation/I18N_IMPLEMENTATION_SUMMARY.md similarity index 100% rename from I18N_IMPLEMENTATION_SUMMARY.md rename to docs/implementation/I18N_IMPLEMENTATION_SUMMARY.md diff --git a/IMPLEMENTATION_SUMMARY.md b/docs/implementation/IMPLEMENTATION_SUMMARY.md similarity index 100% rename from IMPLEMENTATION_SUMMARY.md rename to docs/implementation/IMPLEMENTATION_SUMMARY.md diff --git a/INVESTIGATION_SUMMARY.md b/docs/implementation/INVESTIGATION_SUMMARY.md similarity index 100% rename from INVESTIGATION_SUMMARY.md rename to docs/implementation/INVESTIGATION_SUMMARY.md diff --git a/PHASE_0_COMPLETE.md b/docs/implementation/PHASE_0_COMPLETE.md similarity index 100% rename from PHASE_0_COMPLETE.md rename to docs/implementation/PHASE_0_COMPLETE.md diff --git a/PHASE_3_COMPLETE.md b/docs/implementation/PHASE_3_COMPLETE.md similarity index 100% rename from PHASE_3_COMPLETE.md rename to docs/implementation/PHASE_3_COMPLETE.md diff --git a/PHASE_4_COMPLETE.md b/docs/implementation/PHASE_4_COMPLETE.md similarity index 100% rename from PHASE_4_COMPLETE.md rename to docs/implementation/PHASE_4_COMPLETE.md diff --git a/PHASE_5_COMPLETE.md b/docs/implementation/PHASE_5_COMPLETE.md similarity index 100% rename from PHASE_5_COMPLETE.md rename to docs/implementation/PHASE_5_COMPLETE.md diff --git a/QA_AUDIT_REPORT_LOADING_OVERLAYS.md b/docs/implementation/QA_AUDIT_REPORT_LOADING_OVERLAYS.md similarity index 100% rename from QA_AUDIT_REPORT_LOADING_OVERLAYS.md rename to docs/implementation/QA_AUDIT_REPORT_LOADING_OVERLAYS.md diff --git a/QA_MIGRATION_COMPLETE.md b/docs/implementation/QA_MIGRATION_COMPLETE.md similarity index 100% rename from QA_MIGRATION_COMPLETE.md rename to docs/implementation/QA_MIGRATION_COMPLETE.md diff --git a/QA_PHASE5_VERIFICATION_REPORT.md b/docs/implementation/QA_PHASE5_VERIFICATION_REPORT.md similarity index 100% rename from QA_PHASE5_VERIFICATION_REPORT.md rename to docs/implementation/QA_PHASE5_VERIFICATION_REPORT.md diff --git a/docs/implementation/README.md b/docs/implementation/README.md new file mode 100644 index 00000000..0029323d --- /dev/null +++ b/docs/implementation/README.md @@ -0,0 +1,39 @@ +# Implementation Documentation Archive + +This directory contains archived implementation documentation and historical records +of feature development in Charon. + +## Purpose + +These documents serve as historical references for: + +- Feature implementation details and decisions +- Migration summaries and upgrade paths +- Investigation reports and debugging sessions +- Phase completion records + +## Document Index + +Documents will be organized here after migration from the project root: + +| Document | Description | +|----------|-------------| +| `AGENT_SKILLS_MIGRATION_SUMMARY.md` | Agent skills system migration details | +| `BULK_ACL_FEATURE.md` | Bulk ACL feature implementation | +| `I18N_IMPLEMENTATION_SUMMARY.md` | Internationalization implementation | +| `IMPLEMENTATION_SUMMARY.md` | General implementation summary | +| `INVESTIGATION_SUMMARY.md` | Investigation and debugging records | +| `ISSUE_16_ACL_IMPLEMENTATION.md` | Issue #16 ACL implementation details | +| `PHASE_*_COMPLETE.md` | Phase completion documentation | +| `QA_*.md` | QA audit and verification reports | +| `SECURITY_*.md` | Security implementation records | +| `WEBSOCKET_FIX_SUMMARY.md` | WebSocket fix implementation | + +## Note + +These are **historical implementation records**. For current documentation, refer to: + +- `/docs/` - Main documentation +- `/README.md` - Project overview +- `/CONTRIBUTING.md` - Contribution guidelines +- `/CHANGELOG.md` - Version history diff --git a/SECURITY_CONFIG_PRIORITY.md b/docs/implementation/SECURITY_CONFIG_PRIORITY.md similarity index 100% rename from SECURITY_CONFIG_PRIORITY.md rename to docs/implementation/SECURITY_CONFIG_PRIORITY.md diff --git a/SECURITY_HEADERS_IMPLEMENTATION_SUMMARY.md b/docs/implementation/SECURITY_HEADERS_IMPLEMENTATION_SUMMARY.md similarity index 100% rename from SECURITY_HEADERS_IMPLEMENTATION_SUMMARY.md rename to docs/implementation/SECURITY_HEADERS_IMPLEMENTATION_SUMMARY.md diff --git a/SECURITY_IMPLEMENTATION_PLAN.md b/docs/implementation/SECURITY_IMPLEMENTATION_PLAN.md similarity index 100% rename from SECURITY_IMPLEMENTATION_PLAN.md rename to docs/implementation/SECURITY_IMPLEMENTATION_PLAN.md diff --git a/WEBSOCKET_FIX_SUMMARY.md b/docs/implementation/WEBSOCKET_FIX_SUMMARY.md similarity index 100% rename from WEBSOCKET_FIX_SUMMARY.md rename to docs/implementation/WEBSOCKET_FIX_SUMMARY.md diff --git a/docs/plans/structure.md b/docs/plans/structure.md index 4665eb39..74c50d32 100644 --- a/docs/plans/structure.md +++ b/docs/plans/structure.md @@ -1,6 +1,6 @@ # Repository Structure Reorganization Plan -**Date**: December 15, 2025 +**Date**: December 21, 2025 (Revised) **Status**: Proposed **Risk Level**: Medium (requires CI/CD updates, Docker path changes) @@ -8,7 +8,7 @@ ## Executive Summary -The repository root level currently contains **60+ items**, making it difficult to navigate and maintain. This plan proposes moving files into logical directories to achieve a cleaner, more organized structure with only **~15 essential items** at the root level. +The repository root level currently contains **81 items**, making it difficult to navigate and maintain. This plan proposes moving files into logical directories to achieve a cleaner, more organized structure with only **~15 essential items** at the root level. **Key Benefits**: @@ -28,7 +28,7 @@ The repository root level currently contains **60+ items**, making it difficult |----------|-------|----------|--------| | **Docker Compose Files** | 5 | `docker-compose.yml`, `docker-compose.dev.yml`, etc. | 🔴 Scattered | | **CodeQL SARIF Files** | 6 | `codeql-go.sarif`, `codeql-results-*.sarif` | 🔴 Build artifacts at root | -| **Implementation Docs** | 9 | `BULK_ACL_FEATURE.md`, `IMPLEMENTATION_SUMMARY.md`, etc. | 🔴 Should be in docs/ | +| **Implementation Docs** | 16 | `BULK_ACL_FEATURE.md`, `IMPLEMENTATION_SUMMARY.md`, etc. | 🔴 Should be in docs/ | | **Config Files** | 8 | `eslint.config.js`, `.pre-commit-config.yaml`, `Makefile`, etc. | 🟡 Mixed - some stay, some move | | **Docker Files** | 3 | `Dockerfile`, `docker-entrypoint.sh`, `DOCKER.md` | 🟡 Could group | | **Core Docs** | 4 | `README.md`, `CONTRIBUTING.md`, `LICENSE`, `VERSION.md` | 🟢 Stay at root | @@ -43,7 +43,7 @@ The repository root level currently contains **60+ items**, making it difficult 1. **Docker Compose Sprawl**: 5 files at root when they should be grouped 2. **SARIF Pollution**: 6 CodeQL SARIF files are build artifacts (should be .gitignored) -3. **Documentation Chaos**: 9 implementation/feature docs scattered at root instead of `docs/` +3. **Documentation Chaos**: 16 implementation/feature docs scattered at root instead of `docs/` 4. **Mixed Purposes**: Docker files, configs, docs, code all at same level --- @@ -74,9 +74,10 @@ The repository root level currently contains **60+ items**, making it difficult ├── .markdownlint.json # Markdown lint config ├── .markdownlintrc # Markdown lint config ├── .pre-commit-config.yaml # Pre-commit hooks -├── .sourcery.yml # Sourcery config +├── CHANGELOG.md # Project changelog ├── Chiron.code-workspace # VS Code workspace ├── CONTRIBUTING.md # Contribution guidelines +├── CONTRIBUTING_TRANSLATIONS.md # Translation guidelines ├── LICENSE # License file ├── Makefile # Build automation ├── README.md # Project readme @@ -98,6 +99,7 @@ The repository root level currently contains **60+ items**, making it difficult │ ├── docker-compose.dev.yml # Dev override (moved from root) │ ├── docker-compose.local.yml # Local override (moved from root) │ ├── docker-compose.remote.yml # Remote override (moved from root) +│ ├── docker-compose.override.yml # Remote override (moved from root) │ └── README.md # Compose file documentation ├── docker-entrypoint.sh # Entrypoint script (moved from root) └── README.md # Docker documentation (DOCKER.md renamed) @@ -145,6 +147,8 @@ docs/ **New entries** to prevent SARIF files at root: +> **Note**: The `*.sarif` pattern may already exist in `.gitignore`. Verify before adding to avoid duplication. The explicit patterns below ensure comprehensive coverage. + ```gitignore # Add to "CodeQL & Security Scanning" section: # ----------------------------------------------------------------------------- @@ -163,8 +167,42 @@ docs/ /codeql-results-go-backend.sarif /codeql-results-go-new.sarif /codeql-results-js.sarif + +# Test artifacts at root +/block*.txt +/final_block_test.txt + +# Debug/temp config files at root +/caddy_*.json +!package*.json + +# Trivy scan outputs at root +/trivy-*.txt ``` +#### Local Override Migration + +**Important**: With the move to `.docker/compose/`, the standard `docker-compose.override.yml` behavior changes: + +- **Previous behavior**: `docker-compose.override.yml` at repository root was auto-applied by Docker Compose +- **New behavior**: Override files at `.docker/compose/docker-compose.override.yml` must be explicitly referenced with `-f` flag + +**Updated .gitignore entry**: + +```gitignore +# Local docker-compose override (new location) +.docker/compose/docker-compose.override.yml +``` + +**Usage with new location**: + +```bash +# Development with override +docker compose -f .docker/compose/docker-compose.yml -f .docker/compose/docker-compose.override.yml up -d +``` + +**Note**: Users with existing `docker-compose.override.yml` at root should move it to `.docker/compose/` and update their workflow scripts accordingly. + --- ## File Migration Table @@ -200,6 +238,15 @@ docs/ | `/SECURITY_CONFIG_PRIORITY.md` | `/docs/implementation/SECURITY_CONFIG_PRIORITY.md` | Move | | `/SECURITY_IMPLEMENTATION_PLAN.md` | `/docs/implementation/SECURITY_IMPLEMENTATION_PLAN.md` | Move | | `/WEBSOCKET_FIX_SUMMARY.md` | `/docs/implementation/WEBSOCKET_FIX_SUMMARY.md` | Move | +| `/AGENT_SKILLS_MIGRATION_SUMMARY.md` | `/docs/implementation/AGENT_SKILLS_MIGRATION_SUMMARY.md` | Move | +| `/I18N_IMPLEMENTATION_SUMMARY.md` | `/docs/implementation/I18N_IMPLEMENTATION_SUMMARY.md` | Move | +| `/INVESTIGATION_SUMMARY.md` | `/docs/implementation/INVESTIGATION_SUMMARY.md` | Move | +| `/PHASE_0_COMPLETE.md` | `/docs/implementation/PHASE_0_COMPLETE.md` | Move | +| `/PHASE_3_COMPLETE.md` | `/docs/implementation/PHASE_3_COMPLETE.md` | Move | +| `/PHASE_4_COMPLETE.md` | `/docs/implementation/PHASE_4_COMPLETE.md` | Move | +| `/PHASE_5_COMPLETE.md` | `/docs/implementation/PHASE_5_COMPLETE.md` | Move | +| `/QA_PHASE5_VERIFICATION_REPORT.md` | `/docs/implementation/QA_PHASE5_VERIFICATION_REPORT.md` | Move | +| `/SECURITY_HEADERS_IMPLEMENTATION_SUMMARY.md` | `/docs/implementation/SECURITY_HEADERS_IMPLEMENTATION_SUMMARY.md` | Move | ### CodeQL SARIF Files → Delete (Add to .gitignore) @@ -214,6 +261,20 @@ docs/ **Note**: These are generated by CodeQL and should never be committed. +### Test/Debug Files → Delete + Gitignore + +| Current Path | Action | Reason | +|-------------|--------|--------| +| `/block_test.txt` | Delete + gitignore | Test artifact | +| `/blocking_test.txt` | Delete + gitignore | Test artifact | +| `/final_block_test.txt` | Delete + gitignore | Test artifact | +| `/caddy_config_qa.json` | Delete + gitignore | Debug config | +| `/caddy_crowdsec_config.json` | Delete + gitignore | Debug config | +| `/trivy-image-scan.txt` | Delete + gitignore | Scan output | +| `/trivy-scan-output.txt` | Delete + gitignore | Scan output | + +**Note**: These are test/debug artifacts that should never be committed. + ### Files Staying at Root | File | Reason | @@ -222,17 +283,19 @@ docs/ | `Makefile` | Build automation - standard location | | `README.md` | Project entry point - standard location | | `CONTRIBUTING.md` | Contributor guidelines - standard location | +| `CONTRIBUTING_TRANSLATIONS.md` | Translation contribution guidelines - standard location | | `LICENSE` | License file - standard location | | `VERSION.md` | Version documentation - standard location | +| `CHANGELOG.md` | Project changelog - standard location | | `Chiron.code-workspace` | VS Code workspace - standard location | -| `go.work`, `go.work.sum` | Go workspace - required at root | +| `go.work` | Go workspace - required at root | +| `go.work.sum` | Go workspace checksums - required at root | | `package.json` | Root package (pre-commit, etc.) - required at root | | `eslint.config.js` | ESLint config - required at root | | `.codecov.yml` | Codecov config - required at root | | `.goreleaser.yaml` | GoReleaser config - required at root | | `.markdownlint.json` | Markdown lint config - required at root | | `.pre-commit-config.yaml` | Pre-commit config - required at root | -| `.sourcery.yml` | Sourcery config - required at root | | All `.git*` files | Git configuration - required at root | | All hidden directories | Standard locations | @@ -461,9 +524,30 @@ docs/implementation/ git mv SECURITY_CONFIG_PRIORITY.md docs/implementation/ git mv SECURITY_IMPLEMENTATION_PLAN.md docs/implementation/ git mv WEBSOCKET_FIX_SUMMARY.md docs/implementation/ + git mv AGENT_SKILLS_MIGRATION_SUMMARY.md docs/implementation/ + git mv I18N_IMPLEMENTATION_SUMMARY.md docs/implementation/ + git mv INVESTIGATION_SUMMARY.md docs/implementation/ + git mv PHASE_0_COMPLETE.md docs/implementation/ + git mv PHASE_3_COMPLETE.md docs/implementation/ + git mv PHASE_4_COMPLETE.md docs/implementation/ + git mv PHASE_5_COMPLETE.md docs/implementation/ + git mv QA_PHASE5_VERIFICATION_REPORT.md docs/implementation/ + git mv SECURITY_HEADERS_IMPLEMENTATION_SUMMARY.md docs/implementation/ ``` -4. **Delete SARIF files**: +4. **Delete test/debug files**: + + ```bash + git rm block_test.txt + git rm blocking_test.txt + git rm final_block_test.txt + git rm caddy_config_qa.json + git rm caddy_crowdsec_config.json + git rm trivy-image-scan.txt + git rm trivy-scan-output.txt + ``` + +5. **Delete SARIF files**: ```bash git rm codeql-go.sarif @@ -474,7 +558,7 @@ docs/implementation/ git rm codeql-results-js.sarif ``` -5. **Commit file moves**: +6. **Commit file moves**: ```bash git commit -m "chore: reorganize repository structure @@ -484,6 +568,7 @@ docs/implementation/ - Move DOCKER.md to .docker/README.md - Move implementation docs to docs/implementation/ - Delete committed SARIF files (should be gitignored) + - Delete test/debug artifacts (should be gitignored) " ``` @@ -611,6 +696,74 @@ docs/implementation/ - Update any external documentation - Monitor for issues in next few days +### Phase 6: Documentation & Enforcement + +1. **Create structure enforcement instructions**: + Create `.github/instructions/structure.instructions.md` to enforce the clean structure going forward: + + ```markdown + --- + applyTo: '*' + description: 'Repository structure guidelines to maintain organized file placement' + --- + + # Repository Structure Guidelines + + ## Root Level Rules + + The repository root should contain ONLY: + - Essential config files (`.gitignore`, `.pre-commit-config.yaml`, `Makefile`, etc.) + - Standard project files (`README.md`, `CONTRIBUTING.md`, `LICENSE`, `CHANGELOG.md`) + - Go workspace files (`go.work`, `go.work.sum`) + - VS Code workspace (`Chiron.code-workspace`) + - Primary `Dockerfile` (entrypoint and compose files live in `.docker/`) + + ## File Placement Rules + + ### Implementation/Feature Documentation + - **Location**: `docs/implementation/` + - **Pattern**: `*_SUMMARY.md`, `*_IMPLEMENTATION.md`, `*_COMPLETE.md`, `*_FEATURE.md` + - **Never** place implementation docs at root + + ### Docker Compose Files + - **Location**: `.docker/compose/` + - **Files**: `docker-compose.yml`, `docker-compose.*.yml` + - **Override**: Local overrides go in `.docker/compose/docker-compose.override.yml` + + ### Docker Support Files + - **Location**: `.docker/` + - **Files**: `docker-entrypoint.sh`, Docker documentation + + ### Test Artifacts + - **Never commit**: `*.sarif`, `*_test.txt`, `*.cover` files at root + - **Location**: Test outputs should go to `test-results/` or be gitignored + + ### Debug/Temp Config Files + - **Never commit**: Temporary JSON configs like `caddy_*.json` at root + - **Location**: Use `configs/` for persistent configs, gitignore temp files + + ## Before Creating New Files + + Ask yourself: + 1. Is this a standard project file? → Root is OK + 2. Is this implementation documentation? → `docs/implementation/` + 3. Is this Docker-related? → `.docker/` or `.docker/compose/` + 4. Is this a test artifact? → `test-results/` or gitignore + 5. Is this a script? → `scripts/` + 6. Is this runtime config? → `configs/` + + ## Enforcement + + Pre-commit hooks and CI will flag files placed incorrectly at root level. + ``` + +2. **Update .pre-commit-config.yaml** (optional future enhancement): + Consider adding a hook to detect new files at root that don't match allowed patterns. + +3. **Announce changes**: + - Update `CHANGELOG.md` with structure reorganization entry + - Notify contributors of new file placement guidelines + --- ## Risk Assessment @@ -665,6 +818,8 @@ If critical issues arise after merge: - [ ] Pre-commit checks pass - [ ] All VS Code tasks work - [ ] Documentation updated +- [ ] Structure instructions file created at `.github/instructions/structure.instructions.md` +- [ ] Test/debug files cleaned up and gitignored - [ ] PR reviewed by maintainers ✅ **After Merge**: @@ -673,7 +828,7 @@ If critical issues arise after merge: - [ ] Docker images build successfully - [ ] No broken links in documentation - [ ] No regressions reported -- [ ] Root level has ~15 items (down from 60+) +- [ ] Root level has ~15 items (down from 81) --- diff --git a/final_block_test.txt b/final_block_test.txt deleted file mode 100644 index 1f0db1bd..00000000 --- a/final_block_test.txt +++ /dev/null @@ -1,103 +0,0 @@ -* Host localhost:80 was resolved. -* IPv6: ::1 -* IPv4: 127.0.0.1 - % Total % Received % Xferd Average Speed Time Time Time Current - Dload Upload Total Spent Left Speed - 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying [::1]:80... -* Connected to localhost (::1) port 80 -> GET / HTTP/1.1 -> Host: localhost -> User-Agent: curl/8.5.0 -> Accept: */* -> X-Forwarded-For: 172.16.0.99 -> -< HTTP/1.1 200 OK -< Accept-Ranges: bytes -< Alt-Svc: h3=":443"; ma=2592000 -< Content-Length: 2367 -< Content-Type: text/html; charset=utf-8 -< Etag: "deyz8cxzfqbt1tr" -< Last-Modified: Mon, 15 Dec 2025 17:46:40 GMT -< Server: Caddy -< Vary: Accept-Encoding -< Date: Mon, 15 Dec 2025 18:02:32 GMT -< -{ [2367 bytes data] - 100 2367 100 2367 0 0 1136k 0 --:--:-- --:--:-- --:--:-- 2311k -* Connection #0 to host localhost left intact - - - - - - Site Not Configured | Charon - - - -
- -

Site Not Configured

-

- The domain you are trying to access is pointing to this server, but no proxy host has been configured for it yet. -

-

- If you are the administrator, please log in to the Charon dashboard to configure this host. -

- Go to Dashboard -
- - - - diff --git a/frontend/package.json b/frontend/package.json index 3f2c365a..18a0b811 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,9 +22,9 @@ "test:coverage": "vitest --coverage --coverage.provider=istanbul --coverage.reporter=json-summary --coverage.reporter=lcov --coverage.reporter=text", "e2e:install": "npx playwright install --with-deps", "e2e:test": "playwright test", - "e2e:up:block": "docker compose -f ../docker-compose.local.yml down && CHARON_SECURITY_WAF_MODE=block docker compose -f ../docker-compose.local.yml up -d", - "e2e:up:monitor": "docker compose -f ../docker-compose.local.yml down && CHARON_SECURITY_WAF_MODE=monitor docker compose -f ../docker-compose.local.yml up -d", - "e2e:down": "docker compose -f ../docker-compose.local.yml down" + "e2e:up:block": "docker compose -f ../.docker/compose/docker-compose.local.yml down && CHARON_SECURITY_WAF_MODE=block docker compose -f ../.docker/compose/docker-compose.local.yml up -d", + "e2e:up:monitor": "docker compose -f ../.docker/compose/docker-compose.local.yml down && CHARON_SECURITY_WAF_MODE=monitor docker compose -f ../.docker/compose/docker-compose.local.yml up -d", + "e2e:down": "docker compose -f ../.docker/compose/docker-compose.local.yml down" }, "dependencies": { "@radix-ui/react-checkbox": "^1.3.3", diff --git a/scripts/coraza_integration.sh b/scripts/coraza_integration.sh index b97e3e77..5c966532 100644 --- a/scripts/coraza_integration.sh +++ b/scripts/coraza_integration.sh @@ -13,7 +13,7 @@ sleep 1 # Brief: Integration test for Coraza WAF using Docker Compose and built image # Steps: # 1. Build the local image: docker build -t charon:local . -# 2. Start docker-compose.local.yml: docker compose -f docker-compose.local.yml up -d +# 2. Start docker-compose.local.yml: docker compose -f .docker/compose/docker-compose.local.yml up -d # 3. Wait for API to be ready and then configure a ruleset that blocks a simple signature # 4. Request a path containing the signature and verify 403 (or WAF block response) @@ -129,7 +129,7 @@ fi # NOTE: We intentionally do NOT mount $(pwd)/backend or $(pwd)/frontend/dist here. # In CI, frontend/dist does not exist (it's built inside the Docker image). # Mounting a non-existent directory would override the built frontend with an empty dir. -# For local development with hot-reload, use docker-compose.local.yml instead. +# For local development with hot-reload, use .docker/compose/docker-compose.local.yml instead. docker run -d --name charon-debug --cap-add=SYS_PTRACE --security-opt seccomp=unconfined --network containers_default -p 80:80 -p 443:443 -p 8080:8080 -p 2019:2019 -p 2345:2345 \ -e CHARON_ENV=development -e CHARON_DEBUG=1 -e CHARON_HTTP_PORT=8080 -e CHARON_DB_PATH=/app/data/charon.db -e CHARON_FRONTEND_DIR=/app/frontend/dist \ -e CHARON_CADDY_ADMIN_API=http://localhost:2019 -e CHARON_CADDY_CONFIG_DIR=/app/data/caddy -e CHARON_CADDY_BINARY=caddy -e CHARON_IMPORT_CADDYFILE=/import/Caddyfile \ diff --git a/scripts/crowdsec_startup_test.sh b/scripts/crowdsec_startup_test.sh index d46ca1ea..28f29d7e 100755 --- a/scripts/crowdsec_startup_test.sh +++ b/scripts/crowdsec_startup_test.sh @@ -318,7 +318,7 @@ if [ "$CRITICAL_FAILURE" = "true" ]; then echo "To fix:" echo " 1. Ensure configs/crowdsec/acquis.yaml exists with 'source:' definition" echo " 2. Ensure Dockerfile copies acquis.yaml to /etc/crowdsec.dist/" - echo " 3. Ensure docker-entrypoint.sh copies configs to /etc/crowdsec/" + echo " 3. Ensure .docker/docker-entrypoint.sh copies configs to /etc/crowdsec/" echo "" exit 1 fi