FROM node:20-alpine as base # Install Deno RUN apk update && apk upgrade && \ apk add --no-cache dumb-init curl unzip && \ curl -fsSL https://deno.land/install.sh | sh && \ mv /root/.deno/bin/deno /usr/local/bin/ && \ apk del curl unzip && \ rm -rf /var/cache/apk/* # Set working directory WORKDIR /app # DEPENDENCIES stage FROM base as deps # Copy package files for Deno COPY package.json deno.lock* ./ # Install using Deno RUN deno install # BUILDER stage FROM base as builder WORKDIR /app # Copy dependencies from deps stage COPY --from=deps /app/node_modules ./node_modules # Copy source code COPY . . # Create production build RUN deno task build # PRODUCTION stage FROM base as production # Set prod environment ENV NODE_ENV=production \ PORT=3000 # Create non-root user RUN addgroup -g 1001 -S nodejs && \ adduser -S -u 1001 -G nodejs nodejs WORKDIR /app # Copy only necessary files from builder COPY --chown=nodejs:nodejs --from=builder /app/package.json ./ COPY --chown=nodejs:nodejs --from=builder /app/deno.lock* ./ COPY --chown=nodejs:nodejs --from=builder /app/node_modules ./node_modules COPY --chown=nodejs:nodejs --from=builder /app/build ./build # Switch to non-root user USER nodejs # Expose port EXPOSE 3000 # Use dumb-init to handle signals properly ENTRYPOINT ["dumb-init", "--"] # Start the application # For adapter-node (SSR): CMD ["node", "build/index.js"]