Docker compose restarting service with docker.io/library/ container
Describe the Bug
docker_compose will not register a service as running if one of the containers uses an image in the form docker.io/library/<name>. This seems to be an old format but it is still valid and used (eg. by authentik).
Expected Behavior
The provider should handle prefixes like this and ignore them when looking for running containers. The running container will show <name>:<version> rather than docker.io/library/<name>:<version>.
Steps to Reproduce
Steps to reproduce the behavior:
- Deploy authentik with the
docker_composeresource- Something like
docker_compose { 'authentik':
ensure => present,
compose_files => ['/my.compose.yaml']
}
- Run puppet several times, each time it will report the service is not running and restart it.
Environment
- Version 7.0.0
- Platform Ubuntu 22.04
Additional Context
I followed the authentik docs for setup and then moved the .env and docker-compose.yaml files to puppet
I confirm the bug in version 10.0.1. It is located in lib/puppet/provider/docker_compose/ruby.rb around line 45 in the exists? function.
What's happening?
The function exists? compares the compose.yaml with what is currently running: It executes first:
/usr/bin/docker compose -f compose.yaml -p netbox config
and then fetches the .services[].image (yq query). If you have written docker.io/your-image in your compose.yaml, it will output docker.io/your-image.
Then it executes:
/usr/bin/docker ps --format '{{.Label "com.docker.compose.service"}}-{{.Image}}' --filter label=com.docker.compose.project=your_project_name
this will output the image name of the running container, with docker.io omitted because it's hardcoded as the default provider.
In my case with the netbox stack:
# reading current conf
vm-prod-netbox2 [/srv/netbox]# /usr/bin/docker ps --format '{{.Label "com.docker.compose.service"}}-{{.Image}}' --filter label=com.docker.compose.project=netbox
netbox-housekeeping-netboxcommunity/netbox:v4.1.4-3.0.2
netbox-worker-netboxcommunity/netbox:v4.1.4-3.0.2
nginx-nginx:alpine-slim
netbox-netboxcommunity/netbox:v4.1.4-3.0.2
redis-valkey/valkey:8.0-alpine
postgresql-postgres:13-alpine
redis-cache-valkey/valkey:8.0-alpine
# reading conf from compose.yaml file
vm-prod-netbox2 [/srv/netbox]# /usr/bin/docker compose -f /srv/netbox/compose.yaml -p netbox config | yq .services[].image
netboxcommunity/netbox:v4.1.4-3.0.2
netboxcommunity/netbox:v4.1.4-3.0.2
netboxcommunity/netbox:v4.1.4-3.0.2
nginx:alpine-slim
postgres:13-alpine
docker.io/valkey/valkey:8.0-alpine
docker.io/valkey/valkey:8.0-alpine
exists? tests that count is the same (7 on both side), but images name are not the same, so puppet concludes that the stack must be reapplied. The difference here is on the valkey image.
If I drop the docker.io/ from my compose.yaml, my node changes his status to "UNCHANGED"
Maybe we can use this regexp to "canonicalize" the image name from the config, at the end of the get_image function:
^(?:docker.io\/)?(?:library\/)?(?<image>.+?)(?:\:latest)?$
This regexp
- remove docker.io/ at the beginning
- remove library/ at the beginning
- remove :latest at the end