Skip to main content
The DjangoApplication construct simplifies deployment of Django applications to Kubernetes. It automatically configures the deployment, service, ingress, and environment variables needed to run a Django application.

Constructor

new DjangoApplication(scope: Construct, appname: string, props: DjangoApplicationProps)

Properties

deployment
DeploymentProps
required
Deployment configuration including image, replicas, environment variables, and resource limits.
djangoSettingsModule
string
required
The value for the DJANGO_SETTINGS_MODULE environment variable. This specifies which settings file Django should use (e.g., "myapp.settings.production").
port
number
default:"80"
Port to expose the application on. This is used for the Kubernetes service and ingress configuration.
domains
NonEmptyArray<HostRules>
Array of domain configurations. Each entry specifies:
  • host: The domain name (e.g., "api.example.com")
  • paths: Array of URL paths to expose (e.g., ["/api", "/admin"])
  • isSubdomain: Whether this is a subdomain for certificate purposes
Optional if the application is not publicly accessible (e.g., Celery workers).
ingressProps
Partial<Omit<IngressProps, 'port'>>
Optional ingress configuration to override default settings, such as custom annotations for path-based routing.
createServiceAccount
boolean
default:"false"
Whether to create a Kubernetes service account and attach it to deployment pods. The service account name will be the release name.

Behavior

The DjangoApplication construct automatically:
  1. Sets environment variables: Injects DJANGO_SETTINGS_MODULE and DOMAINS (comma-separated list of hosts)
  2. Creates ingress rules: Configures ingress based on the provided domains and paths
  3. Manages certificates: Uses the isSubdomain flag to determine certificate generation strategy
  4. Configures service: Creates a Kubernetes service exposing the specified port

Usage Example

Basic Django Application

import { DjangoApplication } from '@pennlabs/kittyhawk';

new DjangoApplication(this, 'django-api', {
  deployment: {
    image: 'pennlabs/example-backend',
    replicas: 2,
    secret: 'example-secret',
    env: [
      { name: 'DEBUG', value: 'false' },
      { name: 'DATABASE_URL', value: 'postgresql://...' },
    ],
  },
  djangoSettingsModule: 'example.settings.production',
  domains: [
    { host: 'api.example.com', paths: ['/api'] },
  ],
});

Django with Multiple Domains

new DjangoApplication(this, 'django-multi', {
  deployment: {
    image: 'pennlabs/backend',
    replicas: 3,
    secret: 'backend-secret',
  },
  djangoSettingsModule: 'myapp.settings.production',
  domains: [
    { host: 'api.example.com', paths: ['/api', '/admin'] },
    { host: 'webhook.example.com', paths: ['/'] },
  ],
  port: 8000,
});

Django ASGI (WebSockets)

Example from the Kittyhawk README:
new DjangoApplication(this, 'django-asgi', {
  deployment: {
    image: backendImage,
    cmd: ['/usr/local/bin/asgi-run'],
    replicas: 2,
    secret: secret,
    env: [
      { name: 'REDIS_HOST', value: 'redis' },
    ],
  },
  djangoSettingsModule: 'example.settings.production',
  domains: [{ host: domain, paths: ['/api/ws'] }],
});

Django Without Public Access (Celery Worker)

new DjangoApplication(this, 'celery-worker', {
  deployment: {
    image: 'pennlabs/backend',
    cmd: ['celery', '-A', 'myapp', 'worker'],
    replicas: 1,
    secret: 'backend-secret',
    env: [
      { name: 'REDIS_HOST', value: 'redis' },
    ],
  },
  djangoSettingsModule: 'myapp.settings.production',
  // No domains - not publicly accessible
});
  • Deployments - Configuration options for the underlying deployment
  • Ingress - Ingress construct for custom routing
  • Certificates - Certificate management for TLS

Build docs developers (and LLMs) love