life coded

a personal blog by Maximilian Ehlers

Security and convenience with Docker private networks

Docker is great, and I do not want to write much about what it does, but rather a problem that I have faced in my setup.

What I wanted to do was hosting a webserver inside of 1 container and a git client ( in another. The webserver should be able to proxy requests from a certain url to the git client.

First attempt

What I did first was exposing a port on my git client as follows:

docker run -d --name=gitea -p

and then proxying the requests to localhost:3000.

While this works it has quite a big flaw in my setup. Namely my firewall settings with ufw are being overwritten and port 3000 is reachable from the outside, while I only want to expose Ports 80 and 443, which will then do the proxying.


After some digging I came upon private networks in Docker. This basically puts containers that you specify into their own subnet where they can find each other by name and the ports they use are reachable.

Initialize the network

To setup a private network just run the following command (use the parameters that fit your style):
docker network create --driver bridge --subnet --gateway first_private_network

Adding container to network

The only addition to the command I have used above to get gitea running is --network=first_private_network.
Adding this when starting your containers will put them into the private network.

When doing this with both the webserver and the git client you can now do the following (this is for nginx) :

location /url {
  proxy_pass http://gitea:3000

Now scan port 3000 on your server (tutorial with nmap). It should be closed and everything is fine again.

Take away

Using a private network for services that have to communicate with each other seems to be the most convenient method, as DNS is provided and you can just call the services by the name you specified.

More importantly though you can also be assured that no firewall rules will be overwritten and that your initial security setup will stay in place, which is why I wrote this post in the first place :).