# check=skip=SecretsUsedInArgOrEnv # Multi-stage Docker build for RxMinder application # Uses centralized configuration and follows security best practices # Build stage FROM oven/bun:alpine AS builder # Install system dependencies for native modules RUN apk add --no-cache python3 make g++ gettext # Create non-root user for security RUN addgroup -g 1001 -S nodeuser && adduser -S nodeuser -u 1001 -G nodeuser # Create and set permissions for the working directory RUN mkdir -p /app && chown -R nodeuser:nodeuser /app WORKDIR /app USER nodeuser # Copy package files first for better Docker layer caching COPY --chown=nodeuser:nodeuser package.json ./ COPY --chown=nodeuser:nodeuser bun.lock ./ # Install dependencies RUN bun install --frozen-lockfile # Copy source code COPY --chown=nodeuser:nodeuser . ./ # Build arguments for environment configuration # Application Configuration ARG APP_NAME=RxMinder ARG APP_VERSION=1.0.0 ARG APP_BASE_URL=http://localhost:5173 # Database Configuration ARG VITE_COUCHDB_URL=http://localhost:5984 ARG VITE_COUCHDB_USER=admin ARG VITE_COUCHDB_PASSWORD=change-this-secure-password # Authentication Configuration ARG JWT_SECRET=your-super-secret-jwt-key-change-in-production # Email Configuration (Optional) ARG VITE_MAILGUN_API_KEY="" ARG VITE_MAILGUN_DOMAIN="" ARG VITE_MAILGUN_FROM_NAME="RxMinder" ARG VITE_MAILGUN_FROM_EMAIL="" # OAuth Configuration (Optional) ARG VITE_GOOGLE_CLIENT_ID="" ARG VITE_GITHUB_CLIENT_ID="" # Feature Flags ARG ENABLE_EMAIL_VERIFICATION=true ARG ENABLE_OAUTH=true ARG ENABLE_ADMIN_INTERFACE=true ARG DEBUG_MODE=false # Build Environment ARG NODE_ENV=production # Set environment variables for build process # These are embedded into the static build at compile time ENV VITE_APP_NAME=$APP_NAME ENV APP_VERSION=$APP_VERSION ENV APP_BASE_URL=$APP_BASE_URL ENV VITE_COUCHDB_URL=$VITE_COUCHDB_URL ENV VITE_COUCHDB_USER=$VITE_COUCHDB_USER ENV VITE_COUCHDB_PASSWORD=$VITE_COUCHDB_PASSWORD ENV JWT_SECRET=$JWT_SECRET ENV VITE_MAILGUN_API_KEY=$VITE_MAILGUN_API_KEY ENV VITE_MAILGUN_DOMAIN=$VITE_MAILGUN_DOMAIN ENV VITE_MAILGUN_FROM_NAME=$VITE_MAILGUN_FROM_NAME ENV VITE_MAILGUN_FROM_EMAIL=$VITE_MAILGUN_FROM_EMAIL ENV VITE_GOOGLE_CLIENT_ID=$VITE_GOOGLE_CLIENT_ID ENV VITE_GITHUB_CLIENT_ID=$VITE_GITHUB_CLIENT_ID ENV ENABLE_EMAIL_VERIFICATION=$ENABLE_EMAIL_VERIFICATION ENV ENABLE_OAUTH=$ENABLE_OAUTH ENV ENABLE_ADMIN_INTERFACE=$ENABLE_ADMIN_INTERFACE ENV DEBUG_MODE=$DEBUG_MODE ENV NODE_ENV=$NODE_ENV # Process HTML template with APP_NAME RUN envsubst '$APP_NAME' < index.html.template > index.html || cp index.html.template index.html # Build the application RUN bun run build # Production stage - serve with nginx FROM nginx:alpine # Install wget for health checks RUN apk add --no-cache wget # Copy built files from builder stage COPY --from=builder /app/dist /usr/share/nginx/html # Copy nginx configuration COPY --from=builder /app/docker/nginx.conf /etc/nginx/conf.d/default.conf # Set proper permissions for nginx RUN chown -R nginx:nginx /usr/share/nginx/html && \ chown -R nginx:nginx /var/cache/nginx && \ chown -R nginx:nginx /var/log/nginx && \ chown -R nginx:nginx /etc/nginx/conf.d # Add health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1 # Expose port 80 EXPOSE 80 # Start nginx (runs as nginx user by default in alpine) CMD ["nginx", "-g", "daemon off;"]