Skip to content

API

Pyrig plugin that integrates container support into a project.

rig

Mirrored namespace through which this plugin extends pyrig's scaffolding.

Mirrors the pyrig.rig package layout so pyrig's cross-package plugin discovery finds this plugin's configuration and tooling customizations automatically.

configs

Configuration files this plugin contributes to pyrig's discovery scope.

container_file

Containerfile configuration management.

ContainerfileConfigFile

Bases: StringConfigFile

The project's Containerfile, built from a Python slim base image.

Copies in the uv binary, installs runtime dependencies with uv, and runs the project as a non-root user (appuser, UID 1000).

content
content() -> str

Build the required Containerfile text.

Returns:

Type Description
str

Dockerfile instructions that copy in the uv binary, install

str

the project's runtime dependencies, and run the project as the

str

non-root appuser user.

Source code in src/pyrig_containers/rig/configs/container_file.py
    def content(self) -> str:
        """Build the required `Containerfile` text.

        Returns:
            Dockerfile instructions that copy in the `uv` binary, install
            the project's runtime dependencies, and run the project as the
            non-root `appuser` user.
        """
        latest_python_version = PyprojectConfigFile.I.latest_possible_python_version()
        package_root = PackageManager.I.package_root().as_posix()
        project_name = PackageManager.I.project_name()
        workdir = Path(project_name).as_posix()
        app_username = "appuser"
        entrypoint = json.dumps(list(PackageManager.I.run_args(project_name)))
        readme_path, license_path, pyproject_path, lock_file_path = (
            ReadmeConfigFile.I.path().as_posix(),
            LicenseConfigFile.I.path().as_posix(),
            PyprojectConfigFile.I.path().as_posix(),
            PackageManager.I.lock_file().as_posix(),
        )
        copy_files = f"{readme_path} {license_path} {pyproject_path} {lock_file_path}"
        install_dependencies_no_dev = (
            PackageManager.I.install_dependencies_no_dev_args()
        )
        image_url, image_source_path, image_destination_path = (
            PackageManager.I.container_image()
        )
        return f"""FROM python:{latest_python_version}-slim
WORKDIR /{workdir}
COPY --from={image_url} {image_source_path} {image_destination_path}
COPY {copy_files} ./
RUN useradd --create-home --uid=1000 {app_username}
RUN chown --recursive {app_username}:{app_username} .
USER {app_username}
COPY --chown={app_username}:{app_username} {package_root} {package_root}
RUN {install_dependencies_no_dev}
RUN rm {copy_files}
ENTRYPOINT {entrypoint}
"""
extension
extension() -> str

Return an empty string; Containerfile has no file extension.

Source code in src/pyrig_containers/rig/configs/container_file.py
def extension(self) -> str:
    """Return an empty string; `Containerfile` has no file extension."""
    return ""
extension_separator
extension_separator() -> str

Return an empty string, overriding the default . separator.

Prevents a trailing dot from being appended when the extension is empty, so the filename remains Containerfile instead of Containerfile..

Source code in src/pyrig_containers/rig/configs/container_file.py
def extension_separator(self) -> str:
    """Return an empty string, overriding the default `.` separator.

    Prevents a trailing dot from being appended when the extension is
    empty, so the filename remains `Containerfile` instead of
    `Containerfile.`.
    """
    return ""
parent_path
parent_path() -> Path

Return the project root directory.

Source code in src/pyrig_containers/rig/configs/container_file.py
def parent_path(self) -> Path:
    """Return the project root directory."""
    return Path()
stem
stem() -> str

Return "Containerfile".

Source code in src/pyrig_containers/rig/configs/container_file.py
def stem(self) -> str:
    """Return `"Containerfile"`."""
    return "Containerfile"

version_control

Version control config overrides this plugin contributes to pyrig.

remote

Container-specific extensions to GitHub remote repository configuration.

workflows

Container-aware overrides for the project's GitHub Actions workflow configs.

deploy

Extension of the deploy workflow that builds and pushes a container image.

Runs after a release and tags the image with both the release version and latest.

DeployWorkflowConfigFile

Bases: DeployWorkflowConfigFile

