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:latestDocker 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: bridgeCreate .env:
DD_API_KEY=your_datadog_api_key
ENVIRONMENT=productionDeploy:
# 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 -dNginx 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=2Create 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-southeast1AWS 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.fqdnKubernetes 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 specDeploy:
kubectl apply -f k8s-deployment.yaml
kubectl get services raksha-serviceHelm 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.yamlCI/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:
- mainPerformance 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
- Use HTTPS - Always encrypt traffic in production
- Private Networks - Deploy in VPC/private subnets when possible
- Firewall Rules - Restrict access to essential ports only
- 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:latestSecret Management
Kubernetes Secrets:
kubectl create secret generic raksha-secrets \
--from-literal=DD_API_KEY=your_key \
--from-literal=GITHUB_TOKEN=your_tokenCloud 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.