community.docker icon indicating copy to clipboard operation
community.docker copied to clipboard

Some images do not return a valid Config object causing an AttributeError: 'NoneType' object has no attribute 'get'

Open mrvanes opened this issue 5 months ago • 17 comments

SUMMARY

Starting a running container using community.docker.docker_container causes this error:

fatal: [docker1.vm.scz-vm.net]: FAILED! => changed=false 
  msg: 'Task failed: Module failed: ''NoneType'' object has no attribute ''get'''
ISSUE TYPE
  • Bug Report
COMPONENT NAME

community.docker.docker_container:

ANSIBLE VERSION
ansible [core 2.19.0]
  config file = /home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg
  configured module search path = ['/home/martin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  ansible collection location = /home/martin/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.13.7 (main, Aug 20 2025, 22:17:40) [GCC 15.2.0] (/usr/bin/python3)
  jinja version = 3.1.6
  pyyaml version = 6.0.2 (with libyaml v0.2.5)
COLLECTION VERSION
# /home/martin/.ansible/collections/ansible_collections
Collection       Version
---------------- -------
community.docker 3.13.10

# /usr/lib/python3/dist-packages/ansible_collections
Collection       Version
---------------- -------
community.docker 4.6.1  
CONFIGURATION
CACHE_PLUGIN(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = yaml
CACHE_PLUGIN_CONNECTION(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = .ansible/facts
CALLBACKS_ENABLED(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = ['profile_tasks']
CONFIG_FILE() = /home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg
DEFAULT_BECOME(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = True
DEFAULT_FORKS(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = 25
DEFAULT_GATHERING(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = smart
DEFAULT_LOAD_CALLBACK_PLUGINS(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = True
DEFAULT_STDOUT_CALLBACK(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = yaml
DEFAULT_UNDEFINED_VAR_BEHAVIOR(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = True
DEPRECATION_WARNINGS(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = True
HOST_KEY_CHECKING(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = False
INTERPRETER_PYTHON(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = /usr/bin/python3
MAX_FILE_SIZE_FOR_DIFF(/home/martin/Projects/SURF/SRAM/SRAM-deploy/ansible.cfg) = 1044480
OS / ENVIRONMENT

Linux Ubuntu 25.10

STEPS TO REPRODUCE
  • Have community.docker.docker_container task to start a container
  • Run playbook
  • Experience crash
- name: "Create the pyFF container"
  community.docker.docker_container:
    name: "{{ containers.pyff }}"
    image: "{{ images.pyff }}"
    restart_policy: "always"
    state: "started"
    pull: true
    init: true
    env:
      USER: "{{ metadata_user_uid | string }}"
      GROUP: "{{ metadata_group_gid | string }}"
    mounts:
      - source: "{{ metadata_basedir }}/web"
        target: "/opt/pyff/web"
        type: "bind"
      - source: "{{ metadata_basedir }}/feeds"
        target: "/opt/pyff/feeds"
        type: "bind"
        read_only: true
      - source: "{{ metadata_basedir }}/src"
        target: "/opt/pyff/src"
        type: "bind"
        read_only: true
      - source: "{{ metadata_basedir }}/certs"
        target: "/opt/pyff/certs"
        type: "bind"
        read_only: true
      - source: "{{ metadata_basedir }}/xslt"
        target: "/opt/pyff/xslt"
        type: "bind"
        read_only: true
    healthcheck:
      test:
        - "CMD"
        - "bash"
        - "-c"
        - "[[ $(($(date +%s)-$(date -r /opt/pyff/web/idps.xml +%s))) -lt 400 ]]"
      interval: "10s"
      timeout: "5s"
      retries: 3
      start_period: "5s"
EXPECTED RESULTS

Started container

ACTUAL RESULTS
[ERROR]: Task failed: Module failed: 'NoneType' object has no attribute 'get'
Origin: /home/martin/Projects/SURF/SRAM/SRAM-deploy/roles/docker_metadata/tasks/pyff.yml:66:3

64   notify: "Restart the pyFF container"
65
66 - name: "Create the pyFF container"
     ^ column 3

fatal: [docker1.vm.scz-vm.net]: FAILED! => changed=false 
  msg: 'Task failed: Module failed: ''NoneType'' object has no attribute ''get'''

The problem is in line 663 of module_container/docker_api.py:

    if image and image['Config'].get('Env'):

In docker 29, the image object api contains null for Config, so it can't get 'Env':

# docker inspect ghcr.io/surfscz/sram-pyff:main
[
    {
        "Id": "sha256:5afcd4f96dc2970611c8446e11494c65bb36e2f5790be19a76033b3152de6bcf",
        "RepoTags": [
            "ghcr.io/surfscz/sram-pyff:main"
        ],
        "RepoDigests": [
            "ghcr.io/surfscz/sram-pyff@sha256:5afcd4f96dc2970611c8446e11494c65bb36e2f5790be19a76033b3152de6bcf"
        ],
        "Config": null,
        "Architecture": "",
        "Os": "",
        "Size": 96404588,
        "RootFS": {},
        "Metadata": {
            "LastTagTime": "2025-11-20T07:10:44.519152963Z"
        },
        "Descriptor": {
            "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
            "digest": "sha256:5afcd4f96dc2970611c8446e11494c65bb36e2f5790be19a76033b3152de6bcf",
            "size": 3232
        }
    }
]

After changing 663 to this:

    if image and image.get('Config') is not None:
        if image['Config'].get('Env'):

and 986 to this:

    if image and image.get('Config') is not None:

and 1006 to:

    if image and image.get('Config') is not None:

and 1210 to:

    if image and image.get('Config') is not None:

.... everything works as expected.

mrvanes avatar Nov 20 '25 08:11 mrvanes

This seems to be a bug in Docker 29 when migrating from earlier versions, see #1194. Try to re-pull the image.

(Simply ignoring this in the code is the wrong approach, your containers likely end up in a wrong state since some of their configuration is missing.)

felixfontein avatar Nov 21 '25 05:11 felixfontein

No, removing the image doesn't help. docker_container will always fail the second run and the image inspect is again incomplete. What's interesting is that docker says the image is the only one not "In Use" by any container (signified by the U behind the image name), which simply isn't true?

mrvanes avatar Nov 21 '25 08:11 mrvanes

Here's a Docker bug report for this issue: https://github.com/moby/moby/issues/51566

felixfontein avatar Nov 21 '25 12:11 felixfontein

(According to the API docs: https://docs.docker.com/reference/api/engine/version/v1.52/#tag/Image/operation/ImageInspect the Config field never should be null.)

felixfontein avatar Nov 21 '25 12:11 felixfontein

@mrvanes I am trying this:

  • removing containerd.io
  • removing /var/lib/containerd
  • reinstalling containerd.io

Note that I am using the containerd backing store to ensure I can build multi-platform images:

❯ cat --plain /etc/docker/daemon.json
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3",
    "tag": "{{.Name}}/{{.ImageName}}"
  },
  "ipv6": true,
  "fixed-cidr-v6": "<NOMNOMNOM>",
  "features": {
    "containerd-snapshotter": true
  }
}

kristof-mattei avatar Nov 21 '25 21:11 kristof-mattei

Ignore above, still fails.

This feels weirdly relevant: https://github.com/moby/moby/issues/51532

kristof-mattei avatar Nov 21 '25 21:11 kristof-mattei

Thx for your time and apologies for assuming this was a docker_container issue. I agree https://github.com/moby/moby/issues/51566 looks like the most likely candidate for my problems!

mrvanes avatar Nov 25 '25 09:11 mrvanes

No worries. It's far from obvious that this isn't an issue with the module. I first thought that I'd have to fix it, but then I noticed that Config being null is just wrong and means that something is broken with Docker. Making the module accept that will likely screw up your deployments, since (potentially) important image-specific configuration is not used.

felixfontein avatar Nov 25 '25 20:11 felixfontein

We fixed it for now by sticking the "docker host" container to docker 28.

mrvanes avatar Nov 27 '25 17:11 mrvanes

https://github.com/moby/moby/issues/51566#issuecomment-3601718061

Once https://github.com/moby/moby/pull/51629 is released I'll bump docker-ce and report back here.

kristof-mattei avatar Dec 02 '25 18:12 kristof-mattei

29.1.2 is out with that fix: https://github.com/moby/moby/releases/tag/docker-v29.1.2

felixfontein avatar Dec 03 '25 05:12 felixfontein

29.1.2 is out with that fix: https://github.com/moby/moby/releases/tag/docker-v29.1.2

Let me run a test. I'll report back. If I don't report back, it means my home DNS is down.

kristof-mattei avatar Dec 03 '25 16:12 kristof-mattei

Still works here. I'll let it run for a day or 2 and report back.

kristof-mattei avatar Dec 03 '25 17:12 kristof-mattei

With "still works here", you mean the problem is still there, or that it seems to be gone and it's working as before 29.0.0?

felixfontein avatar Dec 03 '25 17:12 felixfontein

With "still works here", you mean the problem is still there, or that it seems to be gone and it's working as before 29.0.0?

Sorry, I should've been more explicit.

I installed 29.1.2 and the bug in this issue (#1206) is gone.

kristof-mattei avatar Dec 03 '25 21:12 kristof-mattei

And last update from me: One of the container that always was giving me issues (see https://github.com/ansible-collections/community.docker/issues/1194) updated this morning, and the ansible scripts ran without any problems.

kristof-mattei avatar Dec 04 '25 17:12 kristof-mattei

@kristof-mattei that's great to hear!

felixfontein avatar Dec 04 '25 19:12 felixfontein