Docker Packaging Guide
This guide explains how to build, run, and optimize the GoServe Docker image.
Step-by-Step: From Zero to Running
If you have just cloned the repository, follow these steps to get a containerized GoServe instance running with a sample model.
1. Clone the Repository
2. Build the Docker Image
No local dependencies (like Go or ONNX) are needed on your host machine; the Dockerfile handles everything.
3. Run the Container
We will mount the examples folder so we can test with the image classification model.
# Using absolute path for volume mounting (recommended)
docker run -d \
--name goserve \
-p 8080:8080 \
-v "$(pwd)/examples:/app/examples" \
goserve:latest
4. Load the Model & Test
# Load model
curl -X POST http://localhost:8080/v1/models \
-H "Content-Type: application/json" \
-d '{"name": "mobilenet", "path": "/app/examples/image-classification/models/mobilenetv2.onnx"}'
# Check health
curl http://localhost:8080/health
How the Multi-Stage Build Works
GoServe uses a Multi-Stage Dockerfile. This is a professional pattern that separates the build environment from the runtime environment.
Why use Multi-Stage?
If we used a single stage, our final image would be >1GB because it would contain the Go compiler, C++ build tools (gcc), and source code. By using two stages, our final image is under 100MB and only contains the bare essentials needed to run.
Stage 1: The Builder (AS builder)
- Base:
golang:1.25-bookworm(A full Go development environment). - Setup: We install
build-essentialso we can use CGO (needed for ONNX). - Dependency: We download the ONNX Runtime Linux x64 shared library (
.so) version 1.23.2 from GitHub. - Compilation: We build the Go binary. We use
CGO_LDFLAGSandCGO_CFLAGSto tell the Go compiler exactly where we put the ONNX library files. - Result: We have a compiled binary named
goserveand the librarylibonnxruntime.so.
Stage 2: The Runtime (Final Image)
- Base:
gcr.io/distroless/cc-debian12(A tiny image with only C++ runtime libraries). - Cleanup: We throw away the Go compiler, the source code, and all the build tools.
- Copying: We only copy two things from the builder stage:
- The
goservebinary. - The
libonnxruntime.solibrary (placed into/usr/lib).
- The
- Execution: We set
LD_LIBRARY_PATHso the binary can find the ONNX library at startup.
Prerequisites
- Docker Desktop (Windows/macOS) or Docker Engine (Linux).
- At least 2GB of RAM available for the build process (ONNX library is large).
- An internet connection to download dependencies during the build.
Potential Problems & Must-Haves
1. Library Path (Must-Have)
The binary requires libonnxruntime.so to be in the system's library path. Our Dockerfile handles this by copying it to /usr/lib and setting ENV LD_LIBRARY_PATH=/usr/lib.
2. Architecture Mismatch
The current Dockerfile downloads the x64 (amd64) version of ONNX Runtime. If you are building on Apple Silicon (M1/M2) or ARM64 Linux, the binary will not run.
- Fix: Update the download URL in the Dockerfile to use the aarch64 package for ARM builds.
3. Permissions
On Linux, ensure the user running Docker has permissions to read the model files you are mounting. If you see "Permission Denied" in the container logs, check the UID/GID of your model folder.
Verifying the Build
We provide a cross-platform Python script to verify your Docker setup:
This script automates the build, starts a container, and runs a test inference using the MobileNet example.