🐳 Docker Debugging Deep Dive: Fixing Port Conflicts, Volumes & Networking in a Django + MySQL + NGINX Setup

Recently, I ran into a Docker-related issue that looked deceptively simple — but turned into a valuable deep-dive into container networking, volume persistence, and real-world troubleshooting.
Here’s a breakdown of what happened, how I debugged it, and what I learned.
🧩 The Stack
I was containerizing a basic full-stack app using:
Django (backend API)
MySQL (relational database)
NGINX (reverse proxy)
The app was orchestrated using Docker Compose, with each service defined as a container.
❌ The Problem
When I spun up my containers, everything seemed to build just fine — until the deployment hit a wall with this error:
bashCopyEditError starting userland proxy: listen tcp4 0.0.0.0:80: bind: address already in use
In short: NGINX was trying to bind to port 80, but something else was already using it.
🛠️ The Fixes — Step by Step
1. 🔍 Solving the Port Conflict
This was the first and most immediate blocker. I found that my host machine already had a service (probably Apache or another NGINX instance) using port 80.
✅ Solution:
Either stop the conflicting service, or
Change the NGINX container’s exposed port in the
docker-compose.yml
:
yamlCopyEditports:
- "8080:80" # Now maps container port 80 to host port 8080
2. 🧹 Cleaning Up Residual MySQL Data
Even after restarting containers, MySQL was acting strangely — failing on startup with data-related errors.
✅ Solution:
Removed the old volume storing MySQL data.
Re-created the volume externally to decouple lifecycle from containers.
bashCopyEditdocker volume rm my_mysql_data
docker volume create my_mysql_data
Then updated docker-compose.yml
:
yamlCopyEditvolumes:
- my_mysql_data:/var/lib/mysql
3. 🌐 Creating a Custom Docker Bridge Network
To ensure all services could talk to each other reliably (especially NGINX to Django, and Django to MySQL), I created an external bridge network.
bashCopyEditdocker network create notes-app-nw
Then added this to the Compose file:
yamlCopyEditnetworks:
default:
external:
name: notes-app-nw
This ensured all containers shared a common network with static naming.
🧪 Final Result
After these changes, I re-ran:
bashCopyEditdocker-compose up --build
And this time — everything just worked. ✅
MySQL initialized with a fresh schema.
Django connected cleanly to the database.
NGINX reverse-proxied requests to Django on the internal network.
💡 Key Takeaways
Port 80 errors are common — always double-check what’s running on your host.
Volumes persist across container restarts — don’t forget to clean or isolate them when debugging.
Custom Docker networks make multi-container setups more predictable and secure.
Docker is powerful but requires systems thinking — it’s not just about code, it’s about configuration and infrastructure.
🧠 Final Thoughts
This was a great exercise in real-world Docker troubleshooting. It reminded me that debugging container issues isn’t just about error messages — it’s about understanding how your services interact, persist data, and expose themselves to the outside world.
If you’ve faced a similar issue — or have tips for handling Docker networking and volumes — drop a comment or share your experience!
Subscribe to my newsletter
Read articles from paritosh pati directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
