Bun.js+Express+PostgreSQL容器化后数据库请求挂起问题
Bun.js + Express + Drizzle ORM容器化部署后数据库请求挂起问题
我正在使用Bun.js结合Express框架与Drizzle ORM开发后端,并将后端与PostgreSQL数据库进行容器化部署。目前遇到数据库请求持续挂起的问题,且无任何错误提示——以登录接口为例,发起请求时仅打印了inside login 1,但未打印inside login 2,请求一直处于挂起状态未完成。
怀疑问题点:数据库重连逻辑
我怀疑问题出在数据库连接的重连逻辑上,相关代码如下:
const client = new Client({ connectionString: process.env.DB_URL!, }); let retry = 2; while (retry > 0) { try { await client.connect(); break; } catch (error) { if (retry < 0) { process.exit(1); } retry = retry - 1; console.log(error); console.log('Trying to connect db failed remaining attempts: ' + retry + ". Waiting for 2000ms"); await new Promise(res => setTimeout(res, 2000)); } } export const db = drizzle(client, { schema: { ...users, ...session, ...emailVarification, ...resetToken }, logger: true }); const app = express(); app.use(express.json()) app.use(protectionCSRF) app.use('/api/user', userRoute) app.get('/hello-world', (req, res) => { return res.status(200).json({ message: "Hello World!" }) }) app.listen(process.env.PORT, () => { console.log(process.env.DB_URL) console.log(`server running on http://localhost:${process.env.PORT}/api`); });
登录接口代码示例
登录接口的具体代码如下:
export const login = async ( req: Request<unknown, unknown, { email: string; password: string }>, res: Response<Res<{ email: string; name: string; id: string; email_verified: boolean }>> ) => { try { const validEmail = z.string().parse(req.body.email); const validPassword = z.string().parse(req.body.password); console.log('inside login 1'); const user = await db.query.userSchema.findFirst({ where: eq(userSchema.email, validEmail), }); console.log('inside login 2'); if (!user) { return res.status(404).json({ isSuccess: false, issues: [], message: "Invalid email or password", }); } const isValidPassword = await password.verify(user.password, validPassword, "argon2d"); if (!isValidPassword) { return res.status(404).json({ isSuccess: false, issues: [], message: "Invalid email or password", }); } const session = await lucia.createSession(user.id, { ip_country: "INDIA" }); const sessionCookie = lucia.createSessionCookie(session.id); res.set("Location", "/"); res.set("Set-Cookie", sessionCookie.serialize()); return res.status(200).json({ isSuccess: true, message: "User login success", result: { email: user.email, id: user.id, name: user.name, email_verified: !!user.email_verified, }, }); } catch (err: any) { if (err instanceof ZodError) { return res.status(400).json({ isSuccess: false, message: err.message, issues: err.issues, }); } return res.status(500).json({ isSuccess: false, message: err.message, issues: [], }); } };
Docker配置文件
Dockerfile
FROM oven/bun:1.1.8-alpine as development WORKDIR /usr/src/app COPY package.json . COPY bun.lockb . RUN bun install COPY . . # CMD [ "bun" ,"run", "dev" ] RUN bun run build FROM oven/bun:1.1.8-alpine as production ARG BUN_ENV=production ENV BUN_ENV=${BUN_ENV} WORKDIR /usr/src/app COPY package.json . COPY bun.lockb . RUN bun install --production COPY --from=development /usr/src/app/dist ./dist CMD [ "bun" , "run", "dist/index.js" ]
docker-compose.yml
version: '3.8' services: backend: env_file: - .env environment: - DB_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} container_name: auth_backend build: context: . dockerfile: Dockerfile target: development command: bun run dev #over-riding the default RUN bun run build command from docker file ports: - "${PORT}:${PORT}" depends_on: - db develop: watch: - action: sync path: ./src target: /usr/src/app/src - action: rebuild path: package.json db: image: postgres:16.3-alpine3.18 container_name: My_DB restart: unless-stopped volumes: # - .:/dev/shm - ~/db-data:/var/lib/postgresql/data env_file: - path: .env required: true ports: - "${POSTGRES_PORT}:5432" environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_DB: ${POSTGRES_DB} volumes: db-data:
已尝试的解决方法
- 将环境变量
DB_URL改为容器化前使用的postgres://postgres:pass123@localhost:5430/AUTH - 修改
src/index.ts中的数据库连接方式,但问题仍未解决
内容的提问来源于stack exchange,提问作者Prajwal Parashkar
相关产品推荐
相关产品推荐

