Proxy ports into a running Docker(-Compose) container
Publishing ports in Docker is done only once at the beginning on the
creation of the container. Yet sometimes there is the need to talk to
the service inside a container, but the container itself does not have
the proper tools to do what you want with it built-in. Yet re-creating
the container just to publish the ports, maybe manifesting it
temporarily in some docker-compose.yml
, and then forgetting about it
to open up some security problem is not great.
So the following script allows to temporally proxy to a port of
a running container, whether for manually ran containers or the ones in
a network from Docker-Compose. It tries to find the network and
attaches to it, unless it's bridge
, and uses a socat
to run the
proxy. The arguments are the container name or ID, the port to proxy
to, and an optional port where to publish (if not given, Docker will
pick one).
#!/bin/sh set -eu if test ! "$#" -ge 2; then echo "$0 <container> <target_port> (<local_port>)" exit 1 fi container="$1" port="$2" network=$(docker inspect --format '{{range $k,$v:= .NetworkSettings.Networks}}{{println $k}}{{end}}' "$container" | head -n1) inner_port=8080 publish="$inner_port" if test "$#" -ge 3; then publish="$3:$publish" fi docker run \ --rm \ --publish="$publish" \ --link="$container:target" \ $(if test "$network" != "bridge"; then echo "--network=$network"; fi) \ alpine/socat \ "tcp-listen:$inner_port,fork,reuseaddr" \ "tcp-connect:target:$port"