Skip to content

Web Application Example

This example demonstrates deploying a production web application with auto-scaling, ingress, and service discovery.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                      Web Application                        │
│                                                             │
│  ┌─────────────┐      ┌─────────────┐                      │
│  │   Ingress   │─────▶│    Web      │                      │
│  │  (Traefik)  │      │  (Nginx)    │                      │
│  └─────────────┘      └─────────────┘                      │
│                              │                              │
│                    ┌─────────┴─────────┐                    │
│                    │                  │                    │
│              ┌─────▼─────┐      ┌─────▼─────┐              │
│              │   API     │      │  Static   │              │
│              │ Service   │      │   Files   │              │
│              └───────────┘      └───────────┘              │
└─────────────────────────────────────────────────────────────┘

Application Definition

apiVersion: core.oam.dev/v1alpha2
kind: Application
metadata:
  name: web-platform
  labels:
    environment: production
    team: platform
spec:
  components:
    - name: frontend
      type: containerizedworkload.nomad.oam.dev
      properties:
        driver: docker
        containers:
          - name: nginx
            image: nginx:1.25-alpine
            ports:
              - name: http
                containerPort: 80
            resources:
              cpu: 500m
              memory: 256Mi
            env:
              NGINX_HOST: localhost
              NGINX_WORKER_PROCESSES: "4"
        volumes:
          - source: static-assets
            destination: /usr/share/nginx/html
            readOnly: true
      traits:
        - type: scaler
          properties:
            replicas: 5
            min: 2
            max: 10
            scaleMetric: cpu
            scaleTarget: 70
        - type: updatestrategy.nomad.oam.dev
          properties:
            strategy: rolling
            maxParallel: 2
            minHealthyTime: 30s
            autoRevert: true
        - type: servicediscovery.nomad.oam.dev
          properties:
            serviceName: frontend
            tags:
              - web
              - production
            port: http
            check:
              type: http
              path: /health
              interval: 10s
              timeout: 3s
        - type: volume
          properties:
            name: static-assets
            type: csi
            source: static-files
            mountPath: /usr/share/nginx/html

    - name: api
      type: webservice
      properties:
        image: myapp/api:v2.1.0
        ports:
          - name: http
            port: 8080
            expose: true
          - name: metrics
            port: 9090
        resources:
          cpu: 2000m
          memory: 1024Mi
        env:
          - name: DATABASE_URL
            valueFrom:
              consulKey:
                key: database/url
          - name: LOG_LEVEL
            value: info
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 15
          periodSeconds: 20
      traits:
        - type: scaler
          properties:
            replicas: 3
            min: 2
            max: 8
            scaleMetric: memory
            scaleTarget: 80
        - type: updatestrategy.nomad.oam.dev
          properties:
            strategy: canary
            canary: 1
            maxParallel: 1
            minHealthyTime: 60s
            autoRevert: true
        - type: ingress
          properties:
            host: api.example.com
            pathPrefix: /v2
            port: 8080
            tls: true
            stripPrefix: true
        - type: servicediscovery.nomad.oam.dev
          properties:
            serviceName: api
            tags:
              - api
              - v2
            port: http
            check:
              type: http
              path: /health
              interval: 10s
              timeout: 3s
        - type: vault-secret
          properties:
            path: secret/data/production/api
            changeMode: restart
            env:
              DB_USER: DB_USER
              DB_PASS: DB_PASS
              API_KEY: API_KEY

    - name: static-files
      type: webservice
      properties:
        image: s3-sync:latest
        args:
          - sync
          - s3://assets.example.com/
          - /var/www
        resources:
          cpu: 250m
          memory: 128Mi

  scopes:
    - scopeRef:
        kind: networkscope.nomad.oam.dev
        name: production-network
      properties:
        networkMode: bridge
        serviceMesh: true
        connectSidecar: true

    - scopeRef:
        kind: nodepool.nomad.oam.dev
        name: production-pool
      properties:
        poolName: production-pool
        datacenter:
          - dc1
          - dc2

    - scopeRef:
        kind: namespace.nomad.oam.dev
        name: production-ns
      properties:
        namespace: web-platform-prod

Deployment

# Apply the application
kubectl apply -f web-app.yaml

# Check status
kubectl get application web-platform

# View components
kubectl get components web-platform

Scaling

The frontend component scales based on CPU usage:

  • Minimum: 2 replicas
  • Maximum: 10 replicas
  • Scale up when CPU > 70%
  • Scale down after 2 minutes cooldown

The API component scales based on memory:

  • Minimum: 2 replicas
  • Maximum: 8 replicas
  • Scale up when memory > 80%