Skip to content
Back to skills

Deployment Automation

ASecurity

Automate application deployment to cloud platforms and servers. Use when setting up CI/CD pipelines, deploying to Docker/Kubernetes, or configuring cloud infrastructure. Handles GitHub Actions, Docker, Kubernetes, AWS, Vercel, and deployment best practices.

  • 416 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added June 2, 2026
ai-agentsjavascripttypescriptjavabashnextjsnodenodejsdockerkubernetesaws

Works with

  • cli
  • api

Security analysis

A92/100
  • mediumUses curl or wget to download content
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 3 files and shows the line behind each finding

Scanned June 2, 2026

npx -y skills add aiskillstore/marketplace --skill deployment-automation --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Deployment Automation?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Deployment Automation
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aiskillstore-deployment-automation/badge)](https://www.skillsdirectory.com/skills/aiskillstore-deployment-automation)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: deployment-automation
description: Automate application deployment to cloud platforms and servers. Use when setting up CI/CD pipelines, deploying to Docker/Kubernetes, or configuring cloud infrastructure. Handles GitHub Actions, Docker, Kubernetes, AWS, Vercel, and deployment best practices.
metadata:
  tags: deployment, CI/CD, Docker, Kubernetes, AWS, GitHub-Actions, automation
  platforms: Claude, ChatGPT, Gemini
---


# Deployment Automation


## When to use this skill

- **New Projects**: Set up automated deployment from scratch
- **Manual Deployment Improvement**: Automate repetitive manual tasks
- **Multi-Environment**: Separate dev, staging, and production environments
- **Scaling**: Introduce Kubernetes to handle traffic growth

## Instructions

### Step 1: Docker Containerization

Package the application as a Docker image.

**Dockerfile** (Node.js app):
```dockerfile
# Multi-stage build for smaller image size
FROM node:18-alpine AS builder

WORKDIR /app

# Copy package files and install dependencies
COPY package*.json ./
RUN npm ci --only=production

# Copy source code
COPY . .

# Build application (if needed)
RUN npm run build

# Production stage
FROM node:18-alpine

WORKDIR /app

# Copy only necessary files from builder
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./

# Create non-root user for security
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001
USER nodejs

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node healthcheck.js

# Start application
CMD ["node", "dist/index.js"]
```

**.dockerignore**:
```
node_modules
npm-debug.log
.git
.env
.env.local
dist
build
coverage
.DS_Store
```

**Build and Run**:
```bash
# Build image
docker build -t myapp:latest .

# Run container
docker run -d -p 3000:3000 --name myapp-container myapp:latest

# Check logs
docker logs myapp-container

# Stop and remove
docker stop myapp-container
docker rm myapp-container
```

### Step 2: GitHub Actions CI/CD

Automatically runs tests and deploys on code push.

**.github/workflows/deploy.yml**:
```yaml
name: CI/CD Pipeline

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

env:
  NODE_VERSION: '18'
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run linter
        run: npm run lint

      - name: Run tests
        run: npm test -- --coverage

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage/coverage-final.json

  build:
    needs: test
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'

    steps:
      - uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - 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=sha,prefix={{branch}}-
            type=semver,pattern={{version}}
            latest

      - 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 }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: production

    steps:
      - name: Deploy to production
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.PROD_HOST }}
          username: ${{ secrets.PROD_USER }}
          key: ${{ secrets.PROD_SSH_KEY }}
          script: |
            cd /app
            docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
            docker-compose up -d --no-deps --build web
            docker image prune -f
```

### Step 3: Kubernetes Deployment

Implement scalable container orchestration.

**k8s/deployment.yaml**:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  namespace: production
  labels:
    app: myapp
spec:
  replicas: 3
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: ghcr.io/username/myapp:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: myapp-secrets
              key: database-url
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
  namespace: production
spec:
  selector:
    app: myapp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000
  type: LoadBalancer

---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: myapp-hpa
  namespace: production
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: myapp
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 80
```

**Deployment Script** (deploy.sh):
```bash
#!/bin/bash
set -e

# Variables
NAMESPACE="production"
IMAGE_TAG="${1:-latest}"

echo "Deploying myapp:${IMAGE_TAG} to ${NAMESPACE}..."

# Apply Kubernetes manifests
kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/secrets.yaml
kubectl apply -f k8s/deployment.yaml
kubectl apply -f k8s/service.yaml

# Update image
kubectl set image deployment/myapp myapp=ghcr.io/username/myapp:${IMAGE_TAG} -n ${NAMESPACE}

# Wait for rollout
kubectl rollout status deployment/myapp -n ${NAMESPACE} --timeout=5m

# Verify
kubectl get pods -n ${NAMESPACE} -l app=myapp

echo "Deployment completed successfully!"
```

### Step 4: Vercel/Netlify (Frontend)

Simply deploy static sites and Next.js apps.

**vercel.json**:
```json
{
  "version": 2,
  "builds": [
    {
      "src": "package.json",
      "use": "@vercel/next"
    }
  ],
  "env": {
    "DATABASE_URL": "@database-url",
    "API_KEY": "@api-key"
  },
  "regions": ["sin1", "icn1"],
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        }
      ]
    }
  ],
  "redirects": [
    {
      "source": "/old-path",
      "destination": "/new-path",
      "permanent": true
    }
  ]
}
```

**CLI Deployment**:
```bash
# Install Vercel CLI
npm i -g vercel

