Automating Deployments to Alibaba Cloud SAE with GitHub Actions


In our previous guides, we successfully containerized our Node.js RocketMQ consumer and deployed it to Alibaba Cloud Serverless App Engine (SAE), enabling it to auto-scale based on queue depth.

However, logging into your terminal, manually building a Docker image, tagging it, pushing it to the Container Registry (ACR), and then clicking through the SAE console to update your application is tedious and prone to human error. In a modern DevOps culture, this process should be completely invisible.

By integrating GitHub Actions, you can create a Continuous Integration and Continuous Deployment (CI/CD) pipeline. The moment an engineer merges a pull request into the main branch, GitHub will automatically build the new image and roll it out to SAE without a single second of downtime.

Here is exactly how to set up an automated CI/CD pipeline for your offline-first cloud architecture.


Step 1: Secure Your Credentials with GitHub Secrets


Your CI/CD pipeline needs permission to push images to Alibaba Cloud ACR and update your SAE application. You should never hardcode these credentials in your repository.

Instead, we will use a dedicated RAM (Resource Access Management) User with the principle of least privilege.

  1. Create a RAM User in Alibaba Cloud: Create a user specifically for GitHub Actions. Grant it only two permissions: AliyunContainerRegistryFullAccess and AliyunSAEFullAccess.
  2. Generate Access Keys: Note the AccessKey ID and AccessKey Secret for this RAM user.
  3. Configure GitHub Secrets: Go to your GitHub repository -> Settings -> Secrets and variables -> Actions -> New repository secret. Add the following secrets:
    • ALIYUN_ACCESS_KEY_ID: Your RAM Access Key ID.
    • ALIYUN_ACCESS_KEY_SECRET: Your RAM Access Key Secret.
    • ACR_USERNAME: Your Alibaba Cloud Container Registry login username.
    • ACR_PASSWORD: Your Alibaba Cloud Container Registry password.
    • SAE_APP_ID: The unique ID of your SAE application (found in the SAE console).

Step 2: Creating the GitHub Actions Workflow


GitHub Actions are defined using YAML files stored in a specific directory in your repository.

  1. In the root of your Node.js project, create the following directory structure: .github/workflows/
  2. Create a file named deploy-sae.yml inside that folder.

Paste the following production-ready workflow into deploy-sae.yml:

name: Deploy Consumer to Alibaba Cloud SAE

# 1. Triggers: Run this workflow whenever code is pushed to the main branch
on:
  push:
    branches:
      - main

# Define environment variables used throughout the workflow
env:
  REGION_ID: cn-hangzhou # Change this to your specific Alibaba Cloud region
  ACR_REGISTRY: registry.cn-hangzhou.aliyuncs.com
  ACR_NAMESPACE: healthcare-sync
  IMAGE_NAME: rocketmq-consumer

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      # Step 1: Checkout the code from the repository
      - name: Checkout Code
        uses: actions/checkout@v3

      # Step 2: Set up Docker Buildx for efficient image building
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      # Step 3: Log in to Alibaba Cloud Container Registry (ACR)
      - name: Login to Alibaba Cloud ACR
        uses: aliyun/acr-login@v1
        with:
          login-server: ${{ env.ACR_REGISTRY }}
          username: "${{ secrets.ACR_USERNAME }}"
          password: "${{ secrets.ACR_PASSWORD }}"

      # Step 4: Build the Docker image and push it to ACR
      # We use the GitHub commit SHA as a unique tag for version control
      - name: Build and Push Docker Image
        run: |
          IMAGE_TAG=${{ github.sha }}
          FULL_IMAGE_URL=$ACR_REGISTRY/$ACR_NAMESPACE/$IMAGE_NAME:$IMAGE_TAG
          
          echo "Building image: $FULL_IMAGE_URL"
          docker build -t $FULL_IMAGE_URL .
          
          echo "Pushing image to ACR..."
          docker push $FULL_IMAGE_URL
          
          # Save the image URL to an environment variable for the next step
          echo "IMAGE_URL=$FULL_IMAGE_URL" >> $GITHUB_ENV

      # Step 5: Install and Configure Alibaba Cloud CLI
      - name: Setup Aliyun CLI
        uses: aliyun/setup-aliyun-cli-action@v1
        with:
          region: ${{ env.REGION_ID }}
          access-key-id: ${{ secrets.ALIYUN_ACCESS_KEY_ID }}
          access-key-secret: ${{ secrets.ALIYUN_ACCESS_KEY_SECRET }}

      # Step 6: Deploy the new image to Serverless App Engine (SAE)
      - name: Update SAE Application
        run: |
          echo "Deploying new image to SAE Application ID: ${{ secrets.SAE_APP_ID }}"
          
          aliyun sae DeployApplication \
            --AppId ${{ secrets.SAE_APP_ID }} \
            --ImageUrl ${{ env.IMAGE_URL }} \
            --MinReadyInstances 1 \
            --UpdateStrategy '{"type":"RollingUpdate","batchUpdate":{"batch":2,"releaseType":"auto"}}'
          
          echo "Deployment triggered successfully! SAE is now performing a rolling update."

Step 3: Understanding the Pipeline Architecture


Let’s break down why this specific pipeline configuration is robust and production-ready:


1. Immutable Tagging (${{ github.sha }})


Notice that we are not tagging the Docker image as latest. Using latest is a dangerous anti-pattern because it makes rolling back to previous versions incredibly difficult. Instead, we tag the image using ${{ github.sha }}, which is the unique, 40-character Git commit hash.

  • Benefit: If a bug makes it to production, you can look at the running image tag in the SAE console, instantly match it to the exact code commit in GitHub, and easily revert if necessary.

2. The aliyun/acr-login Action


Instead of writing complex bash scripts to handle Docker authentication, we use the officially maintained Alibaba Cloud GitHub Action for ACR. This securely handles the token exchange and ensures your credentials are never exposed in the build logs.


3. Zero-Downtime Rolling Updates (UpdateStrategy)


When the Alibaba Cloud CLI triggers the DeployApplication command, we pass a specific JSON configuration: '{"type":"RollingUpdate","batchUpdate":{"batch":2,"releaseType":"auto"}}'.

  • Benefit: SAE will not shut down all your running consumers at once. It will spin up the new version of your code in batches, verify that the new containers are healthy and successfully connecting to RocketMQ, and only then terminate the old containers. This ensures your data synchronization is never interrupted during a deployment.

Conclusion


By implementing this GitHub Actions workflow, you have bridged the gap between your code repository and your Alibaba Cloud infrastructure.

Now, your engineering team can focus entirely on writing business logic and conflict-resolution algorithms. The moment they merge a pull request, GitHub securely builds the image, archives it in ACR, and orchestrates a zero-downtime rolling deployment across your auto-scaling SAE cluster.

Your architecture is now highly available, offline-resilient, deeply observable, and fully automated.

Leave a Comment