paint-brush
Step-By-Step Tutorial To Deploy A Node.js App To Kubernetesby@shedrack
972 reads
972 reads

Step-By-Step Tutorial To Deploy A Node.js App To Kubernetes

by Shedrack AkintayoMarch 30th, 2021
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

JavaScript community is the least sensitive to containerization as a first principle. The community is far removed from the discussions around container runtimes, ingress, networking, and orchestration. Tools such as Netlify and Vercel have provided a modern developer experience that makes deployments frictionless. With cf-for-k8s project, developers can deploy to a Kubernetes cluster of Node.JS apps. In addition, the Cloud Foundry project can make a full stack of NodeJS applications running on any infrastructure.
featured image - Step-By-Step Tutorial To Deploy A Node.js App To Kubernetes
Shedrack Akintayo HackerNoon profile picture

As a broad generalization, the JavaScript community is the least sensitive to Containerization as a first principle. The community is far removed from the discussions around container runtimes, ingress, networking, and orchestration – mostly because themes such as server-side rendering, code caching, and performance improvements are more relevant and relatable to them.

In addition, tools such as Netlify and Vercel have provided a modern developer experience that makes deployments frictionless. The sheer convenience that these deployment tools provide has made the ecosystem desire the same kind of experience for all infrastructure.

Getting JavaScript developers, as a community, to talk about containers and Kubernetes as a mainstream topic is a challenge. The ease of use they get from other tools plus the complexity of Kubernetes-based deployments makes it an order of magnitude harder to get the JS community to work with modern cloud infrastructure. This leads to a widening gap within the community between development and deployment.

We are therefore left with the following questions – what is the best path for the JavaScript community to adopt modern application deployment methods? What is a means to deploy JavaScript apps to Kubernetes, minus the friction?

Turns out that the cloud native community has some answers. The Cloud Foundry project cf-for-k8s, along with a Cloud Native Buildpacks implementation called Paketo Buildpacks, can provide a path for JavaScript application developers to deploy conveniently to Kubernetes. Both of these are open source and belong to the Cloud Foundry Foundation.

By using the time-tested cf push interface, JavaScript developers don't have to make a choice between deploying conveniently and deploying to modern infrastructure.

The Cloud Foundry developer experience is focused on simplifying deployments not just for JavaScript but for all other languages as well. Containers are built from source by internal stages in the deployment process thanks to Buildpacks which detect the language, runtime dependencies, and frameworks needed for each language and then supplies them during the build process. For JavaScript specifically, a set of Buildpacks are used to cover base, start, and install parts for both Node and Yarn based applications.

Ultimately, what does this enable?

This approach provides solutions to many problems that arise due to containerization workflows in the JavaScript ecosystem. Let us look at some of the common limitations and problems and see how Cloud Foundry provides a solution to these.

Let's start with a fundamental problem - Writing a Dockerfile.

In order to create a container for an application written in Node.JS, we need a Dockerfile. This will specify the commands needed to download dependencies, install the application, and finally start it.

Dockerfiles are a combination of shell scripts and some context in which to execute them. They represent additional cognitive load for a JavaScript engineer and can be difficult to write and maintain as apps scale.

Next, the convenient deployment methods promised by Netlify, Vercel, Cloudflare pages etc. are limited to static websites and not full-fledged applications. Developers who would like to deploy full stack applications are forced to look elsewhere. They either have to default to writing Dockerfiles or use platforms such as Heroku which are more accommodating of their needs.

Which brings us to the next problem - control over infrastructure. Netlify and Heroku, which are both popular among JavaScript devs do not expose the infrastructure that they run on.

Developers do not have any control over the nature of compute that will ultimately power their experience. There aren't options to accommodate multi- or hybrid- cloud architectures.

Beyond all this, there is a long tail of best platform ops practices that cannot be implemented with JavaScript apps. The list includes (but is not limited to) multi-stage builds, HTTP proxies, npm install performance, healthchecks, CVE scanning, container logging, testing during image builds, and microservice docker-compose setups.

As one example, let’s have a look at how Cloud Foundry solves these problems.

First of all, using Paketo (or any other Buildpacks) eliminates the need for writing Dockerfiles. Consequently, the burden of maintaining them is also eliminated. Cloud Foundry can deploy single-page apps, complex applications, or headless API endpoints and builds them uniformly. With the cf-for-k8s project, developers can deploy to a Kubernetes cluster of their choice, which is running on any infrastructure.

In addition, platform operators can make use of the Buildpacks to apply best practices during build time as opposed to pushing this as another task for developers to worry about.

Here's a link to a tutorial that explains how to deploy a full stack Node.JS application to Kubernetes using the Cloud Foundry developer experience. (Watch a video instead, if you're the sort that prefers to learn visually).

Here are some of the highlights from the installation process:

The command used to deploy the application is

cf push foo-foo
Pushing app foo-foo to org test / space dev as admin...Packaging files to upload...Uploading files... 530 B / 530 B [====================================================] 100.00% 1s
Waiting for API to complete processing files...
Staging app and tracing logs...

The analysis phase within the cf push process identified the need for the following Buildpacks

 3 of 4 buildpacks participating   paketo-buildpacks/node-engine 0.1.2   paketo-buildpacks/npm-install 0.2.1   paketo-buildpacks/npm-start   0.0.2

The Buildpacks selected the NPM build process and completed installing the app in a mere seconds.

Selected NPM build process: 'npm install'      Executing build process   Running 'npm install --unsafe-perm --cache /layers/paketo-buildpacks_npm-install/npm-cache'   Completed in 1.415s

Finally, the build completes and the containers are cached as layers inside a container registry. These layers can be individually addressed and updated allowing operators to rebase the final image instead of rebuilding whole images during updates.

After the build complete and the containers have been cached, the app is automatically started and a unique link(route) will be generated for you to see the app live.

Paketo NPM Start Buildpack 0.0.2   Assigning launch processes   web: node server.js   Adding layer 'paketo-buildpacks/node-engine:node'   Adding layer 'paketo-buildpacks/npm-install:modules'   Adding layer 'paketo-buildpacks/npm-install:npm-cache'   Adding 1/1 app layer(s)   Adding layer 'launcher'   Adding layer 'config'   Adding label 'io.buildpacks.lifecycle.metadata'   Adding label 'io.buildpacks.build.metadata'   Adding label 'io.buildpacks.project.metadata'   *** Images (sha256:8d82765365bcceb52cc3b378e6f1d82e7869acd0543562039d855ad628918f6c):   registry.gitlab.com/ramanujank/test-container-registry/278317be-6f71-498e-9e6a-7eb2e1076bcd   registry.gitlab.com/ramanujank/test-container-registry/278317be-6f71-498e-9e6a-7eb2e1076bcd:b1.20210219.123808   Adding cache layer 'paketo-buildpacks/node-engine:node'   Adding cache layer 'paketo-buildpacks/npm-install:modules'   Adding cache layer 'paketo-buildpacks/npm-install:npm-cache'   Build successful
Waiting for app foo-foo to start...

If you have questions when getting started with cf-for-k8s or, for that matter Cloud Foundry in general, go to the Cloud Foundry community at slack.cloudfoundry.org. You’ll find the community is more than happy to welcome and help you out. Also, for more information about the Cloud Foundry Foundation and what it does, visit cloudfoundry.org.