Skip to content

Docker Troubleshooting

npm ci fails during the frontend image build

Symptom: npm ci exits with a wall of "Missing: ... from lock file" errors, or an EBADPLATFORM/EBADENGINE warning.

Cause: package-lock.json out of sync with package.json, or a Node version mismatch with a transitive dependency's engine requirement (see Images "Why Node 22, not 20"). npm ci is deliberately strict here - unlike Yarn, it has no --frozen-lockfile-equivalent flag to disable this check, and a stray extra CLI flag has previously been mistaken for one and corrupted lockfile resolution entirely.

Fix: regenerate the lockfile cleanly and rebuild:

cd frontend
npm install --package-lock-only
cd ..
docker build -f frontend/Dockerfile -t akshayabazaar-frontend:local ./frontend --no-cache

Backend container CreateContainerConfigError / crashes immediately

Symptom: container exits right after start, or (in Kubernetes) CreateContainerConfigError: image has non-numeric user.

Cause: usually a missing/incorrect ConnectionStrings__DefaultConnection (the container starts, tries to migrate/connect, and exits), or (Kubernetes only) an unrebuilt image after a Dockerfile UID change.

Fix: check the actual error first:

docker compose logs api --tail=100
Cross-reference against Kubernetes → Troubleshooting if running under Kubernetes instead of Compose.

HEALTHCHECK never turns healthy

docker inspect ecommerce_api --format='{{json .State.Health}}' | ConvertFrom-Json | Select-Object -ExpandProperty Log
Shows the actual wget output/exit code from each health check attempt - almost always either "connection refused" (app hasn't started listening yet - check start_period/retries haven't been shortened) or a genuine 500 from /health (check docker compose logs api).

Port already in use (Ports are not available)

Something else on the host already owns the port Compose wants to publish (80, 443, 3309, 5000, 3000, 8080). Find it before changing this project's own port mapping:

Get-NetTCPConnection -LocalPort 80 -State Listen -ErrorAction SilentlyContinue
Override via .env (MYSQL_HOST_PORT=3310, etc.) rather than editing docker-compose.yml directly, so the change stays local to your machine.

frontend never reaches healthy - stuck waiting on api

frontend depends_on: api: condition: service_healthy - if api itself never turns healthy, frontend never even starts its own health check cycle. Diagnose api first (see above), not frontend.

Stale image after a code change

docker compose build --no-cache api
docker compose up -d api
--no-cache is the reliable fix when a layer that should have invalidated (e.g. a COPYd file) appears not to have - Docker's layer cache occasionally over-trusts an unchanged-looking COPY src/ . when only file contents changed, not names/timestamps in a way it tracked.