diff --git a/Dockerfile/python/lessie-email/Dockerfile b/Dockerfile/python/lessie-email/Dockerfile index 5f1d942..92a264e 100644 --- a/Dockerfile/python/lessie-email/Dockerfile +++ b/Dockerfile/python/lessie-email/Dockerfile @@ -1,18 +1,45 @@ +# ==================== 安装依赖阶段(构建镜像)==================== # 基础镜像:3.12-slim轻量化,小镜像 -FROM python:3.12-slim as builder +FROM python:3.12-slim AS builder # 构建阶段:隔离构建依赖,最终镜像仅保留运行时,镜像瘦身 WORKDIR /app -# 默认测试环境,可通过env修改 development/production ENV PYTHONUNBUFFERED=1 \ PYTHONDONTWRITEBYTECODE=1 \ UV_SYSTEM_PYTHON=1 \ UV_HTTP_TIMEOUT=600 \ UV_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \ - UV_EXTRA_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple \ + UV_EXTRA_INDEX_URL=https://pypi.tuna.tsinghua.edu.cn/simple + +# 安装构建依赖 +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + g++ \ + build-essential \ + python3-dev \ + ca-certificates \ + curl \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get clean + +# 复制uv和依赖文件 +COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv +COPY pyproject.toml uv.lock ./ + +# 安装依赖:--frozen锁定版本,--no-dev默认安装生产依赖 +# 依赖安装到venv,保证隔离性,同时支持uv run调用 +RUN uv sync --frozen --no-dev + + +# ==================== 运行时阶段(最终镜像)==================== +FROM python:3.12-slim AS runtime + +# 默认测试环境,可通过 env 修改 +ENV PYTHONUNBUFFERED=1 \ + PYTHONDONTWRITEBYTECODE=1 \ # 可外部覆盖的核心启动参数 - APP_ENV=test \ + ENV=test \ APP_PORT=8031 \ APP_HOST=0.0.0.0 \ # 是否开启热重载:默认关闭(生产/测试环境不需要),开发环境可设为1 @@ -20,32 +47,6 @@ ENV PYTHONUNBUFFERED=1 \ # 日志配置文件:默认使用json配置,可设为空关闭 APP_LOG_CONFIG=logging_config.json -# 安装构建依赖(仅builder阶段需要,运行时镜像会剔除) -RUN apt-get update && apt-get install -y --no-install-recommends \ - gcc \ - g++ \ - build-essential \ - python3-dev \ - && rm -rf /var/lib/apt/lists/* \ - # 清理apt缓存,进一步减小构建层体积 - && apt-get clean - -# 复制uv和依赖文件(**核心缓存层**:仅pyproject.toml/uv.lock变更时才重新安装依赖) -COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv -COPY pyproject.toml uv.lock ./ - -# 安装依赖:--frozen锁定版本,--no-dev默认安装生产依赖(开发环境可通过uv sync --dev覆盖) -# 依赖安装到venv,保证隔离性,同时支持uv run调用 -RUN uv sync --frozen --no-dev - -# ==================== 运行时阶段(最终镜像)==================== -FROM python:3.12-slim as runtime - -# 继承构建阶段的环境变量(可被外部传参覆盖) -ENV PYTHONUNBUFFERED=1 \ - PYTHONDONTWRITEBYTECODE=1 \ - UV_SYSTEM_PYTHON=1 - # 设置工作目录,与构建阶段一致 WORKDIR /app @@ -62,9 +63,5 @@ EXPOSE ${APP_PORT} # 启动脚本:用shell脚本解析环境变量,动态生成启动命令 CMD ["/bin/sh", "-c", \ - "if [ $APP_RELOAD -eq 1 ]; then \ - uv run uvicorn app.main:app --host $APP_HOST --port $APP_PORT --reload ${APP_LOG_CONFIG:+-log-config $APP_LOG_CONFIG}; \ - else \ - uv run uvicorn app.main:app --host $APP_HOST --port $APP_PORT ${APP_LOG_CONFIG:+-log-config $APP_LOG_CONFIG}; \ - fi" \ -] \ No newline at end of file + "exec uv run uvicorn app.main:app --host ${APP_HOST} --port ${APP_PORT} --log-config logging_config.json" \ +] diff --git a/Dockerfile/web/lessie_official_web_Dockerfile b/Dockerfile/web/lessie_old_official_web_Dockerfile similarity index 100% rename from Dockerfile/web/lessie_official_web_Dockerfile rename to Dockerfile/web/lessie_old_official_web_Dockerfile diff --git a/Dockerfile/web/lessie_web_Dockerfile b/Dockerfile/web/lessie_web_Dockerfile index 08fe95b..f9ddccf 100644 --- a/Dockerfile/web/lessie_web_Dockerfile +++ b/Dockerfile/web/lessie_web_Dockerfile @@ -1,10 +1,54 @@ -# 使用 Nginx 官方轻量镜像 -FROM nginx:1.25-alpine +# # 使用 Nginx 官方轻量镜像 +# FROM nginx:1.25-alpine -# 拷贝前端构建产物 -COPY dist/ /usr/share/nginx/html/ +# # 拷贝前端构建产物 +# COPY dist/ /usr/share/nginx/html/ -# 暴露端口 +# # 暴露端口 +# EXPOSE 80 + +# CMD ["nginx", "-g", "daemon off;"] + + + +# 第一阶段:构建阶段 - 使用指定node20.15.0版本,安装pnpm +FROM node:20.15.0-alpine AS builder + +# 设定工作目录(容器内的项目目录) +WORKDIR /app + +# 配置pnpm源(可选,加速国内安装) +ENV PNPM_REGISTRY=https://registry.npmmirror.com/ +# 全局安装pnpm(node20+推荐corepack管理pnpm,更适配) +RUN corepack enable && corepack prepare pnpm@latest --activate + +# 复制包管理文件(先复制lock文件,利用docker层缓存,避免代码变动重复装包) +COPY package.json pnpm-lock.yaml* ./ + +# 安装项目依赖(--frozen-lockfile 锁定依赖版本,保证构建一致性) +RUN pnpm install --frozen-lockfile + +# 复制整个项目代码到容器 +COPY . . + +# 构建参数:指定构建环境(默认im,可在build时覆盖为test/im/prod等) +ARG BUILD_ENV=im +# 执行对应环境的构建命令(拼接为pnpm build:xxx) +RUN pnpm build:${BUILD_ENV} + +RUN mv /app/dist/main/index.html /app/dist/ + + +# 第二阶段:运行阶段 - 使用官方Nginx稳定版,仅保留dist目录,减小镜像体积 +FROM nginx:stable-alpine + +# 暴露Nginx默认端口(前端项目常规端口) EXPOSE 80 -CMD ["nginx", "-g", "daemon off;"] +# 可选:替换Nginx默认配置(解决前端路由刷新404、开启gzip压缩,优化静态资源) +# COPY ./nginx.conf /etc/nginx/conf.d/default.conf + +# 从构建阶段(builder)复制构建后的dist目录到Nginx的静态资源根目录 +COPY --from=builder /app/dist /usr/share/nginx/html + +# Nginx镜像默认会启动nginx,无需额外CMD/ENTRYPOINT \ No newline at end of file diff --git a/SCM/构建镜像/v4/build_image_lessie_ai_web_v4.groovy b/SCM/构建镜像/v4/build_image_lessie_ai_web_v4.groovy index 2acd6f4..cfbba17 100644 --- a/SCM/构建镜像/v4/build_image_lessie_ai_web_v4.groovy +++ b/SCM/构建镜像/v4/build_image_lessie_ai_web_v4.groovy @@ -38,7 +38,7 @@ pipeline { ) choice( name: 'BUILD_ENV', - choices: ['im', 's2', 'prod'], + choices: ['im', 'prod'], description: '选择构建的环境配置, 默认为 pnpm build:im 构建' ) string( @@ -97,6 +97,8 @@ pipeline { stage('获取信息') { steps { script { + def cause = currentBuild.getBuildCauses('hudson.model.Cause$UserIdCause') + env.ACTUAL_USER = cause ? cause.userName[0] : "系统/自动触发" // 获取分支名 env.Code_branch = "${params.Code_branch}" // 获取最近一次提交的哈希值(短格式,前8位) @@ -170,23 +172,6 @@ pipeline { } } - stage('pnpm i&b') { - steps { - script { - def buildEnv = params.BUILD_ENV // 获取参数 - sh """ - export PATH="/data/nvm/versions/node/v20.15.0/bin:$PATH" - echo "开始安装依赖包" - cd ${WORKSPACE}/ && rm -rf node_modules && pnpm install - echo "开始构建" - pnpm build:${buildEnv} - mv dist/main/index.html dist/ - chmod -R 755 dist/ - """ - } - } - } - stage('登录容器') { steps { withCredentials([usernamePassword( @@ -206,7 +191,7 @@ pipeline { script { // 构建镜像,添加标签信息 sh """ - docker build -t ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${IMAGE_TAG} \ + docker build -t ${REGISTRY}/${NAMESPACE}/${IMAGE_NAME}:${IMAGE_TAG} --build-arg BUILD_ENV=${params.BUILD_ENV} \ --label "git-branch='${Code_branch}'" \ --label "git-commit='${GIT_COMMIT_SHORT}'" \ --label "git-author='${GIT_AUTHOR}'" \ diff --git a/SCM/部署镜像/s1/v3/DM_s1_lessie_review_service.js b/SCM/部署镜像/s1/v3/DM_s1_lessie_email.groovy similarity index 97% rename from SCM/部署镜像/s1/v3/DM_s1_lessie_review_service.js rename to SCM/部署镜像/s1/v3/DM_s1_lessie_email.groovy index 6ffdbcd..a95429f 100644 --- a/SCM/部署镜像/s1/v3/DM_s1_lessie_review_service.js +++ b/SCM/部署镜像/s1/v3/DM_s1_lessie_email.groovy @@ -16,7 +16,7 @@ pipeline { name: 'IMAGE_NAME', description: 'sit 仓库镜像 (除非输入 CUSTOM_IMAGE, 否则使用这里的)', registry: 'https://uswccr.ccs.tencentyun.com', - image: 'lessiesit/lessie-review-service', + image: 'lessiesit/lessie-email', credentialId: 'dxin_img_hub_auth', filter: '.*', defaultTag: '', @@ -26,7 +26,7 @@ pipeline { string( name: 'CUSTOM_IMAGE', defaultValue: '', - description: '手输完整镜像//:,例如: uswccr.ccs.tencentyun.com/lessiesit/lessie-sourcing-agents:v0.0.1 (填充后,则忽略镜像仓库选择)' + description: '手输完整镜像//:,例如: uswccr.ccs.tencentyun.com/lessiesit/lessie-email:v0.0.1 (填充后,则忽略镜像仓库选择)' ) booleanParam( name: 'ROLLBACK_VERSION', @@ -42,11 +42,11 @@ pipeline { environment { LARK_ROBOT = "4b8d66d0-c0f0-4587-b0e5-cff772cb3046" // 飞书机器人ID,用于发送部署通知 KUBECONFIG = credentials('k8s-test-config-admin') // k8s 凭证 ID, Jenkins 中配置的凭证名称 - Deployment_yaml = "${WORKSPACE}/lessie-ai/sit/s1/lessie-review-service.yaml" - Deployment_name = "sit-lessie-review-service" + Deployment_yaml = "${WORKSPACE}/lessie-ai/sit/s1/lessie-email.yaml" + Deployment_name = "s1-lessie-email" K8s_namespace = "sit" - Pod_container_name = "lessie-review-service" - Pod_environment = "sit" + Pod_container_name = "lessie-email" + Pod_environment = "s1" } stages { stage('回滚上版') { @@ -86,7 +86,7 @@ pipeline { def matcher = (customImage =~ imageRegex) if (!matcher.matches()) { error "CUSTOM_IMAGE 格式不正确,必须是 registry/namespace/repository:tag 格式\n" + - "示例: uswccr.ccs.tencentyun.com/lessiesit/lessie-sourcing-agents:v1.0.0\n" + + "示例: uswccr.ccs.tencentyun.com/lessie-ai-web:v1.0.0\n" + "当前输入: ${customImage}" } @@ -188,21 +188,25 @@ pipeline { sh """ echo "--- Deployment 状态 ---" kubectl describe deployment ${Deployment_name} -n ${K8s_namespace} || true + echo " " echo '--- Pod 列表 ---' kubectl get pods -n ${K8s_namespace} -l "app=${Pod_container_name},environment=${Pod_environment}" -o wide || true + echo " " echo "--- Pod 描述 (describe) ---" for pod in \$(kubectl get pods -n ${K8s_namespace} -l "app=${Pod_container_name},environment=${Pod_environment}" -o jsonpath='{.items[*].metadata.name}'); do echo "-- Pod 描述 \$pod --" kubectl describe pod \$pod -n ${K8s_namespace} || true done - + echo " " + echo "--- 最近 200 行 Pod 日志 ---" for pod in \$(kubectl get pods -n ${K8s_namespace} -l "app=${Pod_container_name},environment=${Pod_environment}" -o jsonpath='{.items[*].metadata.name}'); do echo "-- logs \$pod --" kubectl logs \$pod -n ${K8s_namespace} --tail=200 || true done + echo " " """ error("=== Deployment 发布失败,请检查以上输出定位问题 ===") }