Troubleshooting
Common Password Pusher Pro Self-Hosted Docker Compose and Podman boot issues—port binds and host remaps.
Common boot and networking issues when running Self-Hosted Pro. This page will grow over time. For day-to-day Compose commands, see Operations.
listen tcp :80: bind: permission denied
You may see a log line like:
Failed to start HTTP listener","error":"listen tcp :80: bind: permission denied"
What is going wrong
Compose port mappings such as "8095:80" only change how the host exposes the container. Inside the container, Thruster (the HTTP proxy in front of Rails) still tries to bind :80.
The Pro image runs as a non-root user (pwpush). Ports below 1024 are privileged:
| Runtime | Typical behavior |
|---|---|
| Rootful Docker | Usually allows non-root processes to bind 80/443 |
| Podman (especially rootless) | Often denies bind on :80 — this error is common |
Host ports already taken by other containers is a separate problem. Mapping "8095:80" already avoids that on the host. The permission error is about the in-container bind.
Recommended fix
Listen on an unprivileged port inside the container, publish that to your host port, and override the healthcheck (the image default probes http://localhost:80/up).
services:
pwpush-pro:
image: registry.apnotic.com/pwpush-pro:latest
env_file:
- .env
environment:
HTTP_PORT: "8080"
volumes:
- pwpush-pro-data:/opt/PasswordPusher/storage
ports:
- "8095:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/up"]
interval: 30s
timeout: 3s
restart: unless-stopped
volumes:
pwpush-pro-data:
driver: local
Match the host side of ports to whatever you need (for example "80:8080" if host 80 is free). The important part is that the right-hand (container) port matches HTTP_PORT and the healthcheck.
Recreate after changing env or ports:
docker compose up -d --force-recreate
# or the podman-compose equivalent
Alternative: keep container port 80
If you prefer the default internal port 80 (and your runtime allows it):
ports:
- "8095:80"
sysctls:
- net.ipv4.ip_unprivileged_port_start=0
or:
cap_add:
- NET_BIND_SERVICE
On some rootless Podman hosts, sysctls and capabilities are restricted. In that case use HTTP_PORT=8080 as above.
Quick checks
| Check | Expectation |
|---|---|
| Log message | listen tcp :80 is inside the container; host remap does not change it |
HTTP_PORT |
Set to an unprivileged port (e.g. 8080) when bind on 80 is denied |
Compose ports |
Right-hand port matches HTTP_PORT (e.g. "8095:8080") |
| Healthcheck | If you set HTTP_PORT, override Compose healthcheck to match |
Related
| Topic | Doc |
|---|---|
| External TLS / proxy headers | Behind a reverse proxy |
| Start / stop / logs | Operations |
| Install runbook | Getting started checklist |
| Overview | Pro Self-Hosted |