diff --git a/Dockerfile b/Dockerfile index b44d467..9350424 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,19 @@ FROM node:18-alpine -WORKDIR /app/gradesa # Disable Husky during install ENV HUSKY=0 -# Set default environment variables for build - -ENV SESSION_SECRET=secret \ - - DB_HOST=localhost \ - - DB_PORT=5432 \ - - DB_USER=postgres \ - - DB_PASSWORD=password \ - - DB_NAME=postgres +# Can be overriden by setting build-args when building image +ARG DB_HOST="localhost" +ARG DB_PORT="5432" +ARG DB_USER="postgres" +ARG DB_PASSWORD="password" +ARG DB_NAME="postgres" +ARG SESSION_SECRET="secret" +ARG NODE_ENV="production" +# NOTE: The above args and the following ENVs are overridden +# by .env and .env.$NODE_ENV file contents if they exist +# so these apply ONLY when ./init-env.sh has not been run RUN apk update && \ apk add --no-cache wget && \ @@ -25,14 +22,29 @@ RUN apk update && \ RUN apk add --no-cache postgresql-client +# OpenShift requires non-root user +RUN adduser -D nonroot +USER nonroot + +WORKDIR /app/gradesa + # Copy package files from gradesa -COPY gradesa/package*.json ./ +COPY --chown=nonroot:nonroot gradesa/package*.json ./ + +# Set default environment variables for build +ENV SESSION_SECRET=$SESSION_SECRET \ + DB_HOST=$DB_HOST \ + DB_PORT=$DB_PORT \ + DB_USER=$DB_USER \ + DB_PASSWORD=$DB_PASSWORD \ + DB_NAME=$DB_NAME \ + NODE_ENV=$NODE_ENV # Install ALL dependencies (including dev) for build -RUN npm i +RUN npm ci # Copy app files including .env.production -COPY gradesa/ . +COPY --chown=nonroot:nonroot gradesa/ . #This is for memory optimizing ENV NODE_OPTIONS="--max-old-space-size=8192" @@ -41,16 +53,15 @@ ENV NODE_OPTIONS="--max-old-space-size=8192" RUN npm run build # Remove dev dependencies -RUN npm prune --production +RUN npm prune --omit=dev + +# Copy static files to .next/standalone, this is not done automatically +RUN cp -r .next/static .next/standalone/.next +RUN cp -r public .next/standalone/ -# OpenShift requires non-root user -RUN adduser -D nonroot && chown -R nonroot:nonroot /app/gradesa -USER nonroot # Next.js needs to listen on 8080 ENV PORT=8080 EXPOSE 8080 - - -CMD ["npm", "start"] \ No newline at end of file +CMD ["npm", "run", "start:standalone"] diff --git a/docker-compose.prod.yaml b/docker-compose.prod.yaml new file mode 100644 index 0000000..4894596 --- /dev/null +++ b/docker-compose.prod.yaml @@ -0,0 +1,30 @@ +services: + db: + image: docker.io/library/postgres:15 + container_name: gradesa-db + environment: + POSTGRES_PASSWORD: password + volumes: + - pg-data:/var/lib/postgresql/data/ + restart: unless-stopped + healthcheck: + test: ["CMD", "pg_isready", "-U", "postgres"] + interval: 10s + retries: 20 + command: -p 7742 + + gradesa: + build: + context: . + dockerfile: Dockerfile + args: + NODE_ENV: production + DB_HOST: db + DB_PORT: 7742 + ports: + - 8080:8080 + depends_on: + - db + +volumes: + pg-data: diff --git a/gradesa/package.json b/gradesa/package.json index 09723b2..3611be3 100644 --- a/gradesa/package.json +++ b/gradesa/package.json @@ -7,6 +7,7 @@ "dev": "next dev --turbopack", "build": "next build", "start": "sh ./data/migrate.sh --skip-schema-gen && next start", + "start:standalone": "sh ./data/migrate.sh --skip-schema-gen && node .next/standalone/server.js", "lint": "next lint", "test": "vitest --disable-console-intercept", "test:coverage": "vitest --disable-console-intercept --coverage.enabled=true", diff --git a/gradesa/src/app/pages/[type]/[slug]/edit-button.js b/gradesa/src/app/pages/[type]/[slug]/edit-button.js index c8c5dfe..409060e 100644 --- a/gradesa/src/app/pages/[type]/[slug]/edit-button.js +++ b/gradesa/src/app/pages/[type]/[slug]/edit-button.js @@ -2,17 +2,18 @@ import { checkUseIsAdmin } from "@/context/user.context"; import { Button } from "@/components/ui/button"; -import router from "next/navigation"; +import { useRouter } from "next/navigation"; import { useUser } from "@/context/user.context"; export default function EditButton({ url }) { const { setActAs } = useUser(); + const router = useRouter(); if (checkUseIsAdmin()) { return (