Image

class Image(modal.object.Object)

Base class for container images to run functions in.

Do not construct this class directly; instead use one of its static factory methods, such as modal.Image.debian_slim, modal.Image.from_registry, or modal.Image.micromamba.

add_local_file

add_local_file(self, local_path, remote_path, *, copy=False)

Adds a local file to the image at remote_path within the container.

By default (copy=False), the files are added to containers on startup and are not built into the actual Image, which speeds up deployment.

Set copy=True to copy the files into an Image layer at build time instead, similar to how COPY works in a Dockerfile.

copy=True can slow down iteration since it requires a rebuild of the Image and any subsequent build steps whenever the included files change, but it is required if you want to run additional build steps after this one.

Added in v0.66.40: This method replaces the deprecated modal.Image.copy_local_file method.

Parameters

local_pathstr | Path
Path to the file on the local machine.
remote_pathstr
Absolute path inside the container where the file should appear.
copybool
If True, bake the file into an image layer at build time; if False, mount at container startup. (Default is False)

Returns

A new Image with the file layer or mount applied.

add_local_dir

add_local_dir(self, local_path, remote_path, *, copy=False, ignore=[])

Adds a local directory's content to the image at remote_path within the container.

By default (copy=False), the files are added to containers on startup and are not built into the actual Image, which speeds up deployment.

Set copy=True to copy the files into an Image layer at build time instead, similar to how COPY works in a Dockerfile.

copy=True can slow down iteration since it requires a rebuild of the Image and any subsequent build steps whenever the included files change, but it is required if you want to run additional build steps after this one.

Added in v0.66.40: This method replaces the deprecated modal.Image.copy_local_dir method.

Parameters

local_pathstr | Path
Path to the directory on the local machine.
remote_pathstr
Absolute path inside the container where the directory contents should appear.
copybool
If True, bake the tree into an image layer at build time; if False, mount at container startup. (Default is False)
ignoreSequence[str] | Callable[[Path], bool]
Predicate or pattern list for file exclusion (True means exclude). A sequence is converted to a dockerignore-style matcher. (Default is [])

Returns

A new Image with the directory layer or mount applied.

Usage

from modal import FilePatternMatcher

image = modal.Image.debian_slim().add_local_dir(
    "~/assets",
    remote_path="/assets",
    ignore=["*.venv"],
)

image = modal.Image.debian_slim().add_local_dir(
    "~/assets",
    remote_path="/assets",
    ignore=lambda p: p.is_relative_to(".venv"),
)

image = modal.Image.debian_slim().add_local_dir(
    "~/assets",
    remote_path="/assets",
    ignore=FilePatternMatcher("**/*.txt"),
)

# When including files is simpler than excluding them, you can use the `~` operator to invert the matcher.
image = modal.Image.debian_slim().add_local_dir(
    "~/assets",
    remote_path="/assets",
    ignore=~FilePatternMatcher("**/*.py"),
)

# You can also read ignore patterns from a file.
image = modal.Image.debian_slim().add_local_dir(
    "~/assets",
    remote_path="/assets",
    ignore=FilePatternMatcher.from_file("/path/to/ignorefile"),
)

add_local_python_source

add_local_python_source(self, *modules, copy=False, ignore=NON_PYTHON_FILES)

Adds locally available Python packages/modules to containers.

Adds all files from the specified Python package or module to containers running the Image.

Packages are added to the /root directory of containers, which is on the PYTHONPATH of any executed Modal Functions, enabling import of the module by that name.

By default (copy=False), the files are added to containers on startup and are not built into the actual Image, which speeds up deployment.

Set copy=True to copy the files into an Image layer at build time instead. This can slow down iteration since it requires a rebuild of the Image and any subsequent build steps whenever the included files change, but it is required if you want to run additional build steps after this one.

Note: This excludes all dot-prefixed subdirectories or files and all .pyc/__pycache__ files. To add full directories with finer control, use .add_local_dir() instead and specify /root as the destination directory.

By default only includes .py-files in the source modules. Set the ignore argument to a list of patterns or a callable to override this behavior.

Added in v0.67.28: This method replaces the deprecated modal.Mount.from_local_python_packages pattern.

Parameters

