From 72905ca37e35c1cb92311329569bd687949f4c1a Mon Sep 17 00:00:00 2001 From: Sahil Sharma Date: Sat, 18 Apr 2026 00:28:13 +0530 Subject: [PATCH 1/3] feat: dockerfile for backend --- backend/.dockerignore | 9 ++++ backend/docker-compose.yml | 107 ++++++++++++++++++++++++++++++++++--- backend/dockerfile | 58 ++++++++++++++++++++ 3 files changed, 168 insertions(+), 6 deletions(-) create mode 100644 backend/.dockerignore create mode 100644 backend/dockerfile diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..db24a1b --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,9 @@ +node_modules +dist +coverage +uploads +.env +.env.* +npm-debug.log* +pnpm-debug.log* +.git diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index 2a2054b..51036bd 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -24,13 +24,108 @@ services: environment: KAFKA_BROKER_ID: 1 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 - KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,PLAINTEXT_INTERNAL://0.0.0.0:29092 - KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:${KAFKA_HOST_PORT:-19092},PLAINTEXT_INTERNAL://kafka:29092 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_INTERNAL:PLAINTEXT - KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT_INTERNAL + KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:29092,PLAINTEXT_HOST://0.0.0.0:9092 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:${KAFKA_HOST_PORT:-19092} + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 healthcheck: - test: ['CMD', 'kafka-topics', '--bootstrap-server', 'localhost:9092', '--list'] + test: ['CMD', 'kafka-topics', '--bootstrap-server', 'localhost:29092', '--list'] interval: 10s timeout: 10s - retries: 5 + retries: 12 + + mongo: + image: mongo:7.0 + container_name: paperstack-mongo + restart: unless-stopped + ports: + - '27017:27017' + volumes: + - mongo_data:/data/db + healthcheck: + test: ['CMD', 'mongosh', '--quiet', '--eval', 'db.adminCommand("ping").ok'] + interval: 10s + timeout: 10s + retries: 10 + + qdrant: + image: qdrant/qdrant:v1.13.5 + container_name: paperstack-qdrant + restart: unless-stopped + ports: + - '6333:6333' + - '6334:6334' + volumes: + - qdrant_data:/qdrant/storage + + backend: + platform: linux/amd64 + build: + context: . + dockerfile: dockerfile + target: api + container_name: paperstack-backend + restart: unless-stopped + depends_on: + kafka: + condition: service_healthy + mongo: + condition: service_healthy + qdrant: + condition: service_started + environment: + NODE_ENV: production + PORT: 8001 + UPLOAD_DIR: /app/uploads + MONGO_DB_URI: ${MONGO_DB_URI:-mongodb://mongo:27017/paperstack} + QDRANT_URL: ${QDRANT_URL:-http://qdrant:6333} + QDRANT_API_KEY: ${QDRANT_API_KEY:-} + KAFKA_BROKERS: ${KAFKA_BROKERS:-kafka:29092} + KAFKA_CLIENT_ID: ${KAFKA_CLIENT_ID:-paperstack-backend} + KAFKA_TOPIC: ${KAFKA_TOPIC:-document-processing} + JWT_SECRET: ${JWT_SECRET:-change-me} + JWT_EXPIRATION_TIME: ${JWT_EXPIRATION_TIME:-3600} + AUTH_COOKIE_NAME: ${AUTH_COOKIE_NAME:-access_token} + EMBEDDING_PROVIDER: ${EMBEDDING_PROVIDER:-fastembed} + LLM_PROVIDER: ${LLM_PROVIDER:-groq} + GROQ_API_KEY: ${GROQ_API_KEY:-} + GEMINI_API_KEY: ${GEMINI_API_KEY:-} + ports: + - '8001:8001' + volumes: + - uploads_data:/app/uploads + + consumer: + platform: linux/amd64 + build: + context: . + dockerfile: dockerfile + target: consumer + container_name: paperstack-consumer + restart: unless-stopped + depends_on: + kafka: + condition: service_healthy + mongo: + condition: service_healthy + qdrant: + condition: service_started + environment: + NODE_ENV: production + UPLOAD_DIR: /app/uploads + MONGO_DB_URI: ${MONGO_DB_URI:-mongodb://mongo:27017/paperstack} + QDRANT_URL: ${QDRANT_URL:-http://qdrant:6333} + QDRANT_API_KEY: ${QDRANT_API_KEY:-} + KAFKA_BROKERS: ${KAFKA_BROKERS:-kafka:29092} + KAFKA_CLIENT_ID: ${KAFKA_CLIENT_ID:-paperstack-backend} + KAFKA_TOPIC: ${KAFKA_TOPIC:-document-processing} + EMBEDDING_PROVIDER: ${EMBEDDING_PROVIDER:-fastembed} + GEMINI_API_KEY: ${GEMINI_API_KEY:-} + volumes: + - uploads_data:/app/uploads + +volumes: + mongo_data: + qdrant_data: + uploads_data: diff --git a/backend/dockerfile b/backend/dockerfile new file mode 100644 index 0000000..27cbc17 --- /dev/null +++ b/backend/dockerfile @@ -0,0 +1,58 @@ +FROM node:22-bookworm-slim AS base + +ENV PNPM_HOME=/pnpm +ENV PATH=$PNPM_HOME:$PATH + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates \ + python3 \ + make \ + g++ \ + && rm -rf /var/lib/apt/lists/* \ + && corepack enable + +WORKDIR /app + +FROM base AS deps + +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile + +FROM deps AS build + +COPY nest-cli.json tsconfig.json tsconfig.build.json ./ +COPY src ./src +RUN pnpm build + +FROM base AS prod-deps + +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile --prod + +FROM node:22-bookworm-slim AS runtime-base + +ENV NODE_ENV=production +ENV PORT=8001 +ENV UPLOAD_DIR=/app/uploads + +WORKDIR /app + +COPY --from=prod-deps /pnpm /pnpm +ENV PNPM_HOME=/pnpm +ENV PATH=$PNPM_HOME:$PATH + +COPY --from=prod-deps /app/node_modules ./node_modules +COPY --from=build /app/dist ./dist +COPY package.json ./ + +RUN mkdir -p /app/uploads && chown -R node:node /app + +USER node + +FROM runtime-base AS api +EXPOSE 8001 +CMD ["node", "dist/main"] + +FROM runtime-base AS consumer +CMD ["node", "dist/consumer/main"] From ee821379d3ba493ca346833a609b9cba3b745758 Mon Sep 17 00:00:00 2001 From: Sahil Sharma Date: Wed, 22 Apr 2026 01:00:36 +0530 Subject: [PATCH 2/3] feat: dockerfile for FE and coderabbit comment fix --- .env.prod.example | 21 ++++++++ backend/.env.example | 6 ++- backend/docker-compose.yml | 29 +++++++---- docker-compose.prod.yml | 104 +++++++++++++++++++++++++++++++++++++ frontend/.dockerignore | 7 +++ frontend/dockerfile | 32 ++++++++++++ frontend/nginx.conf | 17 ++++++ 7 files changed, 205 insertions(+), 11 deletions(-) create mode 100644 .env.prod.example create mode 100644 docker-compose.prod.yml create mode 100644 frontend/.dockerignore create mode 100644 frontend/dockerfile create mode 100644 frontend/nginx.conf diff --git a/.env.prod.example b/.env.prod.example new file mode 100644 index 0000000..07078f8 --- /dev/null +++ b/.env.prod.example @@ -0,0 +1,21 @@ +MONGO_DB_URI=mongodb+srv://:@/?retryWrites=true&w=majority +QDRANT_URL=https://..aws.cloud.qdrant.io:6333 +QDRANT_API_KEY= + +JWT_SECRET= +JWT_EXPIRATION_TIME=3600 +AUTH_COOKIE_NAME=access_token + +KAFKA_BROKERS=kafka:29092 +KAFKA_CLIENT_ID=paperstack-backend +KAFKA_TOPIC=document-processing +KAFKA_HOST_PORT=19092 + +EMBEDDING_PROVIDER=fastembed +LLM_PROVIDER=groq +GROQ_API_KEY= +GEMINI_API_KEY= + +BACKEND_HOST_PORT=8001 +FRONTEND_HOST_PORT=3000 +VITE_API_BASE_URL=http://:8001/api/v1 diff --git a/backend/.env.example b/backend/.env.example index deaa67d..9ba8b69 100644 --- a/backend/.env.example +++ b/backend/.env.example @@ -2,9 +2,11 @@ PORT=8001 NODE_ENV=development #MONGO DB -MONGO_DB_URI=your_mongo_db_uri +MONGO_INITDB_ROOT_USERNAME=paperstack_admin +MONGO_INITDB_ROOT_PASSWORD=change-me-mongo-password +MONGO_DB_URI=mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017/paperstack?authSource=admin -#JWT +#JWT (required before running docker compose) JWT_SECRET=your_jwt_secret # JWT expiry in seconds (3600 = 1h, 86400 = 1d) JWT_EXPIRATION_TIME=3600 diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index 51036bd..50b1a32 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -39,12 +39,26 @@ services: image: mongo:7.0 container_name: paperstack-mongo restart: unless-stopped - ports: - - '27017:27017' + environment: + MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME:-paperstack_admin} + MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD:-change-me-mongo-password} volumes: - mongo_data:/data/db healthcheck: - test: ['CMD', 'mongosh', '--quiet', '--eval', 'db.adminCommand("ping").ok'] + test: + [ + 'CMD', + 'mongosh', + '--quiet', + '--username', + '${MONGO_INITDB_ROOT_USERNAME:-paperstack_admin}', + '--password', + '${MONGO_INITDB_ROOT_PASSWORD:-change-me-mongo-password}', + '--authenticationDatabase', + 'admin', + '--eval', + 'db.adminCommand("ping").ok', + ] interval: 10s timeout: 10s retries: 10 @@ -53,9 +67,6 @@ services: image: qdrant/qdrant:v1.13.5 container_name: paperstack-qdrant restart: unless-stopped - ports: - - '6333:6333' - - '6334:6334' volumes: - qdrant_data:/qdrant/storage @@ -78,13 +89,13 @@ services: NODE_ENV: production PORT: 8001 UPLOAD_DIR: /app/uploads - MONGO_DB_URI: ${MONGO_DB_URI:-mongodb://mongo:27017/paperstack} + MONGO_DB_URI: ${MONGO_DB_URI:-mongodb://${MONGO_INITDB_ROOT_USERNAME:-paperstack_admin}:${MONGO_INITDB_ROOT_PASSWORD:-change-me-mongo-password}@mongo:27017/paperstack?authSource=admin} QDRANT_URL: ${QDRANT_URL:-http://qdrant:6333} QDRANT_API_KEY: ${QDRANT_API_KEY:-} KAFKA_BROKERS: ${KAFKA_BROKERS:-kafka:29092} KAFKA_CLIENT_ID: ${KAFKA_CLIENT_ID:-paperstack-backend} KAFKA_TOPIC: ${KAFKA_TOPIC:-document-processing} - JWT_SECRET: ${JWT_SECRET:-change-me} + JWT_SECRET: ${JWT_SECRET:?JWT_SECRET is required} JWT_EXPIRATION_TIME: ${JWT_EXPIRATION_TIME:-3600} AUTH_COOKIE_NAME: ${AUTH_COOKIE_NAME:-access_token} EMBEDDING_PROVIDER: ${EMBEDDING_PROVIDER:-fastembed} @@ -114,7 +125,7 @@ services: environment: NODE_ENV: production UPLOAD_DIR: /app/uploads - MONGO_DB_URI: ${MONGO_DB_URI:-mongodb://mongo:27017/paperstack} + MONGO_DB_URI: ${MONGO_DB_URI:-mongodb://${MONGO_INITDB_ROOT_USERNAME:-paperstack_admin}:${MONGO_INITDB_ROOT_PASSWORD:-change-me-mongo-password}@mongo:27017/paperstack?authSource=admin} QDRANT_URL: ${QDRANT_URL:-http://qdrant:6333} QDRANT_API_KEY: ${QDRANT_API_KEY:-} KAFKA_BROKERS: ${KAFKA_BROKERS:-kafka:29092} diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..5cb7e55 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,104 @@ +services: + zookeeper: + image: confluentinc/cp-zookeeper:7.5.0 + container_name: paperstack-zookeeper + restart: unless-stopped + environment: + ZOOKEEPER_CLIENT_PORT: 2181 + ZOOKEEPER_TICK_TIME: 2000 + volumes: + - zookeeper_data:/var/lib/zookeeper/data + + kafka: + image: confluentinc/cp-kafka:7.5.0 + container_name: paperstack-kafka + restart: unless-stopped + depends_on: + - zookeeper + ports: + - '${KAFKA_HOST_PORT:-19092}:9092' + environment: + KAFKA_BROKER_ID: 1 + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:29092,PLAINTEXT_HOST://0.0.0.0:9092 + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:${KAFKA_HOST_PORT:-19092} + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 + volumes: + - kafka_data:/var/lib/kafka/data + + backend: + platform: linux/amd64 + build: + context: ./backend + dockerfile: dockerfile + target: api + container_name: paperstack-backend + restart: unless-stopped + depends_on: + - kafka + environment: + NODE_ENV: production + PORT: 8001 + UPLOAD_DIR: /app/uploads + MONGO_DB_URI: ${MONGO_DB_URI} + QDRANT_URL: ${QDRANT_URL} + QDRANT_API_KEY: ${QDRANT_API_KEY:-} + KAFKA_BROKERS: ${KAFKA_BROKERS:-kafka:29092} + KAFKA_CLIENT_ID: ${KAFKA_CLIENT_ID:-paperstack-backend} + KAFKA_TOPIC: ${KAFKA_TOPIC:-document-processing} + JWT_SECRET: ${JWT_SECRET} + JWT_EXPIRATION_TIME: ${JWT_EXPIRATION_TIME:-3600} + AUTH_COOKIE_NAME: ${AUTH_COOKIE_NAME:-access_token} + EMBEDDING_PROVIDER: ${EMBEDDING_PROVIDER:-fastembed} + LLM_PROVIDER: ${LLM_PROVIDER:-groq} + GROQ_API_KEY: ${GROQ_API_KEY:-} + GEMINI_API_KEY: ${GEMINI_API_KEY:-} + ports: + - '${BACKEND_HOST_PORT:-8001}:8001' + volumes: + - uploads_data:/app/uploads + + consumer: + platform: linux/amd64 + build: + context: ./backend + dockerfile: dockerfile + target: consumer + container_name: paperstack-consumer + restart: unless-stopped + depends_on: + - kafka + environment: + NODE_ENV: production + UPLOAD_DIR: /app/uploads + MONGO_DB_URI: ${MONGO_DB_URI} + QDRANT_URL: ${QDRANT_URL} + QDRANT_API_KEY: ${QDRANT_API_KEY:-} + KAFKA_BROKERS: ${KAFKA_BROKERS:-kafka:29092} + KAFKA_CLIENT_ID: ${KAFKA_CLIENT_ID:-paperstack-backend} + KAFKA_TOPIC: ${KAFKA_TOPIC:-document-processing} + EMBEDDING_PROVIDER: ${EMBEDDING_PROVIDER:-fastembed} + GEMINI_API_KEY: ${GEMINI_API_KEY:-} + volumes: + - uploads_data:/app/uploads + + frontend: + platform: linux/amd64 + build: + context: ./frontend + dockerfile: dockerfile + args: + VITE_API_BASE_URL: ${VITE_API_BASE_URL} + container_name: paperstack-frontend + restart: unless-stopped + depends_on: + - backend + ports: + - '${FRONTEND_HOST_PORT:-3000}:80' + +volumes: + zookeeper_data: + kafka_data: + uploads_data: diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..42dd497 --- /dev/null +++ b/frontend/.dockerignore @@ -0,0 +1,7 @@ +node_modules +dist +.env +.env.* +npm-debug.log* +pnpm-debug.log* +.git diff --git a/frontend/dockerfile b/frontend/dockerfile new file mode 100644 index 0000000..7b72b2e --- /dev/null +++ b/frontend/dockerfile @@ -0,0 +1,32 @@ +FROM node:22-bookworm-slim AS base + +ENV PNPM_HOME=/pnpm +ENV PATH=$PNPM_HOME:$PATH + +RUN corepack enable + +WORKDIR /app + +FROM base AS deps + +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile + +FROM deps AS build + +ARG VITE_API_BASE_URL +ENV VITE_API_BASE_URL=$VITE_API_BASE_URL + +COPY index.html package.json tsconfig.json tsconfig.app.json tsconfig.node.json vite.config.ts ./ +COPY public ./public +COPY src ./src +RUN pnpm build + +FROM nginx:1.27-alpine AS runtime + +COPY --from=build /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..9c43522 --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,17 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + location = /healthz { + access_log off; + add_header Content-Type text/plain; + return 200 'ok'; + } +} From 8d999e7d0e869417f1738c885b526709239f03cc Mon Sep 17 00:00:00 2001 From: Sahil Sharma Date: Wed, 22 Apr 2026 01:12:19 +0530 Subject: [PATCH 3/3] fix: coderabbit fix-2 --- backend/docker-compose.yml | 14 +++++++-- backend/src/consumer/consumer.module.ts | 6 +++- backend/src/main/app.module.ts | 6 +++- docker-compose.prod.yml | 38 +++++++++++++++++-------- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml index 50b1a32..9f72f45 100644 --- a/backend/docker-compose.yml +++ b/backend/docker-compose.yml @@ -67,6 +67,16 @@ services: image: qdrant/qdrant:v1.13.5 container_name: paperstack-qdrant restart: unless-stopped + healthcheck: + test: + [ + 'CMD-SHELL', + 'if command -v curl >/dev/null 2>&1; then curl -fsS http://localhost:6333/readyz >/dev/null; elif command -v wget >/dev/null 2>&1; then wget -q -O- http://localhost:6333/readyz >/dev/null; else exit 1; fi', + ] + interval: 10s + timeout: 5s + retries: 12 + start_period: 10s volumes: - qdrant_data:/qdrant/storage @@ -84,7 +94,7 @@ services: mongo: condition: service_healthy qdrant: - condition: service_started + condition: service_healthy environment: NODE_ENV: production PORT: 8001 @@ -121,7 +131,7 @@ services: mongo: condition: service_healthy qdrant: - condition: service_started + condition: service_healthy environment: NODE_ENV: production UPLOAD_DIR: /app/uploads diff --git a/backend/src/consumer/consumer.module.ts b/backend/src/consumer/consumer.module.ts index 45473dd..e5f4d54 100644 --- a/backend/src/consumer/consumer.module.ts +++ b/backend/src/consumer/consumer.module.ts @@ -15,7 +15,11 @@ import { DocumentConsumerService } from './document-consumer/document-consumer.s @Module({ imports: [ - ConfigModule.forRoot({ isGlobal: true, envFilePath: '.env' }), + ConfigModule.forRoot({ + isGlobal: true, + envFilePath: '.env', + expandVariables: true, + }), DbModule, KafkaModule, DocumentsModule, diff --git a/backend/src/main/app.module.ts b/backend/src/main/app.module.ts index cc8da25..89759a9 100644 --- a/backend/src/main/app.module.ts +++ b/backend/src/main/app.module.ts @@ -13,7 +13,11 @@ import { ChatModule } from 'src/modules/chat/chat.module'; @Module({ imports: [ - ConfigModule.forRoot({ isGlobal: true, envFilePath: '.env' }), + ConfigModule.forRoot({ + isGlobal: true, + envFilePath: '.env', + expandVariables: true, + }), DbModule, UserModule, AuthModule, diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 5cb7e55..d940a4e 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -6,6 +6,11 @@ services: environment: ZOOKEEPER_CLIENT_PORT: 2181 ZOOKEEPER_TICK_TIME: 2000 + healthcheck: + test: ['CMD', 'nc', '-z', 'localhost', '2181'] + interval: 5s + timeout: 5s + retries: 5 volumes: - zookeeper_data:/var/lib/zookeeper/data @@ -14,9 +19,10 @@ services: container_name: paperstack-kafka restart: unless-stopped depends_on: - - zookeeper + zookeeper: + condition: service_healthy ports: - - '${KAFKA_HOST_PORT:-19092}:9092' + - '127.0.0.1:${KAFKA_HOST_PORT:-19092}:9092' environment: KAFKA_BROKER_ID: 1 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 @@ -25,6 +31,11 @@ services: KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 + healthcheck: + test: ['CMD', 'kafka-topics', '--bootstrap-server', 'localhost:29092', '--list'] + interval: 10s + timeout: 10s + retries: 12 volumes: - kafka_data:/var/lib/kafka/data @@ -37,18 +48,19 @@ services: container_name: paperstack-backend restart: unless-stopped depends_on: - - kafka + kafka: + condition: service_healthy environment: NODE_ENV: production PORT: 8001 UPLOAD_DIR: /app/uploads - MONGO_DB_URI: ${MONGO_DB_URI} - QDRANT_URL: ${QDRANT_URL} + MONGO_DB_URI: ${MONGO_DB_URI:?MONGO_DB_URI is required} + QDRANT_URL: ${QDRANT_URL:?QDRANT_URL is required} QDRANT_API_KEY: ${QDRANT_API_KEY:-} KAFKA_BROKERS: ${KAFKA_BROKERS:-kafka:29092} KAFKA_CLIENT_ID: ${KAFKA_CLIENT_ID:-paperstack-backend} KAFKA_TOPIC: ${KAFKA_TOPIC:-document-processing} - JWT_SECRET: ${JWT_SECRET} + JWT_SECRET: ${JWT_SECRET:?JWT_SECRET is required} JWT_EXPIRATION_TIME: ${JWT_EXPIRATION_TIME:-3600} AUTH_COOKIE_NAME: ${AUTH_COOKIE_NAME:-access_token} EMBEDDING_PROVIDER: ${EMBEDDING_PROVIDER:-fastembed} @@ -56,7 +68,7 @@ services: GROQ_API_KEY: ${GROQ_API_KEY:-} GEMINI_API_KEY: ${GEMINI_API_KEY:-} ports: - - '${BACKEND_HOST_PORT:-8001}:8001' + - '127.0.0.1:${BACKEND_HOST_PORT:-8001}:8001' volumes: - uploads_data:/app/uploads @@ -69,12 +81,13 @@ services: container_name: paperstack-consumer restart: unless-stopped depends_on: - - kafka + kafka: + condition: service_healthy environment: NODE_ENV: production UPLOAD_DIR: /app/uploads - MONGO_DB_URI: ${MONGO_DB_URI} - QDRANT_URL: ${QDRANT_URL} + MONGO_DB_URI: ${MONGO_DB_URI:?MONGO_DB_URI is required} + QDRANT_URL: ${QDRANT_URL:?QDRANT_URL is required} QDRANT_API_KEY: ${QDRANT_API_KEY:-} KAFKA_BROKERS: ${KAFKA_BROKERS:-kafka:29092} KAFKA_CLIENT_ID: ${KAFKA_CLIENT_ID:-paperstack-backend} @@ -90,11 +103,12 @@ services: context: ./frontend dockerfile: dockerfile args: - VITE_API_BASE_URL: ${VITE_API_BASE_URL} + VITE_API_BASE_URL: ${VITE_API_BASE_URL:?VITE_API_BASE_URL is required} container_name: paperstack-frontend restart: unless-stopped depends_on: - - backend + backend: + condition: service_started ports: - '${FRONTEND_HOST_PORT:-3000}:80'