Step-by-Step Guide to Deploying and Running Remix 2.3.1 with Prisma in Production on Docker
This guide explains how to deploy a Remix 2.3.1 application using Prisma in a Docker container for production environments. The process is demonstrated using a specific Dockerfile.
Prerequisites
- Basic understanding of Docker and containerization
- Docker installed on your system
- Node.js knowledge
- Familiarity with Remix and Prisma frameworks
Dockerfile Breakdown
The provided Dockerfile is structured into multiple stages to optimize the build process and minimize the final image size.
Base Image and Dependencies
Dockerfile
FROM node:21.3.0-alpine3.17 as base ENV NODE_ENV production RUN apk update && apk --no-cache add build-base postgresql-dev RUN apk add tzdata
This section sets up the base image using node:21.3.0-alpine3.17 and installs necessary dependencies.
Installing Dependencies
Dockerfile
# Install all node_modules, including dev dependencies FROM base as deps WORKDIR /myapp ADD package.json ./ RUN npm install --include=dev
It installs all node modules, including development dependencies.
Setting Up Production Dependencies
Dockerfile
# Setup production node_modules FROM base as production-deps WORKDIR /myapp COPY --from=deps /myapp/node_modules /myapp/node_modules ADD package.json ./ RUN npm prune --omit=dev
This stage copies the node modules and prunes them to keep only what is needed for production.
Building the App
Dockerfile
# Build the appFROM base as build WORKDIR /myapp COPY --from=deps /myapp/node_modules /myapp/node_modules COPY .env_production /myapp/.env ADD prisma . RUN npx prisma generate ADD . . RUN npm run build
Here, the application is built. It includes copying environment variables, generating Prisma client, and running the build script.
Creating the Production Image
Dockerfile
# Finally, build the production image with minimal footprint FROM base WORKDIR /myapp COPY --from=production-deps /myapp/node_modules /myapp/node_modules COPY --from=build /myapp/node_modules/.prisma /myapp/node_modules/.prisma COPY --from=build /myapp/build /myapp/build COPY --from=build /myapp/public /myapp/public COPY --from=build /myapp/package.json /myapp/package.json COPY --from=build /myapp/start.sh /myapp/start.sh COPY --from=build /myapp/prisma /myapp/prisma COPY --from=build /myapp/.env /myapp/.env ENTRYPOINT [ "./start.sh" ]
The final stage creates a minimal production image. It copies the built application and its dependencies from the previous stages.
Deploying with Docker
- Build the Docker Image: Run docker build -t your-app-name . to create the Docker image.
- Running the Container: Start the container using docker run -d your-app-name.
PS start.sh script:
npx prisma migrate deploy npm run start
PPS and a full Dockerfile:
# base node image FROM node:21.3.0-alpine3.17 as base ENV NODE_ENV production RUN apk update && apk --no-cache add build-base postgresql-dev RUN apk add tzdata # Install all node_modules, including dev dependencies FROM base as deps WORKDIR /myapp ADD package.json ./ RUN npm install --include=dev # Setup production node_modules FROM base as production-deps WORKDIR /myapp COPY --from=deps /myapp/node_modules /myapp/node_modules ADD package.json ./ RUN npm prune --omit=dev # Build the app FROM base as build WORKDIR /myapp COPY --from=deps /myapp/node_modules /myapp/node_modules COPY .env_production /myapp/.env ADD prisma . RUN npx prisma generate ADD . . RUN npm run build # Finally, build the production image with minimal footprint FROM base WORKDIR /myapp COPY --from=production-deps /myapp/node_modules /myapp/node_modules COPY --from=build /myapp/node_modules/.prisma /myapp/node_modules/.prisma COPY --from=build /myapp/build /myapp/build COPY --from=build /myapp/public /myapp/public COPY --from=build /myapp/package.json /myapp/package.json COPY --from=build /myapp/start.sh /myapp/start.sh COPY --from=build /myapp/prisma /myapp/prisma COPY --from=build /myapp/.env /myapp/.env ENTRYPOINT [ "./start.sh" ]
PPS And do not forget to add .dockerignore file for Remix while building! Put it on the same level as Dockerfile.
/node_modules *.log .DS_Store .env /.cache /public/build /build