diff --git a/client/.dockerignore b/client/.dockerignore new file mode 100644 index 0000000..e37d2c3 --- /dev/null +++ b/client/.dockerignore @@ -0,0 +1,5 @@ +node_modules +dist +.env.local +npm-debug.log +.git diff --git a/client/Dockerfile b/client/Dockerfile new file mode 100644 index 0000000..4d059c8 --- /dev/null +++ b/client/Dockerfile @@ -0,0 +1,29 @@ +FROM node:20-alpine AS build + +WORKDIR /app + +COPY package*.json ./ +RUN npm ci + +COPY . . + +ARG VITE_API_URL +ARG VITE_KEYCLOAK_URL +ARG VITE_KEYCLOAK_REALM +ARG VITE_KEYCLOAK_CLIENT_ID + +ENV VITE_API_URL=$VITE_API_URL +ENV VITE_KEYCLOAK_URL=$VITE_KEYCLOAK_URL +ENV VITE_KEYCLOAK_REALM=$VITE_KEYCLOAK_REALM +ENV VITE_KEYCLOAK_CLIENT_ID=$VITE_KEYCLOAK_CLIENT_ID + +RUN npm run build + +FROM nginx:1.27-alpine AS runtime + +COPY nginx/default.conf /etc/nginx/conf.d/default.conf +COPY --from=build /app/dist /usr/share/nginx/html + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/client/nginx/default.conf b/client/nginx/default.conf new file mode 100644 index 0000000..c664296 --- /dev/null +++ b/client/nginx/default.conf @@ -0,0 +1,26 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + location = /healthz { + access_log off; + add_header Content-Type text/plain; + return 200 "ok\n"; + } + + location /api/ { + proxy_pass http://server:3000/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location / { + try_files $uri $uri/ /index.html; + } +} diff --git a/server/.dockerignore b/server/.dockerignore new file mode 100644 index 0000000..ae9e2a5 --- /dev/null +++ b/server/.dockerignore @@ -0,0 +1,6 @@ +node_modules +dist +.env +npm-debug.log +coverage +.git diff --git a/server/Dockerfile b/server/Dockerfile new file mode 100644 index 0000000..72f07f9 --- /dev/null +++ b/server/Dockerfile @@ -0,0 +1,44 @@ +FROM node:20-bookworm-slim AS build + +WORKDIR /app + +ARG DATABASE_URL=postgresql://postgres:postgres@localhost:5432/toir +ENV DATABASE_URL=$DATABASE_URL + +RUN apt-get update \ + && apt-get install -y --no-install-recommends openssl \ + && rm -rf /var/lib/apt/lists/* + +COPY package*.json ./ +COPY prisma ./prisma + +RUN npm ci + +COPY nest-cli.json tsconfig*.json prisma.config.ts ./ +COPY src ./src + +RUN npx prisma generate +RUN npm run build + +FROM node:20-bookworm-slim AS runtime + +WORKDIR /app + +ENV NODE_ENV=production + +RUN apt-get update \ + && apt-get install -y --no-install-recommends openssl \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=build /app/package*.json ./ +COPY --from=build /app/node_modules ./node_modules +COPY --from=build /app/prisma ./prisma +COPY --from=build /app/prisma.config.ts ./prisma.config.ts +COPY --from=build /app/dist ./dist +COPY docker-entrypoint.sh ./docker-entrypoint.sh + +RUN chmod +x ./docker-entrypoint.sh + +EXPOSE 3000 + +CMD ["./docker-entrypoint.sh"] diff --git a/server/docker-entrypoint.sh b/server/docker-entrypoint.sh new file mode 100644 index 0000000..7f715fa --- /dev/null +++ b/server/docker-entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -eu + +if [ -d "prisma/migrations" ] && [ -n "$(find prisma/migrations -mindepth 1 -maxdepth 1 -type d 2>/dev/null)" ]; then + echo "Applying Prisma migrations with migrate deploy..." + npx prisma migrate deploy +else + echo "No Prisma migrations found, syncing schema with db push..." + npx prisma db push +fi + +exec node dist/src/main.js