Deploy workflow that adds a job to build and push a container image to GHCR.

container_image_tag_latest
container_image_tag_latest() -> str

Build the project's image reference tagged latest.

Source code in src/pyrig_containers/rig/configs/version_control/remote/workflows/deploy.py
def container_image_tag_latest(self) -> str:
    """Build the project's image reference tagged `latest`."""
    return ContainerRegistry.I.image_tag("latest")
container_image_tag_version
container_image_tag_version() -> str

Build the project's image reference tagged with the project version.

Returns:

Type Description
str

Image reference tagged with the bare project version.

Source code in src/pyrig_containers/rig/configs/version_control/remote/workflows/deploy.py
def container_image_tag_version(self) -> str:
    """Build the project's image reference tagged with the project version.

    Returns:
        Image reference tagged with the bare project version.
    """
    return ContainerRegistry.I.image_tag(self.insert_version_expansion())
insert_actor
insert_actor() -> str

Return the expression that resolves to the workflow actor.

Returns:

Type Description
str

GitHub Actions expression for github.actor.

Source code in src/pyrig_containers/rig/configs/version_control/remote/workflows/deploy.py
def insert_actor(self) -> str:
    """Return the expression that resolves to the workflow actor.

    Returns:
        GitHub Actions expression for `github.actor`.
    """
    return self.insert_expression("github.actor")
job_container_image
job_container_image() -> dict[str, Any]

Build the job that builds and pushes the container image to GHCR.

Requests packages: write permission at the job level, required to push to GHCR.

Returns:

Type Description
dict[str, Any]

Dict mapping the derived job ID to its configuration.

Source code in src/pyrig_containers/rig/configs/version_control/remote/workflows/deploy.py
def job_container_image(self) -> dict[str, Any]:
    """Build the job that builds and pushes the container image to GHCR.

    Requests `packages: write` permission at the job level, required to
    push to GHCR.

    Returns:
        Dict mapping the derived job ID to its configuration.
    """
    return self.job(
        self.job_container_image,
        permissions={
            **self.permission_contents(),
            **self.permission_packages(write=True),
        },
        steps=self.steps_container_image(),
    )
jobs
jobs() -> dict[str, Any]

Add the container image publish job to the base jobs.

Returns:

Type Description
dict[str, Any]

Dict combining the base jobs with the container image job.

Source code in src/pyrig_containers/rig/configs/version_control/remote/workflows/deploy.py
def jobs(self) -> dict[str, Any]:
    """Add the container image publish job to the base jobs.

    Returns:
        Dict combining the base jobs with the container image job.
    """
    return {
        **super().jobs(),
        **self.job_container_image(),
    }
step_build_container_image
step_build_container_image() -> dict[str, Any]

Build a step that builds the container image.

Tags the built image with both the versioned tag and the latest tag.

Returns:

Type Description
dict[str, Any]

Step that runs podman build.

Source code in src/pyrig_containers/rig/configs/version_control/remote/workflows/deploy.py
def step_build_container_image(self) -> dict[str, Any]:
    """Build a step that builds the container image.

    Tags the built image with both the versioned tag and the `latest` tag.

    Returns:
        Step that runs `podman build`.
    """
    return self.step(
        self.step_build_container_image,
        run=ContainerEngine.I.build_args(
            tags=(
                self.container_image_tag_version(),
                self.container_image_tag_latest(),
            ),
        ).multiline(),
        env={
            self.version_var(): self.insert_output_version(),
        },
    )
step_login_container_registry
step_login_container_registry() -> dict[str, Any]

Build a step that logs podman in to the container registry.

Authenticates as the workflow actor, using the automatic GITHUB_TOKEN secret as the password.

Returns:

Type Description
dict[str, Any]

Step that runs podman login against the registry.

