Skip to content

Commit 1941713

Browse files
committed
make Dokploy happy
1 parent 90f412c commit 1941713

5 files changed

Lines changed: 100 additions & 57 deletions

File tree

docker-compose.build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ services:
44
context: ./server
55
environment:
66
# 基础配置 - 必需
7-
- POSTGRESQL_URL=postgresql://prisma:${POSTGRES_PASSWORD:-rote_password_123}@postgres:5432/rote
7+
- POSTGRESQL_URL=postgresql://prisma:${POSTGRES_PASSWORD:-rote_password_123}@rote-postgres:5432/rote
88
ports:
99
- "3000:3000"
1010
depends_on:
11-
- postgres
11+
- rote-postgres
1212
restart: unless-stopped
1313

1414
rote-frontend:
@@ -26,7 +26,7 @@ services:
2626
# 运行时环境变量,用于启动脚本注入配置
2727
- VITE_API_BASE=${VITE_API_BASE:-http://localhost:3000}
2828
restart: unless-stopped
29-
postgres:
29+
rote-postgres:
3030
image: postgres:17
3131
container_name: rote-postgres
3232
restart: unless-stopped

docker-compose.yml

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,48 +17,33 @@ services:
1717
container_name: rote-backend
1818
environment:
1919
# 基础配置 - 必需
20-
- POSTGRESQL_URL=postgresql://prisma:${POSTGRES_PASSWORD:-rote_password_123}@postgres:5432/rote
20+
- POSTGRESQL_URL=postgresql://prisma:${POSTGRES_PASSWORD:-rote_password_123}@rote-postgres:5432/rote
2121
ports:
22-
- "3000:3000"
22+
- "3000"
2323
depends_on:
24-
postgres:
24+
rote-postgres:
2525
condition: service_healthy
26-
healthcheck:
27-
test:
28-
[
29-
"CMD-SHELL",
30-
'node -e "require(''http'').get(''http://localhost:3000/v2/api/health'', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)}).on(''error'', () => process.exit(1))" || exit 1',
31-
]
32-
interval: 10s
33-
timeout: 5s
34-
retries: 5
35-
start_period: 30s
3626
restart: unless-stopped
27+
command: ["sh", "-c", "sleep 15 && npx prisma db push && npm start"]
28+
3729

3830
rote-frontend:
3931
image: rabithua/rote-frontend:${IMAGE_TAG:-latest}
4032
container_name: rote-frontend
4133
ports:
42-
- "3001:3001"
34+
- "3001"
4335
depends_on:
44-
rote-backend:
45-
condition: service_healthy
36+
- rote-backend
4637
environment:
4738
- VITE_API_BASE=${VITE_API_BASE:-http://localhost:3000}
48-
healthcheck:
49-
test: ["CMD-SHELL", "curl -f http://localhost:3001 || exit 1"]
50-
interval: 10s
51-
timeout: 5s
52-
retries: 5
53-
start_period: 10s
5439
restart: unless-stopped
5540

56-
postgres:
41+
rote-postgres:
5742
image: postgres:17
5843
container_name: rote-postgres
5944
restart: unless-stopped
6045
ports:
61-
- "5432:5432"
46+
- "5432"
6247
environment:
6348
POSTGRES_USER: prisma
6449
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-rote_password_123}
@@ -67,10 +52,15 @@ services:
6752
- rote-postgres-data:/var/lib/postgresql/data
6853
healthcheck:
6954
test: ["CMD-SHELL", "pg_isready -U prisma -d rote"]
70-
interval: 10s
71-
timeout: 5s
72-
retries: 5
73-
start_period: 10s
55+
interval: 5s
56+
timeout: 3s
57+
retries: 10
58+
start_period: 30s
7459

7560
volumes:
7661
rote-postgres-data:
62+
63+
networks:
64+
default:
65+
name: rote-network
66+
driver: bridge

server/Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ RUN npm install --silent
77
COPY . .
88
RUN npx prisma generate
99
EXPOSE 3000
10+
11+
# 💡 修正点:以 root 身份安装 netcat,供后续动态等待使用
12+
RUN apk add --no-cache netcat-openbsd
13+
1014
RUN chown -R node /usr/src
1115
USER node
1216
CMD ["sh", "-c", "npx prisma db push && npm start"]

server/server.ts

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from './utils/config';
1414
import { errorHandler } from './utils/handlers';
1515
import { injectDynamicUrls } from './utils/main';
16+
import { waitForDatabase } from './utils/prisma';
1617
import { recorderIpAndTime } from './utils/recoder';
1718
import { StartupMigration } from './utils/startupMigration';
1819

@@ -124,23 +125,35 @@ app.use((req, res) => {
124125
});
125126
});
126127

