-
-
Notifications
You must be signed in to change notification settings - Fork 408
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
feat: implemented docker support for nextjs app #255
base: main
Are you sure you want to change the base?
Conversation
@EkkoKo is attempting to deploy a commit to the t3-oss Team on Vercel. A member of the Team first needs to authorize it. |
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.
Haven't tested it out myself yet but got some initial thoughts
"@types/node": "^18.15.11", | ||
"@types/react": "^18.0.31", | ||
"tailwindcss": "^3.3.1", | ||
"postcss": "^8.4.21", | ||
"autoprefixer": "^10.4.14", |
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.
im no docker expert but why do these need to be production deps all of a sudden?
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.
when you run pnpm install --prod
it only installs dependencies
and when nextjs is trying to create to build it fails because it looks for those dependencies.
@@ -12,11 +12,11 @@ | |||
"with-env": "dotenv -e ../../.env --" | |||
}, | |||
"dependencies": { | |||
"prisma": "^4.12.0", |
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.
same here - prisma
is a devDep, why does it need to be a prod dep now?
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.
in the turbo.json we declare that before build it should run db:generate
, db:generate
runs prisma
and because we only install dependencies
I had to add it.
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.
I would recommend leaving the devDependencies and prod dependencies as they are, but limit the number of packages installed with pnpm install --filter @acme/nextjs...
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.
As long as you're using output: "standalone"
devDep will not get included on the final image, so imo you don't need --prod
when running pnpm install
, specially since you're doing prune
anyway.
I havent tested it, but im looking forward using it. I think its also a good idea to include a docker compose file. |
I have included a |
Any plans to merge this? |
I've burned all day trying to get docker setup and it looks like everything out there is either broken or results in an image size of a GB in size. Anyone have a working docker setup that doesn't alter dependencies? |
Here, ARG NODE_VERSION=18.17.1
ARG ALPINE_VERSION=3.17
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS base
RUN npm i -g pnpm@8.7.5
RUN npm i -g turbo@1.10.14
FROM base AS builder
# Set working directory
WORKDIR /app
COPY . .
RUN turbo prune --scope=test-app --docker
# Add lockfile and package.json's of isolated subworkspace
FROM base AS installer
WORKDIR /app
ARG TURBO_TEAM
ARG TURBO_TOKEN
ENV TURBO_TEAM=$TURBO_TEAM
ENV TURBO_TOKEN=$TURBO_TOKEN
# First install the dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ ./
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
RUN pnpm install --frozen-lockfile
# Build the project
COPY --from=builder /app/out/full/ ./
RUN CI=true SKIP_ENV_VALIDATION=1 pnpm build --filter=test-app
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION} AS runner
WORKDIR /app
COPY --from=installer /app/apps/test-app/next.config.mjs .
COPY --from=installer /app/apps/test-app/package.json .
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=installer /app/apps/test-app/.next/standalone ./
COPY --from=installer /app/apps/test-app/.next/static ./apps/test-app/.next/static
COPY --from=installer /app/apps/test-app/public ./apps/test-app/public
CMD node apps/test-app/server.js |
@albertilagan Thanks for the reply! A couple of things I found that you may want to add:
FROM node:18-alpine AS base
# 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
FROM base AS builder
WORKDIR /app
RUN npm install -g turbo
COPY . .
RUN turbo prune --scope=@acme/nextjs --docker
FROM base as installer
WORKDIR /app
RUN npm install -g pnpm
RUN npm install -g turbo
ARG TURBO_TEAM
ARG TURBO_TOKEN
ENV TURBO_TEAM=$TURBO_TEAM
ENV TURBO_TOKEN=$TURBO_TOKEN
# First install dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/pnpm-lock.yaml ./pnpm-lock.yaml
RUN pnpm install --frozen-lockfile
# Build the project and its dependencies
COPY --from=builder /app/out/full/ .
COPY turbo.json turbo.json
## This would be useful for browser environment variables that are actually baked at build time and you aren't passing them in otherwise.
# COPY .env.production .env.production
RUN CI=true SKIP_ENV_VALIDATION=true turbo run build --filter=@acme/nextjs...
FROM base AS runner
WORKDIR /app
EXPOSE 3000
ENV PORT 3000
ENV NODE_ENV production
ENV HOSTNAME localhost
# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
USER nextjs
COPY --from=installer /app/apps/nextjs/next.config.mjs .
COPY --from=installer /app/apps/nextjs/package.json .
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=installer --chown=nextjs:nodejs /app/apps/nextjs/.next/standalone ./
COPY --from=installer --chown=nextjs:nodejs /app/apps/nextjs/.next/static ./apps/nextjs/.next/static
COPY --from=installer --chown=nextjs:nodejs /app/apps/nextjs/public ./apps/nextjs/public
CMD node apps/nextjs/server.js For anyone reading this out of context, you also want a .dockerignore in your root node_modules
# This line is **EXTREMELY** important
# https://github.com/vercel/turbo/issues/1997#issuecomment-1273565773
**/node_modules You also want standalone as @albertilagan pointed out. Here's a full file that supports multi package: import "./src/env.mjs";
import "@acme/auth/env.mjs";
/** @type {import("next").NextConfig} */
const config = {
reactStrictMode: true,
/** Enables hot reloading for local packages without a build step */
transpilePackages: ["@acme/api", "@acme/auth", "@acme/db"],
/** We already do linting and typechecking as separate tasks in CI */
eslint: { ignoreDuringBuilds: true },
typescript: { ignoreBuildErrors: true },
output: 'standalone',
};
export default config; |
You're welcome :) Yeah feel free to extend it to whatever you need. I can't really share the script, but we utilize |
@albertilagan great work! are you checking the any chance you know how to check the |
we are not, doesn't really apply to us because we have a good k8s config setup and separation of environments,
and apply the |
COPY --from=builder /app/out/json . | ||
COPY --from=builder /app/out/pnpm-lock.yaml\* ./ | ||
|
||
RUN yarn global add pnpm && pnpm fetch --prod && pnpm install -r --offline --prod |
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.
why mix with yarn and pnpm ??
ENV SKIP_ENV_VALIDATION true | ||
|
||
COPY .gitignore .gitignore | ||
COPY --from=builder /app/tsconfig.json ./tsconfig.json |
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.
No description provided.