Remix recommends placing@remix-run/dev in devDependencies, so it's not bundled in the server.
When building Remix in a Dockerfile, we normally prune out development dependencies before building the app. When using Turborepo in a monorepo, this is accomplished by the turbo prune command.
However, once the app is pruned, we lose access to devDependencies. As a result, the remix CLI is no longer available, and we can't run remix vite:build. The current temporary solution is to put @remix-run/dev into production dependencies, but that's not recommended by the Remix team.
Note that this doesn't only happen with Docker; it's just much more evident with Docker because we prune the repo before building. This bug will occur with any build process that removes devDependencies before running remix vite:build.
Dockerfile:
# base node image
FROM node:bullseye-slim as base
RUN apt-get update && apt-get install -y openssl
# == Pruner
# Throwaway stage to reduce size of final image
FROM base as builder
RUN mkdir /app
WORKDIR /app
RUN npm install -g turbo
COPY . .
RUN turbo prune --docker
# == Installer/Builder
# Throwaway stage to reduce size of final image
FROM base as installer
RUN mkdir /app
WORKDIR /app
RUN npm install -g turbo
# Copy package.json over, install dependencies
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ .
COPY --from=builder /app/out/package-lock.json ./package-lock.json
RUN npm clean-install
# Build the project
COPY --from=builder /app/out/full/ .
COPY turbo.json turbo.json
# This step here fails if the remix CLI is not present.
RUN npx turbo run build
# == Runner
FROM base as runner
WORKDIR /app
ENV NODE_ENV=production
# Don't run production as root
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 remix
USER remix
COPY --from=installer --chown=remix:nodejs /app/ ./
WORKDIR /app
CMD ["npm", "run", "start"]
Ok, turns out this wasn't remix's fault. The command is missing due to an upstream node 22.5.0 issue where npm install and npm clean-install were silently failing. Sorry!
Reproduction
Remix recommends placing
@remix-run/dev
indevDependencies
, so it's not bundled in the server.When building Remix in a Dockerfile, we normally prune out development dependencies before building the app. When using Turborepo in a monorepo, this is accomplished by the
turbo prune
command.However, once the app is pruned, we lose access to devDependencies. As a result, the remix CLI is no longer available, and we can't run
remix vite:build
. The current temporary solution is to put@remix-run/dev
into productiondependencies
, but that's not recommended by the Remix team.Note that this doesn't only happen with Docker; it's just much more evident with Docker because we prune the repo before building. This bug will occur with any build process that removes
devDependencies
before runningremix vite:build
.Dockerfile:
This issue was reported in https://github.com/remix-run/remix/issues/1233, but was closed without fixing it.
I think this can be fixed if we included the remix CLI in one of the other packages, like
@remix-run/node
or@remix-run/serve
.System Info
Used Package Manager
npm
Expected Behavior
The build should succeed.
Actual Behavior
Running
npm run build
which runsremix vite:build
fails with the following error:sh: 1: remix: not found