Skip to main content

Overview

Orphelix can be deployed in multiple ways depending on your infrastructure and requirements. This guide covers all deployment methods from simple standalone setups to enterprise Kubernetes deployments.

Standalone

Single-server deployment with PM2

Docker

Containerized deployment with Docker Compose

Kubernetes

Native Kubernetes deployment with Helm

Cloud Platforms

AWS, GCP, Azure managed services

Prerequisites

General Requirements

Required for all deployment methods
node --version
# v20.11.0 or higher
Required for real cluster mode
  • Valid kubeconfig file
  • Appropriate RBAC permissions
  • Network access to Kubernetes API
Minimum permissions:
  • get, list, watch on: pods, deployments, services, nodes, events, configmaps, secrets
  • patch on deployments (for restart)
Required for GitOps features
  • GitHub OAuth App credentials
  • GitHub App credentials (for repository access)
See GitHub Setup Guide
Required for AI features
OPENAI_API_KEY=sk-...

Deployment Methods

Method 1: Standalone (PM2)

Best for: Small teams, single server, quick setup
1

Clone repository

git clone https://github.com/corapoid/orphelix.git
cd orphelix/app
2

Install dependencies

npm install
3

Configure environment

cp .env.example .env.local
Edit .env.local:
NEXTAUTH_SECRET=your-random-secret
NEXTAUTH_URL=https://your-domain.com

# GitHub OAuth (optional)
GITHUB_ID=your-oauth-app-id
GITHUB_SECRET=your-oauth-app-secret

# GitHub App (optional)
GITHUB_APP_ID=123456
GITHUB_APP_CLIENT_ID=Iv1.abc123
GITHUB_APP_CLIENT_SECRET=secret
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n..."

# OpenAI (optional)
OPENAI_API_KEY=sk-...
4

Build application

npm run build:standalone
This creates a standalone build in .next/standalone/
5

Start with CLI

# Start (with PM2)
./orphelix-cli.js start

# Check status
./orphelix-cli.js status

# View logs
./orphelix-cli.js logs

# Stop
./orphelix-cli.js stop
6

Access application

Production considerations:
  • Use reverse proxy (nginx, Caddy)
  • Enable HTTPS with Let’s Encrypt
  • Configure firewall rules
  • Set up log rotation
  • Enable automatic restart on crash

Method 2: Docker

Best for: Containerized environments, isolated deployments Important notes:
  • Mount kubeconfig as read-only volume
  • Persist database with volume
  • Use secrets management for sensitive data
  • Configure health checks
  • Set resource limits (CPU, memory)

Method 3: Kubernetes (Helm)

Best for: Enterprise deployments, high availability, scalability
1

Install Helm

# macOS
brew install helm

# Linux
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
2

Add Orphelix Helm repository

helm repo add orphelix https://charts.orphelix.dev
helm repo update
Helm chart coming soon! For now, use manual deployment below.
3

Create namespace

kubectl create namespace orphelix
4

Create secrets

# NextAuth secret
kubectl create secret generic orphelix-nextauth \
  --from-literal=secret=$(openssl rand -base64 32) \
  -n orphelix

# GitHub OAuth
kubectl create secret generic orphelix-github-oauth \
  --from-literal=client-id=your-oauth-client-id \
  --from-literal=client-secret=your-oauth-client-secret \
  -n orphelix

# GitHub App
kubectl create secret generic orphelix-github-app \
  --from-literal=app-id=123456 \
  --from-literal=client-id=Iv1.abc123 \
  --from-literal=client-secret=secret \
  --from-file=private-key=github-app-private-key.pem \
  -n orphelix

# OpenAI
kubectl create secret generic orphelix-openai \
  --from-literal=api-key=sk-... \
  -n orphelix
5

Create deployment manifest

Create orphelix-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: orphelix
  namespace: orphelix
  labels:
    app: orphelix
