Docker-Compose
- Docker Docs Compose specification, The Compose Specification
Some commands:
docker-compose pull
, it would seem this is required to ensure the latest image(s) is downloadeddocker-compose up -d --build --force-recreate
-d
--build
on required if the compose includes building an image--force-recreate
docker-compose down
docker-compose stop|start|restart
it is better to use down and up commands has they force the recreation of the container (no image). This is as the scripts on start-up usually assume a new container.docker-compose build --pull
, will pull the latest images and rebuild a Docker file.
Docker Compose Versions/Types
Docker compose can be installed as a specific program and run as docker-compose
to it can be run as an add-in to docker and run as docker compose
. Not sure of the advantages of one over the other, however the latest version of the separate program docker-compose
can be directly downloaded as described below, whereas the docker compose
add-in is via distribution package manager. Ultimately both methods seem to be functional.
Installation / Update
To check current version: docker-compose --version
The latest version of docker-compose can be check here: git hub docker compose releases change the version sub-directory as required.
sudo curl -L "https://github.com/docker/compose/releases/download/v2.32.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose
- Install Docker Engine : Docker Engine
Networking
By default Docker-Compose will create a new network for the given compose file. You can change the behavior by defining custom networks in your compose file.
Create and assign custom network
*Example:*
networks: custom-network: services: app: networks: - custom-network
Use existing networks
If you want to use an existing Docker network for your compose files, you can add the `external: true` parameter in your compose file *Example:*
networks: existing-network: external: true
Volumes
Volumes allow Docker containers to use persistent storage. In a compose file, you can create and map volumes like this:
volumes: my-volume: services: app: volumes: - my-volume:/path-in-container
These volumes are stored in `/var/lib/docker/volumes`.
Docker external named volumes
Docker compose external named volumes can be used across the Docker installation and they need to be created by the user (otherwise fails) using the docker volume create command. (References: Volumes in Docker Compose tutorial, Using volumes in Docker Compose)
Example:
Defines web_data volume:
docker volume create --driver local \ --opt type=none \ --opt device="/var/opt/my_website/dist" \ --opt o=bind web_data
docker-compose.yml file with a named volume web_data defined externally:
version '3' volumes: web_data: external: true services: app: image: nginx:alpine ports: - 80:80 volumes: - web_data:/usr/share/nginx/html:ro
There are different volume types like nfs, btrfs, ext3, ext4, and also 3rd party plugins to create volumes.
External named volumes can be defined dynamically from environment variables using a name section as we did in the previous example.
NFS File System not ready
It is amazing for how long I put up with this before fixing it. Every time I booted the main server VM Traefik would fail. All the other services that relied on Traefik would not operate. A simple start/restart of Traefik always worked. Most of the other Docker containers that relied upon Traefik needed to be restarted too. It was annoying and made me doubt that my Docker system was ready for “production” although I had been using a couple containers for a couple of months.
I have my docker working directory on an NFS share directory. Unfortunately after a reboot docker compose Trafik would fail on start up with obscure Docker log messages (sudo journalctl -b0 -u docker
), e.g. error=“failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during cont
with reference to mount a volume, sorry the message was too long to file and I did not get full copy. The log message volume that failed also changed. This lead me to believe a possible problem with Docker starting up before the NFS network file system was ready. So I did the following.
- Found the systemd unit name for the drive mount using:
systemctl list-units –type=mount
, in my particular case it wasmnt-docker_store.mount
for/mnt/docker_store
- Updated the systemd service for Docker
- use systemctl status docker to find the service file, in my case
/lib/systemd/system/docker.service
- edit the systemd file and add mount unit found to the [Unit] After and Requires directives. You are not meant to directly edit the service file, but rather use the
sudo systemctl edit docker.service
to create a drop in replacement file.
- After this reboot to test. (Yes you can use
sudo systemctl daemon-reload
, however I wanted to test boot performance, so a reboot is necessary anyway.)
Example: This is the existing unchanged service:
/lib/systemd/system/docker.service
The override file for docker.service below has some additional services under [Unit] defined that must be running before before docker can be started. In addition I added a further 10 seconds wait to allow system undeer [Service] to stabilise as an ExecStartPre
before starting docker.
systemctl show docker.service
shows the service definition, it looks like it shows all dependencies, not just main service file ones.
References
- Docker