Trouble running UPNP on Docker

7.4k Views Asked by At

I trying to run an UPnP service on my docker container using the Cling UPNP library (http://4thline.org/projects/cling/). There is a simple program that creates a device (in software) that hosts some service. This is written in Java and when I try to run the program I get the following exception (Note: This runs perfectly fine directly on my Ubuntu machine):

Jun 5, 2015 1:47:24 AM org.teleal.cling.UpnpServiceImpl <init>
INFO: >>> Starting UPnP service...
Jun 5, 2015 1:47:24 AM org.teleal.cling.UpnpServiceImpl <init>
INFO: Using configuration: org.teleal.cling.DefaultUpnpServiceConfiguration
Jun 5, 2015 1:47:24 AM org.teleal.cling.transport.RouterImpl <init>
INFO: Creating Router: org.teleal.cling.transport.RouterImpl
Exception occured: org.teleal.cling.transport.spi.InitializationException: Could not discover any bindable network interfaces and/or addresses
org.teleal.cling.transport.spi.InitializationException: **Could not discover any bindable network interfaces and/or addresses
    at org.teleal.cling.transport.impl.NetworkAddressFactoryImpl.<init>(NetworkAddressFactoryImpl.java:99)**
1

There are 1 best solutions below

1
On

For anyone that finds this and needs the answer.

Your container is obscuring your external network. In other words, by default containers are isolated and cannot see the outer network which is of course required in order to open the ports in your IGD.

You can run your container as a "host" to make it non isolated, simply add --network host to your container creation command.

Example (taken from https://docs.docker.com/network/network-tutorial-host/#procedure):

docker run --rm -d --network host --name my_nginx nginx

I have tested this using docker-compose.yml which looks a bit different:

version: "3.4"
services:
  upnp:
    container_name: upnp
    restart: on-failure:10
    network_mode: host  # works while the container runs
    build:
      context: .
      network: host  # works during the build if needed

version 3.4 is very important and the network: host will not work otherwise!

My upnp container Dockerfile looks like so:

FROM alpine:latest

RUN apk update
RUN apk add bash
RUN apk add miniupnpc

RUN mkdir /scripts
WORKDIR /scripts
COPY update_upnp .
RUN chmod a+x ./update_upnp

# cron to update each UPnP entries every 10 minutes
RUN echo -e "*/10\t*\t*\t*\t*\tbash /scripts/update_upnp 8080 TCP" >> /etc/crontabs/root

CMD ["crond", "-f"]

# on start, open needed ports
ENTRYPOINT bash update_upnp 80 TCP && bash update_upnp 8080 TCP

update_upnp script is simply using upnpc (installed as miniupnpc in the Dockerfile above) to open the ports.

Hopefully this will help somebody.

Edit: Here is how update_upnp script may look like:

#!/bin/bash

port=$1
protocol=$2
echo "Updating UPnP entry with port [$port] and protocol [$protocol]"

gateway=$(ip route | head -1 | awk '{print $3}')
echo "Detected gateway is [$gateway]"

# port - e.g. 80
# protocol - TCP or UDP
upnpc -e 'your-app-name' -r $port $protocol

echo "Done updating UPnP entry with port [$port] and protocol [$protocol]"