1. Answers
  2. Host static site on Kubernetes with Nginx?

How do I host a static site on Kubernetes with Nginx?

To host a static website on Kubernetes with Nginx, you need to set up a Kubernetes cluster, deploy an Nginx server, and configure it to serve your static content. We’ll use Pulumi to automate this process. Here’s a step-by-step guide:

  1. Set up a Kubernetes cluster: Ensure you have a Kubernetes cluster running. You can use any Kubernetes provider, such as AWS EKS, Google GKE, or Azure AKS. For simplicity, this example assumes you already have a cluster set up and kubectl configured to interact with it.

  2. Deploy Nginx: We’ll create a Kubernetes Deployment for Nginx and a Service to expose it.

  3. Configure Ingress: We’ll set up an Ingress resource to route traffic to the Nginx service.

  4. Serve Static Content: We’ll configure Nginx to serve static content from a specified directory.

Here’s the complete Pulumi program to achieve this:

Detailed Explanation:

  1. Nginx Deployment: This will create a Deployment resource with Nginx as the container. The static content will be stored in a ConfigMap, which will be mounted as a volume in the Nginx container.

  2. Service: This will expose the Nginx Deployment internally within the cluster.

  3. Ingress: This will expose the Nginx service to the outside world and route HTTP traffic to it.

Pulumi Program:

import * as pulumi from "@pulumi/pulumi";
import * as k8s from "@pulumi/kubernetes";

// Define the namespace
const namespace = new k8s.core.v1.Namespace("static-site-ns");

// Create a ConfigMap to hold the static content
const staticContent = new k8s.core.v1.ConfigMap("static-content", {
    metadata: {
        namespace: namespace.metadata.name,
    },
    data: {
        "index.html": "<html><body><h1>Hello, Pulumi!</h1></body></html>",
    },
});

// Create the Nginx Deployment
const nginxDeployment = new k8s.apps.v1.Deployment("nginx-deployment", {
    metadata: {
        namespace: namespace.metadata.name,
    },
    spec: {
        selector: { matchLabels: { app: "nginx" } },
        replicas: 1,
        template: {
            metadata: { labels: { app: "nginx" } },
            spec: {
                containers: [{
                    name: "nginx",
                    image: "nginx:latest",
                    volumeMounts: [{
                        name: "static-content",
                        mountPath: "/usr/share/nginx/html",
                        subPath: "index.html",
                    }],
                }],
                volumes: [{
                    name: "static-content",
                    configMap: {
                        name: staticContent.metadata.name,
                    },
                }],
            },
        },
    },
});

// Create a Service to expose the Nginx Deployment
const nginxService = new k8s.core.v1.Service("nginx-service", {
    metadata: {
        namespace: namespace.metadata.name,
    },
    spec: {
        type: "ClusterIP",
        selector: nginxDeployment.spec.template.metadata.labels,
        ports: [{ port: 80, targetPort: 80 }],
    },
});

// Create an Ingress to expose the Nginx Service
const nginxIngress = new k8s.networking.v1.Ingress("nginx-ingress", {
    metadata: {
        namespace: namespace.metadata.name,
        annotations: {
            "nginx.ingress.kubernetes.io/rewrite-target": "/",
        },
    },
    spec: {
        rules: [{
            http: {
                paths: [{
                    path: "/",
                    pathType: "Prefix",
                    backend: {
                        service: {
                            name: nginxService.metadata.name,
                            port: { number: 80 },
                        },
                    },
                }],
            },
        }],
    },
});

// Export the Ingress URL
export const ingressUrl = nginxIngress.status.loadBalancer.ingress[0].hostname;

Explanation of the Code:

  • Namespace: We create a namespace to isolate our resources.
  • ConfigMap: This holds our static content, which in this case is a simple HTML file.
  • Deployment: This defines the Nginx deployment. We mount the ConfigMap as a volume to serve the static content.
  • Service: This exposes the Nginx deployment internally within the Kubernetes cluster.
  • Ingress: This exposes the Nginx service to the outside world and routes HTTP traffic to it.
  • Export: The Ingress URL is exported so you can easily access your static site.

This Pulumi program sets up everything you need to host a static site on Kubernetes with Nginx. Just run it with pulumi up, and your static site will be deployed and accessible via the Ingress URL.

Deploy this code

Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.

Sign up

New to Pulumi?

Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.

Sign up