diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml new file mode 100644 index 00000000..97c86f52 --- /dev/null +++ b/.github/workflows/docker-image.yml @@ -0,0 +1,19 @@ +name: Docker Image CI + +on: + push: + branches: [ "main"] + pull_request: + branches: [ "main" ] + +jobs: + + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - name: Build the Docker image + working-directory: ./next + run: docker build . --file Dockerfile --tag sse-web:$(date +%s) diff --git a/next/Dockerfile b/next/Dockerfile new file mode 100644 index 00000000..7bae33d8 --- /dev/null +++ b/next/Dockerfile @@ -0,0 +1,70 @@ +FROM node:20 AS base + +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. + +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ +RUN \ + if [ -f yarn.lock ]; then yarn --frozen-lockfile; \ + elif [ -f package-lock.json ]; then npm ci; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ + else echo "Lockfile not found." && exit 1; \ + fi + + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +RUN npx prisma generate + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN \ + if [ -f yarn.lock ]; then yarn run build; \ + elif [ -f package-lock.json ]; then npm run build; \ + elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \ + else echo "Lockfile not found." && exit 1; \ + fi + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV=production +# Uncomment the following line in case you want to disable telemetry during runtime. +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +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 + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/next-config-js/output +ENV HOSTNAME="0.0.0.0" +CMD ["node", "server.js"] diff --git a/next/app/api/authLevel/route.ts b/next/app/api/authLevel/route.ts index 91df23cb..98e5e936 100644 --- a/next/app/api/authLevel/route.ts +++ b/next/app/api/authLevel/route.ts @@ -1,6 +1,8 @@ import { PrismaClient } from "@prisma/client"; import { NextRequest, NextResponse } from "next/server"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/course/[id]/route.ts b/next/app/api/course/[id]/route.ts index 33a001fb..dfb19045 100644 --- a/next/app/api/course/[id]/route.ts +++ b/next/app/api/course/[id]/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/course/route.ts b/next/app/api/course/route.ts index bc06e1fe..48d303fa 100644 --- a/next/app/api/course/route.ts +++ b/next/app/api/course/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/courseTaken/route.ts b/next/app/api/courseTaken/route.ts index a42bcfe6..da23ed56 100644 --- a/next/app/api/courseTaken/route.ts +++ b/next/app/api/courseTaken/route.ts @@ -1,5 +1,7 @@ import { Prisma, PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/departments/[id]/route.ts b/next/app/api/departments/[id]/route.ts index 19357de0..195815c2 100644 --- a/next/app/api/departments/[id]/route.ts +++ b/next/app/api/departments/[id]/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/departments/route.ts b/next/app/api/departments/route.ts index 37a47719..932437fd 100644 --- a/next/app/api/departments/route.ts +++ b/next/app/api/departments/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/go/[golink]/route.ts b/next/app/api/go/[golink]/route.ts index 4213ca9e..408e74a5 100644 --- a/next/app/api/go/[golink]/route.ts +++ b/next/app/api/go/[golink]/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/golinks/officer/route.ts b/next/app/api/golinks/officer/route.ts index 6f2a21ff..fcddd0de 100644 --- a/next/app/api/golinks/officer/route.ts +++ b/next/app/api/golinks/officer/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client" +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient() export async function GET() { diff --git a/next/app/api/golinks/public/route.ts b/next/app/api/golinks/public/route.ts index 00229cb9..31f87dbd 100644 --- a/next/app/api/golinks/public/route.ts +++ b/next/app/api/golinks/public/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client" +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient() export async function GET() { diff --git a/next/app/api/golinks/route.ts b/next/app/api/golinks/route.ts index a842455e..b132d8bb 100644 --- a/next/app/api/golinks/route.ts +++ b/next/app/api/golinks/route.ts @@ -1,4 +1,7 @@ import { PrismaClient } from "@prisma/client"; + +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); function validateGoLink(goLink: string) { diff --git a/next/app/api/hourBlocks/route.ts b/next/app/api/hourBlocks/route.ts index 4d23ef84..71830e6f 100644 --- a/next/app/api/hourBlocks/route.ts +++ b/next/app/api/hourBlocks/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/mentor/[id]/route.ts b/next/app/api/mentor/[id]/route.ts index a5ad53df..c4ec23c6 100644 --- a/next/app/api/mentor/[id]/route.ts +++ b/next/app/api/mentor/[id]/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/mentor/route.ts b/next/app/api/mentor/route.ts index 7f685a31..ef690810 100644 --- a/next/app/api/mentor/route.ts +++ b/next/app/api/mentor/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/mentorSkill/[id]/route.ts b/next/app/api/mentorSkill/[id]/route.ts index 6d58ec2d..df81c54c 100644 --- a/next/app/api/mentorSkill/[id]/route.ts +++ b/next/app/api/mentorSkill/[id]/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); export async function GET(request: Request, { params }: { params: { id: string } }) { diff --git a/next/app/api/mentorSkill/route.ts b/next/app/api/mentorSkill/route.ts index 437f73ee..1c87b3a1 100644 --- a/next/app/api/mentorSkill/route.ts +++ b/next/app/api/mentorSkill/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); export async function GET() { diff --git a/next/app/api/officer/[active]/route.ts b/next/app/api/officer/[active]/route.ts index 17a76a67..e22833df 100644 --- a/next/app/api/officer/[active]/route.ts +++ b/next/app/api/officer/[active]/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); export async function GET() { diff --git a/next/app/api/officer/route.ts b/next/app/api/officer/route.ts index 5f4146f4..dffcdf3e 100644 --- a/next/app/api/officer/route.ts +++ b/next/app/api/officer/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); export async function GET() { diff --git a/next/app/api/quotes/[id]/route.ts b/next/app/api/quotes/[id]/route.ts index 98cf29b8..fdce5034 100644 --- a/next/app/api/quotes/[id]/route.ts +++ b/next/app/api/quotes/[id]/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/quotes/route.ts b/next/app/api/quotes/route.ts index d8683333..37cab608 100644 --- a/next/app/api/quotes/route.ts +++ b/next/app/api/quotes/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/schedule/[id]/route.ts b/next/app/api/schedule/[id]/route.ts index 1b57d865..062cd3cf 100644 --- a/next/app/api/schedule/[id]/route.ts +++ b/next/app/api/schedule/[id]/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/schedule/route.ts b/next/app/api/schedule/route.ts index 4fb2f001..ef3909d8 100644 --- a/next/app/api/schedule/route.ts +++ b/next/app/api/schedule/route.ts @@ -1,5 +1,7 @@ import { Prisma, PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/app/api/skill/[id]/route.ts b/next/app/api/skill/[id]/route.ts index 10a868fa..617792c9 100644 --- a/next/app/api/skill/[id]/route.ts +++ b/next/app/api/skill/[id]/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); export async function GET(request: Request, { params }: { params: { id: string } }) { diff --git a/next/app/api/skill/route.ts b/next/app/api/skill/route.ts index 94af4db5..12dd4458 100644 --- a/next/app/api/skill/route.ts +++ b/next/app/api/skill/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); export async function GET() { diff --git a/next/app/api/skills/[id]/route.ts b/next/app/api/skills/[id]/route.ts index e5537315..c781ae5a 100644 --- a/next/app/api/skills/[id]/route.ts +++ b/next/app/api/skills/[id]/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); export async function GET(request: Request, { params }: { params: { id: string } }) { diff --git a/next/app/api/skills/route.ts b/next/app/api/skills/route.ts index 4ee88ec6..359b3d10 100644 --- a/next/app/api/skills/route.ts +++ b/next/app/api/skills/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); export async function GET() { diff --git a/next/app/api/user/route.ts b/next/app/api/user/route.ts index b17c8709..25ec25b0 100644 --- a/next/app/api/user/route.ts +++ b/next/app/api/user/route.ts @@ -1,5 +1,7 @@ import { PrismaClient } from "@prisma/client"; +export const dynamic = 'force-dynamic' + const prisma = new PrismaClient(); /** diff --git a/next/next.config.js b/next/next.config.js index 902cf28e..87ce953d 100644 --- a/next/next.config.js +++ b/next/next.config.js @@ -2,7 +2,8 @@ const nextConfig = { images: { domains: ['dummyimage.com'] - } + }, + output: "standalone", } module.exports = nextConfig