Images define the container environment for your Modal Functions and Sandboxes.
Creating images
FromRegistry
Creates an Image from a public or private container registry.
// Public image
image := mc.Images.FromRegistry("python:3.11-slim", nil)
// Private image with authentication
secret, _ := mc.Secrets.FromName(ctx, "docker-hub-secret", nil)
image := mc.Images.FromRegistry("myorg/private-image:latest", &modal.ImageFromRegistryParams{
Secret: secret,
})
The image tag (e.g., “python:3.11-slim”, “ubuntu:22.04”)
Optional parametersSecret for private registry authentication
Returns:
*Image - The Image instance
FromAwsEcr
Creates an Image from AWS ECR.
secret, _ := mc.Secrets.FromName(ctx, "aws-secret", nil)
image := mc.Images.FromAwsEcr("123456789.dkr.ecr.us-east-1.amazonaws.com/my-image:latest", secret)
Returns:
*Image - The Image instance
FromGcpArtifactRegistry
Creates an Image from GCP Artifact Registry.
secret, _ := mc.Secrets.FromName(ctx, "gcp-secret", nil)
image := mc.Images.FromGcpArtifactRegistry("us-docker.pkg.dev/project/repo/image:tag", secret)
The Artifact Registry image tag
Returns:
*Image - The Image instance
FromID
Looks up an existing Image by its ID.
image, err := mc.Images.FromID(ctx, "im-123abc")
if err != nil {
// Handle error
}
Context for the operation
Returns:
*Image - The Image instance
error - NotFoundError if the Image doesn’t exist
Image methods
DockerfileCommands
Extends an Image with Dockerfile-like commands. Returns a new Image.
image := mc.Images.FromRegistry("python:3.11-slim", nil)
image = image.DockerfileCommands([]string{
"RUN apt-get update && apt-get install -y git",
"RUN pip install numpy pandas",
}, nil)
// With build options
image = image.DockerfileCommands([]string{
"RUN pip install torch",
}, &modal.ImageDockerfileCommandsParams{
GPU: "T4",
ForceBuild: true,
})
List of Dockerfile commands (without the base FROM instruction)
params
*ImageDockerfileCommandsParams
Build options for this layerEnvironment variables for the build
Secrets to make available during build
GPU to use for build (e.g., “T4”, “A100:2”)
Force rebuild, ignoring cache
Returns:
*Image - A new Image with the commands added as a layer
COPY commands that copy from local context are not yet supported. Use COPY --from= to copy from other images.
Build
Eagerly builds the Image on Modal. This is called automatically when creating Sandboxes.
app, _ := mc.Apps.FromName(ctx, "my-app", &modal.AppFromNameParams{
CreateIfMissing: true,
})
image, err := image.Build(ctx, app)
if err != nil {
// Handle error
}
fmt.Printf("Built image: %s\n", image.ImageID)
Context for the operation
The App to associate the build with
Returns:
*Image - The built Image (same instance with ImageID set)
error - Error if the build fails
Managing images
Delete
Deletes an Image by ID.
err := mc.Images.Delete(ctx, "im-123abc", nil)
if err != nil {
// Handle error
}
Context for the operation
The ID of the Image to delete
Optional parameters (currently none defined)
Returns:
error - NotFoundError if the Image doesn’t exist
Deletion is irreversible and will prevent Functions/Sandboxes from using the Image. Deleting an Image does not delete its intermediate layers.
Image type
The unique identifier for the Image (set after building)
Example usage
package main
import (
"context"
"fmt"
"github.com/modal-labs/modal-client/go"
)
func main() {
ctx := context.Background()
mc, _ := modal.NewClient()
defer mc.Close()
// Create a custom image
image := mc.Images.FromRegistry("python:3.11-slim", nil)
// Add dependencies
image = image.DockerfileCommands([]string{
"RUN apt-get update && apt-get install -y curl git",
"RUN pip install requests numpy",
}, nil)
// Build the image
app, _ := mc.Apps.FromName(ctx, "my-app", &modal.AppFromNameParams{
CreateIfMissing: true,
})
builtImage, err := image.Build(ctx, app)
if err != nil {
panic(err)
}
fmt.Printf("Image built successfully: %s\n", builtImage.ImageID)
// Use the image with a Sandbox
sb, _ := mc.Sandboxes.Create(ctx, app, builtImage, nil)
defer sb.Terminate(ctx, nil)
// The image is now ready to use
}