From Tutorial to Real DevOps: How I Deployed a Full Stack App on AWS (and Fixed Everything That Broke)
Most tutorials make DevOps look easy.
You follow steps → run commands → everything works.
But when I tried deploying a real project on AWS using Docker…
Nothing worked the first time.
This blog is not a “perfect guide.” It’s a real debugging journey — where things broke, and I fixed them step by step.
🧠 Project Overview
I deployed a full-stack application using:
🐳 Docker & Docker Compose
⚙️ Django (Backend API)
🗄️ MySQL (Database)
🌐 Nginx (Reverse Proxy)
☁️ AWS EC2 (Cloud Hosting)
Architecture:
User → Nginx → Django → MySQL
⚙️ Initial Setup
After setting up my EC2 instance and cloning the project, I ran:
docker compose up --build
And that’s where the real journey began.
💥 Issue 1: Disk Space Error
❌ Error:
no space left on device
🧠 Understanding:
Docker images (especially Python + MySQL) are heavy. My EC2 instance didn’t have enough storage.
✅ Fix:
- Cleaned unused Docker resources:
docker system prune -a
Removed unnecessary images & containers
Learned importance of resource management
💥 Issue 2: Permission Denied (mysql-data)
❌ Error:
permission denied: mysql-data/#innodb_redo
🧠 Understanding:
Docker was trying to include database files in the build context. These files had restricted permissions.
✅ Fix:
Created .dockerignore:
mysql-data/
👉 This prevents Docker from sending DB files during build.
💥 Issue 3: Nginx Cannot Find Django
❌ Error:
host not found in upstream "django_cont"
🧠 Understanding:
Docker networking works using service names, not container names.
❌ Wrong:
proxy_pass http://django_cont:8000;
✅ Fix:
proxy_pass http://django:8000;
💥 Issue 4:
Django Cannot Connect to Database
❌ Error:
Unknown server host 'mysql'
🧠 Understanding:
My docker-compose service name was:
db:
But Django was trying:
DB_HOST=mysql
✅ Fix:
DB_HOST=db
💥 Issue 5: Service Startup Timing Problem
❌ Error:
Can't connect to server on 'db'
🧠 Understanding:
MySQL takes time to start
Django tries immediately → fails
✅ What happened:
After a few seconds, MySQL became ready → Django connected successfully.
👉 This taught me:
Not all errors are permanent — some are timing issues
💥 Issue 6:
App Works in Terminal but Not Browser
❌ Problem:
curl localhost→ works ✅Browser →
ERR_CONNECTION_TIMED_OUT❌
🧠 Understanding:
This means:
App is running internally, but blocked externally
✅ Fix:
Checked AWS Security Group
Allowed inbound traffic on port 80
🎉 Final Result
After solving all issues:
✅ Django running via Gunicorn
✅ Nginx reverse proxy working
✅ MySQL connected
✅ App accessible via public IP
🧠 Key Learnings (Most Important Part)
🔍 1. Log Reading > Tutorials
Instead of guessing, I learned to:
Find the first error
Identify the component
Fix root cause
🌐 2. Docker Networking is Critical
Services communicate via service names
Not container names
⚙️ 3. Debugging is Layered
| Layer | Example Issue |
|---|---|
| System | Disk full |
| Docker | Build failure |
| Networking | Host not found |
| App | DB connection |
| Cloud | Security group |
⏱️ 4. Timing Matters
Not all failures are real bugs — some are just:
Services not ready yet
☁️ 5. Cloud != Local Machine
Even if everything works locally:
Cloud networking can still break your app
💼 Resume Highlight
Deployed a containerized Django application using Docker Compose with Nginx reverse proxy and MySQL on AWS EC2. Diagnosed and resolved real-world issues including disk limitations, container networking, service dependencies, and cloud firewall configurations.
🚀 What’s Next
Add custom domain + HTTPS (SSL)
Setup CI/CD pipeline (Jenkins / GitHub Actions)
Optimize Docker images (multi-stage builds)
Add monitoring (Prometheus / Grafana)
💬 Final Thoughts
This project didn’t teach me just “how to deploy an app.”
It taught me:
How to think like an engineer.
If your project is breaking…
👉 Good. That’s where real learning begins.
If you're also learning DevOps or building something similar, feel free to connect 🤝 Let’s grow together 🚀
#DevOps #Docker #AWS #Django #LearningInPublic #LazyStack


