diff --git a/Dockerfile.multi b/Dockerfile.multi index b4596daa0..16fd7a7ba 100644 --- a/Dockerfile.multi +++ b/Dockerfile.multi @@ -1,43 +1,40 @@ +# Dockerfile.multi # v0.7.4 -# Build API, Client and Data Provider +# Base for all builds FROM node:20-alpine AS base +WORKDIR /app +COPY package*.json ./ +COPY packages/data-provider/package*.json ./packages/data-provider/ +COPY client/package*.json ./client/ +COPY api/package*.json ./api/ +RUN npm ci # Build data-provider FROM base AS data-provider-build WORKDIR /app/packages/data-provider -COPY ./packages/data-provider ./ -RUN npm install; npm cache clean --force +COPY packages/data-provider ./ RUN npm run build RUN npm prune --production -# React client build +# Client build FROM base AS client-build WORKDIR /app/client -COPY ./client/package*.json ./ -# Copy data-provider to client's node_modules -COPY --from=data-provider-build /app/packages/data-provider/ /app/client/node_modules/librechat-data-provider/ -RUN npm install; npm cache clean --force -COPY ./client/ ./ +COPY client ./ +COPY --from=data-provider-build /app/packages/data-provider/dist /app/packages/data-provider/dist ENV NODE_OPTIONS="--max-old-space-size=2048" RUN npm run build +RUN npm prune --production -# Node API setup +# API setup (including client dist) FROM base AS api-build +WORKDIR /app +COPY api ./api +COPY config ./config +COPY --from=data-provider-build /app/packages/data-provider/dist ./packages/data-provider/dist +COPY --from=client-build /app/client/dist ./client/dist WORKDIR /app/api -COPY api/package*.json ./ -COPY api/ ./ -# Copy helper scripts -COPY config/ ./ -# Copy data-provider to API's node_modules -COPY --from=data-provider-build /app/packages/data-provider/ /app/api/node_modules/librechat-data-provider/ -RUN npm install --include prod; npm cache clean --force -COPY --from=client-build /app/client/dist /app/client/dist +RUN npm prune --production EXPOSE 3080 ENV HOST=0.0.0.0 CMD ["node", "server/index.js"] - -# Nginx setup -FROM nginx:1.27.0-alpine AS prod-stage -COPY ./client/nginx.conf /etc/nginx/conf.d/default.conf -CMD ["nginx", "-g", "daemon off;"] diff --git a/api/server/index.js b/api/server/index.js index 39529f73f..83922f025 100644 --- a/api/server/index.js +++ b/api/server/index.js @@ -39,7 +39,7 @@ const startServer = async () => { app.get('/health', (_req, res) => res.status(200).send('OK')); - // Middleware + /* Middleware */ app.use(noIndex); app.use(errorController); app.use(express.json({ limit: '3mb' })); @@ -48,7 +48,7 @@ const startServer = async () => { app.use(staticCache(app.locals.paths.dist)); app.use(staticCache(app.locals.paths.fonts)); app.use(staticCache(app.locals.paths.assets)); - app.set('trust proxy', 1); // trust first proxy + app.set('trust proxy', 1); /* trust first proxy */ app.use(cors()); if (DISABLE_COMPRESSION !== 'true') { @@ -61,12 +61,12 @@ const startServer = async () => { ); } - // OAUTH + /* OAUTH */ app.use(passport.initialize()); passport.use(await jwtLogin()); passport.use(passportLogin()); - // LDAP Auth + /* LDAP Auth */ if (process.env.LDAP_URL && process.env.LDAP_USER_SEARCH_BASE) { passport.use(ldapLogin); } @@ -76,7 +76,7 @@ const startServer = async () => { } app.use('/oauth', routes.oauth); - // API Endpoints + /* API Endpoints */ app.use('/api/auth', routes.auth); app.use('/api/keys', routes.keys); app.use('/api/user', routes.user); diff --git a/deploy-compose.yml b/deploy-compose.yml index cb67e2a62..4f4ebe1b3 100644 --- a/deploy-compose.yml +++ b/deploy-compose.yml @@ -30,11 +30,10 @@ services: target: /app/librechat.yaml - ./images:/app/client/public/images - ./logs:/app/api/logs + - client-dist:/app/client/dist # Share client dist files + client: - build: - context: . - dockerfile: Dockerfile.multi - target: prod-stage + image: nginx:1.27.0-alpine container_name: LibreChat-NGINX ports: - 80:80 @@ -44,6 +43,7 @@ services: restart: always volumes: - ./client/nginx.conf:/etc/nginx/conf.d/default.conf + - client-dist:/usr/share/nginx/html # Use shared client dist files mongodb: container_name: chat-mongodb # ports: # Uncomment this to access mongodb from outside docker, not safe in deployment @@ -88,3 +88,4 @@ services: volumes: pgdata2: + client-dist: # Define a named volume for client dist files diff --git a/package.json b/package.json index 93471416c..d5e2de8b8 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,6 @@ "test:api": "cd api && npm run test", "e2e:update": "playwright test --config=e2e/playwright.config.js --update-snapshots", "e2e:report": "npx playwright show-report e2e/playwright-report", - "prepare": "node config/prepare.js", "lint:fix": "eslint --fix \"{,!(node_modules|venv)/**/}*.{js,jsx,ts,tsx}\"", "lint": "eslint \"{,!(node_modules|venv)/**/}*.{js,jsx,ts,tsx}\"", "format": "prettier-eslint --write \"{,!(node_modules|venv)/**/}*.{js,jsx,ts,tsx}\"",