refactor: 彻底移除 docker compose,改用纯 docker 构建+重启部署
All checks were successful
Build and Deploy / build (push) Successful in 12s
Build and Deploy / deploy (push) Successful in 26s

This commit is contained in:
cheney 2026-09-01 10:27:11 +08:00
parent e11814048c
commit a5c5d24083
7 changed files with 53 additions and 83 deletions

View File

@ -3,27 +3,36 @@ name: Build and Deploy
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build Docker image
run: |
docker build -t awesome-index:latest .
deploy:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Copy files to server
- name: Copy scripts to server
uses: appleboy/scp-action@master
with:
host: 114.134.187.170
username: root
password: ${{ secrets.SERVER_PASSWORD }}
source: "package.json,package-lock.json,src,public,.env.example,start.sh"
source: "start.sh,.env.example"
target: "/app/awesome/"
- name: Deploy and start service
- name: Restart container
uses: appleboy/ssh-action@master
with:
host: 114.134.187.170
@ -31,10 +40,5 @@ jobs:
password: ${{ secrets.SERVER_PASSWORD }}
script: |
cd /app/awesome
# 如不存在 .env 则从 example 复制
[ ! -f .env ] && cp .env.example .env
# 执行启动脚本
chmod +x start.sh
bash start.sh

30
Jenkinsfile vendored
View File

