Validate .env files against a declarative YAML schema. Catch missing required variables, malformed URLs, out-of-range ports, wrong enums, and bad length bounds — before your container starts, not after production breaks.
# Clone
git clone https://github.com/sen-ltd/envcheck
cd envcheck
# Build & run via Docker (no Python install needed)
docker build -t envcheck .
docker run --rm -v "$PWD:/work" envcheck --schema envcheck.example.yml --env .env.env.example files are just a list of keys. They can't express:
- "
DATABASE_URLmust be a valid URL" - "
NODE_ENVmust be one ofdevelopment|staging|production" - "
JWT_SECRETmust be a string of at least 32 characters" - "
PORTmust be a valid TCP port (1–65535)"
Existing tools don't fill the gap: dotenv-linter is Rust, style-only, and doesn't do types; envalid is code-based and JavaScript-only. envcheck is a small, single-purpose CLI that lets you check in a YAML schema alongside your .env.example and run it in CI in any language ecosystem.
# envcheck.yml
DATABASE_URL:
type: url
required: true
description: Primary Postgres connection string
PORT:
type: port
required: true
NODE_ENV:
type: string
required: true
enum: [development, staging, production]
JWT_SECRET:
type: string
required: true
min_length: 32Then in CI:
docker run --rm -v "$PWD:/work" envcheck --schema envcheck.yml --env .env --ciExit code 0 means valid; 1 means validation errors; 2 means the schema or env file itself was missing or broken.
| Type | Matches |
|---|---|
string |
Any non-empty string (length checks optional) |
int |
Signed integer |
bool |
true|false|1|0|yes|no (case-insensitive) |
url |
Anything urllib.parse sees as scheme+netloc |
email |
x@y.z shape (not full RFC 5321) |
port |
Integer in 1..65535 |
path |
Non-empty, no NUL byte |
Additional per-field constraints: required, pattern (regex), enum, min_length, max_length, description.
.env:3: DATABASE_URL: expected url, got "localhost:5432"
.env:7: PORT: expected port (1-65535), got "99999"
.env:12: LOG_LEVEL: expected one of [debug, info, warn, error], got "trace"
.env: missing required variable: JWT_SECRET
4 errors found in .env
Line numbers point at the actual line in your .env, formatted path:line: message so your editor's jump-to-error picks them up automatically. Colors are emitted only on a TTY, disabled by --ci or the NO_COLOR environment variable.
| Flag | Behavior |
|---|---|
--schema |
Path to YAML schema (default envcheck.yml) |
--env |
Path to env file (default .env) |
--strict |
Error on unknown vars (in .env but not schema) |
--ci |
Plain output, no ANSI color |
# Emit a .env.example skeleton from a schema
docker run --rm -v "$PWD:/work" envcheck example --schema envcheck.yml > .env.examplepip install .
envcheck --schema envcheck.yml --env .envRequires Python 3.10+. The only runtime dependency is PyYAML.
docker run --rm --entrypoint pytest envcheck -q| Code | Meaning |
|---|---|
| 0 | .env is valid |
| 1 | Validation errors (missing, wrong type, etc.) |
| 2 | Config error: missing schema file, malformed YAML |
MIT. See LICENSE.
