Building your container

Integration Partners
Last Updated: August 11, 2026

Before you begin: Complete Build a gRPC RTD service. Also read the Publisher request payload reference, and the DSP bid response payload reference if you are implementing bid shading, to understand which signals are available to your decisioning logic.

This topic covers packaging your gRPC service as a Docker container that meets Index Cloud's requirements. Read the constraints below carefully before making language or architecture decisions, particularly the no-egress requirement and security constraints, which have significant implications for how you structure your service.

Networking and security constraints

The following constraints are enforced by Index Cloud and cannot be changed. They affect both how you write your GetMutations implementation and how you package your container, so read them before writing any code.

  • No egress. Your container cannot make outbound network calls at runtime. Ingress to your container is only available within Index Cloud. All data (model weights, lookup tables, configuration) must be embedded in the image or mounted via config file at startup. Any architecture that relies on external API calls or database lookups during request handling will not work.

  • Read-only filesystem. Your container runs with a read-only filesystem.

  • Non-root execution. Containers run as user 1000, group 1000. Ensure your base image and entrypoint are compatible.

  • Vulnerability scanning. All images are scanned on download and on an ongoing basis. A CVSS score of 9 or higher blocks deployment. Choose base images carefully.

  • Cryptographically signed code. Containers run in isolated environments per partner.

  • Config files. These are mountable in TOML format at your preferred path.

  • Model data. This is mounted at MODEL_PATH. See Environment variables.

Logging

Logs from your container should be written to STDOUT or STDERR, as appropriate. Index Exchange (Index) collects these logs and reserves the right to decide what log information to make available to you.

Note: Prefer metrics over verbose logging. Use metrics, not logs, to capture container performance.

Recommended base images

Choose a minimal base image to keep your image under 1 GiB and reduce vulnerability surface. Recommended options are gcr.io/distroless/base-nossl (Go, Rust) and alpine:latest. Avoid full OS images such as ubuntu or debian unless necessary, because these are more likely to contain packages with a CVSS score of 9 or higher that would block deployment. Ensure the base image is compatible with non-root execution (user 1000, group 1000) and x86 architecture.

Container resource profile

Your container must meet the following requirements:

RequirementSpecification

Architecture

x86

Max image size

1 GiB

Max model data size

5 GiB

Response SLA

5ms (95th percentile)

Max error rate

< 3%

Required endpoints

Containers must expose the endpoints described below. GRPC_PORT is used for the gRPC service and the required gRPC healthcheck protocol. SERVER_PORT is used for the required HTTP metrics endpointClosed A URL which is configured to interact with a server in a specific way..

Orchestration endpoints

Containers MUST implement the gRPC healthcheck protocol (grpc.health.v1.Health) on GRPC_PORT. Index and the testing tool probe this endpoint.

  • Liveness SHOULD report SERVING while the main thread is running, and NOT_SERVING otherwise.

  • Readiness SHOULD report SERVING only once the application, including model load, is ready to serve traffic, and NOT_SERVING otherwise.

Metrics endpoint

Containers MUST expose an HTTP metrics endpoint at /metrics, which provides runtime metrics in Prometheus format. See Validating and deploying your container for the required metric, permitted tags, and an example response.

Environment variables

Index sets the following environment variables in your container at runtime. Do not hardcode these values. Read them from the environment at startup.

VariableDescription

SERVER_PORT

Port for your container's HTTP metrics endpoint (/metrics). Set by Index at container start; always read it from the environment. There is no fixed default, unlike GRPC_PORT, which defaults to 50051.

GRPC_PORT

Port your gRPC service listens on. Set by Index at container start. Default: 50051.

MODEL_PATH

Directory where model data files are mounted. Your container reads model files from here at startup. Ensure this directory exists. Create it with mkdir -p $MODEL_PATH in your Dockerfile.

Usage examples

The following examples show how to read these variables at startup.

Go

grpcPort := os.Getenv("GRPC_PORT")
if grpcPort == "" { grpcPort = "50051" }
serverPort := os.Getenv("SERVER_PORT")
modelPath := os.Getenv("MODEL_PATH")

Rust

let grpc_port = std::env::var("GRPC_PORT").unwrap_or("50051".into());
let server_port = std::env::var("SERVER_PORT").expect("SERVER_PORT must be set");
let model_path = std::env::var("MODEL_PATH").unwrap_or("/models".into());

Recommended languages

The following table summarizes how each language performs against the latency profile this integration requires:

LanguageRecommendationNotes

Rust

Recommended

Best raw throughput. No GC pauses, predictable latency. Maximizes QPSClosed Queries Per Second (QPS). The number of bid requests a DSP processes per second. Also known as impressions per second. per core.

Go

Recommended

Strong concurrency model, excellent gRPC ecosystem. ARTF reference implementations are in Go and Rust.

C++, Java

Use with care

Require more care around latency consistency.

Python

Not recommended

Difficult to meet the 5ms latency requirement without offloading request processing to native code.

The ARTF reference implementations are available at github.com/IABTechLab/agentic-rtb-framework.

Architectural patterns

Apply the following patterns when structuring your service.

Do

  • Pre-load at startup. All data should be integrated into the image or loaded from mounted files at boot. Only signal readiness once everything is fully loaded.

  • Cache aggressively. Use memory for lookup tables, model weights, and pre-computed decisions.

  • Minimize per-request allocation. Object pooling, pre-allocated buffers, and arena patterns reduce GC pressure (Go) and allocation overhead (Rust).

  • Keep the gRPC handler minimal. Deserialize, run logic, build mutations, return. Log and aggregate telemetry asynchronously.

  • Design for graceful restarts. Signal readiness only once the model is fully loaded.

Don't

  • Make external network calls during request handling.

  • Use heavy per-request logging. Use metrics counters instead.

  • Load models dynamically after startup.

  • Ship large images built from unnecessary dependencies.

Next: Continue to Validating and deploying your container to begin the deployment process.