Skip to content

Commit e718e5d

Browse files
committed
add blog post on debugging docker container
1 parent 0c1007c commit e718e5d

File tree

2 files changed

+301
-0
lines changed

2 files changed

+301
-0
lines changed

src/assets/Debugging/debugging.md

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
---
2+
title: Advanced Docker Container Debugging - A comprehensive guide
3+
authorName: Prajwol Amatya
4+
authorAvatar: https://1.gravatar.com/avatar/de64e53c0e2cb393dd0d14ffdd53058ee9c607b35e366dd392425bd1b95a034c?size=256
5+
authorLink: https://github.com/prajwolamatya
6+
createdAt: April 29, 2025
7+
tags: debugging, docker
8+
banner: https://blog.jankaritech.com/src/assets/Debugging/images/Debugging.png
9+
---
10+
11+
Docker has revolutionized modern software development by enabling lightweight, portable, and scalable containerized applications. However, as deployments grow in complexity, so do the challenges in debugging and optimizing containers. In this blog, we'll explore powerful debugging techniques using a sample project with Node.js, Nginx, and Redis. You can get the sample project [here](https://github.com/prajwolamatya/debug-docker).
12+
13+
Our setup consists of:
14+
- A Node.js application (port 3000)
15+
- Nginx as a reverse proxy (port 80)
16+
- Redis for caching (port 6379)
17+
18+
## 1. Container Inspection
19+
### Viewing Running Containers
20+
First, let's check our running containers:
21+
22+
```bash
23+
docker-compose ps
24+
```
25+
26+
**Expected Output:**
27+
```console
28+
Name Command State Ports
29+
debug-docker_nginx_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:80->80/tcp
30+
debug-docker_nodejs-app_1 docker-entrypoint.sh node ... Up 0.0.0.0:3000->3000/tcp
31+
debug-docker_redis_1 docker-entrypoint.sh redis ... Up 0.0.0.0:6379->6379/tcp
32+
```
33+
34+
- **State:** Shows if container is running/stopped
35+
- **Ports:** Reveals port mappings (host:container)
36+
37+
### Inspecting Container Details
38+
For deeper inspection of a specific container:
39+
40+
```bash
41+
docker inspect debug-docker_nodejs-app_1
42+
```
43+
44+
This returns a JSON with all container details including:
45+
- Network settings
46+
- Mounts
47+
- Environment variables
48+
- IP addresses
49+
50+
**Pro Tip:** Filter specific information:
51+
52+
```bash
53+
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' debug-docker_nodejs-app_1
54+
```
55+
56+
## 2. Log Analysis
57+
### Viewing Container Logs
58+
59+
```bash
60+
docker-compose logs
61+
```
62+
63+
**Example Output (when accessing the service):**
64+
65+
```console
66+
debug-docker_nodejs-app_1 | Node.js server running on port 3000
67+
```
68+
69+
This confirms your Node.js application launched successfully
70+
71+
### Generating Request Logs
72+
Make a test request to generate logs:
73+
74+
```bash
75+
curl -v http://localhost:3000
76+
```
77+
78+
After the request, check logs again to see:
79+
80+
```console
81+
debug-docker_nodejs-app_1 | Node.js server running on port 3000
82+
debug-docker_nodejs-app_1 | GET / 200 7.001 ms - 19
83+
```
84+
85+
To view only GET requests from the last 5 minutes
86+
```bash
87+
docker logs --since 5m debug-docker_nodejs-app_1 | grep "GET"
88+
```
89+
90+
**Expected Output:**
91+
92+
```console
93+
GET / 200 7.001 ms - 19
94+
```
95+
96+
## 3. Network Troubleshooting
97+
### Checking Container Connectivity
98+
99+
Test if Nginx can reach Node.js:
100+
101+
```bash
102+
docker exec debug-docker_nginx_1 ping nodejs-app
103+
```
104+
105+
**Expected Output:**
106+
```console
107+
PING nodejs-app (172.19.0.3): 56 data bytes
108+
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.060 ms
109+
```
110+
- **Success:** <1ms response confirms network connectivity
111+
- **Failure:** Would show "unknown host" or timeout
112+
113+
### Examining Post Accessibility
114+
Check if Node.js is listening on port 3000 inside its container:
115+
116+
```bash
117+
docker exec debug-docker_nodejs-app_1 netstat -tuln
118+
```
119+
120+
**Expected Output:**
121+
```console
122+
Active Internet connections (only servers)
123+
Proto Recv-Q Send-Q Local Address Foreign Address State
124+
tcp 0 0 :::3000 :::* LISTEN
125+
```
126+
127+
- Shows Node.js listening on port 3000
128+
- No output means service isn't running properly
129+
130+
## 4. Interactive Debugging
131+
### Executing into Containers
132+
133+
For Node.js application debugging:
134+
```bash
135+
docker exec -it debug-docker_nodejs-app_1 sh
136+
```
137+
Now you can:
138+
1. Check running processes: `ps aux`
139+
```bash
140+
ps aux
141+
```
142+
143+
**Output:**
144+
145+
```console
146+
PID USER TIME COMMAND
147+
1 root 0:00 {MainThread} node app.js
148+
28 root 0:00 sh
149+
45 root 0:00 ps aux
150+
```
151+
- Shows all running processes in the container
152+
- `PID1`: Your Node.js application (node app.js)
153+
- `PID28`: The shell session you just started
154+
- `PID 45`: The `ps aux` command itself
155+
- Confirms your application is running as the main process
156+
157+
2. Examine environment variables: `printenv`
158+
```bash
159+
printenv
160+
```
161+
162+
**Output:**
163+
```console
164+
NODE_VERSION=23.11.0
165+
HOSTNAME=ada88201c429
166+
YARN_VERSION=1.22.22
167+
SHLVL=1
168+
HOME=/root
169+
TERM=xterm
170+
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
171+
PWD=/app
172+
```
173+
- Displays all environment variables to your Node.js app
174+
175+
3. Test Redis connectivity: `redis-cli -h redis ping`
176+
```bash
177+
redis-cli -h redis ping
178+
```
179+
180+
**Output:**
181+
```console
182+
PONG
183+
```
184+
185+
- Tests connectivity to your Redis container
186+
- `PONG` response confirms network connectivity
187+
188+
### Debugging Nginx Configuration
189+
```bash
190+
docker exec -it debug-docker_nginx_1 nginx -t
191+
```
192+
193+
**Expected Output:**
194+
```console
195+
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
196+
nginx: configuration file /etc/nginx/nginx.conf test is successful
197+
```
198+
199+
## 5. Health Checks and Readiness Probes
200+
Let's enhance our `docker-compose.yml` with health checks:
201+
202+
```yaml
203+
services:
204+
nodejs-app:
205+
# ... existing config ...
206+
healthcheck:
207+
test: ["CMD", "curl", "-f", "http://localhost:3000"]
208+
interval: 30s
209+
timeout: 10s
210+
retries: 3
211+
212+
redis:
213+
# ... existing config ...
214+
healthcheck:
215+
test: ["CMD", "redis-cli", "ping"]
216+
interval: 30s
217+
timeout: 5s
218+
retries: 3
219+
```
220+
221+
Now check the container health:
222+
``bash
223+
docker ps --format "table {{.Names}}\t{{.Status}}"
224+
```
225+
226+
**Expected Output:**
227+
```console
228+
NAMES STATUS
229+
debug-docker_nginx_1 Up 5 minutes
230+
debug-docker_nodejs-app_1 Up 5 minutes (healthy)
231+
debug-docker_redis_1 Up 5 minutes (healthy)
232+
```
233+
234+
## 6. Temporary Debug Containers
235+
Sometimes you need additional tools. Create a temporary debug container in the same network:
236+
```bash
237+
docker run -it --rm --network debug-docker_default alpine sh
238+
```
239+
240+
Now from this container you can:
241+
1. Test DNS resolution:
242+
```bash
243+
nslookup nodejs-app
244+
```
245+
246+
**Expected Output:**
247+
```console
248+
Server: 127.0.0.11
249+
Address: 127.0.0.11:53
250+
251+
Non-authoritative answer:
252+
Name: nodejs-app
253+
Address: 172.19.0.3
254+
```
255+
256+
- Confirms Docker's internal DNS is working
257+
- Shows the service name resolves to the correct container IP (172.19.03)
258+
259+
2. Check connectivity:
260+
```bash
261+
wget -qO- http://nodejs-app:3000
262+
```
263+
264+
**Expected Output:**
265+
```console
266+
Hello from Node.js!
267+
```
268+
269+
- Shows successful TCP connection to port 3000
270+
- Returns the actual HTTP response from your Node.js app
271+
272+
## 7. Docker System Diagnostics
273+
When facing resource issues:
274+
```bash
275+
docker system df
276+
```
277+
278+
**Example Output:**
279+
```console
280+
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
281+
Images 17 3 2.374GB 2.295GB (96%)
282+
Containers 3 3 2B 0B (0%)
283+
Local Volumes 2 1 88B 88B (100%)
284+
Build Cache 108 0 37.82MB 37.82MB
285+
```
286+
287+
Check detailed resource usage:
288+
```bash
289+
docker stats
290+
```
291+
292+
**Example Output:**
293+
```console
294+
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
295+
5111f46d640b debug-docker_nginx_1 0.00% 9.633MiB / 31.06GiB 0.03% 41.9kB / 126B 0B / 4.1kB 13
296+
e701e4d02bb0 debug-docker_nodejs-app_1 0.00% 13.31MiB / 31.06GiB 0.04% 45.3kB / 3.49kB 0B / 0B 7
297+
3e0399cc7510 debug-docker_redis_1 0.93% 4.691MiB / 31.06GiB 0.01% 42.3kB / 126B 1.43MB / 0B 6
298+
```
299+
300+
## Conclusion
301+
Effective Docker debugging requires a systematic approach. By mastering these techniques, you'll be able to diagnose and resolve even the most complex Docker issues in production environments.
327 KB
Loading

0 commit comments

Comments
 (0)