diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..884e2c1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +node_modules +.next +.git +.env* +*.md +tests/ +.storybook/ +storybook-static/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..71cb16f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,44 @@ +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 . . + +# Build-time args for NEXT_PUBLIC_ vars and Sentry source maps +ARG NEXT_PUBLIC_IDP_BASE_URL +ARG SENTRY_ORG +ARG SENTRY_PROJECT +ARG SENTRY_AUTH_TOKEN + +ENV NEXT_PUBLIC_IDP_BASE_URL=$NEXT_PUBLIC_IDP_BASE_URL +ENV SENTRY_ORG=$SENTRY_ORG +ENV SENTRY_PROJECT=$SENTRY_PROJECT +ENV SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN + +# Dummy DATABASE_URL for build — Next.js compiles server components which +# import lib/database.ts, but it doesn't actually connect during build. +ENV DATABASE_URL="postgresql://dummy:dummy@localhost:5432/dummy" + +RUN npm run build + +FROM node:22-alpine AS runner +WORKDIR /app + +RUN adduser -D -u 1000 appuser + +ENV NODE_ENV=production +ENV PORT=3000 +ENV HOSTNAME=0.0.0.0 + +COPY --from=builder /app/public ./public +COPY --from=builder --chown=appuser:appuser /app/.next/standalone ./ +COPY --from=builder --chown=appuser:appuser /app/.next/static ./.next/static + +USER appuser +EXPOSE 3000 + +CMD ["node", "server.js"] diff --git a/app/layout.tsx b/app/layout.tsx index 7dab1a1..b26ce8d 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -4,7 +4,7 @@ import "./globals.css"; import { NavBar } from "@/components/navbar"; import { ThemeProvider } from "next-themes"; import { Toaster } from "@/components/ui/toaster"; -import { Analytics } from "@vercel/analytics/react"; + import { StatusIndicatorStack } from "@/components/status-indicators"; const inter = Inter({ subsets: ["latin"] }); @@ -28,7 +28,7 @@ export default function RootLayout({