The application includes a production-ready multi-stage Dockerfile optimized for React Router 7 applications.
Dockerfile Configuration
The Dockerfile uses a multi-stage build process to minimize the final image size:
FROM node:20-alpine AS development-dependencies-env
COPY . /app
WORKDIR /app
RUN npm ci
FROM node:20-alpine AS production-dependencies-env
COPY ./package.json package-lock.json /app/
WORKDIR /app
RUN npm ci --omit=dev
FROM node:20-alpine AS build-env
COPY . /app/
COPY --from=development-dependencies-env /app/node_modules /app/node_modules
WORKDIR /app
RUN npm run build
FROM node:20-alpine
COPY ./package.json package-lock.json /app/
COPY --from=production-dependencies-env /app/node_modules /app/node_modules
COPY --from=build-env /app/build /app/build
WORKDIR /app
CMD ["npm", "run", "start"]
Build Stages Explained
- development-dependencies-env: Installs all dependencies including dev dependencies
- production-dependencies-env: Installs only production dependencies
- build-env: Builds the React Router application
- Final stage: Creates the minimal runtime image with only production dependencies and build output
Building the Docker Image
Build the image
Build the Docker image from the project root:docker build -t portfolio-javier-navas .
Run the container
Run the container with port mapping:docker run -p 3000:3000 portfolio-javier-navas
The application will be available at http://localhost:3000. Run with environment variables
If your application requires MongoDB, pass environment variables:docker run -p 3000:3000 \
-e MONGODB_URI="mongodb+srv://user:[email protected]/?retryWrites=true&w=majority" \
-e MONGODB_DB="portafolio" \
-e MONGODB_COLLECTION_NFQ="nfq" \
portfolio-javier-navas
Never hardcode sensitive credentials in the Dockerfile. Always pass them as environment variables at runtime.
The containerized application can be deployed to any platform that supports Docker:
# Build and push to ECR
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <account-id>.dkr.ecr.us-east-1.amazonaws.com
docker build -t portfolio-javier-navas .
docker tag portfolio-javier-navas:latest <account-id>.dkr.ecr.us-east-1.amazonaws.com/portfolio-javier-navas:latest
docker push <account-id>.dkr.ecr.us-east-1.amazonaws.com/portfolio-javier-navas:latest
Port Configuration
The application runs on port 3000 by default. Make sure to:
- Expose port 3000 in your container orchestration platform
- Configure health checks on
http://localhost:3000
- Map the container port to your desired host port
Build Output Structure
After building, the application contains:
├── package.json
├── package-lock.json
├── build/
│ ├── client/ # Static assets (JS, CSS, images)
│ └── server/ # Server-side code (index.js)
The Docker container runs npm run start which executes:
"start": "react-router-serve ./build/server/index.js"
Next Steps
MongoDB Setup
Configure MongoDB connection for production
Environment Variables
Set up required environment variables