Docker Compose rules

Stagely runs a safe subset of Docker Compose. See which settings it refuses, such as privileged mode and bind mounts, how it limits builds, and why.

The Compose rules are a security control. Each refused setting would give a container access to its machine, weaken its isolation, or reach the build worker that all pull requests share.

Stagely applies the rules twice. First, Stagely checks your Compose files when it plans a deploy. Then, before it builds anything, the agent checks the resolved project on the build worker, with every variable filled in. A failed check fails the deploy with an error that names the service and the field.

Refused in services

Refused Examples
Privileged containers privileged: true, also on a post_start or pre_stop hook
Host namespaces network_mode, pid, ipc, uts, userns_mode, cgroup
More privileges cap_add, cgroup_parent, runtime, and any security_opt other than no-new-privileges
Devices devices, device_cgroup_rules, gpus, deploy.resources.reservations.devices
Bind mounts ./data:/data, /srv:/srv, type: bind, and any mount type other than volume and tmpfs
The Docker socket as a mount, or through use_api_socket
Other containers’ volumes volumes_from with container:. Volumes from another service of the project are fine.
Programs on the machine provider services
Label files label_file. Use labels instead.

Refused at the top level

  • Volumes with driver_opts, or a driver other than local
  • Networks with driver_opts, a driver other than bridge, external: true, or the name host
  • secrets or configs with a file source. Use environment or content sources instead.

Limits on build

Build workers belong to the environment, so the pull requests of all its projects share them. Build workers also hold registry credentials that can push images.

  • context, additional_contexts and dockerfile must be paths in the repository. Stagely refuses absolute paths, paths that start with ~, paths outside the repository and URLs. An additional context can also be an image (docker-image://...) or another service (service:...).
  • Stagely refuses network: host, privileged, entitlements, ssh, tags and cache_to.
  • cache_from takes only image names.
  • The source must not contain a symbolic link that points outside the repository.

Variables

Compose files can use variables in most fields, such as image, environment and ports. The values come from the plain config values and from the .env file in the directory of the first Compose file in the compose list of .stagely.yml. The build worker fills in the variables after the plan, so Stagely can’t know their values when it checks the plan. So Stagely refuses a variable in every field that the rules check:

  • volumes entries in short syntax, and the type and source of a long-syntax volume
  • volumes_from and security_opt
  • the build’s context, additional_contexts, dockerfile, network, secrets and cache_from
  • the driver of a top-level volume, and the driver and name of a top-level network
  • paths in include, extends and env_file

What is fine

  • Named volumes. They live on the stagelet’s machine and survive deploys and resets of the same stagelet.
  • Public images, such as redis:7-alpine, and services built from the repository.
  • include, extends and env_file, as .stagely.yml describes.