DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • AppOps with Kubernetes and Devtron - The Perfect Fit
  • How To Use the Node Docker Official Image
  • 7 Ways of Containerizing Your Node.js Application
  • Zero to Hero on Kubernetes With Devtron

Trending

  • Concourse CI/CD Pipeline: Webhook Triggers
  • Artificial Intelligence, Real Consequences: Balancing Good vs Evil AI [Infographic]
  • Immutable Secrets Management: A Zero-Trust Approach to Sensitive Data in Containers
  • From Zero to Production: Best Practices for Scaling LLMs in the Enterprise
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Deployment
  4. Kubernetes With Bitnami and Sentry

Kubernetes With Bitnami and Sentry

Tutorial for Developers: build, deploy and monitor container-based applications on Kubernetes with Bitnami and Sentry.io.

By 
Vikram Vaswani user avatar
Vikram Vaswani
·
May. 18, 20 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
5.7K Views

Join the DZone community and get the full member experience.

Join For Free

Introduction

No matter the size of your development team or the scale at which it operates, bugs are inevitable in software development. That's why tools that quickly identify and debug errors are critical in a continuous deployment environment. These tools also need to enable the swift deployment of patches and updates to your applications.

Sentry is a popular cloud-based framework that helps developers diagnose and fix application errors in real-time. Bitnami offers a curated catalog of secure, optimized, and up-to-date containers and Helm charts for enterprises to build and deploy applications across platforms and cloud vendors. Together, this combination gives enterprise developers all the tooling they need to create and publish applications consistently, monitor and debug errors in those running applications, and release new and improved versions on an iterative basis.

This article walks you through the process of developing a basic Node.js/Express application, deploying it on Kubernetes with Bitnami's Node.js container image and Helm chart, and monitoring errors thrown by it in real-time with Sentry.

Assumptions and Prerequisites

This guide makes the following assumptions:

  • You have a Docker environment installed and configured. Learn more about installing Docker.
  • You have a Docker Hub account. Register for a free account.
  • You have a Sentry account. Register for a free account.
  • You have a Kubernetes cluster running with Helm v3.x and kubectl installed. Learn more about getting started with Kubernetes and Helm using different cloud providers.

Step 1: Create an Express Application

Tip: If you already have an Express application, you can use that instead and skip to Step 2. If you are using a MEAN application, you may need to adapt the MongoDB connection string in the application source code as explained in our MEAN tutorial.

The first step is to create a simple Express application. Follow the steps below:

  • Begin by creating a directory for your application and making it the current working directory:

mkdir myapp
cd myapp

  • Create a package.json file listing the dependencies for the project:

    JSON
     




    x
    12


     
    1
    {
    2
      "name": "simple-sentry-app",
    3
      "version": "1.0.0",
    4
      "description": "Sentry app",
    5
      "main": "server.js",
    6
      "scripts": {
    7
        "start": "node server.js"
    8
      },
    9
      "dependencies": {
    10
        "express": "^4.13"
    11
      }
    12
    }


  • Create a server.js file for the Express application. This is a skeleton application that randomly returns a greeting or an error.

    JSON
     




    xxxxxxxxxx
    1
    28


     
    1
    'use strict';
    2
     
                
    3
    // constants
    4
    const express = require('express');
    5
    const PORT = process.env.PORT || 3000;
    6
    const app = express();
    7
     
                
    8
    // route
    9
    app.get('/', function (req, res) {
    10
      let x = Math.floor((Math.random() * 4) + 1);
    11
      switch (x) {
    12
        case 1:
    13
          res.send('Hello, world\n');
    14
          break;
    15
        case 2:
    16
          res.send('Have a good day, world\n');
    17
          break;
    18
        case 3:
    19
          throw new Error('Insufficient memory');
    20
          break;
    21
        case 4:
    22
          throw new Error('Cannot connect to source');
    23
          break;
    24
        }
    25
    });
    26
     
                
    27
    app.listen(PORT);
    28
    console.log('Running on http://localhost:' + PORT);


Step 2: Integrate Sentry

Sentry works by logging errors using a unique application DSN. Therefore, the next step is to register your application with Sentry and obtain its unique logging DSN.

  • Log in to the Sentry dashboard.
  • Navigate to the "Projects" page and click "Create project".
  • Select "Express" as the platform.
  • Add a project name and set up alerts (optional).
  • Click "Create a project" to create a new project.
  • On the project quickstart page, note and copy the unique DSN for your project.

