初始化
Build docker and publish / prepare (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.admin image_name:ppanel-admin name:admin]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.api image_name:ppanel-api name:api]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.node image_name:ppanel-node name:node]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.queue image_name:ppanel-queue name:queue]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.scheduler image_name:ppanel-scheduler name:scheduler]) (push) Has been cancelled
Build docker and publish / deploy (push) Has been cancelled
Build docker and publish / notify (push) Has been cancelled
Build docker and publish / prepare (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.admin image_name:ppanel-admin name:admin]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.api image_name:ppanel-api name:api]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.node image_name:ppanel-node name:node]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.queue image_name:ppanel-queue name:queue]) (push) Has been cancelled
Build docker and publish / build (map[dockerfile:deploy/Dockerfile.scheduler image_name:ppanel-scheduler name:scheduler]) (push) Has been cancelled
Build docker and publish / deploy (push) Has been cancelled
Build docker and publish / notify (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
name: Build docker and publish
|
||||
run-name: zero-ppanel Docker构建和部署
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- dev
|
||||
|
||||
env:
|
||||
REPO: ${{ vars.REPO || 'registry.kxsw.us/vpn-server' }}
|
||||
SSH_HOST: ${{ github.ref_name == 'main' && vars.SSH_HOST || vars.DEV_SSH_HOST }}
|
||||
SSH_PORT: ${{ vars.SSH_PORT }}
|
||||
SSH_USER: ${{ vars.SSH_USER }}
|
||||
SSH_PASSWORD: ${{ github.ref_name == 'main' && vars.SSH_PASSWORD || vars.DEV_SSH_PASSWORD }}
|
||||
TG_BOT_TOKEN: ${{ secrets.TG_BOT_TOKEN }}
|
||||
TG_CHAT_ID: ${{ secrets.TG_CHAT_ID }}
|
||||
VERSION: ${{ github.sha }}
|
||||
BUILDTIME: ${{ github.event.head_commit.timestamp }}
|
||||
|
||||
jobs:
|
||||
# ============================================================
|
||||
# Job 1: 设置环境变量,供后续 jobs 共享
|
||||
# ============================================================
|
||||
prepare:
|
||||
runs-on: ario-server
|
||||
outputs:
|
||||
docker_tag: ${{ steps.vars.outputs.docker_tag }}
|
||||
container_suffix: ${{ steps.vars.outputs.container_suffix }}
|
||||
deploy_path: ${{ steps.vars.outputs.deploy_path }}
|
||||
steps:
|
||||
- name: ⚙️ 计算部署变量
|
||||
id: vars
|
||||
run: |
|
||||
case "${{ github.ref_name }}" in
|
||||
main)
|
||||
echo "docker_tag=latest" >> $GITHUB_OUTPUT
|
||||
echo "container_suffix=" >> $GITHUB_OUTPUT
|
||||
echo "deploy_path=/root/bindbox" >> $GITHUB_OUTPUT
|
||||
;;
|
||||
dev)
|
||||
echo "docker_tag=dev" >> $GITHUB_OUTPUT
|
||||
echo "container_suffix=-dev" >> $GITHUB_OUTPUT
|
||||
echo "deploy_path=/root/bindbox-dev" >> $GITHUB_OUTPUT
|
||||
;;
|
||||
*)
|
||||
echo "docker_tag=${{ github.ref_name }}" >> $GITHUB_OUTPUT
|
||||
echo "container_suffix=-${{ github.ref_name }}" >> $GITHUB_OUTPUT
|
||||
echo "deploy_path=/root/vpn_server_other" >> $GITHUB_OUTPUT
|
||||
;;
|
||||
esac
|
||||
|
||||
# ============================================================
|
||||
# Job 2: 并行矩阵构建 5 个服务镜像
|
||||
# ============================================================
|
||||
build:
|
||||
runs-on: ario-server
|
||||
needs: prepare
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
service:
|
||||
- name: api
|
||||
dockerfile: deploy/Dockerfile.api
|
||||
image_name: ppanel-api
|
||||
- name: admin
|
||||
dockerfile: deploy/Dockerfile.admin
|
||||
image_name: ppanel-admin
|
||||
- name: node
|
||||
dockerfile: deploy/Dockerfile.node
|
||||
image_name: ppanel-node
|
||||
- name: queue
|
||||
dockerfile: deploy/Dockerfile.queue
|
||||
image_name: ppanel-queue
|
||||
- name: scheduler
|
||||
dockerfile: deploy/Dockerfile.scheduler
|
||||
image_name: ppanel-scheduler
|
||||
|
||||
steps:
|
||||
- name: 📥 下载代码
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🔧 安装 Docker CLI
|
||||
run: |
|
||||
set -e
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# 等待 apt 锁释放
|
||||
for i in $(seq 1 60); do
|
||||
if ! fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; then break; fi
|
||||
echo "等待 apt 锁... ($i/60)"; sleep 5
|
||||
done
|
||||
|
||||
apt-get update -y -o Dpkg::Lock::Timeout=300
|
||||
apt-get install -y -o Dpkg::Lock::Timeout=300 ca-certificates curl gnupg
|
||||
|
||||
# 安装 Docker 官方 CLI (API >= 1.44)
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/debian/gpg \
|
||||
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] \
|
||||
https://download.docker.com/linux/debian \
|
||||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
|
||||
> /etc/apt/sources.list.d/docker.list
|
||||
apt-get update -y -o Dpkg::Lock::Timeout=300
|
||||
apt-get install -y -o Dpkg::Lock::Timeout=300 docker-ce-cli docker-buildx-plugin
|
||||
|
||||
echo "Docker CLI 版本: $(docker --version)"
|
||||
echo "API 版本: $(docker version --format '{{.Client.APIVersion}}')"
|
||||
|
||||
- name: 📤 构建并推送 ${{ matrix.service.name }}
|
||||
run: |
|
||||
DOCKER_TAG="${{ needs.prepare.outputs.docker_tag }}"
|
||||
IMAGE_BASE="${{ env.REPO }}/${{ matrix.service.image_name }}"
|
||||
|
||||
echo "构建服务: ${{ matrix.service.name }}"
|
||||
echo "镜像: ${IMAGE_BASE}"
|
||||
echo "标签: ${DOCKER_TAG} | ${{ env.VERSION }}"
|
||||
|
||||
docker build \
|
||||
-f ${{ matrix.service.dockerfile }} \
|
||||
--platform linux/amd64 \
|
||||
--build-arg VERSION=${{ env.VERSION }} \
|
||||
--build-arg BUILDTIME=${{ env.BUILDTIME }} \
|
||||
-t ${IMAGE_BASE}:${{ env.VERSION }} \
|
||||
-t ${IMAGE_BASE}:${DOCKER_TAG} \
|
||||
.
|
||||
|
||||
docker push ${IMAGE_BASE}:${{ env.VERSION }}
|
||||
docker push ${IMAGE_BASE}:${DOCKER_TAG}
|
||||
|
||||
echo "✅ ${{ matrix.service.name }} 镜像推送完成"
|
||||
|
||||
# ============================================================
|
||||
# Job 3: 部署到服务器
|
||||
# ============================================================
|
||||
deploy:
|
||||
runs-on: ario-server
|
||||
needs: [prepare, build]
|
||||
# PR 不触发部署,只有直接推送才部署
|
||||
if: github.event_name == 'push'
|
||||
|
||||
steps:
|
||||
- name: 📥 下载代码 (获取 docker-compose.cloud.yml)
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 📂 传输 docker-compose.cloud.yml
|
||||
uses: appleboy/scp-action@v0.1.7
|
||||
with:
|
||||
host: ${{ env.SSH_HOST }}
|
||||
username: ${{ env.SSH_USER }}
|
||||
password: ${{ env.SSH_PASSWORD }}
|
||||
port: ${{ env.SSH_PORT }}
|
||||
source: "deploy/docker-compose.cloud.yml"
|
||||
target: "${{ needs.prepare.outputs.deploy_path }}/"
|
||||
strip_components: 1
|
||||
|
||||
- name: 🚀 部署服务
|
||||
uses: appleboy/ssh-action@v1.0.3
|
||||
with:
|
||||
host: ${{ env.SSH_HOST }}
|
||||
username: ${{ env.SSH_USER }}
|
||||
password: ${{ env.SSH_PASSWORD }}
|
||||
port: ${{ env.SSH_PORT }}
|
||||
timeout: 300s
|
||||
command_timeout: 600s
|
||||
script: |
|
||||
set -e
|
||||
DEPLOY_PATH="${{ needs.prepare.outputs.deploy_path }}"
|
||||
DOCKER_TAG="${{ needs.prepare.outputs.docker_tag }}"
|
||||
REPO="${{ env.REPO }}"
|
||||
|
||||
echo "部署目录: ${DEPLOY_PATH}"
|
||||
echo "镜像标签: ${DOCKER_TAG}"
|
||||
|
||||
cd ${DEPLOY_PATH}
|
||||
|
||||
# 写入环境变量供 docker-compose 使用
|
||||
cat > .env <<EOF
|
||||
PPANEL_TAG=${DOCKER_TAG}
|
||||
PPANEL_REPO=${REPO}
|
||||
EOF
|
||||
|
||||
# 拉取所有服务的最新镜像
|
||||
docker-compose -f docker-compose.cloud.yml pull
|
||||
|
||||
# 滚动更新所有 ppanel 服务
|
||||
docker-compose -f docker-compose.cloud.yml up -d \
|
||||
ppanel-api ppanel-admin ppanel-node ppanel-queue ppanel-scheduler
|
||||
|
||||
# 清理旧镜像
|
||||
docker image prune -f || true
|
||||
|
||||
echo "✅ 部署完成,当前运行容器:"
|
||||
docker-compose -f docker-compose.cloud.yml ps
|
||||
|
||||
# ============================================================
|
||||
# Job 4: 通知
|
||||
# ============================================================
|
||||
notify:
|
||||
runs-on: ario-server
|
||||
needs: [prepare, build, deploy]
|
||||
if: always() && github.event_name == 'push'
|
||||
steps:
|
||||
- name: 📱 发送 Telegram 通知
|
||||
uses: appleboy/telegram-action@master
|
||||
with:
|
||||
token: ${{ env.TG_BOT_TOKEN }}
|
||||
to: ${{ env.TG_CHAT_ID }}
|
||||
message: |
|
||||
${{ (needs.build.result == 'success' && needs.deploy.result == 'success') && '✅ 部署成功!' || '❌ 部署失败!' }}
|
||||
|
||||
📦 项目: zero-ppanel
|
||||
🌿 分支: ${{ github.ref_name }}
|
||||
🏷️ 标签: ${{ needs.prepare.outputs.docker_tag }}
|
||||
📝 提交: `${{ github.sha }}`
|
||||
👤 提交者: ${{ github.actor }}
|
||||
🕐 时间: ${{ github.event.head_commit.timestamp }}
|
||||
|
||||
构建: ${{ needs.build.result }} | 部署: ${{ needs.deploy.result }}
|
||||
${{ (needs.build.result != 'success' || needs.deploy.result != 'success') && '⚠️ 请检查 Actions 日志获取详细信息' || '' }}
|
||||
parse_mode: Markdown
|
||||
Reference in New Issue
Block a user