turbo
turbo copied to clipboard
[turborepo] with docker: Cannot find module '/app/apps/web/server.js
What version of Turborepo are you using?
^1.6.3
What package manager are you using / does the bug impact?
Yarn v1
What operating system are you using?
Mac
Describe the Bug
After following existing monorepo and with docker tutorials step by step I can't get the docker running a nextjs application.
I'm avoiding to git clone the with-docker example since I don't want the architectural decision to keep the UI components within an external package.
Expected Behavior
The app is starting smoothly with yarn dev
and the expected output is being seen on localhost:3000. Running the production version with docker-compose up --build
should output the same results.
To Reproduce
These steps can also be found from the reproduction repo
Steps to reproduce
- Following this guide step by step to initialize repo
- Create package.json with following contents
{
"workspaces": [
"packages/*",
"apps/*"
],
"private": true,
"scripts": {
"build": "turbo run build",
"test": "turbo run test",
"lint": "turbo run lint",
"dev": "turbo run dev"
}
}
-
yarn install
-
yarn add turbo -DW
- Create turbo.json with following contents
{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": [".next/**"]
},
"test": {
"dependsOn": ["build"],
"outputs": [],
"inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"]
},
"lint": {
"outputs": []
},
"deploy": {
"dependsOn": ["build", "test", "lint"],
"outputs": []
},
"dev": {
"cache": false
}
}
}
- Create directories
packages
andapps
-
cd apps
-
npx create-next-app@latest
and name itweb
, select typescript and eslint -
cd ..
-
yarn install
-
yarn dev
- Everything works smoothly and the app is visible on localhost:3000
- Proceed using Deploying with Docker guide
- Replicate example Dockerfile to /apps/web/Dockerfile
- add .gitignore to root with following contents
.turbo/**
build/**
dist/**
.next/**
node_modules
- Add
output: 'standalone'
to next.config.js referring to this issue - Create docker-compose.yml to root with following contents
version: "3"
services:
web:
container_name: web
build:
context: .
dockerfile: ./apps/web/Dockerfile
restart: always
ports:
- 3000:3000
-
docker-compose up --build
Expected behavior
I expect the app to be running on localhost:3000
Actual behavior
I get the following error
Attaching to web
web | node:internal/modules/cjs/loader:998
web | throw err;
web | ^
web |
web | Error: Cannot find module '/app/apps/web/server.js'
web | at Module._resolveFilename (node:internal/modules/cjs/loader:995:15)
web | at Module._load (node:internal/modules/cjs/loader:841:27)
web | at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:82:12)
web | at node:internal/main/run_main_module:23:47 {
web | code: 'MODULE_NOT_FOUND',
web | requireStack: []
web | }
web |
web | Node.js v19.0.1
Reproduction Repo
https://github.com/peksi/turborepo-docker-nextjs-bug
I am experiencing the same with Next13 and Node v19+
It seems that in the docker container the apps/web/server.js
doesn't exist. It's the entry point that is mentioned in the example dockerfile
Further inspection inside the docker container shows that web/
contains only .next/static/
where rest of material lays.
Here's the ls -Rlah apps/web/
output from the container if it helps.
Temporarily fixed this now by allowing to run yarn start
on root folder and changing dockerfile CMD to CMD ["yarn", "turbo", "run", "start", "--filter=web"]
by modifying following files
I think that it's not the optimal way of doing things, since turborepo's docs or examples don't mention yarn start
anywhere. I don't close the issue since this is the situation where you end up straight after following the documentation.
I was able to fix the issue with the following
This of course does not include the permissions changes (this is a Dockerfile.dev) but for prod, I am still experimenting with the right permission steps to get this config below to work.
Just for anyone who might be unlucky as well.
I am using NPM workspaces in my project therefore you should update this config with Yarn or PNPM if needed
The working directory is the monorepo itself
FROM node:alpine AS builder
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /monorepo
RUN npm install -g turbo
COPY ./ ./
RUN turbo prune --scope=web --docker
FROM node:alpine AS installer
RUN apk add --no-cache libc6-compat
RUN apk update
WORKDIR /monorepo
COPY .gitignore .gitignore
COPY --from=builder /monorepo/out/json/ ./
COPY --from=builder /monorepo/out/package-lock.json ./package-lock.json
RUN npm install
COPY --from=builder /monorepo/out/full/ ./
COPY turbo.json turbo.json
RUN npx turbo run build --filter=web...
FROM node:alpine AS runner
WORKDIR /monorepo
COPY --from=installer /monorepo ./
WORKDIR /monorepo/apps/web
CMD ["npm", "run", "dev"]
I am able to run the application just fine at the installer
level, but then if I create a production
image that just copies everything, it fails to find modules.
I'm building a nestjs
application which requires that node_modules
are copied over to the image... and for what I see there are some broken symlinks when I do so, resulting in modules not found.
Any advice?
I tried copying the entire folder from installer
to production
but it still has the same issue.
I had the same issue, what solved it for me was adding the outputFileTracingRoot
in next.config.js, and keeping the .dockerignore clean.
I originally thought the outputFilteTracingRoot
was needed only if you're using a shared UI library (which I'm not), but once adding that it started working.
const path = require("path");
module.exports = {
reactStrictMode: true,
output: "standalone",
experimental: {
outputFileTracingRoot: path.join(__dirname, "../../"),
},
};
Turborepo with Next.js as the frontend & WordPress as the backend, and I wanted to be able to build only the UI. -- apps/frontend -- apps/wordpress
I had the same issue too
any news? facing the same issue.
i am currently using @peksi 's workaround to run via CMD ["yarn", "turbo", "run", "start", "--filter=web"]
instead of server.js which works but doesnt feel optimal
this works for me, db
is shared prisma
FROM --platform=linux/amd64 node:lts AS base
# The web Dockerfile is copy-pasted into our main docs at /docs/handbook/deploying-with-docker.
# Make sure you update this Dockerfile, the Dockerfile in the web workspace and copy that over to Dockerfile in the docs.
FROM base AS builder
# Set working directory
WORKDIR /app
RUN yarn global add turbo
COPY . .
RUN turbo prune --scope=auth --docker
# Add lockfile and package.json's of isolated subworkspace
FROM base AS installer
WORKDIR /app
# First install dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/yarn.lock ./yarn.lock
RUN yarn install
# Build the project and its dependencies
COPY --from=builder /app/out/full/ .
COPY turbo.json turbo.json
# Uncomment and use build args to enable remote caching
# ARG TURBO_TEAM
# ENV TURBO_TEAM=$TURBO_TEAM
# ARG TURBO_TOKEN
# ENV TURBO_TOKEN=$TURBO_TOKEN
RUN rm -f apps/auth/.env
RUN yarn turbo run build --filter=db
RUN yarn turbo run build --filter=auth
FROM base AS runner
WORKDIR /app
# Don't run production as root
# RUN addgroup --system --gid 1001 prod
# RUN adduser --system --uid 1001 prod
# USER prod
COPY --from=installer /app .
CMD ["node", "apps/auth/dist/"]
This issue appears to be a question moreso centered around Docker than Turborepo. I'm going to close due to that and inactivity.
If anyone here would like to keep the party going, please feel free to talk in a Discussion!