Tip: You can obtain the project DSN from the "Settings -> Projects -> Client Keys (DSN)" page at any time.

Next, revisit the application source code and integrate the Sentry Node SDK as follows:

  • Update the package.json file to include the Sentry Node SDK in the dependency list:

    JSON
     




    xxxxxxxxxx
    1
    13


     
    1
    {
    2
      "name": "simple-sentry-app",
    3
      "version": "1.0.0",
    4
      "description": "Sentry app",
    5
      "main": "server.js",
    6
      "scripts": {
    7
        "start": "node server.js"
    8
      },
    9
      "dependencies": {
    10
        "express": "^4.13",
    11
        "@sentry/node": "^5.15"
    12
      }
    13
    }


  • Update the server.json file to integrate Sentry with your application. Replace the SENTRY-DSN placeholder in the script below with the unique DSN for your project, as obtained previously.

    JSON
     




    xxxxxxxxxx
    1
    37


     
    1
    'use strict';
    2
     
                
    3
    // constants
    4
    const express = require('express');
    5
    const PORT = process.env.PORT || 3000;
    6
    const app = express();
    7
    const Sentry = require('@sentry/node');
    8
     
                
    9
    // define Sentry DSN
    10
    Sentry.init({ dsn: 'SENTRY-DSN' });
    11
     
                
    12
    // add Sentry middleware
    13
    app.use(Sentry.Handlers.requestHandler());
    14
     
                
    15
    // route
    16
    app.get('/', function (req, res) {
    17
      let x = Math.floor((Math.random() * 4) + 1);
    18
      switch (x) {
    19
        case 1:
    20
          res.send('Hello, world\n');
    21
          break;
    22
        case 2:
    23
          res.send('Have a good day, world\n');
    24
          break;
    25
        case 3:
    26
          throw new Error('Insufficient memory');
    27
          break;
    28
        case 4:
    29
          throw new Error('Cannot connect to source');
    30
          break;
    31
        }
    32
    });
    33
     
                
    34
    app.use(Sentry.Handlers.errorHandler());
    35
     
                
    36
    app.listen(PORT);
    37
    console.log('Running on http://localhost:' + PORT);


Tip: For more information about how Sentry integrates with Node.js and Express, refer to the official documentation.

Step 3: Create and publish a Docker image of the application

Bitnami's Node.js Helm chart can pull a container image of your Node.js application from a registry such as Docker Hub. Therefore, before you can use the chart, you must create and publish a Docker image of the application by following these steps:

  • Create a file named Dockerfile in the application's working directory, and fill it with the following content:

    Dockerfile
     




    xxxxxxxxxx
    1
    30


     
    1
    # First build stage
    2
    FROM bitnami/node:14 as builder
    3
    ENV NODE_ENV="production"
    4
     
                
    5
    # Copy app's source code to the /app directory
    6
    COPY . /app
    7
     
                
    8
    # The application's directory will be the working directory
    9
    WORKDIR /app
    10
     
                
    11
    # Install Node.js dependencies defined in '/app/packages.json'
    12
    RUN npm install
    13
     
                
    14
    # Second build stage
    15
    FROM bitnami/node:14-prod
    16
    ENV NODE_ENV="production"
    17
     
                
    18
    # Copy the application code
    19
    COPY --from=builder /app /app
    20
     
                
    21
    # Create a non-root user
    22
    RUN useradd -r -u 1001 -g root nonroot
    23
    RUN chown -R nonroot /app
    24
    USER nonroot
    25
     
                
    26
    WORKDIR /app
    27
    EXPOSE 3000
    28
     
                
    29
    # Start the application
    30
    CMD ["npm", "start"]


    This Dockerfile consists of two build stages:

    • The first stage uses the Bitnami Node.js 14.x development image to copy the application source and install the required application modules using npm install.
    • The second stage uses the Bitnami Node.js 14.x production image and creates a minimal Docker image that only consists of the application source, modules, and Node.js runtime.

Tip: Bitnami's Node.js production image is different from its Node.js development image. The production image (tagged with the suffix prod) is based on minideb and does not include additional development dependencies. It is therefore lighter and smaller in size than the development image and is commonly used in multi-stage builds as the final target image.

