How I Dockerized a Full-Stack Chat App as a Single Deployment
When I built my real-time chat application, getting it running locally was straightforward — start the React dev server, spin up Node.js, make sure MongoDB is running. But deploying it? That was a different story.
The app has three moving parts: a React 19 frontend, a Node.js/Express backend with Socket.io, and a MongoDB database. Each one has its own dependencies, its own environment variables, its own way of breaking.
Docker Compose turned out to be the right tool for this. Instead of deploying each service separately and hoping they could find each other, I defined everything in a single docker-compose.yml. The backend and frontend each got their own Dockerfile, and MongoDB ran from the official image.
The trickiest part was getting Socket.io to work correctly behind the container network. WebSocket connections don't behave the same way as regular HTTP requests when you're routing through Docker's internal DNS. I had to configure the CORS origins carefully and make sure the client was connecting to the right host.
Environment variables were another pain point. In development, everything reads from .env files. In Docker, you need to pass them through the compose file or use Docker secrets. I ended up using a combination — non-sensitive config in the compose file, and sensitive values (like the MongoDB connection string and Clerk API keys) through .env files that Docker Compose picks up automatically.
The result: anyone can clone the repo, run docker-compose up, and have the entire application running — frontend, backend, database, everything. No "works on my machine" problems.
Key takeaways: - Docker Compose is perfect for multi-service applications where services need to communicate - WebSocket connections need special attention in containerized environments - Keep your Dockerfiles lean — multi-stage builds for the frontend reduced the image size significantly - Always test your containerized app with fresh volumes to catch missing environment variables early