Do not disable IPv6 just because ss shows a CasaOS or Docker service listening on :::80. On Linux, an IPv6 wildcard listener can also accept IPv4 depending on socket settings, and Docker normally publishes ports to IPv4 when no host address is specified.
The source case was CasaOS on Debian 12 in GCP, not ZimaOS. The correct diagnosis is to test IPv4 explicitly, inspect the CasaOS gateway and Docker port bindings, and check the cloud firewall before changing GRUB or globally disabling IPv6.
First Test IPv4 Directly
curl -4 -v http://127.0.0.1:80/
curl -4 -v http://SERVER_IPV4:80/
ss -ltnp | grep ':80'
If local IPv4 works but remote IPv4 fails, the problem is likely host/cloud firewall or routing rather than CasaOS binding.
Docker Port Publishing Normally Includes IPv4
Docker's current Docker port publishing guide says normal published ports are reachable through host address mappings; explicit IPv6-only behavior requires different configuration.
Check CasaOS Itself
systemctl status casaos
journalctl -u casaos --no-pager -n 100
ss -ltnp | grep -E ':80|casaos'
The current CasaOS installer still enumerates IPv4 NIC addresses when printing the dashboard URL, so a healthy install is not designed to require IPv6-only access.
Check the GCP Firewall
Confirm the VM has an IPv4 address, route, and ingress rule for the chosen CasaOS web port. A cloud firewall can block port 80 even when the service is listening correctly.
Do Not Disable IPv6 Globally as the First Fix
Older CasaOS components have historically expected /proc/net/tcp6 to exist, and disabling IPv6 has caused app-management issues in some builds. Removing IPv6 can create a second problem without fixing the first.
If You Need an IPv4-Only Docker Binding
ports:
- "0.0.0.0:8080:80"
Use explicit IPv4 binding only when you control that Compose definition and understand the exposure implications.
Check the CasaOS Web Port
The installer may choose another available port if 80 is already occupied. Confirm the actual CasaOS HTTP port before assuming the service failed.
The Docker networking guide covers the same networking fundamentals.
Check sysctl Only After Testing Real Connectivity
If you still suspect dual-stack socket behavior, inspect sysctl net.ipv6.bindv6only. A value of 0 allows many IPv6 wildcard sockets to accept IPv4-mapped connections; a value of 1 makes them IPv6-only. Do not change it system-wide unless you understand every service affected.
Check Docker's Actual Published Addresses
docker ps --format 'table {{.Names}} {{.Ports}}'
docker inspect CONTAINER --format '{{json .NetworkSettings.Ports}}'
This shows whether Docker created an IPv4 mapping such as 0.0.0.0:PORT, an IPv6 mapping, or both. It is more reliable than inferring behavior from one process-list line.
Remember GCP Has Two Firewall Layers
A Debian host can have its own nftables/iptables rules while GCP separately controls VPC firewall ingress. A service may be correct locally yet unreachable externally because either layer blocks the port.
FAQ
Does :::80 always mean IPv6-only?
No. Verify with curl -4 before drawing that conclusion.
Should I disable IPv6 in GRUB?
Not as the first troubleshooting step. It can break components that expect IPv6 kernel interfaces.
Why does localhost work but public IPv4 not work?
Check the cloud firewall, security group, route, and host firewall.
Is this a ZimaOS issue?
The source thread concerns CasaOS installed on Debian 12, not ZimaOS.