127-
app.listen(port, async () => {
128-
console.log(`Rote Node backend server listening on port ${port}!`);
129-
128+
// 启动服务器前等待数据库就绪
129+
(async () => {
130130
try {
131-
// 初始化配置管理器
132-
await initializeConfig();
131+
// 等待数据库连接就绪
132+
await waitForDatabase();
133+
134+
// 启动服务器
135+
app.listen(port, async () => {
136+
console.log(`Rote Node backend server listening on port ${port}!`);
137+
138+
try {
139+
// 初始化配置管理器
140+
await initializeConfig();
133141

134-
// 配置管理器初始化后,重新初始化 CORS 配置(从数据库读取)
135-
initializeCorsConfig();
142+
// 配置管理器初始化后,重新初始化 CORS 配置(从数据库读取)
143+
initializeCorsConfig();
136144

137-
// 验证关键配置是否正确加载
138-
validateSystemConfiguration();
145+
// 验证关键配置是否正确加载
146+
validateSystemConfiguration();
139147

140-
// 启动时检查系统状态
141-
await StartupMigration.checkStartupStatus();
142-
await StartupMigration.showConfigStatus();
148+
// 启动时检查系统状态
149+
await StartupMigration.checkStartupStatus();
150+
await StartupMigration.showConfigStatus();
151+
} catch (error) {
152+
console.error('❌ Failed to initialize system:', error);
153+
}
154+
});
143155
} catch (error) {
144-
console.error('❌ Failed to initialize system:', error);
156+
console.error('❌ Failed to start server:', error);
157+
process.exit(1);
145158
}
146-
});
159+
})();

server/utils/prisma.ts

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const prisma = new PrismaClient({
55
{ level: "warn", emit: "event" },
66
{ level: "info", emit: "event" },
77
{ level: "error", emit: "event" },
8-
],
8+
},
99
});
1010

1111
prisma.$on("warn", (e) => {
@@ -20,17 +20,53 @@ prisma.$on("error", (e) => {
2020
// console.log("Prisma Error:", e);
2121
});
2222

23-
// Check if Prisma connection is successful
24-
(async () => {
25-
try {
26-
console.log("Checking Prisma connection...");
27-
await prisma.$connect();
28-
await prisma.rote.findFirst();
29-
console.log("Prisma connected successfully!");
30-
} catch (error) {
31-
console.info("Failed to connect to Prisma.", error);
32-
process.exit(1); // 如果连接失败,终止进程
23+
/**
24+
* 等待数据库连接就绪,带重试机制
25+
* @param maxRetries 最大重试次数,默认 30 次
26+
* @param retryDelay 重试延迟(毫秒),默认 2 秒
27+
*/
28+
export async function waitForDatabase(
29+
maxRetries: number = 30,
30+
retryDelay: number = 2000
31+
): Promise<void> {
32+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
33+
try {
34+
console.log(`🔄 Attempting to connect to database (${attempt}/${maxRetries})...`);
35+
36+
// 如果之前有连接尝试,先断开
37+
try {
38+
await prisma.$disconnect();
39+
} catch {
40+
// 忽略断开连接的错误
41+
}
42+
43+
// 尝试连接
44+
await prisma.$connect();
45+
46+
// 尝试执行一个简单的查询来验证连接
47+
await prisma.$queryRaw`SELECT 1`;
48+
console.log("✅ Prisma connected successfully!");
49+
return;
50+
} catch (error: any) {
51+
// 确保在错误时断开连接
52+
try {
53+
await prisma.$disconnect();
54+
} catch {
55+
// 忽略断开连接的错误
56+
}
57+
58+
if (attempt === maxRetries) {
59+
console.error("❌ Failed to connect to database after all retries:", error);
60+
throw new Error(
61+
`Database connection failed after ${maxRetries} attempts. Please check your database configuration. Error: ${error?.message || error}`
62+
);
63+
}
64+
console.log(
65+
`⏳ Database not ready yet, retrying in ${retryDelay / 1000}s... (${attempt}/${maxRetries})`
66+
);
67+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
68+
}
3369
}
34-
})();
70+
}
3571

3672
export default prisma;

0 commit comments

Comments
 (0)