Deployment Guide

Production-ready deployment options for RAKṢĀ vulnerability scanner.

Docker Deployment

Single Container

# Basic production deployment
docker run -d \
  --name raksha-prod \
  -p 80:8080 \
  --restart unless-stopped \
  -e DD_API_KEY=${DATADOG_API_KEY} \
  -e MAX_UPLOAD_MB=100 \
  -v /var/log/raksha:/var/log \
  ghcr.io/gaurav21/raksha:latest
 
# With custom configuration
docker run -d \
  --name raksha-custom \
  -p 8430:8080 \
  --restart unless-stopped \
  -e MAX_UPLOAD_MB=200 \
  -e SCAN_UPLOAD_DIR=/tmp/scans \
  -e DD_SERVICE=my-raksha \
  -e DD_ENV=staging \
  -v /opt/raksha/rules:/app/rules:ro \
  -v /var/tmp/raksha:/tmp/scans \
  ghcr.io/gaurav21/raksha:latest

Docker Compose

Create docker-compose.yml:

version: '3.8'
 
services:
  raksha:
    image: ghcr.io/gaurav21/raksha:latest
    container_name: raksha-api
    restart: unless-stopped
    ports:
      - "8430:8080"
    environment:
      - DD_API_KEY=${DD_API_KEY}
      - DD_SERVICE=avyay-raksha
      - DD_ENV=${ENVIRONMENT:-production}
      - DD_VERSION=1.0.0
      - MAX_UPLOAD_MB=100
      - SCAN_UPLOAD_DIR=/tmp/raksha-scans
    volumes:
      - scan-cache:/tmp/raksha-scans
      - ./rules:/app/rules:ro
      - ./logs:/var/log/raksha
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    deploy:
      resources:
        limits:
          memory: 2G
          cpus: '1.0'
        reservations:
          memory: 512M
          cpus: '0.5'
 
  nginx:
    image: nginx:alpine
    container_name: raksha-proxy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./ssl:/etc/nginx/ssl:ro
      - ./logs/nginx:/var/log/nginx
    depends_on:
      - raksha
    deploy:
      resources:
        limits:
          memory: 256M
          cpus: '0.2'
 
volumes:
  scan-cache:
    driver: local
 
networks:
  default:
    driver: bridge

Create .env:

DD_API_KEY=your_datadog_api_key
ENVIRONMENT=production

Deploy:

# Start services
docker-compose up -d
 
# View logs
docker-compose logs -f raksha
 
# Scale for high load
docker-compose up -d --scale raksha=3
 
# Update
docker-compose pull && docker-compose up -d

Nginx Configuration

Create nginx.conf:

events {
    worker_connections 1024;
}
 