spec:
  replicas: 2
  selector:
    matchLabels:
      app: orphelix
  template:
    metadata:
      labels:
        app: orphelix
    spec:
      serviceAccountName: orphelix
      containers:
      - name: orphelix
        image: orphelix:latest
        ports:
        - containerPort: 3000
          name: http
        env:
        - name: NODE_ENV
          value: "production"
        - name: NEXTAUTH_URL
          value: "https://orphelix.your-domain.com"
        - name: NEXTAUTH_SECRET
          valueFrom:
            secretKeyRef:
              name: orphelix-nextauth
              key: secret
        - name: GITHUB_ID
          valueFrom:
            secretKeyRef:
              name: orphelix-github-oauth
              key: client-id
        - name: GITHUB_SECRET
          valueFrom:
            secretKeyRef:
              name: orphelix-github-oauth
              key: client-secret
        - name: GITHUB_APP_ID
          valueFrom:
            secretKeyRef:
              name: orphelix-github-app
              key: app-id
        - name: GITHUB_APP_CLIENT_ID
          valueFrom:
            secretKeyRef:
              name: orphelix-github-app
              key: client-id
        - name: GITHUB_APP_CLIENT_SECRET
          valueFrom:
            secretKeyRef:
              name: orphelix-github-app
              key: client-secret
        - name: GITHUB_APP_PRIVATE_KEY
          valueFrom:
            secretKeyRef:
              name: orphelix-github-app
              key: private-key
        - name: OPENAI_API_KEY
          valueFrom:
            secretKeyRef:
              name: orphelix-openai
              key: api-key
        resources:
          requests:
            cpu: 500m
            memory: 512Mi
          limits:
            cpu: 1000m
            memory: 1Gi
        livenessProbe:
          httpGet:
            path: /api/health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /api/health
            port: 3000
          initialDelaySeconds: 10
          periodSeconds: 5
        volumeMounts:
        - name: kubeconfig
          mountPath: /root/.kube
          readOnly: true
      volumes:
      - name: kubeconfig
        secret:
          secretName: orphelix-kubeconfig

---
apiVersion: v1
kind: Service
metadata:
  name: orphelix
  namespace: orphelix
spec:
  selector:
    app: orphelix
  ports:
  - port: 80
    targetPort: 3000
    name: http
  type: ClusterIP

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: orphelix
  namespace: orphelix
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - orphelix.your-domain.com
    secretName: orphelix-tls
  rules:
  - host: orphelix.your-domain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: orphelix
            port:
              number: 80
6

Create RBAC for cluster access

Create orphelix-rbac.yaml:
apiVersion: v1
kind: ServiceAccount
metadata:
  name: orphelix
  namespace: orphelix

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: orphelix-viewer
rules:
# Core resources
- apiGroups: [""]
  resources:
  - pods
  - pods/log
  - services
  - nodes
  - namespaces
  - events
  - configmaps
  - secrets
  - persistentvolumes
  - persistentvolumeclaims
  - resourcequotas
  - limitranges
  verbs: ["get", "list", "watch"]

# Apps
- apiGroups: ["apps"]
  resources:
  - deployments
  - statefulsets
  - daemonsets
  - replicasets
  verbs: ["get", "list", "watch"]

# Deployments - restart (patch)
- apiGroups: ["apps"]
  resources:
  - deployments
  verbs: ["patch"]

# Batch
- apiGroups: ["batch"]
  resources:
  - jobs
  - cronjobs
  verbs: ["get", "list", "watch"]

# Networking
- apiGroups: ["networking.k8s.io"]
  resources:
  - ingresses
  verbs: ["get", "list", "watch"]

