Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/publishImage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Publish Docker image

on:
pull_request:
branches: [ main ]
release:
types: [ published ]

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- uses: actions/checkout@v4

- uses: docker/setup-buildx-action@v3

- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}/distcode
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=raw,value=latest,enable={{is_default_branch}}
type=sha

- uses: docker/build-push-action@v5
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
DATABASE_URL=${{ secrets.DATABASE_URL }}
NEXTAUTH_URL=${{ secrets.NEXTAUTH_URL }}
NEXTAUTH_SECRET=${{ secrets.NEXTAUTH_SECRET }}
GLITHUB_CLIENT_ID=${{ secrets.GLITHUB_CLIENT_ID }}
GLITHUB_CLIENT_SECRET=${{ secrets.GLITHUB_CLIENT_SECRET }}
GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }}
GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }}
POSTGRES_DB=${{ secrets.POSTGRES_DB }}
POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }}
POSTGRES_USER=${{ secrets.POSTGRES_USER }}
RABBITMQ_URL=${{ secrets.RABBITMQ_URL }}
RABBITMQ_EXCHANGE=${{ secrets.RABBITMQ_EXCHANGE }}
RABBITMQ_EXCHANGETYPE=${{ secrets.RABBITMQ_EXCHANGETYPE }}
RABBITMQ_QUEUE=${{ secrets.RABBITMQ_QUEUE }}
RABBITMQ_ROUTING_KEY=${{ secrets.RABBITMQ_ROUTING_KEY }}

126 changes: 109 additions & 17 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,28 +1,120 @@
# 1. Install dependencies only when needed
FROM node:22-alpine AS deps
# Use the official Node.js 22 Slim image as a base for better compatibility
FROM node:22-slim AS base

# Stage 1: Install dependencies
FROM base AS deps
WORKDIR /app
RUN npm install -g pnpm

COPY package.json pnpm-lock.yaml* ./
RUN pnpm install --frozen-lockfile
# Copy package manifests and install all dependencies
COPY package.json pnpm-lock.yaml* .npmrc* ./
RUN corepack enable pnpm && pnpm i --frozen-lockfile

# 2. Rebuild the source code only when needed
FROM node:22-alpine AS builder
# Stage 2: Build the application
FROM base AS builder
WORKDIR /app
RUN npm install -g pnpm

# Define build-time arguments for environment variables
ARG DATABASE_URL
ARG NEXTAUTH_URL
ARG NEXTAUTH_SECRET
ARG GLITHUB_CLIENT_ID
ARG GLITHUB_CLIENT_SECRET
ARG GOOGLE_CLIENT_ID
ARG GOOGLE_CLIENT_SECRET
ARG POSTGRES_DB
ARG POSTGRES_PASSWORD
ARG POSTGRES_USER
ARG RABBITMQ_URL
ARG RABBITMQ_EXCHANGE
ARG RABBITMQ_EXCHANGETYPE
ARG RABBITMQ_QUEUE
ARG RABBITMQ_ROUTING_KEY

# Set environment variables for the build process
ENV DATABASE_URL=$DATABASE_URL
ENV NEXTAUTH_URL=$NEXTAUTH_URL
ENV NEXTAUTH_SECRET=$NEXTAUTH_SECRET
ENV GLITHUB_CLIENT_ID=$GLITHUB_CLIENT_ID
ENV GLITHUB_CLIENT_SECRET=$GLITHUB_CLIENT_SECRET
ENV GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID
ENV GOOGLE_CLIENT_SECRET=$GOOGLE_CLIENT_SECRET
ENV POSTGRES_DB=$POSTGRES_DB
ENV POSTGRES_PASSWORD=$POSTGRES_PASSWORD
ENV POSTGRES_USER=$POSTGRES_USER
ENV RABBITMQ_URL=$RABBITMQ_URL
ENV RABBITMQ_EXCHANGE=$RABBITMQ_EXCHANGE
ENV RABBITMQ_EXCHANGETYPE=$RABBITMQ_EXCHANGETYPE
ENV RABBITMQ_QUEUE=$RABBITMQ_QUEUE
ENV RABBITMQ_ROUTING_KEY=$RABBITMQ_ROUTING_KEY

# Copy dependencies and source code
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN pnpm build

# 3. Production image, copy all the files and run nextjs
FROM node:22-alpine AS runner
# Build the Next.js application using pnpm
RUN corepack enable pnpm && pnpm run build

# Stage 3: Production image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
RUN npm install -g pnpm
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json

ENV NODE_ENV=production

# Create a non-root user for security (Debian-style)
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# We only need production dependencies to run the app
COPY package.json pnpm-lock.yaml* .npmrc* ./
RUN corepack enable pnpm && pnpm i --prod --frozen-lockfile


# Define build-time arguments for environment variables
ARG DATABASE_URL
ARG NEXTAUTH_URL
ARG NEXTAUTH_SECRET
ARG GLITHUB_CLIENT_ID
ARG GLITHUB_CLIENT_SECRET
ARG GOOGLE_CLIENT_ID
ARG GOOGLE_CLIENT_SECRET
ARG POSTGRES_DB
ARG POSTGRES_PASSWORD
ARG POSTGRES_USER
ARG RABBITMQ_URL
ARG RABBITMQ_EXCHANGE
ARG RABBITMQ_EXCHANGETYPE
ARG RABBITMQ_QUEUE
ARG RABBITMQ_ROUTING_KEY

# Set environment variables for the build process
ENV DATABASE_URL=$DATABASE_URL
ENV NEXTAUTH_URL=$NEXTAUTH_URL
ENV NEXTAUTH_SECRET=$NEXTAUTH_SECRET
ENV GLITHUB_CLIENT_ID=$GLITHUB_CLIENT_ID
ENV GLITHUB_CLIENT_SECRET=$GLITHUB_CLIENT_SECRET
ENV GOOGLE_CLIENT_ID=$GOOGLE_CLIENT_ID
ENV GOOGLE_CLIENT_SECRET=$GOOGLE_CLIENT_SECRET
ENV POSTGRES_DB=$POSTGRES_DB
ENV POSTGRES_PASSWORD=$POSTGRES_PASSWORD
ENV POSTGRES_USER=$POSTGRES_USER
ENV RABBITMQ_URL=$RABBITMQ_URL
ENV RABBITMQ_EXCHANGE=$RABBITMQ_EXCHANGE
ENV RABBITMQ_EXCHANGETYPE=$RABBITMQ_EXCHANGETYPE
ENV RABBITMQ_QUEUE=$RABBITMQ_QUEUE
ENV RABBITMQ_ROUTING_KEY=$RABBITMQ_ROUTING_KEY

# Copy the built application from the builder stage, setting ownership
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/package.json .

# Switch to the non-root user
USER nextjs

EXPOSE 3000

ENV PORT=3000

# Start the Next.js server using pnpm start (which runs `next start`)
CMD ["pnpm", "start"]
1 change: 1 addition & 0 deletions next.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
output: "standalone",
turbopack: {
rules: {
"*.svg": {
Expand Down