From b0a04392690329957f2e83c34bb7325f2117ff5d Mon Sep 17 00:00:00 2001 From: zk Date: Tue, 2 Jun 2026 19:35:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=83=A8=E7=BD=B2=E6=96=87?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.prod | 3 +- .env.test | 2 +- Dockerfile | 35 +++++++++++++++ Jenkinsfile | 104 +++++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 15 +++++++ 5 files changed, 156 insertions(+), 3 deletions(-) create mode 100644 Dockerfile create mode 100644 Jenkinsfile create mode 100644 docker-compose.yml diff --git a/.env.prod b/.env.prod index d21bc95..bef86ef 100644 --- a/.env.prod +++ b/.env.prod @@ -1,4 +1,4 @@ -ENV=dev +ENV=prod # PostgreSQL(本地爬虫库) PG_HOST=192.168.31.51 @@ -14,7 +14,6 @@ DB_USER=root DB_PASSWORD=^CgDatabase2020 DB_NAME=offerpie - # AI 供应商 VOLCENGINE_API_KEY=fd065993-bee2-4f31-8bf2-56d5d3012c02 VOLCENGINE_BASE_URL=https://ark.cn-beijing.volces.com/api/v3 diff --git a/.env.test b/.env.test index 1f7122d..badb7b6 100644 --- a/.env.test +++ b/.env.test @@ -1,4 +1,4 @@ -ENV=dev +ENV=test # PostgreSQL(本地爬虫库) PG_HOST=192.168.31.51 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ede2e05 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,35 @@ +# 使用 Python 3.12 slim 镜像 +FROM python:3.12-slim + +ENV TZ=Asia/Shanghai +ENV ENV=prod +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + +# 时区 + 系统依赖 +RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \ + && rm -rf /etc/apt/sources.list.d/* \ + && echo "deb https://mirrors.aliyun.com/debian/ bookworm main non-free contrib" > /etc/apt/sources.list \ + && echo "deb https://mirrors.aliyun.com/debian-security/ bookworm-security main non-free contrib" >> /etc/apt/sources.list \ + && echo "deb https://mirrors.aliyun.com/debian/ bookworm-updates main non-free contrib" >> /etc/apt/sources.list \ + && apt-get clean \ + && apt-get update \ + && apt-get install -y --no-install-recommends curl \ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir -p /app/logs + +WORKDIR /app + +# 先拷贝依赖声明,利用 Docker 层缓存 +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt \ + -i https://mirrors.aliyun.com/pypi/simple/ \ + --trusted-host mirrors.aliyun.com + +# 拷贝应用代码和环境配置 +COPY app/ ./app/ +COPY .env.prod ./.env.prod + +# 纯后台服务,无 HTTP 端口 +CMD ["python", "-m", "app.main"] diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..fc5fb71 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,104 @@ +/** + * OfferPie Job Cleaner 部署流水线 + * + * 架构:Jenkins 本地编译镜像 → scp 到目标机 → SSH 远程重启容器 + * 目标机目录:/opt/offerpie/job-cleaner/ + */ +pipeline { + agent any + + parameters { + choice(name: 'BRANCH', choices: ['master', 'dev'], description: '选择要部署的分支') + } + + environment { + // 目标服务器配置 + DEPLOY_HOST = '192.168.31.51' + DEPLOY_PORT = '22' + DEPLOY_USER = 'jsxq' + DEPLOY_PASS = '123456' + + // 项目配置 + IMAGE_NAME = 'offerpie-job-cleaner' + IMAGE_TAG = 'latest' + CONTAINER_NAME = 'offerpie-job-cleaner' + REMOTE_DIR = '/opt/offerpie/job-cleaner' + + // SSH 命令前缀 + SSH_CMD = "sshpass -p '${DEPLOY_PASS}' ssh -o StrictHostKeyChecking=no -p ${DEPLOY_PORT} ${DEPLOY_USER}@${DEPLOY_HOST}" + SCP_CMD = "sshpass -p '${DEPLOY_PASS}' scp -o StrictHostKeyChecking=no -P ${DEPLOY_PORT}" + } + + stages { + stage('环境检查') { + steps { + sh 'sshpass -V' + } + } + + stage('拉取代码') { + steps { + echo "拉取 ${params.BRANCH} 分支代码" + git branch: "${params.BRANCH}", + credentialsId: 'gitea-fab089c1-b55d-4b58-9fad', + url: 'http://git.jianshixingqiu.com/offerpai/offerpie_job_cleaner.git' + } + } + + stage('本地编译') { + steps { + echo "开始构建镜像" + sh "docker build -t ${IMAGE_NAME}:${IMAGE_TAG} ." + echo "导出镜像" + sh "docker save -o ${IMAGE_NAME}.tar ${IMAGE_NAME}:${IMAGE_TAG}" + } + } + + stage('文件传输') { + steps { + echo "传输文件到目标服务器" + sh "${SSH_CMD} 'mkdir -p ${REMOTE_DIR}'" + sh "${SCP_CMD} ${IMAGE_NAME}.tar ${DEPLOY_USER}@${DEPLOY_HOST}:${REMOTE_DIR}/" + sh "${SCP_CMD} docker-compose.yml ${DEPLOY_USER}@${DEPLOY_HOST}:${REMOTE_DIR}/docker-compose.yml" + } + } + + stage('部署') { + steps { + script { + // 加载镜像 + sh "${SSH_CMD} 'docker load < ${REMOTE_DIR}/${IMAGE_NAME}.tar'" + + // 停掉旧容器 + sh "${SSH_CMD} 'cd ${REMOTE_DIR} && docker compose down || true'" + + // 启动新容器 + sh "${SSH_CMD} 'cd ${REMOTE_DIR} && docker compose up -d'" + + // 等待启动 + sh 'sleep 5' + + // 检查容器是否在运行 + sh "${SSH_CMD} 'docker ps -f name=${CONTAINER_NAME} --format \"{{.Status}}\"'" + } + } + } + + stage('清理') { + steps { + sh "${SSH_CMD} 'rm -f ${REMOTE_DIR}/${IMAGE_NAME}.tar'" + sh "rm -f ${IMAGE_NAME}.tar" + } + } + } + + post { + success { + echo "✅ 部署成功!容器 ${CONTAINER_NAME} 已启动" + } + failure { + echo '❌ 部署失败,请检查日志' + sh "rm -f ${IMAGE_NAME}.tar || true" + } + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..83a1cb8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + cleaner: + build: . + container_name: offerpie-job-cleaner + restart: unless-stopped + environment: + - ENV=prod + - TZ=Asia/Shanghai + volumes: + - ./logs:/app/logs + deploy: + resources: + limits: + memory: 1G + cpus: '2'