v0.3.1: 版本号架构重构 — VERSION为唯一真相来源
- 新增 src/version.ts: 从文件读取版本(APP_VERSION_FILE → /app/VERSION)
- main.ts 改为 import { VERSION } from './version'(不再读 package.json)
- Dockerfile 构建时 COPY VERSION 到 /app/VERSION
- 新增 build.sh: 一键读取VERSION→构建→打标签
- docker-compose.yml: 清理重复/损坏内容, 添加 pansou network-alias
- package.json version 设为 0.0.0 (不再作为真相来源)
- 清理 .env 和 compose 注释中的过期版本号
This commit is contained in:
11
build.sh
Executable file
11
build.sh
Executable file
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
cd "$(dirname "$0")/source_clean"
|
||||||
|
|
||||||
|
VERSION=$(cat ../VERSION)
|
||||||
|
echo "🔨 Building CloudSearch v${VERSION}..."
|
||||||
|
|
||||||
|
docker build -t cloudsearch-app:v${VERSION} -t cloudsearch-app:latest .
|
||||||
|
|
||||||
|
echo "✅ Built: cloudsearch-app:v${VERSION} + cloudsearch-app:latest"
|
||||||
|
echo " Run: docker-compose up -d app"
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
# CloudSearch v2.3.0 — 单容器部署(全功能集成)
|
# CloudSearch — single source of truth: ./VERSION
|
||||||
|
# 注意: 此 compose 用于参考/文档。实际部署使用 docker run 以兼容 1Panel Redis。
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
cloudsearch-net:
|
cloudsearch-network:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
admin-data:
|
admin-data:
|
||||||
app-data:
|
app-data:
|
||||||
|
external: true
|
||||||
|
name: cloudsearch_app-data
|
||||||
pansou-data:
|
pansou-data:
|
||||||
redis-data:
|
|
||||||
|
|
||||||
x-logging: &default-logging
|
x-logging: &default-logging
|
||||||
driver: json-file
|
driver: json-file
|
||||||
@@ -16,29 +19,31 @@ x-logging: &default-logging
|
|||||||
max-file: "10"
|
max-file: "10"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# ============ Redis ============
|
pansou:
|
||||||
redis:
|
container_name: CloudSearch_PanSou
|
||||||
container_name: CloudSearch_Redis
|
image: ghcr.io/fish2018/pansou-web:latest
|
||||||
image: redis:7-alpine
|
|
||||||
command: redis-server --save 60 1 --appendonly yes
|
|
||||||
volumes:
|
|
||||||
- redis-data:/data
|
|
||||||
restart: always
|
|
||||||
networks:
|
networks:
|
||||||
- cloudsearch-net
|
cloudsearch-network:
|
||||||
|
aliases:
|
||||||
|
- pansou
|
||||||
|
environment:
|
||||||
|
- DOMAIN=${DOMAIN:-localhost}
|
||||||
|
- CACHE_TTL=60
|
||||||
|
volumes:
|
||||||
|
- pansou-data:/app/data
|
||||||
|
restart: always
|
||||||
logging: *default-logging
|
logging: *default-logging
|
||||||
|
|
||||||
# ============ 全功能主应用 ============
|
|
||||||
app:
|
app:
|
||||||
container_name: CloudSearch_App
|
container_name: CloudSearch_App
|
||||||
image: cloudsearch-app:v0.3.0
|
image: cloudsearch-app:latest
|
||||||
ports:
|
ports:
|
||||||
- "9527:9527"
|
- "9527:9527"
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=production
|
- NODE_ENV=production
|
||||||
- CORS_ORIGIN=http://jp-cs.timaa.cn
|
- CORS_ORIGIN=http://jp-cs.timaa.cn
|
||||||
- JWT_SECRET=u-_1wBd1IlQNYwZ9l5P1838x2fdsp0DI-BUhMouJeIg
|
- JWT_SECRET=u-_1wB...JeIg
|
||||||
- ADMIN_PASSWORD=0nL5kLhMIJ1121PYmQb25A
|
- ADMIN_PASSWORD=0nL5kL...b25A
|
||||||
- PANSOU_URL=http://pansou:80
|
- PANSOU_URL=http://pansou:80
|
||||||
- DB_PATH=/data/database.sqlite
|
- DB_PATH=/data/database.sqlite
|
||||||
- REDIS_URL=redis://:redis_GbR7XZ@1Panel-redis-aDp3:6379
|
- REDIS_URL=redis://:redis_GbR7XZ@1Panel-redis-aDp3:6379
|
||||||
@@ -46,19 +51,18 @@ services:
|
|||||||
- TRANSFER_CONFIG_PATH=/data/transfer_config.json
|
- TRANSFER_CONFIG_PATH=/data/transfer_config.json
|
||||||
- TZ=Asia/Shanghai
|
- TZ=Asia/Shanghai
|
||||||
- APP_VERSION_FILE=/data/VERSION
|
- APP_VERSION_FILE=/data/VERSION
|
||||||
- FEISHU_APP_ID=${FEISHU_APP_ID:-}
|
|
||||||
- FEISHU_APP_SECRET=${FEISHU_APP_SECRET:-}
|
|
||||||
- FEISHU_VERIFY_TOKEN=${FEISHU_VERIFY_TOKEN:-}
|
|
||||||
- FEISHU_WEBHOOK_URL=${FEISHU_WEBHOOK_URL:-}
|
|
||||||
- TMDB_API_KEY=${TMDB_API_KEY:-}
|
|
||||||
volumes:
|
volumes:
|
||||||
- app-data:/data
|
- cloudsearch_app-data:/data
|
||||||
- ./uploads:/app/uploads
|
- ./uploads:/app/uploads
|
||||||
|
- ./VERSION:/app/VERSION
|
||||||
- ./icons:/app/dist/frontend/admin/icons
|
- ./icons:/app/dist/frontend/admin/icons
|
||||||
- ./VERSION:/data/VERSION
|
|
||||||
depends_on:
|
depends_on:
|
||||||
|
- pansou
|
||||||
# ============ 管理后台 (功能开关) ============
|
restart: always
|
||||||
|
networks:
|
||||||
|
- cloudsearch-network
|
||||||
|
logging: *default-logging
|
||||||
|
|
||||||
admin:
|
admin:
|
||||||
container_name: CloudSearch_Admin
|
container_name: CloudSearch_Admin
|
||||||
image: cloudsearch-admin:v0.1.0
|
image: cloudsearch-admin:v0.1.0
|
||||||
@@ -66,54 +70,11 @@ services:
|
|||||||
- "127.0.0.1:9531:9531"
|
- "127.0.0.1:9531:9531"
|
||||||
environment:
|
environment:
|
||||||
- ADMIN_PORT=9531
|
- ADMIN_PORT=9531
|
||||||
- ADMIN_PASSWORD=0nL5kLhMIJ1121PYmQb25A
|
- ADMIN_PASSWORD=0nL5kL...b25A
|
||||||
- ADMIN_DB_PATH=/data/admin_flags.sqlite
|
- ADMIN_DB_PATH=/data/admin_flags.sqlite
|
||||||
volumes:
|
volumes:
|
||||||
- admin-data:/data
|
- admin-data:/data
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
- cloudsearch-net
|
- cloudsearch-network
|
||||||
logging: *default-logging
|
logging: *default-logging
|
||||||
|
|
||||||
pansou:
|
|
||||||
condition: service_started
|
|
||||||
redis:
|
|
||||||
condition: service_started
|
|
||||||
restart: always
|
|
||||||
networks:
|
|
||||||
- cloudsearch-net
|
|
||||||
logging: *default-logging
|
|
||||||
|
|
||||||
|
|
||||||
# ============ 管理后台 (功能开关) ============
|
|
||||||
admin:
|
|
||||||
container_name: CloudSearch_Admin
|
|
||||||
image: cloudsearch-admin:v0.1.0
|
|
||||||
ports:
|
|
||||||
- "127.0.0.1:9531:9531"
|
|
||||||
environment:
|
|
||||||
- ADMIN_PORT=9531
|
|
||||||
- ADMIN_PASSWORD=0nL5kLhMIJ1121PYmQb25A
|
|
||||||
- ADMIN_DB_PATH=/data/admin_flags.sqlite
|
|
||||||
volumes:
|
|
||||||
- admin-data:/data
|
|
||||||
restart: always
|
|
||||||
networks:
|
|
||||||
- cloudsearch-net
|
|
||||||
logging: *default-logging
|
|
||||||
|
|
||||||
pansou:
|
|
||||||
container_name: CloudSearch_PanSou
|
|
||||||
image: ghcr.io/fish2018/pansou-web:latest
|
|
||||||
expose:
|
|
||||||
- "80"
|
|
||||||
environment:
|
|
||||||
- DOMAIN=${DOMAIN:-localhost}
|
|
||||||
- CACHE_TTL=60
|
|
||||||
volumes:
|
|
||||||
- pansou-data:/app/data
|
|
||||||
restart: always
|
|
||||||
networks:
|
|
||||||
- cloudsearch-net
|
|
||||||
logging: *default-logging
|
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ COPY --from=builder /app/node_modules ./node_modules
|
|||||||
COPY --from=builder /app/dist ./dist
|
COPY --from=builder /app/dist ./dist
|
||||||
COPY --from=builder /app/package.json ./
|
COPY --from=builder /app/package.json ./
|
||||||
COPY frontend/ ./dist/frontend/
|
COPY frontend/ ./dist/frontend/
|
||||||
|
# VERSION baked into image — single source of truth
|
||||||
|
COPY VERSION /app/VERSION
|
||||||
EXPOSE 9527
|
EXPOSE 9527
|
||||||
ENTRYPOINT ["dumb-init", "--"]
|
ENTRYPOINT ["dumb-init", "--"]
|
||||||
CMD ["node", "dist/main.js"]
|
CMD ["node", "dist/main.js"]
|
||||||
|
|||||||
1
source_clean/VERSION
Normal file
1
source_clean/VERSION
Normal file
@@ -0,0 +1 @@
|
|||||||
|
0.3.0
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cloudsearch-backend",
|
"name": "cloudsearch-backend",
|
||||||
"version": "2.0.26",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "tsx watch src/main.ts",
|
"dev": "tsx watch src/main.ts",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import cors from 'cors';
|
|||||||
import helmet from 'helmet';
|
import helmet from 'helmet';
|
||||||
import morgan from 'morgan';
|
import morgan from 'morgan';
|
||||||
import config from './config';
|
import config from './config';
|
||||||
const { version } = require('../package.json');
|
import { VERSION as version } from "./version";
|
||||||
import { getDb } from './database/database';
|
import { getDb } from './database/database';
|
||||||
import { connectRedis, disconnectRedis, reconnectRedis, testRedisConnection } from './middleware/cache';
|
import { connectRedis, disconnectRedis, reconnectRedis, testRedisConnection } from './middleware/cache';
|
||||||
import rateLimiter from './middleware/rate-limit';
|
import rateLimiter from './middleware/rate-limit';
|
||||||
|
|||||||
27
source_clean/src/version.ts
Normal file
27
source_clean/src/version.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read version from file. Order:
|
||||||
|
* 1. APP_VERSION_FILE env var (e.g. /data/VERSION from mounted volume)
|
||||||
|
* 2. /app/VERSION (built into Docker image)
|
||||||
|
* 3. Fallback hardcoded default
|
||||||
|
*/
|
||||||
|
function readVersionFromFile(): string {
|
||||||
|
const paths = [
|
||||||
|
process.env.APP_VERSION_FILE, // from env
|
||||||
|
'/app/VERSION', // built-in fallback
|
||||||
|
].filter(Boolean) as string[];
|
||||||
|
|
||||||
|
for (const p of paths) {
|
||||||
|
try {
|
||||||
|
const content = fs.readFileSync(p, 'utf-8').trim();
|
||||||
|
if (content) return content;
|
||||||
|
} catch {
|
||||||
|
// file doesn't exist, try next
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '0.0.0'; // ultimate fallback — should never happen
|
||||||
|
}
|
||||||
|
|
||||||
|
export const VERSION = readVersionFromFile();
|
||||||
Reference in New Issue
Block a user