FROM node:20-alpine AS base RUN corepack enable && corepack prepare pnpm@9.15.4 --activate WORKDIR /app FROM golang:1.22-alpine AS node-build WORKDIR /src ARG MEDIA_NODE_VERSION=1.3.12 RUN apk add --no-cache git ca-certificates COPY node/media-node/ ./ RUN go mod tidy \ && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X main.version=${MEDIA_NODE_VERSION}" -o /media-node-linux-amd64 ./cmd/media-node \ && CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags="-s -w -X main.version=${MEDIA_NODE_VERSION}" -o /media-node-linux-arm64 ./cmd/media-node FROM base AS builder COPY package.json pnpm-workspace.yaml ./ COPY apps/master-api ./apps/master-api COPY packages ./packages RUN pnpm install --no-frozen-lockfile RUN pnpm --filter @media-cluster/shared-types build RUN pnpm --filter @media-cluster/protocol build WORKDIR /app/apps/master-api RUN pnpm exec prisma generate RUN pnpm build WORKDIR /app RUN mkdir -p /out \ && cp -R apps/master-api/dist /out/dist \ && cp -R apps/master-api/prisma /out/prisma \ && cp apps/master-api/package.json /out/package.json \ && mkdir -p /out/assets \ && cp -R apps/master-api/assets/. /out/assets/ \ && mkdir -p /out/local-packages \ && cp -R packages/shared-types /out/local-packages/shared-types \ && cp -R packages/protocol /out/local-packages/protocol FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production # python3 blijft voor Odido Widevine CDM (pywidevine); make/g++ alleen voor npm native builds RUN apk add --no-cache openssl wget python3 py3-pip make g++ COPY --from=builder /out/dist ./dist COPY --from=builder /out/prisma ./prisma COPY --from=builder /out/package.json ./package.json COPY --from=builder /out/assets ./assets COPY --from=builder /out/local-packages ./local-packages COPY --from=node-build /media-node-linux-amd64 /app/install/media-node-linux-amd64 COPY --from=node-build /media-node-linux-arm64 /app/install/media-node-linux-arm64 COPY deploy/node/install-unraid.sh /app/install/unraid.sh COPY deploy/node/install-synology.sh /app/install/synology.sh COPY deploy/node/upgrade-node.sh /app/install/upgrade-node.sh COPY apps/master-api/scripts/odido_cdm.py /app/scripts/odido_cdm.py # Remove workspace protocol deps before npm install RUN node -e "\ const fs=require('fs');\ const p=JSON.parse(fs.readFileSync('package.json','utf8'));\ delete p.dependencies['@media-cluster/protocol'];\ delete p.dependencies['@media-cluster/shared-types'];\ p.dependencies.prisma = (p.devDependencies && p.devDependencies.prisma) || '6.3.1';\ delete p.devDependencies;\ delete p.scripts;\ fs.writeFileSync('package.json', JSON.stringify(p, null, 2));" RUN npm install --omit=dev \ && npx prisma generate \ && pip3 install --no-cache-dir --break-system-packages pywidevine requests \ && apk del make g++ # IMPORTANT: copy workspace packages AFTER npm install (npm wipes node_modules) RUN mkdir -p node_modules/@media-cluster \ && cp -R local-packages/shared-types node_modules/@media-cluster/shared-types \ && cp -R local-packages/protocol node_modules/@media-cluster/protocol \ && node -e "\ const fs=require('fs');\ const p=JSON.parse(fs.readFileSync('node_modules/@media-cluster/protocol/package.json','utf8'));\ p.dependencies={'@media-cluster/shared-types':'1.0.0'};\ delete p.devDependencies;\ fs.writeFileSync('node_modules/@media-cluster/protocol/package.json', JSON.stringify(p,null,2));\ const s=JSON.parse(fs.readFileSync('node_modules/@media-cluster/shared-types/package.json','utf8'));\ delete s.devDependencies;\ fs.writeFileSync('node_modules/@media-cluster/shared-types/package.json', JSON.stringify(s,null,2));\ " \ && node -e "require('@media-cluster/protocol'); require('@media-cluster/shared-types'); console.log('workspace packages ok')" EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=5s --start-period=60s --retries=5 \ CMD wget -qO- http://127.0.0.1:3000/health || exit 1 CMD ["sh", "-c", "npx prisma migrate deploy && node dist/app.js"]