Skip to main content

Build Your Own Qube

Prerequisites

  1. A Server Running Ubuntu:

    • Ensure you have a server with Ubuntu installed, along with a non-root user who has sudo privileges and an active firewall.
  2. Docker Installed:

    • Install Docker on your server and verify that it's running correctly.
  3. Node.js and npm Installed:

    • Install Node.js and npm using the PPA managed by NodeSource.
  4. Docker Hub Account:

    • Set up a Docker Hub account to pull Docker images and push your custom images to the Docker Hub repository.

Step 1 --- Installing Your Application Dependencies

To create your Docker image, you need to prepare your application files, which will be copied to the container. These files include your application's static content, code, and dependencies.

First, create a directory for your project in your non-root user's home directory. We will name ours `node_project`, but you can choose any name you prefer.

  1. Create the project directory:

mkdir node_project

  1. Navigate to the project directory:

cd node_project

This will be the root directory of your project.

Next, create a `package.json` file to define your project's dependencies and other identifying information. Open this file with your preferred text editor:

  1. Open the `package.json` file:

nano package.json

4. Add the following information to the `package.json` file:

{
"name": "nodejs-image-demo",
"version": "1.0.0",
"description": "nodejs image demo",
"author": "Sammy the Shark <sammy@example.com>",
"license": "MIT",
"main": "app.js",
"keywords": [
"nodejs",
"bootstrap",
"express"
],
"dependencies": {
"express": "^4.16.4"
}
}

Replace `"Your Name <your.email@example.com>"` with your own name and contact details. This file includes the project name, version, description, author information, and license. The `"main"` field specifies the entry point for the application, which is `app.js`. The `"dependencies"` section lists the project dependencies, in this case, Express 4.16.4 or higher.

5. Save and close the `package.json` file after adding the required details.

To install your project's dependencies as listed in the `package.json` file, run the following command:

6. Install project dependencies:

npm install

This command will install the packages specified in the `package.json` file into your project directory.

With the dependencies installed, you are now ready to move on to building the application files.

Step 2 --- Creating the Application Files

In this step, we'll create a simple website that provides information about sharks. Our application will have a main entry point, `app.js`, and a `views` directory that will contain the project's static assets. The landing page, `index.html`, will provide basic information and a link to a detailed shark information page, `sharks.html`.

Creating the Main Application File

First, let's set up the main application file that will define the routes for our website.

  1. Open the `app.js` file:

nano app.js

  1. Define the application and its routes:

The first part of `app.js` will create the Express application and Router objects, and define the base directory and port as constants. This sets up the basic structure of the application, including the routes for the landing page and the sharks information page.

const express = require('express');
const app = express();
const router = express.Router();

const path = __dirname + '/views/';
const port = 8080;

router.use(function (req,res,next) {
console.log('/' + req.method);
next();
});

router.get('/', function(req,res){
res.sendFile(path + 'index.html');
});

router.get('/sharks', function(req,res){
res.sendFile(path + 'sharks.html');
});

app.use(express.static(path));
app.use('/', router);

app.listen(port, function () {
console.log('Example app listening on port 8080!')
})

3. Save and close the `app.js` file after adding the above content.

Adding Static Content

Next, we will add static content to our application. This includes creating the landing page (`index.html`) and the shark information page (`sharks.html`), along with a custom CSS file for styling.

1. Create the `views` directory:

mkdir views

2. Create and open the `index.html` file:

nano views/index.html

3. Add the following HTML code for the landing page:

<!DOCTYPE html>
<html lang="en">

<head>
<title>About Sharks</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link href="css/styles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css">
</head>

<body>
<nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
<div class="container">
<button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
</button> <a class="navbar-brand" href="#">Everything Sharks</a>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav mr-auto">
<li class="active nav-item"><a href="/" class="nav-link">Home</a>
</li>
<li class="nav-item"><a href="/sharks" class="nav-link">Sharks</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="jumbotron">
<div class="container">
<h1>Want to Learn About Sharks?</h1>
<p>Are you ready to learn about sharks?</p>
<br>
<p><a class="btn btn-primary btn-lg" href="/sharks" role="button">Get Shark Info</a>
</p>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-lg-6">
<h3>Not all sharks are alike</h3>
<p>Though some are dangerous, sharks generally do not attack humans. Out of the 500 species known to researchers, only 30 have been known to attack humans.
</p>
</div>
<div class="col-lg-6">
<h3>Sharks are ancient</h3>
<p>There is evidence to suggest that sharks lived up to 400 million years ago.
</p>
</div>
</div>
</div>
</body>

