"Ip route add" command

Hi all,

is it possible to run following command in docker compose traefik service?

ip route add [ADDRESS POOL] via [DOCKER NETWORK ADDRESS]

I try to figure it out why I ask this question.

I have traefik configured prefectly, and through file provider, I forward a domain traffic to a LAN device.

I need to add a different address set in order to do that.

What i did (and it works fine) is:

  1. Add following property to traefik service in docker compose cap_add: - NET_ADMIN
  2. Use the traefik container terminal docker-compose exect -it traefik /bin/sh
  3. Run the command I report above

I wish to find a way to do this from docker compose file or, if it is not possible, by create a Dockerfile FROM traefik, but I'm stuck

I'm looking to achieve the same. Have you found a solution?

A container is just a thin layer around an application. It's not a VM, it uses the host OS and networking. So I would assume you need to configure routing on host. Maybe check with the Docker Forum, it's not really a Traefik topic.

Well, although it is a Docker question, it is also related to Traefik...

I have defined a router in my dynamic Traefik config file, which connects to an external service. The IP of this service is a private IP on the other end of a site 2 site Wireguard connection. So Traefik by default can't connect to this service, as the IP is unknown.

When I manually add the route in the Traefik container (with ip route add 192.168.100.0/24 via 172.50.0.2, whereas 192.168.100.0/24 is the IP range of my service and 172.50.0.2 is the IP of my Wireguard container), everything works perfectly and I can access my service through the host/path defined in my Traefik router.

But everytime my Traefik container is recreated, I manually have to add the route mentioned above. Therefore it would be great, if this route could somehow be added when creating the container!

Any ideas on how to achieve this? Or maybe an alternative way to tell Traefik to route requests to 192.168.100.0/24 via the Wireguard container?

Any help is appreciated.

I found a solution.
I create an entrypoint script that I used instead the traefik one.

I bind the volume for init.sh script and I change traefik entrypoint with init.sh script.

The env variable GATEWAYSERVICE is used to resolve container ip inside the script.

The init.sh script is paste below, you can see I put some check for env variables, this is not really necessary.

If you find a more elegant solution, please report here.

traefik:
    image: traefik:v3.0.2
    restart: unless-stopped
    depends_on:
      wireguard:
        condition: service_started
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    networks:
      default:
      traefik:
    environment:
      - NETWORK_MASK=10.0.0.0/24
      - GATEWAYSERVICE=myservice
    security_opt:
      - no-new-privileges:true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/ssl-certs:/ssl-certs
      - ./traefik/init.sh:/init.sh
      - ./traefik/config:/etc/traefik/config
      - ./traefik/ssl-certs:/letsencrypt
    cap_add:
      - NET_ADMIN
    entrypoint: /init.sh
#!/bin/sh
set -e

GATEWAYIP=$(getent hosts "$GATEWAYSERVICE" | awk '{ print $1 }')

echo "NETWORK_MASK: $NETWORK_MASK"
echo "GATEWAYIP: $GATEWAYIP"

if [ -z "$NETWORK_MASK" ]; then
    echo "Error: NETWORK_MASK is not defined." >&2
    exit 1
fi

if [ -z "$GATEWAYIP" ]; then
    echo "Error: GATEWAYIP is not defined." >&2
    exit 1
fi

if ! ip route show | grep -q "$NETWORK_MASK via $GATEWAYIP"; then
    echo "Adding IP route..."
    ip route add "$NETWORK_MASK" via "$GATEWAYIP" dev eth0
else
    echo "IP route already exists."
fi

echo "Starting Traefik..."
exec /entrypoint.sh "$@"

Thanks for sharing your solution, really appreciate it!!

I have assigned a static IP to my Wireguard container, so therefore I can skip the step to resolve the GATEWAYIP. But other than that, your script looks great!

The issue I am having though is that I after the Starting Traefik log message, I am getting the following error message: = '' is not a Traefik command: assuming shell execution.. Any idea what might be causing this? Must have something to do with exec /entrypoint.sh "$@"...

I miss some part of docker-compose.yml

That's happen probably because of I use traefik configuration declared in docker compose like this:

command:
      - --log.level=DEBUG

Are you using static traefik.yml config? In this case probably the input $@ to entrypoint.sh is not correct.

I'm inspecting the entrypoint.sh from repo click here

I guess this is the section might be interesting for you

# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
    set -- traefik "$@"
fi

As far as I understand (I'm not a shell script expert), this snippet check if argument 1 is traefik. If it is not, traefik command is appended here set -- traefik "$@"

So at this point you can try to append the snippet i paste here between this two lines in the init.sh script I paste in previously.

echo "Starting Traefik..."
exec /entrypoint.sh "$@"

Let me know if I'm right

If this solves your problem, reply with the entire and correct init.sh script and solve the topic, so people can copy/paste and use it as is :wink:

Yes, I am using a static traefik.yml config file. Adding set -- traefik "$@" between the two lines solved the issue. Everything is working perfectly now, thank you very much for your help!!!

Here is my adapted init.sh

#!/bin/sh
set -e

# Uncomment the following line, if GATEWAYIP is not defined as .env variable and therefore should be resolved from the service/container
# GATEWAYIP=$(getent hosts "$GATEWAYSERVICE" | awk '{ print $1 }')

echo "NETWORK_MASK: $NETWORK_MASK"
echo "GATEWAYIP: $GATEWAYIP"

if [ -z "$NETWORK_MASK" ]; then
    echo "Error: NETWORK_MASK is not defined." >&2
    exit 1
fi

if [ -z "$GATEWAYIP" ]; then
    echo "Error: GATEWAYIP is not defined." >&2
    exit 1
fi

if ! ip route show | grep -q "$NETWORK_MASK via $GATEWAYIP"; then
    echo "Adding IP route..."
    ip route add "$NETWORK_MASK" via "$GATEWAYIP" #  dev eth4
else
    echo "IP route already exists."
fi

echo "Starting Traefik..."

set -- traefik "$@"

exec /entrypoint.sh "$@"

Edit: As you @greenbeam-ita started the topic, I can't mark it as solved. You will have to do that yourself...

@r748 but you didn't add the condition :rofl:

# first arg is `-f` or `--some-option`
if [ "${1#-}" != "$1" ]; then
    set -- traefik "$@"
fi

This condition is important to allow the script work with all traefik configuration

When using the conditional clause, it doesn't work! The error = '' is not a Traefik command: assuming shell execution then remains.

Without the condition, the Traefik container starts flawlessly!

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.