Skip to content

Deployment Guide

This guide covers production deployment of OJS backends using the infrastructure templates in the deploy/ directory. Four deployment methods are available: Helm charts, Terraform modules, raw Kubernetes manifests, and Docker Compose with monitoring.

MethodBest forPrerequisites
HelmKubernetes-native teamsKubernetes 1.26+, Helm 3
TerraformMulti-cloud IaCTerraform 1.5+, cloud provider account
Kubernetes manifestsSimple K8s deployments, Kustomize usersKubernetes 1.26+
Docker ComposeLocal dev, single-server deploymentsDocker, Docker Compose

The Helm chart deploys an OJS server with its backing store (Redis, PostgreSQL, or NATS) and optional monitoring.

Terminal window
helm repo add openjobspec https://charts.openjobspec.org
helm repo update
# Install with Redis backend (default)
helm install ojs openjobspec/ojs-server
# Install with PostgreSQL backend
helm install ojs openjobspec/ojs-server --set backend=postgres

Key values.yaml overrides:

# Backend selection
backend: redis # redis | postgres | nats
# Server configuration
replicaCount: 3
image:
repository: ghcr.io/openjobspec/ojs-backend-redis
tag: latest
# Resource limits
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: "2"
memory: 2Gi
# Auto-scaling
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
# Monitoring
metrics:
enabled: true
serviceMonitor:
enabled: true
# Network policy
networkPolicy:
enabled: true
# Redis (when backend=redis)
redis:
enabled: true
architecture: standalone
  • Enable networkPolicy to restrict traffic to OJS pods
  • Set resource requests and limits for predictable scheduling
  • Enable serviceMonitor if running Prometheus Operator
  • Use PodDisruptionBudget (included by default) for availability during upgrades

Terraform modules provision OJS infrastructure on AWS, GCP, and Azure.

Deploys OJS on ECS Fargate with ElastiCache Redis and an ALB.

module "ojs" {
source = "github.com/openjobspec/openjobspec//deploy/terraform/aws"
cluster_name = "ojs-production"
backend = "redis"
instance_type = "cache.r7g.large"
desired_count = 3
cpu = 1024
memory = 2048
vpc_id = var.vpc_id
subnet_ids = var.private_subnet_ids
alb_subnet_ids = var.public_subnet_ids
}

Resources created: ECS cluster, Fargate service, ElastiCache Redis, ALB, security groups, CloudWatch log group.

Terminal window
cd deploy/terraform/aws # or gcp, azure
terraform init
terraform plan
terraform apply

Raw Kubernetes manifests with Kustomize overlays for teams that prefer plain YAML over Helm.

deploy/kubernetes/
├── base/
│ ├── kustomization.yaml
│ ├── namespace.yaml
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── configmap.yaml
│ └── redis/
├── overlays/
│ ├── dev/
│ │ └── kustomization.yaml
│ └── production/
│ ├── kustomization.yaml
│ ├── hpa.yaml
│ ├── pdb.yaml
│ ├── networkpolicy.yaml
│ └── monitoring/
Terminal window
# Development
kubectl apply -k deploy/kubernetes/overlays/dev
# Production
kubectl apply -k deploy/kubernetes/overlays/production
  • HorizontalPodAutoscaler — Scales based on CPU and custom metrics
  • PodDisruptionBudget — Ensures availability during node maintenance
  • NetworkPolicy — Restricts ingress/egress to required ports
  • RBAC — Least-privilege service account
  • Security context — Read-only filesystem, non-root user, dropped capabilities
  • Prometheus annotations — Scrape configuration for metrics collection

The deploy/grafana/ directory provides pre-built Grafana dashboards and Prometheus configuration for OJS observability.

DashboardWhat it shows
OJS OverviewThroughput (jobs/sec), latency (p50/p95/p99), queue depth, error rate
Queue DetailPer-queue depth, processing rate, wait time, dead letter count
AlertsPre-configured alert rules for queue depth, error rate, and latency
MetricTypeDescription
ojs_jobs_enqueued_totalCounterTotal jobs enqueued
ojs_jobs_completed_totalCounterTotal jobs completed
ojs_jobs_failed_totalCounterTotal jobs failed
ojs_jobs_duration_secondsHistogramJob execution duration
ojs_queue_depthGaugeCurrent queue depth
ojs_queue_latency_secondsHistogramTime from enqueue to start
ojs_workers_activeGaugeActive worker count
ojs_dead_letter_countGaugeDead letter queue size
ojs_scheduler_runs_totalCounterScheduler loop executions
ojs_heartbeat_latency_secondsHistogramWorker heartbeat latency
ojs_batch_sizeHistogramBatch enqueue sizes
ojs_workflow_duration_secondsHistogramWorkflow execution duration
ojs_cron_triggers_totalCounterCron job triggers
Terminal window
cd deploy/grafana
docker compose up -d

This starts Prometheus (scraping OJS metrics on :8080/metrics) and Grafana (available at http://localhost:3000) with dashboards pre-provisioned.

  1. Add the Prometheus scrape target:

    prometheus.yml
    scrape_configs:
    - job_name: ojs
    static_configs:
    - targets: ['ojs-server:8080']
    metrics_path: /metrics
  2. Import dashboards from deploy/grafana/dashboards/ into your Grafana instance.