DockFlare/project_outline.txt
ChrispyBacon-dev 7a0e1b3e20 project outline
2025-04-14 11:14:26 +02:00

50 lines
No EOL
4.8 KiB
Text

Project Goal:
To create an automated system that dynamically manages Cloudflare Tunnel ingress rules based on Docker container labels on a host machine. Essentially, it acts as a self-hosted "Cloudflare Tunnel Ingress Controller" for Docker.
Core Problem Solved:
Eliminates the manual process of configuring public hostnames and DNS entries in Cloudflare Tunnels every time a new Docker service needs to be exposed or an existing one is updated/removed.
Key Features & Functionality:
Cloudflare Tunnel Entity Management:
On startup, checks via the Cloudflare API if a tunnel with a specified name (TUNNEL_NAME from .env) exists within the configured Cloudflare account (CF_ACCOUNT_ID).
If the tunnel doesn't exist, it creates it using the Cloudflare API (POST /accounts/{acc_id}/cfd_tunnel).
Retrieves and stores the Tunnel ID and the necessary runtime Tunnel Token directly from the API response.
cloudflared Agent Container Management:
Manages the lifecycle of the actual cloudflared agent process, running it as a separate Docker container (cloudflare/cloudflared:latest).
Uses the Tunnel Token (obtained via API) to authenticate the agent (docker run ... tunnel --token ...).
Automatically starts the agent container after successful initialization of the main application.
Provides Start/Stop buttons in the web UI to manually control the agent container via the Docker API.
Dynamic Ingress Rule Management (via Docker Labels):
Listens for Docker container start and stop events on the host using the Docker API.
Processes containers that have specific labels (default prefix cloudflare.tunnel.):
cloudflare.tunnel.enable="true": Marks the container for management.
cloudflare.tunnel.hostname="subdomain.yourdomain.com": The desired public hostname.
cloudflare.tunnel.service="http://target:port": The internal URL the tunnel should proxy to (e.g., http://localhost:8080, http://container_name:9000).
Maintains an internal state (managed_rules) representing the desired ingress configuration based on running, labeled containers.
Automatically updates the Cloudflare Tunnel's configuration (PUT /accounts/{acc_id}/cfd_tunnel/{tun_id}/configurations) by adding/removing ingress rules to match the managed_rules state. Relies on Cloudflare to automatically handle the corresponding CNAME DNS records.
Graceful Deletion:
When a managed container stops, its corresponding ingress rule is marked as pending_deletion in the internal state.
A deletion timestamp (delete_at) is calculated based on a configurable grace period (e.g., 8 hours).
A background task periodically checks for expired rules (delete_at <= now) and triggers an update to the Cloudflare configuration to remove them.
State Persistence:
The managed_rules state (including hostname, service, container ID, status, and deletion timestamp) is saved to a JSON file (state.json by default) to survive restarts of the management application.
Reconciliation on Startup:
When the application starts, it compares currently running labeled Docker containers, the loaded state from state.json, and the actual configuration fetched from Cloudflare to ensure consistency and trigger necessary updates.
Web UI (Flask):
Provides a status dashboard showing:
Tunnel initialization status, ID, and masked token.
cloudflared agent container status (running, stopped, etc.).
Start/Stop buttons for the agent container.
A table listing all currently managed ingress rules (hostname, service, status, associated container ID, scheduled deletion time).
A "Force Delete" button for each managed rule to bypass the grace period and remove the rule immediately.
Technical Implementation:
Language: Python 3
Core Libraries: requests (Cloudflare API), docker (Docker API/events), Flask (Web UI), python-dotenv (Configuration), threading (Background tasks).
Deployment: Runs as a Docker container, typically managed by docker-compose.yml. Requires mounting the Docker socket (/var/run/docker.sock) to interact with the Docker daemon.
Configuration: Primarily via an .env file (API Token, Account ID, Tunnel Name, optional grace period, labels, etc.) and Docker labels on target application containers.
Authentication: Uses a Cloudflare API Token with Account:Cloudflare Tunnel:Edit permissions (and potentially Zone:DNS:Edit if explicit DNS management were added).
Key Files:
app.py: Main Python application code (Flask routes, API logic, Docker event handling, state management).
Dockerfile: Builds the application container, installing Python, dependencies, and cloudflared (though cloudflared CLI is not used for setup anymore).
docker-compose.yml: Defines the service for running the application container and mounts the Docker socket.
requirements.txt: Lists Python dependencies.
.env: Stores sensitive configuration and parameters (API keys, IDs, tunnel name).
state.json: (Created at runtime) Persists the managed rules state.