Hello, I’m new to Fly and I don’t understand how I should set up a pnpm monorepo on Fly, because when I follow the official article, it ends up copying all node_modules and it inflates the image size greatly.
There is an official guide from pnpm but I’m a complete noob at Docker so I’m not really sure how the final Dockerfile should look.
# syntax = docker/dockerfile:1
# Adjust NODE_VERSION as desired
ARG NODE_VERSION=20.5.1
FROM node:${NODE_VERSION}-slim as base
LABEL fly_launch_runtime="NodeJS"
RUN corepack enable
# Set production environment
ENV NODE_ENV=production
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
FROM base AS prod-deps
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
# Throw-away build stage to reduce size of final image
FROM base as build
# Install packages needed to build node modules
RUN apt-get update -qq && \
apt-get install -y pkg-config build-essential
COPY --link . .
# Install node modules
RUN pnpm i
# Final stage for app image
FROM base
# Copy built application
COPY --from=build /app/ /app
WORKDIR /app/packages/api
# Start the server by default, this can be overwritten at runtime
CMD [ "pnpm", "run", "start" ]
Could I get some guidance please how to properly write a docker file so it deploys a package under app successfully? (It also depends on prisma, so it should be built as well)
The official guide describes how to build and run what appears to be two independent apps that may share some common dependencies. I suspect that this doesn’t match your setup.
What would be most helpful to know is how you run your application today. As an example, it may be that your www and prisma apps are merely built, and the only app you are running is an api server that makes use of the database through prisma and serves bundled javascript based on the code in www.
Other configurations are possible. For example you may start two servers, where the www server talks to your api server.
Without knowing more, it is difficult to craft a dockerfile that does what you know. After all “monorepository” simply means many projects in one repository.
It would be helpful to see your package.json, both at the top level and probably also the package.json files in each directory where you start a server (I suspect that at a minimum that would include api).
Since prisma doesn’t have a start script, it clearly isn’t an application.
I’m troubled by the fact that I don’t see any scripts being run in the build stage. I presume that you need to run something that calls the generate script in the prisma directory.
So far, I’ve only seen one start script (I’m still curious what is in web), but if you only have one application with a start script, try changing:
To
# Copy built application
COPY --from=build /app/packages/api /app
WORKDIR /app
With this change, the only app that will be in your image will be the api app. Hopefully the build process places bundled javascript from the web app and generated database access code from the prisma app into the api app; but I’m making a lot of assumptions here as I can’t see your application.