Deployment

GitHub Actions CI/CD

Automate deployments with GitHub Actions and SkyPort

GitHub Actions CI/CD

Automate your deployments to SkyPort using GitHub Actions.

Prerequisites

  • SkyPort instance with API access
  • GitHub repository
  • API token from SkyPort

Generate API Token

In SkyPort dashboard:

  1. Go to Settings → API Tokens
  2. Click "Generate Token"
  3. Copy the token (starts with sk_)
  4. Add to GitHub repository as secret SKYPORT_TOKEN

Basic Workflow

Create .github/workflows/deploy.yml:

name: Deploy to SkyPort

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      
      - name: Build Docker image
        run: |
          docker build -t my-app:${{ github.sha }} .
          docker tag my-app:${{ github.sha }} my-app:latest
      
      - name: Deploy to SkyPort
        env:
          SKYPORT_TOKEN: ${{ secrets.SKYPORT_TOKEN }}
          SKYPORT_SERVER: https://skyport.example.com
        run: |
          skyport docker run -d \
            --name my-app \
            -p 3000:3000 \
            my-app:${{ github.sha }}

Docker Build and Push

name: Build and Deploy

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2
      
      - name: Build and push to registry
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: |
            registry.example.com/my-app:${{ github.sha }}
            registry.example.com/my-app:latest
          registry: registry.example.com
          username: ${{ secrets.REGISTRY_USERNAME }}
          password: ${{ secrets.REGISTRY_PASSWORD }}
      
      - name: Deploy with SkyPort
        env:
          SKYPORT_TOKEN: ${{ secrets.SKYPORT_TOKEN }}
          SKYPORT_SERVER: https://skyport.example.com
        run: |
          # Stop old container
          skyport docker stop my-app || true
          skyport docker rm my-app || true
          
          # Run new container
          skyport docker run -d \
            --name my-app \
            -p 3000:3000 \
            registry.example.com/my-app:${{ github.sha }}

Multi-Environment Deployment

name: Deploy to Multiple Environments

on:
  push:
    branches:
      - main
      - staging

jobs:
  deploy:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        environment:
          - name: staging
            server: https://skyport-staging.example.com
            token: SKYPORT_STAGING_TOKEN
          - name: production
            server: https://skyport.example.com
            token: SKYPORT_PROD_TOKEN
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      
      - name: Build Docker image
        run: docker build -t my-app:${{ github.sha }} .
      
      - name: Deploy to ${{ matrix.environment.name }}
        env:
          SKYPORT_TOKEN: ${{ secrets[matrix.environment.token] }}
          SKYPORT_SERVER: ${{ matrix.environment.server }}
        run: |
          skyport docker stop my-app-${{ matrix.environment.name }} || true
          skyport docker rm my-app-${{ matrix.environment.name }} || true
          
          skyport docker run -d \
            --name my-app-${{ matrix.environment.name }} \
            -p 3000:3000 \
            my-app:${{ github.sha }}

Conditional Deployment

name: Deploy on Release

on:
  release:
    types: [published]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
        with:
          ref: ${{ github.ref }}
      
      - name: Build and deploy
        env:
          SKYPORT_TOKEN: ${{ secrets.SKYPORT_TOKEN }}
          SKYPORT_SERVER: https://skyport.example.com
        run: |
          VERSION=${{ github.event.release.tag_name }}
          docker build -t my-app:$VERSION .
          
          skyport docker run -d \
            --name my-app-$VERSION \
            -p 3000:3000 \
            my-app:$VERSION

PM2 Deployment

name: Deploy Node.js App

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      
      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Deploy to SkyPort
        env:
          SKYPORT_TOKEN: ${{ secrets.SKYPORT_TOKEN }}
          SKYPORT_SERVER: https://skyport.example.com
        run: |
          skyport pm2 stop app || true
          skyport pm2 delete app || true
          
          skyport pm2 start ecosystem.config.js --env production

Secrets Management

Set up secrets in GitHub:

  1. Go to repository Settings → Secrets and variables → Actions
  2. Click "New repository secret"
  3. Add secrets:
    • SKYPORT_TOKEN
    • SKYPORT_SERVER
    • REGISTRY_USERNAME (if using registry)
    • REGISTRY_PASSWORD (if using registry)

Notifications

Add Slack notifications:

- name: Notify Slack on success
  if: success()
  uses: 8398a7/action-slack@v3
  with:
    status: ${{ job.status }}
    text: 'Deployment to ${{ matrix.environment.name }} succeeded'
    webhook_url: ${{ secrets.SLACK_WEBHOOK }}

- name: Notify Slack on failure
  if: failure()
  uses: 8398a7/action-slack@v3
  with:
    status: ${{ job.status }}
    text: 'Deployment to ${{ matrix.environment.name }} failed'
    webhook_url: ${{ secrets.SLACK_WEBHOOK }}

Best Practices

  • Use branch protection rules
  • Require PR reviews before deployment
  • Use environment secrets for production
  • Implement health checks after deploy
  • Set up rollback on failure
  • Log all deployments
  • Use semantic versioning

Next: Production Setup | Scaling

SkyPort

SkyPort Docs

Self-hosted infrastructure platform