*modulesstr
Python package or module names to include from the local project.
copybool
If True, bake sources into an image layer; if False, mount at container startup. (Default is False)
ignoreSequence[str] | Callable[[Path], bool]
Patterns or callable controlling which files to exclude. (Default is NON_PYTHON_FILES)

Returns

A new Image with the Python source mount or layer applied.

Usage

# includes everything except data.json
modal.Image.debian_slim().add_local_python_source("mymodule", ignore=["data.json"])

# exclude large files
modal.Image.debian_slim().add_local_python_source(
    "mymodule",
    ignore=lambda p: p.stat().st_size > 1e9
)

from_id

from_id(cls, image_id, client=None)

Construct an Image from an id and look up the Image result.

The ID of an Image object can be accessed using .object_id.

Parameters

image_idstr
Image object ID to load.
client"modal.client.Client | None"
Optional Modal client; uses the default synchronizer client when omitted.

Returns

A hydrated Image handle for the given ID.

build

build(self, app)

Eagerly build an image.

If your image was previously built, then this method will not rebuild your image and your cached image is returned.

For defining Modal functions, images are built automatically when deploying or running an App. You do not need to build the image explicitly in that case.

Parameters

appmodal.app._App
Initialized app used as the load context for the image build.

Returns

This image after the build (and resolver load) completes.

Usage

image = modal.Image.debian_slim().uv_pip_install("scipy", "numpy")

app = modal.App.lookup("build-image", create_if_missing=True)
with modal.enable_output():  # To see logs in your local terminal
    image.build(app)

# Save the image id
my_image_id = image.object_id

# Reference the image with the id or uses it another context.
built_image = modal.Image.from_id(my_image_id)

Alternatively, you can pre-build an image and use it in a sandbox:

app = modal.App.lookup("sandbox-example", create_if_missing=True)

with modal.enable_output():
    image = modal.Image.debian_slim().uv_pip_install("scipy")
    image.build(app)

sb = modal.Sandbox.create("python", "-c", "import scipy; print(scipy)", app=app, image=image)
print(sb.stdout.read())
sb.terminate()
app = modal.App()
image = modal.Image.debian_slim()

# No need to explicitly build the image for defining a function.
@app.function(image=image)
def f():
    ...

pip_install

pip_install(self, *packages, find_links=None, index_url=None,
    extra_index_url=None, pre=False, extra_options="", force_build=False,
    env=None, secrets=None, gpu=None)

Install a list of Python packages using pip.

Parameters

*packagesstr | list[str]
Python packages to install, e.g. numpy or matplotlib>=3.5.0.
find_linksstr | None
Passed as --find-links to pip.
index_urlstr | None
Passed as --index-url to pip.
extra_index_urlstr | None
Passed as --extra-index-url to pip.
prebool
If True, allow pre-release versions (--pre). (Default is False)
extra_optionsstr
Additional raw options for pip, e.g. --no-build-isolation. (Default is "")
force_buildbool
If True, skip cached image builds (similar to docker build --no-cache). (Default is False)
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
gpustr | None
GPU type to attach to the builder container.

Returns

A new Image with the pip install layer applied.

Usage

Simple installation:

image = modal.Image.debian_slim().pip_install("click", "httpx~=0.23.3")

More complex installation:

image = (
    modal.Image.from_registry(
        "nvidia/cuda:12.2.0-devel-ubuntu22.04", add_python="3.11"
    )
    .pip_install(
        "ninja",
        "packaging",
        "wheel",
        "transformers==4.40.2",
    )
    .pip_install(
        "flash-attn==2.5.8", extra_options="--no-build-isolation"
    )
)

pip_install_private_repos

pip_install_private_repos(self, *repositories, git_user, find_links=None,
    index_url=None, extra_index_url=None, pre=False, extra_options="", gpu=None,
    env=None, secrets=None, force_build=False)

Install a list of Python packages from private git repositories using pip.

This method currently supports Github and Gitlab only.

  • Github: Provide a modal.Secret that contains a GITHUB_TOKEN key-value pair
  • Gitlab: Provide a modal.Secret that contains a GITLAB_TOKEN key-value pair

These API tokens should have permissions to read the list of private repositories provided as arguments.

We recommend using Github's 'fine-grained' access tokens. These tokens are repo-scoped, and avoid granting read permission across all of a user's private repos.

Parameters

