> ## Documentation Index
> Fetch the complete documentation index at: https://aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# Shipping artifacts

> Ship Python apps from Bazel as OCI container images using aspect_rules_py's py_image_layer, running them locally and pushing to a cloud registry for staging deployment.

This lesson follows a typical journey to get code into a development or staging environment.
You’ll create a docker (OCI) container image, run it locally, and push it to a cloud.

## Define the image

[`aspect_rules_py`](https://github.com/aspect-build/rules_py) — the same ruleset that provides the `py_binary` you've been using — also provides `py_image_layer`, which splits a `py_binary` into OCI layers (interpreter, third-party packages, and your code) so image rebuilds stay fast and cache-friendly. (Projects scaffolded with the `oci` feature ship a small `py3_image` macro that wraps exactly this; here we'll wire it up directly to see the pieces.)

Add the container targets to `app/BUILD.bazel`. `py_image_layer` produces the layer tarballs, [`rules_oci`](https://github.com/bazel-contrib/rules_oci)'s `oci_image` assembles them onto a base image, and `oci_load` makes the result loadable into your local container runtime:

```python theme={null}
load("@aspect_rules_py//py:defs.bzl", "py_image_layer")
load("@rules_oci//oci:defs.bzl", "oci_image", "oci_load")

# Split the app's py_binary into cacheable layers.
py_image_layer(
    name = "layers",
    binary = ":app_bin",
)

oci_image(
    name = "image",
    base = "@ubuntu",  # pulled via an oci.pull() in MODULE.bazel; py_image_layer
    # already bundles the hermetic interpreter, so any minimal base works.
    entrypoint = ["/app/app_bin"],
    tars = [":layers"],
)

oci_load(
    name = "load",
    image = ":image",
    repo_tags = ["localhost/app:latest"],
)
```

## Run the image

You can build `:image` to produce the OCI image.
However, most devs expect that a container image is also loaded into the daemon as part of building it, since that’s how `docker build` works.
That's what the `oci_load` target above is for — it's runnable and calls the equivalent of `docker load` for you.

```python theme={null}
 % bazel query --output=label_kind app:all

py_library rule //app:app
py_binary rule //app:app_bin
tar rule //app:layers
oci_image rule //app:image
oci_load rule //app:load
```

`oci_load` is the rule kind you want, so run `bazel run //app:load`

The command prints the registry and tag that was loaded: `Loaded image: localhost/app:latest`

That means you can now run it with your container runtime:

```python theme={null}
% docker run --rm -it localhost/app:latest
  _______________________________________
 /                                       \
| -- Built at <unstamped> --              |
| I'm a cow, I found this on the internet |
| <!DOCTYPE html>                         |
| <html>                                  |
...
```

## Stamping artifacts

Say you deploy the container to prod, and the monitoring system pages you because it’s crash-looping. You want to figure out whether the crashes are on the new version - but you still have `<unstamped>` in the program.

When you build artifacts for pushing to an environment, ideally in a continuous delivery step on CI, you are willing to give up some of the determinism guarantee. It’s okay to have some cache misses after you’ve got green test results. Bazel has a `--stamp` flag which means that the outputs can intentionally be non-deterministic and use data from VCS.

So run:

```python theme={null}
% bazel run --stamp //app:load
% docker run --rm -it localhost/app:latest
  _______________________________________
 /                                       \
| -- Built at 1737154064 --               |
| I'm a cow, I found this on the internet |
| <!DOCTYPE html>                         |
```

Now you see the header template was re-built with a current timestamp, then the application and the container image updated as well.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.