diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..fd1f5b0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.git +.gitignore +node_modules +.next +.env +.env.* +!.env.example +README.md diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..383599b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +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 +RUN npm run build + +FROM node:22-alpine AS runner +WORKDIR /app +ENV NODE_ENV=production + +RUN addgroup --system --gid 1001 nodejs \ + && adduser --system --uid 1001 nextjs + +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" + +CMD ["node", "server.js"] diff --git a/deploy/caddy/Caddyfile.ops-dashboard b/deploy/caddy/Caddyfile.ops-dashboard new file mode 100644 index 0000000..e8e0cab --- /dev/null +++ b/deploy/caddy/Caddyfile.ops-dashboard @@ -0,0 +1,7 @@ +# Block to add to /srv/scrum4me/caddy/Caddyfile +# After adding, restart Caddy (not reload — see deploy notes): +# docker compose restart caddy + +ops.jp-visser.nl { + reverse_proxy 172.18.0.1:3001 +} diff --git a/deploy/docker-compose.ops-dashboard.yml b/deploy/docker-compose.ops-dashboard.yml new file mode 100644 index 0000000..47580a9 --- /dev/null +++ b/deploy/docker-compose.ops-dashboard.yml @@ -0,0 +1,19 @@ +# Fragment to merge into /srv/scrum4me/compose/docker-compose.yml +# Add the ops-dashboard service under the `services:` key. +# +# Build the image first: +# docker build -t ops-dashboard /srv/ops/ops-dashboard +# +# Then bring the service up: +# docker compose -f /srv/scrum4me/compose/docker-compose.yml up -d ops-dashboard + +services: + ops-dashboard: + build: + context: /srv/ops/ops-dashboard + env_file: /srv/ops/ops-dashboard.env + ports: + - "127.0.0.1:3001:3000" + restart: unless-stopped + depends_on: + - postgres diff --git a/deploy/ops-dashboard.env.example b/deploy/ops-dashboard.env.example new file mode 100644 index 0000000..c83c373 --- /dev/null +++ b/deploy/ops-dashboard.env.example @@ -0,0 +1,5 @@ +# Copy to /srv/ops/ops-dashboard.env on the server and fill in real values. +DATABASE_URL="postgresql://USER:PASSWORD@postgres:5432/ops_dashboard" +SEED_USER_EMAIL="admin@example.com" +SEED_USER_PASSWORD="changeme" +SESSION_SECRET="replace-with-a-long-random-string" diff --git a/next.config.ts b/next.config.ts index e9ffa30..68a6c64 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,7 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + output: "standalone", }; export default nextConfig;