Since I reinstalled the OS and have fewer apps installed, it is a good moment to rebuild my workflow and drop a couple of old habits.
Previously, to access the local app from the internet (for example, to receive a webhook), I used the ngrok service1. But on a fresh system, I did not have the app installed, so I have looked at alternatives - what I can use instead of it2. Especially since I have Podman already installed.
In the end, I discovered that I can use Cloudflare Tunnel with containers, so I gave it a spin - and it worked flawlessly!
tl;dr: Magic sauce is to set host.containers.internal (or host.docker.internal for Docker) to target host.
First things first - we need a Cloudflare account with some domain and Cloudflare One. Free plan for both is okay.
Once we have the required accounts, we can navigate to Network -> Connectors in Cloudflare One to create a new tunnel. Select Cloudflared as a tunnel type (as we need only one direction access - from the internet to our service) and name the new tunnel.
Then can select the environment as Docker to have a command like this (THE_TOKEN will be replaced with your token - this is secret, do not share!):
docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token THE_TOKEN
We can run it to see if it is working (a message will appear in the UI). After that, we can go to ‘Route tunnel’ and ‘Published applications’ (when we edit, it will be ‘Published application routes’) and configure it to your needs.
In the screenshot below, I have a configuration that will point my-subdomain.example.com to localhost:5000.

And that is all. After starting the container (with a proper token), my service is exposed as needed.
ngrok is nice, but I wanted to have something without an additional executable installed ↩︎
I could also set up nginx and use SSH for that purpose, but this time I wanted to not set up anything on the VMs. ↩︎