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

CommandWhat it does
login --api-key --api-baseStore credentials in ~/.envious/config
app list | create <name> | delete <id>Manage applications
env list | create | deleteManage 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
versionPrint 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.

VariableDefaultDescription
PORT8080TCP port
DATABASE_PATH./envious.dbSQLite file — back this up
DB_DRIVERsqlitesqlite or postgres
DATABASE_URLPostgres URL (only when DB_DRIVER=postgres)
ENCRYPTION_KEYValue encryption at rest + session signing. Always set in production.
LOG_LEVELinfodebug | info | warn | error
LOG_FORMATjsonjson for collectors, text for local dev
RATE_LIMIT_RPS / RATE_LIMIT_BURST20 / 40Per-IP API throttle (0 disables)

REST API

All endpoints live under /api and require X-API-Key, except GET /api/version which is public.

EndpointDescription
GET /api/versionBuild version (public)
GET /api/apps · POST /api/appsList / create applications
GET /api/apps/:id · DELETE /api/apps/:idFetch / delete an application
GET /api/envs?app_id= · POST /api/envsList (optionally filtered) / create environments
GET /api/envs/:id · DELETE /api/envs/:idFetch / delete an environment
GET /api/envs/:id/vars · POST /api/envs/:id/varsList / set variables
PUT /api/vars/:id · DELETE /api/vars/:idUpdate / 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.