Dockerize and orchestrate your fullstack MEAN app easily

In the era of cloud services on demand, you may ask : why bothering to dockerize your app while you can deploy your frontend on a static AWS S3 hosting, your backend on lambdas, your API on AWS API gateway and your database on RDS ? Simply because it’s worth knowing how easy it is to actually create a fullstack app and deploy it all on a single hosting using docker compose orchestration.

Image for post
Image for post

For my side projects, I’m using a very basic hosting provider which is a dedicated server for less than few bucks a month running ubuntu server. I like using it to test side projects and for conveniency, I dockerize all the components and use docker compose to orchestrate all the containers. The main goal here is to deploy quickly your app for testing and experimenting on the field, rather than dealing with distributed services. Once you extract the value of your experiment and you see tractions for your app, then switching to other architecture is of course worthful.

In this article, we will cover
1. how to create and dockerize a MEAN app
and 2. How to orcherstrate all services using docker-compose

Even though I will add some code snippet for each element of the technical stack, the focus will be mainly given on the docker part. This means that you should be familiar with mysql, angular and nodeJS and have all dependencies already installed (node, npm, angular-cli).

Pre-requisite

Depending of your Operating system, you will need to install Docker daemon and docker-compose on your Operating System.

create a MEAN app

MEAN stands usually for MongoDB — Express — Angular — NodeJs but in this article, I prefer using Mysql instead of MongoDB.

Let’s first structure our project with the following directory architecture :

Image for post
Image for post

As you can see, I created a main directory called mean-docker and 3 sub-directories for each of the components of the projects. In this manner, each sub-directory will have its own Dockerfile. Let’s see what they look like.

1. database Dockerfile

In the database folder, create a file called Dockerfile and simply add the content below :

Once build and loaded as a container (that will cover later on), this will create a mysql server with the root password you defined. Also, you can create a directory called sql-scripts if you need to create at launch time initial tables and prefilled values. Here are some examples :

Image for post
Image for post

2.1 backend architecture

We will of course use nodeJs as a javascript runtime for our backend service. We will rely on Express for the web application framework and of course mysql driver for querying our mysql database. Here what the backend/package.json looks like :

Going into the backend folder and running npm install will install all the dependencies listed in package.json.

As you can see if the package.json file, if we run npm start, nodeJS will load the file called app.js that will contain our API as well as our code to interact with mysql. Here is the content of app.js :

For properly structuring our backend, we have separated the server configuration/loading (app.js) from the API logic (api.js). Below a very simple example of api.js that will interact with our mysql database to retrieve and expose data :

What is important here is that we named our database host as ‘database’. This link is in fact described later on in our docker-compose.yml file in which we will link the database service to the backend service so the backend will be able to interact as we described.

As you can see, for the example purpose, we have a single route GET /jobs that will return all the jobs stored in our mysql service.

2.2 backend Dockerfile

Now that we have build our backend, let’s simple dockerize it by firstly creating a Dockerfile :

Later on, when we will create our backend docker image, we don’t want to include all the local node_modules folder into the image (as it will be also created when npm install will be called by docker), so we can create a simple .dockerignore file including :

Our final backend folder content should look like :

Image for post
Image for post

Let’s now create an angular frontend and dockerize it.

3.1 frontend architecture

Go back to the root mean-docker folder and simply run the angular command to create an angular project :

This will create all the angular structure. Let’s focus simply on how to query our backend. To to so, we will create a JobRepositoryService that will have a method querying the GET /jobs API and returning asynchronously an array of Job using RxJs :

Then, in any of our angular composent, we can inject this JobRepositoryService and subscribe to the getJobs Observable :

3.2 frontend Dockerfile

The frontend Dockerfile looks very much like the backend Dockerfile as they both use a node image :

The only difference here is that we expose our frontend on the regular 80 port. Do not also forget to create the .dockerignore file including the following content for the same reasons :

4. Docker compose

Now we have all our services expressed with their Dockerfile, we can describe the orchestratation declaring a simple docker-compose.yml file located on the root mean-docker folder :

We have 3 distinct services in our MEAN stack. Each of them having a Dockerfile. So in the build node, we locate the folder where the Dockerfile is located. We also define the port forwarding. And most importantly, we create a link between the backend and the database container by specifying the links node.

Now, to create the images and launch the containers, we just have to run the following command :

And to check the status of the containers, we have the following command :

You app is now running and you can access your frontend using localhost:4200 (if you encounter an error, you can try to enhance the ng start script from the frontend/package.json by adding the following :

Conclusion

As you can see, creating a dockerize MEAN stack is very easy. You simply need to structure your project in a way that each of your service has its own Dockerfile. Then, by using docker-compose, you can run your multi-container docker app and create links between services.

I’m personnaly using this orchestration approach for quickly creating MVPs in order to focus on the learning of the MVP experiment rather than focusing on scalability at this early stage.

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store