In previous posts I had written about how to set up a Kubernetes cluster on self-hosted hardware with the purpose of hosting applications on a Local Area Network (LAN) to use as an intranet of sorts. Today I'll cover how to deploy client-side applications onto Kubernetes cluster which was provisioned.
Servers to Cloud Platforms
First, let's talk about how the deployments would be handled on a cloud platform. During the .com days, a server would have to be provisioned to host web applications (i.e. Apache/Nginx). The static website would then have to be copied into a static HTML folder (i.e./var/www/html
) in order to be served to clients via the web server.
The process of web hosting was improved with the rise of containerization. Instead of having to set up and manage a web server directly on your server hardware, now you can pull a pre-configured image and mount your static web content onto a container which would drastically improve website deployment times.
The rise of cloud platforms furthers the improvement by abstracting away the deployment environment from the developer entirely so that more focus can be placed on the website assets themselves instead of provisioning and configuring servers.
Cloud platforms implement hosted storage using a standard called Object-Based-Storage. Object-based-storage utilizes web endpoints to control and manage assets uploaded to a server. Site content can be managed and served directly using the HTTP protocol.AWS S3 is a perfect example of how object-based-storage works.
Minio
Minio is a self-hosted service which provides object-based-storage using the AWS S3 protocol; meaning that the endpoints which Minio provides are interchangeable with S3. Minio can be used as a gateway to hosted object-based-storage services which reside on multiple cloud platforms (i.e. Google Cloud Platform (GCP), Amazon Web Services (AWS), Microsoft Azure), but for the sake of this deployment, Minio will be used as a frontend for a mounted volume on our Kubernetes cluster.
Deploying the Services
Before we can deploy a static website to our Kubernetes cluster, we will first have to provision a Minio server.
The Minio documentation utilizes aMinio Operator and akubectl krew plugin to provision servers. Utilizing these tools will be covered in a later production release document. For the sake of this tutorial, deploying Minio will be handled with theMinio helm chart
UtilizingTerraform, the Minio server can be deployed to Helm with the following snippet:
provider"helm"{}resource"helm_release""rel_minio"{name="files"chart="minio"repository="https://charts.bitnami.com/bitnami"}
The helm chart can be deployed with the following commands:
terraform planterraform apply
Once the helm deployment has been completed, the service will be available from the Kubernetes cluster. In order to interact with the services, the credentials will have to be read in from the Kubernetes secrets which are generated by the helm chart. The following commands retrieve the secrets from Kubernetes and store them in environment variables:
exportminio_access_key=$(kubectl get secret files-minio--namespace econovizer-o=jsonpath='{.data.access-key}' |base64--decode)exportminio_secret_key=$(kubectl get secret files-minio--namespace econovizer-o=jsonpath='{.data.secret-key}' |base64--decode)
We then have to port-forward the Kubernetes service in order to access it.
kubectl port-forward services/files-minio 9000:9000
Configuring the Minio Client
Minio provides a CLI calledmc which can be utilized to interact with the Minio server. We have to call themc
tool with the$minio_secret_key
and the$minio_access_key
environment variables we created earlier.
mcalias set localhttp://127.0.0.1:9000$minio_access_key$minio_secret_key
With the client configured we can now create a bucket for hosting our static site.
mc mblocal/static
Before assets can be served from the bucket, the bucket needs to be configured for public asses.
mc policysetdownloadlocal/static
Creating the React Application
With the hosting environment established, we can now create our static website. The easiest way to set up the static website is usingCreate React App.
npx create-react-app my-app
This command will create a React application with the namemy-app
in the current folder. We need to change into themy-app
folder --cd my-app
. Build the project with the commandnpm run build
. The build command creates a new folderbuild
.
With the build folder created, we can deploy the build to our bucket with themc
command
mccp-r build/*local/static/mcls local/static# list the files which were just uploaded to the local/static bucket
Ideally from this point, you would be able to access the static site fromhttp://localhost:9000/static
, however Minio has a limitation which prevents it from serving up files unless they were referenced directly.http://localhost:9000/static
will return an XML document containing aListBucketResult
instead ofindex.html
.http://localhost:9000/static/index.html
will return the desired web page. Since the URL would end withindex.html
, React would be looking for a web root and fail to load.
Fortunately, the issue could be fixed with a proxy application:s3www.
To simplify the deployment of s3www, I created a Terraform template which deploys the following resources to Kubernetes:
- s3www pod deployment
- s3www Kubernetes service
- Ingress which proxies the s3www service
This file can be run with the following commands:
terraform initterraform plan-var"acces_key=$minio_access_key"-var"secret_key=$minio_secret_key"-var'namespace=my-namespace'-out deployment.planterraform apply deployment.plan
Once Terraform is complete, the React application will be available from your Kubernetes cluster via Ingress. (i.e.http://host.docker.internal/
)
References
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse