Skip to content

Commit

Permalink
Docker image build improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
kahlstrm committed Jan 15, 2024
1 parent c4f78fb commit 2c59572
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 43 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ npm-debug.log
.gitignore
*.md
dist
uploads/
9 changes: 9 additions & 0 deletions .env.docker-compose.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
PAYLOAD_DATABASE_URL="mongodb://mongo/payload"
PAYLOAD_SECRET="verysecretkey"
PAYLOAD_REVALIDATION_KEY="veryprivatekey"
PAYLOAD_PORT=3001

NEXT_REVALIDATION_KEY="veryprivatekey"

PUBLIC_FRONTEND_URL="http://localhost:3000"
PUBLIC_SERVER_URL="http://cms:3001"
35 changes: 11 additions & 24 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,15 @@ ARG NODE_VERSION=20
# Use a specific version of the Node.js Alpine image as the base. Alpine images are minimal and lightweight.
FROM node:${NODE_VERSION}-alpine AS base
# Update the package list and install libc6-compat. This package is often required for binary Node.js modules.
RUN apk update && apk add --no-cache libc6-compat
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
RUN pnpm config set store-dir ~/.pnpm-store

# Set environment variables (copied from .env.example)
# TODO: Figure out a better way to do this
ENV PAYLOAD_DATABASE_URL="mongodb://127.0.0.1:27017/payload"
ENV PAYLOAD_SECRET="verysecretkey"
ENV PAYLOAD_REVALIDATION_KEY="veryprivatekey"
ENV PAYLOAD_PORT=3001
ENV [email protected]
ENV PAYLOAD_DEVELOPMENT_AUTOLOGIN_PASSWORD=root
ENV PAYLOAD_LOCAL_DEVELOPMENT=true

ENV NEXT_REVALIDATION_KEY="veryprivatekey"

ENV PUBLIC_FRONTEND_URL="http://localhost:3000"
ENV PUBLIC_SERVER_URL="http://localhost:3001"

RUN apk add --no-cache libc6-compat

# Setup pnpm and turbo
# Start a new stage based on the base image for setting up pnpm (a package manager) and turbo (for monorepo management).
FROM base as setup
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
RUN pnpm config set store-dir ~/.pnpm-store
RUN pnpm install --global turbo

# Build argument for specifying the project
Expand Down Expand Up @@ -56,7 +40,7 @@ RUN rm -rf /app/out/full/*/*/node_modules

# Build the project using turbo
# Start a new stage for building the project. This stage will compile and prepare the project for production.
FROM pruner AS builder
FROM setup AS builder
WORKDIR /app

# Copy pruned lockfile and package.json files
Expand All @@ -68,7 +52,7 @@ COPY --from=pruner /app/out/json/ .
# Install dependencies for the pruned project
# Utilize BuildKit's cache to speed up the dependency installation process.
RUN --mount=type=cache,id=pnpm,target=~/.pnpm-store pnpm install
# TODO Readd: --frozen-lockfile when turbo prune is fixed https://github.com/vercel/turbo/issues/3382#issuecomment-1684098542
# TODO Re-add: --frozen-lockfile when turbo prune is fixed https://github.com/vercel/turbo/issues/3382#issuecomment-1684098542

# Copy pruned source code
# Bring in the necessary source code to the builder stage for compilation.
Expand All @@ -77,13 +61,16 @@ COPY --from=pruner /app/out/full/ .
# Build with turbo and prune dev dependencies
# Use turbo to build the project, followed by pruning development dependencies to minimize the final image size.
RUN turbo build --filter=${PROJECT}...
RUN --mount=type=cache,id=pnpm,target=~/.pnpm-store pnpm prune --prod --no-optional
# NOTE: --no-optional breaks payload webpack build, let's not use it :)
RUN --mount=type=cache,id=pnpm,target=~/.pnpm-store rm -rf node_modules && pnpm install --prod
# Remove source files to further reduce the image size, keeping only the compiled output and necessary runtime files.
RUN rm -rf ./**/*/src

# Final production image
# Start the final stage for the production-ready image.
FROM base AS runner
#this needs to be here for some reason again, otherwise the WORKDIR command doesn't pick it up
ARG PROJECT=web
# Create a non-root user and group for better security.
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nodejs
Expand Down
15 changes: 0 additions & 15 deletions apps/web/next.config.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,6 @@
/** @type {import("next").NextConfig} */
module.exports = {
reactStrictMode: true,
rewrites: () => [
{
source: "/admin/:path*",
destination: `${process.env.PUBLIC_SERVER_URL}/admin/:path*`,
},
{
source: "/api/:path*",
destination: `${process.env.PUBLIC_SERVER_URL}/api/:path*`,
},
// TODO: only for dev:
{
source: "/media/:path*",
destination: `${process.env.PUBLIC_SERVER_URL}/media/:path*`,
},
],
images: {
// TODO: only for dev:
remotePatterns: [
Expand Down
15 changes: 14 additions & 1 deletion apps/web/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,23 @@ import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";

export function middleware(request: NextRequest): NextResponse {
const pathname = request.nextUrl.pathname;
if (
pathname.startsWith("/admin") ||
pathname.startsWith("/media") ||
pathname.startsWith("/api")
) {
const destination = new URL(process.env.PUBLIC_SERVER_URL || "");
const url = request.nextUrl.clone();
url.host = destination.host;
url.port = destination.port;
url.pathname = pathname;
return NextResponse.rewrite(url);
}
return NextResponse.redirect(
new URL(`/fi/${request.nextUrl.pathname}`, request.url),
);
}
export const config = {
matcher: ["/((?!_next|api|media|admin|fi|en).*)"],
matcher: ["/((?!_next|fi|en).*)"],
};
8 changes: 5 additions & 3 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ services:
depends_on:
- mongo
env_file:
- .env
- .env.docker-compose.prod
expose:
- 3001

Expand All @@ -30,11 +30,13 @@ services:
args:
- PROJECT=web
depends_on:
- mongo
- cms
env_file:
- .env
- .env.docker-compose.prod
expose:
- 3000
ports:
- 3000:3000

volumes:
data:

0 comments on commit 2c59572

Please sign in to comment.