1. Answers
  2. Deploy PostgreSQL on Kubernetes using TypeScript and Docker

How Do I Deploy the Postgresql:14-Alpine Docker Image on Kubernetes With TypeScript?

Introduction

This guide aims to help you deploy a PostgreSQL instance using the postgresql:14-alpine Docker image on a Kubernetes cluster. We will leverage Pulumi with TypeScript to define and manage our Kubernetes resources. The guide covers setting up a namespace, creating persistent storage, deploying the database using a StatefulSet, and exposing it with a service. This setup ensures data persistence and high availability for the PostgreSQL database.

Key Points:

  • Define a Kubernetes Namespace for isolation.
  • Create a PersistentVolume and PersistentVolumeClaim for data persistence.
  • Deploy a StatefulSet to manage the PostgreSQL pods.
  • Expose the PostgreSQL service using a Service.

Step-by-Step Deployment Process

  1. Create a Namespace: Start by defining a namespace to isolate the PostgreSQL deployment.

  2. Define Persistent Storage: Set up a PersistentVolume and a PersistentVolumeClaim to ensure data persistence.

  3. Deploy the StatefulSet: Use a StatefulSet to manage the deployment of PostgreSQL pods, ensuring they have stable identities and storage.

  4. Expose the Service: Finally, create a Service to expose the PostgreSQL database to other applications within the cluster.

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

// Create a namespace for our PostgreSQL deployment
const namespace = new k8s.core.v1.Namespace("postgresql-ns", {
    metadata: {
        name: "postgresql-ns",
    },
});

// Define a PersistentVolume for PostgreSQL data
const persistentVolume = new k8s.core.v1.PersistentVolume("postgresql-pv", {
    metadata: {
        name: "postgresql-pv",
    },
    spec: {
        capacity: {
            storage: "10Gi",
        },
        accessModes: ["ReadWriteOnce"],
        hostPath: {
            path: "/mnt/data",
        },
    },
});

// Define a PersistentVolumeClaim to request the PersistentVolume
const persistentVolumeClaim = new k8s.core.v1.PersistentVolumeClaim("postgresql-pvc", {
    metadata: {
        namespace: namespace.metadata.name,
        name: "postgresql-pvc",
    },
    spec: {
        accessModes: ["ReadWriteOnce"],
        resources: {
            requests: {
                storage: "10Gi",
            },
        },
    },
});

// Deploy PostgreSQL using a StatefulSet
const statefulSet = new k8s.apps.v1.StatefulSet("postgresql", {
    metadata: {
        namespace: namespace.metadata.name,
        name: "postgresql",
    },
    spec: {
        serviceName: "postgresql",
        replicas: 1,
        selector: {
            matchLabels: {
                app: "postgresql",
            },
        },
        template: {
            metadata: {
                labels: {
                    app: "postgresql",
                },
            },
            spec: {
                containers: [
                    {
                        name: "postgresql",
                        image: "postgres:14-alpine",
                        ports: [
                            {
                                containerPort: 5432,
                                name: "postgresql",
                            },
                        ],
                        volumeMounts: [
                            {
                                name: "postgresql-storage",
                                mountPath: "/var/lib/postgresql/data",
                            },
                        ],
                        env: [
                            {
                                name: "POSTGRES_DB",
                                value: "mydatabase",
                            },
                            {
                                name: "POSTGRES_USER",
                                value: "admin",
                            },
                            {
                                name: "POSTGRES_PASSWORD",
                                value: "adminpassword",
                            },
                        ],
                    },
                ],
            },
        },
        volumeClaimTemplates: [
            {
                metadata: {
                    name: "postgresql-storage",
                },
                spec: {
                    accessModes: ["ReadWriteOnce"],
                    resources: {
                        requests: {
                            storage: "10Gi",
                        },
                    },
                },
            },
        ],
    },
});

// Expose the PostgreSQL service
const service = new k8s.core.v1.Service("postgresql", {
    metadata: {
        namespace: namespace.metadata.name,
        name: "postgresql",
    },
    spec: {
        ports: [
            {
                port: 5432,
                targetPort: "postgresql",
            },
        ],
        selector: {
            app: "postgresql",
        },
    },
});

Summary

In this guide, we successfully deployed a PostgreSQL instance on a Kubernetes cluster using Pulumi with TypeScript. We covered the creation of a namespace for isolation, set up persistent storage, deployed the database using a StatefulSet, and exposed it with a service. This configuration ensures that your PostgreSQL database remains highly available and persistent, ready to serve your applications.

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