feat: scaffolding with standalone docker base

This commit is contained in:
opencode committed 2026-10-18 10:26:21 +02:00
1 parent e8e293e08f
commit 5ba920eb11
10 files changed
+3329

No files matched your search

+11
View File
@@ -0,0 +1,11 @@
node_modules
.next
.git
.worktrees
.superpowers
Dockerfile
docker-compose.yml
.dockerignore
.env
.env*.local
npm-debug.log
+12
View File
@@ -0,0 +1,12 @@
DATABASE_URL=file:/data/gutscheine.db
APP_USER=haushalt
APP_PASSWORD_HASH=$2b$10$REPLACE_ME
SESSION_SECRET=REPLACE_WITH_32_CHARS_MIN
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
MAIL_FROM=gutscheine@example.de
TELEGRAM_BOT_TOKEN=
CRON_SECRET=REPLACE_ME
TZ=Europe/Berlin
+19
View File
@@ -0,0 +1,19 @@
FROM node:22-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci
FROM node:22-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npx prisma generate && npm run build
FROM node:22-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production PORT=3000 HOSTNAME=0.0.0.0
RUN addgroup -S app && adduser -S app -G app
COPY --from=builder --chown=app:app /app/.next/standalone ./
COPY --from=builder --chown=app:app /app/.next/static ./.next/static
COPY --from=builder --chown=app:app /app/prisma ./prisma
USER app
EXPOSE 3000
CMD ["node", "server.js"]
+9
View File
@@ -0,0 +1,9 @@
services:
app:
build: .
ports: ["3000:3000"]
volumes: ["gutschein-data:/data"]
env_file: [.env]
restart: unless-stopped
volumes:
gutschein-data: {}
+3
View File
@@ -0,0 +1,3 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = { output: "standalone" };
export default nextConfig;
+3213
View File
File diff suppressed because it is too large. Load diff
+27
View File
@@ -0,0 +1,27 @@
{
"name": "gutscheintracker",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"test": "vitest run"
},
"dependencies": {
"next": "15.3.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"prisma": "6.5.0",
"@prisma/client": "6.5.0",
"nodemailer": "6.9.14",
"bcryptjs": "2.4.3",
"jose": "5.9.6"
},
"devDependencies": {
"typescript": "5.6.3",
"vitest": "3.0.0",
"@types/node": "22.7.0",
"@types/nodemailer": "6.4.16",
"@types/bcryptjs": "2.4.6"
}
}
+7
View File
@@ -0,0 +1,7 @@
import { describe, it, expect } from "vitest";
describe("scaffolding", () => {
it("has standalone output configured", async () => {
const cfg = await import("../next.config");
expect(cfg.default.output).toBe("standalone");
});
});
+21
View File
@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["dom", "dom.iterable", "es2022"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [{ "name": "next" }],
"paths": { "@/*": ["./*"] }
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
+7
View File
@@ -0,0 +1,7 @@
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
environment: "node",
},
});