agentleFS
AnyOrgNameAnyOrgName/php-skills/skills/devops/env-config/SKILL.md

env-config

Skill4 starsChanged 4 months agoMITView on GitHub

Configure PHP apps the 12-factor way — read config from the environment, separate .env from real secrets, and manage per-environment overrides safely. Use when the user wants to move hardcoded configuration or credentials out of PHP code and into the environment; the user wants different configuration values for local, staging, and production from a single codebase; the user needs to store API keys, database passwords, or tokens without committing them or baking them into the image. Keywords: config, env, secrets, 12-factor, dotenv, per-environment.

  • Reads credentials

4 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

4 rules. 0 are common, 1 is distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 4 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Do not use this skill when the user needs per-user or gradually-rolled-out feature flags evaluated at runtime.

    line 64
  2. Very specific:

    Do not use this skill for how a specific framework's config/*.php files or service definitions are structured.

    line 65
  3. Very specific:

    Commit a .env.example documenting every required key with placeholder values, add .env to .gitignore, and keep real values out of version …

    line 89
  4. Very specific:

    Read environment variables into a typed config object at boot and inject that, rather than scattering getenv()/$_ENV lookups through the …

    line 91

“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md
<!-- generated: do not edit — source: knowledge/atoms/devops/env-config/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->

12-Factor PHP Configuration

When to use

  • The user wants to move hardcoded configuration or credentials out of PHP code and into the environment.
  • The user wants different configuration values for local, staging, and production from a single codebase.
  • The user needs to store API keys, database passwords, or tokens without committing them or baking them into the image.

When NOT to use

  • Do not use this skill when the user needs per-user or gradually-rolled-out feature flags evaluated at runtime.
  • Do not use this skill for how a specific framework's config/*.php files or service definitions are structured.

Core guidance

  • Treat .env as a local-dev convenience, not production config — Use a .env file (via vlucas/phpdotenv or the framework loader) only for local development, and inject real environment variables directly in production.
  • Read configuration from environment variables — Source configuration that varies between deploys (DB DSN, cache host, API base URLs, keys) from environment variables, not from committed per-env PHP files.
  • Keep real secrets in a secrets manager, not .env — Store production secrets (DB passwords, tokens, keys) in a secrets manager or the platform's encrypted secret store, and inject them as env vars at runtime.

Quick recipe

  1. List every required variable with a placeholder in .env.example, add .env to .gitignore, and keep the real .env for local dev only. (verify: .env.example is committed, .env is gitignored)
  2. At boot, read each variable once, cast it to its type, and throw a clear error for any missing required key, exposing the result as a typed config object. (verify: Booting with a required variable unset fails fast with a named error)
  3. In production, source secret values from a secrets manager into the process environment at deploy time instead of shipping a .env in the image. (verify: The production container holds no .env and reads secrets from injected env vars)

Best practices

  • In production, compile the resolved configuration into a single cached file at deploy time instead of reading and parsing env/.env on every request
  • Commit a .env.example documenting every required key with placeholder values, add .env to .gitignore, and keep real values out of version control
  • Read environment variables into a typed config object at boot and inject that, rather than scattering getenv()/$_ENV lookups through the request path
  • At application boot, read each required variable once, cast it to the correct type, and fail fast with a clear error if a required value is missing

Anti-patterns

Anti-patternWhy it failsDo instead
Dumping the full environment in errors or logsIt writes every secret into logs and error pages, where it is broadly readable and hard to purge.Log only non-sensitive keys, redact secret values, and disable verbose config dumps in production.
Hardcoding credentials in sourceThe secret is exposed to everyone with repo read access and cannot be rotated without a code change and redeploy.Read the secret from an injected environment variable backed by a secrets manager, and keep the literal out of code.
Per-environment code branches or config files in the repoThe artifact is no longer environment-agnostic, so a build tested for staging can behave differently in production.Drive all environment differences through env vars so one immutable build runs everywhere unchanged.

See references/anti-patterns.md.

Common mistakes

  1. Cached config ignores env changes until rebuilt — Frameworks that cache resolved config (e.g. config:cache) stop reading env vars at runtime, so later env changes have no effect. Fix: Rebuild the config cache as part of every deploy, and never call the env reader directly in application code once config is cached.
  2. Committing .env leaks secrets into git history — Accidentally committing a real .env puts every secret it holds into git history, where deleting the file does not remove it. Fix: Add .env to .gitignore before the first commit; if one leaked, rotate the exposed secrets immediately and scrub history with a tool like git-filter-repo.
  3. Env values are strings, so "false" is truthy — Every environment variable is a string, so getenv('DEBUG') returns the string "false", which is truthy in a boolean check. Fix: Cast explicitly — compare against 'true', use filter_var($v, FILTER_VALIDATE_BOOL), or map through a typed config layer that coerces booleans and integers.

Version notes

  • phpdotenv 5 requires PHP 7.2+ and supports safe loading (PHP >=7.4) — vlucas/phpdotenv v5 supports PHP 7.2 and later and offers safeLoad() plus ->required()->notEmpty() validation, so the same loader covers 7.4 through 8.4.

Security

  • Keep secrets out of the repo, image, and logs — Never commit real secrets, bake them into an image layer, or emit them in logs or error pages; inject them from a secrets manager at runtime and gitignore .env.

Testing

  • Activation and decision behavior are verified in eval/scenarios/devops/env-config.yaml.

Additional resources

  • references/anti-patterns.md
  • references/core.md
  • references/examples.md
  • references/pitfalls.md
  • references/recipes.md
  • references/version-differences.md

Knowledge graph

Related: databases/redis, devops/deployment-strategies, devops/docker-php

<!-- graph-fragment: graph/fragments/devops/env-config.yaml -->

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.