# Production Files With -f — Docker Compose

Source: https://www.skillbyai.com/en/docker-compose/e-prod

> Explicit file lists for each environment.

## Combine files explicitly

For other environments, pass files explicitly: `docker compose -f compose.yaml -f compose.prod.yaml up -d`. Later files override earlier ones. A production file typically adds restart policies, resource limits, logging options, and removes development conveniences simply by not including the override. Review the merged result with `config` before deploying.

## The production file

Restart policies and resource limits.

```yaml
services:
  web:
    restart: unless-stopped
  api:
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M
```

## The merged production configuration, run

I ran this with Docker Compose v2.38.1 and jq in the demo "shop" project. docker compose config parses, interpolates, merges and validates the files without starting containers; the Docker daemon was not running, so nothing was started. With -f for base and prod files, the API gets restart unless-stopped and limits of 1 CPU and 512M (normalised to 536,870,912 bytes, so M means MiB here). Because the override is not loaded, the development port 3000 is gone.

```bash
docker compose -f compose.yaml -f compose.prod.yaml config --format json | jq -c ".services.api | {restart, limits: .deploy.resources.limits, ports: [.ports[]?.published]}"
```

Output:

```
{"restart":"unless-stopped","limits":{"cpus":1,"memory":"536870912"},"ports":[]}
```

**Quiz:** Why did port 3000 disappear in the production configuration?

- [ ] Production disables all ports
- [x] The automatic override file is not loaded when -f files are given
- [ ] The prod file deletes ports explicitly
- [ ] Port 3000 is reserved

*Answer:* The automatic override file is not loaded when -f files are given. Explicit -f lists replace the default file set.