</html>

4. Save and close the `index.html` file after adding the above content.

5. Create and open the `sharks.html` file:

nano views/sharks.html

6. Add the following HTML code for the shark information page:

<!DOCTYPE html>
<html lang="en">

<head>
<title>About Sharks</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link href="css/styles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Merriweather:400,700" rel="stylesheet" type="text/css">
</head>
<nav class="navbar navbar-dark bg-dark navbar-static-top navbar-expand-md">
<div class="container">
<button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span>
</button> <a class="navbar-brand" href="/">Everything Sharks</a>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav mr-auto">
<li class="nav-item"><a href="/" class="nav-link">Home</a>
</li>
<li class="active nav-item"><a href="/sharks" class="nav-link">Sharks</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="jumbotron text-center">
<h1>Shark Info</h1>
</div>
<div class="container">
<div class="row">
<div class="col-lg-6">
<p>
<div class="caption">Some sharks are known to be dangerous to humans, though many more are not. The sawshark, for example, is not considered a threat to humans.
</div>
<img src="https://assets.digitalocean.com/articles/docker_node_image/sawshark.jpg" alt="Sawshark">
</p>
</div>
<div class="col-lg-6">
<p>
<div class="caption">Other sharks are known to be friendly and welcoming!</div>
<img src="https://assets.digitalocean.com/articles/docker_node_image/sammy.png" alt="Sammy the Shark">
</p>
</div>
</div>
</div>

</html>

7. Save and close the `sharks.html` file after adding the above content.

8. Create the `css` directory within the `views` directory:

mkdir views/css

9. Create and open the `styles.css` file:

nano views/css/styles.css

10. Add the following CSS code to style your pages:

.navbar {
margin-bottom: 0;
}

body {
background: #020A1B;
color: #ffffff;
font-family: 'Merriweather', sans-serif;
}

h1,
h2 {
font-weight: bold;
}

p {
font-size: 16px;
color: #ffffff;
}

.jumbotron {
background: #0048CD;
color: white;
text-align: center;
}

.jumbotron p {
color: white;
font-size: 26px;
}

.btn-primary {
color: #fff;
text-color: #000000;
border-color: white;
margin-bottom: 5px;
}

img,
video,
audio {
margin-top: 20px;
max-width: 80%;
}

div.caption: {
float: left;
clear: both;
}

11. Save and close the `styles.css` file after adding the above content.

With the application files in place and the project dependencies installed, you are ready to start the application.

If your server has a firewall enabled, allow traffic on port 8080:

sudo ufw allow 8080

To start the application, make sure you are in your project's root directory:

cd \~/node_project

Start the application with:

node app.js

Navigate your browser to `http://your_server_ip:8080` to see your application. You should see the landing page, and clicking on the "Get Shark Info" button will take you to the detailed shark information page.

You now have a NodeJS application up and running

Step 3 --- Writing the Dockerfile

A Dockerfile specifies the instructions to build your application container, ensuring a consistent environment across different setups by avoiding dependency or runtime discrepancies.

Creating the Dockerfile

  1. Create the Dockerfile in your project's root directory:

nano Dockerfile

2. Set the Base Image:

Docker images are built using layers. Start by setting the base image for your application. We'll use the `node:10-alpine` image, a lightweight version derived from Alpine Linux.

FROM node:10-alpine

This image includes Node.js and npm. Each Dockerfile must begin with a `FROM` instruction.

3. Set Up Non-Root User:

To avoid running the container as root, which is a security risk, use the pre-existing non-root `node` user. Define the working directory and set permissions.

RUN mkdir -p /home/node/app/node_modules && chown -R node:node
/home/node/app

WORKDIR /home/node/app

4. Copy Project Files:

Copy the `package.json` and `package-lock.json` files first to take advantage of Docker's caching mechanism.

COPY package\*.json ./

5. Install Dependencies:

Switch to the `node` user before running `npm install` to ensure proper file ownership.

USER node

RUN npm install

6. Copy Application Code:

Copy the remaining application code and set appropriate permissions.

\...

COPY \--chown=node:node . .

7. Expose Application Port and Define Startup Command:

Document the port the container will use and specify the command to run the application.

EXPOSE 8080

