This won’t be an expert breakdown of the problem but I hope it will help those of you that are attempting to accomplish the same goal. I’m still familiarizing myself with Docker, Docker Compose, Portainer and Nginx Proxy Manager, so at this point I know enough to be dangerous.

Initially, as I started out, I allowed various containers to have ports exposed from the host. This server is effectively private and only accessible to clients on my local network. But one can never be too cautious and the last thing I would want is malware on my network to find and exploit any vulnerable applications.

After about a month of adding software to the server, I decided it was time to start tightening things down a bit. At first, I thought it would be as simple as specifying 127.0.0.1 or localhost to attach the ports to, but that wasn’t the case.

This is where my knowledge drops off and I’m not able to explain why neither would work. I think it’s an internal name resolution issue or maybe a context issue regarding which host is interpreted as being localhost on the Nginx Proxy Manager side.

The solution? Fully remove the port declarations from the Docker Compose statements, add a hostname declaration and provide access to the same network used by NPM.

For example, starting with this:

services:
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    ports:
    - 8088:80

And changing it to the lines below. I recommend commenting the lines out first, rather than removing them, until you know it’s working but I did not show that in this example.

services:
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    hostname: pma_app
    networks:
      - nginx_default
networks:
  nginx_default:
    external: true

Adding the network for NPM to the same Docker Compose will enable the two containers to communicate with each other without exposing ports on the host.

Then, in Nginx Proxy Manager, for the host field use the hostname that you specified in the Docker Compose. Even though you aren’t exposing the ports to your network they will be accessible to NPM.

It seems that in most cases the port that you need to specify in NPM will correspond to the same port number that would have previously been exposed for the container. That isn’t always the case, though, and it can be helpful in those scenarios to review the container’s logs.

Note that specifying the same port in different NPM proxy host entries in this way won’t conflict. Unlike with exposed ports on the host, you can use the same port for different applications but again, referencing it via the hostname is key.

After making these changes to the containers that do not need to communicate with anything outside of the host, I’ve slightly hardened this server.

I did not do this for all container-based applications as some need to be more accessible to remote clients with ports that aren’t used for HTTP/HTTPS traffic. The Stream feature of NPM may provide a way to handle those applications more securely, but I haven’t jumped into that, yet.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

I’m Mike

Welcome to my blog, which I have maintained for several years, off and on, to share things that I’ve learned from numerous projects and various problem solving escapades. This is my way of giving something back to the online communities that have helped me learn more about a wide variety of topics.