http {
    upstream raksha {
        server raksha:8080;
        # For scaled deployments:
        # server raksha-1:8080;
        # server raksha-2:8080;
        # server raksha-3:8080;
    }
 
    # Rate limiting
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/m;
    limit_req_zone $binary_remote_addr zone=upload:10m rate=5r/m;
 
    server {
        listen 80;
        server_name your-domain.com;
        client_max_body_size 200M;
 
        # Security headers
        add_header X-Content-Type-Options nosniff;
        add_header X-Frame-Options DENY;
        add_header X-XSS-Protection "1; mode=block";
 
        # API endpoints with rate limiting
        location /scan/upload {
            limit_req zone=upload burst=2 nodelay;
            proxy_pass http://raksha;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_read_timeout 300s;
        }
 
        location /scan/ {
            limit_req zone=api burst=5 nodelay;
            proxy_pass http://raksha;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_read_timeout 300s;
        }
 
        # All other requests
        location / {
            proxy_pass http://raksha;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
 
        # Health check (no rate limit)
        location /health {
            proxy_pass http://raksha;
            access_log off;
        }
    }
}

Cloud Deployments

Google Cloud Run

# Build and deploy to Cloud Run
gcloud config set project your-project-id
 
# Deploy from container registry
gcloud run deploy raksha-api \
  --image=ghcr.io/gaurav21/raksha:latest \
  --platform=managed \
  --region=asia-southeast1 \
  --allow-unauthenticated \
  --memory=2Gi \
  --cpu=2 \
  --timeout=300 \
  --concurrency=80 \
  --max-instances=10 \
  --set-env-vars="MAX_UPLOAD_MB=100,DD_API_KEY=your_key"
 
# Custom deployment with secrets
gcloud run deploy raksha-api \
  --image=ghcr.io/gaurav21/raksha:latest \
  --platform=managed \
  --region=asia-southeast1 \
  --set-env-vars="MAX_UPLOAD_MB=100" \
  --update-secrets="DD_API_KEY=datadog-key:latest" \
  --memory=4Gi \
  --cpu=2

Create cloudrun.yaml for advanced configuration:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  name: raksha-api
  annotations:
    run.googleapis.com/ingress: all
spec:
  template:
    metadata:
      annotations:
        autoscaling.knative.dev/maxScale: "20"
        autoscaling.knative.dev/minScale: "1"
        run.googleapis.com/execution-environment: gen2
        run.googleapis.com/cpu-throttling: "false"
    spec:
      containerConcurrency: 100
      timeoutSeconds: 300
      containers:
      - image: ghcr.io/gaurav21/raksha:latest
        ports:
        - containerPort: 8080
        env:
        - name: MAX_UPLOAD_MB
          value: "200"
        - name: DD_SERVICE
          value: "avyay-raksha"
        - name: DD_ENV
          value: "production"
        resources:
          limits:
            cpu: "2"
            memory: "4Gi"

Deploy:

gcloud run services replace cloudrun.yaml --region=asia-southeast1

AWS ECS (Fargate)

Create task-definition.json:

{
  "family": "raksha-api",
  "networkMode": "awsvpc",
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "1024",
  "memory": "2048",
  "executionRoleArn": "arn:aws:iam::account:role/ecsTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::account:role/ecsTaskRole",
  "containerDefinitions": [
    {
      "name": "raksha",
      "image": "ghcr.io/gaurav21/raksha:latest",
      "portMappings": [
        {
          "containerPort": 8080,
          "protocol": "tcp"
        }
      ],
      "environment": [
        {
          "name": "MAX_UPLOAD_MB",
          "value": "100"
        },
        {
          "name": "DD_SERVICE",
          "value": "avyay-raksha"
        }
      ],
      "secrets": [
        {
          "name": "DD_API_KEY",
          "valueFrom": "arn:aws:secretsmanager:region:account:secret:datadog-api-key"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/raksha-api",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}

Deploy:

# Register task definition
aws ecs register-task-definition --cli-input-json file://task-definition.json
 
# Create service
aws ecs create-service \
  --cluster your-cluster \
  --service-name raksha-api \
  --task-definition raksha-api:1 \
  --desired-count 2 \
  --launch-type FARGATE \
  --network-configuration "awsvpcConfiguration={subnets=[subnet-12345],securityGroups=[sg-12345],assignPublicIp=ENABLED}"

Azure Container Instances

# Create resource group
az group create --name raksha-rg --location eastus
 
# Deploy container
az container create \
  --resource-group raksha-rg \
  --name raksha-api \
  --image ghcr.io/gaurav21/raksha:latest \
  --ports 8080 \
  --dns-name-label raksha-api-unique \
  --memory 2 \
  --cpu 1 \
  --environment-variables \
    'MAX_UPLOAD_MB=100' \
    'DD_SERVICE=avyay-raksha' \
  --secure-environment-variables \
    'DD_API_KEY=your_datadog_key'
 
# Get public IP
az container show \
  --resource-group raksha-rg \
  --name raksha-api \
  --query ipAddress.fqdn

Kubernetes Deployment

Basic Deployment

Create k8s-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: raksha-api
  labels:
    app: raksha
spec:
  replicas: 3
  selector:
    matchLabels:
      app: raksha
  template:
    metadata:
      labels:
        app: raksha
        tags.datadoghq.com/service: "avyay-raksha"
        tags.datadoghq.com/env: "production"
        tags.datadoghq.com/version: "1.0.0"
    spec:
      containers:
      - name: raksha
        image: ghcr.io/gaurav21/raksha:latest
        ports:
        - containerPort: 8080
          name: http
        env:
        - name: MAX_UPLOAD_MB
          value: "100"
        - name: DD_AGENT_HOST
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        - name: DD_SERVICE
          value: "avyay-raksha"
        - name: DD_ENV
          value: "production"
        - name: DD_VERSION
          value: "1.0.0"
        envFrom:
        - secretRef:
            name: raksha-secrets
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "2Gi"
            cpu: "1"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: raksha-service
spec:
  selector:
    app: raksha
  ports:
  - port: 80
    targetPort: 8080
    name: http
  type: LoadBalancer
---
apiVersion: v1
kind: Secret
metadata:
  name: raksha-secrets
type: Opaque
data:
  DD_API_KEY: <base64-encoded-key>

With Datadog Admission Controller

apiVersion: apps/v1
kind: Deployment
metadata:
  name: raksha-api
  labels:
    app: raksha
    tags.datadoghq.com/service: "avyay-raksha"
    tags.datadoghq.com/env: "production"
    tags.datadoghq.com/version: "1.0.0"
  annotations:
    admission.datadoghq.com/enabled: "true"
spec:
  replicas: 3
  selector:
    matchLabels:
      app: raksha
  template:
    metadata:
      labels:
        app: raksha
        tags.datadoghq.com/service: "avyay-raksha"
        tags.datadoghq.com/env: "production"
        tags.datadoghq.com/version: "1.0.0"
      annotations:
        admission.datadoghq.com/python-lib.version: "v2.17.0"
    spec:
      containers:
      - name: raksha
        image: ghcr.io/gaurav21/raksha:latest
        # ... rest of container spec

Deploy:

kubectl apply -f k8s-deployment.yaml
kubectl get services raksha-service

Helm Chart

Create helm/raksha/Chart.yaml:

apiVersion: v2
name: raksha
description: RAKṢĀ Code Security Scanner
version: 1.0.0
appVersion: "1.0.0"

Create helm/raksha/values.yaml:

image:
  repository: ghcr.io/gaurav21/raksha
  tag: "latest"
  pullPolicy: IfNotPresent
 
replicaCount: 3
 
service:
  type: LoadBalancer
  port: 80
  targetPort: 8080
 
ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
  hosts:
    - host: raksha.example.com
      paths: ["/"]
  tls:
    - secretName: raksha-tls
      hosts: ["raksha.example.com"]
 
env:
  MAX_UPLOAD_MB: "100"
  DD_SERVICE: "avyay-raksha"
  DD_ENV: "production"
 
secrets:
  DD_API_KEY: ""
 
resources:
  requests:
    memory: "512Mi"
    cpu: "250m"
  limits:
    memory: "2Gi"
    cpu: "1"
 
datadog:
  enabled: true
  env: production
  service: avyay-raksha
  version: "1.0.0"

Deploy:

helm install raksha ./helm/raksha --values production-values.yaml

CI/CD Pipeline Integration

GitHub Actions

Create .github/workflows/deploy.yml:

name: Deploy RAKṢĀ
 
on:
  push:
    branches: [main]
    paths-ignore: ['docs/**', '*.md']
 
env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}
 
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
 
    steps:
    - name: Checkout
      uses: actions/checkout@v4
 
    - name: Log in to Container Registry
      uses: docker/login-action@v3
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
 
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v5
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
        tags: |
          type=ref,event=branch
          type=ref,event=pr
          type=sha
          type=raw,value=latest,enable={{is_default_branch}}
 
    - name: Build and push Docker image
      uses: docker/build-push-action@v5
      with:
        context: .
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
 
    - name: Deploy to Cloud Run
      uses: google-github-actions/deploy-cloudrun@v2
      with:
        service: raksha-api
        image: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
        region: asia-southeast1
        env_vars: |
          MAX_UPLOAD_MB=100
          DD_SERVICE=avyay-raksha
          DD_ENV=production
        secrets: |
          DD_API_KEY=datadog-api-key:latest
 
    - name: Update Datadog deployment
      run: |
        curl -X POST "https://api.datadoghq.com/api/v1/events" \
          -H "Content-Type: application/json" \
          -H "DD-API-KEY: ${{ secrets.DD_API_KEY }}" \
          -d '{
            "title": "RAKṢĀ Deployment",
            "text": "New version deployed: ${{ github.sha }}",
            "tags": ["service:avyay-raksha", "env:production"]
          }'

GitLab CI

Create .gitlab-ci.yml:

variables:
  DOCKER_REGISTRY: registry.gitlab.com
  DOCKER_IMAGE: $CI_REGISTRY_IMAGE
  DOCKER_TAG: $CI_COMMIT_SHA
 
stages:
  - build
  - deploy
 
build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $DOCKER_IMAGE:$DOCKER_TAG .
    - docker tag $DOCKER_IMAGE:$DOCKER_TAG $DOCKER_IMAGE:latest
    - docker push $DOCKER_IMAGE:$DOCKER_TAG
    - docker push $DOCKER_IMAGE:latest
 
deploy:production:
  stage: deploy
  image: google/cloud-sdk:alpine
  script:
    - echo $GCP_SERVICE_KEY | base64 -d > gcloud-service-key.json
    - gcloud auth activate-service-account --key-file gcloud-service-key.json
    - gcloud config set project $GCP_PROJECT_ID
    - gcloud run deploy raksha-api 
        --image=$DOCKER_IMAGE:$DOCKER_TAG 
        --region=asia-southeast1 
        --platform=managed
  only:
    - main

Performance Optimization

Resource Sizing

Development:

  • CPU: 0.5 cores
  • Memory: 1GB
  • Storage: 10GB

Production (Light Load):

  • CPU: 1-2 cores
  • Memory: 2-4GB
  • Storage: 50GB

Production (High Load):

  • CPU: 4-8 cores
  • Memory: 8-16GB
  • Storage: 200GB

Caching Strategy

# Add Redis for scan result caching
version: '3.8'
services:
  redis:
    image: redis:alpine
    volumes:
      - redis-data:/data
    deploy:
      resources:
        limits:
          memory: 512M
 
  raksha:
    # Add environment variable
    environment:
      - REDIS_URL=redis://redis:6379
 
volumes:
  redis-data:

Load Balancing

For high-throughput environments:

upstream raksha_pool {
    least_conn;
    server raksha-1:8080 max_fails=3 fail_timeout=30s;
    server raksha-2:8080 max_fails=3 fail_timeout=30s;
    server raksha-3:8080 max_fails=3 fail_timeout=30s;
}

Security Considerations

Network Security

  1. Use HTTPS - Always encrypt traffic in production
  2. Private Networks - Deploy in VPC/private subnets when possible
  3. Firewall Rules - Restrict access to essential ports only
  4. API Gateway - Consider rate limiting and authentication

Container Security

# Security-hardened Dockerfile
FROM python:3.11-slim
 
# Create non-root user
RUN groupadd -r raksha && useradd -r -g raksha raksha
 
# Set secure file permissions
COPY --chown=raksha:raksha . /app
USER raksha
 
# Run with read-only root filesystem
# docker run --read-only --tmpfs /tmp ghcr.io/gaurav21/raksha:latest

Secret Management

Kubernetes Secrets:

kubectl create secret generic raksha-secrets \
  --from-literal=DD_API_KEY=your_key \
  --from-literal=GITHUB_TOKEN=your_token

Cloud Secrets:

# AWS Secrets Manager
aws secretsmanager create-secret \
  --name raksha/datadog-api-key \
  --secret-string your_api_key
 
# Google Secret Manager  
gcloud secrets create datadog-api-key \
  --data-file=<(echo -n "your_api_key")

Next: Configuration Guide for scanner customization and rule management.