# Login
vercel login

# Deploy to preview
vercel

# Deploy to production
vercel --prod

# Set environment variable
vercel env add DATABASE_URL
```

### Step 5: Zero-Downtime Deployment Strategy

Deploy new versions without service interruption.

**Blue-Green Deployment** (docker-compose):
```yaml
version: '3.8'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - app-blue
      - app-green

  app-blue:
    image: myapp:blue
    environment:
      - NODE_ENV=production
      - COLOR=blue

  app-green:
    image: myapp:green
    environment:
      - NODE_ENV=production
      - COLOR=green
```

**switch.sh** (Blue/Green Switch):
```bash
#!/bin/bash

CURRENT_COLOR=$(cat current_color.txt)
NEW_COLOR=$([[ "$CURRENT_COLOR" == "blue" ]] && echo "green" || echo "blue")

# Deploy new version to inactive environment
docker-compose up -d app-${NEW_COLOR}

# Wait for health check
sleep 10

# Health check
if curl -f http://localhost:8080/health; then
  # Update nginx to point to new environment
  sed -i "s/${CURRENT_COLOR}/${NEW_COLOR}/g" nginx.conf
  docker-compose exec nginx nginx -s reload

  # Update current color
  echo ${NEW_COLOR} > current_color.txt

  # Stop old environment after 5 minutes (rollback window)
  sleep 300
  docker-compose stop app-${CURRENT_COLOR}

  echo "Deployment successful! Switched to ${NEW_COLOR}"
else
  echo "Health check failed! Keeping ${CURRENT_COLOR}"
  docker-compose stop app-${NEW_COLOR}
  exit 1
fi
```

## Output format

### Deployment Checklist

```markdown
## Deployment Checklist

### Pre-Deployment
- [ ] All tests passing (unit, integration, E2E)
- [ ] Code review approved
- [ ] Environment variables configured
- [ ] Database migrations ready
- [ ] Rollback plan documented

### Deployment
- [ ] Docker image built and tagged
- [ ] Image pushed to container registry
- [ ] Kubernetes manifests applied
- [ ] Rolling update started
- [ ] Pods healthy and ready

### Post-Deployment
- [ ] Health check endpoint responding
- [ ] Metrics/logs monitoring active
- [ ] Performance baseline established
- [ ] Old pods terminated (after grace period)
- [ ] Deployment documented in changelog
```

## Constraints

### Required Rules (MUST)

1. **Health Checks**: Health check endpoint for all services
   ```typescript
   app.get('/health', (req, res) => {
     res.status(200).json({ status: 'ok' });
   });
   ```

2. **Graceful Shutdown**: Handle SIGTERM signal
   ```javascript
   process.on('SIGTERM', async () => {
     console.log('SIGTERM received, shutting down gracefully');
     await server.close();
     await db.close();
     process.exit(0);
   });
   ```

3. **Environment Variable Separation**: No hardcoding; use .env files

### Prohibited Rules (MUST NOT)

1. **No Committing Secrets**: Never commit API keys or passwords to Git
2. **No Debug Mode in Production**: `NODE_ENV=production` is required
3. **Avoid latest tag only**: Use version tags (v1.0.0, sha-abc123)

## Best practices

1. **Multi-stage Docker builds**: Minimize image size
2. **Immutable infrastructure**: Redeploy instead of modifying servers
3. **Blue-Green deployment**: Zero-downtime deployment and easy rollback
4. **Monitoring required**: Prometheus, Grafana, Datadog

## References

- [Docker Docs](https://docs.docker.com/)
- [Kubernetes Docs](https://kubernetes.io/docs/)
- [GitHub Actions](https://docs.github.com/en/actions)
- [Vercel](https://vercel.com/docs)
- [12 Factor App](https://12factor.net/)

## Metadata

### Version
- **Current Version**: 1.0.0
- **Last Updated**: 2025-01-01
- **Compatible Platforms**: Claude, ChatGPT, Gemini

### Related Skills
- [monitoring](../monitoring/SKILL.md): Post-deployment monitoring
- [security](../security/SKILL.md): Deployment security

### Tags
`#deployment` `#CI/CD` `#Docker` `#Kubernetes` `#automation` `#infrastructure`

## Examples

### Example 1: Basic usage
<!-- Add example content here -->

### Example 2: Advanced usage
<!-- Add advanced example content here -->

Files in this skill

  • SKILL.md11.7 KB
  • SKILL.toon653 B
  • skill-report.json9.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.