Source code in src/pyrig_containers/rig/configs/version_control/remote/workflows/deploy.py
def step_login_container_registry(self) -> dict[str, Any]:
    """Build a step that logs podman in to the container registry.

    Authenticates as the workflow actor, using the automatic
    `GITHUB_TOKEN` secret as the password.

    Returns:
        Step that runs `podman login` against the registry.
    """
    actor_var, token_var = "ACTOR", "TOKEN"
    return self.step(
        self.step_login_container_registry,
        run=ContainerEngine.I.login_args(
            registry=ContainerRegistry.I.host(),
            username=self.insert_parameter_expansion(actor_var),
            password=self.insert_parameter_expansion(token_var),
        ).multiline(),
        env={
            actor_var: self.insert_actor(),
            token_var: self.insert_github_token(),
        },
    )
step_push_container_image_latest
step_push_container_image_latest() -> dict[str, Any]

Build a step that pushes the latest image tag to the registry.

Returns:

Type Description
dict[str, Any]

Step that runs podman push for the latest tag.

Source code in src/pyrig_containers/rig/configs/version_control/remote/workflows/deploy.py
def step_push_container_image_latest(self) -> dict[str, Any]:
    """Build a step that pushes the `latest` image tag to the registry.

    Returns:
        Step that runs `podman push` for the `latest` tag.
    """
    return self.step(
        self.step_push_container_image_latest,
        run=str(ContainerEngine.I.push_args(tag=self.container_image_tag_latest())),
    )
step_push_container_image_version
step_push_container_image_version() -> dict[str, Any]

Build a step that pushes the versioned image tag to the registry.

Returns:

Type Description
dict[str, Any]

Step that runs podman push for the versioned tag.

Source code in src/pyrig_containers/rig/configs/version_control/remote/workflows/deploy.py
def step_push_container_image_version(self) -> dict[str, Any]:
    """Build a step that pushes the versioned image tag to the registry.

    Returns:
        Step that runs `podman push` for the versioned tag.
    """
    return self.step(
        self.step_push_container_image_version,
        run=ContainerEngine.I.push_args(
            tag=self.container_image_tag_version(),
        ).multiline(),
        env={
            self.version_var(): self.insert_output_version(),
        },
    )
steps_container_image
steps_container_image() -> list[dict[str, Any]]

Build the ordered steps for the publish-container-image job.

Returns:

Type Description
list[dict[str, Any]]

Ordered list of step dicts: core setup, log in to the registry,

list[dict[str, Any]]

build the image, then push the versioned tag and the latest tag.

Source code in src/pyrig_containers/rig/configs/version_control/remote/workflows/deploy.py
def steps_container_image(self) -> list[dict[str, Any]]:
    """Build the ordered steps for the publish-container-image job.

    Returns:
        Ordered list of step dicts: core setup, log in to the registry,
        build the image, then push the versioned tag and the latest tag.
    """
    return [
        *self.steps_core_setup(),
        self.step_login_container_registry(),
        self.step_extract_version(),
        self.step_build_container_image(),
        self.step_push_container_image_version(),
        self.step_push_container_image_latest(),
    ]

tools

Container-specific overrides and additions for pyrig's CLI tool wrappers.

containers

Tools for building and publishing container images.

engine

Podman command construction for authenticating, building, and publishing images.

ContainerEngine

Bases: Tool

podman command wrapper.

Constructs podman command arguments for authenticating with a registry and building and pushing container images. Typical usage: call login_args to authenticate, build_args to build and tag the image, then push_args to publish each tag to the registry.

build_args
build_args(
    *args: str, tags: Iterable[str] = (), context: str = "."
) -> Args

Build args to build and tag an image from the build context.

Constructs podman build --tag=<tag>... <context>, repeating --tag for each provided tag and inserting *args before the context. No --file is passed, so podman discovers the Containerfile in the build context automatically.

Parameters:

Name Type Description Default
*args str

Additional arguments appended before the context (e.g. --file to point at a specific Containerfile, or --no-cache).

()
tags Iterable[str]

Image references to tag the built image with. Defaults to none.

()
context str

Build context directory. Defaults to the current directory.

'.'

Returns:

Type Description
Args

Args for the podman build command.

