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.
| Symptom | Root cause |
|---|---|
| Browser can't open | Only internal ports mapped, or 8080 not mapped |
| Config lost after restart | No named volume mounted |
| Volume permission error | Container 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
| Environment | Notes |
|---|---|
| Port conflict | docker ps to find usage; swap the host-side port; the container port stays |
| Data persistence | Named volume required; bare directory mounts need owner attention |
| Permission error | Image docs recommend -u 1000:1000; or change the owner / mount directory |
| Windows Docker Desktop | Same commands; open the browser manually |
| Not measured | Docker 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
- Only Nginx 8080 is exposed: 3456/3457/3459 are internal container ports that don't need host mapping.
- No named volume: data is lost when the container is rebuilt.
- Container user vs volume owner mismatch (image docs recommend
-u 1000:1000).
Solution
- Start with the project docker/README.md parameters:
-p 8080:8080+ named volume +-u 1000:1000. - On port conflict,
docker psto find usage and swap the host port (-p 8081:8080). - 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-routerSource & evidence
← Gateway & Routing domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk