Custom container images
Create custom container images for your sandboxes.
Background
Before creating your custom Docker image, ensure that the image you need is not already available on the Docker Hub. Read the Docker documentation to build your own Docker image.
Create images
You have two options for host container images:
Host publicly on Docker Hub
Host privately in a Google Cloud Artifact Registry (see steps below)
Docker Hub
Host publicly on Docker Hub. When using public Docker hub there is not any required integration or security changes required to run containers within your Instruqt sandbox.
Within your track sandbox configuration select add host

Provide your hostname and container name. For example public docker hub container "busybox" would just require "busybox" to be put in for the container image name. If you have your own namespace you would prefix the name of your repository with that namespace (ie. namespace/repository)

Click save to add the host to the sandbox
Google Cloud Artifact Registry
Host privately in a Google Cloud Artifact Registry (see steps below)
Instruqt only supports Linux x86/amd64 based images. If you are using an Apple Silicon Macbook, use the --platform=linux/amd64 flag for docker build command.
If you opt for private images, you need to authorize Instruqt's service accounts access to your repository. You can do so by granting the role roles/storage.objectViewer on the backing storage and roles/artifactregistry.reader role to the following Instruqt service accounts:
serviceAccount:instruqt-participants-nodepool@instruqt-prod.iam.gserviceaccount.comserviceAccount:instruqt-backend@instruqt-prod.iam.gserviceaccount.com
Image streaming (caching) compatibility
Instruqt pulls sandbox container images onto GKE nodes that have image streaming enabled. With streaming, a container starts before its image is fully downloaded, which is the difference between a host that is ready in seconds and one that stalls on a multi-gigabyte pull.
Streaming is best-effort. When an image is not eligible, GKE falls back to a full pull without reporting an error: the container still starts, only much slower. Empty layers and duplicate layers are the most common reasons an image becomes ineligible.
Requirements
Store the image in a standard or remote Artifact Registry repository, or in a public registry on Docker Hub. Images hosted anywhere else, such as Quay, GitHub Container Registry, or Amazon ECR, are not eligible.
Use an OCI or Docker V2 schema 2 manifest. Images built with the V2 manifest schema 1 format are not eligible; rebuilding with any current version of Docker or BuildKit produces a supported manifest.
Build for
linux/amd64.Keep the image free of empty and duplicate layers.
Size must be greater than 10 MB.
Avoid empty layers
An empty layer is a layer whose filesystem diff contains no changes. Empty layers always carry the same well-known digest, sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4, so two of them in one image are duplicates as well: a single stray RUN repeated twice creates both problems at once.
Common sources of empty layers:
RUNsteps that change nothing on disk, such asRUN true,RUN echo "building app", orRUN ls -la /opt.COPYorADDof a directory that contains no files.VOLUMEdeclarations, which create a mount point but no content.
Collapse related commands into a single layer instead:
Metadata instructions such as ENV, LABEL, WORKDIR, USER, EXPOSE, CMD, and ENTRYPOINT do not create filesystem layers when you build with BuildKit, so they are safe to use freely.
Avoid duplicate layers
A duplicate layer is the same layer digest appearing more than once in an image manifest. Common sources:
Copying identical content into the final image twice, for example two
COPY --from=buildersteps that resolve to the same files.Multi-stage builds where two stages run the same install commands and both are copied into the final image.
Rebasing or appending layers onto a base image that already contains those exact layers.
More than one empty layer.
Give each layer distinct content, and copy any given artifact into the final stage exactly once.
Verify an image before you use it
Inspect a local image with docker. Duplicate layers print a digest; a clean image prints nothing:
Empty layers show up as 0B steps in the build history:
For an image already pushed to a registry, inspect the manifest with crane:
Fix an existing image
If you cannot rebuild from the Dockerfile, flatten the image into a single layer. This removes every empty and duplicate layer:
Last updated
Was this helpful?