# Compose File Rules

> Learn what FlyWP accepts, modifies, and blocks in Compose files, including size limits, reserved settings, and advanced mode exceptions.

Source: https://flywp.com/docs/site/docker-compose-apps/compose-file-rules/

FlyWP validates your Compose file before deploying it and checks it again on every update. The validator flags any settings that could compromise the server or other sites, and adjusts a few options so your app integrates smoothly with FlyWP. If an issue is found, FlyWP highlights the exact line, service, and reason.

FlyWP then saves a managed copy of the validated file. Your app runs from this managed copy, not directly from your pasted snippet or remote link.

## Limits

| Limit | Value |
| --- | --- |
| File size | 64 KB |
| Services in one app | 20 |
| Extra networks in one app | 2 |
| Ports read from one range | 20 |

FlyWP also evaluates YAML anchors and references. If expanding `&name` anchors and `*name` references causes the file to exceed 1 MB, FlyWP rejects it.

## The file must be readable

The validator stops if it encounters syntax or parsing errors. Fix any of the following issues and re-check:

- The file isn't valid UTF-8 text.
- Indentation is incorrect, or a required colon or quote is missing.
- A duplicate key appears within the same block.
- An alias like `*name` is referenced before its `&name` anchor is defined.
- The file contains multiple YAML documents. Remove `---` and any subsequent documents.
- Tabs are used for indentation instead of spaces.
- A custom YAML tag (any tag starting with `!`) is used.
- YAML structures are nested too deeply.
- The file is missing the `services:` block, or defines no services under it.
- A service is missing an `image:` definition.

Values that Docker Compose parses as dates (such as `2026-11-07`) must be enclosed in quotes.

Any `${...}` variable expression that Docker Compose can't resolve will be rejected. If you need a literal dollar sign rather than a variable, escape it with `$$`.

## Names

Service, volume, and network names may only contain letters, numbers, dashes, underscores, and dots. A name can't be digits only; start it with a letter. Names that FlyWP reserves for itself are refused.

FlyWP manages names for your app, its volumes, and its networks. Any top-level `name:`, as well as custom volume and network names, are automatically replaced with app-scoped names.

## Changed by FlyWP

FlyWP adjusts certain settings automatically and notes each change during validation. You don't have to remove these from your file, but your app will run using FlyWP's adapted configuration:

- `version` is stripped.
- `container_name` is removed. FlyWP names containers after your app; other services within the app can still communicate using the service name.
- `logging` is replaced with FlyWP's centralized logging configuration so the **Logs** page works properly.
- `limits` defined in your file are superseded by FlyWP's resource settings. Manage them on the **Resources** page.
- `deploy`, `scale`, and `pull_policy` are removed. FlyWP runs a single instance of each service and pulls fresh images during each deploy.
- `profiles` stops a service from starting. Remove `profiles` to let the service run.
- `env_file` is removed because local files aren't stored on the server. Configure variables on the **Environment** page or use **Import .env**.
- `build` directives are removed when FlyWP pulls pre-built images. Building from source requires a linked repository and only supports `context`, `dockerfile`, `args`, and `target`.
- Use a `TZ` environment variable instead of mounting host timezone files.

### Ports

Services cannot expose raw ports directly to the internet. Instead, route web traffic to your service by attaching a domain under **Domains**. Ports 80 and 443 are reserved for FlyWP's server proxy, while ports 22, 3306, and 20022 are reserved for system services, so apps cannot bind to them.

### Secrets in build arguments

Docker bakes build arguments directly into the image layers. Never pass sensitive credentials or secrets as build arguments. Instead, supply them as environment variables that your container reads at runtime.

## Refused in every mode

FlyWP blocks these configurations even when advanced mode is enabled:

- `include` and `extends` directives.
- Mounting `docker.sock`, which would give full control over every container on the server.
- Directory paths outside the repository or app folder (paths containing `../` are prohibited).
- Mounting the entire app root directory. Mount a specific subdirectory instead, such as `./data`.
- Any directory belonging to FlyWP core or other sites on the server.
- Nested directory mounts where a directory sits inside an already-mounted parent. Use a named volume for shared data instead.
- Mount destination paths that don't start with `/` or that contain a `:`.
- Custom `network_mode` directives. FlyWP connects your app's services over an isolated private bridge network.
- `extra_hosts` configured with `host-gateway`.
- Host namespaces, such as `pid: host`, `ipc: host`, or host-level networking.
- Any setting that bypasses the resource limits configured in FlyWP.
- References to external containers outside this app. Use service names defined within the same file.
- External volumes (`external: true`) or external networks.
- Volume drivers other than `local`, network drivers other than `bridge`, or custom `driver_opts` on volumes.
- Network options that could conflict with networks belonging to other sites.
- Container images referenced by image ID. Always reference images by tag name.
- Image names reserved for FlyWP's internal infrastructure.
- An image from a registry at a private address, or one FlyWP can't find. Use a registry that is reachable on the internet. If the registry's domain is new, try again in a few minutes.
- Volume mount options other than read-only (`ro`).
- Unrecognized or unsupported Docker Compose directives. FlyWP will display an error identifying the unsupported key.

## Refused unless advanced mode is on

Enable advanced mode on the **Advanced** settings page to permit these options. Because they grant elevated host-level control, only enable them for trusted applications:

- `privileged` mode.
- `cap_add` to add Linux kernel capabilities.
- `security_opt` options that disable container isolation boundaries.
- `sysctls` that modify kernel runtime parameters.
- `devices` to grant direct access to host hardware.
- `host` namespaces.
- Host directory mounts outside the application directory.

Even with advanced mode enabled, access to the Docker socket, FlyWP system ports and networks, containers from other apps, and internal scheduler labels remains strictly blocked.

## Warnings

If you paste a Compose file or load it from a link, FlyWP only receives that single file. If your Compose file mounts an external config file (like `./config.yml`) that doesn't exist locally, Docker will create an empty directory with that name instead, and the container may fail to start. To deploy an app that relies on supplementary files, create the app from a GitHub repository.

If an environment variable has no default value declared in the Compose file, it won't be set unless you define it on the **Environment** page.
