# Base image FROM python:3.12.3-slim-bookworm as base # Install Nginx, curl, and build-essential RUN apt update && apt install -y nginx curl build-essential \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ && rm /etc/nginx/sites-enabled/default # Install Node tools RUN curl -fsSL https://deb.nodesource.com/setup_21.x | bash - \ && apt-get install -y nodejs \ && npm install -g corepack pm2 # Frontend Build FROM base AS builder WORKDIR /app/web # Install dependencies based on the preferred package manager COPY ./apps/web/package.json ./apps/web/pnpm-lock.yaml* ./ COPY ./apps/web /app/web # Remove any environment files that might interfere RUN rm -f .env* # Omit --production flag for TypeScript devDependencies RUN \ if [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \ elif [ -f package-lock.json ]; then npm ci; \ else echo "Warning: Lockfile not found. It is recommended to commit lockfiles to version control." && npm install; \ fi # Environment variables must be present at build time ARG NEXT_PUBLIC_LEARNHOUSE_API_URL ARG NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL ARG NEXT_PUBLIC_LEARNHOUSE_DOMAIN ARG NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG ARG NEXT_PUBLIC_LEARNHOUSE_MULTI_ORG ARG NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN ENV NEXT_PUBLIC_LEARNHOUSE_API_URL=${NEXT_PUBLIC_LEARNHOUSE_API_URL} ENV NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL=${NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL} ENV NEXT_PUBLIC_LEARNHOUSE_DOMAIN=${NEXT_PUBLIC_LEARNHOUSE_DOMAIN} ENV NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG=${NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG} ENV NEXT_PUBLIC_LEARNHOUSE_MULTI_ORG=${NEXT_PUBLIC_LEARNHOUSE_MULTI_ORG} ENV NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN=${NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN} # Next.js collects completely anonymous telemetry data about general usage # Disable telemetry at build time ENV NEXT_TELEMETRY_DISABLED 1 # Build Next.js based on the preferred package manager RUN \ if [ -f pnpm-lock.yaml ]; then pnpm build; \ elif [ -f package-lock.json ]; then npm run build; \ else npm run build; \ fi # Final image FROM base AS runner RUN addgroup --system --gid 1001 system \ && adduser --system --uid 1001 app \ && mkdir .next \ && chown app:system .next COPY --from=builder /app/web/public ./app/web/public # Automatically leverage output traces to reduce image size # https://nextjs.org/docs/advanced-features/output-file-tracing COPY --from=builder --chown=app:system /app/web/.next/standalone ./app/web/ COPY --from=builder --chown=app:system /app/web/.next/static ./app/web/.next/static # Environment variables must be redefined at run time ARG NEXT_PUBLIC_LEARNHOUSE_API_URL ARG NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL ARG NEXT_PUBLIC_LEARNHOUSE_DOMAIN ARG NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG ARG NEXT_PUBLIC_LEARNHOUSE_MULTI_ORG ARG NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN ENV NEXT_PUBLIC_LEARNHOUSE_API_URL=${NEXT_PUBLIC_LEARNHOUSE_API_URL} ENV NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL=${NEXT_PUBLIC_LEARNHOUSE_BACKEND_URL} ENV NEXT_PUBLIC_LEARNHOUSE_DOMAIN=${NEXT_PUBLIC_LEARNHOUSE_DOMAIN} ENV NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG=${NEXT_PUBLIC_LEARNHOUSE_DEFAULT_ORG} ENV NEXT_PUBLIC_LEARNHOUSE_MULTI_ORG=${NEXT_PUBLIC_LEARNHOUSE_MULTI_ORG} ENV NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN=${NEXT_PUBLIC_LEARNHOUSE_TOP_DOMAIN} # Backend Build WORKDIR /app/api COPY ./apps/api/uv.lock ./ COPY ./apps/api/pyproject.toml ./ # Install dependencies with uv (fallback to pip if needed) RUN pip install --upgrade pip && \ pip install uv && \ (uv sync --system || pip install -e .) && \ pip install uvicorn COPY ./apps/api ./ # Run the backend WORKDIR /app COPY ./extra/nginx.conf /etc/nginx/conf.d/default.conf ENV PORT=80 LEARNHOUSE_PORT=9000 HOSTNAME=0.0.0.0 # Set DATABASE_URL to use the same value as LEARNHOUSE_SQL_CONNECTION_STRING at runtime ENV DATABASE_URL=${LEARNHOUSE_SQL_CONNECTION_STRING} COPY ./extra/start.sh /app/start.sh # Make the start script executable RUN chmod +x /app/start.sh # Use the start script CMD ["sh", "/app/start.sh"]