# Autoscaling
- apiGroups: ["autoscaling"]
  resources:
  - horizontalpodautoscalers
  verbs: ["get", "list", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: orphelix-viewer
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: orphelix-viewer
subjects:
- kind: ServiceAccount
  name: orphelix
  namespace: orphelix
7

Deploy

# Apply RBAC
kubectl apply -f orphelix-rbac.yaml

# Apply deployment
kubectl apply -f orphelix-deployment.yaml

# Check status
kubectl get pods -n orphelix
kubectl logs -f deployment/orphelix -n orphelix
8

Access application

# Via ingress (if configured)
https://orphelix.your-domain.com

# Or port-forward
kubectl port-forward -n orphelix svc/orphelix 3000:80
High availability configuration:
  • Set replicas: 3 or more
  • Use anti-affinity rules
  • Configure HPA for auto-scaling
  • Use external database (PostgreSQL)
  • Implement distributed sessions

Method 4: Cloud Platforms

AWS Elastic Kubernetes Service (EKS)
1

Create EKS cluster

eksctl create cluster \
  --name orphelix-cluster \
  --region us-east-1 \
  --nodegroup-name standard-workers \
  --node-type t3.medium \
  --nodes 3
2

Install AWS Load Balancer Controller

helm repo add eks https://aws.github.io/eks-charts
helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
  -n kube-system \
  --set clusterName=orphelix-cluster
3

Deploy Orphelix

Use Kubernetes deployment method aboveUpdate Ingress:
annotations:
  kubernetes.io/ingress.class: alb
  alb.ingress.kubernetes.io/scheme: internet-facing
  alb.ingress.kubernetes.io/target-type: ip
  alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:...
AWS-specific features:
  • Use EKS IRSA for kubeconfig auth
  • Store secrets in AWS Secrets Manager
  • Use RDS for database
  • CloudWatch for logs and metrics

Configuration

Environment Variables

# NextAuth
NEXTAUTH_SECRET=your-random-secret-here
NEXTAUTH_URL=https://your-domain.com

# Database
DATABASE_URL=file:./orphelix.db

# Node
NODE_ENV=production
# GitHub OAuth (for login)
GITHUB_ID=your-oauth-app-client-id
GITHUB_SECRET=your-oauth-app-client-secret

# GitHub App (for GitOps)
GITHUB_APP_ID=123456
GITHUB_APP_CLIENT_ID=Iv1.abc123
GITHUB_APP_CLIENT_SECRET=your-client-secret
GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----"
# OpenAI
OPENAI_API_KEY=sk-...
# Port (default: 3000)
PORT=3000

# Hostname (default: 0.0.0.0)
HOSTNAME=0.0.0.0

# Log level
LOG_LEVEL=info

Reverse Proxy (nginx)

nginx configuration:
server {
    listen 80;
    server_name orphelix.your-domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name orphelix.your-domain.com;

    ssl_certificate /etc/letsencrypt/live/orphelix.your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/orphelix.your-domain.com/privkey.pem;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # SSE support
    location /api/stream {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Connection '';
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding off;
    }
}

Monitoring

Health Checks

Endpoint: /api/health
curl http://localhost:3000/api/health
Response:
{
  "status": "ok",
  "timestamp": "2025-01-28T10:00:00Z",
  "version": "0.1.0"
}

Logs

# View logs
./orphelix-cli.js logs

# Or directly
pm2 logs orphelix

# Log location
~/.pm2/logs/

Metrics

Prometheus metrics: (Coming soon)
# /api/metrics endpoint
# Prometheus format
orphelix_http_requests_total{method="GET",path="/api/deployments"} 1234
orphelix_http_request_duration_seconds{method="GET",path="/api/deployments"} 0.123

Backup and Recovery

Database Backup

SQLite database:
# Backup
cp orphelix.db orphelix.db.backup

# Or with timestamp
cp orphelix.db "orphelix.db.$(date +%Y%m%d_%H%M%S).backup"

# Restore
cp orphelix.db.backup orphelix.db
Automated backup script:
#!/bin/bash
# backup-orphelix.sh

BACKUP_DIR="/backups/orphelix"
DB_PATH="/app/orphelix.db"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR"
cp "$DB_PATH" "$BACKUP_DIR/orphelix-$TIMESTAMP.db"

# Keep only last 30 days
find "$BACKUP_DIR" -name "orphelix-*.db" -mtime +30 -delete
Cron job:
0 2 * * * /usr/local/bin/backup-orphelix.sh

Kubernetes Backup

Using Velero:
# Install Velero
velero install \
  --provider aws \
  --bucket orphelix-backups \
  --backup-location-config region=us-east-1

# Backup Orphelix namespace
velero backup create orphelix-backup --include-namespaces orphelix

# Restore
velero restore create --from-backup orphelix-backup

Security Hardening

Best Practices

  • Force HTTPS redirect
  • Use valid SSL certificates
  • Enable HSTS headers
  • Configure secure cookies
  • Never commit secrets to Git
  • Use environment variables
  • Use secret managers (AWS Secrets Manager, Azure Key Vault, etc.)
  • Rotate secrets regularly
  • Configure firewall rules
  • Use private networks
  • Implement rate limiting
  • Enable DDoS protection
  • Enforce strong passwords
  • Enable 2FA for GitHub
  • Use short-lived tokens
  • Implement session timeout
  • Enable audit logging
  • Monitor failed login attempts
  • Set up alerts for anomalies
  • Regular security reviews

Security Headers

Add to nginx config:
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';" always;

Troubleshooting

Check:
  • Node version: node --version (must be 20+)
  • Port availability: lsof -i :3000
  • Environment variables: Check .env.local
  • Database: Verify orphelix.db exists and is writable
Logs:
# PM2
pm2 logs orphelix

# Docker
docker logs orphelix

# Kubernetes
kubectl logs deployment/orphelix -n orphelix
Check:
  • Kubeconfig: kubectl config view
  • Current context: kubectl config current-context
  • Cluster access: kubectl get nodes
  • RBAC permissions: kubectl auth can-i get pods
For cloud providers:
  • AWS: Token may be expired, run aws eks update-kubeconfig
  • GCP: Run gcloud container clusters get-credentials
  • Azure: Run az aks get-credentials
Check:
  • OAuth App credentials in .env.local
  • GitHub App credentials
  • Callback URL matches: https://your-domain.com/api/auth/callback/github
  • Organization access granted
Test:
curl https://your-domain.com/api/github/auth-status
Solutions:
  • Increase memory limit in PM2/Docker/K8s
  • Reduce concurrent requests
  • Enable aggressive garbage collection:
    NODE_OPTIONS="--max-old-space-size=2048"
    
  • Check for memory leaks in logs

Upgrading

Standalone

cd orphelix/app

# Pull latest
git pull origin main

# Install dependencies
npm install

# Rebuild
npm run build:standalone

# Restart
./orphelix-cli.js restart

Docker

# Pull latest
git pull origin main

# Rebuild image
docker-compose build

# Restart
docker-compose up -d

Kubernetes

# Update image
kubectl set image deployment/orphelix \
  orphelix=orphelix:v0.2.0 \
  -n orphelix

# Or apply new manifest
kubectl apply -f orphelix-deployment.yaml

Performance Tuning

Node.js Optimization

# Increase memory
NODE_OPTIONS="--max-old-space-size=4096"

# Enable V8 optimizations
NODE_OPTIONS="--optimize-for-size"

# Production mode
NODE_ENV=production

Next.js Optimization

// next.config.mjs
export default {
  output: 'standalone',
  compress: true,
  poweredByHeader: false,
  reactStrictMode: true,
  swcMinify: true,
}

Database Optimization

# Enable WAL mode (better concurrency)
sqlite3 orphelix.db "PRAGMA journal_mode=WAL;"

# Optimize database
sqlite3 orphelix.db "VACUUM; ANALYZE;"

Next Steps

Support

Need help? Create an issue or ask in Discussions.