# check=skip=SecretsUsedInArgOrEnv # Build stage FROM oven/bun:alpine AS builder # Install system dependencies for native modules RUN apk add --no-cache python3 make g++ # 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 # CouchDB Configuration ARG VITE_COUCHDB_URL=http://localhost:5984 ARG VITE_COUCHDB_USER=admin ARG VITE_COUCHDB_PASSWORD=change-this-secure-password # Application Configuration ARG APP_BASE_URL=http://localhost:5173 # OAuth Configuration (Optional) ARG VITE_GOOGLE_CLIENT_ID="" ARG VITE_GITHUB_CLIENT_ID="" # Build Environment ARG NODE_ENV=production # Set environment variables for build process # These are embedded into the static build at compile time ENV VITE_COUCHDB_URL=$VITE_COUCHDB_URL ENV VITE_COUCHDB_USER=$VITE_COUCHDB_USER ENV VITE_COUCHDB_PASSWORD=$VITE_COUCHDB_PASSWORD ENV APP_BASE_URL=$APP_BASE_URL ENV VITE_GOOGLE_CLIENT_ID=$VITE_GOOGLE_CLIENT_ID ENV VITE_GITHUB_CLIENT_ID=$VITE_GITHUB_CLIENT_ID ENV NODE_ENV=$NODE_ENV # Build the application RUN bun run build # Production stage - serve with nginx FROM nginx:alpine # Install curl for health checks RUN apk add --no-cache curl # 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 curl -f http://localhost/ || exit 1 # Expose port 80 EXPOSE 80 # Start nginx (runs as nginx user by default in alpine) CMD ["nginx", "-g", "daemon off;"]