How to Dockerize a Full Stack MEVN Application

First things first. Let’s check the directory structure of the app.

A Full Stack MEVN Application

A Full Stack MEVN Application

Let’s take a look into the DB image first.

1FROM mongo:latest
2
3WORKDIR /app
4COPY . /app
5
6ENV MONGO_INITDB_ROOT_USERNAME=root
7ENV MONGO_INITDB_ROOT_PASSWORD=password
8
9EXPOSE 27017

I thought importing dump data should be working if I used CMD or ENTRYPOINT.
It didn’t work though. So I picked a solution using exec and shell script. It’s in the last part. 😉
Now, let’s check the Express.js backend server image.

1FROM node:12
2WORKDIR /app
3COPY . /app
4RUN npm install
5CMD ["node", "index.js"]

Pretty simple, isn’t it? 😉
Let’s move on to the FE part.

 1FROM nginx:latest
 2WORKDIR /app
 3COPY . /app
 4RUN apt update -y \
 5    && apt install curl -y \
 6    && curl -sL https://deb.nodesource.com/setup_12.x | bash - \
 7    && apt install nodejs -y \
 8    && node --version \
 9    && npm install \
10    && npm run build \
11    && rm -rf /usr/share/nginx/html/* \
12    && cp -r /app/dist/* /usr/share/nginx/html/ \
13    && service nginx start
14EXPOSE 80

You know what? Too much complicated? 😉 This is not a raw development server, but a production server.
But this is not the best way to deploy Vue apps, better solution is to separate the building stage using node docker image, and also need some hack in nginx configuration in case you use history mode.
Finally, let's check our docker-compose.yml file.

 1version: "3"
 2services:
 3  db:
 4    container_name: mongo-container
 5    build: ./backend/db
 6    environment:
 7      MONGO_INITDB_DATABASE: sageglass
 8    ports:
 9      - "27017:27017"
10    volumes:
11      - db-data:/data/db
12    restart: always
13  frontend:
14    container_name: vuejs-app
15    build: ./frontend
16    ports:
17      - "80:80"
18    restart: always
19  backend:
20    container_name: express-app
21    build: ./backend
22    depends_on:
23      - db
24    ports:
25      - "9000:9000"
26    restart: always
27volumes:
28  db-data:

Now, here comes the shell script named “db-init.sh” for importing db dump.

1mongoimport --authenticationDatabase admin --username root --password password --host localhost --db sageglass --collection location --type json --file location.json \
2&& mongoimport --authenticationDatabase admin --username root --password password --host localhost --db sageglass --collection config --type json --file config.json \
3&& mongoimport --authenticationDatabase admin --username root --password password --host localhost --db sageglass --collection overlay --type json --file overlay.json \
4&& mongoimport --authenticationDatabase admin --username root --password password --host localhost --db sageglass --collection map --type json --file map.json --jsonArray \
5&& mongoimport --authenticationDatabase admin --username root --password password --host localhost --db sageglass --collection connected --type json --file connected.json --jsonArray \
6&& mongoimport --authenticationDatabase admin --username root --password password --host localhost --db sageglass --collection non-connected --type json --file non-connected.json --jsonArray \
7&& mongoimport --authenticationDatabase admin --username root --password password --host localhost --db sageglass --collection health --type json --file health.json \
8&& mongoimport --authenticationDatabase admin --username root --password password --host localhost --db sageglass --collection tints --type json --file tints.json --jsonArray \
9&& mongoimport --authenticationDatabase admin --username root --password password --host localhost --db sageglass --collection upcoming --type json --file upcoming.json --jsonArray

Need to be careful to the last tag “–jsonArray”.
When should it be there?
Literally, it should be there when the data is json array, not an object.
Alright, now let’s get the whole app up and running with these commands:

1docker-compose up -d
2docker exec -it mongo-container sh /app/db-init.sh

Awesome! We got the whole app containerized.
The whole source code to review the real flow is here.
Happy dockerizing! 🙂

comments powered by Disqus