Skip to content

Commit 241b5d9

Browse files
authored
docs: add troubleshooting section for Docker build and runtime issues (#951)
1 parent 6a8b6ae commit 241b5d9

File tree

2 files changed

+184
-0
lines changed

2 files changed

+184
-0
lines changed

docs/deploy.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ This will start the container in the background and detached.
8888
- `docker exec -it safe-settings /bin/sh`
8989
- You will now be inside the running **Docker** container and can perform any troubleshooting needed
9090

91+
### Troubleshooting Docker Build and Runtime Issues
92+
For detailed guidance on debugging Docker image builds, runtime failures, and comparing local vs. GHCR images, see [docker-debugging.md](docker-debugging.md).
93+
9194
## Deploy the app to AWS Lambda
9295

9396
### Production-Ready Template

docs/docker-debugging.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
2+
# Docker Build and Test Debugging Runbook
3+
4+
This document summarizes the Docker experiments done for this repo and converts them into a repeatable workflow for debugging local image builds and GHCR images.
5+
6+
## Goals
7+
8+
- Build and test the app image from local source.
9+
- Compare behavior with the published image from GHCR.
10+
- Quickly diagnose common failures (container startup, shell access, port exposure, env setup).
11+
12+
## What We Learned From The Experiments
13+
14+
- The image is Alpine-based, so use /bin/sh, not /bin/bash.
15+
- Use docker rm (or docker container rm) to remove containers. Commands like docker delete, docker destroy, or docker remove do not exist.
16+
- To pass host binding correctly, use HOST=0.0.0.0 (equal sign), not HOST:0.0.0.0.
17+
- Port mapping is required for host access: -p 3000:3000.
18+
- Supplying .env values is required for realistic startup testing.
19+
- Testing both local and GHCR images with the same runtime flags makes behavior comparisons easier.
20+
21+
## Prerequisites
22+
23+
- Docker is installed and running.
24+
- A valid .env file exists at repo root.
25+
- You are in repo root.
26+
27+
## 1) Build And Test Local Image
28+
29+
Build the local image:
30+
31+
```bash
32+
docker build -t safe-settings:local .
33+
```
34+
35+
Run container in foreground with explicit runtime env and port mapping:
36+
37+
```bash
38+
docker run --name safe-settings-local \
39+
--env-file ./.env \
40+
--env NODE_ENV=development \
41+
--env HOST=0.0.0.0 \
42+
-p 3000:3000 \
43+
-it safe-settings:local
44+
```
45+
46+
If startup fails, inspect logs:
47+
48+
```bash
49+
docker logs safe-settings-local
50+
```
51+
52+
Shell into running container for investigation:
53+
54+
```bash
55+
docker exec -it safe-settings-local /bin/sh
56+
```
57+
58+
Clean up:
59+
60+
```bash
61+
docker rm -f safe-settings-local
62+
```
63+
64+
## 2) Pull And Test GHCR Image
65+
66+
Pull published image:
67+
68+
```bash
69+
docker pull ghcr.io/github/safe-settings:2.1.19
70+
```
71+
72+
Run with the same env and port flags used for local testing:
73+
74+
```bash
75+
docker run --name safe-settings-ghcr \
76+
--env-file ./.env \
77+
--env NODE_ENV=development \
78+
--env HOST=0.0.0.0 \
79+
-p 3000:3000 \
80+
-it ghcr.io/github/safe-settings:2.1.19
81+
```
82+
83+
Inspect logs:
84+
85+
```bash
86+
docker logs safe-settings-ghcr
87+
```
88+
89+
Debug inside container:
90+
91+
```bash
92+
docker exec -it safe-settings-ghcr /bin/sh
93+
```
94+
95+
Clean up:
96+
97+
```bash
98+
docker rm -f safe-settings-ghcr
99+
```
100+
101+
## 3) Fast Differential Debug (Local vs GHCR)
102+
103+
Use this when one image works and the other does not.
104+
105+
1. Run both images with identical flags (env, HOST, port mapping).
106+
2. Compare startup logs side-by-side.
107+
3. Compare environment inside each container:
108+
109+
```bash
110+
docker exec -it safe-settings-local /bin/sh -c 'env | sort'
111+
docker exec -it safe-settings-ghcr /bin/sh -c 'env | sort'
112+
```
113+
114+
4. Confirm app process is listening on expected port inside container:
115+
116+
```bash
117+
docker exec -it safe-settings-local /bin/sh -c 'netstat -lntp 2>/dev/null || ss -lntp'
118+
docker exec -it safe-settings-ghcr /bin/sh -c 'netstat -lntp 2>/dev/null || ss -lntp'
119+
```
120+
121+
5. Validate host reachability:
122+
123+
```bash
124+
curl -i http://localhost:3000/
125+
```
126+
127+
## 4) Common Failure Patterns And Fixes
128+
129+
Symptom: container exits immediately.
130+
Likely causes:
131+
- Missing required variables in .env.
132+
- Invalid app credentials.
133+
Checks:
134+
- docker logs <container-name>
135+
- Confirm .env has required app settings.
136+
137+
Symptom: cannot connect from host to localhost:3000.
138+
Likely causes:
139+
- Missing -p 3000:3000.
140+
- App not binding to all interfaces.
141+
Checks:
142+
- Ensure HOST=0.0.0.0 is set.
143+
- Ensure port mapping is present.
144+
145+
Symptom: cannot shell into container with bash.
146+
Likely cause:
147+
- Alpine image does not include bash.
148+
Fix:
149+
- Use /bin/sh.
150+
151+
Symptom: name conflict when re-running tests.
152+
Likely cause:
153+
- Old container still exists.
154+
Fix:
155+
- docker rm -f <container-name>
156+
157+
## 5) Minimal Known-Good Commands
158+
159+
Local:
160+
161+
```bash
162+
docker build -t safe-settings:local . && \
163+
docker run --rm --name safe-settings-local \
164+
--env-file ./.env \
165+
--env NODE_ENV=development \
166+
--env HOST=0.0.0.0 \
167+
-p 3000:3000 \
168+
-it safe-settings:local
169+
```
170+
171+
GHCR:
172+
173+
```bash
174+
docker pull ghcr.io/github/safe-settings:2.1.19 && \
175+
docker run --rm --name safe-settings-ghcr \
176+
--env-file ./.env \
177+
--env NODE_ENV=development \
178+
--env HOST=0.0.0.0 \
179+
-p 3000:3000 \
180+
-it ghcr.io/github/safe-settings:2.1.19
181+
```

0 commit comments

Comments
 (0)