diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..16579ba --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +docker +.git +.env +.env.local +.env.development +.env.test +.env.production +.vscode \ No newline at end of file diff --git a/.env.example b/.env.example index 3570785..a8cffff 100644 --- a/.env.example +++ b/.env.example @@ -1,2 +1,12 @@ POLAR_API_BASE_URL=https://api.polar.sh/v1 -LANGBASE_API_KEY="your_langbase_api_key_here" \ No newline at end of file +LANGBASE_API_KEY=your_langbase_api_key_here + +DATABASE_URL=your_database_connection_string_here +NEXTAUTH_URL=http://localhost:3000 +NEXTAUTH_SECRET=your_nextauth_secret_here + +EMAIL_SERVER_HOST=smtp.example.com +EMAIL_SERVER_PORT=587 +EMAIL_SERVER_USER=your_email_user +EMAIL_SERVER_PASSWORD=your_email_password +EMAIL_FROM=example@example.com diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8cc351d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,68 @@ +FROM node:20-alpine AS base + +# 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* .npmrc* ./ +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 --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED=1 +ENV BUILD_STANDALONE=true + +RUN npx prisma generate + +RUN \ + if [ -f yarn.lock ]; then yarn run build; \ + elif [ -f package-lock.json ]; then npm run build; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV=production +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +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 +COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma + +USER nextjs + +EXPOSE 3000 + +ENV PORT=3000 + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/config/next-config-js/output +ENV HOSTNAME="0.0.0.0" +CMD ["node", "server.js"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..71c19e2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,28 @@ +services: + laminarflow: + container_name: laminarflow + build: + context: . + dockerfile: Dockerfile + ports: + - "3000:3000" + env_file: + # All runtime environment variables + - .env + restart: unless-stopped + # Optional: if you need to persist any data + # volumes: + # - ./data:/app/data + + # Optional: healthcheck to ensure the app is running + healthcheck: + test: + [ + "CMD", + "node", + "-e", + "require('http').get('http://localhost:3000', (res) => process.exit(res.statusCode === 200 ? 0 : 1))", + ] + interval: 30s + timeout: 10s + retries: 3 diff --git a/next.config.js b/next.config.js index f9e4652..b9e0aa5 100644 --- a/next.config.js +++ b/next.config.js @@ -1,5 +1,6 @@ /** @type {import('next').NextConfig} */ const nextConfig = { + output: process.env.BUILD_STANDALONE === "true" ? "standalone" : undefined, eslint: { ignoreDuringBuilds: true, }, diff --git a/package.json b/package.json index 5c12c0e..b9a574d 100644 --- a/package.json +++ b/package.json @@ -4,10 +4,10 @@ "private": true, "scripts": { "dev": "next dev", - "build": "prisma generate && DISABLE_ESLINT_PLUGIN=true next build", + "build": "next build", "start": "next start", "lint": "next lint", - "postinstall": "prisma generate" + "prisma:generate": "prisma generate" }, "dependencies": { "@arcjet/inspect": "1.0.0-beta.6",