*repositoriesstr
Git URLs without scheme, e.g. github.com/org/repo@ref or with #subdirectory=.
git_userstr
Username embedded in HTTPS git URLs for authentication.
find_linksstr | None
Passed as --find-links to pip.
index_urlstr | None
Passed as --index-url to pip.
extra_index_urlstr | None
Passed as --extra-index-url to pip.
prebool
If True, allow pre-release versions. (Default is False)
extra_optionsstr
Additional raw options for pip. (Default is "")
gpustr | None
GPU type to attach to the builder container.
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets that supply GITHUB_TOKEN / GITLAB_TOKEN as required.
force_buildbool
If True, skip cached image builds. (Default is False)

Returns

A new Image with private repositories installed.

Usage

image = (
    modal.Image
    .debian_slim()
    .pip_install_private_repos(
        "github.com/ecorp/private-one@1.0.0",
        "github.com/ecorp/private-two@main"
        "github.com/ecorp/private-three@d4776502"
        # install from 'inner' directory on default branch.
        "github.com/ecorp/private-four#subdirectory=inner",
        git_user="erikbern",
        secrets=[modal.Secret.from_name("github-read-private")],
    )
)

pip_install_from_requirements

pip_install_from_requirements(self, requirements_txt, find_links=None, *,
    index_url=None, extra_index_url=None, pre=False, extra_options="",
    force_build=False, env=None, secrets=None, gpu=None)

Install a list of Python packages from a local requirements.txt file.

Parameters

requirements_txtstr
Path to a requirements.txt file on the local machine.
find_linksstr | None
Passed as --find-links to pip.
index_urlstr | None
Passed as --index-url to pip.
extra_index_urlstr | None
Passed as --extra-index-url to pip.
prebool
If True, allow pre-release versions. (Default is False)
extra_optionsstr
Additional raw options for pip. (Default is "")
force_buildbool
If True, skip cached image builds. (Default is False)
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
gpustr | None
GPU type to attach to the builder container.

Returns

A new Image with requirements installed.

pip_install_from_pyproject

pip_install_from_pyproject(self, pyproject_toml, optional_dependencies=[], *,
    find_links=None, index_url=None, extra_index_url=None, pre=False,
    extra_options="", force_build=False, env=None, secrets=None, gpu=None)

Install dependencies specified by a local pyproject.toml file.

optional_dependencies is a list of the keys of the optional-dependencies section(s) of the pyproject.toml file (e.g. test, doc, experiment, etc). When provided, all of the packages in each listed section are installed as well.

Parameters

pyproject_tomlstr
Path to a pyproject.toml using PEP 621 [project.dependencies].
optional_dependencieslist[str]
Keys under [project.optional-dependencies] to install additionally. (Default is [])
find_linksstr | None
Passed as --find-links to pip.
index_urlstr | None
Passed as --index-url to pip.
extra_index_urlstr | None
Passed as --extra-index-url to pip.
prebool
If True, allow pre-release versions. (Default is False)
extra_optionsstr
Additional raw options for pip. (Default is "")
force_buildbool
If True, skip cached image builds. (Default is False)
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
gpustr | None
GPU type to attach to the builder container.

Returns

A new Image with project dependencies installed.

uv_pip_install

uv_pip_install(self, *packages, requirements=None, find_links=None,
    index_url=None, extra_index_url=None, pre=False, extra_options="",
    force_build=False, uv_version=None, env=None, secrets=None, gpu=None)

Install a list of Python packages using uv pip install.

This method assumes that:

  • Python is on the $PATH and dependencies are installed with the first Python on the $PATH.
  • The shell supports $()-style substitution as used in the generated Dockerfile.
  • The command builtin is available on the $PATH.

Added in v1.1.0.

Parameters

*packagesstr | list[str]
Python packages to pass to uv pip install.
requirementslist[str] | None
Optional list of requirement file paths (passed as --requirements).
find_linksstr | None
Passed as --find-links to uv pip.
index_urlstr | None
Passed as --index-url to uv pip.
extra_index_urlstr | None
Passed as --extra-index-url to uv pip.
prebool
If True, allow pre-releases (--prerelease allow). (Default is False)
extra_optionsstr
Additional raw options appended to the uv pip install invocation. (Default is "")
force_buildbool
If True, skip cached image builds. (Default is False)
uv_versionstr | None
Pin the uv binary version copied from ghcr.io/astral-sh/uv.
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
gpustr | None
GPU type to attach to the builder container.

