Quickly expose Docker ports
When running Docker containers you can easily publish ports on the container level or directly onto the host system so the service could be accessible from outsite (internet). This is true for systems that need to be exposed publicly, like web servers, however it's highly recommended to keep all sensitive services (like Redis) only available on the local network due to security risks.
Let's say you start Redis daemon in the container with the following command:
docker run -d --restart=always --name=redis redis
Redis container will be started in the background and expose ony 1 port. Check it
docker ps command:
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES 8648ad732d40 redis "docker-entrypoint.s…" Up 7 minutes 6379/tcp redis
In case if you wanted to expose Redis to the public for troubleshooting you'd have to remove and create a new container. That won't work since all the data and logs will be lost. So we need to somehow temporarily expose the container to the public net. Here's when socat might come handy.
The goal is to create a new container (socat) that will talk to our redis service
over the same docker network. There's already a socat docker image:
we'll just use that. The following command should spawn the "proxy" container:
docker run \ -d \ --link=redis \ -p 16379:6379 \ --name=redis-public \ alpine/socat \ TCP4-LISTEN:6379,fork,reuseaddr TCP4:redis:6379
We are exposing port 16379 on the host system so that it won't be picked up by
the network scanners right away, but you can pick any port you'd like. Check if our
proxy is up with
CONTAINER ID IMAGE COMMAND STATUS PORTS NAMES 17322b86a601 alpine/socat "socat TCP4-LISTEN:6…" Up 1 second 0.0.0.0:16379->6379/tcp redis-public 8648ad732d40 redis "docker-entrypoint.s…" Up 12 minutes 6379/tcp redis
Now we can access the redis container via the proxy:
telnet localhost 16379 Trying ::1... Connected to localhost. Escape character is '^]'. info $2643 # Server redis_version:4.0.7 redis_git_sha1:00000000 redis_git_dirty:0 redis_build_id:b6959c1042901757 # ... other stuff
Cool, so it works. Same process works if you want to connect to the remote host:
telnet public-ip 16379. Once we're done troubleshooting the issues (or whatever),
simply kill the container:
docker rm -f redis-public
All of above should work with any type of service (PostegreSQL, http servers, etc) as long as they run over TCP protocol.