Spaces:
Sleeping
Sleeping
File size: 6,640 Bytes
68f7925 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# syntax=docker.io/docker/dockerfile:1
# Force cache invalidation for HuggingFace Spaces
ARG CACHEBUST=1
FROM node:slim AS base
# Install Python and build tools for native dependencies
# Install Chromium and dependencies for Puppeteer
RUN apt-get update && apt-get install -y \
python3 make g++ \
chromium \
fonts-noto-cjk \
fonts-liberation \
fonts-freefont-ttf \
ca-certificates \
libnss3 \
libatk-bridge2.0-0 \
libdrm2 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxrandr2 \
libgbm1 \
libxkbcommon0 \
libasound2 \
libatspi2.0-0 \
libgtk-3-0 \
libglib2.0-0 \
libxss1 \
libgconf-2-4 \
&& rm -rf /var/lib/apt/lists/*
# Set Puppeteer to use installed Chromium
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
ENV PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
# Install dependencies only when needed
FROM base AS deps
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci --include=optional; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi
# Install the correct platform-specific packages based on architecture
RUN if [ "$(uname -m)" = "x86_64" ]; then \
npm install lightningcss-linux-x64-gnu@1.29.1 --no-save; \
elif [ "$(uname -m)" = "aarch64" ]; then \
npm install lightningcss-linux-arm64-gnu@1.29.1 --no-save; \
fi && \
npm rebuild @tailwindcss/oxide --update-binary
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
# Clear all cache to avoid build issues
RUN rm -rf .next node_modules/.cache
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Rebuild native dependencies for the builder stage
# Rebuild sharp and other native modules for the platform
RUN if [ "$(uname -m)" = "x86_64" ]; then \
npm install lightningcss-linux-x64-gnu@1.29.1 --no-save; \
elif [ "$(uname -m)" = "aarch64" ]; then \
npm install lightningcss-linux-arm64-gnu@1.29.1 --no-save; \
fi && \
npm rebuild sharp && \
npm rebuild @tailwindcss/oxide --update-binary
# Clean up build artifacts
RUN rm -rf .next/cache node_modules/.cache
# Build arguments for API keys (passed from HuggingFace Spaces environment)
ARG OPENAI_TEMPLATE_AI_DEV
ARG OPENAI_GENERATE_FV_AI
ARG CLAUDE_TEMPLATE_AI_DEV
ARG ANTHROPIC_API_KEY
ARG GOOGLE_API_KEY
ARG NEXT_PUBLIC_APP_ENV
ARG OKTA_OAUTH2_ISSUER
ARG OKTA_OAUTH2_CLIENT_ID
ARG OKTA_OAUTH2_CLIENT_SECRET
ARG SECRET
# Set environment variables for build time
ENV NEXT_TELEMETRY_DISABLED=1
ENV NEXT_PUBLIC_APP_ENV=$NEXT_PUBLIC_APP_ENV
ENV OPENAI_TEMPLATE_AI_DEV=$OPENAI_TEMPLATE_AI_DEV
ENV OPENAI_GENERATE_FV_AI=$OPENAI_GENERATE_FV_AI
ENV CLAUDE_TEMPLATE_AI_DEV=$CLAUDE_TEMPLATE_AI_DEV
ENV ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY
ENV GOOGLE_API_KEY=$GOOGLE_API_KEY
ENV OKTA_OAUTH2_ISSUER=$OKTA_OAUTH2_ISSUER
ENV OKTA_OAUTH2_CLIENT_ID=$OKTA_OAUTH2_CLIENT_ID
ENV OKTA_OAUTH2_CLIENT_SECRET=$OKTA_OAUTH2_CLIENT_SECRET
ENV SECRET=$SECRET
# Set memory limit for build process
ENV NODE_OPTIONS="--max-old-space-size=2048"
RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi
# Remove build cache to reduce image size (keep only necessary runtime files)
RUN rm -rf .next/cache/webpack .next/cache/swc node_modules/.cache
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
# Disable Next.js telemetry and set cache to writable location
ENV NEXT_TELEMETRY_DISABLED=1
ENV TMPDIR=/tmp
# Runtime environment variables for API keys
ARG OPENAI_TEMPLATE_AI_DEV
ARG OPENAI_GENERATE_FV_AI
ARG CLAUDE_TEMPLATE_AI_DEV
ARG ANTHROPIC_API_KEY
ARG GOOGLE_API_KEY
ARG NEXT_PUBLIC_APP_ENV
ARG OKTA_OAUTH2_ISSUER
ARG OKTA_OAUTH2_CLIENT_ID
ARG OKTA_OAUTH2_CLIENT_SECRET
ARG SECRET
ENV NEXT_PUBLIC_APP_ENV=$NEXT_PUBLIC_APP_ENV
ENV OPENAI_TEMPLATE_AI_DEV=$OPENAI_TEMPLATE_AI_DEV
ENV OPENAI_GENERATE_FV_AI=$OPENAI_GENERATE_FV_AI
ENV CLAUDE_TEMPLATE_AI_DEV=$CLAUDE_TEMPLATE_AI_DEV
ENV ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY
ENV GOOGLE_API_KEY=$GOOGLE_API_KEY
ENV OKTA_OAUTH2_ISSUER=$OKTA_OAUTH2_ISSUER
ENV OKTA_OAUTH2_CLIENT_ID=$OKTA_OAUTH2_CLIENT_ID
ENV OKTA_OAUTH2_CLIENT_SECRET=$OKTA_OAUTH2_CLIENT_SECRET
ENV SECRET=$SECRET
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs --home /home/nextjs
# Copy node_modules for runtime (including Puppeteer)
COPY --from=builder /app/node_modules ./node_modules
RUN chown -R nextjs:nodejs ./node_modules
# Ensure nextjs user has access to home directory
RUN chown -R nextjs:nodejs /home/nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
# Copy .next directory but exclude cache to avoid permission issues
COPY --from=builder --chown=nextjs:nodejs /app/.next/server ./.next/server
COPY --from=builder --chown=nextjs:nodejs /app/.next/required-server-files.json ./.next/required-server-files.json
COPY --from=builder --chown=nextjs:nodejs /app/.next/routes-manifest.json ./.next/routes-manifest.json
COPY --from=builder --chown=nextjs:nodejs /app/.next/build-manifest.json ./.next/build-manifest.json
COPY --from=builder --chown=nextjs:nodejs /app/.next/package.json ./.next/package.json
# Copy optional manifest files (may not exist in all builds)
RUN --mount=type=bind,from=builder,source=/app/.next,target=/tmp/source \
if [ -f /tmp/source/prerender-manifest.json ]; then cp /tmp/source/prerender-manifest.json ./.next/; fi && \
if [ -f /tmp/source/react-loadable-manifest.json ]; then cp /tmp/source/react-loadable-manifest.json ./.next/; fi && \
chown -R nextjs:nodejs ./.next/
# Create cache directories and ensure full permissions (combining both approaches)
RUN mkdir -p /tmp/.next/cache/images && \
mkdir -p /app/.next/cache/images && \
chmod -R 777 /tmp && \
chmod -R 755 /app/.next && \
chmod -R 777 /app/.next/cache/images && \
chown -R nextjs:nodejs /tmp/.next && \
chown -R nextjs:nodejs /app/.next
USER nextjs
EXPOSE 7860
ENV PORT=7860
ENV HOSTNAME="0.0.0.0"
# Optimize for HuggingFace free tier
ENV NODE_OPTIONS="--max-old-space-size=1024"
CMD ["node", "server.js"] |