Day 7 of my 90-Day Devops Journey: Deploying a Dockerized Node.js App on Minikube
Tags: kubernetes, node, docker, beginners
Published: 2024-06-27 16:46:38

Hey everyone, welcome back to day 7 of my 90-day DevOps project adventure!  I apologize for missing yesterday's post due to some personal commitments and technical issues. Juggling responsibilities alongside these projects can be a real challenge, but thanks for your continued support, it means a lot to me!

Today, we'll dive into deploying a Dockerized Node.js application on a local Kubernetes cluster using Minikube. This project took me two days due to research and other commitments, highlighting the importance of planning and perseverance.

### Project Overview

This guide will walk you through deploying a Dockerized Node.js application on a single-node Kubernetes cluster using Minikube on your local machine. 


### Prerequisites

Before we begin, ensure you have the following installed:

1. **Docker:** Make sure Docker is up and running on your system. ([https://docs.docker.com/](https://docs.docker.com/))
2. **Minikube:** This tool sets up a single-node Kubernetes cluster on your machine. We'll cover Minikube installation in a future post specific to Windows. ([https://minikube.sigs.k8s.io/docs/start/](https://minikube.sigs.k8s.io/docs/start/))
3. **kubectl:** The command-line tool for interacting with Kubernetes clusters. Installation instructions are usually included with your Kubernetes distribution.


### Step-by-Step Guide

**1. Dockerize Your Node.js Application**

First, we need to create a `Dockerfile` to define how our application will be built as a Docker image.

**Create a Dockerfile:**

In your Node.js project directory, create a file named `Dockerfile` with the following content:

```dockerfile
FROM node:14
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
```

**Build and Tag the Docker Image:**

Now, build the Docker image using the `docker build` command and tag it with your desired name and version:

```bash
docker build -t <your-docker-hub-username>/my-app:latest .
```

**Replace `<your-docker-hub-username>` with your actual Docker Hub username.**

**Push the Image to Docker Hub (Optional):**

If you want to deploy your application across different environments, you can push the image to a public registry like Docker Hub:

```bash
docker push <your-docker-hub-username>/my-app:latest
```


**2. Set Up Kubernetes with Minikube**

**Start Minikube:**

Fire up a single-node Kubernetes cluster on your local machine using Minikube:

```bash
minikube start
```

**Create a Deployment:**

Define a deployment configuration file (deployment.yaml) for your application:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 2  # This will run two replicas of your application pod
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: <your-docker-hub-username>/my-app:latest  # Update with your image details
        ports:
        - containerPort: 3000
```

**Apply the Deployment:**

Use `kubectl apply` to deploy your application based on the configuration file:

```bash
kubectl apply -f deployment.yaml
```

**Expose the Deployment as a Service:**

Make your application accessible outside the cluster by creating a Service of type LoadBalancer:

```bash
kubectl expose deployment my-app-deployment --type=LoadBalancer --port=3000
```

**Check Pod Status:**

Verify if your application pods are running successfully:

```bash
kubectl get pods
```


### Challenges and Solutions

Deploying applications with Kubernetes can encounter some common issues. Here are a few challenges you might face and how to address them:

**1. ImagePullBackOff:**

* **Description:** Kubernetes cannot pull the specified Docker image.
* **Solutions:**
    * Double-check the image name and tag for accuracy.
    * Ensure proper access to the Docker registry, especially for private ones.
    * Manually pull the image on a Kubernetes node using `docker pull <image-name>`.
    * Consider using a more aggressive image pull policy (e.g., `Always` instead of `IfNotPresent`).

**2. CrashLoopBackOff :**

* **Solutions:**
    * Inspect container logs for error messages using `kubectl logs <pod-name>`.
    * Verify the container image and its entrypoint/command for correctness.
    * Check if resource limits and requests are sufficient for the container.
    * Ensure necessary environment variables are set and accessible within the container.

**3. NodeNotReady:**

* **Description:** A Kubernetes node is unavailable for workloads.
* **Solutions:**
    * Use `kubectl get nodes` to view node status and identify the problematic node.
    * Investigate node logs for any errors using `journalctl` (Linux) or system event viewer (Windows).
    * Ensure the node has sufficient resources (CPU, memory, disk).
    * If necessary, restart the node or the Kubelet service on the node.


### Docker Errors and Solutions

While working with Docker, you might encounter some errors. Here are a few common ones and how to fix them:

**1. DockerDaemonNotRunning:**

* **Description:** The Docker daemon is not running on your system.
* **Solutions:**
    * Start the Docker daemon using your system's service management tools (e.g., `systemctl start docker` on Linux).
    * Check Docker daemon logs for any issues using `journalctl -u docker` (Linux).

**2. DockerImagePullFailure:**

* **Description:** Docker fails to pull the specified image.
* **Solutions:**
    * Verify the image name and tag for typos.
    * Ensure proper access to the Docker registry, especially for private ones.
    * Try manually pulling the image using `docker pull <image-name>`.

**3. DockerContainerStartFailure:**

* **Description:** Docker cannot start the container.
* **Solutions:**
    * Examine container logs for error messages using `docker logs <container-name>`.
    * Verify the container image, entrypoint, and command for correctness.
    * Check if resource constraints allow the container to run properly.
    * Ensure required environment variables are set within the container.

**4. DockerNetworkIssues:**

* **Description:** Problems with Docker network configuration.
* **Solutions:**
    * Verify Docker network settings and ensure proper configuration.
    * Inspect the network using `docker network inspect <network-name>`.
    * If necessary, recreate the network or containers.


### Valuable Resources

For further exploration, refer to the following resources:

* Kubernetes Documentation: [https://kubernetes.io/docs/home/](https://kubernetes.io/docs/home/)
* Minikube Documentation: [https://minikube.sigs.k8s.io/docs/start/](https://minikube.sigs.k8s.io/docs/start/)
* Docker Documentation: [https://docs.docker.com/](https://docs.docker.com/)
* Kubernetes Tutorials: [https://kubernetes.io/docs/tutorials/](https://kubernetes.io/docs/tutorials/)


### Conclusion

While deploying applications with Kubernetes can be challenging, understanding common errors and solutions can significantly smoothen the process. By leveraging Docker to containerize your application and utilizing Kubernetes for orchestration, you achieve robust, scalable, and resilient deployments. This project not only enhanced my understanding of Kubernetes but also emphasized the importance of perseverance and thorough research in DevOps. Stay tuned for more insights and projects as we continue this 90-day journey!

Happy Kubernetes-ing!