DEV Community

Cover image for From Containers to Clusters: Deploying Cipher Horizon in Production
Daniele Minatto
Daniele Minatto

Posted on

From Containers to Clusters: Deploying Cipher Horizon in Production

Introduction

Deploying a microservices architecture like Cipher Horizon requires a well-thought-out strategy for containerization, orchestration, and automation. This post details our journey from local development to production deployment, sharing insights and lessons learned along the way.

Understanding Our Deployment Requirements

Before diving into implementation, we identified key requirements:

  1. Scalability
    • Horizontal scaling capabilities
    • Auto-scaling based on demand
    • Resource optimization
  2. Reliability
    • High availability
    • Fault tolerance
    • Disaster recovery
  3. Maintainability
    • Easy updates and rollbacks
    • Configuration management
    • Monitoring and observability

Containerization Strategy

Docker Implementation

Our containerization strategy focused on creating efficient, secure, and maintainable container images:

# Base service image
FROM node:18-alpine AS base
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# Development image
FROM base AS development
RUN npm install --only=development
COPY . .
RUN npm run build

# Production image
FROM base AS production
COPY --from=development /app/dist ./dist
COPY --from=development /app/config ./config

# Health check and configuration
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:${PORT}/health || exit 1

ENV NODE_ENV=production
EXPOSE ${PORT}
CMD ["node", "dist/main.js"]
Enter fullscreen mode Exit fullscreen mode

Multi-Stage Build Strategy

// Build configuration
interface BuildConfig {
    stages: {
        base: {
            dependencies: string[];
            security: SecurityConfig;
        };
        development: {
            tools: string[];
            tests: TestConfig;
        };
        production: {
            optimization: OptimizationConfig;
            monitoring: MonitoringConfig;
        };
    };
}
Enter fullscreen mode Exit fullscreen mode

Why Multi-Stage Builds?

We chose multi-stage builds for several reasons:

  1. Smaller Production Images
    • Only necessary artifacts included
    • Reduced attack surface
    • Faster deployment times
  2. Development/Production Parity
    • Consistent base image
    • Reproducible builds
    • Clear separation of concerns
  3. Security Benefits
    • Minimal production dependencies
    • Reduced vulnerability surface
    • Better secret management

Kubernetes Deployment Strategy

Base Configuration

Our Kubernetes deployment strategy emphasizes reliability and scalability:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cipher-service
  namespace: cipher-horizon
spec:
  replicas: 3
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    spec:
      containers:
      - name: cipher-service
        image: cipher-horizon/service:${VERSION}
        resources:
          requests:
            memory: "256Mi"
            cpu: "200m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: http
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: http
          initialDelaySeconds: 5
          periodSeconds: 5
Enter fullscreen mode Exit fullscreen mode

Resource Management

We implemented careful resource management through:

-Resource Quotas

apiVersion: v1
kind: ResourceQuota
metadata:
  name: cipher-quota
  namespace: cipher-horizon
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    limits.cpu: "8"
    limits.memory: 16Gi
Enter fullscreen mode Exit fullscreen mode

-Horizontal Pod Autoscaling

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: cipher-service-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: cipher-service
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
Enter fullscreen mode Exit fullscreen mode

CI/CD Pipeline Implementation

Our CI/CD pipeline ensures reliable and consistent deployments:

name: Cipher Horizon CI/CD

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '18'

      - name: Install Dependencies
        run: npm ci

      - name: Run Tests
        run: npm run test:ci

      - name: Build Docker Image
        run: |
          docker build -t cipher-horizon/service:${GITHUB_SHA} .

      - name: Run Security Scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'cipher-horizon/service:${GITHUB_SHA}'
          format: 'table'
          exit-code: '1'
          severity: 'CRITICAL,HIGH'
Enter fullscreen mode Exit fullscreen mode

Deployment Automation

We implemented several automation strategies:

  • Automated Rollbacks
class DeploymentManager {
    async deploy(version: string): Promise<void> {
        try {
            await this.performDeployment(version);
            await this.validateDeployment();
        } catch (error) {
            await this.rollback(version);
            throw new DeploymentError(error);
        }
    }

    private async validateDeployment(): Promise<void> {
        // Health checks
        // Performance metrics
        // Error rate monitoring
    }
}
Enter fullscreen mode Exit fullscreen mode
  • Configuration Management
@Injectable()
class ConfigurationManager {
    async updateConfig(
        environment: string,
        config: ConfigUpdate
    ): Promise<void> {
        const configMap = await this.k8sClient.configMaps.get(
            `${environment}-config`
        );

        await this.validateConfig(config);
        await this.applyConfig(configMap, config);
        await this.rolloutUpdate(environment);
    }
}
Enter fullscreen mode Exit fullscreen mode

Cost Optimization Strategies

We implemented several cost optimization measures:

Resource Optimization

interface ResourceOptimization {
    compute: {
        rightSizing: boolean;
        autoScaling: {
            enabled: boolean;
            metrics: string[];
            thresholds: {
                cpu: number;
                memory: number;
            };
        };
    };
    storage: {
        tiering: boolean;
        compression: boolean;
        retention: {
            hot: number;  // days
            warm: number;
            cold: number;
        };
    };
}
Enter fullscreen mode Exit fullscreen mode

Cost Monitoring

@Injectable()
class CostMonitor {
    async monitorCosts(): Promise<void> {
        const costs = await this.getCurrentCosts();

        if (this.isOverBudget(costs)) {
            await this.triggerCostAlert(costs);
        }

        await this.recordMetrics(costs);
    }
}
Enter fullscreen mode Exit fullscreen mode

Best Practices and Lessons Learned

  1. Container Management
    • Use minimal base images
    • Implement proper layering
    • Regular security updates
    • Proper tagging strategy
  2. Kubernetes Operations
    • Implement proper monitoring
    • Use namespace isolation
    • Regular cluster maintenance
    • Backup and disaster recovery
  3. CI/CD Pipeline
    • Automated testing
    • Security scanning
    • Deployment validation
    • Rollback procedures
  4. Cost Management
    • Regular resource optimization
    • Cost monitoring
    • Capacity planning
    • Budget alerts

Looking Ahead: Testing Strategies

As we continue to evolve Cipher Horizon, our next post will focus on comprehensive testing strategies


What testing challenges have you encountered in your microservices deployments? Share your experiences in the comments below!

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

👋 Kindness is contagious

If you found this article helpful, a little ❤️ or a friendly comment would be much appreciated!

Got it