changed docker

This commit is contained in:
Andreas Knuth 2025-08-27 17:37:22 -05:00
parent 93301696cf
commit 1832f98d40
3 changed files with 82 additions and 30 deletions

View File

@ -1,40 +1,61 @@
# Multi-stage build for production # ---------- Base for installs ----------
FROM node:22-alpine AS deps FROM node:22-alpine AS base
WORKDIR /app WORKDIR /app
# ---------- Production deps ----------
FROM base AS deps
COPY package*.json ./ COPY package*.json ./
# nur Prod-Deps für die runner-Stage (schnellerer Start, kleineres Image)
RUN npm ci --only=production RUN npm ci --only=production
FROM node:22-alpine AS builder # ---------- Full deps + Build ----------
WORKDIR /app FROM base AS builder
COPY package*.json ./ COPY package*.json ./
# volle Deps inkl. devDependencies
RUN npm ci RUN npm ci
# Rest des Codes
COPY . . COPY . .
RUN npm run build RUN npm run build
# ---------- Development stage ----------
FROM base AS dev
ENV NODE_ENV=development
# nur package-Dateien kopieren, damit npm install gecacht wird
COPY package*.json ./
RUN npm install
# Quellcode kommt zur Laufzeit per Bind-Mount aus Compose
# (sorgt für Hot Reload)
EXPOSE 3000
ENV HOSTNAME="0.0.0.0"
CMD ["npm", "run", "dev"]
# ---------- Production runner ----------
FROM node:22-alpine AS runner FROM node:22-alpine AS runner
WORKDIR /app WORKDIR /app
ENV NODE_ENV=production ENV NODE_ENV=production
ENV PORT=3000 ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# Create non-root user # non-root user
RUN addgroup --system --gid 1001 nodejs RUN addgroup --system --gid 1001 nodejs \
RUN adduser --system --uid 1001 nextjs && adduser --system --uid 1001 nextjs
# Copy built application # für Healthcheck
RUN apk add --no-cache curl
# statische Assets & Standalone-Output aus builder
COPY --from=builder /app/public ./public COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs USER nextjs
EXPOSE 3000 EXPOSE 3000
ENV PORT=3000 # Health check (pfad anpassen, falls dein Endpoint anders heißt)
ENV HOSTNAME="0.0.0.0"
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/api/health || exit 1 CMD curl -fsS http://127.0.0.1:3000/api/health || exit 1
# Next.js standalone startet über server.js
CMD ["node", "server.js"] CMD ["node", "server.js"]

View File

@ -1,38 +1,42 @@
version: '3.8'
services: services:
# Development service # ---- Development ----
app-dev: app-dev:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
target: dev
ports: ports:
- "3000:3000" - "3000:3000"
volumes:
- .:/app
- /app/node_modules
- /app/.next
environment: environment:
- NODE_ENV=development - NODE_ENV=development
command: npm run dev - HOSTNAME=0.0.0.0
profiles: # Hot-Reload & persistente Caches
- dev volumes:
- .:/app
- node_modules:/app/node_modules
- next:/app/.next
# CMD kommt aus Dockerfile (npm run dev)
profiles: [dev]
# Production service # ---- Production ----
app-prod: app-prod:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
# target: runner # (optional; letzter Stage ist ohnehin runner)
ports: ports:
- "3000:3000" - "3010:3000"
environment: environment:
- NODE_ENV=production - NODE_ENV=production
- SITE_URL=${SITE_URL:-https://hamtonbrown.com} - SITE_URL=${SITE_URL:-https://hamtonbrown.com}
- CONTACT_TO_EMAIL=${CONTACT_TO_EMAIL:-contact@hamtonbrown.com} - CONTACT_TO_EMAIL=${CONTACT_TO_EMAIL:-contact@hamtonbrown.com}
- RESEND_API_KEY=${RESEND_API_KEY} - RESEND_API_KEY=${RESEND_API_KEY}
restart: unless-stopped restart: unless-stopped
profiles: profiles: [prod]
- prod
volumes:
node_modules:
next:
networks: networks:
default: default:

31
package-lock.json generated
View File

@ -1,13 +1,14 @@
{ {
"name": "hamtonbrown-cpa", "name": "hamptonbrown-associates",
"version": "0.1.0", "version": "0.1.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "hamtonbrown-cpa", "name": "hamptonbrown-associates",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@hookform/resolvers": "^3.3.2",
"@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.0.0", "clsx": "^2.0.0",
@ -16,6 +17,7 @@
"next-sitemap": "^4.2.3", "next-sitemap": "^4.2.3",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-hook-form": "^7.48.2",
"resend": "^2.1.0", "resend": "^2.1.0",
"tailwind-merge": "^2.0.0", "tailwind-merge": "^2.0.0",
"tailwindcss-animate": "^1.0.7", "tailwindcss-animate": "^1.0.7",
@ -151,6 +153,15 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
} }
}, },
"node_modules/@hookform/resolvers": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.10.0.tgz",
"integrity": "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==",
"license": "MIT",
"peerDependencies": {
"react-hook-form": "^7.0.0"
}
},
"node_modules/@humanwhocodes/config-array": { "node_modules/@humanwhocodes/config-array": {
"version": "0.13.0", "version": "0.13.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
@ -5495,6 +5506,22 @@
"react": "^18.3.1" "react": "^18.3.1"
} }
}, },
"node_modules/react-hook-form": {
"version": "7.62.0",
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.62.0.tgz",
"integrity": "sha512-7KWFejc98xqG/F4bAxpL41NB3o1nnvQO1RWZT3TqRZYL8RryQETGfEdVnJN2fy1crCiBLLjkRBVK05j24FxJGA==",
"license": "MIT",
"engines": {
"node": ">=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/react-hook-form"
},
"peerDependencies": {
"react": "^16.8.0 || ^17 || ^18 || ^19"
}
},
"node_modules/react-is": { "node_modules/react-is": {
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",