Docker-compose invalid. Additional properties are not allowed

Viewed 7963

Here is my docker-compose.yml:

version: "3.0"
services:
  control_node:
      hostname: controlnode
      container_name: controlnode
      build: ./control_node/
      command: tail -F anything
      privileged: true
      volumes:
      - ${CONTROL_NODE_SSH}:/home/ansible/.ssh
      - ${SHARED_FOLDER}:/shared
      networks:   
        labnet.io:
            ipv4_address: 10.10.0.2

  ubuntu-a:
      hostname: ubuntu-a   
      container_name: ubuntu-a
      build: ./ubuntu/
      command: tail -F anything
      ports:
      - ${UBUNTU_A_WEBSERVER_PORT}:80
      privileged: true
      volumes:
      - ${UBUNTU_A_SSH}:/home/ansible/.ssh
      - ${SHARED_FOLDER}/shared:/shared
      networks:   
        labnet.io:
            ipv4_address: 10.10.0.3

  ubuntu-b:
      hostname: ubuntu-b   
      container_name: ubuntu-b
      build: ./ubuntu/
      command: tail -F anything
      ports:
      - ${UBUNTU_B_APPSERVER_PORT}:8080
      privileged: true
      volumes:
      - ${UBUNTU_B_SSH}:/home/ansible/.ssh
      - ${SHARED_FOLDER}/shared:/shared
      networks:   
        labnet.io:
            ipv4_address: 10.10.0.4

  ubuntu-c:
      hostname: ubuntu-c   
      container_name: ubuntu-c
      build: ./ubuntu/
      command: tail -F anything
      ports:
      - ${UBUNTU_C_WEBSERVER_PORT}:80
      privileged: true
      volumes:
      - ${UBUNTU_C_SSH}:/home/ansible/.ssh
      - ${SHARED_FOLDER}/shared:/shared
      networks:   
        labnet.io:
            ipv4_address: 10.10.0.5

  ubuntu-d:
      hostname: ubuntu-d   
      container_name: ubuntu-d
      build: ./ubuntu/
      command: tail -F anything
      ports:
      - ${UBUNTU_D_APPSERVER_PORT}:8080
      privileged: true
      volumes:
      - ${UBUNTU_D_SSH}:/home/ansible/.ssh
      - ${SHARED_FOLDER}/shared:/shared
      networks:   
        labnet.io:
            ipv4_address: 10.10.0.6

networks:   
  labnet.io:
    name: labnet.io
    driver: bridge
    ipam:
     config:
       - subnet: 10.10.0.0/16
         gateway: 10.10.0.1

When I run docker-compose up -d, I get:

ERROR: The Compose file './docker-compose.yml' is invalid because:
networks.labnet.io.ipam.config value Additional properties are not allowed ('gateway' was unexpected)
networks.labnet.io value Additional properties are not allowed ('name' was unexpected)

2 Answers

Edit: Releases 1.27.0+ have merged v2/v3 file formats, as you can see in https://github.com/docker/compose/releases So, the version property is now only informative.

However, as mention by BMitch, if support to swarm mode is needed, the field gateway can't be in compose-file because is not supported in version 3 syntax.


I had the same problem here with docker-compose version 1.25.5, but no longer in 1.29.2.

version: '3'
networks:
        nginx_net:
                driver: bridge
                ipam:
                        driver: default
                        config:
                                - gateway: "192.168.0.254"
                                  subnet: "192.168.0.0/24"

...

docker network inspect compose_nginx_net
[
    {
        "Name": "compose_nginx_net",
        "Id": "2137c736e0c56d90cbc657a6a9f819a117edb273fdde1a4963ee68769901d368",
        "Created": "2021-12-12T14:42:15.33387384Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "192.168.0.0/24",
                    "Gateway": "192.168.0.254"
                }
            ]
        },
...

In the v3 syntax, the gateway field is not supported:

Additional IPAM configurations, such as gateway, are only honored for version 2 at the moment.

Source: https://docs.docker.com/compose/compose-file/compose-file-v3/#ipam

However, setting static IPs on your containers is a strong code smell, it indicates your attempting to treat containers as small VMs, and that's the wrong design for working with containers. Same goes for setting a container name. Doing this breaks the ability to update the container without some kind of outage because you have to stop the old container and delete it to free the IP and name. Unless you need privileged, I'd also remove that. If you don't need write access to the ssh keys, only mount those read only. I'd move the command to be part of your image definition. And you should define your image name with your hub username (or local registry). The result looks like:

version: "3.0"
services:
  control_node:
      image: username/control:latest
      build: ./control_node/
      volumes:
      - ${CONTROL_NODE_SSH}:/home/ansible/.ssh:ro
      - ${SHARED_FOLDER}:/shared

  ubuntu-a:
      image: username/ubuntu:latest
      build: ./ubuntu/
      ports:
      - ${UBUNTU_A_WEBSERVER_PORT}:80
      volumes:
      - ${UBUNTU_A_SSH}:/home/ansible/.ssh:ro
      - ${SHARED_FOLDER}/shared:/shared

  ubuntu-b:
      image: username/ubuntu:latest
      build: ./ubuntu/
      ports:
      - ${UBUNTU_B_APPSERVER_PORT}:8080
      volumes:
      - ${UBUNTU_B_SSH}:/home/ansible/.ssh:ro
      - ${SHARED_FOLDER}/shared:/shared

  ubuntu-c:
      image: username/ubuntu:latest
      build: ./ubuntu/
      ports:
      - ${UBUNTU_C_WEBSERVER_PORT}:80
      volumes:
      - ${UBUNTU_C_SSH}:/home/ansible/.ssh:ro
      - ${SHARED_FOLDER}/shared:/shared

  ubuntu-d:
      image: username/ubuntu:latest
      build: ./ubuntu/
      ports:
      - ${UBUNTU_D_APPSERVER_PORT}:8080
      volumes:
      - ${UBUNTU_D_SSH}:/home/ansible/.ssh:ro
      - ${SHARED_FOLDER}/shared:/shared

Lastly, I'll add that many of the things you are trying to do don't seem appropriate for Swarm Mode which is the reason for the version 3 syntax. If you don't need to support Swarm Mode, then one of the version 2 formats would likely be more appropriate for your use case.

Related