Returns

A new Image with packages installed via uv.

Usage

image = modal.Image.debian_slim().uv_pip_install("torch==2.7.1", "numpy")

poetry_install_from_file

poetry_install_from_file(self, poetry_pyproject_toml, poetry_lockfile=None, *,
    ignore_lockfile=False, force_build=False, with_=[], without=[], only=[],
    poetry_version="latest", old_installer=False, env=None, secrets=None,
    gpu=None)

Install poetry dependencies specified by a local pyproject.toml file.

If not provided as argument the path to the lockfile is inferred. However, the file has to exist, unless ignore_lockfile is set to True.

Note that the root project of the poetry project is not installed, only the dependencies. For including local python source files see add_local_python_source

Poetry will be installed to the Image (using pip) unless poetry_version is set to None. Note that the interpretation of poetry_version="latest" depends on the Modal Image Builder version, with versions 2024.10 and earlier limiting poetry to 1.x.

Parameters

poetry_pyproject_tomlstr
Path to a Poetry pyproject.toml file.
poetry_lockfilestr | None
Path to poetry.lock; if omitted, inferred next to the pyproject.
ignore_lockfilebool
If True, do not copy or use a lockfile even when present. (Default is False)
force_buildbool
If True, skip cached image builds. (Default is False)
with_list[str]
Optional dependency groups to include (poetry install --with). (Default is [])
withoutlist[str]
Optional dependency groups to exclude (poetry install --without). (Default is [])
onlylist[str]
Only install dependency groups in this list (poetry install --only). (Default is [])
poetry_versionstr | None
Poetry version specifier to pip install, or None to skip installing Poetry. (Default is "latest")
old_installerbool
If True, use Poetry's legacy installer. (Default is False)
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
gpustr | None
GPU type to attach to the builder container.

Returns

A new Image with Poetry dependencies installed.

uv_sync

uv_sync(self, uv_project_dir="./", *, force_build=False, groups=None,
    extras=None, frozen=True, extra_options="", uv_version=None, env=None,
    secrets=None, gpu=None)

Creates a virtual environment with the dependencies in a uv managed project with uv sync.

The pyproject.toml and uv.lock in uv_project_dir are automatically added to the build context. The uv_project_dir is relative to the current working directory of where modal is called.

NOTE: This does not install the project itself into the environment (this is equivalent to the --no-install-project flag in the uv sync command) and you would be expected to add any local python source files using Image.add_local_python_source or similar methods after this call.

This ensures that updates to your project code wouldn't require reinstalling third-party dependencies after every change.

uv workspaces are currently not supported.

Added in v1.1.0.

Parameters

uv_project_dirstr
Path to the local uv project directory (contains pyproject.toml). (Default is "./")
force_buildbool
If True, skip cached image builds. (Default is False)
groupslist[str] | None
Dependency groups passed as uv sync --group.
extraslist[str] | None
Optional extras passed as uv sync --extra.
frozenbool
If True and a uv.lock exists, run uv sync --frozen so the lock is not updated at build time. (Default is True)
extra_optionsstr
Additional raw options appended to uv sync. (Default is "")
uv_versionstr | None
Pin the uv binary version copied from ghcr.io/astral-sh/uv.
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
gpustr | None
GPU type to attach to the builder container.

Returns

A new Image with a uv-managed virtual environment.

Usage

image = modal.Image.debian_slim().uv_sync()

dockerfile_commands

dockerfile_commands(self, *dockerfile_commands, context_files={}, env=None,
    secrets=None, gpu=None, context_dir=None, force_build=False,
    ignore=AUTO_DOCKERIGNORE, build_args={})

Extend an image with arbitrary Dockerfile-like commands.

Parameters

*dockerfile_commandsstr | list[str]
Dockerfile lines to append after FROM base (strings or nested lists).
context_filesdict[str, str]
Map of container paths to local files to include in the build context. (Default is {})
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
gpustr | None
GPU type to attach to the builder container.
context_dirPath | str | None
Root directory for resolving relative COPY paths in implicit context mounts.
force_buildbool
If True, skip cached image builds. (Default is False)
ignoreSequence[str] | Callable[[Path], bool]
Ignore rules for the implicit context mount (defaults to auto .dockerignore behavior). (Default is AUTO_DOCKERIGNORE)
build_argsdict[str, str]
Dockerfile ARG values forwarded to the build. (Default is {})

