UPnP with Docker
How-to
Getting straight to the point. How do I set up a docker container to continuously configure UPnP entries to point to the host with configurable ports?
First, you'll need a bash script to execute the required commands to create or update the UPnP entry:
update_upnp
#!/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]"
Second, a Dockerfile with the required packages and configured crontab:
Dockerfile
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 5 minutes
RUN echo -e "*/5\t*\t*\t*\t*\tbash /scripts/update_upnp 8080 TCP" >> /etc/crontabs/root
CMD ["crond", "-f"]
Finally, a docker-compose.yml file (only for reproduceability), that sets the network_mode
of the container to host
.
Without this line, the container would see the docker network default route instead of the real default route and UPnP will not work.
docker-compose.yml
version: "3.4"
services:
upnp:
restart: always
network_mode: host # this is the important line!
build:
context: .