# Environment Files

**Package:** Laravel Compose | **Version:** 1 | **URL:** https://mozex.dev/docs/laravel-compose/v1/stacks/environment-files

---

Before every redeploy, the package writes `environment()` into the stack directory as `.env`. Compose reads that file when it interpolates `${VAR}` in the compose file, and only then. Nothing else in the app reads it. The name is configurable through `env_file`; a name other than `.env` is handed to compose as `--env-file` on every call.

## Why the file is generated

Your app already has one source of truth for its settings, and secrets shared between the app and a container (a Meilisearch master key, a gateway's signing secret) must never drift between the two. So the stack class reads config, the config reads the app's own `.env`, and the container env file is an output. A value only has to change in one place, and the next deploy applies it.

The other side of that coin: never edit the generated file by hand on the server. The next redeploy overwrites it, silently. The one exception is a stack whose `environment()` is empty (a class-less one, for instance): with nothing to write, an existing file is left as it is.

## The shell doesn't get a say

Compose reads the shell before the env file: a variable set in the environment of the `docker compose` process beats the same variable in the file. Laravel exports the app's own `.env` into the environment of every process it starts, so an app key that shares a name with a stack key (`MEILISEARCH_PORT` in the app's `.env` and in `environment()`, say) would win over the file the redeploy just wrote, and the container would come up with the app's value. Silently.

So every compose command runs with the keys the stack writes unset, for that process only. The file is the value compose sees, and `environment()` is the one place a container's setting comes from. A variable the stack doesn't write still comes from the shell, which is what the `${VAR:-default}` knobs and `compose:doctor`'s "set in this shell" warning are about.

## What can go in it

Keys must match `[A-Za-z_][A-Za-z0-9_]*`. Values can be strings, integers, floats, booleans (`true`/`false`), null (written as empty), backed enums (their value), and `Stringable` objects. Anything else, an array for instance, throws a `ComposeException` naming the key and the stack.

Values are quoted with Compose's own rules, because a raw `KEY=value` line breaks in ways that are hard to spot:

| Value | Written as | Why |
|---|---|---|
| `abc-123` | `abc-123` | Nothing to protect. |
| `hello world # tag` | `'hello world # tag'` | An unquoted ` #` starts a comment; the value would be truncated. |
| `say "hi" $HOME` | `'say "hi" $HOME'` | Single quotes keep everything literal, including the dollar. |
| `it's` | `"it's"` | Single quotes can't hold a single quote, so double quotes with `\`, `"`, and `$` escaped. |
| `ends with \` | `"ends with \\"` | Compose reads a backslash before a closing quote as an escaped quote, single quotes included, and never finds the end of the value. |
| a value with a line break | throws | Env files are line-oriented; there is no way to write it. |

The test suite round-trips every one of those through `docker compose config`, so what you put in `environment()` is what the container sees.

## Secrets

The file is written with `0600` permissions and sits inside the working tree. `compose:make` adds a `.gitignore` with `.env` to the stack directory, and Laravel's own root `.gitignore` already contains `.env`, which git applies at every depth. `compose:doctor` asks git whether the file would be ignored and warns when it wouldn't.

## The contract with the compose file

Every variable the compose file consumes without a default must be a key of `environment()`. `${MEILI_KEY}` and `${MEILI_KEY:?message}` count; `${PORT:-7700}` and `${PORT-7700}` don't, they carry their own fallback, and neither does `${COMPOSE_PROJECT_NAME}`, which compose fills from the project name the package passes. The doctor checks this before anything touches Docker, so a renamed key fails the preflight instead of the rollout. For a stack with an empty `environment()`, the keys of a hand-written env file in its directory count instead.

Knobs the stack doesn't own belong in the compose file as defaults. Bind addresses, timeouts, log levels: give them `${VAR:-value}` there and only write the ones the app decides.

---

## Table of Contents

- [Introduction](https://mozex.dev/docs/laravel-compose/v1)
- [AI Integration](https://mozex.dev/docs/laravel-compose/v1/ai-integration)
- [Support Us](https://mozex.dev/docs/laravel-compose/v1/support-us)
- [Requirements](https://mozex.dev/docs/laravel-compose/v1/requirements)
- [Changelog](https://mozex.dev/docs/laravel-compose/v1/changelog)
- [Contributing](https://mozex.dev/docs/laravel-compose/v1/contributing)
- [Questions & Issues](https://mozex.dev/docs/laravel-compose/v1/questions-and-issues)
- [About Mozex](https://mozex.dev/docs/laravel-compose/v1/about)
- [Installation](https://mozex.dev/docs/laravel-compose/v1/installation)
- [Configuration](https://mozex.dev/docs/laravel-compose/v1/configuration)

### Stacks

- [Defining a Stack](https://mozex.dev/docs/laravel-compose/v1/stacks/defining-a-stack)
- [Discovery](https://mozex.dev/docs/laravel-compose/v1/stacks/discovery)
- [Environment Files](https://mozex.dev/docs/laravel-compose/v1/stacks/environment-files)
- [Compose Files](https://mozex.dev/docs/laravel-compose/v1/stacks/compose-files)

### Deploying

- [Redeploy](https://mozex.dev/docs/laravel-compose/v1/deploying/redeploy)
- [Hosting Platforms](https://mozex.dev/docs/laravel-compose/v1/deploying/hosting-platforms)
- [Remote Daemons](https://mozex.dev/docs/laravel-compose/v1/deploying/remote-daemons)
- [Doctor](https://mozex.dev/docs/laravel-compose/v1/deploying/doctor)

### Operating

- [Status, Logs, and Down](https://mozex.dev/docs/laravel-compose/v1/operating/status-logs-down)
- [Health Check](https://mozex.dev/docs/laravel-compose/v1/operating/health-check)
- [Events](https://mozex.dev/docs/laravel-compose/v1/operating/events)
- [Testing](https://mozex.dev/docs/laravel-compose/v1/operating/testing)

### Recipes

- [Meilisearch](https://mozex.dev/docs/laravel-compose/v1/recipes/meilisearch)
- [Telegram Bot API](https://mozex.dev/docs/laravel-compose/v1/recipes/telegram-bot-api)