Returns

A new Image with the Dockerfile fragment applied.

Usage

from modal import FilePatternMatcher

# By default a .dockerignore file is used if present in the current working directory
image = modal.Image.debian_slim().dockerfile_commands(
    ["COPY data /data"],
)

image = modal.Image.debian_slim().dockerfile_commands(
    ["COPY data /data"],
    ignore=["*.venv"],
)

image = modal.Image.debian_slim().dockerfile_commands(
    ["COPY data /data"],
    ignore=lambda p: p.is_relative_to(".venv"),
)

image = modal.Image.debian_slim().dockerfile_commands(
    ["COPY data /data"],
    ignore=FilePatternMatcher("**/*.txt"),
)

# When including files is simpler than excluding them, you can use the `~` operator to invert the matcher.
image = modal.Image.debian_slim().dockerfile_commands(
    ["COPY data /data"],
    ignore=~FilePatternMatcher("**/*.py"),
)

# You can also read ignore patterns from a file.
image = modal.Image.debian_slim().dockerfile_commands(
    ["COPY data /data"],
    ignore=FilePatternMatcher.from_file("/path/to/dockerignore"),
)

entrypoint

entrypoint(self, entrypoint_commands)

Set the ENTRYPOINT for the image.

Parameters

entrypoint_commandslist[str]
argv tokens for the ENTRYPOINT JSON array form.

Returns

A new Image with the entrypoint Dockerfile directive applied.

shell

shell(self, shell_commands)

Overwrite default shell for the image.

Parameters

shell_commandslist[str]
argv tokens for the SHELL JSON array form.

Returns

A new Image with the shell Dockerfile directive applied.

run_commands

run_commands(self, *commands, env=None, secrets=None, volumes=None, gpu=None,
    force_build=False)

Extend an image with a list of shell commands to run.

Parameters

*commandsstr | list[str]
Shell commands to run as separate RUN lines (strings or nested lists).
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
volumesdict[str | PurePosixPath, _Volume] | None
Modal volumes to attach during the build step.
gpustr | None
GPU type to attach to the builder container.
force_buildbool
If True, skip cached image builds. (Default is False)

Returns

A new Image with the commands executed as layers.

micromamba

micromamba(python_version=None, force_build=False)

A Micromamba base image. Micromamba allows for fast building of small Conda-based containers.

Parameters

python_versionstr | None
Python series or full version to install in the base conda environment.
force_buildbool
If True, skip cached image builds. (Default is False)

Returns

A Micromamba-based Image.

micromamba_install

micromamba_install(self, *packages, spec_file=None, channels=[],
    force_build=False, env=None, secrets=None, gpu=None)

Install a list of additional packages using micromamba.

Parameters

*packagesstr | list[str]
Conda packages to install, e.g. numpy or version constraints.
spec_filestr | None
Optional local path to a conda spec file to pass with -f.
channelslist[str]
Conda channels to pass with repeated -c flags. (Default is [])
force_buildbool
If True, skip cached image builds. (Default is False)
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
gpustr | None
GPU type to attach to the builder container.

Returns

A new Image with micromamba packages installed.

from_registry

from_registry(tag, secret=None, *, setup_dockerfile_commands=[],
    force_build=False, add_python=None, **kwargs)

Build a Modal Image from a public or private image registry, such as Docker Hub.

The image must be built for the linux/amd64 platform.

If your image does not come with Python installed, you can use the add_python parameter to specify a version of Python to add to the image. Otherwise, the image is expected to have Python on PATH as python, along with pip.

You may also use setup_dockerfile_commands to run Dockerfile commands before the remaining commands run. This might be useful if you want a custom Python installation or to set a SHELL. Prefer run_commands() when possible though.

To authenticate against a private registry with static credentials, you must set the secret parameter to a modal.Secret containing a username (REGISTRY_USERNAME) and an access token or password (REGISTRY_PASSWORD).

To authenticate against private registries with credentials from a cloud provider, use Image.from_gcp_artifact_registry() or Image.from_aws_ecr().

Parameters