Source code in src/pyrig_containers/rig/tools/containers/engine.py
def build_args(
    self,
    *args: str,
    tags: Iterable[str] = (),
    context: str = ".",
) -> Args:
    """Build args to build and tag an image from the build context.

    Constructs `podman build --tag=<tag>... <context>`, repeating
    `--tag` for each provided tag and inserting `*args` before the
    context. No `--file` is passed, so podman discovers the
    `Containerfile` in the build context automatically.

    Args:
        *args: Additional arguments appended before the context (e.g.
            `--file` to point at a specific Containerfile, or
            `--no-cache`).
        tags: Image references to tag the built image with. Defaults to none.
        context: Build context directory. Defaults to the current directory.

    Returns:
        Args for the `podman build` command.
    """
    tag_args = (f"--tag={tag}" for tag in tags)
    return self.args("build", *tag_args, *args, context)
dev_dependencies
dev_dependencies() -> tuple[str, ...]

Return an empty tuple; podman is a system package, not a Python one.

Source code in src/pyrig_containers/rig/tools/containers/engine.py
def dev_dependencies(self) -> tuple[str, ...]:
    """Return an empty tuple; `podman` is a system package, not a Python one."""
    return ()
group
group() -> str

Return Group.TOOLING.

Source code in src/pyrig_containers/rig/tools/containers/engine.py
def group(self) -> str:
    """Return `Group.TOOLING`."""
    return Group.TOOLING
image_url
image_url() -> str

Return the Shields.io badge URL for podman.

Source code in src/pyrig_containers/rig/tools/containers/engine.py
def image_url(self) -> str:
    """Return the Shields.io badge URL for `podman`."""
    return f"https://img.shields.io/badge/Container-{self.shield_name().capitalize()}-A23CD6?logo=podman&logoColor=grey&colorA=0D1F3F&colorB=A23CD6"
link_url
link_url() -> str

Return the URL of the podman project page.

Source code in src/pyrig_containers/rig/tools/containers/engine.py
def link_url(self) -> str:
    """Return the URL of the `podman` project page."""
    return "https://podman.io"
login_args
login_args(
    *args: str, registry: str, username: str, password: str
) -> Args

Build args to authenticate the container engine with a registry.

Constructs podman login <registry> --username=<username> --password=<password>, appending *args at the end.

Parameters:

Name Type Description Default
*args str

Additional arguments appended to the command.

()
registry str

Registry host to authenticate against (e.g. ghcr.io).

required
username str

Account name to log in as.

required
password str

Token or password for the account.

required

Returns:

Type Description
Args

Args for the podman login command.

Source code in src/pyrig_containers/rig/tools/containers/engine.py
def login_args(
    self,
    *args: str,
    registry: str,
    username: str,
    password: str,
) -> Args:
    """Build args to authenticate the container engine with a registry.

    Constructs `podman login <registry> --username=<username>
    --password=<password>`, appending `*args` at the end.

    Args:
        *args: Additional arguments appended to the command.
        registry: Registry host to authenticate against (e.g. `ghcr.io`).
        username: Account name to log in as.
        password: Token or password for the account.

    Returns:
        Args for the `podman login` command.
    """
    return self.args(
        "login",
        registry,
        f"--username={username}",
        f"--password={password}",
        *args,
    )
name
name() -> str

Return "podman".

Source code in src/pyrig_containers/rig/tools/containers/engine.py
def name(self) -> str:
    """Return `"podman"`."""
    return "podman"
push_args
push_args(*args: str, tag: str) -> Args

Build args to push a tagged image to its registry.

Constructs podman push <tag>, appending *args at the end.

Parameters:

Name Type Description Default
*args str

Additional arguments appended to the command.

()
tag str

Fully qualified image reference to push (e.g. ghcr.io/owner/repo:latest).

required

Returns:

Type Description
Args

Args for the podman push command.

Source code in src/pyrig_containers/rig/tools/containers/engine.py
def push_args(self, *args: str, tag: str) -> Args:
    """Build args to push a tagged image to its registry.

    Constructs `podman push <tag>`, appending `*args` at the end.

    Args:
        *args: Additional arguments appended to the command.
        tag: Fully qualified image reference to push (e.g.
            `ghcr.io/owner/repo:latest`).

    Returns:
        Args for the `podman push` command.
    """
    return self.args("push", tag, *args)
registry

Container registry identity and badge metadata for publishing images.

ContainerRegistry

Bases: Tool

GitHub Container Registry (GHCR) wrapper.

