From 222208862cbacf8dc06bd05024d820a872973894 Mon Sep 17 00:00:00 2001 From: gewuyou Date: Sun, 11 May 2025 11:44:34 +0800 Subject: [PATCH] =?UTF-8?q?ci/cd:=20=E6=B7=BB=E5=8A=A0=20master=20?= =?UTF-8?q?=E5=88=86=E6=94=AF=E7=9A=84=E6=8C=81=E7=BB=AD=E9=9B=86=E6=88=90?= =?UTF-8?q?=E5=92=8C=E9=83=A8=E7=BD=B2=E6=B5=81=E6=B0=B4=E7=BA=BF-=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20bootstrap-master.yml=20=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E6=96=87=E4=BB=B6=EF=BC=8C=E7=94=A8=E4=BA=8E=20Nacos=20?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=92=8C=E5=8F=91=E7=8E=B0=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=20-=20=E7=A7=BB=E9=99=A4=20application-master.yml=20=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=20Nacos=20=E7=9B=B8=E5=85=B3=E9=85=8D=E7=BD=AE=20-=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20Docker=20Compose=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E7=94=A8=E4=BA=8E=E5=AE=9A=E4=B9=89=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=E7=BB=93=E6=9E=84=20-=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=20Gitea=20Actions=20=E5=B7=A5=E4=BD=9C=E6=B5=81=EF=BC=8C?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BB=8E=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E5=88=B0=E9=83=A8=E7=BD=B2=E7=9A=84=E8=87=AA=E5=8A=A8=E5=8C=96?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=20-=20=E9=85=8D=E7=BD=AE=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E7=AD=96=E7=95=A5=EF=BC=8C=E6=8F=90=E9=AB=98=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E6=95=88=E7=8E=87=20-=20=E6=B7=BB=E5=8A=A0=E8=BF=9C=E7=A8=8B?= =?UTF-8?q?=E9=83=A8=E7=BD=B2=E6=AD=A5=E9=AA=A4=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=86=85=E9=83=A8=E5=92=8C=E6=96=B0=E5=8A=A0=E5=9D=A1=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E7=9A=84=E8=87=AA=E5=8A=A8=E9=83=A8=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/deploy.master.yml | 219 ++++++++++++++++++ docker/docker-compose.master.agent.yml | 32 +++ docker/docker-compose.master.main.yml | 48 ++++ .../src/main/resources/application-master.yml | 7 +- .../src/main/resources/bootstrap-master.yml | 23 ++ .../src/main/resources/application-master.yml | 22 +- .../src/main/resources/bootstrap-master.yml | 20 ++ 7 files changed, 344 insertions(+), 27 deletions(-) create mode 100644 .gitea/workflows/deploy.master.yml create mode 100644 docker/docker-compose.master.agent.yml create mode 100644 docker/docker-compose.master.main.yml create mode 100644 llmx-core/llmx-core-service/src/main/resources/bootstrap-master.yml create mode 100644 llmx-impl/llmx-impl-bailian/src/main/resources/bootstrap-master.yml diff --git a/.gitea/workflows/deploy.master.yml b/.gitea/workflows/deploy.master.yml new file mode 100644 index 0000000..e832654 --- /dev/null +++ b/.gitea/workflows/deploy.master.yml @@ -0,0 +1,219 @@ +name: CI/CD Pipeline + +on: + push: + branches: + - master # 触发构建的分支 + +env: + # ========== 环境变量配置 ========== + DOCKER_REGISTRY_URL: ${{vars.DOCKER_REGISTRY_URL}} # 私有Docker镜像仓库地址 + INTERNAL_DOCKER_REGISTRY_URL: ${{vars.INTERNAL_DOCKER_REGISTRY_URL}} + PROJECT_NAME: llmx # 项目名称 + MAIN_COMPOSE_FILE: docker/docker-compose.master.main.yml + AGENT_COMPOSE_FILE: docker/docker-compose.master.agent.yml + SERVER_PASSWORD: ${{ secrets.SERVER_PASSWORD }} # 仓库密码 + JCNC_GITEA_URL: ${{vars.SERVER_GITEA_URL}} # Gitea地址 + RUNNER_TOOL_CACHE: /opt/tools-cache # 工具缓存目录 + GRADLE_CACHE_KEY: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + SPRING_PROFILES_ACTIVE: master + INTERNAL_SERVER_HOST: ${{ vars.INTERNAL_SERVER_HOST }} + INTERNAL_SERVER_PROT: ${{ vars.INTERNAL_SERVER_PROT }} + SINGAPORE_SERVER_HOST: ${{ vars.SINGAPORE_SERVER_HOST }} + SSH_PROT: ${{ vars.SSH_PROT }} +jobs: + build-and-deploy: + runs-on: ubuntu-latest + container: + image: jcnc/act-runner:latest # 使用自定义Runner镜像 + options: --user root # 以root用户运行(需要docker权限) + + steps: + # ========== 1. 代码检出 ========== + - name: 🛒 Checkout source code + uses: ${{env.JCNC_GITEA_URL}}/actions/checkout@v4 + with: + fetch-depth: 0 # 获取完整git历史(某些插件需要) + + # ========== 2. Docker环境准备 ========== + - name: 🐳 Install Docker Environment + run: | + echo "=== 检查Docker安装状态 ===" + if ! command -v docker >/dev/null; then + echo "❌ Docker未安装,开始安装..." + curl -fsSL https://get.docker.com | sh | tee docker-install.log + echo "✅ Docker安装完成" + echo "✅ Docker Compose安装完成" + else + echo "ℹ️ Docker已安装,版本: $(docker -v)" + echo "ℹ️ Docker Compose已安装,版本: $(docker compose version)" + fi + + # ========== 3. Gradle环境准备 ========== + - name: 🔧 Prepare Gradle Environment + run: | + echo "赋予gradlew执行权限..." + chmod +x gradlew + echo "当前目录结构:" + ls -al + # ========== 4. 恢复缓存 ========== + - name: 📦 Use Cache + id: cache + uses: ${{env.JCNC_GITEA_URL}}/actions/cache/restore@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + ~/.cache + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + env: + ACTIONS_RUNNER_DEBUG: true # 启用缓存调试输出 + + - name: ⚙️ Setup Gradle + uses: ${{env.JCNC_GITEA_URL}}/gradle/actions/setup-gradle@v4 + with: + gradle-version: wrapper # 使用项目自带的gradle-wrapper + - name: 📦 Copy Compose File to Internal Server + uses: ${{env.JCNC_GITEA_URL}}/appleboy/scp-action@v1 + with: + host: ${{ env.INTERNAL_SERVER_HOST }} + port: $INTERNAL_SERVER_PROT + username: root + password: ${{ secrets.INTERNAL_SERVER_PASSWORD }} + source: $MAIN_COMPOSE_FILE + target: "/home/luke/deploy/llmx/docker-compose.master.yml" + - name: 📦 Copy Compose File to Singapore Server + uses: ${{env.JCNC_GITEA_URL}}/appleboy/scp-action@v1 + with: + host: $SINGAPORE_SERVER_HOST + port: $SSH_PROT + username: root + password: ${{ secrets.SINGAPORE_SERVER_PASSWORD }} + source: $AGENT_COMPOSE_FILE + target: "/home/deploy/llmx/docker-compose.master.yml" + # ========== 5. 构建阶段 ========== + - name: 🏗️ Build with Jib + run: | + echo "开始构建Docker镜像..." + ./gradlew jib --stacktrace --build-cache --info -Dorg.gradle.caching=true -Dorg.gradle.jvmargs="-Xmx2g -Xms2g -XX:MaxMetaspaceSize=1g" | tee build.log + + echo "=== 镜像构建结果 ===" + docker images | grep ${{ env.PROJECT_NAME }} || true + - name: 🛑 Stop Gradle Daemon + run: | + echo "停止Gradle守护进程..." + ./gradlew --stop + echo "剩余Java进程:" + ps aux | grep java || true + - name: 🛰️ Tag & Push to Internal Registry + run: | + echo "标记并推送镜像到内部服务器..." + docker tag ${{env.DOCKER_REGISTRY_URL}}/llmx-core-service:latest ${{env.INTERNAL_DOCKER_REGISTRY_URL}}/llmx-core-service:latest + docker tag ${{env.DOCKER_REGISTRY_URL}}/llmx-impl-bailian:latest ${{env.INTERNAL_DOCKER_REGISTRY_URL}}/llmx-impl-bailian:latest + + echo "${{ secrets.INTERNAL_DOCKER_REGISTRY_PASSWORD }}" | docker login ${{env.INTERNAL_DOCKER_REGISTRY_URL}} -u root --password-stdin + docker push ${{env.INTERNAL_DOCKER_REGISTRY_URL}}/llmx-core-service:latest + docker push ${{env.INTERNAL_DOCKER_REGISTRY_URL}}/llmx-impl-bailian:latest + docker logout ${{env.INTERNAL_DOCKER_REGISTRY_URL}} + - name: 🛰️ Tag & Push to Singapore Registry + run: | + echo "标记并推送镜像到内部服务器..." + docker tag ${{env.DOCKER_REGISTRY_URL}}/llmx-core-service:latest ${{env.SINGAPORE_DOCKER_REGISTRY_URL}}/llmx-core-service:latest + docker tag ${{env.DOCKER_REGISTRY_URL}}/llmx-impl-bailian:latest ${{env.SINGAPORE_DOCKER_REGISTRY_URL}}/llmx-impl-bailian:latest + + echo "${{ secrets.INTERNAL_DOCKER_REGISTRY_PASSWORD }}" | docker login ${{env.SINGAPORE_DOCKER_REGISTRY_URL}} -u root --password-stdin + docker push ${{env.SINGAPORE_DOCKER_REGISTRY_URL}}/llmx-core-service:latest + docker push ${{env.SINGAPORE_DOCKER_REGISTRY_URL}}/llmx-impl-bailian:latest + docker logout ${{env.SINGAPORE_DOCKER_REGISTRY_URL}} + # ========== 6. 保存缓存 ========== + - name: 📦 Save Cache + id: cache + uses: ${{env.JCNC_GITEA_URL}}/actions/cache/save@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + ~/.cache + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + env: + ACTIONS_RUNNER_DEBUG: true # 启用缓存调试输出 + - name: 🧼 Cleanup Dangling Images + run: | + echo "开始清理无标签镜像..." + docker image prune -f + remote-internal-deploy: + needs: build-and-deploy + runs-on: ubuntu-latest + container: + image: jcnc/act-runner:latest # 使用自定义Runner镜像 + options: --user root # 以root用户运行(需要docker权限) + steps: + - name: ✈️ Deploy on Internal Server + uses: ${{env.JCNC_GITEA_URL}}/appleboy/ssh-action@v1 + with: + host: $INTERNAL_SERVER_HOST + port: $INTERNAL_SERVER_PROT + username: root + password: ${{ secrets.INTERNAL_SERVER_PASSWORD }} + script: | + cd /home/luke/deploy/llmx + echo "准备部署环境..." + chmod +x docker-compose.master.yml + echo "当前Docker状态:" + docker ps -a + echo "清理旧容器..." + docker compose -f docker-compose.master.yml down --remove-orphans + echo "清理后Docker状态:" + docker ps -a + echo "拉取最新镜像..." + docker compose -f docker-compose.master.yml pull + echo "启动新服务..." + docker compose -f docker-compose.master.yml up -d + docker compose ps + echo "=== 服务状态检查 ===" + docker compose -f docker-compose.master.yml ps + echo "开始清理无标签镜像..." + docker image prune -f + echo "清理docker-compose.master.yml" + rm -rf docker-compose.master.yml + remote-singapore-deploy: + needs: build-and-deploy + runs-on: ubuntu-latest + container: + image: jcnc/act-runner:latest # 使用自定义Runner镜像 + options: --user root # 以root用户运行(需要docker权限) + steps: + - name: ✈️ Deploy on Internal Server + uses: ${{env.JCNC_GITEA_URL}}/appleboy/ssh-action@v1 + with: + host: $SINGAPORE_SERVER_HOST + port: $SSH_PROT + username: root + password: ${{ secrets.SINGAPORE_SERVER_PASSWORD }} + script: | + cd /home/deploy/llmx + echo "准备部署环境..." + chmod +x docker-compose.master.yml + echo "当前Docker状态:" + docker ps -a + echo "清理旧容器..." + docker compose -f docker-compose.master.yml down --remove-orphans + echo "清理后Docker状态:" + docker ps -a + echo "拉取最新镜像..." + docker compose -f docker-compose.master.yml pull + echo "启动新服务..." + docker compose -f docker-compose.master.yml up -d + docker compose ps + echo "=== 服务状态检查 ===" + docker compose -f docker-compose.master.yml ps + echo "开始清理无标签镜像..." + docker image prune -f + echo "清理docker-compose.master.yml" + rm -rf docker-compose.master.yml diff --git a/docker/docker-compose.master.agent.yml b/docker/docker-compose.master.agent.yml new file mode 100644 index 0000000..212ec44 --- /dev/null +++ b/docker/docker-compose.master.agent.yml @@ -0,0 +1,32 @@ +services: + llmx-core-service-banana: + image: ${DOCKER_REGISTRY_URL}/llmx-core-service + container_name: llmx-core-service + ports: + - "9002:9002" + networks: + - llmx-net-master + environment: + SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE} + volumes: + - llmx-core-service-volume:/app/volume + restart: always + llmx-impl-bailian-banana: + image: ${DOCKER_REGISTRY_URL}/llmx-impl-bailian + container_name: llmx-impl-bailian + ports: + - "9003:9003" + networks: + - llmx-net-master + environment: + SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE} + volumes: + - llmx-impl-bailian-volume:/app/volume + restart: always + +networks: + llmx-net-master: + driver: bridge +volumes: + llmx-core-service-volume: + llmx-impl-bailian-volume: diff --git a/docker/docker-compose.master.main.yml b/docker/docker-compose.master.main.yml new file mode 100644 index 0000000..0d61505 --- /dev/null +++ b/docker/docker-compose.master.main.yml @@ -0,0 +1,48 @@ +services: + llmx-core-service-apple: + image: ${DOCKER_REGISTRY_URL}/llmx-core-service + container_name: llmx-core-service + ports: + - "9002:9002" + networks: + - llmx-net-master + environment: + SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE} + volumes: + - llmx-core-service-volume:/app/volume + restart: always + llmx-database: + image: postgres:16-alpine # 长期支持版本推荐用 16 + container_name: llmx-database + restart: always + ports: + - "9052:5432" + networks: + - llmx-net-master + environment: + POSTGRES_DB: llmx_db + POSTGRES_USER: llmx + POSTGRES_PASSWORD: L4s6f9y3, + volumes: + - llmx-db-volume + llmx-impl-bailian-apple: + image: ${DOCKER_REGISTRY_URL}/llmx-impl-bailian + container_name: llmx-impl-bailian + ports: + - "9003:9003" + networks: + - llmx-net-master + environment: + SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE} + volumes: + - llmx-impl-bailian-volume:/app/volume + restart: always + +networks: + llmx-net-master: + driver: bridge + +volumes: + llmx-core-service-volume: + llmx-impl-bailian-volume: + llmx-db-volume: diff --git a/llmx-core/llmx-core-service/src/main/resources/application-master.yml b/llmx-core/llmx-core-service/src/main/resources/application-master.yml index e78b1c6..5af7893 100644 --- a/llmx-core/llmx-core-service/src/main/resources/application-master.yml +++ b/llmx-core/llmx-core-service/src/main/resources/application-master.yml @@ -1,7 +1,2 @@ server: - port: 9002 -spring: - cloud: - nacos: - discovery: - server-addr: 49.235.96.75:9001 \ No newline at end of file + port: 9002 \ No newline at end of file diff --git a/llmx-core/llmx-core-service/src/main/resources/bootstrap-master.yml b/llmx-core/llmx-core-service/src/main/resources/bootstrap-master.yml new file mode 100644 index 0000000..473128d --- /dev/null +++ b/llmx-core/llmx-core-service/src/main/resources/bootstrap-master.yml @@ -0,0 +1,23 @@ +spring: + cloud: + nacos: + username: nacos + password: L4s6f9y3, + server-addr: 49.235.96.75:8848 + discovery: + server-addr: ${spring.cloud.nacos.server-addr} + username: ${spring.cloud.nacos.username} + password: ${spring.cloud.nacos.password} + group: llmx-${spring.profiles.active} + namespace: ab34d859-6f1a-4f28-ac6b-27a7410ab27b + config: + file-extension: yaml + namespace: ab34d859-6f1a-4f28-ac6b-27a7410ab27b + refresh-enabled: true + extension-configs: + - data-id: ${spring.application.name}-${spring.profiles.active}.yaml + refresh: true + group: ${spring.application.name} + - data-id: common-db.yaml + refresh: true + group: infra \ No newline at end of file diff --git a/llmx-impl/llmx-impl-bailian/src/main/resources/application-master.yml b/llmx-impl/llmx-impl-bailian/src/main/resources/application-master.yml index 292217d..9beecae 100644 --- a/llmx-impl/llmx-impl-bailian/src/main/resources/application-master.yml +++ b/llmx-impl/llmx-impl-bailian/src/main/resources/application-master.yml @@ -1,22 +1,2 @@ server: - port: 9003 -spring: - application: - name: llmx-impl-bailian - cloud: - nacos: - discovery: - server-addr: 49.235.96.75:9001 # Nacos 服务地址 -# 阿里云配置 -aliyun: - # DashScope服务配置 - dash: - # 访问凭证配置 - scope: - access-key-id: LTAI5tHiA2Ry3XTAfoSEJW6z # 阿里云访问密钥ID - access-key-secret: K5sf4FxZZuUgLEFnyfepBfMqFGmDcD # 阿里云访问密钥密钥 - endpoint: bailian.cn-beijing.aliyuncs.com # 阿里云服务端点 - workspace-id: llm-axfkuqft05uzbjpi # 工作区ID - api-key: sk-78af4dd964a94f4cb373851064dbdc12 # API密钥 - app-id: 3fae0bbab2e54a90a37aa02cd12dd62c # 应用ID - base-url: https://dashscope.aliyuncs.com/api/v1/apps/ # 基础API URL + port: 9003 \ No newline at end of file diff --git a/llmx-impl/llmx-impl-bailian/src/main/resources/bootstrap-master.yml b/llmx-impl/llmx-impl-bailian/src/main/resources/bootstrap-master.yml new file mode 100644 index 0000000..399cdd9 --- /dev/null +++ b/llmx-impl/llmx-impl-bailian/src/main/resources/bootstrap-master.yml @@ -0,0 +1,20 @@ +spring: + cloud: + nacos: + username: nacos + password: L4s6f9y3, + server-addr: 49.235.96.75:8848 + discovery: + username: ${spring.cloud.nacos.username} + password: ${spring.cloud.nacos.password} + server-addr: ${spring.cloud.nacos.server-addr} + group: llmx-${spring.profiles.active} + namespace: ab34d859-6f1a-4f28-ac6b-27a7410ab27b + config: + file-extension: yaml + namespace: ab34d859-6f1a-4f28-ac6b-27a7410ab27b + refresh-enabled: true + extension-configs: + - data-id: ${spring.application.name}-${spring.profiles.active}.yaml + refresh: true + group: ${spring.application.name} \ No newline at end of file