diff --git a/client/src/Dockerfile b/client/src/Dockerfile new file mode 100644 index 0000000..4d059c8 --- /dev/null +++ b/client/src/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/docker-compose.yml b/docker-compose.yml index a23bc93..02c59cc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,22 +1,112 @@ services: postgres: image: postgres:16 - container_name: toir-postgres + container_name: toir-light-postgres restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-postgres} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change-me} POSTGRES_DB: ${POSTGRES_DB:-toir} - ports: - - "${POSTGRES_PORT:-5432}:5432" healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-toir}"] + test: + [ + "CMD-SHELL", + "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-toir}", + ] interval: 10s timeout: 5s retries: 5 start_period: 10s volumes: - postgres-data:/var/lib/postgresql/data + networks: + - toir-light + + server: + build: + context: ./server + dockerfile: Dockerfile + container_name: toir-light-server + restart: unless-stopped + depends_on: + postgres: + condition: service_healthy + environment: + PORT: 3000 + DATABASE_URL: postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-change-me}@postgres:5432/${POSTGRES_DB:-toir} + CORS_ALLOWED_ORIGINS: ${CORS_ALLOWED_ORIGINS:-http://localhost:8080,https://toir.greact.ru} + KEYCLOAK_ISSUER_URL: ${KEYCLOAK_ISSUER_URL:-https://sso.greact.ru/realms/toir} + KEYCLOAK_AUDIENCE: ${KEYCLOAK_AUDIENCE:-toir-backend} + KEYCLOAK_JWKS_URL: ${KEYCLOAK_JWKS_URL:-} + healthcheck: + test: + [ + "CMD", + "node", + "-e", + "fetch('http://127.0.0.1:3000/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))", + ] + interval: 15s + timeout: 5s + retries: 5 + start_period: 20s + expose: + - "3000" + networks: + - toir-light + - proxy + + db-seed: + build: + context: . + dockerfile: db-seed/Dockerfile + container_name: toir-light-db-seed + restart: "no" + depends_on: + postgres: + condition: service_healthy + environment: + PGPASSWORD: ${POSTGRES_PASSWORD:-change-me} + POSTGRES_USER: ${POSTGRES_USER:-postgres} + POSTGRES_DB: ${POSTGRES_DB:-toir} + networks: + - toir-light + + client: + build: + context: ./client + dockerfile: Dockerfile + args: + VITE_API_URL: ${VITE_API_URL:-/api} + VITE_KEYCLOAK_URL: ${VITE_KEYCLOAK_URL:-https://sso.greact.ru} + VITE_KEYCLOAK_REALM: ${VITE_KEYCLOAK_REALM:-toir} + VITE_KEYCLOAK_CLIENT_ID: ${VITE_KEYCLOAK_CLIENT_ID:-toir-frontend} + container_name: toir-light-client + restart: unless-stopped + depends_on: + server: + condition: service_healthy + db-seed: + condition: service_completed_successfully + healthcheck: + test: ["CMD-SHELL", "wget -qO- http://127.0.0.1/healthz >/dev/null 2>&1 || exit 1"] + interval: 15s + timeout: 5s + retries: 5 + start_period: 10s + ports: + - "${CLIENT_PORT:-8080}:80" + expose: + - "80" + networks: + - toir-light + - proxy volumes: postgres-data: + +networks: + toir-light: + driver: bridge + proxy: + external: true 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"]