DEV Community

Cover image for From 500 Errors to a Fully Working Cloud App: My EpicBook Deployment on Azure
Ebelechukwu Lucy Okafor
Ebelechukwu Lucy Okafor

Posted on

From 500 Errors to a Fully Working Cloud App: My EpicBook Deployment on Azure

This week, I moved beyond simple deployments and built a real-world, multi-tier application architecture using Terraform + Ansible + Nginx + Node.js + MySQL on Microsoft Azure.
And honestly? It didn’t work at first.
But that’s where the real learning happened.
Let me walk you through the full journey, including the mistakes, fixes, and key DevOps lessons you can apply immediately.

The Goal
Deploy a production-style web application (EpicBook) with:
🌐 Web Layer → Nginx (Reverse Proxy)
⚙️ App Layer → Node.js (Express app)
🗄️ Database Layer → MySQL (separate VM)
🏗️ Infrastructure → Terraform
🤖 Automation → Ansible

Step 1: Provisioning Infrastructure with Terraform
Instead of manually creating servers, I used Terraform to spin up:
4 Virtual Machines (web1, web2, app, db)
Virtual Network + Subnets
Public IPs
Network Security Groups
terraform init
terraform plan
terraform apply

Lesson: Infrastructure should be code. If you can’t recreate it in minutes, it’s not production-ready.

Step 2: SSH Setup (First Real Problem)
After provisioning, Ansible couldn’t connect:
UNREACHABLE! SSH host key verification failed

Why does this happen?
Every time Terraform creates new VMs, they get new SSH fingerprints.
Fix:
ssh-keyscan -H >> ~/.ssh/known_hosts

Lesson: Always run ssh-keyscan after redeploying infrastructure.

Step 3: Running Ansible
I executed my playbook:
ansible-playbook -i inventory.ini site.yml

✔ Everything passed
✔ No errors
But then I opened the browser…

Step 4: The 500 Internal Server Error
500 Internal Server Error
nginx/1.18.0

At this point, many people would think:
“But Ansible said SUCCESS…”
This is where DevOps thinking matters.

Step 5: Debugging the Problem
I inspected the application:
cat /var/www/epicbook/server.js

Discovery:
It’s a Node.js app
Runs on port 8080
Not a static website
The mistake:
I configured Nginx like this:
root /var/www/epicbook;

That only works for HTML files, not backend apps.

Step 6: Fixing the Architecture
This was the turning point.
✅ Fix 1: Nginx Reverse Proxy
location / {
proxy_pass http://localhost:8080;
}

Now Nginx forwards traffic to Node.js.

✅ Fix 2: Install Node.js

  • name: Install Node.js apt: name: nodejs state: present

✅ Fix 3: Install Dependencies

  • name: Install npm packages npm: path: /var/www/epicbook

✅ Fix 4: Run App as a Service
Created a systemd service:
ExecStart=/usr/bin/node server.js

✅ Fix 5: Database Setup
Installed MySQL on the DB server
Created:
database: bookstore
user: epicbook

✅ Fix 6: Use Private Network (CRITICAL)
Instead of:
"host": "127.0.0.1"

I used:
"host": "10.0.1.7"
Lesson: Databases should NEVER be exposed publicly.
Other Errors I Encountered

  1. Git “Dubious Ownership” fatal: detected dubious ownership

✔ Fix:
Remove and re-clone the directory

  1. SSH Timeout Connection timed out

✔ Fix:
Retry + verify connectivity

Final Result
After fixing everything:
✅ App running on both web servers
✅ Nginx routing traffic correctly
✅ Node.js processing requests
✅ MySQL storing data
Open in browser:
http://
http://

Idempotency Check
I ran the playbook again:
ansible-playbook -i inventory.ini site.yml

✔ changed=0
Lesson: Good automation should be safe to run multiple times.

What I Learned (The Real Value)
This assignment wasn’t just about tools it was about thinking like a DevOps engineer.
Key Takeaways:
✔ “Success” in automation doesn’t mean the app works
✔ Always verify in the browser (real user test)
✔ Understand your application (Node.js ≠ static site)
✔ Debugging is more important than writing code
✔ Architecture decisions matter more than commands

Final Insight
A deployment is only successful when a real user can access the application — not when the playbook says “OK”.

If You're Learning DevOps…
Start building projects like this:
Multi-tier apps
Real debugging scenarios
Infrastructure + application together
That’s how you move from:
👉 “I know commands”
to
👉 “I can solve real-world problems”

Let’s Connect
If you’re also learning DevOps or working on similar projects, I’d love to connect and learn together.

DevOps #Terraform #Ansible #Azure #NodeJS #CloudComputing #LearningInPublic

Top comments (0)