Skip to content
/ mean-docker Public template

A Mean stack (Angular 17.0.3, Expressjs 4.17.1, MongoDB) jump start project with support of docker.

License

Notifications You must be signed in to change notification settings

nitin27may/mean-docker

Repository files navigation

Mongo Build Expressjs Build Angular Build Nginx Build

MEAN (Stack) using Docker

Overview

This project demonstrates a MEAN (MongoDB, Express, Angular, NodeJS) stack application running on Docker. It is an ideal starting point for creating a full-stack web application and demonstrates both development and production setups using Docker. Additionally, it showcases using GitHub Actions for building and pushing Docker images to Docker Hub.

The architecture of the application while running:

Quick Start

Clone repo, navigate to root folder and run docker-compose -f 'docker-compose.nginx.yml' up

  git clone https://github.com/nitin27may/mean-docker.git
  cd mean-docker 
  docker-compose -f 'docker-compose.nginx.yml' up

Demo

mean-docker-demo.mp4

Project Structure

The apps written in the following JavaScript frameworks/libraries:

folder Description
frontend frontend app using Angular
api api using expressjs
loadbalancer load balancer using nginx
mongo mongo db image setup

Project Details

This application features user registration, login, and a full CRUD (Create, Read, Update, Delete) example with Angular Routing and REST API samples using Express.js. REST services are secured using JWT (JSON Web Tokens).

Technologies Used

Angular (17.0.3)

The frontend of this project is built with Angular, which is represented by the "A" in MEAN stack. To enable Server Side Rendering (SSR), we opted to use the Node.js Alpine image instead of a lightweight Docker image like Nginx to run the Angular application.

The project includes sample code for various functionalities, such as

  • User registration
  • Login
  • Profile Management
  • Complete CRUD example for contacts.

Additionally, there are samples of code for implementing an authentication guard, services, HTTP interceptors, resolvers, and JWT authentication.

This is a simple web application. It has working user registration, login page and there is a complete example of CRUD which contains example for Angular Routing and exprtess js rest api samples. Also, rest services are secure using JWT.

For folder structure details refer this link: [Frontend Folder Structure] (/docs/angular-frontend-structure.md)

Dockerfile for Production Dockerfile for Development

Expressjs (4.17.1)

In MEAN stack, E stands for Expressjs, all rest services are developed using express js.

It contains sample for:

  1. Mongo dB connection and schema validation using Mongoose
  2. JWT implementation for Authorization
  3. API routing
  4. User registration & login APIs
  5. Complete CRUD example for Contact

For folder structure details refer this link: API Folder Structure

Dockerfile for production Dockerfile for development

Mongo DB

We are using Mongodb for database. MongoDB is a cross-platform document-oriented database program. Classified as a NoSQL database program, MongoDB uses JSON-like documents with optional schemas.

Seed data script Database user creation script

NGINX

_Note: only if you are using docker. _

We have uses NGINX loadbalancer in case if there is a requirement that frontend and api need to be exposed on same port. For configutration please check nginx.conf

Load balancer (nginx) Dockerfile

Getting started

Using Docker

Prerequisite

Install latest Docker Desktop

Development mode:

You can start the application in debug mode (database, api and frontend) using docker-compose:

git clone https://github.com/nitin27may/mean-docker.git
cd mean-docker

docker-compose -f 'docker-compose.debug.yml' up

It will run fronend http://localhost:4200 and api on http://localhost:3000. you can also access mongodb on port 27017.

Also, it will automatically refresh (hot reload) your UI for code changes. That is also true for expressjs file changes.

Production mode:

For Production mode, there is 2 options:

Using 2 containers (Express (frontend and api) and Mongo)
  git clone https://github.com/nitin27may/mean-docker.git
  cd mean-docker
  
  docker-compose -f 'docker-compose.yml' up

or just run beow as docker consider default file name 'docker-compose.yml'

  docker-compose up

It will run fronend and api on http://localhost:3000. you can also access mongodb on port 27017

