Feedback

Chat Icon

Helm in Practice

Designing, Deploying, and Operating Kubernetes Applications at Scale

A Practical Guide to Building Multi-Service Applications with Helm
71%

A Quick Recap and Moving Forward

In a previous chapter, we built a simple Todo application that uses SQLite for storage. While SQLite is easy to set up, it's not what will introduce you to managing real-world applications with different components. In this chapter, we will be concerned with more challenging tasks:

  • Adapt our application code to use PostgreSQL instead of SQLite to introduce a database dependency.
  • Build and push the updated application image to our Harbor registry.
  • Create a Helm chart that deploys both our application and a PostgreSQL database as a dependency.
  • Deploy the application using our new Helm chart.
  • Verify the deployment and run Helm tests.
  • Discuss best practices throughout the process.

Our new application will support the same functionality as before (creating and listing tasks):

  • GET /tasks —> Returns all tasks as JSON.
  • POST /tasks —> Creates a new task.

We will introduce a third endpoint for health checks:

  • GET /health —> Returns a simple health status for Kubernetes probes

Let's move on to the implementation. Start by creating a new directory for our updated application:

mkdir -p $HOME/todowithdb-app/app

This is the new application code that:

  • Uses psycopg2 to connect to PostgreSQL
  • Reads database connection details from environment variables
  • Includes a health check endpoint
  • Initializes the database schema on startup
  • Handles database connections simply (no pooling for code brevity)
  • Runs on port 5000 of the container.
cat << 'EOF' > $HOME/todowithdb-app/app/app.py
import os
from flask import Flask, jsonify, request
import psycopg2
from psycopg2.extras import RealDictCursor

app = Flask(__name__)

# Database configuration from environment variables
# These will be injected by Kubernetes from our Helm values
DB_HOST = os.environ.get("DB_HOST", "localhost")
DB_PORT = int(os.environ.get("DB_PORT", "5432"))
DB_NAME = os.environ.get("DB_NAME", "todo_db")
DB_USER = os.environ.get("DB_USER", "todo_user")
DB_PASSWORD = os.environ.get("DB_PASSWORD", "todo_password")


def get_db_connection():
    """
    Create a new PostgreSQL connection.
    In production, you might use a connection pool or PgBouncer,
    but this simple approach works well for learning.
    """
    conn = psycopg2.connect(
        host=DB_HOST,
        port=DB_PORT,
        dbname=DB_NAME,
        user=DB_USER,
        password=DB_PASSWORD,
    )
    return conn


def init_db():
    """
    Initialize the database schema.
    Creates the tasks table if it doesn't exist.
    In production, use a migration tool like Alembic.
    """
    conn = get_db_connection()
    try:
        with conn.cursor() as cursor:
            cursor.execute(
                """
                CREATE TABLE IF NOT EXISTS tasks (
                    id SERIAL PRIMARY KEY,
                    title TEXT NOT NULL,
                    description TEXT NOT NULL
                );
                """
            )
        conn.commit()
    finally:
        conn.close()


@app.route("/health", methods=["GET"])
def health_check():
    """Simple health check endpoint for Kubernetes probes."""
    return jsonify({"status": "healthy"})


@app.route("/tasks", methods=["GET"])
def get_tasks():
    """Return all tasks as JSON."""
    conn

Helm in Practice

Designing, Deploying, and Operating Kubernetes Applications at Scale

Enroll now to unlock current content and receive all future updates for free. Your purchase supports the author and fuels the creation of more exciting content. Act fast, as the price will rise as the course nears completion!

Unlock now  $15.99$11.99

Hurry! This limited time offer ends in:

To redeem this offer, copy the coupon code below and apply it at checkout:

Learn More