tagstr
Registry image reference (e.g. python:3.11-slim).
secret_Secret | None
Optional secret for static registry credentials.
setup_dockerfile_commandslist[str]
Extra Dockerfile lines run after FROM during base setup. (Default is [])
force_buildbool
If True, skip cached image builds. (Default is False)
add_pythonstr | None
Optional standalone Python series to inject when the base image lacks Python.
**kwargs
Additional arguments forwarded to the internal image constructor (e.g. registry config).

Returns

An Image based on the registry tag.

Usage

modal.Image.from_registry("python:3.11-slim-bookworm")
modal.Image.from_registry("ubuntu:22.04", add_python="3.11")
modal.Image.from_registry("nvcr.io/nvidia/pytorch:22.12-py3")

from_gcp_artifact_registry

from_gcp_artifact_registry(tag, secret=None, *, setup_dockerfile_commands=[],
    force_build=False, add_python=None, **kwargs)

Build a Modal image from a private image in Google Cloud Platform (GCP) Artifact Registry.

You will need to pass a modal.Secret containing your GCP service account key data as SERVICE_ACCOUNT_JSON. This can be done from the Secrets page. Your service account should be granted a specific role depending on the GCP registry used:

Note: This method does not use GOOGLE_APPLICATION_CREDENTIALS as that variable accepts a path to a JSON file, not the actual JSON string.

See Image.from_registry() for information about the other parameters.

Parameters

tagstr
Full GCP Artifact Registry image reference.
secret_Secret | None
Secret containing SERVICE_ACCOUNT_JSON for registry authentication.
setup_dockerfile_commandslist[str]
Extra Dockerfile lines run after FROM during base setup. (Default is [])
force_buildbool
If True, skip cached image builds. (Default is False)
add_pythonstr | None
Optional standalone Python series to inject when the base image lacks Python.
**kwargs
Additional arguments forwarded to from_registry.

Returns

An Image based on the private GCP artifact.

Usage

modal.Image.from_gcp_artifact_registry(
    "us-east1-docker.pkg.dev/my-project-1234/my-repo/my-image:my-version",
    secret=modal.Secret.from_name(
        "my-gcp-secret",
        required_keys=["SERVICE_ACCOUNT_JSON"],
    ),
    add_python="3.11",
)

from_aws_ecr

from_aws_ecr(tag, secret=None, *, setup_dockerfile_commands=[],
    force_build=False, add_python=None, **kwargs)

Build a Modal image from a private image in AWS Elastic Container Registry (ECR).

You will need to pass a modal.Secret containing either IAM user credentials or OIDC configuration to access the target ECR registry.

For IAM user authentication, set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_REGION.

For OIDC authentication, set AWS_ROLE_ARN and AWS_REGION.

IAM configuration details can be found in the AWS documentation for "Private repository policies".

For more details on using an AWS role to access ECR, see the OIDC integration guide.

See Image.from_registry() for information about the other parameters.

Parameters

tagstr
Full ECR image URI.
secret_Secret | None
Secret with IAM or OIDC credentials for ECR.
setup_dockerfile_commandslist[str]
Extra Dockerfile lines run after FROM during base setup. (Default is [])
force_buildbool
If True, skip cached image builds. (Default is False)
add_pythonstr | None
Optional standalone Python series to inject when the base image lacks Python.
**kwargs
Additional arguments forwarded to from_registry.

Returns

An Image based on the private ECR image.

Usage

modal.Image.from_aws_ecr(
    "000000000000.dkr.ecr.us-east-1.amazonaws.com/my-private-registry:my-version",
    secret=modal.Secret.from_name(
        "aws",
        required_keys=["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_REGION"],
    ),
    add_python="3.11",
)

from_dockerfile

from_dockerfile(path, *, force_build=False, context_dir=None, env=None,
    secrets=None, gpu=None, add_python=None, build_args={},
    ignore=AUTO_DOCKERIGNORE)

Build a Modal image from a local Dockerfile.

If your Dockerfile does not have Python installed, you can use the add_python parameter to specify a version of Python to add to the image.

Parameters

pathstr | Path
Path to the Dockerfile on the local machine.
force_buildbool
If True, skip cached image builds. (Default is False)
context_dirPath | str | None
Build context directory for resolving relative COPY paths.
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
gpustr | None
GPU type to attach to the builder container.
add_pythonstr | None
Standalone Python version to add when the Dockerfile does not install Python.
build_argsdict[str, str]
Dockerfile ARG values forwarded to the build. (Default is {})
ignoreSequence[str] | Callable[[Path], bool]
Ignore rules for the implicit context mount (defaults to auto .dockerignore behavior). (Default is AUTO_DOCKERIGNORE)

