Gateway & Routing · recorded 2026-08-29 · applies to 1 tool(s) ✓ Verified

Problem: Docker deployment: ports / volumes / permissions —— Trove problem library

Verified 2026-08-29Docker deploy broken/lost config/permission — follow docker/README.md: -p 8080:8080 + named volume + -u 1000:1000.

Quick fix

# One-liner: start with the project docker/README.md parameters (8080 mapping + named volume + user flag)
docker run -d --name ccr -p 8080:8080 -v ccr-data:/data -u 1000:1000 <image-name>

Use the actual image name/data directory from the project's docker/README.md; this line fixes all three problems (can't open + lost config + permissions).

What you will run into

You run the gateway in Docker; the container shows as running but the browser just won't open it. Or the config disappears entirely after one container rebuild. Or startup reports a volume permission error.

The three classic Docker deployment traps hit at once: wrong port mapping, no data persistence, and a mismatch between the container user and directory owner.

Why this happens

  • In the gateway image, Nginx listens on 8080, while 3456/3457/3459 are internal container ports - only used for inter-service access inside the container network, no need to map them to the host. If you only map the internal ports, the host has no entry point -> the browser can't open it.
  • Without a named volume, config is written to the container's writable layer and is lost the moment the container is deleted -> "config lost after restart".
  • The image recommends running with -u 1000:1000; when the container user and the mounted directory's owner mismatch, the container can't read/write inside -> permission error.
SymptomRoot cause
Browser can't openOnly internal ports mapped, or 8080 not mapped
Config lost after restartNo named volume mounted
Volume permission errorContainer user vs host directory owner mismatch

Docker is an isolated runtime; the three traps map to three layers of isolation: network isolation — the container has its own network namespace, and ports listening inside are only visible inside the container by default;

-p host-port:container-port is the "punch a hole" action, so mapping only the internal ports (3456/3457/3459) means the holes are in a wall nobody walks by — the host has no entry point.

Storage isolation — the container's writable layer lives and dies with the container; data placed there is one-shot;

a named volume is "mounting a piece of host storage into the container", and after a rebuild you mount it again and the data is still there.

User isolation — processes inside run as the image-specified user (e.g. 1000:1000), while the mounted directory's owner belongs to the host; when the IDs don't match, the container can't read/write inside.

All three traps share one methodology: understand "inside the container ≠ host machine"; everything must be explicitly punched through the boundary — ports explicitly mapped, data explicitly mounted, permissions explicitly aligned.

Step by step

1. Check port usage — Required

docker ps

See whether 8080 is taken; if so, use a different host port -p 8081:8080 (the container still uses 8080).

2. Start with the correct parameters — Required

Per the project's docker/README.md: only map the host ports you need (usually -p 8080:8080), use a named volume for data, and add -u 1000:1000:

docker run -d --name ccr -p 8080:8080 -v ccr-data:/data -u 1000:1000 <image-name>

3. Verify in the browser — Required

open http://localhost:8080

The management UI opening means the port is fine (on Windows, open the browser manually).

4. Recover data — Required

If config was lost because no volume was mounted before: mount the old data directory to the matching data directory and restart:

docker run -d --name ccr -p 8080:8080 -v /path/to/old-data:/data -u 1000:1000 <image-name>

How to confirm it works

One command after startup shows status and mapping (expected output shape):

docker ps --filter name=ccr
-> STATUS Up / PORTS 0.0.0.0:8080->8080/tcp

The browser opens http://localhost:8080 and shows the management UI; config survives container restarts (nothing lost).

Other environments

EnvironmentNotes
Port conflictdocker ps to find usage; swap the host-side port; the container port stays
Data persistenceNamed volume required; bare directory mounts need owner attention
Permission errorImage docs recommend -u 1000:1000; or change the owner / mount directory
Windows Docker DesktopSame commands; open the browser manually
Not measuredDocker form not measured in this marketplace (local container limits); compiled from project docs + web cases

Symptom

Container runs but the browser can't open it; config lost after restart; or a volume permission error.

Cause

  1. Only Nginx 8080 is exposed: 3456/3457/3459 are internal container ports that don't need host mapping.
  2. No named volume: data is lost when the container is rebuilt.
  3. Container user vs volume owner mismatch (image docs recommend -u 1000:1000).

Solution

  1. Start with the project docker/README.md parameters: -p 8080:8080 + named volume + -u 1000:1000.
  2. On port conflict, docker ps to find usage and swap the host port (-p 8081:8080).
  3. Data recovery: mount the volume to the matching data directory and restart.
Verification Evidence
  • Project docker/README.md; web cases: CSDN (Docker port conflict/permission scenarios).
  • Docker form not measured in this marketplace (local container limits), honestly noted.

Applicable tools (1)

This problem is linked from the tool pages below — reachable from either side.

claude-code-router

Source & evidence

Recorded Verified ✓ VerifiedApplies to 1 tool(s)
Entries contain locally measured or reviewable-source solutions; unmeasured items are explicitly labeled.

← Gateway & Routing domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk