Installation
Warden is distributed as a Docker image and a Helm chart. It runs as a single binary with no external dependencies.
Docker (Recommended)
Section titled “Docker (Recommended)”Pull and run the Warden image:
docker run -d \ -p 9090:9090 \ -v warden_data:/data \ ghcr.io/projecthelena/warden:latestWarden is now running at http://localhost:9090.
Docker Compose
Section titled “Docker Compose”With SQLite (Default)
Section titled “With SQLite (Default)”Create a docker-compose.yml:
services: warden: image: ghcr.io/projecthelena/warden:latest ports: - "9090:9090" volumes: - warden_data:/data
volumes: warden_data:docker compose up -dWith PostgreSQL
Section titled “With PostgreSQL”For larger deployments or an external database:
services: warden: image: ghcr.io/projecthelena/warden:latest ports: - "9090:9090" environment: - DB_URL=postgres://warden:warden@db:5432/warden?sslmode=disable depends_on: db: condition: service_healthy
db: image: postgres:17 environment: - POSTGRES_USER=warden - POSTGRES_PASSWORD=warden - POSTGRES_DB=warden volumes: - pg_data:/var/lib/postgresql/data healthcheck: test: ["CMD", "pg_isready", "-U", "warden"] interval: 5s retries: 5
volumes: pg_data:docker compose up -dKubernetes (Helm Chart)
Section titled “Kubernetes (Helm Chart)”Warden has an official Helm chart for Kubernetes deployments. The chart supports SQLite, internal PostgreSQL (auto-deployed StatefulSet), or external PostgreSQL.
Source: github.com/projecthelena/helm-charts
Add the Helm Repository
Section titled “Add the Helm Repository”helm repo add projecthelena https://charts.projecthelena.comhelm repo updateInstall with SQLite (Default)
Section titled “Install with SQLite (Default)”helm install warden projecthelena/warden \ --namespace warden \ --create-namespaceThis deploys Warden with SQLite and a 1Gi PersistentVolumeClaim for data persistence.
Install with PostgreSQL
Section titled “Install with PostgreSQL”helm install warden projecthelena/warden \ --namespace warden \ --create-namespace \ --set database.type=postgres \ --set database.postgres.enabled=true \ --set database.postgres.auth.password=your-secure-passwordThis deploys Warden alongside an internal PostgreSQL StatefulSet with 5Gi of persistent storage.
Install with an External PostgreSQL
Section titled “Install with an External PostgreSQL”If you already have a PostgreSQL instance:
helm install warden projecthelena/warden \ --namespace warden \ --create-namespace \ --set database.type=postgres \ --set database.external.enabled=true \ --set database.external.url="postgres://user:pass@db.example.com:5432/warden?sslmode=require"Chart Values Reference
Section titled “Chart Values Reference”| Value | Default | Description |
|---|---|---|
replicaCount | 1 | Number of replicas |
image.repository | ghcr.io/projecthelena/warden | Container image |
image.tag | latest | Image tag |
service.type | ClusterIP | Kubernetes service type |
service.port | 9090 | Service port |
config.cookieSecure | false | Set to true for HTTPS |
config.trustProxy | false | Set to true behind a reverse proxy |
database.type | sqlite | sqlite or postgres |
database.sqlite.persistence.size | 1Gi | SQLite PVC size |
database.postgres.enabled | false | Deploy internal PostgreSQL |
database.postgres.auth.password | Auto-generated | PostgreSQL password |
database.postgres.persistence.size | 5Gi | PostgreSQL PVC size |
database.external.enabled | false | Use external PostgreSQL |
database.external.url | — | External PostgreSQL connection string |
ingress.enabled | false | Enable Kubernetes Ingress |
ingressRoute.enabled | false | Enable Traefik IngressRoute |
resources.requests.cpu | 100m | CPU request |
resources.requests.memory | 128Mi | Memory request |
resources.limits.cpu | 500m | CPU limit |
resources.limits.memory | 256Mi | Memory limit |
Exposing Warden with Ingress
Section titled “Exposing Warden with Ingress”Standard Kubernetes Ingress:
ingress: enabled: true className: nginx annotations: cert-manager.io/cluster-issuer: letsencrypt hosts: - host: status.example.com paths: - path: / pathType: Prefix tls: - secretName: warden-tls hosts: - status.example.comTraefik IngressRoute:
ingressRoute: enabled: true entryPoints: - websecure routes: - match: Host(`status.example.com`) kind: Rule tls: certResolver: letsencryptExample: ArgoCD with Traefik and PostgreSQL
Section titled “Example: ArgoCD with Traefik and PostgreSQL”Here’s a complete ArgoCD Application manifest deploying Warden on Kubernetes with Traefik and an internal PostgreSQL database:
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: warden namespace: argocdspec: project: default source: repoURL: https://charts.projecthelena.com chart: warden targetRevision: 0.2.4 helm: values: | database: type: postgres postgres: enabled: true auth: username: warden password: "" # auto-generated — see ignoreDifferences below database: warden persistence: enabled: true size: 10Gi accessMode: ReadWriteOnce storageClass: your-storage-class ingressRoute: enabled: true entryPoints: - websecure routes: - match: Host(`status.example.com`) kind: Rule tls: certResolver: letsencrypt ignoreDifferences: - kind: Secret name: warden-postgresql jsonPointers: - /data destination: server: https://kubernetes.default.svc namespace: warden syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true - ServerSideApply=true - RespectIgnoreDifferences=trueBuild from Source
Section titled “Build from Source”Requirements: Go 1.25+ and Node.js 22+
git clone https://github.com/projecthelena/warden.gitcd wardenmake build./bin/wardenThis builds the React frontend, embeds it into the Go binary, and outputs a single executable at bin/warden.
Environment Variables
Section titled “Environment Variables”| Variable | Default | Description |
|---|---|---|
LISTEN_ADDR | :9090 | Address and port to listen on |
DB_TYPE | sqlite | sqlite or postgres; a PostgreSQL DB_URL selects PostgreSQL automatically |
DB_PATH | /data/warden.db | SQLite database file path |
DB_URL | — | PostgreSQL connection string (auto-switches from SQLite) |
COOKIE_SECURE | false | Set to true when running behind HTTPS |
TRUST_PROXY | false | Set to true when behind a reverse proxy for correct IP-based rate limiting |
See Application configuration for all deployment options, including HTTP diagnostics, rollup tuning and the optional metrics listener. MCP can be disabled with MCP_ENABLED=false; see MCP.
Database Options
Section titled “Database Options”| Feature | SQLite (Default) | PostgreSQL |
|---|---|---|
| Setup | Zero configuration | Requires running PostgreSQL |
| Best for | Single instance, low-to-medium traffic | High availability, large-scale |
| Backups | Copy the database file | pg_dump or existing pipeline |
| Performance | Great for most workloads | Better under heavy concurrent writes |
SQLite is the default and requires no setup. The database file is created automatically at the path specified by DB_PATH.
To use PostgreSQL, set the DB_URL environment variable. Warden auto-detects the database type from the connection string prefix. This selects the backend; it does not migrate existing SQLite data. See Database and PostgreSQL migration before moving an existing installation.
Database Migrations
Section titled “Database Migrations”Migrations run automatically on startup. Warden ships with embedded migration files for both SQLite and PostgreSQL — no manual migration steps required.
Verifying the Installation
Section titled “Verifying the Installation”After starting Warden, open http://localhost:9090 in your browser (or your Ingress hostname for Kubernetes). You should see the setup page where you’ll create your first admin account.
You can also check the health endpoint:
curl http://localhost:9090/healthz