# Use the official Bun image as base FROM oven/bun:1 as builder # Set working directory WORKDIR /app # Copy package files COPY package*.json ./ COPY bun.lockb* ./ # Install dependencies RUN bun install --frozen-lockfile # Copy source code COPY src/ ./src/ COPY tsconfig.json ./ # Build the application RUN bun run build # Production stage FROM node:18-alpine # Install security updates RUN apk update && apk upgrade && apk add --no-cache dumb-init # Create app directory WORKDIR /app # Create non-root user RUN addgroup -g 1001 -S nodejs && \ adduser -S nodeuser -u 1001 # Copy built application from builder stage COPY --from=builder --chown=nodeuser:nodejs /app/dist ./dist COPY --from=builder --chown=nodeuser:nodejs /app/package.json ./ # Install production dependencies RUN npm ci --only=production && npm cache clean --force # Create logs directory RUN mkdir -p logs && chown nodeuser:nodejs logs # Switch to non-root user USER nodeuser # Expose port EXPOSE 3000 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD node -e "require('http').get('http://localhost:3000/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1))" # Start the application ENTRYPOINT ["dumb-init", "--"] CMD ["node", "dist/index.js"]