"bind: address already in use" while starting a docker container via a systemd socket listening on the container's port

Viewed 185

In order to avoid starting docker and a pgadmin container at boot, I'm trying to trigger the start of the container using a systemd socket listening on the container's port (49490) on localhost. This way the first time I connect to 127.0.0.1:49490, docker is launched and the corresponding container is started, and I access the container using this address.

But the service fails with the following error when I connect to 127.0.0.1:49490:

error="driver failed programming external connectivity on endpoint pgadmin (b4e312dd8eac82923f7b8f7a6e89f9c5ee0a42eb48e549594ec1a63b8568a669): Error starting userland proxy: listen tcp4 0.0.0.0:49490: bind: address already in use"

I have configured the corresponding service and socket as follows:

/etc/systemd/system/pgadmin.socket:

[Unit]
Description=Socket to trigger the launch of pgadmin via docker
PartOf=pgadmin.service

[Socket]
ListenStream=127.0.0.1:49490

[Install]
WantedBy=sockets.target

/etc/systemd/system/pgadmin.socket:

[Unit]
Description=Launching pgadmin with docker
After=network.target pgadmin.socket
Requires=pgadmin.socket

[Service]
Type=simple
ExecStart=docker start -a pgadmin
TimeoutSec=15s

[Install]
WantedBy=multi-user.target

For what it's worth, here is the docker-compose.yaml file I used to create the container:

version: '3.8'

services:
  pgadmin:
    restart: always
    image: dpage/pgadmin4:latest
    container_name: pgadmin
    environment:
      PGADMIN_DEFAULT_EMAIL: "******"
      PGADMIN_DEFAULT_PASSWORD: "******"
    ports:
      - "49490:80"
    volumes:
      - data:/var/lib/pgadmin

volumes:
    data:

When I connect to 127.0.0.1:49490 with my browser, the pgadmin.service fails with the error message at the top of this post. And the pgadmin.socket fails with the error message Failed with result 'service-start-limit-hit'.

Here is the messages returned by sudo systemctl status pgadmin.service:

août 20 08:39:27 my-machine systemd[1]: Started Launching pgadmin with docker
août 20 08:39:27 my-machine docker[8755]: time="2021-08-20T08:39:27+02:00" level=error msg="error waiting for container: context canceled"
août 20 08:39:27 my-machine docker[8755]: Error response from daemon: driver failed programming external connectivity on endpoint pgadmin (41e1790973e3464edab122ce66031fe254cd7f43a57cfc8e0168b636f02831f1): Error starting userland proxy: listen tcp4 0.0.0.0:49490: bind: address already in use
août 20 08:39:27 my-machine systemd[1]: pgadmin.service: Main process exited, code=exited, status=1/FAILURE
août 20 08:39:27 my-machine systemd[1]: pgadmin.service: Failed with result 'exit-code'.
août 20 08:39:27 my-machine systemd[1]: pgadmin.service: Start request repeated too quickly.
août 20 08:39:27 my-machine systemd[1]: pgadmin.service: Failed with result 'exit-code'.
août 20 08:39:27 my-machine systemd[1]: Failed to start Launching pgadmin with docker

So my guess is that the socket is occupying the port 49490, which prevents the container to use it. To make sure that the problem comes from the port 49490 being already occupied by the systemd socket, I changed it to 49491 in pgadmin.socket, and that way everything works well, except that I have to use one port to trigger the container and another to use it, which is not very convenient.

I'm not really at ease with configuring systemd services and sockets, so I don't know how to make the socket free the port 49490 before calling the service, and I don't even know if it's possible. I tried to set the option ReusePort=True in the socket configuration, but it didn't change anything. Can anyone tell me what is a right way to do what I want?

I don't know if it's relevant, but my machine is running under archlinux.

0 Answers
Related