MERN Stack with Docker
In this article, we will cover how you can use docker compose to setup MERN stack in development environment.
Requirements on our end are pretty simple and straightforward.
- Control our configuration
- Setup the server
- Setup the client
Furthermore we will explore how we can manage our application on docker.
- Inspect status of running containers
- Start or stop the services
- Inspect logs of individual services
Lets Code
We start by first creating our base directory mern-stack.
Within that directory we will create following files and directories.
- Client/Dockerfile
- Server/Dockerfile
- docker-compose.yml
To keep things simple, I created a client folder which includes React as front-end and a server folder which include nodejs express as back-end. There is one docker-compose.yml file to build and spin up the containers. To make it work properly, each of them client and server folder should have a Dockerfile and Docker files are the blueprints that docker-compose will use to build the containers.
Docker require your apps to be enclosed in a container. Let’s define our Dockerfile under the Client and Server directory
Paste the following lines in Dockerfile to setup the Client of the app.
WORKDIR /usr/src/app/client
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Next, move to the server directory and open the Dockerfile and paste the following code.
WORKDIR /usr/src/app/client
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Once we have a docker container we can build it using docker build command, but we need mongodb to be available for our application to work.
Lets solve that by setting up service definitions in docker-compose.yml file.
services:
server:
container_name: todo-server
restart: always
build: ./server
ports:
- '3010:3010'
volumes:
- ./server:/usr/src/app/server
links:
- mongo
client:
container_name: todo-client
restart: always
build: ./client
volumes:
- ./client:/usr/src/app/client
ports:
- '3000:3000'
mongo:
hostname: mongo
restart: always
image: mongo
ports:
- '27017:27017'
After setting up service definition. In the mongodb connection string, replace host by mongo.
const connection = "mongodb://mongo:27017/docker-app";
Managing MERN Stack Services
In this section, we will cover how we can control our docker instance.
Creating Build
We can create build using following simple command.
docker-compose build
Starting Services
We can start services using following simple command.
docker-compose up -d
-d flag instruct docker compose to run services as daemon.
After starting the services. We can access our MERN Stack app server on.
http://localhost:3010
And MERN Stack app client on.
http://localhost:3000
And mongodb on.
http://localhost:27017
Inspecting Services
We can inspect running services using the following command.
docker-compose ps
Inspecting Logs
There are many approaches you can take to inspect logs of running services.
We will start by most simple and primitive approach.
docker-compose logs
Above command will dump logs of all the running services, although I have found this command to be seldom useful.
We will now cover how we can inspect individual services logs.
docker-compose logs [service_name] -f --tail=10
In above command we use -f flag to follow logs and --tail to fetch last 10 lines you can always increase this number to your liking.
Interacting with MERN Stack container
We will use the following command to bind our shell to MERN Stack server and client container.
docker-compose exec -it server /bin/bash
docker-compose exec -it client /bin/bash
After shell is bound you can run any command within MERN Stack server and client container environment it will be pretty much similar to running a remote shell using ssh.
Stopping containers
At last we will cover how we can stop all the running services.
docker-compose down