-
Notifications
You must be signed in to change notification settings - Fork 21
feat: prepare Coolify production deployment #476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fa7a42a
04f05b7
72fca34
4a12177
b0000ad
cc0472f
3c88e81
adce729
1e8c456
62b707e
3d3469b
d03a0dd
c5bf75a
344b8c5
af8e327
55c4733
b5e0a7b
4723ac8
a450737
5045b6e
cb9f655
43af472
92a8bc7
d822d34
432628b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,71 +1,106 @@ | ||
| FROM node:22.17-alpine AS base | ||
| # syntax=docker/dockerfile:1 | ||
|
|
||
| RUN apk add --no-cache libc6-compat | ||
| WORKDIR /app | ||
| # glibc base — the repo pins linux-x64-gnu native binaries (sharp, rollup, | ||
| # tailwindcss/oxide, lightningcss) that do not resolve on Alpine/musl. | ||
| ARG NODE_IMAGE=node:22-bookworm-slim | ||
|
|
||
| FROM ${NODE_IMAGE} AS base | ||
| RUN apt-get update \ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: The app-stage image installs Prompt for AI agents |
||
| && apt-get install -y --no-install-recommends openssl ca-certificates \ | ||
| && rm -rf /var/lib/apt/lists/* \ | ||
| && corepack enable | ||
| WORKDIR /app | ||
| ENV PNPM_HOME="/pnpm" | ||
| ENV PATH="$PNPM_HOME:$PATH" | ||
| ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 | ||
| # Pin pnpm to match package.json#packageManager (pnpm@11.5.2). | ||
| RUN corepack prepare pnpm@11.5.2 --activate | ||
|
|
||
| RUN corepack enable pnpm && corepack prepare pnpm@11.1.0 --activate | ||
|
|
||
| COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ | ||
| COPY prisma/ ./prisma/ | ||
|
|
||
| # Install production dependencies for runtime layers. | ||
| RUN pnpm install --prod --frozen-lockfile --prefer-offline --ignore-scripts | ||
|
|
||
| # Development stage | ||
| # Development: retained for docker-compose.yml and scripts/docker-dev.sh. | ||
| FROM base AS dev | ||
|
|
||
| # Install all dependencies including devDependencies for development | ||
| RUN pnpm install --frozen-lockfile --prefer-offline --ignore-scripts | ||
|
|
||
| ARG DATABASE_URL=postgresql://docker-build.invalid/emuready | ||
| ARG DATABASE_DIRECT_URL | ||
| COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ | ||
| RUN pnpm install --frozen-lockfile --ignore-scripts | ||
| COPY . . | ||
|
|
||
| # Ensure Prisma client is generated for the current environment | ||
| RUN pnpm exec prisma generate | ||
|
|
||
| # Expose port | ||
| RUN DATABASE_URL="${DATABASE_URL}" DATABASE_DIRECT_URL="${DATABASE_DIRECT_URL:-${DATABASE_URL}}" \ | ||
| pnpm exec prisma generate | ||
| EXPOSE 3000 | ||
|
|
||
| # Start development server | ||
| CMD ["pnpm", "dev"] | ||
|
|
||
| # Build stage for production | ||
| # The build database must be migrated and disposable. Prisma TypedSQL inspects it. | ||
| FROM base AS builder | ||
|
|
||
| # Install all dependencies for building | ||
| RUN pnpm install --frozen-lockfile --prefer-offline --ignore-scripts | ||
|
|
||
| # Copy source code | ||
| ARG DATABASE_URL | ||
| ARG DATABASE_DIRECT_URL | ||
| ARG NEXT_IMAGE_UNOPTIMIZED | ||
| ARG NEXT_PUBLIC_ALLOWED_ORIGINS | ||
| ARG NEXT_PUBLIC_ANDROID_LATEST_APK_URL | ||
| ARG NEXT_PUBLIC_ANDROID_LATEST_JSON_URL | ||
| ARG NEXT_PUBLIC_APP_ENV | ||
| ARG NEXT_PUBLIC_APP_URL | ||
| ARG NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | ||
| ARG NEXT_PUBLIC_DISABLE_COOKIE_BANNER | ||
| ARG NEXT_PUBLIC_DISCORD_LINK | ||
| ARG NEXT_PUBLIC_EMUREADY_BETA_URL | ||
| ARG NEXT_PUBLIC_EMUREADY_EMAIL | ||
| ARG NEXT_PUBLIC_EMUREADY_LITE_GITHUB_URL | ||
| ARG NEXT_PUBLIC_ENABLE_ANALYTICS | ||
| ARG NEXT_PUBLIC_ENABLE_ANDROID_DOWNLOADS | ||
| ARG NEXT_PUBLIC_ENABLE_KOFI_WIDGET | ||
| ARG NEXT_PUBLIC_ENABLE_PATREON_VERIFICATION | ||
| ARG NEXT_PUBLIC_ENABLE_SENTRY | ||
| ARG NEXT_PUBLIC_ENABLE_SW | ||
| ARG NEXT_PUBLIC_GA_ID | ||
| ARG NEXT_PUBLIC_GITHUB_URL | ||
| ARG NEXT_PUBLIC_IGDB_CLIENT_ID | ||
| ARG NEXT_PUBLIC_KOFI_LINK | ||
| ARG NEXT_PUBLIC_LOCAL_STORAGE_PREFIX | ||
| ARG NEXT_PUBLIC_PATREON_LINK | ||
| ARG NEXT_PUBLIC_R2_PUBLIC_BASE_URL | ||
| ARG NEXT_PUBLIC_R2_UPLOADS_PUBLIC_BASE_URL | ||
| ARG NEXT_PUBLIC_TURNSTILE_SITE_KEY | ||
| ARG NEXT_PUBLIC_TWITTER_URL | ||
| ARG NEXT_BUILD_ID | ||
| COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ | ||
| RUN pnpm install --frozen-lockfile --ignore-scripts | ||
| COPY . . | ||
|
|
||
| # Generate Prisma client for building | ||
| RUN pnpm exec prisma generate | ||
|
|
||
| # Build the application | ||
| RUN pnpm build | ||
|
|
||
| # Production stage | ||
| FROM base AS production | ||
|
|
||
| # Copy built application | ||
| COPY --from=builder /app/.next ./.next | ||
| COPY --from=builder /app/public ./public | ||
| COPY --from=builder /app/next.config.ts ./ | ||
| COPY --from=builder /app/prisma/generated ./prisma/generated | ||
|
|
||
| # Create non-root user | ||
| RUN addgroup --system --gid 1001 nodejs | ||
| RUN adduser --system --uid 1001 nextjs | ||
|
|
||
| # Change ownership of the app directory | ||
| RUN chown -R nextjs:nodejs /app | ||
| ENV NEXT_TELEMETRY_DISABLED=1 | ||
| RUN pnpm version:sync | ||
| RUN DATABASE_URL="${DATABASE_URL}" DATABASE_DIRECT_URL="${DATABASE_DIRECT_URL:-${DATABASE_URL}}" \ | ||
| NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="${NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY}" \ | ||
| NEXT_PUBLIC_R2_PUBLIC_BASE_URL="${NEXT_PUBLIC_R2_PUBLIC_BASE_URL}" \ | ||
| NEXT_PUBLIC_R2_UPLOADS_PUBLIC_BASE_URL="${NEXT_PUBLIC_R2_UPLOADS_PUBLIC_BASE_URL}" \ | ||
| NEXT_IMAGE_UNOPTIMIZED="${NEXT_IMAGE_UNOPTIMIZED}" \ | ||
| NEXT_BUILD_ID="${NEXT_BUILD_ID}" \ | ||
| pnpm build | ||
|
|
||
| # One-shot migration image. DATABASE_DIRECT_URL is supplied at runtime. | ||
| FROM base AS migrator | ||
| COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./ | ||
| RUN pnpm install --frozen-lockfile --ignore-scripts | ||
| COPY prisma.config.ts ./ | ||
| COPY prisma ./prisma | ||
| CMD ["pnpm", "exec", "prisma", "migrate", "deploy"] | ||
|
|
||
| # Standalone Next.js runtime. | ||
| FROM ${NODE_IMAGE} AS app | ||
| ARG NEXT_BUILD_ID | ||
| WORKDIR /app | ||
| ENV NODE_ENV=production \ | ||
| HOSTNAME=0.0.0.0 \ | ||
| PORT=3000 \ | ||
| APP_VERSION=${NEXT_BUILD_ID} \ | ||
| NEXT_TELEMETRY_DISABLED=1 | ||
| RUN apt-get update \ | ||
| && apt-get install -y --no-install-recommends curl \ | ||
|
Comment on lines
+93
to
+94
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win Bind the healthcheck to Line 90 makes
♻️ Proposed change RUN apt-get update \
- && apt-get install -y --no-install-recommends curl \
- && rm -rf /var/lib/apt/lists/* \
- && groupadd --system --gid 1001 nodejs \
+ && groupadd --system --gid 1001 nodejs \
&& useradd --system --uid 1001 --gid 1001 --create-home nextjs
@@
HEALTHCHECK --interval=30s --timeout=5s --start-period=40s --retries=3 \
- CMD node -e "fetch('http://127.0.0.1:3000/api/health/live').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
+ CMD node -e "fetch('http://127.0.0.1:'+(process.env.PORT||3000)+'/api/health/live').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"Also applies to: 104-105 🧰 Tools🪛 Hadolint (2.15.1)[warning] 93-93: Pin versions in apt get install. Instead of (DL3008) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||
| && rm -rf /var/lib/apt/lists/* \ | ||
| && groupadd --system --gid 1001 nodejs \ | ||
| && useradd --system --uid 1001 --gid 1001 --create-home nextjs | ||
| 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 | ||
| COPY --from=builder --chown=nextjs:nodejs /app/docs/MOBILE_API.md ./docs/MOBILE_API.md | ||
| USER nextjs | ||
|
|
||
| # Expose port | ||
| EXPOSE 3000 | ||
|
|
||
| # Start production server | ||
| CMD ["pnpm", "start"] | ||
| HEALTHCHECK --interval=30s --timeout=5s --start-period=40s --retries=3 \ | ||
| CMD node -e "fetch('http://127.0.0.1:'+(process.env.PORT||'3000')+'/api/health/live').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))" | ||
| CMD ["node", "server.js"] | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: When building the production image,
docs/remains excluded, so this exception cannot makeMOBILE_API.mdavailable to the builder. The laterCOPY --from=builder /app/docs/MOBILE_API.mdtherefore fails; re-include the parent directory before re-including the file.Prompt for AI agents