Let's take a closer look at the steps in the first build stage:

  • The FROM instruction kicks off the Dockerfile and specifies the base image to use. Bitnami offers several container images for Docker which can be used as base images. Since the example application used in this guide is a Node.js application, Bitnami's Node.js development container is the best choice for the base image.
  • The NODE_ENV environment variable is defined so that npm install only installs the application modules that are required in production environments.
  • The COPY instruction copies the source code from the current directory on the host to the /app directory in the image.
  • The RUN instruction executes a shell command. It's used to run npm install to install the application dependencies.
  • The WORKDIR instructions set the working directory for the image.
  • Here is what happens in the second build stage:

    • Since the target here is a minimal, secure image, the FROM instruction specifies Bitnami's Node.js production container as the base image. Bitnami production images can be identified by the suffix prod in the image tag.
    • The COPY instruction copies the source code and installs dependencies from the first stage to the /app directory in the image.
    • The RUN commands create a non-root user account that the application will run under. For security reasons, it's recommended to always run your application using a non-root user account. Learn more about Bitnami's non-root containers.
    • The CMD instruction specifies the command to run when the image starts. In this case, the npm start will start the application.
  • Build the image using the command below. Replace the DOCKER-USERNAME placeholder in the command below with your Docker account username.

docker build -t DOCKER-USERNAME/myapp:1.0 .

The result of this command is a minimal Docker image containing the application, the Node.js runtime, and all the related dependencies (including the Sentry SDK).

  • Log in to Docker Hub and publish the image. Replace the DOCKER-USERNAME placeholder in the command below with your Docker account username.

docker login
docker push DOCKER-USERNAME/myapp:1.0

Step 4: Deploy the Application on Kubernetes

You can now proceed to deploy the application on Kubernetes using Bitnami's Node.js Helm chart.

  • Deploy the published container image on Kubernetes with Helm using the commands below. Replace the DOCKER-USERNAME placeholder in the command below with your Docker account username.

    Dockerfile
     




    xxxxxxxxxx
    1


     
    1
    helm repo add bitnami https://charts.bitnami.com/bitnami
    2
    helm install node bitnami/node \
    3
      --set image.repository=DOCKER-USERNAME/myapp \
    4
      --set image.tag=1.0 \
    5
      --set getAppFromExternalRepository=false \
    6
      --set service.type=LoadBalancer


    Let's take a closer look at this command:

    • The service.type=LoadBalancer parameter makes the application available at a public IP address.
    • The getAppFromExternalRepository=false parameter controls whether the chart will retrieve the application from an external repository. In this case, since the application is already published as a container image, such retrieval is not necessary.
    • The image.repository and image.tag parameters tell the chart which container image and version to pull from the registry. The values assigned to these parameters should match the image published in Step 3.
  • Wait for the deployment to complete. Obtain the public IP address of the load balancer service:

kubectl get svc | grep node

Tip: See the complete list of parameters supported by the Bitnami Node.js Helm chart.

Step 5: Test Sentry Error Logging

To test the application, browse to the public IP address of the load balancer. You should randomly be presented with either a greeting or an error message, as shown in the images below:

Refresh the page a few times to generate a few errors. Then, log in to your Sentry dashboard and navigate to the project's "Issues" page. You should see a summary of the errors generated by the application, grouped by type, as shown below:

Select one of the errors to see complete details, including the actual lines of code that threw the error, the request headers, and the session details. This information is available for each error captured by Sentry.

Sentry also allows you to search for other errors of a similar nature, both within the project and across your project list. The information provided can be used to debug and identify the root cause of the error.

Once the source of an error is identified and corrected:

  • A new container image of the application can be built, tagged, and published using the Bitnami Node.js container image and the Dockerfile provided in Step 3.
  • The revised application image can then be deployed on Kubernetes by upgrading the Bitnami Node.js Helm chart to use the new container tag, as described in Step 4.

Of course, it's also possible to completely automate these steps; refer to the series linked below to learn about creating an automated CI pipeline with Bitnami containers and charts.

Kubernetes Docker (software) application Bitnami Node.js Continuous Integration/Deployment Chart Express Command (computing)

Published at DZone with permission of Vikram Vaswani. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • AppOps with Kubernetes and Devtron - The Perfect Fit
  • How To Use the Node Docker Official Image
  • 7 Ways of Containerizing Your Node.js Application
  • Zero to Hero on Kubernetes With Devtron

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!