Skip to content

microservices-suite/node-microservices-suite

Repository files navigation

Microservices Suite 🦧

Overview

Welcome to the πŸ“¦ Microservices Suite project! This suite is a collection of Node.js microservices built using the 🦧 mono-repo strategy and leveraging the yarn workspaces concept. Each microservice runs in its isolated Docker container, and Kubernetes orchestrates the deployment, providing scalability and efficiency. To easily work with a @microservices-suite monorepo you need to install Suite CLI. With Suite you can easily scaffold,manage and automate your monorepo in development, CI as well as production. Check the installation guidelines in the README.md section of the .suite-cli root.

Project file structure

β”œβ”€ node-microservices-suite
β”‚  β”œβ”€ .suite-cli/
|  β”‚  β”œβ”€ cli/
|  β”‚  β”‚  β”œβ”€ scripts/
|  β”‚  β”‚  β”œβ”€ cli.js
|  β”‚  β”‚  β”œβ”€ package.json
|  β”‚  β”‚  β”œβ”€ README.md
β”‚  β”œβ”€ api-gateways/
|  β”‚  β”œβ”€ app-1/
|  β”‚  β”‚  β”œβ”€ nginx
|  β”‚  β”‚  β”œβ”€ apache
|  β”‚  β”‚  β”œβ”€ README.md
β”‚  β”œβ”€ graphql/
|  β”‚  β”œβ”€ app-1/
|  β”‚  β”‚  β”œβ”€ apollo-server
|  β”‚  β”‚  β”œβ”€ README.md
β”‚  β”œβ”€ data-persistence/
|  β”‚  β”œβ”€ db-1/
|  β”‚  β”‚  β”œβ”€ Dockerfile
|  β”‚  β”‚  β”œβ”€ README.md
β”‚  β”œβ”€ k8s/
|  β”‚  β”œβ”€ service-1/
|  β”‚  β”‚  β”œβ”€ cluster-ip-service.yml
|  β”‚  β”‚  β”œβ”€ cluster-deployment.yml
|  β”‚  β”‚  β”œβ”€ ingress-service.yml
|  β”‚  β”‚  β”œβ”€ README.md
|  β”œβ”€ microservices/
|  β”‚  β”œβ”€ service-1/
|  β”‚  β”‚  β”œβ”€ src
|  β”‚  β”‚  β”œβ”€ .env
|  β”‚  β”‚  β”œβ”€ .env.dev
|  β”‚  β”‚  β”œβ”€ app.js
|  β”‚  β”‚  β”œβ”€ Dockerfile
β”œβ”€ β”‚  β”‚  β”œβ”€ Dockerfile.dev
|  β”‚  β”‚  β”œβ”€ ecosystem.config.js
|  β”‚  β”‚  β”œβ”€ index.js
|  β”‚  β”‚  β”œβ”€ package.json
|  β”‚  β”‚  β”œβ”€ task.json
|  β”œβ”€ shared/
|  β”‚  β”œβ”€ library-1/
|  β”‚  β”‚  β”œβ”€ APIError.js
|  β”‚  β”‚  β”œβ”€ catchAsync.js
|  β”‚  β”‚  β”œβ”€ index.js
|  β”‚  β”‚  β”œβ”€ package.json
|  β”‚  β”‚  β”œβ”€ pick.js
|  β”‚  β”‚  β”œβ”€ README.md
|  β”‚  β”‚  β”œβ”€ validate
β”‚  β”œβ”€ tests/
|  β”‚  β”œβ”€ service-1/
|  β”‚  β”‚  β”œβ”€ e2e/
|  β”‚  β”‚  β”œβ”€ integration/
|  β”‚  β”‚  β”œβ”€ snapshot/
|  β”‚  β”‚  β”œβ”€ unit/
|  β”‚  β”‚  β”œβ”€ README.md
|  β”œβ”€ .gitignore
|  β”œβ”€ .npmrc
|  β”œβ”€ .yarnrc.yml
|  β”œβ”€ docker-compose.yml
|  β”œβ”€ package.json
|  β”œβ”€ production.yml
|  β”œβ”€ README.md
|  β”œβ”€ yarn.lock

Monorepo strategy benefits for microservices:

  • Enforce DRY Principles:

  • Collaboration:

    • Working within the same repository facilitates learning from peers.
    • Enables the adoption of good coding practices and the avoidance of bad ones.
  • Centralized Development Chores:

    • Manage common files like .gitignore centrally from the root directory
    • Reduce unnecessary repetitions in the codebase.
  • Easily Integrate Development Automation:

    • Task runner configurations and docker-compose can be managed from the root directory.
    • simplify the automation of repetitive workflows.
  • Code Sharing Anywhere:

    • Publish and import organization-scoped libraries from the npm registry with
    yarn release 
    yarn add <@microservices-suite/foo>
    yarn workspace @microservices-suite/<workspace-name> add  @microservices-suite/<library> 
  • Using Suite CLI you could achieve the results with the following commands
    suite release 
    suite add <@microservices-suite/foo>
    suite -W <workspace-name> add  @microservices-suite/<library> 
  • Easily Containerize and Scale:
    • Decouple every microservice to scale individually.
    • Leverage the no-hoist yarn workspace feature and custom scripts to enable efficient packaging of microservices into isolated containers.

