I will explain in this article how to deploy and serve a kubenetes cluster(k3s) using your home laptop/PC. I will also show you how to expose your services to the internet with cloudflare tunnel. I will use a simple web app as an example to show how to build a full-stack application and serve it with the home server.

Here is the overview of the architecture setup.

infras.png

The laptop running all these stuff is a 7 year old Thinkpad with Interl i5 + 16G Mem installed with Ubuntu

Kubenetes

Kubernetes(k8s) is a convenient tool to manage you containerized services and jobs. You don’t need to setup a standard k8s as you don’t neeed a lot features. There are several lightweight alternatives you can use like k3s, microk8s, minikube and kind. Here we use k3s as it’s designed for edge and IoT devices, which fits my laptop

How to install k3s on ubuntu https://docs.k3s.io/installation

Cloudflare Tunnel

In cloudflare we trust…

As the name implies, we can use this service from cloudflare to set up a tunnel that exposes the service we build locally with home broadband. I would say this is the most important part of this setup as otherwise you are just building a toy locally.

How it works (image from cloudflare.com)

image.png

There are two ways to set up the tunnel on your PC, you can use cloudfare dashboard online or cloudflared locally, here are the instructions https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/tunnel-guide/

As here we need to do extra step to expose k3s , we need to set up ingress resource privided by cloudflare. Specifically, we need to add our ingress rules that allow the traffic route to the corresponding service we deployed on k3s. Just download the yaml here then change the rules according to the specification here

This is the ingress configmap I used in this project, before you configure this , make sure you have configured the dns record with cloudflare or other similar service providers.

  - hostname: gitstats.ofeng.org
	path: /api
	service: http://mygit-backend:6000  

  - hostname: gitstats.ofeng.org
	path: /
	service: http://mygit-frontend:80

As you noticed the backend and frontend apps use the same host with different path to separate, this is an easy way to avoid cross region accessing issue.

CI and deployment

This project uses github action workflow as the CI tool as it’s easy to set up since I use github as the repository holder. The CI process do the stuff of building docker image and push to github image registry

I use kustomize to manually deploy after the image building workflow finish. The command looks like kubectl apply -k [kustomize folder] It could be fully automized following the GitOps practice using tools like FluxCD or ArgoCD, but for now I’m good to deploy manually as I need to spend more time on other stuff like coding and testing.

Here is an example how this deployment files look like https://github.com/stefanprodan/podinfo/tree/master/deploy

Database

I use Mysql to hold the application data, it took me a while to decide whether to deploy Mysql outside the cluster or inside. I choosed deploy it within k3s finally as the helm install command is too convenient and it’s easier to set up mysql connection as a service in kubernetes provides a dns name natually. I understand there should be master-slave deploy and failover supports for serious data server, however it’s more important to set up the basics quickly at this stage.

The helm chart I used is from bitnami, the link here https://bitnami.com/stack/mysql/helm

Services

I developed the frontend app with Vue + Element-UI and served with nginx in container. I found Vue is friendly to backend programmers like me. I spent some time on table listing and pagination and built more confidence on writing up Vue apps interacting with data APIs

Regarding the backend app, I use springboot to build the rest APIs that read the mysql database. I deployed a scheduler to fill up and update the data and deployed with a native cronjob workload.

Sum up

This is just a MVP of the project and there are numerous things to do to make it serious. I think the key point here is how to serve anything with the minimum resources at your hand. I always have a lot of side project ideas but I hardly put them into practice, thanks to the cloud infrastructure and tools like k8s/k3s and tunnels which allow me to build and serve some serious stuff.