fix: 修复生产数据库 schema 同步脚本的双重 IF NOT EXISTS bug

prisma db push 生成的 .schema 已自带 CREATE TABLE IF NOT EXISTS,
旧脚本的 sed 替换会生成 IF NOT EXISTS IF NOT EXISTS 导致 SQL 语法错误,
建表全部静默失败。现在只对 CREATE INDEX 做 IF NOT EXISTS 补充。
This commit is contained in:
2026-03-01 22:44:44 +08:00
parent dfb7f464a0
commit bc2b0e40c6
2 changed files with 29 additions and 7 deletions
+4 -4
View File
@@ -17,25 +17,25 @@ COPY . .
ARG NEXT_PUBLIC_AMAP_API_KEY ARG NEXT_PUBLIC_AMAP_API_KEY
ENV NEXT_PUBLIC_AMAP_API_KEY=${NEXT_PUBLIC_AMAP_API_KEY} ENV NEXT_PUBLIC_AMAP_API_KEY=${NEXT_PUBLIC_AMAP_API_KEY}
RUN npx prisma generate RUN npx prisma generate
ENV DATABASE_URL="file:./template.db"
RUN npx prisma db push
RUN npm run build RUN npm run build
# --- Production --- # --- Production ---
FROM base AS runner FROM base AS runner
WORKDIR /app WORKDIR /app
ENV NODE_ENV=production ENV NODE_ENV=production
RUN apk add --no-cache sqlite
RUN addgroup --system --gid 1001 nodejs RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public COPY --from=builder /app/public ./public
COPY --from=builder /app/prisma ./prisma COPY --from=builder /app/prisma ./prisma
COPY --from=builder /app/prisma/template.db ./template.db
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# Prisma CLI + engines for schema sync on startup
COPY --from=deps /app/node_modules/prisma ./node_modules/prisma
COPY --from=deps /app/node_modules/@prisma ./node_modules/@prisma
COPY docker-entrypoint.sh ./ COPY docker-entrypoint.sh ./
RUN chmod +x docker-entrypoint.sh RUN chmod +x docker-entrypoint.sh
+25 -3
View File
@@ -1,14 +1,36 @@
#!/bin/sh #!/bin/sh
set -e set -e
TEMPLATE="/app/template.db"
DB="/app/data/prod.db" DB="/app/data/prod.db"
if [ ! -f "$DB" ]; then if [ ! -f "$DB" ]; then
echo "[db] First run — initializing database" echo "[db] First run — creating database from template"
cp "$TEMPLATE" "$DB"
exec node server.js
fi fi
echo "[db] Syncing schema..." echo "[db] Syncing schema..."
node ./node_modules/prisma/build/index.js db push --skip-generate --accept-data-loss 2>&1
echo "[db] Schema sync complete"
# Schema already contains "CREATE TABLE IF NOT EXISTS" from Prisma.
# Only indexes need the IF NOT EXISTS addition.
sqlite3 "$TEMPLATE" ".schema" | \
sed 's/CREATE INDEX /CREATE INDEX IF NOT EXISTS /g' | \
sed 's/CREATE UNIQUE INDEX /CREATE UNIQUE INDEX IF NOT EXISTS /g' | \
sqlite3 "$DB"
# Add missing columns to existing tables
for table in $(sqlite3 "$TEMPLATE" "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma%'"); do
prod_cols=$(sqlite3 "$DB" "PRAGMA table_info('$table')" | cut -d'|' -f2)
sqlite3 "$TEMPLATE" "PRAGMA table_info('$table')" | while IFS='|' read -r _cid name type notnull dflt _pk; do
if ! echo "$prod_cols" | grep -qx "$name"; then
alter="ALTER TABLE \"$table\" ADD COLUMN \"$name\" $type"
[ -n "$dflt" ] && alter="$alter DEFAULT $dflt"
sqlite3 "$DB" "$alter" && echo "[db] + $table.$name" || echo "[db] WARN: failed to add $table.$name"
fi
done
done
echo "[db] Schema sync complete"
exec node server.js exec node server.js