Ctrl K
ComunidadGuías…

Dockerfile.kaneo

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
FROM --platform=$BUILDPLATFORM node:24.22.2-alpine AS api-builder

RUN apk add --no-cache python3 make g++ && \
  corepack enable && \
  corepack prepare pnpm@12.15.0 --activate

WORKDIR /app

COPY pnpm-workspace.yaml package.json pnpm-lock.yaml vite.config.ts ./
COPY patches ./patches
COPY packages/typescript-config/package.json ./packages/typescript-config/
COPY packages/email/package.json ./packages/email/
COPY packages/libs/package.json ./packages/libs/
COPY packages/permissions/package.json ./packages/permissions/
COPY packages/importers/package.json ./packages/importers/
COPY packages/mcp/package.json ./packages/mcp/
COPY apps/api/package.json ./apps/api/

RUN pnpm install --frozen-lockfile

COPY packages/typescript-config ./packages/typescript-config
COPY packages/email ./packages/email
COPY packages/libs ./packages/libs
COPY packages/permissions ./packages/permissions
COPY packages/importers ./packages/importers
COPY packages/mcp ./packages/mcp
COPY i18n ./i18n
COPY apps/api ./apps/api

WORKDIR /app/packages/email
RUN pnpm run build

WORKDIR /app/packages/permissions
RUN pnpm run build

WORKDIR /app/packages/importers
RUN pnpm run build

WORKDIR /app/apps/api
RUN pnpm run build

# Assembles the production node_modules on the BUILD platform (native, no QEMU emulation).
# All API runtime deps are pure JavaScript (bcrypt was replaced with bcryptjs), so this
# node_modules is architecture-independent and is copied into the runtime stage below.
FROM --platform=$BUILDPLATFORM node:24.22.2-alpine AS api-runtime

WORKDIR /app

COPY --from=api-builder /app/package.json /app/pnpm-lock.yaml /app/pnpm-workspace.yaml ./
COPY --from=api-builder /app/patches ./patches
COPY --from=api-builder /app/apps/api/package.json ./apps/api/
COPY --from=api-builder /app/packages/typescript-config/package.json ./packages/typescript-config/
COPY --from=api-builder /app/packages/libs/package.json ./packages/libs/
COPY --from=api-builder /app/packages/email/package.json ./packages/email/
COPY --from=api-builder /app/packages/permissions/package.json ./packages/permissions/
COPY --from=api-builder /app/packages/importers/package.json ./packages/importers/
COPY --from=api-builder /app/packages/mcp/package.json ./packages/mcp/

RUN sed -i 's/"prepare": "husky"/"prepare": ""/g' package.json && \
  corepack enable && \
  corepack prepare pnpm@12.15.0 --activate && \
  HUSKY=0 NODE_ENV=production pnpm install --prod --frozen-lockfile --no-optional

COPY --from=api-builder /app/apps/api/dist ./apps/api/dist
COPY --from=api-builder /app/apps/api/drizzle ./apps/api/drizzle
COPY --from=api-builder /app/packages/email ./packages/email
COPY --from=api-builder /app/packages/permissions ./packages/permissions
COPY --from=api-builder /app/packages/importers/dist ./packages/importers/dist
COPY --from=api-builder /app/packages/mcp/dist ./packages/mcp/dist

FROM --platform=$BUILDPLATFORM node:24.22.2-alpine AS web-builder

RUN apk add --no-cache python3 make g++ && \
  corepack enable && \
  corepack prepare pnpm@12.15.0 --activate

WORKDIR /app

COPY pnpm-workspace.yaml pnpm-lock.yaml package.json vite.config.ts ./
COPY patches ./patches
COPY apps/web/package.json ./apps/web/
COPY packages/typescript-config/package.json ./packages/typescript-config/
COPY packages/libs/package.json ./packages/libs/
COPY packages/typescript-config ./packages/typescript-config
COPY packages/libs ./packages/libs
COPY packages/permissions ./packages/permissions
COPY packages/editor ./packages/editor
COPY i18n ./i18n
COPY apps/web ./apps/web

RUN pnpm install --frozen-lockfile

WORKDIR /app/packages/permissions
RUN pnpm run build

WORKDIR /app/packages/editor
RUN pnpm run build

WORKDIR /app/apps/web
RUN pnpm run build && find dist -type f -name '*.map' -delete

FROM node:24.22.2-alpine AS runtime

# Alpine replaces older package patches, so accept later security fixes too.
RUN apk add --no-cache 'nginx>=1.30.6' && \
  addgroup -g 1001 appuser && \
  adduser -u 1001 -G appuser -D appuser && \
  mkdir -p /app /app/apps/api/data /var/lib/kaneo /docker-entrypoint.d && \
  chown -R appuser:appuser /app && \
  chown appuser:root /var/lib/kaneo && \
  chmod 2775 /var/lib/kaneo

WORKDIR /app

COPY --from=api-runtime --chown=appuser:appuser /app /app

# Fail the build early if the runtime dependency layout is broken on the target architecture
RUN cd /app/apps/api && node -e "const fs=require('fs');for(const m of ['bcryptjs','hono','pg','drizzle-orm','better-auth','ioredis','valibot','octokit','@modelcontextprotocol/sdk']){fs.accessSync('node_modules/'+m+'/package.json')}for(const m of ['email','permissions','importers']){fs.accessSync('node_modules/@kaneo/'+m+'/dist/index.js')}" && \
  node --input-type=module -e "import { registerTools } from '@kaneo/mcp/tools'; if (typeof registerTools !== 'function') process.exit(1)"

COPY --from=web-builder --chown=appuser:appuser /app/apps/web/dist /usr/share/nginx/html
COPY apps/web/nginx.main.conf /etc/nginx/nginx.conf
COPY --chown=appuser:appuser apps/web/nginx.kaneo.conf /etc/nginx/conf.d/default.conf
COPY --chown=appuser:appuser apps/web/runtime-storage.sh /docker-entrypoint.d/05-kaneo-runtime-storage.sh
COPY --chown=appuser:appuser apps/web/env.sh /docker-entrypoint.d/env.sh
COPY --chown=appuser:appuser apps/web/env.awk /docker-entrypoint.d/env.awk
COPY --chown=appuser:appuser deploy/kaneo-entrypoint.sh /usr/local/bin/kaneo-entrypoint.sh

RUN chmod +x /docker-entrypoint.d/05-kaneo-runtime-storage.sh /docker-entrypoint.d/env.sh /usr/local/bin/kaneo-entrypoint.sh

ENV NODE_ENV=production
ENV TMPDIR=/var/lib/kaneo/tmp

USER 1001:0
EXPOSE 5173

HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=3 \
  CMD wget -Y off --no-verbose --tries=1 --spider http://127.0.0.1:5173/api/health || exit 1

CMD ["/usr/local/bin/kaneo-entrypoint.sh"]