Quickly deploy website on kubernetes locally
Tags: kubernetes, docker, containers
Published: 2023-04-19 02:09:36

Several reasons can justify the need to do local Kubernetes deployments, it can be and often is for learning reasons with a lack of resources or with limited resources, or for testing reasons where either we don't want to pay the bill for our use in the cloud, or it is not allowed to do tests on the production environment in case of on-prem deployment. as bootstrapping a Kubernetes cluster still requires considerable resources in terms of computing and time which may not be worth it when doing just simple tests.

So in this article, I show you an example of deploying a website on Kubernetes without worrying about your resources problems (in a light way).

# **Tools used in this lab :**

*   ***Kubectl:*** It will be used to interact with the Kubernetes cluster. It is the Kubernetes command-line tool, which allows running commands against Kubernetes clusters. [How to install kubctl](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/)
    
*   ***Docker:*** Docker Engine is an open-source containerization technology for building and containerizing applications. It will be used to containerize the website. [How to install Docker](https://docs.docker.com/engine/install/debian/)
    
*   ***Minikube:*** Minikube is a local light Kubernetes, focusing on making it easy to learn and develop for Kubernetes. [How to install Minikube](https://minikube.sigs.k8s.io/docs/start/)
    

Once all these tools are installed, you are ready to start. Create a directory for the lab, then in this directory create another one where you will put the website files.

```bash
mkdir lab
cd lab
mkdir files
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1669984971067/67d7fb67-8a9b-430b-8c18-e02c5778c7fa.png align="left")

Once the website files are in place go back to the lab directory and let's start the containerization

# **Containerization**

In the lab directory, create the Dockerfile.

> Docker builds images automatically by reading the instructions from a Dockerfile -- a text file that contains all commands, in order, needed to build a given image. A Dockerfile adheres to a specific format and set of instructions which you can find at Dockerfile reference

For this lab, we will create a dockerfile as simply as possible. Use *nano Dockerfile* to create the file and paste below content in it then save it.

```plaintext
FROM nginx
COPY /files /usr/share/nginx/html
```

the image we will create here will use a Nginx image as a base image and will copy the website files from the */files* directory to the */usr/share/nginx/html* directory in the container. you can use another image if you want, like an apache image for example.

After that, we can start building the container image of our website.

Build the container with the *docker build* command. the dot . in the command bellow indicates the location of the dockerfile which is the current directory

```bash
docker build -t website .
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1669986396916/bf040250-545c-49aa-990c-dde93e1f55ff.png align="left")

Let's check if the image is available by running *docker images* command

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1669986611905/c6226fd8-9548-4e30-b92a-259ecdc02b6c.png align="left")

We can see that our image is available, now let's try to run it and access our website

```bash
docker run -it -d -p 80:80 website
```

The “-d” option detaches the container from the current shell and runs in the background. as output we will have the container ID.

The -p 80:80 maps to container’s port 80 to local machine port 80.

Once this command is executed we can access our website from the browser via http://localhost:80

Congratulations, you just deployed a website using a container. now let's move on to the next phase of this lab by scaling up a bit and deploying our website using Kubernetes.

# Deployment on Kubernetes

if not already done, start the cluster with the *minikube start* command.

Before you continue we need to make a small basic adjustment to minikube. By default the minikube node uses its own Docker repository that’s not connected to the Docker registry on the local machine, so without pulling, it doesn’t know where to get the image from. If we don't fix this, we'll observe an error ErrImageNeverPull. To fix this, let's use `minikube docker-env` the command that outputs environment variables needed to point the local Docker daemon to the minikube internal Docker registry.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1669989268838/723b375d-013b-4877-825d-6225b53a942b.png align="left")

As a recommendation on the output, To point the shell to minikube's docker-daemon, run: *eval $(minikube -p minikube docker-env)*

After that, the image has to be rebuilt again. Once this is done, we can move on to the actual deployment.

We can create a K8s deployment either via an imperative method (by writing directly the commands in the terminal) or via a declarative method where we declare in a yaml or json manifest file the desired state of our deployment and apply it. We will proceed with the declarative method here.

We can either start writing a manifest from scratch and deal with all the possible errors, or we can save ourselves from all that and use a really cool option of kubectl and quickly generate a file ready to use or on which we can work.

So to save us from all this hustle let's generate a yaml file with the *dry-run* option.

```bash
kubectl create deployment website --image=website --replicas=3 --port=80 --dry-run=client -o yaml > website.yaml
```

Then apply the manifest file

```bash
kubectl create -f website.yaml
```

Now let's see if the deployment has been successful.

```bash
kubectl get po
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1669991575069/773d888a-1d9f-479f-a691-6abe1ad58f32.png align="left")

Oh oh ! It seems we have a problem.

Kubernetes tries to pull the image specified in `the manifest`, but this image is not in the minikube registry or a public Docker registry. So to fix this you have to prevent the image from being pulled from a public registry by setting the image pull policy to never. Edit the website.yaml file the in container section add *imagePullPolicy: Never*

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1669991913622/45982c5e-b58b-4d75-9bf5-0d0c2ea614e6.png align="left")

then save the file then apply tby first deleting the erroneous deployment recheck again.

```bash
kubectl delete -f website.yaml
kubectl create -f website.yaml
kubectl get po
```

It should work now

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1669992228986/be9a0004-ca22-4a43-99c0-ad6872427759.png align="left")

Voila, it's okay now.

Next, expose the website deployment as a Kubernetes Service, specifying a port where it will be accessible with *\--type=NodePort* and *\--port=80*

```bash
kubectl expose deployment website --type=NodePort --port=80
```

Let's check whether the service is running.

```bash
kubectl get svc
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1669992544920/ab45d0cb-1ec9-4745-a2f7-66508278edae.png align="left")

Now let's retrieve a URL that is accessible outside of the container.

```bash
minikube service website --url
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1669992831657/27274468-708d-454e-9f3e-446ca431a722.png align="left")

once the url has been obtained, it can be accessed via a browser.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1669992914935/6ecaa0aa-3b6b-4c2d-9c12-bb737b8eac1b.png align="left")

Well, that's what ends this article, thank you and see you very soon