IT-Wissen/docker/docker-compose.md
2025-04-24 15:50:34 +02:00

376 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
gitea: none
include_toc: true
---
# Docker compose
- __Purpose:__ Defines and manages multi-container Docker applications.
- __Usage:__ Orchestrates multiple services (containers), networks, and volumes for an application.
- __Key Features:__
- Describes how to run one or more containers together.
- Can manage container networking and persistent storage.
- Useful for applications with multiple services (e.g., a web app + database).
- __Output:__ A running application consisting of multiple containers.
`docker-compose.yml` is the file which includes all nescessary information. It can include multiple services like web (built from a Dockerfile) and db (pulled from Docker Hub).
## docker-compose vs. docker compose
- If you're using a modern Docker installation (20.10+), use `docker compose`.
- If you're working on a system with an older Docker version or have compatibility concerns, use `docker-compose`.
| Feature | docker compose | docker-compose |
| --- | --- | --- |
| Integration | Integrated into Docker CLI | Standalone binary |
| Compose Specification | Supports Compose V2 | Supports older Compose V1 |
| Performance | Faster and more efficient | Slower compared to Compose V2 |
| Availability | Docker 20.10+ and Docker Desktop | Any Docker version, standalone |
| Future-proof | Actively developed and maintained | Legacy, less maintained |
check your docker compose version (examples):
```
docker compose version
Docker Compose version v2.32.1
# is installed together with docker v27.4.1
docker-compose --version
docker-compose version 1.25.0, build unknown
# separate installation for old version.
```
## docker-compose.yaml version
Use `version: "3.9"` which is the latest version. Or, with Docker Compose v2 (the newer, built-in CLI plugin), you no longer need a version: line. If you remove it, Compose will simply default to the current spec.
## Image location
### Registry
In docker compose, use `image` to use an existing image from the registry.
```
services:
redis:
init: true
image: redis:latest
```
### Local Image
If the image needs to be built, use `build`.
```
services:
my-local-app:
init: true
build: .
```
`build: .` tells Docker Compose to look for a `Dockerfile` in the same directory as the `docker-compose.yml`.
If the Dockerfile is in a subdirectory, specify the context and Dockerfile path:
```
services:
my-local-app:
init: true
build:
context: ./my-app
dockerfile: Dockerfile.dev
```
- `context:` Specifies the directory containing the application code.
- `dockerfile:` Specifies the name of the Dockerfile if its not the default Dockerfile.
You can mix local builds and images from a registry in the same docker-compose.yml file:
```
services:
myapp:
init: true
build: ./my-app
ports:
- 8080:8080
redis:
init: true
image: redis:latest
webapp:
init: true
build: .
image: registry.cs.zi.uzh.ch/zi-adb-dba/export-digicert-report:latest
```
## Docker Volumes
Bind mounts:
```
version: '3.9'
services:
caddy:
image: caddy:2.6.2
volumes:
- /opt/roger/ssl/certifcate.pem:/cert.pem:ro
# OR: Bind mounts of remote share which are defined through docker volumes
<code>version: '3.9'
services:
fedora:
init: true
image: docker.cloudsmith.io/docuteam/docker/fcrepo:6.2.0
volumes:
- fedora_data:/fcrepo_home
volumes:
fedora_data:
driver_opts:
type: cifs
device: //remote-hostname.com/path/to/share/fedora
o: addr=remote-hostname.com,username=user,password=mysuperpassword,nodev,noexec,nosuid,vers=2.1,uid=1000,gid=1000
```
Docker volumes:
```
version: '3.9'
services:
caddy:
init: true
image: caddy:2.6.2
volumes:
- caddy_data:/data
volumes:
caddy_data
```
### Read-Only
Add `:ro` at the end of the line.
```
volumes:
- /opt/roger/ssl/certifcate.pem:/cert.pem:ro
```
## Dependencies
If there is a special order of starting the containers, you can use `depends_on`, like this:
```
services:
myapp:
init: true
build: ./my-app
ports:
- 8080:8080
redis:
init: true
image: redis:latest
depends_on:
- myapp
```
You can also add `condition`s, like `service_started`, `service_healthy` and `service_completed_successfully`:
```
services:
myapp:
init: true
build: ./my-app
ports:
- 8080:8080
redis:
init: true
image: redis:latest
depends_on:
myapp:
condition: service_started
```
In the following example, Compose will first start the database service, execute the pg_isready command specified in the healthcheck.test property, start the migration service if the value returned by the test command is 0, and finally start the api service if the exit status of the migration service's container is also 0.
```
services:
api:
init: true
build: .
depends_on:
database:
condition: service_healthy
migration:
condition: service_completed_successfully
database:
init: true
image: postgres
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
migration:
init: true
image: migration-tool
```
## Variables
### Variables for docker-compose.yaml
Use `${VARIABLE_NAME}`, like this:
```
services:
ui:
init: true
image: nginx:${NGINX_VERSION}-alpine
```
You can pass the variable when starting docker compose like this:
```
NINGX_VERSION=1.21.5 docker compose up -d
```
You can also use an environment file. If no variable is set on calling `docker compose up`, then it will use the value in the `.env` file.
```
touch .env
# then add the variables:
NINGX_VERSION=1.21.4
```
If the file has a different name or is located in a different path, you can specify the location when starting docker-compose.
```
docker compose --env-file /path/to/environmentfile up -d
```
### Variables for containers
If a variable is already set in the shell, like `PORT` in this example, it will be automatically passed to docker compose, like this:
```
services:
ui:
init: true
image: nginx:1.21.5-alpine
environment:
- PORT
```
To specify the variable in docker compose:
```
services:
ui:
init: true
image: nginx:1.21.5-alpine
environment:
- PORT=81
```
You can also specify a file:
```
services:
ui:
init: true
image: nginx:1.21.5-alpine
environment:
- PORT=81
env_file:
- ./path/to/envfile
```
## Profiles
Start only containers within a certain profile. Note that services WITHOUT a profile will always start!
```
services:
myapp:
init: true
build: ./my-app
ports:
- 8080:8080
profiles:
- blabla
ui:
init: true
image: nginx:1.21.5-alpine
profiles:
- profilename
```
start like this, and it will start only the "ui" service.
```
docker compose --profile profilename up -d
```
## Networks
All containers in a docker compose setup can communicate with eachother. The services, like `myapp` or `ui` can be used as hostnames. This will make linking the containers easier.
If the network must be specialized, e.g. not all containers have connection to other containers, you need to build your own networks.
```
services:
myapp:
init: true
build: ./my-app
networks:
- test
ui:
init: true
image: nginx:1.21.5-alpine
profiles:
- profilename
networks:
- test
networks:
test:
driver: bridge
attachable: true # default; set to false, so that other containers can not be added to the network in the future.
```
## Restart policy
```
ui:
init: true
image: nginx:1.21.5-alpine
restart: always # or other settings...
```
## Commands
### Config
The following command shows you the docker-compose.yaml as it is interpreted by docker.
```
docker compose config
```
### Start
Ins Verzeichnis gehen wo `docker-compose.yml` liegt, und dann `docker-compose start -d`. Mit `-d` wird es im Hintergrund ausgeführt.
### Stop
- The `docker compose stop` command will stop your containers, but it wont remove them.
- The `docker compose kill` command will stop your containers faster, but it wont remove them.
- The `docker compose down` command will stop your containers, but it also removes the stopped containers as well as any networks that were created.
- You can take down 1 step further and add the `-v` flag to remove all volumes too. This is great for doing a full blown reset on your environment by running `docker compose down -v`.
### Events
```
docker compose events
```