0

I have one container I would like to have a fixed IP.

My relevant setup (docker-compose) is the following:

version: '3'

networks:
  default:
    external:
      name: srv

services:

  caddy:
    image: caddy
    container_name: caddy
    volumes:
      - /etc/docker/data/caddy/Caddyfile:/etc/caddy/Caddyfile
      - /etc/docker/data/caddy/data:/data
      - /etc/docker/data/caddy/config:/config
    ports:
      - 80:80
      - 443:443
      - 2015:2015
    environment:
      - ACME_AGREE=true
    restart: unless-stopped
    # networks:
    #   srv:
    #     ipv4_address: 172.19.0.254

When the last lines are commented out, everything is fine. When I uncomment them, restarting the caddy container yields the error

ERROR: Service "caddy" uses an undefined network "srv"

Inspecting the caddy container when it runs correctly:

~ # docker inspect caddy
[
    {
        "Id": "37904d87c82c4612f48bcc9952b6505d871a816336c6b242b4ab3fae51cbfa95",
        "Created": "2021-01-25T18:27:29.686179872Z",
        "Path": "caddy",
(...)        

        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "1a4360ebfe25eff6dffec0f9ec049389da6e53e84eaf76db23bf6028868b31f3",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "2015/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "2015"
                    }
                ],
                "2019/tcp": null,
                "443/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "443"
                    }
                ],
                "80/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "80"
                    }
                ]
            },
            "SandboxKey": "/var/run/docker/netns/1a4360ebfe25",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "srv": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "caddy",
                        "37904d87c82c"
                    ],
                    "NetworkID": "36b7471fa0f16a74531b011ce6762cf66a802fda7622d70d66b6fb130a2398ea",
                    "EndpointID": "8dea6be732eda01a9b4d6cc0a26df2eca8a6df1a6f6d7a961fb46820a6ef9d58",
                    "Gateway": "172.19.0.1",
                    "IPAddress": "172.19.0.8",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:13:00:08",
                    "DriverOpts": null
                }
            }
        }
    }
]

How can I force that container to use a fixed IP?

Note: a similarly titled question (ERROR: Service "xxx" uses an undefined network "xxx") addresses the lack of a definition of the network (not my case)

WoJ
  • 27,165
  • 48
  • 180
  • 345

2 Answers2

1

When you say at the top level

networks:
  default: { ... }

then when you explicitly refer to that network in per-service configuration it needs to use the matching Compose name default

networks:
  # vvv the name of the top-level `networks:` item
  #     (probably different from the `docker network create` name)
  default:
    ipv4_address: 172.19.0.254

The "real" Docker name of the network doesn't matter here; within the Compose file you always use the name under the top-level networks: block.

(Explicitly setting a container's private IPv4 address is a little unusual and you shouldn't usually need to do it. If you don't have a per-service networks: it will connect by default to the default network, even if you've manually reconfigured that network at the top level.)

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • OK, so `default` is not a keyword but a name of a network? I that case why all my containers are in the network `srv` (according to portainer: https://imgur.com/a/bayjHZV) – WoJ Jan 25 '21 at 19:50
  • @timsmelik: isn't the default one `default_docker`? – WoJ Jan 25 '21 at 19:56
  • *"Explicitly setting a container's private IPv4 address is a little unusual"* → yes, I know but I need that specific one to never change because I need to refer to it by IP from another container (and not by name). This is very annoying but at least this is just one. – WoJ Jan 25 '21 at 19:59
  • @WoJ it actually depends on the project name (which by default is the name of the folder your docker-compose file is in; I'm guessing yours is `docker`), but you're right, it does not use `default` as name but prefixes it with `projectname_`. – timsmelik Jan 25 '21 at 20:05
  • `default` is the Compose name of a network, and if you configure it with an `external: { name: srv }` it will use that network instead of creating a new one. – David Maze Jan 25 '21 at 20:40
0

The caddy service does not use the external name of the network, but just sees default. Try updating the network definition:

networks:
  srv:
    external: true

Check the Compose file version 3 reference:

You can also specify the name of the network separately from the name used to refer to it within the Compose file:

version: "3.9"
networks:
  outside:
    external:
      name: actual-name-of-network
timsmelik
  • 732
  • 3
  • 11