1. The problem I’m having:
I try to configure/run a reverse proxy on rootless Podman on CoreOS in VM on Proxmox VE 9 on private LAN and failed ![]()
$ curl --fail --silent --show-error http://kuma.home.lan:8080
curl: (56) Recv failure: Connection reset by peer
$ curl --fail --silent --show-error http://kuma.home.lan:80
curl: (7) Failed to connect to kuma.home.lan port 80 after 7 ms: Could not connect to server
The container I want to proxy/redir works (whoami from traefik). This is the test service for uptime-kuma to be used later.
$ curl --fail --silent --show-error http://kuma.home.lan:2001
Hostname: whoami.localhost
IP: 127.0.0.1
IP: ::1
IP: 192.168.1.13
IP: fe80::5835:1cff:fe82:545d
RemoteAddr: 169.254.1.2:35390
GET / HTTP/1.1
Host: kuma.home.lan:2001
User-Agent: curl/8.11.1
Accept: */*
I’m running Proxmox VE 9 with CoreOS42 as VM, running Podman’s rootless containers. Container’s ports are mapped on non-root Ports (8080, 8443 etc.) Hence, nftables’ forwarding is (hopefully correct) configured, to redirect traffic on port 80 to Container’s port 8080, resp. 433→8433. This setup isn’t using Certs and HTTPS, it’s pre-work for later even using Cert/HTTPS etc.
2. Error messages and/or full log output:
$ journalctl --user -u caddy --no-pager | less +G
Oct 17 19:22:02 coreos-test systemd[2966]: Reloading caddy.service - Caddy - The Ultimate Server with Automatic HTTPS...
Oct 17 19:22:02 coreos-test podman[6009]: 2025-10-17 19:22:02.984904499 +0200 CEST m=+0.205476429 container exec d8358801ccd1d7e3e49f5289ba3fe1e739434c1f3bbc5cd94d0472bab9a59f4f (image=docker.io/library/caddy:2.10-alpine, name=caddy, pod_id=6fa5a5fae7f4adc86ca0865d0dd2aabb91c1dc9b31f686416c536975851954c9, org.opencontainers.image.documentation=https://caddyserver.com/docs, org.opencontainers.image.vendor=Light Code Labs, org.opencontainers.image.version=v2.10.2, PODMAN_SYSTEMD_UNIT=caddy.service, org.opencontainers.image.title=Caddy, org.opencontainers.image.description=a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go, org.opencontainers.image.licenses=Apache-2.0, org.opencontainers.image.source=https://github.com/caddyserver/caddy-docker, org.opencontainers.image.url=https://caddyserver.com)
Oct 17 19:22:03 coreos-test caddy[6009]: {"level":"info","ts":1760721723.1752846,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
Oct 17 19:22:03 coreos-test caddy[6009]: {"level":"info","ts":1760721723.179875,"msg":"adapted config to JSON","adapter":"caddyfile"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1817808,"logger":"admin.api","msg":"received request","method":"POST","host":":2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"34686","headers":{"Accept-Encoding":["gzip"],"Cache-Control":["must-revalidate"],"Content-Length":["934"],"Content-Type":["application/json"],"Origin":["http://:2019"],"User-Agent":["Go-http-client/1.1"]}}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.184274,"logger":"admin","msg":"admin endpoint started","address":":2019","enforce_origin":false,"origins":["//localhost","//192.168.1.13"]}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"warn","ts":1760721723.1843548,"logger":"admin","msg":"admin endpoint on open interface; host checking disabled","address":":2019"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1851923,"logger":"http.auto_https","msg":"automatic HTTPS is completely disabled for server","server_name":"srv0"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1852627,"logger":"http.auto_https","msg":"automatic HTTPS is completely disabled for server","server_name":"srv1"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"debug","ts":1760721723.185309,"logger":"http.auto_https","msg":"adjusted config","tls":{"automation":{"policies":[{}]}},"http":{"http_port":80,"https_port":443,"servers":{"srv0":{"listen":[":443"],"routes":[{"handle":[{"handler":"subroute","routes":[{"handle":[{"handler":"reverse_proxy","upstreams":[{"dial":"192.168.1.13:2001"}]}]}]}],"terminal":true}],"tls_connection_policies":[{}],"automatic_https":{"disable":true}},"srv1":{"listen":[":8086"],"routes":[{"handle":[{"body":"Hello World","handler":"static_response"}]}],"automatic_https":{"disable":true}}}}}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"debug","ts":1760721723.1861422,"logger":"http","msg":"starting server loop","address":"[::]:443","tls":true,"http3":false}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.186211,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1862552,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"debug","ts":1760721723.1864965,"logger":"http","msg":"starting server loop","address":"[::]:8086","tls":false,"http3":false}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"warn","ts":1760721723.1865473,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":8086"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"warn","ts":1760721723.186567,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":8086"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1865819,"logger":"http.log","msg":"server running","name":"srv1","protocols":["h1","h2","h3"]}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"debug","ts":1760721723.1866632,"logger":"events","msg":"event","name":"started","id":"06e6b6e8-851b-49e9-be3f-4a011dc97242","origin":"","data":null}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"debug","ts":1760721723.186714,"logger":"events","msg":"event","name":"stopping","id":"ea4ffbae-6797-4c98-8fa1-06adecf0fac8","origin":"","data":null}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1867507,"logger":"http","msg":"servers shutting down with eternal grace period"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1876256,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1877022,"logger":"admin.api","msg":"load complete"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1883607,"logger":"admin","msg":"stopped previous server","address":":2019"}
Oct 17 19:22:03 coreos-test podman[6009]: 2025-10-17 19:22:03.195969197 +0200 CEST m=+0.416541153 container exec_died d8358801ccd1d7e3e49f5289ba3fe1e739434c1f3bbc5cd94d0472bab9a59f4f (image=docker.io/library/caddy:2.10-alpine, name=caddy, org.opencontainers.image.vendor=Light Code Labs, org.opencontainers.image.source=https://github.com/caddyserver/caddy-docker, org.opencontainers.image.description=a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go, org.opencontainers.image.version=v2.10.2, PODMAN_SYSTEMD_UNIT=caddy.service, org.opencontainers.image.title=Caddy, org.opencontainers.image.url=https://caddyserver.com, org.opencontainers.image.documentation=https://caddyserver.com/docs, org.opencontainers.image.licenses=Apache-2.0)
Oct 17 19:22:03 coreos-test systemd[2966]: Reloaded caddy.service - Caddy - The Ultimate Server with Automatic HTTPS.
3. Caddy version:
$ podman exec -ti caddy caddy version
v2.10.2 h1:g/gTYjGMD0dec+UgMw8SnfmJ3I9+M2TdvoRL/Ovu6U8=
4. How I installed and ran Caddy:
I run caddy as rootless container using Podman.
$ systemctl --user daemon-reload && systemctl --user start caddy
$ systemctl --user daemon-reload && systemctl --user status caddy
● caddy.service - Caddy - The Ultimate Server with Automatic HTTPS
Loaded: loaded (/var/home/core/.config/containers/systemd/caddy/caddy.container; generated)
Drop-In: /usr/lib/systemd/user/service.d
└─10-timeout-abort.conf
Active: active (running) since Fri 2025-10-17 16:16:05 CEST; 3h 21min ago
Invocation: 73645fe3686243de9800dc34c411ffad
Docs: https://caddyserver.com/docs/
Main PID: 3151 (conmon)
Tasks: 11 (limit: 9366)
Memory: 55.8M (peak: 82.1M)
CPU: 31.190s
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/caddy.service
├─libpod-payload-d8358801ccd1d7e3e49f5289ba3fe1e739434c1f3bbc5cd94d0472bab9a59f4f
│ └─3153 caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
└─runtime
└─3151 /usr/bin/conmon --api-version 1 -c d8358801ccd1d7e3e49f5289ba3fe1e739434c1f3bbc5cd94d0472bab9a59f4f -u d8358801ccd1d7e3e49f5289ba3fe1e739434c1f3bbc5cd94d0472bab9a59f4f -r /usr/bin/crun -b /var/home/core/.local/share/co>
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"warn","ts":1760721723.186567,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":8086"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1865819,"logger":"http.log","msg":"server running","name":"srv1","protocols":["h1","h2","h3"]}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"debug","ts":1760721723.1866632,"logger":"events","msg":"event","name":"started","id":"06e6b6e8-851b-49e9-be3f-4a011dc97242","origin":"","data":null}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"debug","ts":1760721723.186714,"logger":"events","msg":"event","name":"stopping","id":"ea4ffbae-6797-4c98-8fa1-06adecf0fac8","origin":"","data":null}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1867507,"logger":"http","msg":"servers shutting down with eternal grace period"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1876256,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1877022,"logger":"admin.api","msg":"load complete"}
Oct 17 19:22:03 coreos-test caddy[3151]: {"level":"info","ts":1760721723.1883607,"logger":"admin","msg":"stopped previous server","address":":2019"}
Oct 17 19:22:03 coreos-test podman[6009]: 2025-10-17 19:22:03.195969197 +0200 CEST m=+0.416541153 container exec_died d8358801ccd1d7e3e49f5289ba3fe1e739434c1f3bbc5cd94d0472bab9a59f4f (image=docker.io/library/caddy:2.10-alpine, name=caddy, o>
Oct 17 19:22:03 coreos-test systemd[2966]: Reloaded caddy.service - Caddy - The Ultimate Server with Automatic HTTPS.
a. System environment:
On CoreOS as Container’s host (in Proxmox VM)
$ cat /etc/os-release
NAME="Fedora Linux"
VERSION="42.20250929.3.0 (CoreOS)"
RELEASE_TYPE=stable
ID=fedora
VERSION_ID=42
VERSION_CODENAME=""
PLATFORM_ID="platform:f42"
PRETTY_NAME="Fedora CoreOS 42.20250929.3.0"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:42"
HOME_URL="https://getfedora.org/coreos/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora-coreos/"
SUPPORT_URL="https://github.com/coreos/fedora-coreos-tracker/"
BUG_REPORT_URL="https://github.com/coreos/fedora-coreos-tracker/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=42
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=42
SUPPORT_END=2026-05-13
VARIANT="CoreOS"
VARIANT_ID=coreos
OSTREE_VERSION='42.20250929.3.0'
$ podman -v
podman version 5.6.1
$ systemctl --version
systemd 257 (257.9-2.fc42)
+PAM +AUDIT +SELINUX -APPARMOR +IMA +IPE +SMACK +SECCOMP -GCRYPT +GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN -IPTC +KMOD +LIBCRYPTSETUP +LIBCRYPTSETUP_PLUGINS +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK +BTF +XKBCOMMON +UTMP +SYSVINIT +LIBARCHIVE
$ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
CoreOS DNS
$ nslookup kuma.home.lan
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: kuma.home.lan
Address: 192.168.1.13
CoreOS nftables:
$ sudo nft list ruleset
table inet filter {
chain forward {
type filter hook forward priority filter; policy accept;
}
}
table inet caddy_redirect {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
tcp dport 80 redirect to :8080
tcp dport 443 redirect to :8443
udp dport 443 redirect to :8443
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
}
}
On Proxmox:
~# sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
There are no fw rules!
b. Command:
$ systemctl --user daemon-reload && systemctl --user start caddy
$ curl --fail --silent --show-error http://kuma.home.lan:8080
curl: (56) Recv failure: Connection reset by peer
$ curl --fail --silent --show-error http://kuma.home.lan:80
curl: (7) Failed to connect to kuma.home.lan port 80 after 7 ms: Could not connect to server
# whoami container I want to redir/proxy
$ curl --fail --silent --show-error http://kuma.home.lan:2001
Hostname: whoami.localhost
IP: 127.0.0.1
IP: ::1
IP: 192.168.1.13
IP: fe80::5835:1cff:fe82:545d
RemoteAddr: 169.254.1.2:35390
GET / HTTP/1.1
Host: kuma.home.lan:2001
User-Agent: curl/8.11.1
Accept: */*
$ netstat -tulpen|grep -E ':(80|8080|2019|8080|8086|443|8443|2001)'
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:8443 0.0.0.0:* LISTEN 1000 90455 8283/pasta
tcp 0 0 0.0.0.0:2001 0.0.0.0:* LISTEN 1000 88981 8289/pasta
tcp 0 0 0.0.0.0:2019 0.0.0.0:* LISTEN 1000 90452 8283/pasta
tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1000 90453 8283/pasta
tcp 0 0 0.0.0.0:8086 0.0.0.0:* LISTEN 1000 90454 8283/pasta
udp 0 0 0.0.0.0:8443 0.0.0.0:* 1000 90456 8283/pasta
c. Service/unit/compose file:
~/.config/containers/systemd/caddy/caddy.container:
[Unit]
Description=Caddy - The Ultimate Server with Automatic HTTPS
Documentation=https://caddyserver.com/docs/
After=network-online.target
[Container]
Image=docker.io/library/caddy:2.10-alpine
ContainerName=caddy
Pod=caddy.pod
Volume=%h/.config/containers/systemd/caddy/conf:/etc/caddy:Z
Volume=caddy_data:/data:Z
Volume=caddy_config:/config:Z
ReloadCmd=sh -c "caddy reload --config /etc/caddy/Caddyfile --force"
[Service]
Restart=always
[Install]
WantedBy=default.target
~/.config/containers/systemd/caddy/caddy.pod:
[Unit]
Description=Caddy Pod
After=network-online.target
Wants=network-online.target
[Pod]
PodName=caddy
HostName=caddy.localhost
PublishPort=8080:80
PublishPort=8443:443/tcp
PublishPort=8443:443/udp
PublishPort=2019:2019
PublishPort=8086:8086
~/.config/containers/systemd/caddy/whoami.container:
[Unit]
Description=WhoAmI - HTTP Service that returns information about the incoming request
Documentation=https://hub.docker.com/r/traefik/whoami
After=network-online.target
[Container]
Image=docker.io/traefik/whoami
ContainerName=whoami
Pod=whoami.pod
[Service]
Restart=always
[Install]
WantedBy=default.target
~/.config/containers/systemd/caddy/whoami.pod:
[Unit]
Description=WhoAmI Pod
After=network-online.target
Wants=network-online.target
[Pod]
PodName=whoami
HostName=whoami.localhost
PublishPort=2001:80
~/.config/containers/systemd/caddy/caddy.nft rules, independent of container
table inet filter {
chain forward {
type filter hook forward priority filter; policy accept;
}
}
table inet caddy_redirect {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
tcp dport 80 redirect to :8080
tcp dport 443 redirect to :8443
udp dport 443 redirect to :8443
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
}
}
d. My complete Caddy config:
{
debug
http_port 80
https_port 443
auto_https off
email olaf@home.lan
admin :2019 {
# Only allow requests from localhost to prevent remote code execution
origins localhost 192.168.1.13
# enforce_origin
}
}
:8086 {
# works as expected
respond "Hello World"
}
kuma.home.lan {
# this response works as expected, reverse_proxy doesn't
#respond "Hello World"
reverse_proxy 192.168.1.13:2001
}