如何在VPS上通过Docker+Next.js执行SQLite的Drizzle生产迁移
解决方案
一、处理Drizzle迁移与应用启动的命令执行问题
方法1:Shell命令串联(简单场景)
直接修改Dockerfile的CMD为shell模式,让迁移命令执行完成后再启动应用:
# 替换原有CMD CMD ["sh", "-c", "pnpm db:migrate:prod && pnpm start"]
注:若迁移命令执行失败,应用不会启动,这是生产环境的合理逻辑,避免应用连接未初始化的数据库。
方法2:Entrypoint脚本(健壮推荐)
通过初始化脚本灵活处理前置操作,还能保证信号正确传递:
- 在项目根目录创建
entrypoint.sh文件:
#!/bin/sh set -e # 执行数据库迁移 pnpm db:migrate:prod # 以exec方式启动应用,确保容器停止时应用能优雅退出 exec pnpm start
- 修改Dockerfile,添加并配置脚本:
# 复制脚本到容器并赋予执行权限 COPY entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/entrypoint.sh # 设置入口脚本 ENTRYPOINT ["entrypoint.sh"]
二、持久化SQLite数据库文件
SQLite依赖本地文件,需将数据库所在目录挂载到宿主机或Docker卷,避免容器销毁后数据丢失:
步骤1:确认数据库路径
确保Drizzle配置中,users.prod.sqlite的存放路径指向项目内固定目录(比如./data),示例配置:
// drizzle.config.js export default { out: "./drizzle", schema: "./src/db/schema.ts", driver: "better-sqlite", dbCredentials: { url: "./data/users.prod.sqlite" } };
步骤2:Dockerfile中创建目录(可选但推荐)
在Dockerfile中添加一行,确保容器内的数据库目录存在:
RUN mkdir -p /app/data
步骤3:运行容器时挂载存储
方式A:绑定宿主机目录(需直接访问宿主机文件时使用)
# 宿主机创建存储目录 mkdir -p /var/nextjs-sqlite-data # 运行容器时挂载目录 docker run -d -p 3000:3000 -v /var/nextjs-sqlite-data:/app/data your-image-name
方式B:使用Docker卷(推荐,Docker统一管理存储)
# 创建Docker卷 docker volume create nextjs-sqlite-data # 运行容器时挂载卷 docker run -d -p 3000:3000 -v nextjs-sqlite-data:/app/data your-image-name
三、完整Dockerfile示例
结合上述操作,最终Dockerfile示例如下:
FROM node:20-alpine WORKDIR /app COPY package.json pnpm-lock.yaml ./ RUN npm install -g pnpm && pnpm install --prod COPY . . RUN mkdir -p /app/data COPY entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"]
内容的提问来源于stack exchange,提问作者deadcoder0904
相关产品推荐
相关产品推荐

