In this article, we will:
Now we can do something cool. With all of our services in the reverse proxy network, we can now get our management interfaces protected! Even the reverse proxy! This is fantastic as it allows us to tunnel all of our admin interfaces behind validated SSL and protect them with IP whitelisting.
Let’s make 3 more subdomains in our DNS:
portainer.<your-domain>.<tld>
npm.<your-domain>.<tld>
<your-docker-host>.<your-domain>.<tld>
(this guide uses cbdocker02
as it’s hostname)in OPNsense, since they’re all the same IP we can do so using aliases
npm.<your-domain>.<tld>
on http, pointing to nginx-proxy-manager
on port 81
. Set the access list to local subnets
(management interfaces should not be exposed to the web, except with great discretion).portainer.<yourdomain>.<tld>
note the fact that we’re proxying to an https endpoint this time.<your-host>.<your-domain>.<tld>
for cockpit (on port 9090).Note that we are reverse proxying to the same domain address (since it should resolve back to our host IP). We are also setting the Scheme to HTTPS, same as portainer.
Oops, we missed a step. Even though we are reverse proxying to portainer, portainer isn’t on the same network! Let’s fix that. in cockpit, navigate to /mnt/containers/portainer
and update the docker-compose.yaml
. Let’s comment out the port exposure at the same time:
services:
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: always
privileged: true
volumes:
- /mnt/containers/portainer/container-data/data:/data:Z
- /var/run/docker.sock:/var/run/docker.sock:Z
# ports:
# - 9443:9443
networks:
- reverseproxy-nw
networks:
reverseproxy-nw:
external: true
You can see me do that below using mc and micro:
At the start of the animation, you can see me uncheck use internal editor. This tells mc to default to micro as the editor.
Let’s now verify that you can access https://portainer.<yourdomain>.<tld>
, https://<your-host>.<your-domain>.<tld>
and https://npm.<yourdomain>.<tld>
. You can see me do that in the animation below:
Success! We are now proxying all of our web admin interfaces behind nginx proxy manager, and restricting those interfaces to local IPs.
The eagle eyed of you may notice the ‘login with oauth’ prompt for portainer. I may have been reading a bit ahead when creating this animation. We’ll get there!
Now log into portainer, and comment out the port exposure for nginx-proxy-manager. Now our only method of accessing the nginx-proxy-manager admin portal and portainer is through the reverse proxy.
Note that we did not comment out the port exposure for cockpit. This is because if we screw up the reverse proxy, we want a way to get back into our host on port 9090. This is referred to as an out of band access method.
Always. Be. Hustling Documenting.
Update gitea to reflect our updated nginx proxy manager configuration:
and portainer:
Alright, we are making good progress. We have most of the tools we need to create a stable, secure docker environment.
One critical part is missing though. We aren’t backing up our data! We need backups. Let’s address that with Backups up Docker.