- AWS container options for ML deployment
- Trade-offs between control and maintenance
- Production patterns (NGINX, sidecars, co-located containers)
- Key decision factors: GPU, runtime, security, and cost

- Pre-built images (e.g., SageMaker pre-built containers)
- Bring-Your-Own-Container (BYOC) — fully custom images
- Run containers on managed platforms — serverless, ECS, or EKS

When to choose managed services (Serverless / ECS / EKS)
- Choose them when you need automatic scaling, integration with other AWS services, or orchestration features (rolling updates, service discovery).
- Trade-off: more control = more maintenance (image security, OS patches, startup tuning).
- Mitigation: use small base images, multi-stage builds, and design for fast cold-starts.
- Images are stored in Amazon ECR.
- SageMaker pulls the image and prepares the runtime.
- Model artifacts are fetched from Amazon S3.
- SageMaker launches an endpoint on managed hosts (EC2 or EKS) to serve predictions.
- Expose an HTTP inference interface (commonly
/pingfor health,/invocationsfor inference). - Respond correctly to health checks so SageMaker knows when the container is ready.
- Use an IAM role (SageMaker execution role) so the container process can access AWS resources like S3 and ECR.

- Simplify deployment: supply model artifact(s) plus a small inference script or handler.
- AWS pre-built images already implement the SageMaker inference contract — minimal glue code needed.
- For specialized logic, provide a custom inference handler or a thin wrapper around the model.

- Pros: minimal maintenance and full compatibility with SageMaker features.
- Cons: limited flexibility for non-standard libraries, custom native binaries, or specific GPU drivers — in these cases, BYOC is required.

- Use BYOC when you need full control over OS, runtime, server setup, or custom binaries (e.g., specific CUDA drivers).
- Common production pattern: custom container with a reverse proxy (NGINX) in front of an application server (Uvicorn/Gunicorn) that hosts the model API.
- BYOC enables precise dependency pinning and the ability to include native libraries.

- Implement health endpoints (
/ping) to let the platform verify readiness and liveness. - Ensure correct port bindings so the container listens on the expected port.
- Minimize startup tasks to reduce launch time and avoid platform timeouts.
- Test locally with Docker before pushing to the registry.
Always test your container locally with Docker and mimic the production environment (same base image, same environment variables, same hardware when possible).

- Start with a minimal base image (distroless or Alpine) with only runtime essentials.
- Use multi-stage builds to separate build-time tooling from runtime artifacts.
- Clean package caches and remove build artifacts to reduce image layers and size.

- Order Dockerfile instructions to maximize layer cache reuse.
- Remove package manager caches (e.g.,
apt-get cleanandrm -rf /var/lib/apt/lists/*). - Prefer slim or Alpine-based framework builds and compress large artifacts.

- Use CUDA-enabled base images from NVIDIA or AWS Deep Learning containers.
- Host NVIDIA driver and kernel must be compatible with CUDA libraries inside the container.
- Pin CUDA and driver versions to avoid compatibility issues.
Driver mismatch warning: If the host GPU driver and the container CUDA libraries are incompatible, the container can fail to access GPUs. Validate on identical instance types before production.
- Start from official NVIDIA or AWS-provided base images.
- Pin CUDA/cuDNN versions explicitly.
- Validate the container on the same instance type and AMI as production to ensure compatibility.
- Pin exact framework versions (e.g., TensorFlow wheel and its compatible CUDA version; PyTorch wheel and CUDA compatibility).
- Avoid loose dependency ranges that allow unexpected upgrades.
- Test images locally and in CI to catch compatibility issues early.

- Deploy multiple containers to one endpoint for patterns such as: primary model container, pre- or post-processing containers, and logging/metrics sidecars.
- Co-located containers share the same host resources.
- Startup order matters — ensure preprocessors are ready before routing requests to the model.
- Each container must expose its own health endpoint.
- Allocate CPU, memory, and GPU carefully so containers do not compete and degrade performance.

- Apply least-privilege IAM policies for SageMaker, ECR, and other AWS services.
- Restrict S3 access strictly to the model artifacts and logs required.
- Use AWS KMS to encrypt model artifacts and sensitive data at rest.

- Scan images for known vulnerabilities and publish an SBOM (software bill of materials).
- Enforce image signing and registry policies (e.g., require ECR image scanning and signed images).
- Rotate credentials and avoid baking secrets into images — prefer IAM roles and secret managers.

- Place endpoints inside a VPC for network isolation.
- Limit access with security groups, NACLs, and private subnets.
- Use VPC endpoints to access S3/ECR without internet egress.
- Build the image:
docker build -t myapp:latest .
- Run the container locally, mapping volumes and ports:
docker run -v "$(pwd)/app:/app" -p 8080:8080 myapp:latest
- Health check:
curl http://localhost:8080/ping
- Test inference:
curl -X POST http://localhost:8080/invocations -H "Content-Type: application/json" -d '{"input": [...] }'
- CI builds the image, runs unit tests, integration tests, and security scans.
- Successful builds are tagged (semantic version, git SHA).
- Push tags to a registry (Amazon ECR).
- Promote tested images from registry to staging/production.
- Gate deployments on passing tests and security scans — only validated images should be deployed.
- Low, consistent latency → single-model dedicated endpoint.
- Many infrequently used models → multi-model endpoints to share instances.
- Unpredictable or spiky traffic → serverless or autoscaling endpoints.
- Large or long-running workloads → asynchronous/batch processing.

- Choose based on latency, traffic patterns, and usage:
- Single-model for low and consistent latency.
- Multi-model for many rarely used models.
- Serverless for spiky or unpredictable traffic.
- Async/batch for long-running or throughput-intensive offline jobs.
- Optimize cost: pick appropriate instance families, use reserved instances where applicable, and consider serverless to reduce idle costs.
- Balance operational overhead against the need for control: BYOC gives full control (and responsibility); pre-built images reduce maintenance and speed time-to-production.
- Always factor in compatibility, security, and reproducibility when selecting base images and framework versions.
- Amazon SageMaker container and inference toolkit documentation
- Amazon ECR image scanning and best practices
- NVIDIA CUDA Docker images
- AWS Deep Learning Containers