No Rust in Production
The runner container does not need rustc, cargo, or .rs files. All native plugin code (flamer) is statically baked into the executable.
Flame’s application-specific native runtime architecture enables lean, secure, and fast production deployments. Flame uses standard multi-stage builds:
flamer) and runtime subsystems..flame/pkg/ (.fm source and .fmi interfaces) are included. The production runner container does not need Rust, Cargo, or any .rs source code.When you build a Flame application for production:
Build Stage (Development / CI / Docker Builder)├── flame.toml├── src/ (Flame source)└── fmp install ──► .flame/pkg/ (.fm source + .fmi interfaces) ↓fmp build --release ↓Produces specialized native binary in target/release/my_server
──────────────────────────────────────────────────────────────
Runner Stage (Production Container)├── my_server (Specialized Native Runtime Binary)├── flame.toml├── src/└── .flame/pkg/ (.fm + .fmi ONLY — zero .rs files required)At runtime in production:
my_server) provides the compiled execution engine and all linked native plugins.src/ and package interfaces from .flame/pkg/..rs files can be deleted or omitted because all native plugin code is already baked directly into the binary during compilation.Consider a production web service built with the flamer web framework plugin.
flame.toml)[package]name = "flame_server"version = "0.1.0"
[dependencies]flamer = "https://github.com/sohamglx/flamer"src/main.fm)import flamer
@Flamerfn main () { app.get("/", () -> String { return "Hello from Flame Production Server!" })
app.get("/health", () -> String { return "{\"status\": \"healthy\", \"runtime\": \"application-specific-native\"}" })
app.listen(8080)}Here is the canonical, production-ready Dockerfile for building and running a Flame application. It uses a multi-stage build:
builder): Installs the Flame toolchain, runs flame install to fetch packages and generate .fmi interface files, and builds the specialized native binary with flame build --release.runner): Uses a minimal runtime base image containing only the compiled binary, Flame source files, .flame/pkg/ (.fm and .fmi), and flame.toml. No Rust compiler or .rs files are present.# ==============================================================================# Stage 1: Build Environment# ==============================================================================FROM rust:1.82-bookworm AS builder
# Install Flame toolchainRUN cargo install --force flamelang
WORKDIR /app
# Copy project manifest and source filesCOPY flame.toml ./COPY src/ ./src/
# Step 1: Install dependencies and ensure .fmi interfaces are properly created# 'fmp install' resolves all packages (e.g., flamer) and creates/caches .fmi metadataRUN fmp install
# Step 2: Build the application-specific native runtime binary# This compiles a specialized native binary into target/release/flame_serverRUN fmp build --release
# Step 3: Optional hygiene - remove any leftover .rs files in .flame/pkg# (Demonstrates that the production runner only needs .fm and .fmi files)RUN find .flame/pkg -type f -name "*.rs" -delete || true
# ==============================================================================# Stage 2: Minimal Production Runner# ==============================================================================FROM debian:bookworm-slim AS runner
# Install essential runtime libraries (OpenSSL and certificates if using HTTPS)RUN apt-get update && apt-get install -y --no-install-recommends \ ca-certificates \ libssl3 \ && rm -rf /var/lib/apt/lists/*
WORKDIR /app
# 1. Copy the specialized native runtime binary from target/release/COPY --from=builder /app/target/release/flame_server /app/flame_server
# 2. Copy the Flame application source code and manifestCOPY --from=builder /app/flame.toml /app/flame.tomlCOPY --from=builder /app/src/ /app/src/
# 3. Copy the resolved package directory containing .fm and .fmi files ONLY# (No Rust source code is copied into production)COPY --from=builder /app/.flame/pkg/ /app/.flame/pkg/
# Set non-root security userRUN useradd -m -u 1000 flameuser && chown -R flameuser:flameuser /appUSER flameuser
# Expose server portEXPOSE 8080
# Configure environmentENV PORT=8080ENV FLAME_ENV=production
# Run the specialized application runtime binary directlyCMD ["/app/flame_server"]From the root of your Flame project containing flame.toml and src/:
docker build -t my-flame-server:latest .docker run -d --name flame-app -p 8080:8080 my-flame-server:latestTest the endpoint using curl:
curl http://localhost:8080/# Returns: Hello from Flame Production Server!
curl http://localhost:8080/health# Returns: {"status": "healthy", "runtime": "application-specific-native"}No Rust in Production
The runner container does not need rustc, cargo, or .rs files. All native plugin code (flamer) is statically baked into the executable.
Minimal Image Size
By excluding compilation tools and unused standard libraries. Docker image size stay minimal.
Instant Boot Time
Specialized native runtimes start immediately without JVM warmup, V8 cold starts, or universal interpreter startup lag.
Hardened Security
A smaller attack surface with no package managers or compilers running inside the production environment.
.fmi Generation During fmp installWhen using plugins and packages in Docker:
fmp install runs before fmp build --release.fmp install inspects native packages and generates the corresponding .fmi interface metadata files in .flame/pkg/<pkg_name>/<pkg_name>.fmi..fmi files provide the runtime with method signatures, parameter layouts, and type definitions without needing raw Rust files.Normal builds (fmp build --release) execute against the real container filesystem:
/app/src/main.fm and /app/.flame/pkg/... are accessed directly.fmp build --vfs --release)If you prefer a single standalone binary that requires no external folders at all, you can build with:
fmp build --vfs --releaseIn this mode, src/ and .flame/pkg/ are embedded directly into the binary via VFS, allowing you to copy only /app/flame_server into a scratch or distroless container.