From 74ee07d64fc08ff4d8d3f1adc9f3d1dece6aafc9 Mon Sep 17 00:00:00 2001 From: Jake Runyan Date: Thu, 12 Feb 2026 23:22:13 -0800 Subject: [PATCH] Dockerize --- .claude/settings.local.json | 4 +++- .dockerignore | 11 +++++++++++ Dockerfile | 28 ++++++++++++++++++++++++++++ README.md | 4 +++- app/about/page.tsx | 3 +-- app/page.tsx | 2 +- docker-compose.yml | 16 ++++++++++++++++ next.config.ts | 1 + 8 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 6406045..8175ca9 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -13,7 +13,9 @@ "Bash(timeout 10 npm run dev:*)", "Bash(grep:*)", "Read(//c/Users/runya/Documents/repositories/recipes/recipes/docs/**)", - "Bash(node scripts/import-recipes.js:*)" + "Bash(node scripts/import-recipes.js:*)", + "Bash(powershell.exe -Command \"Test-Path ''c:\\\\Users\\\\runya\\\\Documents\\\\repositories\\\\cooking\\\\.next\\\\standalone\\\\server.js''\")", + "Bash(powershell.exe -Command:*)" ] } } diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..676eb40 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +node_modules +.next +.git +.gitignore +.claude +*.md +!README.md +Dockerfile +docker-compose.yml +.dockerignore +.env* diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..88aff64 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +FROM node:20-alpine AS deps +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm ci + +FROM node:20-alpine AS build +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . +RUN npm run build + +FROM node:20-alpine AS runner +WORKDIR /app +ENV NODE_ENV=production +ENV HOSTNAME=0.0.0.0 +ENV PORT=3000 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=build /app/public ./public +COPY --from=build --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=build --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs +EXPOSE 3000 + +CMD ["node", "server.js"] diff --git a/README.md b/README.md index f577e5e..8e08a5c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # cooking -Content-first recipe site. +A content-first recipe site. See it in action [HERE](https://recipes.whitney.rip). + + diff --git a/app/about/page.tsx b/app/about/page.tsx index 13a1980..a0de533 100644 --- a/app/about/page.tsx +++ b/app/about/page.tsx @@ -35,8 +35,7 @@ export default function AboutPage() { Each recipe is organized in its own folder with:

diff --git a/app/page.tsx b/app/page.tsx index 5557069..d6506a4 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -64,7 +64,7 @@ export default function Home() {

But Recipe Sites Suck!

- Monetized recipe sites don't bother me, but I do mind when sites have overly aggressive ad integrations that block or move around the main content. Many modern sites share the same user-unfriendly plugins. + Monetized recipe sites don't bother me, but I do mind when sites have overly aggressive ad integrations that block or move around the main content. Many modern sites share the same user-unfriendly plugins.

diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..80f11f6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,16 @@ +services: + cooking: + build: . + restart: unless-stopped + networks: + - traefik + labels: + - "traefik.enable=true" + - "traefik.http.routers.cooking.rule=Host(`recipes.whitney.rip`)" + - "traefik.http.routers.cooking.entrypoints=websecure" + - "traefik.http.routers.cooking.tls.certresolver=letsencrypt" + - "traefik.http.services.cooking.loadbalancer.server.port=3000" + +networks: + traefik: + external: true diff --git a/next.config.ts b/next.config.ts index 95a6154..0557ce1 100644 --- a/next.config.ts +++ b/next.config.ts @@ -2,6 +2,7 @@ import type { NextConfig } from "next"; import createMDX from '@next/mdx'; const nextConfig: NextConfig = { + output: 'standalone', reactStrictMode: true, pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'], };