feat: 从 SQLite 切换到 PostgreSQL
- Prisma provider 改为 postgresql - docker-compose 新增 postgres 服务(带健康检查) - Dockerfile 移除 sqlite3/template.db,改用 npm install prisma 做运行时 schema 同步 - docker-entrypoint.sh 简化为 prisma db push + node server.js
This commit is contained in:
+3
-7
@@ -17,34 +17,30 @@ 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 for automatic schema migration on startup
|
||||||
|
RUN npm install prisma --no-save
|
||||||
|
|
||||||
COPY docker-entrypoint.sh ./
|
COPY docker-entrypoint.sh ./
|
||||||
RUN chmod +x docker-entrypoint.sh
|
RUN chmod +x docker-entrypoint.sh
|
||||||
|
|
||||||
RUN mkdir -p /app/data && chown nextjs:nodejs /app/data
|
|
||||||
|
|
||||||
USER nextjs
|
USER nextjs
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
ENV PORT=3000
|
ENV PORT=3000
|
||||||
ENV HOSTNAME="0.0.0.0"
|
ENV HOSTNAME="0.0.0.0"
|
||||||
ENV DATABASE_URL="file:/app/data/prod.db"
|
|
||||||
|
|
||||||
CMD ["./docker-entrypoint.sh"]
|
CMD ["./docker-entrypoint.sh"]
|
||||||
|
|||||||
+27
-3
@@ -1,18 +1,42 @@
|
|||||||
services:
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: no-whatever-db
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: nowhatever
|
||||||
|
POSTGRES_PASSWORD: nowhatever
|
||||||
|
POSTGRES_DB: nowhatever
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U nowhatever"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 5
|
||||||
|
restart: unless-stopped
|
||||||
|
networks:
|
||||||
|
- nginx
|
||||||
|
|
||||||
app:
|
app:
|
||||||
build: .
|
build: .
|
||||||
image: no-whatever:latest
|
image: no-whatever:latest
|
||||||
container_name: no-whatever
|
container_name: no-whatever
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
volumes:
|
|
||||||
- /data/no-whatever:/app/data
|
|
||||||
environment:
|
environment:
|
||||||
- DATABASE_URL=file:/app/data/prod.db
|
- DATABASE_URL=postgresql://nowhatever:nowhatever@postgres:5432/nowhatever
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks:
|
networks:
|
||||||
- nginx
|
- nginx
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
nginx:
|
nginx:
|
||||||
external: true
|
external: true
|
||||||
|
|||||||
+1
-30
@@ -1,36 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
TEMPLATE="/app/template.db"
|
|
||||||
DB="/app/data/prod.db"
|
|
||||||
|
|
||||||
if [ ! -f "$DB" ]; then
|
|
||||||
echo "[db] First run — creating database from template"
|
|
||||||
cp "$TEMPLATE" "$DB"
|
|
||||||
exec node server.js
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[db] Syncing schema..."
|
echo "[db] Syncing schema..."
|
||||||
|
npx prisma db push --skip-generate --accept-data-loss
|
||||||
|
|
||||||
# 1) Create any new tables
|
|
||||||
sqlite3 "$TEMPLATE" ".schema" | \
|
|
||||||
sed 's/CREATE TABLE /CREATE TABLE IF NOT EXISTS /g' | \
|
|
||||||
sed 's/CREATE INDEX /CREATE INDEX IF NOT EXISTS /g' | \
|
|
||||||
sed 's/CREATE UNIQUE INDEX /CREATE UNIQUE INDEX IF NOT EXISTS /g' | \
|
|
||||||
sqlite3 "$DB" 2>/dev/null || true
|
|
||||||
|
|
||||||
# 2) 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')" 2>/dev/null | cut -d'|' -f2 || echo "")
|
|
||||||
|
|
||||||
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" 2>/dev/null && echo "[db] + $table.$name" || true
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "[db] Schema sync complete"
|
|
||||||
exec node server.js
|
exec node server.js
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
datasource db {
|
datasource db {
|
||||||
provider = "sqlite"
|
provider = "postgresql"
|
||||||
url = env("DATABASE_URL")
|
url = env("DATABASE_URL")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user