我有一个 Next.js 应用程序,我正在尝试对其进行 dockerize。
我的堆栈是 Next.js(Node.js 框架)+ Docker + Drizzle ORM +
better-sqlite3
目前它可以在没有 docker 的情况下使用
pnpm db:generate
和 pnpm db:migrate:dev
进行开发。您可以在我的复制品上看到扩展的命令。
现在我只是尝试将我的 Next.js 应用程序进行 dockerize 以用于生产。
但是,我遇到了一个错误:
42.34 SqliteError: database is locked
42.34 at Database.pragma (/app/node_modules/.pnpm/[email protected]/node_modules/better-sqlite3/lib/methods/pragma.js:11:44)
42.34 at 8699 (/app/.next/server/app/api/delete/route.js:1:1339)
42.34 at t (/app/.next/server/webpack-runtime.js:1:127)
42.34 at 605 (/app/.next/server/app/api/delete/route.js:1:443)
42.34 at t (/app/.next/server/webpack-runtime.js:1:127)
42.34 at r (/app/.next/server/app/api/delete/route.js:1:1558)
42.34 at /app/.next/server/app/api/delete/route.js:1:1589
42.34 at t.X (/app/.next/server/webpack-runtime.js:1:1191)
42.34 at /app/.next/server/app/api/delete/route.js:1:1571
42.34 at Object.<anonymous> (/app/.next/server/app/api/delete/route.js:1:1615) {
42.34 code: 'SQLITE_BUSY'
我正在尝试在我的
docker-compose.yml
文件中的生产容器中创建一个卷。不知道我是否正确,因为这是我第一次使用 Docker。
version: '3'
services:
docker-production:
build:
context: .
dockerfile: Dockerfile
image: docker-production
ports:
- '3001:3000'
volumes:
- ./data:/data
我从 Next.js 官方示例中复制了
Dockerfile
。
FROM node:20-alpine AS base
# 1. Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i; \
else echo "Lockfile not found." && exit 1; \
fi
# 2. Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# This will do the trick, use the corresponding env file for each environment.
COPY .env.production .env.production
RUN mkdir -p /data
RUN npm run build
# 3. Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY --from=builder /app/public ./public
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
ENV HOSTNAME localhost
CMD ["node", "server.js"]
我还有一个
Makefile
可以用简短的方式编写命令。
.PHONY: build-production
build-production: ## Build the production docker image.
docker compose -f docker-compose.yml build
.PHONY: start-production
start-production: ## Start the production docker container.
docker compose -f docker-compose.yml up -d
.PHONY: stop-production
stop-production: ## Stop the production docker container.
docker compose -f docker-compose.yml down
现在我这样做了
make build-production
并且它给出了错误。
我尝试在 Dockerfile 中使用
mkdir -p /data
创建 /data
文件夹,然后再使用 npm run build
开始构建,但它不起作用。
我有一个小的复制品,可以在https://github.com/deadcoder0904/easypanel-nextjs-sqlite/
SQLite + Docker 上使用 ORM 生成它的资源很少。
很想解决这个问题。我该怎么办?
我什至不知道如何调试这个东西。我在 Docker Desktop 中看到 Docker 日志,它显示错误发生在
npm run build
: 之后
3.151 > next build
3.151
5.227 Attention: Next.js now collects completely anonymous telemetry regarding usage.
5.227 This information is used to shape Next.js' roadmap and prioritize features.
5.227 You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
5.227 https://nextjs.org/telemetry
5.227
5.352 ▲ Next.js 14.1.0
5.353 - Environments: .env.production
5.354
5.451 Creating an optimized production build ...
36.98 ✓ Compiled successfully
36.98 Linting and checking validity of types ...
41.65 Collecting page data ...
42.34 SqliteError: database is locked
.
.
.
我现在该如何解决这个问题?
我仍然没有想出解决这个错误的方法,因为它时不时地随机弹出。
这肯定是2个进程在锁定时访问同一个数据库文件的情况。
我使用
@epic-web/remember
创建一个单例并使用默认导出而不是命名导出来尝试修复它。
我也尝试在 next.js 中强制动态,但这些都无法阻止该错误时不时地随机出现。