Using 4 containers (Mongo,api, angular and nginx)
  git clone https://github.com/nitin27may/mean-docker.git
  cd mean-docker

  docker-compose -f 'docker-compose.nginx.yml' up

It will run fronend and api on http://localhost. you can aslo access by it's invidual ports. For Frontend http://localhost:4000 and for api http://localhost:3000 .you can also access mongodb on port 27017

About Docker Compose File

The main focus of this project to show case the possible way to run a real application (Mean stack) using docker.

we have considered 3 scenarios:

  1. Using 2 containers (docker-compose.yml)

    • express: To host Frontend (Angular) and backend api (expressjs) together
    • database: To host MongoDB

Note: If in above case we are using MongoDB as managed service then we will require only one container.

version: "3.8" # specify docker-compose version

# Define the services/containers to be run
services:
  express: #name of the second service
    build: # specify the directory of the Dockerfile
      context: .
      dockerfile: dockerfile
    container_name: mean_angular_express
    ports:
      - "3000:3000" #specify ports forewarding
      # Below database enviornment variable for api is helpful when you have to use database as managed service
    environment:
      - SECRET=Thisismysecret
      - MONGO_DB_USERNAME=admin-user
      - MONGO_DB_PASSWORD=admin-password
      - MONGO_DB_HOST=database
      - MONGO_DB_PORT=
      - MONGO_DB_PARAMETERS=?authSource=admin
      - MONGO_DB_DATABASE=mean-contacts
    links:
      - database

  database: # name of the third service
    image: mongo:latest # specify image to build container from
    container_name: mean_mongo
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin-user
      - MONGO_INITDB_ROOT_PASSWORD=admin-password
      - MONGO_DB_USERNAME=admin-user1
      - MONGO_DB_PASSWORD=admin-password1
      - MONGO_DB=mean-contacts
    volumes:
      - ./mongo:/home/mongodb
      - ./mongo/init-db.d/:/docker-entrypoint-initdb.d/
      - ./mongo/db:/data/db
    ports:
      - "27017:27017" # specify port forewarding
  1. Using 4 containers (docker-compose.nginx.yml)

    • angular: Application's frontend (Angular)
    • express: Application's Rest services (expressjs)
    • database: Application database: MongoDB
    • nginx: As laod balancer, also expose UI and API on same ports

Note: If in above case we are using MongoDB as managed service then we will require only one container.

version: "3.8" # specify docker-compose version

# Define the services/containers to be run
services:
  angular: # name of the first service
    build: frontend # specify the directory of the Dockerfile
    container_name: mean_angular
    ports:
      - "4000:4000" # specify port forewarding
    environment:
      - NODE_ENV=dev

  express: #name of the second service
    build: api # specify the directory of the Dockerfile
    container_name: mean_express
    ports:
      - "3000:3000" #specify ports forewarding
      # Below database enviornment variable for api is helpful when you have to use 
      # database as managed service
    environment:
      - SECRET=Thisismysecret
      - MONGO_DB_USERNAME=admin-user
      - MONGO_DB_PASSWORD=admin-password
      - MONGO_DB_HOST=database
      - MONGO_DB_PORT=
      - MONGO_DB_PARAMETERS=?authSource=admin
      - MONGO_DB_DATABASE=mean-contacts
    links:
      - database

  database: # name of the third service
    image: mongo:latest # specify image to build container from
    container_name: mean_mongo
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin-user
      - MONGO_INITDB_ROOT_PASSWORD=admin-password
      - MONGO_DB_USERNAME=admin-user1
      - MONGO_DB_PASSWORD=admin-password1
      - MONGO_DB=mean-contacts
    volumes:
      - ./mongo:/home/mongodb
      - ./mongo/init-db.d/:/docker-entrypoint-initdb.d/
      - ./mongo/db:/data/db
    ports:
      - "27017:27017" # specify port forewarding

  nginx: #name of the fourth service
    build: loadbalancer # specify the directory of the Dockerfile
    container_name: mean_nginx
    ports:
      - "80:80" #specify ports forewarding
    links:
      - express
      - angular
  1. Development Mode (docker-compose.debug.yml)

    It will run 3 containers which are required for development.

