Alibaba Cloud DevOps Toolchain: CI/CD with China-Optimized Infra
Alibaba Cloud DevOps Toolchain: CI/CD with China-Optimized Infra
Building CI/CD for workloads in China requires more than just picking a cloud provider. GitHub Actions works, but you'll hit network latency issues when pulling dependencies and pushing images across the firewall. The Alibaba Cloud native toolchain — Codeup (Git), Flow (pipelines), ACR (container registry) — is built for this reality. Dependencies stay within the Alibaba network, builds are fast, and compliance requirements are easier to satisfy.
This guide covers setting up a production CI/CD pipeline using Alibaba Cloud's native tools, with fallback patterns for teams that want to keep GitHub as their source of truth.
The Alibaba Cloud DevOps Stack
| Tool | Purpose | Equivalent |
|---|---|---|
| Codeup | Git hosting | GitHub/GitLab |
| Flow | CI/CD pipelines | GitHub Actions/Jenkins |
| ACR (Container Registry) | Docker/OCI images | ECR/GCR |
| ACK | Kubernetes | EKS/GKE |
| OSS | Object storage for artifacts | S3/GCS |
| RDS/PolarDB | Managed databases | RDS/CloudSQL |
| SLS (Log Service) | Log aggregation | CloudWatch/Stackdriver |
You don't have to use all of these — many teams use GitHub + GitHub Actions but route through Alibaba's network by hosting their own build agents in China and pushing only to ACR/ACK.
Option 1: Fully Native Pipeline with Codeup + Flow
Set Up ACR Repository
# Create ACR Enterprise instance (required for private repos)
# This is done via the console or Terraform
# Create namespace and repository
aliyun cr CreateNamespace \
--InstanceId cri-xxxxxxxxxx \
--Namespace your-project
aliyun cr CreateRepository \
--InstanceId cri-xxxxxxxxxx \
--RepoNamespaceName your-project \
--RepoName api-service \
--RepoType PRIVATE \
--Summary "API Service Docker Image"
# Your push endpoint:
# registry-vpc.cn-hangzhou.aliyuncs.com/your-project/api-service
Flow Pipeline Configuration
In the Alibaba Cloud DevOps console, Flow pipelines are defined as YAML (similar to GitHub Actions):
# .yunxiao/pipeline.yml — Alibaba Cloud Flow pipeline
name: api-service-pipeline
triggers:
push:
branches:
- main
- release/**
variables:
REGION: cn-hangzhou
ACR_INSTANCE: cri-xxxxxxxxxx
REGISTRY: registry-vpc.cn-hangzhou.aliyuncs.com
NAMESPACE: your-project
SERVICE: api-service
ACK_CLUSTER: c-xxxxxxxxxxxxxxxxx
stages:
- name: build-and-test
jobs:
- name: test
steps:
- name: Install dependencies
run: npm ci
image: node:20-alpine
- name: Run unit tests
run: npm test -- --coverage
image: node:20-alpine
- name: Lint
run: npm run lint
image: node:20-alpine
- name: build-image
dependsOn: [test]
steps:
- name: Docker build
plugin: docker-build
inputs:
context: .
dockerfile: Dockerfile
image: "${REGISTRY}/${NAMESPACE}/${SERVICE}"
tags:
- "${CI_PIPELINE_ID}"
- latest
- name: Push to ACR
plugin: docker-push
inputs:
image: "${REGISTRY}/${NAMESPACE}/${SERVICE}"
tags:
- "${CI_PIPELINE_ID}"
- latest
credentials: acr-service-credential
- name: deploy-staging
dependsOn: [build-and-test]
condition:
branch: main
jobs:
- name: deploy
steps:
- name: Deploy to ACK staging
plugin: kubectl
inputs:
cluster: "${ACK_CLUSTER}"
command: |
kubectl set image deployment/${SERVICE} \
${SERVICE}=${REGISTRY}/${NAMESPACE}/${SERVICE}:${CI_PIPELINE_ID} \
-n staging
- name: Verify rollout
plugin: kubectl
inputs:
cluster: "${ACK_CLUSTER}"
command: |
kubectl rollout status deployment/${SERVICE} \
-n staging \
--timeout=300s
- name: deploy-production
dependsOn: [deploy-staging]
approval:
required: true
approvers:
- group: platform-team
jobs:
- name: deploy
steps:
- name: Deploy to ACK production
plugin: kubectl
inputs:
cluster: "${ACK_CLUSTER}"
command: |
kubectl set image deployment/${SERVICE} \
${SERVICE}=${REGISTRY}/${NAMESPACE}/${SERVICE}:${CI_PIPELINE_ID} \
-n production
Option 2: GitHub + Self-Hosted Runners in China
If you want to keep GitHub as your source of truth but avoid cross-border latency on builds:
# .github/workflows/build-deploy.yml
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
# Run on a self-hosted runner in cn-hangzhou (ECS instance in your VPC)
runs-on: [self-hosted, linux, cn-hangzhou]
steps:
- uses: actions/checkout@v4
- name: Login to Alibaba ACR
run: |
docker login \
registry-vpc.cn-hangzhou.aliyuncs.com \
--username="${{ secrets.ACR_USERNAME }}" \
--password="${{ secrets.ACR_PASSWORD }}"
- name: Build and push
run: |
IMAGE="registry-vpc.cn-hangzhou.aliyuncs.com/your-project/api:${{ github.sha }}"
docker build -t $IMAGE .
docker push $IMAGE
- name: Deploy to ACK
env:
KUBECONFIG: ${{ secrets.ACK_KUBECONFIG }}
run: |
kubectl set image deployment/api-service \
api-service="registry-vpc.cn-hangzhou.aliyuncs.com/your-project/api:${{ github.sha }}" \
-n production
kubectl rollout status deployment/api-service -n production --timeout=300s
Setting up the self-hosted runner:
# On your ECS instance in cn-hangzhou
# Download and configure GitHub Actions runner
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64-2.313.0.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.313.0/actions-runner-linux-x64-2.313.0.tar.gz
tar xzf ./actions-runner-linux-x64-2.313.0.tar.gz
# Configure runner (get token from GitHub repo settings)
./config.sh \
--url https://github.com/YourOrg/your-repo \
--token YOUR_REGISTRATION_TOKEN \
--labels "cn-hangzhou,linux" \
--name "cn-hangzhou-runner-01"
# Install as systemd service
sudo ./svc.sh install
sudo ./svc.sh start
ACR Image Mirroring for Faster Pulls
Configure ACR to mirror images from Docker Hub so your Kubernetes nodes don't make international requests:
# Create a mirror rule in ACR Enterprise
aliyun cr CreateRepoSyncRule \
--InstanceId cri-xxxxxxxxxx \
--LocalRepoName nginx \
--LocalRepoNamespaceName mirrors \
--SyncRuleName mirror-nginx \
--SyncScope REPO \
--TargetInstanceId cri-xxxxxxxxxx \
--TargetNamespaceName mirrors \
--TargetRepoName nginx \
--SyncTrigger PASSIVE
# Configure containerd on ACK nodes to use ACR as mirror
# In ACK console: Cluster > Node Pools > Node Pool Config > Container Registry Mirrors
# Add: https://registry-vpc.cn-hangzhou.aliyuncs.com
On your deployments, reference images from your ACR mirror:
# Instead of:
image: nginx:1.25
# Use:
image: registry-vpc.cn-hangzhou.aliyuncs.com/mirrors/nginx:1.25
Artifacts to OSS for Non-Container Deliverables
For build artifacts that aren't Docker images (npm packages, binaries, static assets):
# In your pipeline:
# Build static assets
npm run build
# Upload to OSS
ossutil cp -r dist/ oss://your-bucket/releases/${CI_PIPELINE_ID}/ \
--endpoint oss-cn-hangzhou-internal.aliyuncs.com \
--access-key-id $OSS_ACCESS_KEY \
--access-key-secret $OSS_ACCESS_SECRET
# CDN invalidation after upload
aliyun cdn RefreshObjectCaches \
--ObjectPath "https://assets.yourcompany.com/releases/${CI_PIPELINE_ID}/" \
--ObjectType Directory
Using the internal OSS endpoint (oss-cn-hangzhou-internal.aliyuncs.com) from within the same region is free — external OSS traffic costs money.
Log Aggregation with SLS
Configure your ACK deployments to ship logs to SLS (Log Service) instead of just stdout:
# fluentd-config.yaml — Send container logs to SLS
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
namespace: kube-system
data:
fluent.conf: |
<source>
@type tail
path /var/log/containers/*.log
pos_file /var/log/fluentd-containers.log.pos
tag kubernetes.*
read_from_head true
<parse>
@type json
time_format %Y-%m-%dT%H:%M:%S.%NZ
</parse>
</source>
<match kubernetes.**>
@type aliyun_sls
project your-sls-project
logstore k8s-container-logs
endpoint cn-hangzhou-intranet.log.aliyuncs.com
access_key_id "#{ENV['SLS_ACCESS_KEY_ID']}"
access_key_secret "#{ENV['SLS_ACCESS_KEY_SECRET']}"
<buffer tag>
@type memory
flush_interval 5s
chunk_limit_size 2m
</buffer>
</match>
Using the intranet SLS endpoint avoids public internet bandwidth charges.
CI/CD Pipeline Comparison
| Feature | Flow (Native) | GitHub Actions + Self-hosted |
|---|---|---|
| Source of truth | Codeup (Alibaba Git) | GitHub |
| Network for builds | Alibaba internal | Alibaba internal (runner) |
| Code review workflow | Codeup MR | GitHub PR |
| Compliance (data residency) | Full China residency | Git metadata leaves China |
| Familiarity for global team | Learning curve | Familiar |
| Integration with Alibaba services | Native, deep | Via CLI/API |
| Cost | Included in Cloud subscription | GitHub Actions minutes + runner ECS |
For teams whose primary developers are outside China, Option 2 (GitHub + self-hosted runners) is usually the better tradeoff. For teams operating primarily within China or with strict data residency requirements, the native Codeup + Flow stack keeps all code and pipeline data within Alibaba's infrastructure.
Was this article helpful?
Platform Engineer
Terraform enthusiast, platform builder, DRY advocate. I believe infrastructure should be versioned, reviewed, and deployed like any other code. GitOps or bust.
Related Articles
Alibaba Cloud ACK: Managed Kubernetes in Asia's Largest Cloud
Set up and manage a production Kubernetes cluster on Alibaba Cloud ACK (Container Service for Kubernetes). Covers cluster types, node pools, SLB ingress, RRSA workload identity, Container Registry, and Terraform configuration.
Alibaba Cloud ECS: Deploy and Manage Virtual Machines at Scale
Deploy and manage Alibaba Cloud ECS instances — instance families, storage types, security groups, auto-scaling groups, SLB load balancers, image management, and Terraform configuration for production workloads.
Alibaba Cloud for DevOps: ECS, ACK, and the China Cloud Ecosystem
Explore Alibaba Cloud's DevOps ecosystem — ECS compute, ACK Kubernetes, OSS storage, and why it matters for teams operating in China and Asia-Pacific.
Ansible for Infrastructure Automation: Dynamic Inventory, Vault, and CI/CD Integration
Advanced Ansible patterns for production infrastructure — dynamic inventory from AWS/GCP, encrypting secrets with Ansible Vault, integrating with CI/CD pipelines, and structuring large projects with collections.
Alibaba Cloud ACK: Managed Kubernetes for Asia-Pacific Workloads
Deploy and operate production workloads on Alibaba Cloud Container Service for Kubernetes with autoscaling, SLB ingress, and ARMS monitoring.
AWS ECS Fargate: Serverless Container Deployment Without Managing Nodes
Deploy containers on AWS ECS Fargate — no EC2 instances to manage. Covers task definitions, services, load balancers, environment variables, secrets from SSM/Secrets Manager, auto-scaling, and CI/CD integration.