Skip to content

Commit b3aa377

Browse files
committed
fix: improve Docker build process and fix postgres package issue
- Fix Dockerfile cleanup logic to prevent deletion of critical dependencies (postgres, drizzle-orm) - Test and verify docker-compose.build.yml build workflow - Remove duplicate drizzle.config.js file, keep only drizzle.config.ts - Add programmatic database migration script (runMigrations.ts) - Update docker-compose.build.yml with correct startup commands - All services now build and run successfully
1 parent a87b4fb commit b3aa377

7 files changed

Lines changed: 106 additions & 24 deletions

File tree

docker-compose.build.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ services:
1313
condition: service_healthy
1414
restart: unless-stopped
1515
# 启动命令:等待数据库就绪后执行数据库迁移并启动服务
16-
command:
17-
["sh", "-c", "sleep 15 && bun run db:migrate && bun run dist/server.js"]
16+
command: ["sh", "-c", "sleep 15 && bun run dist/server.js"]
1817

1918
rote-frontend:
2019
build:

server/.dockerignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ LICENSE*
6666
jest.config.*
6767
vitest.config.*
6868

69-
# 脚本文件(运行时不需要)
70-
scripts
69+
# 脚本文件(运行时不需要,但保留迁移脚本)
70+
scripts/*
71+
!scripts/runMigrations.ts
7172
*.sh

server/Dockerfile

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,29 +43,46 @@ RUN addgroup --system --gid 1001 nodejs && \
4343
COPY --from=builder --chown=bunuser:nodejs /app/package.json ./
4444
COPY --from=builder --chown=bunuser:nodejs /app/bun.lock* ./
4545

46-
# 🚨 关键优化:在 runner 阶段重新安装生产依赖
47-
# 这样可以确保完全没有 devDependencies,并且只安装运行时需要的包
46+
# 🚨 关键优化:只安装生产依赖(已改用程序化迁移,不需要 drizzle-kit)
4847
RUN bun install --production --frozen-lockfile
4948

50-
# 从 builder 阶段复制编译后的代码
49+
# 从 builder 阶段复制编译后的代码和迁移文件
5150
COPY --from=builder --chown=bunuser:nodejs /app/dist ./dist
52-
53-
# 🔥 终极清理:删除所有不必要的文件
54-
RUN rm -rf /app/node_modules/.cache && \
55-
rm -rf /tmp/* && \
56-
rm -rf /var/cache/apk/* && \
57-
# 🚨 强制删除 TypeScript 及其相关包(生产环境不需要)
58-
rm -rf /app/node_modules/typescript && \
59-
rm -rf /app/node_modules/@typescript-eslint && \
60-
rm -rf /app/node_modules/typescript-eslint && \
61-
# 删除测试相关目录
62-
find /app/node_modules -type d \( -name "test" -o -name "tests" -o -name "__tests__" -o -name "*.test.*" -o -name "*.spec.*" -o -name "docs" -o -name "doc" -o -name "examples" -o -name "example" -o -name "benchmark" -o -name "benchmarks" \) -exec rm -rf {} + 2>/dev/null || true && \
63-
# 删除文档和配置文件
64-
find /app/node_modules -type f \( -name "*.md" -o -name "*.map" -o -name "CHANGELOG*" -o -name "LICENSE*" -o -name "README*" -o -name "*.ts" -o -name "*.tsx" -o -name "*.json" ! -name "package.json" \) ! -path "*/node_modules/@types/*" -delete 2>/dev/null || true && \
65-
# 删除类型定义文件(运行时不需要)
66-
find /app/node_modules -type f -name "*.d.ts" ! -path "*/node_modules/@types/*" -delete 2>/dev/null || true && \
67-
# 删除源码文件(只保留编译后的代码)
68-
find /app/node_modules -type f \( -name "*.js" ! -name "*.min.js" \) -path "*/src/*" -delete 2>/dev/null || true
51+
COPY --from=builder --chown=bunuser:nodejs /app/drizzle ./drizzle
52+
53+
# 🔥 终极清理:删除所有不必要的文件以减小镜像大小
54+
# 注意:避免删除关键依赖包(如 postgres)的必要文件
55+
RUN rm -rf /app/node_modules/.cache /tmp/* /var/cache/apk/* && \
56+
# 删除测试、文档、示例等目录(排除关键依赖包)
57+
find /app/node_modules -type d \( \
58+
-name "test" -o -name "tests" -o -name "__tests__" -o \
59+
-name "*.test.*" -o -name "*.spec.*" -o \
60+
-name "docs" -o -name "doc" -o \
61+
-name "examples" -o -name "example" -o \
62+
-name "benchmark" -o -name "benchmarks" \
63+
\) ! -path "*/node_modules/postgres/*" \
64+
! -path "*/node_modules/drizzle-orm/*" \
65+
-exec rm -rf {} + 2>/dev/null || true && \
66+
# 删除文档、源码映射等(排除关键依赖包)
67+
find /app/node_modules -type f \( \
68+
-name "*.md" -o -name "*.map" -o \
69+
-name "CHANGELOG*" -o -name "LICENSE*" -o -name "README*" \
70+
\) ! -path "*/node_modules/postgres/*" \
71+
! -path "*/node_modules/drizzle-orm/*" \
72+
-delete 2>/dev/null || true && \
73+
# 删除 TypeScript 源文件(但保留 .d.ts 类型定义文件,某些包可能需要)
74+
find /app/node_modules -type f \( \
75+
-name "*.ts" -o -name "*.tsx" \
76+
\) ! -name "*.d.ts" \
77+
! -path "*/node_modules/@types/*" \
78+
! -path "*/node_modules/postgres/*" \
79+
! -path "*/node_modules/drizzle-orm/*" \
80+
-delete 2>/dev/null || true && \
81+
# 删除 package.json 以外的 JSON 配置文件(排除关键依赖包)
82+
find /app/node_modules -type f -name "*.json" ! -name "package.json" ! -path "*/node_modules/@types/*" \
83+
! -path "*/node_modules/postgres/*" \
84+
! -path "*/node_modules/drizzle-orm/*" \
85+
-delete 2>/dev/null || true
6986

7087
# 设置环境变量,提升性能
7188
ENV NODE_ENV=production

server/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"lint:fix": "eslint . --fix",
2020
"db:generate": "drizzle-kit generate",
2121
"db:migrate": "drizzle-kit migrate",
22+
"db:migrate:programmatic": "bun run scripts/runMigrations.ts",
2223
"db:push": "drizzle-kit push",
2324
"db:studio": "drizzle-kit studio"
2425
},

server/scripts/runMigrations.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* 程序化运行数据库迁移
3+
* 使用 drizzle-orm 的 migrate 函数,不依赖 drizzle-kit CLI
4+
*/
5+
import { drizzle } from 'drizzle-orm/postgres-js';
6+
import { migrate } from 'drizzle-orm/postgres-js/migrator';
7+
import postgres from 'postgres';
8+
import * as schema from '../drizzle/schema';
9+
10+
const connectionString = process.env.POSTGRESQL_URL || '';
11+
12+
if (!connectionString) {
13+
console.error('❌ POSTGRESQL_URL environment variable is not set');
14+
process.exit(1);
15+
}
16+
17+
async function runMigrations() {
18+
try {
19+
console.log('🔄 Starting database migrations...');
20+
console.log(`📝 Database URL: ${connectionString.replace(/:[^:@]+@/, ':****@')}`);
21+
22+
// 创建 postgres 客户端
23+
const queryClient = postgres(connectionString, {
24+
max: 1, // 迁移时只需要一个连接
25+
idle_timeout: 20,
26+
connect_timeout: 10,
27+
});
28+
29+
// 创建 Drizzle 实例
30+
const db = drizzle(queryClient, { schema });
31+
32+
// 运行迁移
33+
await migrate(db, { migrationsFolder: './drizzle/migrations' });
34+
35+
console.log('✅ Database migrations completed successfully!');
36+
37+
// 关闭连接
38+
await queryClient.end();
39+
} catch (error: any) {
40+
console.error('❌ Migration failed:', error);
41+
process.exit(1);
42+
}
43+
}
44+
45+
runMigrations();

server/server.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ subscribeConfigChange('site', (_group, newConfig) => {
118118
// 等待数据库连接就绪
119119
await waitForDatabase();
120120

121+
// 运行数据库迁移
122+
const { runMigrations } = await import('./utils/drizzle');
123+
await runMigrations();
124+
121125
// 初始化配置管理器
122126
await initializeConfig();
123127

server/utils/drizzle.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@ export async function waitForDatabase(
5454
}
5555
}
5656

57+
/**
58+
* 运行数据库迁移
59+
*/
60+
export async function runMigrations(): Promise<void> {
61+
try {
62+
console.log('🔄 Running database migrations...');
63+
const { migrate } = await import('drizzle-orm/postgres-js/migrator');
64+
await migrate(db, { migrationsFolder: './drizzle/migrations' });
65+
console.log('✅ Database migrations completed successfully!');
66+
} catch (error: any) {
67+
console.error('❌ Migration failed:', error);
68+
throw error;
69+
}
70+
}
71+
5772
/**
5873
* 关闭数据库连接
5974
*/

0 commit comments

Comments
 (0)