Rookie mistakes i made while dockerizing a MERN app (and how i fixed them)

KirtiKirti
4 min read

I was trying to dockerize a mern stack app inside my ubuntu vm which is running on vmware. thought it’d be a simple setup —> react frontend, express backend, mongodb database, all connected using docker compose. but for some reason the app just didn’t work.

Mongo kept crashing, backend wouldn’t connect, frontend was up but obviously not useful without the backend working. i kept rebuilding images, deleting volumes, restarting containers, even changed mongo versions multiple times, but it still kept breaking. honestly it got super frustrating. but eventually, after trying a bunch of things and reading logs properly (which i should’ve done from the beginning lol), i finally got it working. so this blog is just a breakdown of everything that went wrong, the fixes that worked, and some tips that might help if you're stuck on something similar.

Initial docker-compose.yml

Here’s the base I started with:

services:
  backend:
    build: ./mern/backend
    ports:
      - "5050:5050" 
    networks:
      - mern_network
    environment:
      MONGO_URI: mongodb://mongo:27017/mydatabase  
    depends_on:
      - mongodb

  frontend:
    build: ./mern/frontend
    ports:
      - "5173:5173"  
    networks:
      - mern_network
    environment:
      REACT_APP_API_URL: http://backend:5050 

  mongodb:
    image: mongo:latest  
    ports:
      - "27017:27017"  
    networks:
      - mern_network
    volumes:
      - mongo-data:/data/db  

networks:
  mern_network:
    driver: bridge 

volumes:
  mongo-data:
    driver: local

Everything was ready to run.

Or so I thought.

Crash #1 — MongoDB Container Exited With Code 132

I ran:

docker compose up --build

MongoDB immediately crashed. I checked the logs:

MongoDB 5.0+ requires a CPU with AVX support...
Exited with code 132

What the heck is AVX? Turns out it’s an instruction set — basically special instructions that some modern CPUs understand. But not all CPUs support AVX. And MongoDB 5+ needs it.

I was unknowingly pulling mongo:latest, which defaults to MongoDB 5+. But here’s the catch — I was running all of this inside my VirtualBox Ubuntu VM, which doesn’t support AVX at all. So even if my host machine does, the VM doesn't expose it. Result? MongoDB just nopes out with exit code 132.

Fix? I switched to an older version that doesn’t need AVX:

image: mongo:4.4

Port 27017 Already in Use

Docker spat out:

Bind for 0.0.0.0:27017 failed: port is already allocated

I wasn’t even running Mongo locally, but it turned out Docker had some zombie containers hogging the port.

Fix:

Removed the port mapping (not needed for internal Docker communication):

# Removed:
# ports:
#   - "27017:27017"

Cleaned up:

docker container prune -f
docker volume prune -f

Docker Still Used mongo:latest

Even after changing to mongo:4.4, Docker ignored it.

Fix:

docker rmi mongo:latest
docker compose build --no-cache
docker compose up

This finally pulled the right image.

Backend Crash: Unrecognized field 'apiVersion'

My MongoDB connection had this:

const client = new MongoClient(URI, {
  serverApi: {
    version: ServerApiVersion.v1,
    strict: true,
    deprecationErrors: true,
  },
});

Error:

MongoServerError: Unrecognized field 'apiVersion'

Apparently serverApi is only for Atlas/Mongo 5+. MongoDB 4.4 didn’t like it.

Fix:
Simplified the connection:

const client = new MongoClient(URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

backend connected succesfully

Key Takeaways (aka the scars I earned)

1. Don't trust latest

Always pin your Docker images. latest is risky, especially for databases like Mongo.

image: mongo:4.4  # or 4.2, 5.0 — whatever you know works

2. Read. The. Logs.

Seriously. I ignored logs thinking they were just noise. Turns out they were yelling the answers at me.

3. Rebuild Often

When changing base images or Dockerfiles:

docker compose build --no-cache

Docker's caching can trap you.

4. Don't expose ports unless you need to

Docker services can talk to each other via internal DNS. No need to expose Mongo on host.

Final Thoughts

If you're ever stuck on Docker and everything feels broken:
You’re not alone.
It will click. Bit by bit. Container by container. Log line by log line.

I nearly gave up, but fixing each bug helped me understand the system more deeply — and now I’m confident to build even bigger projects next.

What’s Next?

Now that it’s running:

  • Maybe I’ll add Mongo Express for easier DB access.

  • Or build a CI/CD pipeline.

  • Or write a second blog about deploying this to AWS EC2 or ECS.

But for now?

I’m just vibing in localhost:5173, proud that I got this thing to run. 💪

The repo : https://github.com/imkirti-jpg/docker-compose-MERN

0
Subscribe to my newsletter

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

Written by

Kirti
Kirti

Hi, I'm KirtiI’m actively learning AWS, Python automation, and cloud best practices through real-world projects. Every challenge is a step forward, and every solution is something worth sharing. On this blog, you’ll find: Simplified guides on AWS core services Lessons from my journey breaking into cloud engineering I believe in learning in public—and this blog is where I document my progress, challenges, and wins.