🐳 When Docker Containers Finally Talk to Each Other — A Small Win, A Big Lesson

paritosh patiparitosh pati
2 min read

There’s something really satisfying about watching your containers work perfectly after hours of troubleshooting. Today, I ran into a classic case while setting up a simple two-tier app using Flask + MySQL with Docker. Let me walk you through what went wrong, how I fixed it, and what I learned.


🧪 The Setup

I was building a Flask app that connects to a MySQL database. Both were running in separate containers — pretty straightforward with Docker Compose. Here's a glimpse of my initial setup:

yamlCopyEdit# docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: mydb
      MYSQL_USER: default_user
      MYSQL_PASSWORD: secret
    ports:
      - "3306:3306"

  web:
    build: .
    depends_on:
      - db
    environment:
      MYSQL_HOST: db
      MYSQL_USER: default_user
      MYSQL_PASSWORD: secret
      MYSQL_DB: mydb
    ports:
      - "5000:5000"

🐞 The Errors I Faced

❌ Error 1: Access Denied

arduinoCopyEditMySQLdb._exceptions.OperationalError: (1045, "Access denied for user 'default_user'@'172.20.0.3'")

Turns out, either the username/password didn’t match or the environment variable was missing from the MySQL container. After cross-verifying, I realized I forgot to pass the correct values in the docker-compose.yml. A simple fix, but easy to miss.

❌ Error 2: Can't Connect to MySQL

arduinoCopyEditMySQLdb.OperationalError: (2002, "Can't connect to server on 'mysql'")

This was trickier. The issue? The Flask app was trying to connect before MySQL was ready.


🛠️ The Fix

Here’s how I resolved it:

  1. Corrected all environment variables — double-checked both Flask and MySQL configs.

  2. Used service name (db) instead of IP for MYSQL_HOST.

  3. Added retry logic in Flask app to wait for MySQL:

pythonCopyEditimport time

def init_db():
    for _ in range(5):
        try:
            cur = mysql.connection.cursor()
            return
        except:
            print("Waiting for DB...")
            time.sleep(5)
  1. Used Docker logs effectively to track errors in real-time:
bashCopyEditdocker logs <container_id>

🎉 The Result

Eventually, the app connected to the database, containers were communicating perfectly, and I was able to see the application running smoothly in the browser.


💡 Takeaways

  • Don’t overlook environment variables — they make or break Docker setups.

  • Container names > hardcoded IPs.

  • Services take time to become ready. Add retries or wait strategies.

  • Read logs — they tell the real story.


💬 Final Thoughts

What felt like a small issue turned out to be a great learning moment. Troubleshooting Docker environments isn’t just about fixing; it’s about understanding how services interact and depend on each other.

Every error is a lesson. Every fix is a win. And when it works... it feels so good. 😌


Have you faced similar Docker woes? Share your experience in the comments!

#Docker #Flask #MySQL #DevOps #Python #Containers #Debugging #Hashnode #LearningInPublic #TechBlog

0
Subscribe to my newsletter

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

Written by

paritosh pati
paritosh pati