Files
ljwx-health/.github/workflows/build-and-push.yml
T
rootandClaude Sonnet 4.5 31ac7f2e89 fix: 使用宿主机 IP 地址访问本地 Registry
## 修复问题
- K3s pod 内无法访问 localhost:5000
- 改用宿主机 IP: 173.212.254.252:5000

## 配置更改
- 更新 .env.local-registry 使用宿主机 IP
- 更新 workflow Registry 登录地址
- 更新 K8s deployment 镜像地址
- 配置 Docker daemon 允许不安全的 Registry
- 配置 K3s registries.yaml 支持 HTTP Registry

## 测试
- ✅ Runner pod 可以访问 173.212.254.252:5000
- ✅ Docker 登录成功
- ✅ K3s 配置完成

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-16 07:55:36 +01:00

318 lines
11 KiB
YAML

name: Build and Push Docker Images
on:
push:
branches:
- main
- develop
tags:
- 'v*'
pull_request:
branches:
- main
- develop
workflow_dispatch:
inputs:
component:
description: 'Component to build (all/ljwx-boot/ljwx-admin/ljwx-bigscreen/ljwx-mysql/ljwx-redis)'
required: false
default: 'all'
version:
description: 'Version tag (default: use VERSION from .env or branch name)'
required: false
env:
DOCKER_BUILDKIT: 1
COMPOSE_DOCKER_CLI_BUILD: 1
jobs:
prepare:
name: Prepare Build Information
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
registry: ${{ steps.config.outputs.registry }}
components: ${{ steps.components.outputs.matrix }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Load .env configuration
id: config
run: |
# 优先使用本地 Registry 配置
if [ -f .env.local-registry ]; then
source .env.local-registry
echo "registry=${REGISTRY}" >> $GITHUB_OUTPUT
echo "harbor_host=${HARBOR_HOST}" >> $GITHUB_OUTPUT
echo "harbor_project=${HARBOR_PROJECT}" >> $GITHUB_OUTPUT
elif [ -f .env ]; then
source .env
echo "registry=${REGISTRY:-173.212.254.252:5000}" >> $GITHUB_OUTPUT
echo "harbor_host=${HARBOR_HOST:-173.212.254.252:5000}" >> $GITHUB_OUTPUT
echo "harbor_project=${HARBOR_PROJECT:-ljwx-health}" >> $GITHUB_OUTPUT
else
echo "registry=173.212.254.252:5000" >> $GITHUB_OUTPUT
fi
- name: Determine version
id: version
run: |
if [ -n "${{ github.event.inputs.version }}" ]; then
VERSION="${{ github.event.inputs.version }}"
elif [[ "${{ github.ref }}" == refs/tags/v* ]]; then
VERSION="${GITHUB_REF#refs/tags/v}"
elif [ -f .env ]; then
source .env
VERSION="${LJWX_VERSION}"
else
VERSION="latest"
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "Build version: ${VERSION}"
- name: Determine components to build
id: components
run: |
COMPONENT="${{ github.event.inputs.component }}"
if [ -z "$COMPONENT" ] || [ "$COMPONENT" = "all" ]; then
COMPONENTS='["ljwx-boot", "ljwx-admin", "ljwx-bigscreen", "ljwx-mysql", "ljwx-redis"]'
else
COMPONENTS='["'$COMPONENT'"]'
fi
echo "matrix=${COMPONENTS}" >> $GITHUB_OUTPUT
echo "Components to build: ${COMPONENTS}"
build-and-push:
name: Build and Push ${{ matrix.component }}
needs: prepare
runs-on: self-hosted
strategy:
fail-fast: false
matrix:
component: ${{ fromJson(needs.prepare.outputs.components) }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Log in to Local Registry
run: |
echo "admin123" | docker login 173.212.254.252:5000 -u admin --password-stdin
- name: Prepare build context
id: context
run: |
COMPONENT="${{ matrix.component }}"
VERSION="${{ needs.prepare.outputs.version }}"
REGISTRY="${{ needs.prepare.outputs.registry }}"
case "$COMPONENT" in
ljwx-mysql)
DOCKERFILE="docker/mysql/Dockerfile"
CONTEXT="."
;;
ljwx-redis)
DOCKERFILE="docker/redis/Dockerfile"
CONTEXT="."
;;
ljwx-boot)
DOCKERFILE="ljwx-boot/ljwx-boot-admin/Dockerfile.prod"
CONTEXT="."
;;
ljwx-bigscreen)
DOCKERFILE="ljwx-bigscreen/bigscreen/Dockerfile.prod"
CONTEXT="ljwx-bigscreen/bigscreen"
;;
ljwx-admin)
DOCKERFILE="ljwx-admin/Dockerfile"
CONTEXT="ljwx-admin"
;;
*)
echo "Unknown component: $COMPONENT"
exit 1
;;
esac
echo "dockerfile=${DOCKERFILE}" >> $GITHUB_OUTPUT
echo "context=${CONTEXT}" >> $GITHUB_OUTPUT
echo "image_name=${REGISTRY}/${COMPONENT}" >> $GITHUB_OUTPUT
echo "version=${VERSION}" >> $GITHUB_OUTPUT
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ steps.context.outputs.image_name }}
tags: |
type=raw,value=${{ steps.context.outputs.version }}
type=raw,value=latest
type=sha,prefix={{branch}}-
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ${{ steps.context.outputs.context }}
file: ${{ steps.context.outputs.dockerfile }}
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
BUILD_DATE=${{ github.event.head_commit.timestamp }}
GIT_COMMIT=${{ github.sha }}
VERSION=${{ steps.context.outputs.version }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Image digest
run: echo "Image pushed successfully"
deploy-to-k3s:
name: Deploy to K3s
needs: [prepare, build-and-push]
runs-on: self-hosted
if: success() && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop')
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up kubectl context
run: |
# Verify kubectl is available
kubectl version --client
# Verify cluster connection
kubectl cluster-info
- name: Create namespace if not exists
run: |
kubectl create namespace ljwx-health --dry-run=client -o yaml | kubectl apply -f -
- name: Create Local Registry image pull secret
run: |
kubectl create secret docker-registry harbor-secret \
--docker-server=173.212.254.252:5000 \
--docker-username=admin \
--docker-password=admin123 \
--namespace=ljwx-health \
--dry-run=client -o yaml | kubectl apply -f -
- name: Update image tags in deployments
env:
VERSION: ${{ needs.prepare.outputs.version }}
REGISTRY: ${{ needs.prepare.outputs.registry }}
run: |
# Update ljwx-boot deployment image tag
if [ -f ljwx-boot/k8s/deployment.yml ]; then
sed -i "s|image:.*ljwx-boot:.*|image: ${REGISTRY}/ljwx-boot:${VERSION}|g" ljwx-boot/k8s/deployment.yml
fi
# Update ljwx-bigscreen deployment image tag
if [ -f ljwx-bigscreen/k8s/prod/deployment.yaml ]; then
# Fix namespace to ljwx-health
sed -i 's|namespace: ljwx-system|namespace: ljwx-health|g' ljwx-bigscreen/k8s/prod/deployment.yaml
# Update image reference
sed -i "s|\${REGISTRY}/\${IMAGE_NAME}:\${IMAGE_TAG}|${REGISTRY}/ljwx-bigscreen:${VERSION}|g" ljwx-bigscreen/k8s/prod/deployment.yaml
fi
- name: Deploy ljwx-boot
env:
DB_USERNAME: ${{ secrets.MYSQL_USERNAME || 'root' }}
DB_PASSWORD: ${{ secrets.MYSQL_PASSWORD || '123456' }}
REDIS_PASSWORD: ${{ secrets.REDIS_PASSWORD || '123456' }}
JWT_SECRET: ${{ secrets.JWT_SECRET || 'ljwx-default-jwt-secret-change-me' }}
run: |
# Apply ConfigMap first
kubectl apply -f ljwx-boot/k8s/configmap.yml -n ljwx-health || true
# Create secret from template
if [ -f ljwx-boot/k8s/secret.yml.template ]; then
sed "s|<BASE64_ENCODED_DB_USERNAME>|$(echo -n "${DB_USERNAME}" | base64)|g" ljwx-boot/k8s/secret.yml.template | \
sed "s|<BASE64_ENCODED_DB_PASSWORD>|$(echo -n "${DB_PASSWORD}" | base64)|g" | \
sed "s|<BASE64_ENCODED_REDIS_PASSWORD>|$(echo -n "${REDIS_PASSWORD}" | base64)|g" | \
sed "s|<BASE64_ENCODED_JWT_SECRET>|$(echo -n "${JWT_SECRET}" | base64)|g" | \
kubectl apply -f - -n ljwx-health
fi
# Apply Service
kubectl apply -f ljwx-boot/k8s/service.yml -n ljwx-health || true
# Apply Deployment
kubectl apply -f ljwx-boot/k8s/deployment.yml -n ljwx-health
# Wait for rollout
kubectl rollout status deployment/ljwx-boot -n ljwx-health --timeout=5m
- name: Deploy ljwx-bigscreen
run: |
# Apply ConfigMap
kubectl apply -f ljwx-bigscreen/k8s/base/configmap.yaml -n ljwx-health || true
# Apply Service
kubectl apply -f ljwx-bigscreen/k8s/prod/service.yaml -n ljwx-health || true
# Apply Deployment
kubectl apply -f ljwx-bigscreen/k8s/prod/deployment.yaml -n ljwx-health
# Wait for rollout
kubectl rollout status deployment/ljwx-bigscreen -n ljwx-health --timeout=5m
- name: Verify deployment
run: |
echo "## Deployment Status" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Get pod status
kubectl get pods -n ljwx-health -o wide >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Get service status
echo "### Services" >> $GITHUB_STEP_SUMMARY
kubectl get svc -n ljwx-health >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# Check deployment health
BOOT_READY=$(kubectl get deployment ljwx-boot -n ljwx-health -o jsonpath='{.status.readyReplicas}')
BOOT_DESIRED=$(kubectl get deployment ljwx-boot -n ljwx-health -o jsonpath='{.status.replicas}')
if [ "$BOOT_READY" == "$BOOT_DESIRED" ]; then
echo "✅ ljwx-boot: $BOOT_READY/$BOOT_DESIRED replicas ready" >> $GITHUB_STEP_SUMMARY
else
echo "⚠️ ljwx-boot: $BOOT_READY/$BOOT_DESIRED replicas ready" >> $GITHUB_STEP_SUMMARY
fi
summary:
name: Build Summary
needs: [prepare, build-and-push, deploy-to-k3s]
runs-on: ubuntu-latest
if: always()
steps:
- name: Check build status
run: |
echo "## Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Version:** ${{ needs.prepare.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "**Registry:** ${{ needs.prepare.outputs.registry }}" >> $GITHUB_STEP_SUMMARY
echo "**Components:** ${{ needs.prepare.outputs.components }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "${{ needs.build-and-push.result }}" == "success" ]; then
echo "✅ All images built and pushed successfully!" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Some builds failed. Check the logs above." >> $GITHUB_STEP_SUMMARY
fi
if [ "${{ needs.deploy-to-k3s.result }}" == "success" ]; then
echo "✅ Deployment to K3s successful!" >> $GITHUB_STEP_SUMMARY
elif [ "${{ needs.deploy-to-k3s.result }}" == "skipped" ]; then
echo "⏭️ Deployment skipped (not main/develop branch)" >> $GITHUB_STEP_SUMMARY
else
echo "❌ Deployment to K3s failed. Check the logs above." >> $GITHUB_STEP_SUMMARY
fi