chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
# ========================================
|
||||
# Base Stage: Debian-based Bun with Node.js 22
|
||||
# ========================================
|
||||
FROM oven/bun:1.3.13-slim AS base
|
||||
|
||||
# Install Node.js 22 and common dependencies once in base stage
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
python3 python3-pip python3-venv make g++ curl ca-certificates bash ffmpeg \
|
||||
&& curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
||||
&& apt-get install -y nodejs
|
||||
|
||||
# ========================================
|
||||
# Pruner Stage: Emit a minimal monorepo subset that sim depends on
|
||||
# ========================================
|
||||
FROM base AS pruner
|
||||
WORKDIR /app
|
||||
|
||||
RUN bun install -g turbo@2.9.6
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN turbo prune sim --docker
|
||||
|
||||
# ========================================
|
||||
# Dependencies Stage: Install Dependencies
|
||||
# ========================================
|
||||
FROM base AS deps
|
||||
WORKDIR /app
|
||||
|
||||
# Pruned manifests from the pruner stage. This layer only invalidates when
|
||||
# package.json/bun.lock content changes — not on source edits.
|
||||
COPY --from=pruner /app/out/json/ ./
|
||||
# Use the full bun.lock (not the pruned out/bun.lock). turbo prune emits a
|
||||
# bun.lock that bun 1.3.x rejects with "Failed to resolve prod dependency",
|
||||
# forcing a slow fresh resolve. The full lockfile parses cleanly and bun
|
||||
# only installs what the pruned package.jsons reference.
|
||||
COPY --from=pruner /app/bun.lock ./bun.lock
|
||||
|
||||
# Install all dependencies (including devDependencies — tailwindcss/postcss are
|
||||
# devDeps but required at build time). Then rebuild isolated-vm against Node.js.
|
||||
# JOBS=4 caps node-gyp parallelism — higher values OOM isolated-vm (laverdet/isolated-vm#428).
|
||||
RUN --mount=type=cache,id=bun-cache,target=/root/.bun/install/cache \
|
||||
--mount=type=cache,id=npm-cache,target=/root/.npm \
|
||||
HUSKY=0 bun install --ignore-scripts --linker=hoisted && \
|
||||
cd node_modules/isolated-vm && JOBS=4 npx node-gyp rebuild --release
|
||||
|
||||
# ========================================
|
||||
# Builder Stage: Build the Application
|
||||
# ========================================
|
||||
FROM base AS builder
|
||||
ARG TARGETPLATFORM
|
||||
WORKDIR /app
|
||||
|
||||
# Copy node_modules from deps stage (cached if dependencies don't change)
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
|
||||
# Copy pruned source tree (apps/sim + workspace packages it depends on)
|
||||
COPY --from=pruner /app/out/full/ ./
|
||||
|
||||
# Next.js 16 / Turbopack workspace-root detection looks for a lockfile next to
|
||||
# the workspace package.json. Without it, `next build` fails with
|
||||
# "couldn't find next/package.json from /app/apps/sim". turbo also warns
|
||||
# "Lockfile not found at /app/bun.lock" without it.
|
||||
COPY --from=pruner /app/bun.lock ./bun.lock
|
||||
|
||||
ENV NEXT_TELEMETRY_DISABLED=1 \
|
||||
VERCEL_TELEMETRY_DISABLED=1 \
|
||||
DOCKER_BUILD=1
|
||||
|
||||
# Dummy values so next build can evaluate modules. Override at runtime.
|
||||
ARG DATABASE_URL="postgresql://user:pass@localhost:5432/dummy"
|
||||
ENV DATABASE_URL=${DATABASE_URL}
|
||||
|
||||
ARG NEXT_PUBLIC_APP_URL="http://localhost:3000"
|
||||
ENV NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL}
|
||||
|
||||
# Per-platform cache id keeps arm64/amd64 SWC artifacts isolated.
|
||||
RUN --mount=type=cache,id=next-cache-${TARGETPLATFORM},target=/app/apps/sim/.next/cache \
|
||||
--mount=type=cache,id=turbo-cache-${TARGETPLATFORM},target=/app/.turbo \
|
||||
bun run build
|
||||
|
||||
# Bundle the secrets-loading bootstrap into a self-contained entrypoint. It runs
|
||||
# before (and outside) the Next standalone server, so its dependencies
|
||||
# (@sim/runtime-secrets, AWS SDK) are inlined here rather than resolved from the
|
||||
# pruned standalone node_modules. The dynamic import of ./server.js stays a
|
||||
# runtime import.
|
||||
RUN bun build apps/sim/bootstrap.ts --target=bun --outfile=apps/sim/bootstrap.js
|
||||
|
||||
# ========================================
|
||||
# Runner Stage: Run the actual app
|
||||
# ========================================
|
||||
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
# Node.js 22, Python, ffmpeg, etc. are already installed in base stage
|
||||
ENV NODE_ENV=production
|
||||
|
||||
# Create non-root user and group
|
||||
RUN groupadd -g 1001 nodejs && \
|
||||
useradd -u 1001 -g nodejs nextjs
|
||||
|
||||
# Copy application artifacts from builder
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/apps/sim/public ./apps/sim/public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/apps/sim/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/apps/sim/.next/static ./apps/sim/.next/static
|
||||
|
||||
# Self-contained secrets-loading bootstrap (bundled in the builder stage). Runs
|
||||
# before the standalone server.js to hydrate process.env from the runtime secret.
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/apps/sim/bootstrap.js ./apps/sim/bootstrap.js
|
||||
|
||||
# Copy blog/author content for runtime filesystem reads (not part of the JS bundle)
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/apps/sim/content ./apps/sim/content
|
||||
|
||||
# Copy isolated-vm native module (compiled for Node.js in deps stage)
|
||||
COPY --from=deps --chown=nextjs:nodejs /app/node_modules/isolated-vm ./node_modules/isolated-vm
|
||||
|
||||
# Copy the isolated-vm worker script
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/apps/sim/lib/execution/isolated-vm-worker.cjs ./apps/sim/lib/execution/isolated-vm-worker.cjs
|
||||
|
||||
# Copy the pre-built sandbox library bundles (pptxgenjs, docx, pdf-lib) that
|
||||
# run inside the V8 isolate. Committed into the repo; see
|
||||
# apps/sim/lib/execution/sandbox/bundles/build.ts to regenerate.
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/apps/sim/lib/execution/sandbox/bundles ./apps/sim/lib/execution/sandbox/bundles
|
||||
|
||||
# Guardrails PII runs in a standalone Presidio service (combined analyzer +
|
||||
# anonymizer, docker/pii.Dockerfile), reached over the network via PII_URL —
|
||||
# no Python/Presidio in this image.
|
||||
|
||||
# Create .next/cache directory with correct ownership
|
||||
RUN mkdir -p apps/sim/.next/cache && \
|
||||
chown -R nextjs:nodejs apps/sim/.next/cache
|
||||
|
||||
# Switch to non-root user
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3000
|
||||
ENV PORT=3000 \
|
||||
HOSTNAME="0.0.0.0"
|
||||
|
||||
CMD ["bun", "apps/sim/bootstrap.js"]
|
||||
@@ -0,0 +1,58 @@
|
||||
# ========================================
|
||||
# Base Stage: Alpine Linux with Bun
|
||||
# ========================================
|
||||
FROM oven/bun:1.3.13-alpine AS base
|
||||
|
||||
# ========================================
|
||||
# Dependencies Stage: Install Dependencies
|
||||
# ========================================
|
||||
FROM base AS deps
|
||||
WORKDIR /app
|
||||
|
||||
# Copy only package files needed for migrations (these change less frequently)
|
||||
COPY package.json bun.lock turbo.json ./
|
||||
RUN mkdir -p packages/db packages/logger packages/tsconfig packages/utils
|
||||
COPY packages/db/package.json ./packages/db/package.json
|
||||
COPY packages/logger/package.json ./packages/logger/package.json
|
||||
COPY packages/tsconfig/package.json ./packages/tsconfig/package.json
|
||||
COPY packages/utils/package.json ./packages/utils/package.json
|
||||
|
||||
# Install dependencies with cache mount for faster builds
|
||||
RUN --mount=type=cache,id=bun-cache,target=/root/.bun/install/cache \
|
||||
bun install --ignore-scripts
|
||||
|
||||
# ========================================
|
||||
# Runner Stage: Production Environment
|
||||
# ========================================
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
# Create non-root user and group (cached separately)
|
||||
RUN addgroup -g 1001 -S nodejs && \
|
||||
adduser -S nextjs -u 1001
|
||||
|
||||
# Copy only the necessary files from deps (cached if dependencies don't change)
|
||||
COPY --from=deps --chown=nextjs:nodejs /app/node_modules ./node_modules
|
||||
|
||||
# Copy root package.json for workspace resolution
|
||||
COPY --chown=nextjs:nodejs package.json ./package.json
|
||||
|
||||
# Copy package configuration files (needed for migrations)
|
||||
COPY --chown=nextjs:nodejs packages/db/drizzle.config.ts ./packages/db/drizzle.config.ts
|
||||
|
||||
# Copy tsconfig package (needed for workspace symlink resolution)
|
||||
COPY --chown=nextjs:nodejs packages/tsconfig ./packages/tsconfig
|
||||
|
||||
# Copy utils package (needed by db scripts that import @sim/utils)
|
||||
COPY --chown=nextjs:nodejs packages/utils ./packages/utils
|
||||
|
||||
# Copy logger package (needed by @sim/db's tx-tripwire at import time)
|
||||
COPY --chown=nextjs:nodejs packages/logger ./packages/logger
|
||||
|
||||
# Copy database package source code (changes most frequently - placed last)
|
||||
COPY --chown=nextjs:nodejs packages/db ./packages/db
|
||||
|
||||
# Switch to non-root user
|
||||
USER nextjs
|
||||
|
||||
WORKDIR /app/packages/db
|
||||
@@ -0,0 +1,139 @@
|
||||
# ========================================
|
||||
# Combined Presidio service (analyzer + anonymizer) on a single port (5001)
|
||||
#
|
||||
# ONE image serves both NER engines — the engine is a pure runtime choice via
|
||||
# PII_ENGINE (spacy default | gliner). spaCy large models, torch (CPU), the
|
||||
# gliner package, and the baked GLiNER weights all ship in it, so flipping
|
||||
# engines never requires an image swap.
|
||||
#
|
||||
# ONE image also serves both fleets: the amd64 build ships CUDA torch, which
|
||||
# falls back to CPU when no GPU is present, so the Fargate CPU tasks and the
|
||||
# EC2-GPU tasks pull the same tag. (torch CUDA wheels bundle their own CUDA
|
||||
# libs; the host only needs the nvidia driver + container runtime.)
|
||||
#
|
||||
# Source files are COPY'd last so code edits never re-download deps or models.
|
||||
# ========================================
|
||||
FROM python:3.12-slim-bookworm AS base
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# build-essential for any sdist that compiles native deps (e.g. blis/thinc).
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential curl ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Pinned Python deps. Separate layer so source edits don't reinstall them.
|
||||
COPY apps/pii/requirements.txt ./requirements.txt
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Pinned spaCy models (en + es/it/pl/fi, ~2.2GB total). Downloaded with
|
||||
# retries/resume — the large wheels truncate on flaky networks if pip fetches
|
||||
# the URLs directly.
|
||||
ARG SPACY_MODELS="en_core_web_lg-3.8.0 es_core_news_lg-3.8.0 it_core_news_lg-3.8.0 pl_core_news_lg-3.8.0 fi_core_news_lg-3.8.0"
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
for model in ${SPACY_MODELS}; do \
|
||||
whl="${model}-py3-none-any.whl"; \
|
||||
curl -fL --retry 5 --retry-delay 5 --retry-all-errors -C - \
|
||||
-o "/tmp/${whl}" \
|
||||
"https://github.com/explosion/spacy-models/releases/download/${model}/${whl}" || exit 1; \
|
||||
done && \
|
||||
pip install /tmp/*.whl && \
|
||||
rm /tmp/*.whl
|
||||
|
||||
# --- GLiNER engine deps -------------------------------------------------------
|
||||
# torch is pinned here (not requirements-gliner.txt) because the CPU and CUDA
|
||||
# builds install the same version from different wheel indexes. 2.11.0 is the
|
||||
# newest release published on both the cpu and cu128 indexes for py312.
|
||||
#
|
||||
# cu128's arch list keeps sm_75, the compute capability of the GPU fleet's T4s.
|
||||
# cu121 could not serve this pin anyway — that index stops at torch 2.5.1.
|
||||
# CUDA 12.8 needs an NVIDIA driver >=525 via minor-version compatibility, which
|
||||
# the ECS GPU AMI's nvidia-driver-latest-dkms satisfies.
|
||||
#
|
||||
# arm64 takes the cpu index: cu128 publishes no aarch64 wheel at 2.11.0, and no
|
||||
# arm64 target has a GPU.
|
||||
ARG TORCH_VERSION=2.11.0
|
||||
ARG TORCH_CUDA_INDEX_URL=https://download.pytorch.org/whl/cu128
|
||||
ARG TORCH_CPU_INDEX_URL=https://download.pytorch.org/whl/cpu
|
||||
ARG TARGETARCH
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
case "${TARGETARCH}" in \
|
||||
amd64) torch_index="${TORCH_CUDA_INDEX_URL}" ;; \
|
||||
arm64) torch_index="${TORCH_CPU_INDEX_URL}" ;; \
|
||||
*) echo "unsupported TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;; \
|
||||
esac && \
|
||||
pip install torch==${TORCH_VERSION} --index-url "${torch_index}"
|
||||
|
||||
COPY apps/pii/requirements-gliner.txt ./requirements-gliner.txt
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
pip install -r requirements-gliner.txt
|
||||
|
||||
# Small spaCy models (~60MB total) give the gliner engine tokenization +
|
||||
# lemmas for the regex recognizers; GLiNER does the NER (see engines.py).
|
||||
ARG SPACY_SM_MODELS="en_core_web_sm-3.8.0 es_core_news_sm-3.8.0 it_core_news_sm-3.8.0 pl_core_news_sm-3.8.0 fi_core_news_sm-3.8.0"
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
for model in ${SPACY_SM_MODELS}; do \
|
||||
whl="${model}-py3-none-any.whl"; \
|
||||
curl -fL --retry 5 --retry-delay 5 --retry-all-errors -C - \
|
||||
-o "/tmp/${whl}" \
|
||||
"https://github.com/explosion/spacy-models/releases/download/${model}/${whl}" || exit 1; \
|
||||
done && \
|
||||
pip install /tmp/*.whl && \
|
||||
rm /tmp/*.whl
|
||||
|
||||
# Bake the GLiNER weights at build time (cached layer) so startup never
|
||||
# touches the network. HF_HUB_OFFLINE makes a missing/overridden
|
||||
# PII_GLINER_MODEL fail fast at startup instead of silently downloading.
|
||||
ENV HF_HOME=/opt/hf-cache
|
||||
ARG GLINER_MODEL=urchade/gliner_multi_pii-v1
|
||||
RUN python -c "from gliner import GLiNER; GLiNER.from_pretrained('${GLINER_MODEL}')" && \
|
||||
chmod -R a+rX /opt/hf-cache
|
||||
ENV HF_HUB_OFFLINE=1
|
||||
|
||||
# pytest/httpx for the in-image test suites (tests/) — baked in because the
|
||||
# runtime user has no writable HOME for pip install --user.
|
||||
COPY apps/pii/requirements-dev.txt ./requirements-dev.txt
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
pip install -r requirements-dev.txt
|
||||
|
||||
# Runs after every pip install, because the requirements above resolve against
|
||||
# PyPI and could swap the wheel torch_index chose. A cpu-only torch on amd64
|
||||
# otherwise surfaces only as "torch.cuda.is_available() is False" once GLiNER
|
||||
# loads on a GPU host.
|
||||
RUN python -c "import torch; \
|
||||
have = torch.version.cuda is not None; \
|
||||
want = '${TARGETARCH}' == 'amd64'; \
|
||||
assert have == want, f'{torch.__version__}: cuda build={have}, expected={want}'"
|
||||
|
||||
RUN groupadd -g 1001 pii && \
|
||||
useradd -u 1001 -g pii pii && \
|
||||
chown -R pii:pii /app
|
||||
|
||||
COPY --chown=pii:pii apps/pii/server.py apps/pii/engines.py ./
|
||||
COPY --chown=pii:pii apps/pii/scripts ./scripts
|
||||
COPY --chown=pii:pii apps/pii/tests ./tests
|
||||
|
||||
USER pii
|
||||
|
||||
# Listen on 5001. Runs as its own ECS service (separate task), reached via PII_URL;
|
||||
# 5001 avoids colliding with the app's 3000 in local/compose runs on one host.
|
||||
EXPOSE 5001
|
||||
|
||||
# start-period covers the model cold start. With PII_WORKERS>1 each worker loads
|
||||
# the five spaCy models independently and in parallel, so allow generous headroom
|
||||
# (memory-bandwidth contention stretches the wall-time beyond the single-worker case).
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=300s --retries=3 \
|
||||
CMD curl -fsS http://localhost:5001/health || exit 1
|
||||
|
||||
# Worker count is env-driven so ONE image scales per task size: set PII_WORKERS to
|
||||
# the task's vCPU count (each worker loads the models independently, ~3 GB each, so
|
||||
# size task memory ≈ PII_WORKERS × 3 GB + overhead). Defaults to 1 for local/small.
|
||||
# `sh -c exec` expands the env var while keeping uvicorn as PID 1 for clean SIGTERM.
|
||||
# Quote the expansion so a malformed PII_WORKERS fails uvicorn arg-parsing rather
|
||||
# than being interpreted by the shell.
|
||||
# NB for the gliner engine: EACH worker loads its own GLiNER model copy (into GPU
|
||||
# memory when on cuda), so GPU deployments generally want PII_WORKERS=1 per GPU.
|
||||
CMD ["sh", "-c", "exec uvicorn server:app --host 0.0.0.0 --port 5001 --workers \"${PII_WORKERS:-1}\""]
|
||||
@@ -0,0 +1,52 @@
|
||||
# ========================================
|
||||
# Base Stage: Alpine Linux with Bun
|
||||
# ========================================
|
||||
FROM oven/bun:1.3.13-alpine AS base
|
||||
|
||||
RUN apk add --no-cache libc6-compat curl
|
||||
|
||||
# ========================================
|
||||
# Pruner Stage: Emit a minimal monorepo subset that @sim/realtime depends on
|
||||
# ========================================
|
||||
FROM base AS pruner
|
||||
WORKDIR /app
|
||||
|
||||
RUN bun add -g turbo
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN turbo prune @sim/realtime --docker
|
||||
|
||||
# ========================================
|
||||
# Dependencies Stage: Install Dependencies
|
||||
# ========================================
|
||||
FROM base AS deps
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=pruner /app/out/json/ ./
|
||||
COPY --from=pruner /app/out/bun.lock ./bun.lock
|
||||
|
||||
RUN --mount=type=cache,id=bun-cache,target=/root/.bun/install/cache \
|
||||
bun install --linker=hoisted --omit=dev --ignore-scripts
|
||||
|
||||
# ========================================
|
||||
# Runner Stage: Run the Socket Server
|
||||
# ========================================
|
||||
FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV=production \
|
||||
PORT=3002 \
|
||||
HOSTNAME="0.0.0.0"
|
||||
|
||||
RUN addgroup -g 1001 -S nodejs && \
|
||||
adduser -S nextjs -u 1001
|
||||
|
||||
COPY --from=deps --chown=nextjs:nodejs /app ./
|
||||
COPY --from=pruner --chown=nextjs:nodejs /app/out/full/ ./
|
||||
|
||||
USER nextjs
|
||||
|
||||
EXPOSE 3002
|
||||
|
||||
CMD ["bun", "apps/realtime/src/bootstrap.ts"]
|
||||
Reference in New Issue
Block a user