Closed burn2delete closed 2 years ago
Here is a sample Dockerfile for running the project in docker. Just make sure before running, make sure:
site/.env.local
with the correct variables for your package set up. I am using the vendure package so my env file looks sth like this
COMMERCE_PROVIDER=@vercel/commerce-vendure
NEXT_PUBLIC_VENDURE_SHOP_API_URL=http://localhost:3000/shop-api NEXT_PUBLIC_VENDURE_LOCAL_URL=/vendure-shop-api
* secondly, your vendure backend is running and reachable
So, here is the `Dockerfile` which is located in the root of your project:
FROM node:latest EXPOSE 8000
WORKDIR /app/
COPY package.json /app/ COPY turbo.json /app/ COPY yarn.lock /app/ COPY site/ /app/site/ COPY packages/ /app/packages/
RUN yarn
WORKDIR /app/site/
CMD yarn next dev -p 8000
Additionally I use `docker-compose` for starting.
Here is a sample `docker-compose.yml` which should also be located in the root folder of the project as well.
version: '3.1'
services: server: build: ./ restart: always ports:
with this setup, you just need to run `docker-compose up` and you should have your site running on `localhost:8000` after building is complete.
I hope this helps! :)
@Aryojaam
Hi Since this repo changed from using yarn to pnpm, did you by any chance figured out how to do this with pnpm? I adjusted your Dockerfile to use pnpm. But Cloud Run is throwing me errors.
I've taken a look at vercels official example: https://github.com/vercel/turbo/tree/main/examples/with-docker This uses yarn as well and places the Dockerfile inside the actual app-folder not the root.
EDIT: Happy new year!
@gnacoding Happy new year! :)
Unfortunately I do not have experience with either pnpm or Cloud Run. Maybe you can post the error you are getting here?
But just a wild guess for a fix might be installing pnpm globally in your container with npm i -g pnpm
and then using it in the next steps if you are not already not doing so?
@Aryojaam Thanks for the answer! This is the modified Dockerfile that I used to build the image:
FROM docker.io/node:16-alpine
# Set up pnpm
RUN apk add --no-cache libc6-compat
RUN npm install -g pnpm
RUN npm install -g turbo@1.4.6
WORKDIR /app/
COPY package.json /app/
COPY turbo.json /app/
COPY pnpm-lock.yaml /app/
COPY pnpm-workspace.yaml /app/
COPY packages/ /app/packages/
COPY site/ /app/site/
RUN pnpm install
RUN pnpm build
WORKDIR /app/site/
# use for production instead of dev
# CMD yarn next start -p 8000
CMD pnpm next start
When I ran this image locally it works just fine, but when I deploy it with Cloud Run it builds the image but when I open the URL it just says 'Service Unavailable'. I noticed with this Dockerfile the image is over 2GB large since it does no cleanup. What Cloud Build does is basically taking the Dockerfile from the GitHub Repo and attempts to build it with 'docker build...' and deploys it to its serverless instance Cloud Run (like AWS Lambda).
This was the beginning of my 2 day 'walking down the rabbit hole session' I ended up finding a few more hints from: https://github.com/vercel/next.js/discussions/39432 https://github.com/vercel/turbo/issues/534 https://github.com/pnpm/pnpm/issues/3114 https://github.com/pnpm/pnpm/discussions/4777 Yarn: https://github.com/Elvincth/turbo-strapi-nextjs/blob/main/dev.Dockerfile https://github.com/thmsmtylr/turborepo-starter/blob/main/Dockerfile https://github.com/vercel/turbo/tree/main/examples/with-docker
Based on the links above I created/modified the Dockerfile like this:
# Builder image
FROM docker.io/node:16-alpine AS build
RUN apk add --no-cache curl bash git
ARG PROJECT_NAME=site
WORKDIR /app
# Set up pnpm
RUN apk add --no-cache libc6-compat
RUN npm install -g pnpm
RUN npm install -g turbo@1.4.6
RUN pnpm config set store-dir .pnpm-store
COPY pnpm-lock.yaml ./
RUN pnpm fetch
# Build
COPY . .
RUN pnpm install --frozen-lockfile --offline --ignore-scripts --workspace-root --filter ${PROJECT_NAME}...
RUN pnpm run build --filter=${PROJECT_NAME}...
# WORKAROUND FOR: https://github.com/vercel/next.js/discussions/39432
RUN pnpm install --prod --frozen-lockfile --offline --shamefully-hoist --ignore-scripts --workspace-root --filter ${PROJECT_NAME} && \
cp -Lr ./node_modules ./node_modules_temp && \
rm -rf ./node_modules_temp/.cache && \
rm -rf ./node_modules_temp/.pnpm
# END WORKAROUND
# Runtime image
FROM docker.io/node:16-alpine AS release
ARG PROJECT_NAME=site
ENV NODE_ENV=production
ENV PORT=3000
WORKDIR /app
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=build --chown=nextjs:nodejs /app/${PROJECT_NAME}/.next/standalone ./
COPY --from=build --chown=nextjs:nodejs /app/${PROJECT_NAME}/.next/static* ./.next/static
COPY --from=build --chown=nextjs:nodejs /app/${PROJECT_NAME}/public* ./public
# WORKAROUND FOR: https://github.com/vercel/next.js/discussions/39432
RUN rm -rf ./node_modules
COPY --from=build /app/node_modules_temp ./node_modules
# END WORKAROUND
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]
This Dockerfile runs great and when I inspect the image the prod-build looks perfect but it gives me the same error created in this issue: https://github.com/vercel/next.js/discussions/39432
docker run -p 3000:3000 test5 ─╯
node:internal/modules/cjs/loader:998
throw err;
^
Error: Cannot find module 'next/dist/server/next-server'
Require stack:
- /app/server.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:995:15)
at Function.Module._load (node:internal/modules/cjs/loader:841:27)
at Module.require (node:internal/modules/cjs/loader:1067:19)
at require (node:internal/modules/cjs/helpers:103:18)
at Object.<anonymous> (/app/server.js:2:20)
at Module._compile (node:internal/modules/cjs/loader:1165:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1219:10)
at Module.load (node:internal/modules/cjs/loader:1043:32)
at Function.Module._load (node:internal/modules/cjs/loader:878:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/app/server.js' ]
I started a discussion here and will Update it once I find a solution: https://github.com/vercel/commerce/discussions/928
Posting the Dockerfile that works for me. I had to upgrade next to 13.4 to get rid of the "Error: Cannot find module 'next/dist/server/next-server'" error and now it works perfectly
P.S. I'm using an old setup with packages/ and site/ folders since it has vendure provider.
# Builder image
FROM docker.io/node:16-alpine AS build
RUN apk add --no-cache curl bash git
ARG PROJECT_NAME=site
WORKDIR /app
# Set up pnpm
RUN apk add --no-cache libc6-compat
RUN npm install -g pnpm
RUN npm install -g turbo@1.4.6
RUN pnpm config set store-dir .pnpm-store
COPY pnpm-lock.yaml ./
RUN pnpm fetch
# Build
COPY . .
RUN pnpm install --frozen-lockfile --offline --ignore-scripts --workspace-root --filter ${PROJECT_NAME}...
# Install sharp module
RUN cd site && pnpm add sharp
RUN pnpm run build --filter=${PROJECT_NAME}...
# Runtime image
FROM docker.io/node:16-alpine AS release
ENV NODE_ENV=production
ENV PORT=8000
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY --from=build --chown=nextjs:nodejs /app/site/.next/standalone ./
COPY --from=build --chown=nextjs:nodejs /app/site/.next/static ./site/.next/static
COPY --from=build --chown=nextjs:nodejs /app/site/public ./site/public
# RUN ./node_modules/.bin/next telemetry disable
USER nextjs
CMD ["node", "site/server.js"]
EXPOSE 8000
We're not planning on building a docker image.