Hosting Backend + Database with Docker Compose: My Half-Hour Mystery with Logs

So recently, I was experimenting with hosting both a backend (Node.js) and a MySQL database together using a docker-compose.yml file.
Sounds simple, right? Spin up two containers and boom — everything works.

Well… not exactly.


The Setup

  • One container for my Node.js app

  • One container for MySQL

  • Both wired together in docker-compose.yml

I happily ran docker-compose up --build -d, sat back with a smile, and…

  • MySQL ✅ Running fine

  • Node.js ❌ Creating → Exited → Restarting → Exited

On repeat.
On repeat.
On repeat.

For almost half an hour I stared at it like:
"Why you no run, Node?!"


The Turning Point: Logs to the Rescue

I finally asked AI for help (because googling “why is my container restarting” gave me an existential crisis).
The advice?

Run docker logs node_app

And there it was, staring back at me like a horror movie jump scare:

Error: Environment variables not set

My app was basically yelling at me:
"Dude, you forgot to feed me my ENV values… what do you expect me to do, run on vibes?" 😂


The Fix

  1. Checked my .env file → Values were there.

  2. Realized my app wasn’t actually picking them up inside the container.

  3. Adjusted my docker-compose.yml to properly load env_file: .env.

After fixing that, my Node.js container finally said:
"Fine, I’ll run. But next time, don’t starve me."


Bonus Lesson: .gitignore Your .env

While I was at it, I also learned one more important lesson:

Always add your .env file to .gitignore so you don’t accidentally leak secrets to GitHub.
That way, you can still safely use git add . without worrying that your database password will become open-source.


Key Takeaways

  • Always check logs firstdocker logs <container_name> can save you hours of confusion.

  • ENV values matter → Your app can’t magically know them; you have to pass them in.

  • .env + .gitignore = best friends → Don’t let secrets slip into Git.


At the end of the day, this little debugging journey wasted me 30 minutes but taught me a lesson I’ll never forget:

Containers don’t crash for no reason. They crash because you messed up.


That’s it for today — small learning, big value.
Now I can proudly say: Backend + Database hosted with Docker Compose, and I didn’t cry (much).

August 21

🔄 Update: How I Solved My Issues

After publishing this blog, I finally solved the problems I was stuck with. Here’s what happened:

1️⃣ MySQL Hanging Issue

At first, I was accessing MySQL inside the container with:

docker exec -it mysql bash
mysql -u root -p

But since my database had too many rows and columns, MySQL tried to dump all data in the terminal and it kept hanging.

Fix:

  • I decided to use MySQL Workbench instead.

  • For that, I exposed port 3306 in my docker-compose.yml (it was not exposed earlier, since the DB was only running inside the container).

  • Once I did that, I was able to connect MySQL Workbench → Container → Database smoothly.

  • Took some help from AI debugging to figure out the root cause 😅.


SSL & Nginx in Docker-Compose

I also learned that I could manage my SSL certificates inside the same docker-compose.yml.

Fix:

  • Used Nginx as a reverse proxy inside the docker-compose setup.

  • Configured nginx.conf to allow entries for both port 80 (HTTP) and 443 (HTTPS).

  • Added my chatbot + SSL configuration directly in the compose setup, which made it much cleaner.


🎉Problem Solved!

These changes finally fixed my issues:

  • MySQL Workbench helped avoid hangs.

  • Exposing 3306 allowed external DB management.

  • Nginx + SSL worked inside a single docker-compose file.


Lesson Learned: Sometimes it’s not just about running containers — it’s about exposing the right ports and configuring services properly.

0
Subscribe to my newsletter

Read articles from Taranpreet Batra directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Taranpreet Batra
Taranpreet Batra