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
FROM node:22-alpine AS deps
# ---------- Base for installs ----------
FROM node:22-alpine AS base
WORKDIR /app
# ---------- Production deps ----------
FROM base AS deps
COPY package*.json ./
# nur Prod-Deps für die runner-Stage (schnellerer Start, kleineres Image)
RUN npm ci --only=production
FROM node:22-alpine AS builder
WORKDIR /app
# ---------- Full deps + Build ----------
FROM base AS builder
COPY package*.json ./
# volle Deps inkl. devDependencies
RUN npm ci
# Rest des Codes
COPY . .
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
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# Create non-root user
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# non-root user
RUN addgroup --system --gid 1001 nodejs \
&& 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 --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# Health check
# Health check (pfad anpassen, falls dein Endpoint anders heißt)
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"]

View File

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

31
package-lock.json generated
View File

@ -1,13 +1,14 @@
{
"name": "hamtonbrown-cpa",
"name": "hamptonbrown-associates",
"version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "hamtonbrown-cpa",
"name": "hamptonbrown-associates",
"version": "0.1.0",
"dependencies": {
"@hookform/resolvers": "^3.3.2",
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
@ -16,6 +17,7 @@
"next-sitemap": "^4.2.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.48.2",
"resend": "^2.1.0",
"tailwind-merge": "^2.0.0",
"tailwindcss-animate": "^1.0.7",
@ -151,6 +153,15 @@
"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": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
@ -5495,6 +5506,22 @@
"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": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",