Xuell Infra is a local deployment console for shipping Git repositories into Docker containers, routing them through Caddy, and monitoring live logs from a React frontend.
frontend/: React + Vite UI for creating and managing deploymentsapi/: Express + TypeScript API that orchestrates clone/build/run/route operationsapi/deployments.db: SQLite database for deployment metadataapi/logs/: Per-deployment log files streamed over Server-Sent EventsCaddyfile: Base Caddy config (admin API enabled, readiness endpoint)
- Create deployments from a Git URL
- Live status pipeline:
pending -> building -> deploying -> running(orfailed/stopped) - Stop and delete deployment actions
- Environment variable injection for runtime containers
- Encrypted secret storage at rest (AES-256-GCM)
- Live log streaming from backend to frontend
Install these tools locally:
- Node.js 20+
- npm
- Docker
- Git
- Caddy v2
- Railpack CLI (used by the build pipeline)
Also create the Docker network used by deployed containers:
docker network create brimbleThe API supports these optional environment variables:
BRIMBLE_ENCRYPTION_KEY: Secret used to derive encryption key for env varsCADDY_ADMIN_URL: Caddy admin endpoint (default:http://localhost:2019)
Example:
export BRIMBLE_ENCRYPTION_KEY="replace-with-a-strong-secret"
export CADDY_ADMIN_URL="http://localhost:2019"From project root:
caddy run --config ./Caddyfilecd api
npm install
npx tsx src/index.tsAPI runs on http://localhost:3001.
In a new terminal:
cd frontend
npm install
npm run devFrontend runs on http://localhost:5173 and proxies /deployments to the API.
Frontend:
cd frontend
npm run buildBase path: /deployments
POST /: Create a deploymentGET /: List deploymentsGET /:id: Get one deploymentGET /:id/logs: Stream logs via SSEPOST /:id/stop: Stop a deploymentDELETE /:id: Delete a deployment and related artifacts
{
"git_url": "https://github.com/owner/repo",
"name": "my-app",
"env_vars": {
"NODE_ENV": "production",
"API_KEY": "secret-value"
}
}For each deployment:
- Clone repository to a temp directory
- Build image with Railpack
- Start container on Docker network
brimble - Register Caddy reverse-proxy route for
<id>.localhost - Persist state and stream logs
- Secrets are masked in API responses and frontend display.
- Deleting a deployment removes DB row, Docker image (if present), container (if present), Caddy route, and log file.
- Existing databases are migrated at startup to include
env_secretsif missing.