From 855a7b688062067398b0168c542dbc5702a4f75a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=91=E5=AE=81?= <1772105645@qq.com> Date: Sun, 17 May 2026 19:16:56 +0800 Subject: [PATCH] feat: add Dockerfile and upgrade Jenkinsfile to full CI/CD MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Multi-stage .NET 10 Dockerfile (build + runtime) - Jenkinsfile: Docker build → push to registry → deploy with docker-compose --- .dockerignore | 6 ++++ Dockerfile | 20 ++++++++++++ Jenkinsfile | 84 +++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 87 insertions(+), 23 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..73c559a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +bin/ +obj/ +*.user +*.suo +.vs/ +.idea/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..fab5087 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build +WORKDIR /src + +COPY ["Directory.Build.props", "."] +COPY ["src/RAG.Api/RAG.Api.csproj", "src/RAG.Api/"] +COPY ["src/RAG.Application/RAG.Application.csproj", "src/RAG.Application/"] +COPY ["src/RAG.Infrastructure/RAG.Infrastructure.csproj", "src/RAG.Infrastructure/"] +COPY ["src/RAG.Domain/RAG.Domain.csproj", "src/RAG.Domain/"] +RUN dotnet restore "src/RAG.Api/RAG.Api.csproj" + +COPY . . +RUN dotnet publish "src/RAG.Api/RAG.Api.csproj" -c Release -o /app/publish --no-restore + +FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime +WORKDIR /app +COPY --from=build /app/publish . + +EXPOSE 5211 50051 + +ENTRYPOINT ["dotnet", "RAG.Api.dll"] diff --git a/Jenkinsfile b/Jenkinsfile index f7f7514..de55bcd 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -2,47 +2,85 @@ pipeline { agent any environment { - DOTNET_CLI_TELEMETRY_OPTOUT = '1' - DOTNET_ROOT = '/var/jenkins_home/.dotnet' - DOTNET_SYSTEM_GLOBALIZATION_INVARIANT = '1' - PATH = "${env.DOTNET_ROOT}:${env.PATH}" + CI_REGISTRY = '192.168.1.154:31010' + DOCKER_IMAGE = 'docker/rag-backend' + DOCKER_TAG = "${BUILD_NUMBER}" + DEPLOY_DIR = '/home/xiangning/deploy/rag-backend' } stages { - stage('Setup .NET') { - steps { - sh ''' - if [ ! -f "$DOTNET_ROOT/dotnet" ]; then - echo "=== Installing .NET 10 SDK ===" - mkdir -p $DOTNET_ROOT - curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel 10.0 --install-dir $DOTNET_ROOT - fi - dotnet --version - ''' - } - } - stage('Restore') { + stage('Checkout') { steps { - echo '=== Restore NuGet Packages ===' - sh 'dotnet restore' + echo '=== Checkout ===' + checkout scm + sh 'git log --oneline -5' } } stage('Build') { steps { - echo '=== Build Solution ===' - sh 'dotnet build --no-restore' + echo '=== Build Docker Image ===' + sh """ + echo "Registry: ${CI_REGISTRY}" + echo "Image: ${DOCKER_IMAGE}:${DOCKER_TAG}" + docker build -t ${DOCKER_IMAGE}:${DOCKER_TAG} . + docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${DOCKER_IMAGE}:latest + """ + } + } + + stage('Push') { + steps { + echo '=== Push to Registry ===' + sh """ + echo 'dockerxn001624.' | docker login -u docker --password-stdin ${CI_REGISTRY} + docker tag ${DOCKER_IMAGE}:${DOCKER_TAG} ${CI_REGISTRY}/${DOCKER_IMAGE}:${DOCKER_TAG} + docker tag ${DOCKER_IMAGE}:latest ${CI_REGISTRY}/${DOCKER_IMAGE}:latest + docker push ${CI_REGISTRY}/${DOCKER_IMAGE}:${DOCKER_TAG} + docker push ${CI_REGISTRY}/${DOCKER_IMAGE}:latest + """ + } + } + + stage('Deploy') { + steps { + echo '=== Deploy ===' + sh """ + mkdir -p ${DEPLOY_DIR} + cd ${DEPLOY_DIR} + cat > docker-compose.yml << 'DCOF' +services: + rag-backend: + image: ${CI_REGISTRY}/${DOCKER_IMAGE}:latest + container_name: rag-backend + ports: + - "5211:5211" + - "50051:50051" + restart: unless-stopped + environment: + - ASPNETCORE_ENVIRONMENT=Production + - Kestrel__Endpoints__Http__Url=http://+:5211 + - Kestrel__Endpoints__Grpc__Url=http://+:50051 + volumes: + - ./logs:/app/logs +DCOF + docker compose pull + docker compose down --remove-orphans || true + docker compose up -d + docker image prune -f + docker compose ps + """ } } } post { success { - echo 'Build succeeded!' + echo '=== CI/CD SUCCESS ===' } failure { - echo 'Build failed!' + echo '=== CI/CD FAILED ===' } always { deleteDir()