Microservices

How to deploy microservices with Qovery

In this guide, we'll deploy a set of microservices, a database and a frontend UI application that consumes our public API. Our backend microservices will communicate on a secure internal network, not accessible from the outside. Our front-end application will consume the API only from the publicly exposed application.

The schema of what we want to achieve:

Microservices

As you can see in the picture:

  • we have two backend applications (App A and App B)
  • one of them (App B) connected to a database
  • App A exposes a public API that is consumed by API clients (our frontend application run in users browsers).
  • additionally, we host our frontend application (UI) on Qovery so that users can access it directly in their browsers.

What differentiates Qovery from most other similar platforms is its first-class support of microservices. At Qovery, your project can be easily composed of multiple applications. It's up to you to decide how to build your system, but Qovery enables you to easily and safely communicate between your backend applications, databases, and frontend websites.

  1. Deploy Application A

    In the first step, deploy an application named APP_A in your environment.

    Assumptions:

    • The app exposes REST API over HTTP on port 8080
    • The app name is APP_A

    After the application is created, let's expose the API publicly - it will be used later on by our frontend application.

    Exposing public API

    • Navigate to APP_A application settings
    • Select Port
    • Add port 8080

    Microservices

    This is it. By default, Qovery exposes your ports publicly over HTTPS on port 443, so the app should be publicly accessible and reachable later on by our frontend application.

  2. Deploy Application B

    In the second step, deploy an application named APP_B in your environment.

    Assumptions:

    • The app exposes REST API over HTTP on port 8080
    • The app name is APP_B
    • The app is ready to use a PostgreSQL client to connect to a PostgreSQL database

    Steps to do:

    • Navigate to APP_B application settings
    • Select Port
    • Add port 8080
    • Click Advanced settings in the 8080 port
    • Remove the check from the Publicly Accessible field

    Microservices

  3. Deploy Database

    In this step, we'll deploy a PostgreSQL database that we'll consume in APP_B in the next step.

    • Navigate to the environment in which you previously deployed your apps
    • Create a new PostgreSQL database named MY_DB
  4. Use the database

    In this step, we'll make use of our database in APP_B

    All you need to do to consume your database in APP_B is to configure your PostgreSQL client to use BUILT_IN secrets injected by Qovery. You can read more about this concept here.

    If your APP_B is a Node.js application, this examplary code snippet will work well:

    const { Client } = require('pg')
    const client = new Client({
    host: process.env.QOVERY_DATABASE_MY_DB_HOST,
    port: process.env.QOVERY_DATABASE_MY_DB_PORT,
    user: process.env.QOVERY_DATABASE_MY_DB_USER,
    password: process.env.QOVERY_DATABASE_MY_DB_PASSWORD,
    })
    client.connect(err => {
    if (err) {
    console.error('connection error', err.stack)
    } else {
    console.log('connected')
    }
    })

    This is it! After deploying the database, application and executing the code snippet, you should see the message connected.

    We made use of BUILT_IN variables injected by Qovery to make it easy to consume all the services within the environment.

  5. Consume internal APIs

    In this step, we'll use the private API of our APP_B in our APP_A over a private network. We have already configured everything to make it work. The only missing step is the configuration in APP_A - it needs to know how to access our APP_B.

    In the example below, we'll use Node.js and axios to create an HTTP client able to consume the API of APP_B:

    Now, you can configure your HTTP client in the frontend application to target your backend API:

    const axios = require('axios');
    const appBAddress = "http://" + process.env.QOVERY_APPLICATION_APP_B_HOST + ":" + process.env.QOVERY_APPLICATION_APP_B_PORT
    axios.get(appBAddress + '/api/users')
    .then(response => {
    console.log(response.data);
    })
    .catch(error => {
    console.log(error);
    });

    This is it! Every request using the API client we have just configured will consume the API of APP_B over the secure, internal network.

    Once again, we used the BUILT_IN secrets. Read more about them here

  6. Consume the public API in the frontend application

    In this step, we'll deploy a frontend application and consume our public API exposed by APP_A.

    In the first step, create and deploy your frontend application. If you don't know how to do it, you can take a look at the guide how to delpoy Nuxt.js application.

    After the application is deployed, we can easily configure it to consume our public API. All we need to do is to make use of the BUILT_IN secrets. See how to achieve it in a Nuxt.js example below:

    export default {
    env: {
    apiUrl: process.env.QOVERY_APPLICATION_APP_A_URL
    }
    }
    import axios from 'axios'
    export default axios.create({
    baseURL: process.env.apiUrl
    })

    After providing the configuration from above, our frontend application will be able to consume the API exposed by the publicly exposed APP_A.

Summary

In this guide, we deployed two microservices that communicate over the internal network. We also deployed a frontend application that makes use of a public API exposed by one of our applications. At the same time, we deployed a database and connected it to the second of our backend microservices.