Compose and stack files
Deploying a Docker Compose or Swarm stack file - what is applied, what is not, and what applying it again does.
A Compose file describes several programs at once. ISOGrid reads it and turns
each service into an application of its own: the same kind of application you
would create by hand, with its own size, address, logs and history. A
docker stack file is read the same way.
The file is a way of creating and updating applications. It is not something that keeps running as a group afterwards.
Two kinds of service, two paths
A service that names an image is pulled and run. That is what this page
covers.
A service with a build: section is built from its Dockerfile when you
import the repository. That path reads the file differently, and
how the build is detected describes it.
A file can hold both. Each service takes the path that fits it.
Where the file comes from
Pasted or uploaded. Applications, then From a stack file: paste the YAML or upload it.
From a connected repository. When you pick a repository, the YAML files in it whose services name images are listed as stack files. The platform reads the file itself, shows you what it read and at which commit, and applies that same commit even if someone pushes in between.
From the command line. isogrid stack preview -f compose.yml --stack shop
and isogrid stack apply, with a local file, a folder of files, or
--repo and --path for a file in a connected repository. This is the one
to run from CI.
A file may be up to 256 KB and hold up to 60 services.
Preview first
A preview changes nothing. For each service it says whether an application would be created, updated or skipped and why, which of your registries pulls the image, and everything in the file that will not be applied.
You then decide, per service: the size (the smallest that fits the file's limits is suggested), the network, the registry when several match, the port, where it may run, or to leave it out.
${TAG} and ${TAG:-1.4} are filled from the variables you give. A variable
the file uses and nobody supplied is listed, and blocks the apply.
What is applied
image, which is required.deploy.replicas, from 1 to 10.environment.command,entrypoint,user,healthcheckandstop_grace_period.deploy.update_config,rollback_configandrestart_policy.loggingwith thejson-filedriver:max-sizeandmax-fileturn log retention on for that application.portsandexpose, only to learn which port the program listens on.deploy.resources.limits, only to suggest a size.networks, matched by name to one of your networks. An application joins one network; the first one listed is used.- Anchors and
<<:merge keys.
What is not, and why
build: without an image. The service is skipped here. Import the
repository to build it, or push the image and name it.
Databases, caches, brokers and storage servers. An image of PostgreSQL, MySQL, MongoDB, Redis, RabbitMQ, Kafka, Keycloak, MinIO and the like is skipped, with a pointer to the managed equivalent. Run as an ordinary application it would have no backups and would lose its data on the first move. See Databases and Managed services.
env_file. Not read on this path. Add those variables on the application
afterwards, and secrets as secrets.
volumes. Not mounted, named or bind. A service cannot choose host paths
on shared machines. Attach storage on the application's page after applying.
secrets and configs. Not created. Store the values as secrets and bind
them to the application.
Published host ports. "80:8080" opens nothing on a machine. The
application is private until you make it public from its exposure settings,
and then it gets an address.
cap_add, privileged, devices, network_mode and similar. Not
granted. The preview lists each key it did not apply.
depends_on, container_name, hostname, labels, top-level restart.
Ignored without a warning. Nothing is started in order: an application that
needs another one should retry until it answers.
Placement constraints. They name someone else's machines. One is kept only when it matches a choice the region offers.
Smaller things. mode: global runs as ordinary copies, resource
reservations come from the size, and log drivers other than json-file are
not available.
Names, and how services find each other
Each application is called <stack>-<service>. On its private network it also
answers to the plain service name from the file, so http://api:8000 keeps
working between services on the same network.
An application that already has that name and was not created by this stack is left alone.
An example the platform accepts
services:
api:
image: ghcr.io/acme/api:${TAG:-1.4}
command: ["node", "server.js"]
environment:
LOG_LEVEL: info
ports:
- "8000"
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8000/health"]
interval: 30s
timeout: 5s
retries: 3
deploy:
replicas: 2
resources:
limits:
cpus: "0.5"
memory: 512M
update_config:
parallelism: 1
order: start-first
failure_action: rollback
monitor: 30s
logging:
driver: json-file
options:
max-size: 10m
max-file: "3"
worker:
image: ghcr.io/acme/api:${TAG:-1.4}
command: ["node", "worker.js"]
Applying it again
Applying the same file under the same stack name updates the applications instead of creating new ones.
The file wins for what it sets. Image, copies, command, health check, rollout and log settings are replaced by the file's.
Environment is merged. The file's variables overwrite the same names; variables you added by hand are kept.
The number of copies goes back to the file's. If you scaled an application by hand, the next apply undoes it.
The size is what that apply chooses. From the command line, pass --size
every time, or the application returns to the suggested size.
Nothing is deleted. A service removed from the file leaves its application running. Delete it yourself.
Every created or updated application is then deployed, even when nothing changed, unless you turn deployment off. One service failing does not stop the others; each is reported.
Rolling out and reading logs
Each application rolls out on its own, by the settings the file gave it.
failure_action: rollback returns to the previous version automatically,
pause leaves the decision to you, and continue does neither. monitor is
how long a new version must stay healthy, between 5 and 300 seconds.
isogrid stack apply --wait waits for every deployment and fails if any
failed or was rolled back, which is what a CI job needs. --follow prints the
deployment logs as they come.
Logs are read per application, not per stack: on the application's page, or
with isogrid apps logs <application>. Without log retention, only what the
running copies still hold can be searched.