turbo icon indicating copy to clipboard operation
turbo copied to clipboard

[turborepo] with docker: Cannot find module '/app/apps/web/server.js

Open peksi opened this issue 2 years ago • 4 comments

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

  1. Following this guide step by step to initialize repo
  2. 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"
    }
}
  1. yarn install
  2. yarn add turbo -DW
  3. 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
    }
  }
}
  1. Create directories packages and apps
  2. cd apps
  3. npx create-next-app@latest and name it web, select typescript and eslint
  4. cd ..
  5. yarn install
  6. yarn dev
  7. Everything works smoothly and the app is visible on localhost:3000
  8. Proceed using Deploying with Docker guide
  9. Replicate example Dockerfile to /apps/web/Dockerfile
  10. add .gitignore to root with following contents
.turbo/**
build/**
dist/**
.next/**
node_modules
  1. Add output: 'standalone' to next.config.js referring to this issue
  2. 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

  1. 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

peksi avatar Nov 12 '22 10:11 peksi

I am experiencing the same with Next13 and Node v19+

TannerBarcelos avatar Nov 13 '22 05:11 TannerBarcelos

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.

Screenshot 2022-11-13 at 11 45 25

peksi avatar Nov 13 '22 09:11 peksi

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.

peksi avatar Nov 14 '22 13:11 peksi

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"]

TannerBarcelos avatar Nov 15 '22 01:11 TannerBarcelos

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.

lsemerini avatar Dec 01 '22 14:12 lsemerini

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

g-rasse avatar Dec 16 '22 14:12 g-rasse

I had the same issue too

ThaddeusJiang avatar Jan 13 '23 06:01 ThaddeusJiang

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

christian-draeger avatar Jan 24 '23 15:01 christian-draeger

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/"]

gaboesquivel avatar Jun 26 '23 19:06 gaboesquivel

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!

anthonyshew avatar Feb 05 '24 05:02 anthonyshew