From 53c793342a4d6c042ef9eb21156f8c815fabbe9c Mon Sep 17 00:00:00 2001 From: Jeff Emmett Date: Fri, 26 Dec 2025 22:56:05 -0500 Subject: [PATCH] Add Docker support for self-hosting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Dockerfile with multi-stage build for Next.js - Add docker-compose.yml with Traefik labels for jeffemmett.com - Add .dockerignore - Configure next.config.mjs for standalone output 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .dockerignore | 8 ++++++++ Dockerfile | 43 +++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 28 ++++++++++++++++++++++++++++ next.config.mjs | 2 +- 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1bb8bd6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +node_modules +.next +.git +.gitignore +README.md +*.log +.env* +.vercel diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..40c87a7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,43 @@ +# Build stage +FROM node:20-alpine AS builder + +# Install pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +WORKDIR /app + +# Copy package files +COPY package.json pnpm-lock.yaml ./ + +# Install dependencies +RUN pnpm install --frozen-lockfile + +# Copy source files +COPY . . + +# Build the Next.js app +ENV NEXT_TELEMETRY_DISABLED=1 +RUN pnpm build + +# Production stage +FROM node:20-alpine AS runner + +WORKDIR /app + +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 + +# Install pnpm for production +RUN corepack enable && corepack prepare pnpm@latest --activate + +# Copy necessary files from builder +COPY --from=builder /app/.next/standalone ./ +COPY --from=builder /app/.next/static ./.next/static +COPY --from=builder /app/public ./public + +EXPOSE 3000 + +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +CMD ["node", "server.js"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..71b45b0 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,28 @@ +# Jeff Emmett Personal Website +# Serves: jeffemmett.com, www.jeffemmett.com + +services: + personal-site: + build: + context: . + dockerfile: Dockerfile + container_name: personal-site + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik-public" + - "traefik.http.services.personal-site.loadbalancer.server.port=3000" + - "traefik.http.routers.personal-site.rule=Host(`jeffemmett.com`) || Host(`www.jeffemmett.com`)" + - "traefik.http.routers.personal-site.entrypoints=web" + - "traefik.http.routers.personal-site.service=personal-site" + networks: + - traefik-public + healthcheck: + test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + +networks: + traefik-public: + external: true diff --git a/next.config.mjs b/next.config.mjs index cd7723a..8f9dc9b 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,12 +1,12 @@ /** @type {import('next').NextConfig} */ const nextConfig = { + output: 'standalone', typescript: { ignoreBuildErrors: true, }, images: { unoptimized: true, }, - } export default nextConfig