# Build frontend in a dedicated stage FROM node:24-alpine AS frontend-build WORKDIR /app/frontend COPY frontend/package*.json frontend/package-lock*.json ./ RUN npm ci --silent COPY frontend/ . RUN npm run build # Final runtime image FROM node:24-alpine WORKDIR /app # copy package manifests and install deps (leverage Docker cache) COPY backend/package*.json backend/package-lock*.json ./backend/ RUN cd backend && npm ci --silent # copy backend source (schema, migrations, source) COPY backend ./backend # generate Prisma client against a harmless temp DB path (does not apply migrations) RUN cd backend && DATABASE_URL="file:./data/sqlite.db" npx prisma generate --schema=./prisma/schema.prisma || true # remove devDependencies to slim image RUN cd backend && npm prune --production --silent # install prisma CLI into final image so entrypoint can run migrate deploy at runtime RUN cd backend && npm i --no-audit --no-fund prisma --silent || true # copy entrypoint and make executable COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh # Copy built frontend into the expected location: /app/frontend/dist COPY --from=frontend-build /app/frontend/dist ./frontend/dist WORKDIR /app/backend EXPOSE 3000 ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] CMD ["node", "server.js"]