Returns

An Image built from the Dockerfile plus Modal runtime dependencies.

Usage

from modal import FilePatternMatcher

# By default a .dockerignore file is used if present in the current working directory
image = modal.Image.from_dockerfile(
    "./Dockerfile",
    add_python="3.12",
)

image = modal.Image.from_dockerfile(
    "./Dockerfile",
    add_python="3.12",
    ignore=["*.venv"],
)

image = modal.Image.from_dockerfile(
    "./Dockerfile",
    add_python="3.12",
    ignore=lambda p: p.is_relative_to(".venv"),
)

image = modal.Image.from_dockerfile(
    "./Dockerfile",
    add_python="3.12",
    ignore=FilePatternMatcher("**/*.txt"),
)

# When including files is simpler than excluding them, you can use the `~` operator to invert the matcher.
image = modal.Image.from_dockerfile(
    "./Dockerfile",
    add_python="3.12",
    ignore=~FilePatternMatcher("**/*.py"),
)

# You can also read ignore patterns from a file.
image = modal.Image.from_dockerfile(
    "./Dockerfile",
    add_python="3.12",
    ignore=FilePatternMatcher.from_file("/path/to/dockerignore"),
)

from_scratch

from_scratch(force_build=False)

Create an empty Image, equivalent to FROM scratch in Docker.

The resulting Image has no operating system, shell, or package manager. It is primarily useful as a lightweight filesystem to mount into a Sandbox via Sandbox.mount_image.

Note that since this Image doesn't contain Python or other standard OS utilities, higher-level Image build steps like pip_install cannot be chained onto it. It also cannot be used for modal.Function execution, which requires a Python interpreter.

Parameters

force_buildbool
If True, skip cached image builds. (Default is False)

Returns

An empty Image suitable for minimal filesystem mounts.

Usage

image = modal.Image.from_scratch().add_local_file(local_path, "/bin/my_binary", copy=True)

debian_slim

debian_slim(python_version=None, force_build=False)

Default image, based on the official python Docker images.

Parameters

python_versionstr | None
Python series or full version to use from the Debian slim images.
force_buildbool
If True, skip cached image builds. (Default is False)

Returns

The standard Debian slim Python Image used as Modal's default base.

apt_install

apt_install(self, *packages, force_build=False, env=None, secrets=None,
    gpu=None)

Install a list of Debian packages using apt.

Parameters

*packagesstr | list[str]
Apt package names to install, e.g. git or libpq-dev.
force_buildbool
If True, skip cached image builds. (Default is False)
envdict[str, str | None] | None
Environment variables set in the build container.
secretsCollection[_Secret] | None
Secrets injected as environment variables during the build.
gpustr | None
GPU type to attach to the builder container.

Returns

A new Image with apt-get install layers applied.

Usage

image = modal.Image.debian_slim().apt_install("git")

run_function

run_function(self, raw_f, *, env=None, secrets=None, volumes={},
    network_file_systems={}, gpu=None, cpu=None, memory=None, timeout=60 * 60,
    cloud=None, region=None, force_build=False, args=(), kwargs={},
    include_source=True)

Run user-defined function raw_f as an image build step.

The function runs like an ordinary Modal Function, accepting a resource configuration and integrating with Modal features like Secrets and Volumes. Unlike ordinary Modal Functions, any changes to the filesystem state will be captured on container exit and saved as a new Image.

Only the source code of raw_f, the contents of **kwargs, and any referenced global variables are used to determine whether the image has changed and needs to be rebuilt. If this function references other functions or variables, the image will not be rebuilt if you make changes to them. You can force a rebuild by changing the function's source code itself.

Parameters