Technologies Used

  • Yarn Workspaces:

    • Simplifies managing multiple packages within a single repository.
    • Encourage code sharing & reduce duplication
    • Make it easier to handle dependencies and scripts.
  • Docker Containers:

    • Provides lightweight, portable, and self-sufficient containers for packaging and deploying microservices.

Alpine Images

  • Alpine images are very minimalistic Linux minidistros that cost you only ~5MB of real estate. That is why they are used inside your favourite smart watch ⌚️.
  • One objective of this project is to optimize image builds for Continuous Integration (CI) and production environments through the utilization of the slimmest possible images so that you dont bloat ⚠️ your machine in dev and we have a lean server in prod.

Key Strategies:

  • Multi-Stage Builds:

    • We employ simple Docker constructs like multi-stage builds to optimize our image size.
  • Hoisting and Symlinking:

    • While these practices promote the DRY (Don't Repeat Yourself) principle, they pose a threat to our objective of achieving minimized images. To mitigate this, we leverage no-hoisting and symlinked libraries
    • selectively copying only the node_modules generated by non-hoisted workspaces.
    • These are optimized to consume less disk space, ensuring that only the essential shared libraries required by a specific service are included, thereby maintaining the slim profile of our images.
    • The service itself will build her core node modules normally inside the dockerfile from her package.json

Docker & Node Best Practices

Kubernetes (k8s)

  • Kubernetes offers automated deployment, scaling, and management of containerized applications, ensuring reliability and scalability.

Getting Started

Welcome to our project! To ensure a smooth setup and development experience, ensure you have the following tools installed on your machine:

  • Docker:
    • For containerization and managing containerized applications.
    • πŸ‘‰ Install docker here.
    • We love πŸ’š alpine images <small,simple,secure>.
    • You can read about the specific flavor here
  • Suite CLI:
    • For easy project scaffolding task automation and workflow management.
    • Install suite: check the installation guidelines below.
  • Node.js:
  • At the project <service_root> create .env, .env.dev and .env.staging files and copy environment variables from the .env.example file

Running Components

  • A component in our suite jargon refers to a service or application. With @microservices-suite you can create 1 or more services as well as applications.
  • Suite is component-scoped, giour strategy that enhances modularity and at the same time makes using the monorepo intuitive. Its is inspired by Single Responsibility principle.
  • Apps are simply cohessive microservices aggregated under the ./gateway/apps/ directory to create decoupled services to serve your client. An example is an Ecommerce app. This app can have customer, supplier,orders and products microservices under the ./microservices/ directory. These microservices are then referenced in docker-compose file definitions placed under the ./gateway/apps/ecommerce-app/ directory. Other apps can be added to the ./gateway/apps directory with their docker-compose definitions and api-gateway configs(nginx/appache).
  • Suite scales applications with kubernetes and app-scoped k8s configs are located under the ./k8s/ directory. Therefore the kubernetes configurations for our Ecommerce app will be located at ./k8s/ecommerce-app
  • Suite CLI streamlines the process of starting a service(s) or app(s) in development & production. Follow these steps to get your environment up and running:
  • You can derive the service_name or app-name from the workspace name found in the package.json "name": property e.g
"name": "@microservices-suite/<component-name>"
  • To run an app in either modes [dev,staging,prod]:
  • If -k or --kubectl flag is specified suite spins your app with kubectl . You need to have minikube installed and kubectl. Otherwise defaults to docker compose
  • If -m or --mode is specified you need to have a docker-compose.<mode> specified but this is not necessary with kubectl since we only run the development version of kubectl.
suite start [--kubectl,--mode]|[-km] <mode> <app-name...> 
  • This command uses docker-compose to start your app(s)
  • Suite will handle the setup, ensuring your app is ready.

Running Services with -v --vanilla

  • If you prefer not to use Docker, you can use the -v,--vanilla command to start service(s) using node PM2 engine in production or nodemon in any other mode:
suite start [--vanilla,--mode]|[-vm] <mode> <service_name...>

Using Docker-Compose Directly

  • Should you need to use docker-compose directly for more control over the container orchestration, you can utilize the standard commands provided by Docker:
  • You can replace the yml files with your compose file path and production.yml has been used as an overide. There are many ways to kill the cat in dockers world 😎.
 docker-compose  -f docker-compose.yml -f production.yml up --build -d
 docker-compose down

Contributing

Contributions are welcome! If you'd like to contribute to the Microservices Suite project, please follow these guidelines:

  1. Fork the repository and clone it to your local machine.
git clone https://github.com/microservices-suite/node-microservices-suite.git
  1. Create a new branch for your feature or bug fix:
git checkout -b feat/<my-feature>
  1. Make your changes and make sure that tests pass.

  2. Before committing your changes, make sure it follows the conventional commits specification:

    • We recommend you use the Better Commits CLI tool. It is a CLI for writing better commits, following the conventional commits specification.
  3. Push to the branch:

git push origin feat/<my-feature>
  1. Submit a pull request detailing your changes.

  2. Please ensure that your pull request adheres to the project's code style and conventions.

License

  • This project is licensed under the MIT License. Feel free to use, modify, and distribute this code for any purpose.

Acknowledgements

We would like to thank the developers and contributors to the following technologies used in this project: