## This dockerfile creates multiple docker images. ## Because we are using monorepo with pnpm workspaces, we have many npm packages in this single git repo. ## Some of these packages in the monorepo depend on other packages in the monorepo. ## In order to build these individual packages which inter-depend on eachother, ## all of the dependent code must be present in the build context. ## ## Below, COPY . /usr/src/app copies all the app code into the build context. ## Because we use Tilt, only specific path directories are visible to docker. This helps with build performance. ## When a new package becomes a dependency, we need to update our Tiltfile to include the package directory. ## Tiltfile example of docker_build() args which include `scout` and `next` packages. ## `only=['./pnpm-lock.yaml', './package.json', './packages/scout', './packages/next'],` ## ## FROM node:20 AS base ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" RUN corepack enable WORKDIR /app ENTRYPOINT ["pnpm"] FROM base AS build ARG NEXT_PUBLIC_SITE_URL=https://futureporn.net ARG NEXT_PUBLIC_STRAPI_URL=https://portal.futureporn.net ARG NEXT_PUBLIC_UPPY_COMPANION_URL=https://uppy.futureporn.net ENV NEXT_PUBLIC_SITE_URL ${NEXT_PUBLIC_SITE_URL} ENV NEXT_PUBLIC_STRAPI_URL ${NEXT_PUBLIC_STRAPI_URL} ENV NEXT_PUBLIC_UPPY_COMPANION_URL ${NEXT_PUBLIC_UPPY_COMPANION_URL} ENV NEXT_TELEMETRY_DISABLED 1 COPY . /usr/src/app WORKDIR /usr/src/app RUN mkdir -p /prod RUN pnpm fetch ## strapi needs node-gyp RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install -g node-gyp RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile ENV NODE_ENV production RUN pnpm --recursive build ## we use pnpm deploy to create bundled, isolated node packages for docker containers. See https://pnpm.io/cli/deploy ## we can deploy most packages this way, but with some projects such as next it's not necessary as next's build step packages all dependencies. RUN pnpm deploy --filter=boop --prod /prod/boop RUN pnpm deploy --filter=scout --prod /prod/scout FROM base AS strapi COPY --from=build /usr/src/app/packages/strapi . CMD ["run", "develop"] # NODE_ENV=development is important for the fp/next build. ## @todo remove the --filter FROM base AS boop COPY --from=build /prod/boop /app CMD ["start"] # COPY pnpm-lock.yaml ./ # RUN pnpm fetch # COPY ./packages/next /app # RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store pnpm install # FROM base AS next-prep # ARG NEXT_PUBLIC_SITE_URL=https://futureporn.net # ARG NEXT_PUBLIC_STRAPI_URL=https://portal.futureporn.net # ARG NEXT_PUBLIC_UPPY_COMPANION_URL=https://uppy.futureporn.net # ENV NEXT_PUBLIC_SITE_URL ${NEXT_PUBLIC_SITE_URL} # ENV NEXT_PUBLIC_STRAPI_URL ${NEXT_PUBLIC_STRAPI_URL} # ENV NEXT_PUBLIC_UPPY_COMPANION_URL ${NEXT_PUBLIC_UPPY_COMPANION_URL} # ENV NEXT_TELEMETRY_DISABLED 1 # COPY pnpm-lock.yaml ./ # COPY ./packages/next /app # RUN pnpm fetch # RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store pnpm install # FROM base AS next-build # COPY --from=build /prod/next /app # # RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store pnpm install # # RUN ls -la # RUN pnpm run build FROM base as next RUN apt-get update && apt-get install -y -qq --no-install-recommends dumb-init COPY --chown=node:node --from=build /usr/src/app/packages/next/public ./public COPY --chown=node:node --from=build /usr/src/app/packages/next/.next/standalone ./ COPY --chown=node:node --from=build /usr/src/app/packages/next/.next/static ./.next/static ENV TZ=UTC ENV NODE_ENV=production ENV HOSTNAME="0.0.0.0" ENTRYPOINT [ "dumb-init", "node", "server.js" ] # FROM base AS next-pre # COPY --from=build /prod/next /app # ENV NODE_EXTRA_CA_CERTS "/app/letsencrypt-stg-root-x1.pem" # FROM next-pre AS next-dev # CMD ["pnpm", "run", "dev"] # FROM next-pre AS next-build # RUN pnpm run build # FROM base AS next # RUN apt-get update && apt-get install -y -qq --no-install-recommends dumb-init # # COPY --chown=node:node --from=build /prod/next . # COPY --chown=node:node --from=next-build /app/package.json /app/pnpm-lock.yaml ./ # RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile # COPY --chown=node:node --from=next-build /app/public ./public # COPY --chown=node:node --from=next-build /app/.next/standalone ./ # COPY --chown=node:node --from=next-build /app/.next/static ./.next/static # RUN ls -la . # ENV TZ=UTC # ENV NODE_ENV=production # ENV HOSTNAME="0.0.0.0" # ENTRYPOINT [ "dumb-init", "node", "server.js" ] # FROM base AS scout-manager # COPY --from=build /prod/scout /app # CMD ["run", "start:manager"] # FROM base AS scout-worker # COPY --from=build /prod/scout /app # COPY --from=build /usr/src/app/certs/letsencrypt-stg-root-x1.pem /app # ENV NODE_EXTRA_CA_CERTS "/app/certs/letsencrypt-stg-root-x1.pem" # CMD ["run", "start:worker"] # FROM base AS temporal-worker # COPY --from=build /prod/temporal-worker /app # CMD ["run", "start"] # FROM base AS bot-prep # COPY --from=build /prod/bot /app # FROM bot-prep AS bot # CMD ["run", "start"] # FROM bot-prep AS bot-dev # CMD ["run", "dev"]