# Docker Embedded Mode — Minimal FROM scratch Containers > Deploy a frontend app in a minimal FROM scratch Docker container. The REP gateway serves static files directly — no nginx, no Node.js, no shell. Under 10MB total. Source: https://rep-protocol.dev/deployment/docker-embedded/ In embedded mode, the gateway serves static files directly — no nginx, no Caddy, no Node.js. This produces the smallest possible production image. ## Dockerfile ```dockerfile # Stage 1: Build the frontend FROM node:22-alpine AS build WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Stage 2: FROM scratch — nothing but the binary and static files FROM scratch COPY --from=build /app/dist /static COPY --from=ghcr.io/ruachtech/rep/gateway:latest \ /usr/local/bin/rep-gateway /rep-gateway EXPOSE 8080 USER 65534:65534 ENTRYPOINT ["/rep-gateway"] CMD ["--mode", "embedded", "--static-dir", "/static", "--port", "8080", "--strict"] ``` ## What's in the image Exactly two things: - Your built static files (`dist/`) - The REP gateway binary (~7MB) No OS, no shell, no utilities, no package manager. Attack surface: near zero. ## Running ```bash docker build -t myapp . docker run -p 8080:8080 \ -e REP_PUBLIC_API_URL=https://api.example.com \ -e REP_SENSITIVE_ANALYTICS_KEY=UA-XXXXX \ -e REP_GATEWAY_STRICT=true \ -e REP_GATEWAY_ALLOWED_ORIGINS=https://app.example.com \ myapp ``` ## Multi-architecture builds ```dockerfile # In the gateway download stage ARG TARGETARCH # The gateway image is multi-arch — Docker selects the correct binary COPY --from=ghcr.io/ruachtech/rep/gateway:latest \ /usr/local/bin/rep-gateway /rep-gateway ``` ## Security hardening The `FROM scratch` + non-root pattern provides: - **No shell** — `docker exec` attacks are impossible - **No package manager** — no malware installation vector - **Read-only filesystem** — compatible with `readOnlyRootFilesystem: true` - **Non-root user** — UID 65534 (`nobody`) - **Static binary** — no shared libraries, no dynamic linker > **Tip** > > Embedded mode is recommended for production deployments where you don't need nginx-specific features. The gateway handles HTTP/2, compression, and caching headers natively. ## When to use embedded mode - You want the smallest possible container image - You're deploying a pure SPA with no server-side rendering - Security is a priority (minimal attack surface) - You don't need nginx-specific features (URL rewriting, basic auth, etc.)