raw_fCallable[..., Any]
Callable executed remotely during the image build.
envdict[str, str | None] | None
Environment variables set in the builder container.
secretsCollection[_Secret] | None
Secrets available to the builder function.
volumesdict[str | PurePosixPath, _Volume | _CloudBucketMount]
Volume and bucket mounts attached for the build. (Default is {})
network_file_systemsdict[str | PurePosixPath, _NetworkFileSystem]
Network file systems attached for the build. (Default is {})
gpustr | list[str] | None
GPU type or list of types for the builder container.
cpufloat | None
CPU cores to request (soft limit).
memoryint | None
Memory to request in MiB (soft limit).
timeoutint
Maximum build-step runtime in seconds. (Default is 60 * 60)
cloudstr | None
Cloud provider for the builder function.
regionstr | Sequence[str] | None
Region or regions for the builder function.
force_buildbool
If True, skip cached image builds. (Default is False)
argsSequence[Any]
Positional arguments serialized to the builder function. (Default is ())
kwargsdict[str, Any]
Keyword arguments serialized to the builder function. (Default is {})
include_sourcebool
Whether to include the function's source in the builder image. (Default is True)

Returns

A new Image capturing the filesystem after raw_f completes.

Usage


def my_build_function():
    open("model.pt", "w").write("parameters!")

image = (
    modal.Image
        .debian_slim()
        .pip_install("torch")
        .run_function(my_build_function, secrets=[...], volumes={...})
)

env

env(self, vars)

Sets the environment variables in an Image.

Parameters

varsdict[str, str]
Map of environment variable names to string values.

Returns

A new Image with ENV directives applied.

Usage

image = (
    modal.Image.debian_slim()
    .env({"HF_HUB_ENABLE_HF_TRANSFER": "1"})
)

workdir

workdir(self, path)

Set the working directory for subsequent image build steps and function execution.

Parameters

pathstr | PurePosixPath
Working directory path inside the image.

Returns

A new Image with WORKDIR applied.

Usage

image = (
    modal.Image.debian_slim()
    .run_commands("git clone https://xyz app")
    .workdir("/app")
    .run_commands("yarn install")
)

cmd

cmd(self, cmd)

Set the default command (CMD) to run when a container is started.

Used with modal.Sandbox. Has no effect on modal.Function.

Parameters

cmdlist[str]
argv tokens for the default container command.

Returns

A new Image with CMD applied.

Usage

image = (
    modal.Image.debian_slim().cmd(["python", "app.py"])
)

pipe

pipe(self, func, *args, **kwargs)

Apply a local function to expand the Image recipe.

This method can be useful for defining reusable Image build recipes that compose well with the fluent Image builder interface.

Example

def workspace_setup(image: modal.Image, repo: str) -> modal.Image:
    return image.run_commands(f"git clone {repo}").uv_pip_install(".")

image = (
    modal.Image.debian_slim()
    .apt_install("git")
    .pipe(workspace_setup, "https://github.com/example/repo.git")
)

imports

imports(self)

Used to import packages in global scope that are only available when running remotely.

By using this context manager you can avoid an ImportError due to not having certain packages installed locally.

Returns

Context manager that records import failures until the image is hydrated in the remote environment.

Usage

with image.imports():
    import torch

from_name

from_name(name, *, environment_name=None, client=None)

Reference a named Image that was previously published with .publish().

Names can contain an optional :tag part. If no tag part is included, ":latest" is used, matching Docker conventions.

image = modal.Image.from_name("my-image")     # references my-image:latest
image_v1 = modal.Image.from_name("my-image:v1")

@app.function(image=image)
def run():
    ...

publish

publish(self, name, *, environment_name=None, experimental_options=None,
    client=None)

Publish this image under the given name

The Image must already be created (typically by calling image.build() or sandbox.snapshot_filesystem()).

Image names can contain an explicit tag designation using name:tag. If no tag is included in the name, ":latest" is used, matching Docker conventions. To publish multiple tags, call .publish() once per tag.

image = modal.Image.debian_slim().pip_install("numpy")
image.build(app)
image.publish("my-image-with-numpy")     # my-image-with-numpy:latest
image.publish("my-image-with-numpy:v1")

logs

logs: ImageLogsManager

Access logs for an Image.

Use fetch() to read logs for individual build layers and tail() to read the most recent logs.

See Also

logs.fetch

fetch(self, layers=1)

Fetch logs for the most recent Image build steps.

Parameters

layersint | None
The number of build layers to fetch, counting backward from the final Image. If None, logs are fetched for all build steps. (Default is 1)

logs.tail

tail(self, entries=100)

Fetch the most recent Image logs.

Parameters

entriesint
The number of log entries to return. (Default is 100)