version: "3.8" # specify docker-compose version

# Define the services/containers to be run
services:
  angular: # name of the first service
    build: # specify the directory of the Dockerfile
      context: ./frontend
      dockerfile: debug.dockerfile
    container_name: mean_angular
    volumes:
      - ./frontend:/frontend
      - /frontend/node_modules
    ports:
      - "4200:4200" # specify port forewarding
      - "49153:49153"
    environment:
      - NODE_ENV=dev

  express: #name of the second service
    build: # specify the directory of the Dockerfile
      context: ./api
      dockerfile: debug.dockerfile
    container_name: mean_express
    volumes:
      - ./api:/api
      - /api/node_modules
    ports:
      - "3000:3000" #specify ports forewarding
    environment:
      - SECRET=Thisismysecret
      - NODE_ENV=development
      - MONGO_DB_USERNAME=admin-user
      - MONGO_DB_PASSWORD=admin-password
      - MONGO_DB_HOST=database
      - MONGO_DB_PORT=
      - MONGO_DB_PARAMETERS=?authSource=admin
      - MONGO_DB_DATABASE=mean-contacts
    links:
      - database

  database: # name of the third service
    image: mongo # specify image to build container from
    container_name: mean_mongo
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin-user
      - MONGO_INITDB_ROOT_PASSWORD=admin-password
      - MONGO_DB_USERNAME=admin-user1
      - MONGO_DB_PASSWORD=admin-password1
      - MONGO_DB=mean-contacts

    volumes:
      - ./mongo:/home/mongodb
      - ./mongo/init-db.d/:/docker-entrypoint-initdb.d/
      - ./mongo/db:/data/db
    ports:
      - "27017:27017" # specify port forewarding

Pushing Image to Registry (Github Actions)

Earlier, we were using docker hub autobuild triggers to build images and push to registry (Docker Hub), now it is using github action, we can take an example of frontend image: File : angular-build-and-push.yml

name: Angular Build
on:
  push:
    branches: master
    paths: 
    - 'frontend/**'

jobs:
  main:
    runs-on: Ubuntu-20.04
    steps:
      -
        name: Checkout
        uses: actions/checkout@v2
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      -
        name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      -
        name: Login to DockerHub
        uses: docker/login-action@v1 
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          context: frontend/.
          file: frontend/Dockerfile
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/mean-angular:latest
          secrets: |
            GIT_AUTH_TOKEN=${{ secrets.MYTOKEN }}
      -
        name: Image digest
        run: echo ${{ steps.docker_build.outputs.digest }}

here, DOCKERHUB_USERNAME is your docker hub username and DOCKERHUB_TOKEN, we can generate from account settings (account settings > Security > New Access Token) section from your docker hub accounts and add under your github repo > settings > secrets

Without Docker

Prerequisites

  1. Install latest Node js
  2. Install Nodemon as global package (To run exprerssjs in development mode) npm install -g nodemon
  3. Optional (Install Angular CLI npm install -g @angular/cli)
  4. Install Mongodb locally or Signup for a free managed account
  5. Before running the project make sure that you are able to connect MongoDb , you can use Robo 3T for it

Running the Project

Clone the project and run npm install in frontend and api folder.

  git clone https://github.com/nitin27may/mean-docker.git

  cd mean-docker/frontend

  npm i

  npm start 

  cd mean-docker/api

  npm i

  npm start 

For passing enviornment variables (database details) in api, Navigate to api folder, rename .env.example to .env and update your mongo db details there.

Also, you can run d npm run dev-server from frontend folder to run frontend and api together.

It will run Api on http://localhost:3000 and frontend on http://localhost:4200

Roadmap

See the open issues for a list of proposed features (and known issues).

Contributing

Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

MIT

Contact

Nitin Singh - @nitin27may