[Solved - Not a Caddy Issue] Reverse proxy configuration to point subdomains to specific docker containers — Connections from the outside time out

I am learning docker and some networking and after a couple of days of wandering in the mist here I am.


  • Raspberry Pi 3 B+ with LAN ip address
  • Router with port forwarding enabled: external 80:80, 443:443 pointed to (RasPi LAN ip)
  • A docker container (with docker inside the RasPi) which exposes to the host the port 32783
  • A free domain name domain.duckdns.org

What I want to achieve:
I’d like to be able to reach the above-mentioned container using the address myname.duckdns.org.

Current Caddyfile:

pi@raspberrypi:~ $ cat Caddyfile
domain.duckdns.org {
        proxy /

Caddy output:

pi@raspberrypi:~ caddy --port 80 -conf Caddyfile
Activating privacy features... done.

Serving HTTP on port 80

WARNING: File descriptor limit 1024 is too low for production servers. At least 8192 is recommended. Fix with `ulimit -n 8192`.


  • I can load from my browser and the webpage gets displayed correctly.
  • I can ping domain.duckdns.org and the returned IP matches with my current router ip so DNS :white_check_mark:.
  • If I try to load from my browser http://domain.duckdns.org it goes in timeout ERR_CONNECTION_TIMED_OUT

I think that everything is in check, yet I can’t reverse proxy the container. If anyone could point me in the right direction.

Note I’ve installed the binary generated from the download page simply by specifying ARMv7 for the system, no additional plugins:

pi@raspberrypi:~ $ caddy -version
Caddy v1.0.0 (h1:KI6RPGih2GFzWRPG8s9clKK28Ns4ZlVMKR/v7mxq6+c=)

I’ve omitted the real domain for personal concerns. I’ve also went through other trials and errors guides like:

Hi @Maxiride, I’d say that packets aren’t reaching Caddy at all. Is there a firewall on the Pi? Have you confirmed that the port forwards are working as expected?

Hello @Whitestrake, I’ve tried to investigate the issue more yesterday evening, there are no firewall on the Pi and the port forwarding might be the culprit.

While on the Rounter configuration page I enabled the port forwarding correctly after testing it with the online service https://www.yougetsignal.com/tools/open-ports/ I noticed an odd thing, the IP I see assigned to me from there and the one that I see from terminal is in the form of 93.34.2xx.xx

pi@raspberrypi:~ $ curl ifconfig.me

However from the Router administration panel the “self-declared” ip it shows me is in the form of 100.86.2xx.xx, also from the ISP website it shows me the same address.

It’s like if “everyone else” on the internet sees an IP and my ISP tells me I have a different one :sweat_smile:

On either IPs yougetsignal says that the ports are closed :no_good_man::man_shrugging:

I’ll contact the call center to see if they can clarify me this aspect which might be what’s wrong.

After requesting a static IP I am now able to use caddy as a reverse proxy for my containers, the Caddyfile is unchanged from the original post, however, I am able to run caddy only when specifying port 80. The router port forwarding is also unchanged from the original post. (80:80, 443:443 pointed to the Raspberry internal static IP).

$ caddy -port 80
Activating privacy features... done.

Serving HTTP on port 80

WARNING: File descriptor limit 1024 is too low for production servers. At least 8192 is recommended. Fix with `ulimit -n 8192`.

While calling caddy normally (the Caddyfile is in the same directory that’s why I don’t specify it)

$ caddy
Activating privacy features... 2019/06/20 10:23:12 [INFO] [mydomain.duckdns.org] acme: Obtaining bundled SAN certificate
2019/06/20 10:23:13 [INFO] [mydomain.duckdns.org] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz/aaPqATla4wVyRYLxOOp03kuxJd47fnInE_CIhocM0ZY
2019/06/20 10:23:13 [INFO] [mydomain.duckdns.org] acme: use tls-alpn-01 solver
2019/06/20 10:23:13 [INFO] [mydomain.duckdns.org] acme: Trying to solve TLS-ALPN-01
2019/06/20 10:23:23 [INFO] Unable to deactivated authorizations: https://acme-v02.api.letsencrypt.org/acme/authz/aaPqATla4wVyRYLxOOp03kuxJd47fnInE_CIhocM0ZY
2019/06/20 10:23:23 [mydomain.duckdns.org] failed to obtain certificate: acme: Error -> One or more domains had a problem:
[mydomain.duckdns.org] acme: error: 400 :: urn:ietf:params:acme:error:connection :: Connection refused, url:
HypriotOS/armv7: pirate@black-pearl in ~

Edit: I’ve also tried to install the duckdns plugin.

Connection refused; usually this indicates the port is not firewalled but also not in use.

Test by running caddy -port 443 "tls self_signed" "status 200 /" and then run curl -kIL https://localhost in another terminal window to see if Caddy’s binding 443 properly.

If that goes bad, there’s some other shenanigans going on which bear investigating. If you get a good result, proceed to test with curl -kIL https://[external-ip-address].

If that second test fails, remove and re-apply the port forwarding rules.

I can confirm that Caddy has no role in this issue and that my crappy router provided by the ISP simply doesn’t always respect the port forwarding set.

After more trial and error the DMZ rule is correctly applied 100% of the time. I’d search if it is worth the investment to buy a new router or to keep the Raspberry in the DMZ and carefully set the Caddyfile (maybe I will also need a firewall?) to at least protect from simple to moderate attacks.

Is there any particular documentation you would suggest me? I’m browsing the geofilter and rate limiters plugins to begin with.

Otherwise this can be closed.

1 Like

You’ll want to harden your Raspberry.

This is a really good document: Raspberry Pi Documentation - Configuration

It covers the firewall (with ufw) as well as a lot of other important considerations.

You can look into geofilter and rate limit, but you don’t need them any more in a DMZ than you did using port forwards.

1 Like

Thank you very much for the help provided =)

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.