CMD \[\"node\", \"app.js\"\]

Complete Dockerfile

Here's the complete Dockerfile for your Node.js application:

FROM node:10-alpine

RUN mkdir -p /home/node/app/node_modules && chown -R node:node
/home/node/app

WORKDIR /home/node/app

COPY package\*.json ./

USER node

RUN npm install

COPY \--chown=node:node . .

EXPOSE 8080

CMD \[\"node\", \"app.js\"\]

Adding a .dockerignore File

Before building the image, create a `.dockerignore` file to exclude unnecessary files from the build context, similar to a `.gitignore` file.

  1. Open the `.dockerignore` file:

nano .dockerignore

  1. Add the following entries:
node_modules
npm-debug.log
Dockerfile
.dockerignore

If you are using Git, also exclude your `.git` directory and `.gitignore` file.

Building the Docker Image

Use the `docker build` command to create your image, tagging it with your Docker Hub username and a memorable name.

  1. Build the Docker image:

sudo docker build -t your_dockerhub_username/nodejs-image-demo .

The `.` specifies the current directory as the build context.

2. Check your images:

sudo docker images

You should see an output similar to this:

REPOSITORY TAG IMAGE ID CREATED SIZE

your_dockerhub_username/nodejs-image-demo latest 1c723fb2ef12 8 seconds
ago 73MB

node 10-alpine f09e7c96b6de 3 weeks ago 70.7MB

Running the Docker Container

Run the container using `docker run` with the necessary flags to map ports, run in the background, and assign a name.

  1. Run the container:
sudo docker run \--name nodejs-image-demo -p 80:8080 -d
your_dockerhub_username/nodejs-image-demo

2. Check running containers:

sudo docker ps

You should see an output similar to this:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

e50ad27074a7 your_dockerhub_username/nodejs-image-demo \"node app.js\" 8
seconds ago Up 7 seconds 0.0.0.0:80-\>8080/tcp nodejs-image-demo

3. Access your application:

Navigate to your server's IP address in a web browser:

http://your_server_ip

You should see the application landing page.

With your Dockerfile and `.dockerignore` in place, you can now build and run your Node.js application in a Docker container. This setup ensures a consistent environment and easy deployment across different machines.

Setting Up Minikube, Kubernetes (kubectl), and Helm

In this guide, we'll walk you through setting up Minikube, Kubernetes (kubectl), and Helm on your local machine. These tools are essential for managing and deploying applications on Kubernetes.

Step 1 --- Installing Minikube

Minikube allows you to run Kubernetes locally. Follow these steps to install and start Minikube:

  1. Update your package list and install necessary dependencies:
sudo apt update
sudo apt install -y curl apt-transport-https
  1. Download the Minikube binary:
curl -LO
https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64

3. Install Minikube:

sudo install minikube-linux-amd64 /usr/local/bin/minikube

4. Start Minikube:

minikube start

Step 2 --- Installing Kubernetes (kubectl)

kubectl is the command-line tool for interacting with your Kubernetes cluster. Here's how to install it:

1. Download the latest release of kubectl:

curl -LO \"https://dl.k8s.io/release/\$(curl -L -s
https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl\"

2. Install kubectl:

sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

3. Verify the installation:

kubectl version \--client

Step 3 --- Installing Helm

Helm is a package manager for Kubernetes that simplifies the deployment of applications. Follow these steps to install Helm:

1. Download the Helm installation script and run it:

curl
https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 \|
bash
  1. Verify the installation:

helm version

By following these steps, you will have Minikube, kubectl, and Helm installed on your local machine. This setup will enable you to run a local Kubernetes cluster, manage it with kubectl, and deploy applications using Helm charts.

You are now ready to deploy and manage your Kubernetes applications locally!

Step 4 --- Creating and Deploying a Helm Chart

With Minikube, kubectl, and Helm set up, you can now create and deploy a Helm chart. Helm charts are packages that contain all the resource definitions necessary to run an application in a Kubernetes cluster.

Step 4.1 --- Creating a Helm Chart

1. Create a new Helm chart:

helm create mychart

This command creates a directory named `mychart` with a default Helm chart structure.

2. Navigate to the chart directory:

cd mychart

3. Review the generated files:

The `mychart` directory contains the following key files and directories:

- `Chart.yaml`: Contains metadata about the chart.

- `values.yaml`: Contains the default configuration values for the chart.

- `templates/`: Contains the template files that define Kubernetes resources.

4. Customize your Helm chart:

Edit the `values.yaml` and template files in the `templates/` directory to fit your application's requirements. For example, modify the deployment configuration or service definition.

Step 4.2 --- Deploying the Helm Chart

1. Install the Helm chart in your Minikube cluster:

helm install my-release mychart

Replace `my-release` with the name you want to give to your Helm release. This command deploys your application using the configurations specified in your chart.

2. Verify the deployment:

kubectl get all

This command displays all the resources created by the Helm chart, such as pods, services, and deployments.

3. Access your application:

Minikube provides a convenient way to access services running in your cluster. Use the following command to open the application in your default browser:

minikube service mychart

Replace `mychart` with the name of the service created by your Helm chart.

Step 4.3 --- Updating the Helm Chart

If you make changes to your Helm chart and want to apply them to the running release, use the `helm upgrade` command:

1. Upgrade the Helm release:

helm upgrade my-release mychart

This command applies the changes to the existing release, updating the Kubernetes resources as specified in the modified chart.

Step 4.4 --- Uninstalling the Helm Chart

To remove the Helm release and all associated resources from your cluster, use the `helm uninstall` command:

1. Uninstall the Helm release:

helm uninstall my-release

This command deletes all the resources created by the release.

By following these steps, you have successfully created and deployed a Helm chart on your local Minikube cluster. Helm simplifies the deployment and management of Kubernetes applications, making it easier to package and distribute your applications.

With Minikube, kubectl, and Helm set up, you can now develop, test, and manage your Kubernetes applications efficiently.

Step 5 --- Pushing a Helm Chart to Artifact Hub

Artifact Hub is a web-based application that allows you to find, install, and publish packages and Helm charts. To make your Helm chart available on Artifact Hub, follow these steps:

Step 5.1 --- Preparing Your Helm Chart for Submission

1. Ensure your Helm chart is ready for distribution:

Make sure your chart metadata in `Chart.yaml` is accurate and your `values.yaml` file contains default values that work out of the box.

2. Package your Helm chart:

Package the Helm chart into a `.tgz` file, which is required for submission to Artifact Hub.

helm package mychart

This command creates a `mychart-<version>.tgz` file in your current directory.

Step 5.2 --- Setting Up Your Repository

1. Create a GitHub repository:

Create a new GitHub repository to host your Helm charts. This repository will serve as the Helm chart repository.

2. Push the packaged Helm chart to GitHub:

Upload the `.tgz` file to your GitHub repository. Ensure you commit and push the file to the repository.

3. Create an `index.yaml` file:

Helm requires an `index.yaml` file to list the available charts in the repository. Use the following command to generate this file:

helm repo index \--url
https://\<your-github-username\>.github.io/\<your-repo-name\> .

Replace `<your-github-username>` with your GitHub username and `<your-repo-name>` with the name of your repository. This command generates an `index.yaml` file in your repository.

4. Push the `index.yaml` file to GitHub:

Commit and push the `index.yaml` file to your GitHub repository.

Step 5.3 --- Submitting Your Helm Chart to Artifact Hub

1. Sign in to Artifact Hub:

Go to the Artifact Hub website and sign in with your GitHub account.

2. Add your Helm repository to Artifact Hub:

- Navigate to your profile and select "Control Panel."

- Click on "Repositories" and then "Add repository."

- Fill in the required details:

- Kind: Select "Helm" from the dropdown menu.

- Name: Provide a name for your repository.

- URL: Enter the URL to your `index.yaml` file. For example, `https://<your-github-username>.github.io/<your-repo-name>/index.yaml`.

- Publisher: Select your publisher profile.

- Click "Save."

  1. Verify your repository:

Once your repository is added, Artifact Hub will index it. After indexing, your Helm chart will be searchable and available for installation by the community.

By following these steps, you have successfully packaged and pushed your Helm chart to Artifact Hub. This allows others to easily find, install, and use your Helm chart.

Step 6 --- Qubinets Contributions

Overview

Welcome to Qubinets! Our mission is to provide a hassle-free data infrastructure, enabling developers like you to concentrate more on creating value through application code rather than dealing with infrastructure complexities. We aim to be the leading platform that accelerates the adoption of Artificial Intelligence and Big Data technologies by providing robust, reusable building blocks from a global development community.

Prerequisites

To get started with Qubinets, ensure your application meets the following requirements:

  • Containerization: Your application must be containerized. This ensures it can be easily deployed and managed within a Kubernetes cluster.

  • Package Management: Use Helm to manage your application's packages on a Kubernetes cluster.

For detailed information and examples, please refer to the Qubinets Contributions Guide.

References

  1. Ubuntu

  2. DigitalOcean

  3. Docker

  4. Node.js

  5. Kubernetes

  6. Minikube

  7. Helm

  8. Artifact Hub

  9. GitHub

  10. Qubinets Contributions