Provides the registry host, the project's fully qualified image reference within it, and badge metadata for GHCR.

dev_dependencies
dev_dependencies() -> tuple[str, ...]

Return an empty tuple; the registry requires no Python package.

Source code in src/pyrig_containers/rig/tools/containers/registry.py
def dev_dependencies(self) -> tuple[str, ...]:
    """Return an empty tuple; the registry requires no Python package."""
    return ()
group
group() -> str

Return Group.PROJECT_INFO.

Source code in src/pyrig_containers/rig/tools/containers/registry.py
def group(self) -> str:
    """Return `Group.PROJECT_INFO`."""
    return Group.PROJECT_INFO
host
host() -> str

Return "ghcr.io".

Source code in src/pyrig_containers/rig/tools/containers/registry.py
def host(self) -> str:
    """Return `"ghcr.io"`."""
    return "ghcr.io"
image_name
image_name() -> str

Build the project's fully qualified image name without a tag.

Combines the registry host with the lowercased repository owner and project name, as GHCR requires image names to be lowercase.

Returns:

Type Description
str

Image name in the form ghcr.io/<owner>/<project>.

Source code in src/pyrig_containers/rig/tools/containers/registry.py
def image_name(self) -> str:
    """Build the project's fully qualified image name without a tag.

    Combines the registry host with the lowercased repository owner and
    project name, as GHCR requires image names to be lowercase.

    Returns:
        Image name in the form `ghcr.io/<owner>/<project>`.
    """
    owner = VersionController.I.repo_owner().lower()
    project = PackageManager.I.project_name().lower()
    return f"{self.host()}/{owner}/{project}"
image_tag
image_tag(tag: str) -> str

Build the project's image reference for the given tag.

Parameters:

Name Type Description Default
tag str

Tag to append to the image name (e.g. latest or 1.2.3).

required

Returns:

Type Description
str

Image reference in the form ghcr.io/<owner>/<project>:<tag>.

Source code in src/pyrig_containers/rig/tools/containers/registry.py
def image_tag(self, tag: str) -> str:
    """Build the project's image reference for the given tag.

    Args:
        tag: Tag to append to the image name (e.g. `latest` or `1.2.3`).

    Returns:
        Image reference in the form `ghcr.io/<owner>/<project>:<tag>`.
    """
    return f"{self.image_name()}:{tag}"
image_url
image_url() -> str

Return the Shields.io badge URL for GHCR.

Source code in src/pyrig_containers/rig/tools/containers/registry.py
def image_url(self) -> str:
    """Return the Shields.io badge URL for GHCR."""
    return "https://img.shields.io/badge/GHCR-Container_Image-black?logo=github&logoColor=white"
link_url
link_url() -> str

Return the URL of the project's GHCR container package page.

Source code in src/pyrig_containers/rig/tools/containers/registry.py
def link_url(self) -> str:
    """Return the URL of the project's GHCR container package page."""
    repo_url = RemoteVersionController.I.repo_url()
    package = PackageManager.I.project_name()
    return f"{repo_url}/pkgs/container/{package}"
name
name() -> str

Return "ghcr".

Source code in src/pyrig_containers/rig/tools/containers/registry.py
def name(self) -> str:
    """Return `"ghcr"`."""
    return "ghcr"

packages

Container-specific overrides for pyrig's package-manager tool.

manager

Container-specific conventions for the project's package manager.

PackageManager

Bases: PackageManager

uv package manager, extended with a container-image convention.

Adds container_image, which supplies the image and paths needed to embed the uv binary in a container image.

container_image
container_image() -> tuple[str, str, str]

Return the image and paths for copying uv into a container image.

Returns:

Type Description
tuple[str, str, str]

Tuple of (image, path_in_source_image, path_in_target_image).

Source code in src/pyrig_containers/rig/tools/packages/manager.py
def container_image(self) -> tuple[str, str, str]:
    """Return the image and paths for copying uv into a container image.

    Returns:
        Tuple of `(image, path_in_source_image, path_in_target_image)`.
    """
    return "ghcr.io/astral-sh/uv:latest", "/uv", "/usr/local/bin/uv"