forked from hazem/yslootahrobotics
feat: update environment configuration for production and add Docker support
This commit is contained in:
parent
3fbdc3b187
commit
138e8377a6
23
.dockerignore
Normal file
23
.dockerignore
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
node_modules
|
||||||
|
.next
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Local env files — set these as environment variables in Coolify instead
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# SQLite database files — mount /app/prisma as a persistent volume in Coolify
|
||||||
|
prisma/*.db
|
||||||
|
prisma/*.db-shm
|
||||||
|
prisma/*.db-wal
|
||||||
|
prisma/migrations
|
||||||
|
|
||||||
|
# Dev/test artifacts
|
||||||
|
coverage
|
||||||
|
*.log
|
||||||
|
vitest.config.ts
|
||||||
|
src/**/*.test.ts
|
||||||
|
src/**/*.test.tsx
|
||||||
|
test/
|
||||||
22
.env.example
22
.env.example
@ -1,4 +1,18 @@
|
|||||||
# Stripe Keys
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
# Get your keys from https://dashboard.stripe.com/apikeys
|
# Stripe — https://dashboard.stripe.com/apikeys
|
||||||
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_51RBtf7I7xOcO9rzigsLLK3esMLmBlJoRztbzUadPhQm7tcHQuScViFEkwdfAwDxbaqt5n8BOuJV9wRSMdn2IrxIX00lqGOOJfT
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
STRIPE_SECRET_KEY=sk_test_51RBtf7I7xOcO9rzitxMqK3jnTb3SPdEbyGxGBnPccGEfrIrpiEFEOIEG2oHuTumaUejUN4FyAOBg0AVCBRn6AOKI00LeWSDC10
|
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
|
||||||
|
STRIPE_SECRET_KEY=sk_live_...
|
||||||
|
STRIPE_WEBHOOK_SECRET=whsec_...
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Admin JWT (generate with: openssl rand -hex 32)
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
ADMIN_JWT_SECRET=change_me_generate_with_openssl_rand_hex_32
|
||||||
|
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
# Database — SQLite via libsql
|
||||||
|
# In Coolify: set to file:/app/prisma/lootah.db
|
||||||
|
# and mount /app/prisma as a persistent volume
|
||||||
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
|
DATABASE_URL=file:./prisma/lootah.db
|
||||||
|
|||||||
62
Dockerfile
Normal file
62
Dockerfile
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
# ── Stage 1: install all dependencies ─────────────────────────────────────────
|
||||||
|
FROM node:22.14-alpine AS deps
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# ── Stage 2: build ─────────────────────────────────────────────────────────────
|
||||||
|
FROM node:22.14-alpine AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
|
||||||
|
# Generate Prisma client (reads prisma/schema.prisma + prisma.config.ts)
|
||||||
|
RUN npx prisma generate
|
||||||
|
|
||||||
|
# Build Next.js — produces .next/standalone (set in next.config.mjs)
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ── Stage 3: production runner ─────────────────────────────────────────────────
|
||||||
|
FROM node:22.14-alpine AS runner
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
ENV PORT=3000
|
||||||
|
ENV HOSTNAME=0.0.0.0
|
||||||
|
|
||||||
|
# dumb-init: proper PID 1 / signal forwarding
|
||||||
|
RUN apk add --no-cache dumb-init \
|
||||||
|
&& addgroup --system --gid 1001 nodejs \
|
||||||
|
&& adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
# ── Next.js standalone server ──────────────────────────────────────────────────
|
||||||
|
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/public ./public
|
||||||
|
|
||||||
|
# ── Prisma runtime ─────────────────────────────────────────────────────────────
|
||||||
|
# Config + schema (read by CLI at container startup for db push)
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/prisma.config.ts ./
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/prisma/schema.prisma ./prisma/
|
||||||
|
|
||||||
|
# Generated Prisma client (imported by the compiled Next.js server bundle)
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/src/generated ./src/generated
|
||||||
|
|
||||||
|
# Prisma CLI + its dependencies (devDeps — not bundled into standalone node_modules)
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/.bin/prisma ./node_modules/.bin/prisma
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/prisma ./node_modules/prisma
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@prisma ./node_modules/@prisma
|
||||||
|
COPY --from=builder --chown=nextjs:nodejs /app/node_modules/@libsql ./node_modules/@libsql
|
||||||
|
|
||||||
|
# ── Entrypoint ─────────────────────────────────────────────────────────────────
|
||||||
|
COPY --chown=nextjs:nodejs docker-entrypoint.sh ./
|
||||||
|
RUN chmod +x /app/docker-entrypoint.sh
|
||||||
|
|
||||||
|
USER nextjs
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# dumb-init wraps our entrypoint so SIGTERM is forwarded to node properly
|
||||||
|
ENTRYPOINT ["/usr/bin/dumb-init", "--", "/app/docker-entrypoint.sh"]
|
||||||
14
docker-entrypoint.sh
Normal file
14
docker-entrypoint.sh
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Ensure the persistent database directory exists
|
||||||
|
# (Coolify: mount a volume at /app/prisma so data survives redeployments)
|
||||||
|
mkdir -p /app/prisma
|
||||||
|
|
||||||
|
echo "→ Syncing database schema..."
|
||||||
|
# db push creates the SQLite file and syncs tables to match schema.prisma
|
||||||
|
# --skip-generate: client was already generated at build time
|
||||||
|
/app/node_modules/.bin/prisma db push --skip-generate
|
||||||
|
|
||||||
|
echo "→ Starting Next.js on port ${PORT:-3000}..."
|
||||||
|
exec node /app/server.js
|
||||||
@ -6,6 +6,8 @@ export default defineConfig({
|
|||||||
path: "prisma/migrations",
|
path: "prisma/migrations",
|
||||||
},
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
url: "file:./prisma/lootah.db",
|
// In production (Coolify), set DATABASE_URL=file:/app/prisma/lootah.db
|
||||||
|
// and mount /app/prisma as a persistent volume.
|
||||||
|
url: process.env.DATABASE_URL ?? "file:./prisma/lootah.db",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -5,8 +5,10 @@ import path from 'path';
|
|||||||
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
|
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
|
||||||
|
|
||||||
function createPrismaClient() {
|
function createPrismaClient() {
|
||||||
const dbPath = path.resolve(process.cwd(), 'prisma/lootah.db');
|
// Use DATABASE_URL if set (production/Coolify), otherwise fall back to local path.
|
||||||
const adapter = new PrismaLibSql({ url: `file:${dbPath}` });
|
const dbUrl = process.env.DATABASE_URL
|
||||||
|
?? `file:${path.resolve(process.cwd(), 'prisma/lootah.db')}`;
|
||||||
|
const adapter = new PrismaLibSql({ url: dbUrl });
|
||||||
return new PrismaClient({ adapter } as ConstructorParameters<typeof PrismaClient>[0]);
|
return new PrismaClient({ adapter } as ConstructorParameters<typeof PrismaClient>[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user