Installation
No Go toolchain needed. Download a ready-to-run binary or the Docker image — building from source is only for contributors. All assets live on the Downloads page.
Option 1 — Download the CLI (recommended)
Pick your platform, download, and run. No install step.
# Linux (x86_64)
curl -L -o envious \
https://github.com/marcuwynu23/envious/releases/latest/download/envious-linux-amd64
chmod +x envious
./envious version
# macOS (Apple Silicon; use envious-darwin-amd64 on Intel)
curl -L -o envious \
https://github.com/marcuwynu23/envious/releases/latest/download/envious-darwin-arm64
chmod +x envious
./envious version
# Windows (PowerShell)
Invoke-WebRequest `
-Uri https://github.com/marcuwynu23/envious/releases/latest/download/envious-windows-amd64.exe `
-OutFile envious.exe
.\envious.exe version
Option 2 — Run the server with Docker
docker run -p 8080:8080 \
-e ENCRYPTION_KEY="pick-a-long-random-value" \
-v envious-data:/data \
-e DATABASE_PATH=/data/envious.db \
ghcr.io/marcuwynu23/envious-web:latest
# first start prints: Envious initial API key (store it securely): <KEY>
Option 3 — Build from source (contributors)
Requires Go 1.21+ for the CLI and Go 1.25+ for the server.
cd cli && go mod tidy && go build -o envious .
cd ../web && go mod tidy && go run ./cmd/server
Quick Start
Three steps, about a minute. First start the server (or open the dashboard at
http://localhost:8080/) and save the admin key it prints on first run.
./envious login --api-key=<KEY> --api-base=http://127.0.0.1:8080
./envious app create billing
./envious env create prod --app-id=2
./envious var set 10 DATABASE_URL "postgres://..."
./envious var list 10
./envious var export 10 > .env
Prefer a UI? Log in with the API key and follow Applications → Environments → Variables. The server version is always visible in the header badge and on the /about page.
CLI Reference
| Command | What it does |
|---|---|
login --api-key --api-base | Store credentials in ~/.envious/config |
app list | create <name> | delete <id> | Manage applications |
env list | create | delete | Manage environments (--app-id 0 = all for list, default for create) |
var list [env] [--show-values] | List variables (values hidden by default) |
var set [env] <key> <value> | Create or update (bumps version) |
var delete <var_id> | Delete by variable id |
var export [env] | Print .env format |
var import [env] <file> | Import a .env file |
version | Print stamped version info |
Environments resolve as --env-id → positional id → --env-name with --app-id/--app-name. Ambiguous names error instead of guessing.
Server Configuration
No config file — everything is an environment variable. SQLite is the default backend; Postgres is optional (same API). The full operator manual, including the enterprise setup, lives in USER_GUIDE.md.
| Variable | Default | Description |
|---|---|---|
PORT | 8080 | TCP port |
DATABASE_PATH | ./envious.db | SQLite file — back this up |
DB_DRIVER | sqlite | sqlite or postgres |
DATABASE_URL | — | Postgres URL (only when DB_DRIVER=postgres) |
ENCRYPTION_KEY | — | Value encryption at rest + session signing. Always set in production. |
LOG_LEVEL | info | debug | info | warn | error |
LOG_FORMAT | json | json for collectors, text for local dev |
RATE_LIMIT_RPS / RATE_LIMIT_BURST | 20 / 40 | Per-IP API throttle (0 disables) |
REST API
All endpoints live under /api and require X-API-Key, except GET /api/version which is public.
| Endpoint | Description |
|---|---|
GET /api/version | Build version (public) |
GET /api/apps · POST /api/apps | List / create applications |
GET /api/apps/:id · DELETE /api/apps/:id | Fetch / delete an application |
GET /api/envs?app_id= · POST /api/envs | List (optionally filtered) / create environments |
GET /api/envs/:id · DELETE /api/envs/:id | Fetch / delete an environment |
GET /api/envs/:id/vars · POST /api/envs/:id/vars | List / set variables |
PUT /api/vars/:id · DELETE /api/vars/:id | Update / delete a variable |
GET /api/activity?action=&limit= | Query the audit trail |
Errors are {"error": "..."}. Missing resources return 404, duplicates 409, bad input 400, bad key 401.
Operations: Logs and Audit
Logs go to stdout as JSON with request IDs (X-Request-ID). Every mutation and login lands in the audit trail — in SQLite and on the log stream ("audit":true). Details carry metadata only, never secret values.
# query the trail
curl -H "X-API-Key: $KEY" 'http://127.0.0.1:8080/api/activity?action=var.set&limit=50'
Fluent Bit
[INPUT]
Name tail
Path /var/log/envious/*.log
Parser json
Tag envious.*
Refresh_Interval 5
[OUTPUT]
Name stdout
Match envious.*
Forward to Loki, Elasticsearch, or OpenSearch with their output plugins. Alert on "action":"auth.login_failed" and mirror "audit":true into long-term storage.