@ -3,7 +3,6 @@ pipeline {
environment {
IMAGE_NAME = 'awesome-index'
CONTAINER_NAME = 'awesome'
DEPLOY_PATH = '/app/awesome'
SSH_HOST = '114.134.187.170'
SSH_USER = 'root'
@ -13,9 +12,8 @@ pipeline {
stage('Build') {
steps {
script {
echo "Building Docker image ${IMAGE_NAME}:${BUILD_NUMBER}"
sh "docker build -t ${IMAGE_NAME}:${BUILD_NUMBER} ."
sh "docker tag ${IMAGE_NAME}:${BUILD_NUMBER} ${IMAGE_NAME}:latest"
echo "Building Docker image ${IMAGE_NAME}:latest"
sh "docker build -t ${IMAGE_NAME}:latest ."
}
}
}
@ -29,28 +27,12 @@ pipeline {
// 创建部署目录
sh "sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${remote} 'mkdir -p ${DEPLOY_PATH}/data ${DEPLOY_PATH}/logs'"
// 复制必要文件
sh "sshpass -p '${SSH_PASS}' scp -o StrictHostKeyChecking=no docker-compose.yml ${remote}:${DEPLOY_PATH}/"
sh "sshpass -p '${SSH_PASS}' scp -o StrictHostKeyChecking=no .env.example ${remote}:${DEPLOY_PATH}/.env"
// 上传脚本(构建机 = 部署机,镜像已在服务器上,无需传输镜像)
sh "sshpass -p '${SSH_PASS}' scp -o StrictHostKeyChecking=no .env.example ${remote}:${DEPLOY_PATH}/.env.example"
sh "sshpass -p '${SSH_PASS}' scp -o StrictHostKeyChecking=no start.sh ${remote}:${DEPLOY_PATH}/"
// 导入镜像
sh "docker save ${IMAGE_NAME}:latest | gzip > ${IMAGE_NAME}.tar.gz"
sh "sshpass -p '${SSH_PASS}' scp -o StrictHostKeyChecking=no ${IMAGE_NAME}.tar.gz ${remote}:${DEPLOY_PATH}/"
// 在服务器上加载并重启
sh """
sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${remote} '
cd ${DEPLOY_PATH} &&
gunzip -c ${IMAGE_NAME}.tar.gz | docker load &&
rm -f ${IMAGE_NAME}.tar.gz &&
docker compose down --remove-orphans &&
docker compose up -d
'
"""
// 清理本地
sh "rm -f ${IMAGE_NAME}.tar.gz"
// 在服务器上重启容器
sh "sshpass -p '${SSH_PASS}' ssh -o StrictHostKeyChecking=no ${remote} 'cd ${DEPLOY_PATH} && chmod +x start.sh && bash start.sh'"
}
}
}

View File

@ -21,11 +21,11 @@ npm test # node:test10 个用例
### Docker 部署
```bash
cp .env.example .env # 修改 SESSION_SECRET / ADMIN_INIT_PASSWORD / AI_INGEST_KEY
docker compose up -d --build
docker build -t awesome-index:latest .
bash start.sh # 用新镜像重启容器
```
数据持久化在宿主机 `./data/awesome.duckdb`升级镜像不丢数据。
`start.sh` 会检查 `.env`(不存在则从 `.env.example` 复制),然后 `docker run` 启动容器。数据持久化在宿主机 `./data/awesome.duckdb`重启不丢数据。
## 给人的入口

View File

@ -1,5 +1,5 @@
#!/bin/bash
# Awesome Index 部署脚本(直接部署,不使用 Docker
# Awesome Index 部署脚本(构建机 = 部署机本地构建镜像SSH 重启容器
# 服务器: 114.134.187.170
set -e
@ -19,20 +19,15 @@ if ! command -v sshpass &> /dev/null; then
exit 1
fi
echo "1. 创建部署目录..."
sshpass -p "$REMOTE_PASS" ssh -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" \
"mkdir -p $DEPLOY_PATH/data $DEPLOY_PATH/logs"
echo "1. 构建 Docker 镜像..."
docker build -t awesome-index:latest .
echo "2. 上传源码..."
sshpass -p "$REMOTE_PASS" scp -o StrictHostKeyChecking=no -r \
package.json package-lock.json src public .env.example start.sh \
echo "2. 上传脚本到服务器..."
sshpass -p "$REMOTE_PASS" scp -o StrictHostKeyChecking=no \
start.sh .env.example \
"$REMOTE_USER@$REMOTE_HOST:$DEPLOY_PATH/"
echo "3. 重命名 .env.example 为 .env如不存在..."
sshpass -p "$REMOTE_PASS" ssh -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" \
"cd $DEPLOY_PATH && [ ! -f .env ] && cp .env.example .env"
echo "4. 在服务器上执行启动脚本..."
echo "3. 在服务器上重启容器..."
sshpass -p "$REMOTE_PASS" ssh -o StrictHostKeyChecking=no "$REMOTE_USER@$REMOTE_HOST" \
"cd $DEPLOY_PATH && chmod +x start.sh && bash start.sh"

View File

@ -1,16 +0,0 @@
services:
web:
build: .
container_name: awesome-index
ports:
- "3000:3000"
volumes:
- ./data:/app/data
environment:
PORT: "3000"
DUCKDB_PATH: /app/data/awesome.duckdb
SESSION_SECRET: ${SESSION_SECRET:-change-me-in-production}
ADMIN_INIT_PASSWORD: ${ADMIN_INIT_PASSWORD:-admin}
AI_INGEST_KEY: ${AI_INGEST_KEY:-}
BASE_URL: ${BASE_URL:-http://localhost:3000}
restart: unless-stopped

View File

@ -58,8 +58,8 @@
```
awesome/
├── package.json # 依赖与 scriptsdev / start / test / migrate
├── Dockerfile # 多阶段构建node:22-alpine
├── docker-compose.yml # 单服务编排 + data 卷 + healthcheck
├── Dockerfile # 多阶段构建node:22-bookworm-slim
├── start.sh # 用已构建镜像重启容器docker run无 compose
├── .env.example # 配置样例
├── .gitignore # node_modules / data / .env

View File

@ -1,32 +1,38 @@
#!/bin/bash
set -e
# Awesome Index 启动脚本(直接部署,不使用 Docker
# Awesome Index 重启脚本(使用已构建的镜像,纯 docker run无 compose
DEPLOY_PATH="$(cd "$(dirname "$0")" && pwd)"
cd "$DEPLOY_PATH"
# 检查 .env 文件
if [ ! -f .env ]; then
echo "错误: 缺少 .env 文件,请从 .env.example 复制并修改"
exit 1
if [ -f .env.example ]; then
cp .env.example .env
echo "已从 .env.example 创建 .env请检查 SESSION_SECRET / ADMIN_INIT_PASSWORD / AI_INGEST_KEY"
else
echo "错误: 缺少 .env 文件"
exit 1
fi
fi
# 安装依赖
echo "安装依赖..."
npm ci --omit=dev --no-audit --no-fund
# 停止并删除旧容器
echo "停止旧容器..."
docker rm -f awesome-index 2>/dev/null || true
# 停止旧进程
echo "停止旧进程..."
pkill -f "node src/index.js" 2>/dev/null || true
sleep 1
# 启动服务
# 用新镜像启动容器
echo "启动 Awesome Index..."
nohup node src/index.js > logs/app.log 2>&1 &
docker run -d \
--name awesome-index \
--restart unless-stopped \
-p 3000:3000 \
-v "$DEPLOY_PATH/data:/app/data" \
--env-file .env \
awesome-index:latest
# 健康检查
echo "等待服务就绪..."
sleep 2
sleep 5
MAX_RETRIES=10
RETRY_COUNT=0
@ -35,12 +41,11 @@ while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
echo "✓ 服务已启动: http://localhost:3000"
echo ""
echo "管理后台: http://localhost:3000/admin"
echo "默认账号: admin / (见 .env 中的 ADMIN_INIT_PASSWORD)"
exit 0
fi
RETRY_COUNT=$((RETRY_COUNT + 1))
sleep 2
done
echo "✗ 服务启动失败,请检查日志: tail -50 logs/app.log"
echo "✗ 服务启动失败,请检查日志: docker logs awesome-index"
exit 1