Compose support
Generated from the code · as of CLI 0.6.0
Your docker-compose.yml runs on OmniArc as you wrote it. A few things compose can express have no meaning inside an arc, and omniarc check and omniarc deploy stop on those before anything is uploaded, with the error unsupported. A few more run, but not quite the way compose runs them on your laptop, and omniarc check prints a note.
The Field column is spelled the way omniarc check prints it. Where it holds a path, as in volumes[./src], read it as the source of one of your own volumes.
# Refused
omniarc check stops on each of these, and so does the deploy. Change your compose file as the second column says.
| Field | What to know, and what to do instead |
|---|---|
build.context | A URL as the build context: a Git repository, for example, is fetched when the image is built, and builds on a node do not fetch it. Put the source in your project and point context at that directory. |
build.context | A build context outside the project: it is not in what you deploy. Move it inside the project. |
build.context | A build context that is not a directory in what you deploy: a Git submodule, a nested repository or ignored files do not make it into the upload, and the build would fail on the node after the upload. Put the files in your project as ordinary files. |
build.dockerfile | The Dockerfile is outside the build context. Move it inside the project. |
build.additional_contexts | Needs BuildKit, and nodes build with Buildah. Copy what the build needs into the main build context. |
build.secrets | Needs BuildKit, and nodes build with Buildah. Keep the secret out of the image: set it as a variable with omniarc env set and read it when the container starts. |
build.ssh | Needs BuildKit, and nodes build with Buildah. Put private dependencies in your project before you deploy. |
build.cache_to | Needs BuildKit, and nodes build with Buildah. Remove it. |
build.platforms | Building for several platforms at once needs BuildKit. Nodes build for linux/amd64: list linux/amd64, or remove the key. |
build.privileged | A privileged build cannot run on a node. Remove privileged: true from the build section. |
privileged | A privileged container cannot start in an arc. Remove privileged: true; if the service needs a specific capability, add it with cap_add. |
devices | Host devices are not available to an arc's services. Remove the entry. |
device_cgroup_rules | Host devices are not available to an arc's services. Remove the rule. |
gpus | No GPUs reach an arc. Remove the entry. |
runtime | Other container runtimes, such as nvidia, are not available. Remove the entry. |
cgroup_parent | Placing a container in a cgroup of the host is not available. Remove the entry. |
userns_mode | The host's user namespace is not available to an arc. Remove the entry. |
platform | Services run as linux/amd64, and nodes do not emulate other platforms. Set platform: linux/amd64, or remove the key. |
env_file | An env_file whose name is not in the .env family (vars.txt), or one outside the project, is not read on a node. Move its values into the arc's .env with omniarc env push, then use ${VAR} in compose or env_file: .env. |
label_file | A label_file inside a writable bind mount of the project is read at every deploy, and a service could rewrite it. Keep the file outside every writable bind. |
networks.ext | An external network is one OmniArc did not create, and an arc owns its networks. Remove external: true and let compose create the network. |
networks.mv | macvlan and ipvlan attach to a network interface of the host, which an arc does not have. Use the default bridge network. |
volumes[/srv/abs] | A bind mount from an absolute path, a path that leaves the project (../data) or your home directory (~/data) does not exist on a node. Use a named volume, or a path inside your project. A read-only mount of /etc/localtime or /etc/timezone is allowed. |
volumes[.] | A writable bind mount of the whole project directory, of a .env file or of arc.yaml cannot be kept across deploys. Nor can any mount inside a writable bind of the project, read-only too, or a writable bind that holds a compose file: a service could rewrite what is there or replace it with a link. Bind only the directory the service writes to, keep what compose reads outside it, or add :ro to mount it read-only. |
volumes[/run/podman/podman.sock] | Podman's own API socket is not available to services, so a service cannot start or change containers. To read the arc's containers, as Traefik's docker provider does, bind /var/run/docker.sock instead. |
volumes.nfsvol | A volume whose driver_opts bind a path or mount a network share is not permitted. Use a plain named volume. |
volumes.ext | An external volume is one OmniArc did not create, so it cannot be branched. Remove external: true and let compose create the volume. |
volumes.plug | Only the local volume driver exists in an arc. Remove driver. |
configs.esc | A config file outside the project directory is not in what you deploy. Move the file inside the project. |
secrets.fs | A secret read from a file in your project would be kept on the arc's disk. Take it from the arc's .env with an environment: source instead, and set the value with omniarc env set. |
healthcheck.interval | Each health check costs CPU, so interval must be 5s or more. Raise it. |
healthcheck.start_interval | The container engine rejects start_interval, and the arc starts health checks every 500 ms itself. Remove it. |
logging.driver | Only the json-file, local and none log drivers exist. Use one of them, or remove logging. |
external_links | Nothing outside the project can be reached by name. Remove it, and put what the service talks to in the same compose file. |
compose | Each file in the compose: list of arc.yaml must be a plain file inside the project directory, written out literally: not a URL, an absolute path, a ~ path, a path that leaves the project, or one with a ${VAR} in it. Fix the path, or move the file inside the project. |
include | A remote include:, a URL or a Git repository, is fetched over the network and is not part of what you deploy. Copy the file into your project and include it by its path. |
include | An include: path that leaves the project directory is not in what you deploy. Move the file inside the project. |
include | An include: path with a ${VAR} in it is refused: write the path out literally, so that what you deploy is exactly what compose reads. |
include | An env_file on an include: would carry values onto the arc's disk by a second route. Put the values in the arc's .env with omniarc env push. |
include | An include: whose project_directory is outside the project, or has a ${VAR} in it, is refused. Keep it inside the project and write it literally. |
extends | A remote extends: {file: ...}, a URL or a Git repository, is fetched over the network and is not part of what you deploy. Copy the file into your project and extend it by its path. |
extends | An extends: {file: ...} path that leaves the project directory is not in what you deploy. Move the file inside the project. |
extends | An extends: {file: ...} path with a ${VAR} in it is refused: write the path out literally, so that what you deploy is exactly what compose reads. |
# Runs with a caveat
These run. omniarc check prints the note so it does not surprise you later.
| Field | What to know, and what to do instead |
|---|---|
env_file | An env_file named like a .env file (./apps/api/.env, config/app.env) reads the arc's one .env, as env_file: .env does. Send its values with omniarc env push; --file repeated merges several files into it. |
volumes[./data] | A writable bind mount of a path inside the project is project state: what the service writes there is kept across deploys, outside what you deploy, and branches with the arc like a named volume (a branch: false service's starts empty). The first deploy fills it from that path in your project, if it has one; later deploys keep what the service wrote and ignore the project's copy, and a branch where the service starts empty does not get it back. |
build | Images are built with Buildah, not BuildKit. Most Dockerfiles build the same; the BuildKit-only options are listed above as refused. |
build.platforms | A single platform other than linux/amd64 is built as linux/amd64, so the image is amd64. Set it to linux/amd64, or remove the key. |
network_mode | host is the arc's own network, shared with its other services. It is never the network of the machine the arc runs on. |
pid | host means the arc, not the machine it runs on. |
ipc | host means the arc, not the machine it runs on. |
uts | host means the arc, not the machine it runs on. |
cgroup | host means the arc, not the machine it runs on. |
cap_add | Capabilities are limited by the arc's isolation (its user namespace, AppArmor and seccomp). Some, such as SYS_MODULE, do nothing; omniarc check names the ones in your file that do. |
security_opt | Applies only within the arc's isolation: its user namespace, AppArmor and seccomp. |
sysctls | net.* settings are per arc and work. A setting of the whole kernel, such as kernel.shmmax, fails when the service starts, with the kernel's error. |
secrets.es | A secret from an environment: source is written to the container's writable layer on the arc's disk, so a branch made from the arc starts with it. |
restart | Honoured while the arc runs. After a sleep and wake, the containers that were running are started again, and one-shot containers that had exited stay exited. |
deploy | placement, update_config, rollback_config and mode: global are settings for Swarm, which compose ignores, and so does the arc. |
develop | watch is a feature for your laptop and is ignored. |
volumes[/var/run/docker.sock] | A read-only view of the arc's own containers, enough for Traefik's docker provider and other tools that list containers and follow events. It answers GET and HEAD only, and refuses exec, attach, file copies (archive), export and image save, so a service can look but not start, stop or enter a container. Looking includes what docker inspect and docker logs show for every service of the arc, environment values among them. /run/docker.sock is the same socket. It costs the arc memory: the socket's own server runs in every arc (about 0.5 MB), and the container API behind it starts when asked and stops after 5 s idle, but a client that follows events, as Traefik does, keeps it running (about 54 MB, measured 20 Oct 2026). |
# Everything else
Everything else runs as compose runs it.