Skip to main content

Migrating to rules_oci

This document contains some of the lessons we've learned at https://aspect.dev from doing consulting work, migrating some large client repos from rules_docker to rules_oci.

This guide remains a work-in-progress as we find new patterns.

Update WORKSPACE

The WORKSPACE file contains Bazel module dependency fetching and installation.

Add install steps from a release of rules_oci, along with related rulesets you plan to use.

Replacements by rule

rules_dockerrules_ocicommand to migrate
container_pushoci_pushbuildozer 'set kind oci_push' //...:%container_push
container_imageoci_imagebuildozer 'set kind oci_image' //...:%container_image
container_pullN/Ahttps://github.com/bazel-contrib/rules_oci/issues/63
container_importN/A
container_loadN/A

container_push

registry and repository are merged into one attribute; repository.

-registry = "registry.io",
-repository = "org/image"
+repository = "registry.io/org/image"

tag attribute is now default_tags and allows multiple tags.

-tag = "latest",
+default_tags = ["latest"]

insecure_repository is not needed anymore as it's automatically detected for most cases. However, in case it can't be detected --insecure can be added to the args attribute.

-insecure_repository = true,
+args = ["--insecure"]

tag_file has no drop-in replacement at the moment. However, oci_push supports passing --tag flag at runtime. follow rules_oci#46

-tag_file = ":tag_file",
+ bazel run :push -- --tag $(cat bazel-bin/path/to)

repository_file has no-drop in replacement either. However, oci_push supports passing --repository flag at runtime. follow rules_oci#46

-repository_file = ":tag_file",
+ bazel run :push -- --repository $(cat bazel-bin/path/to)

stamp is unsupported. there is no plan for supporting stamping on oci_push directly.

format is unsupported. the default format is oci and legacy docker format isn't supported.

skip_unchanged_digest is unsupported. oci_push skips existing blobs by default.

extension is unsupported. the default extension is sh. no plans to support it.

tag_tpl and windows_paths attributes are unsupported. no plans to support it.

container_image

oci_image does not support following attributes directly, but can be passed to pkg_tar for layer creation.

  • files -> pkg_tar#srcs
  • compression -> pkg_tar#compressor
  • compression_options -> pkg_tar#compressor_args
  • data_path -> pkg_tar#strip_prefix ?????????????
  • directory -> pkg_tar#package_dir
  • empty_dirs -> pkg_tar#empty_dirs
  • empty_files -> pkg_tar#empty_files
  • tars -> pkg_tar#deps
  • mode -> pkg_tar#mode
  • mtime -> pkg_tar#mtime
  • symlinks -> pkg_tar#symlinks

An example demonstrating migrating tars, directory, symlinks from container_image to oci_image

@@ -1,6 +1,13 @@
-container_image(
+oci_image(
name = "image",
+ tars = [
+ ":new_layer"
+ ]
+)
+
+pkg_tar(
+ name = "new_layer",
symlinks = { "/usr/bin/app": "/app"},
tars = [":app"],
- directory = "/org/image"
+ package_dir = "/org/image"
)

debs is not supported directly as an attribute. However, since .deb files consist of two tar files data.tar.xz and control.tar.xz, these can be passed to oci_image#tars attribute after extracted from deb file.

If the debian files are downloaded via http_archive, bazel recently landed support for extracting these files on the fly.

An example genrule extracting .deb files before passing down to oci_image

genrule(
name = "new_layer",
srcs = [":deb"],
outs = ["data.tar.xz"],
cmd = "tar -xvf -c $@/ $(location :deb)",
)

oci_image(
tars = [":new_layer"]
)

enable_mtime_preservation is unsupported. pkg_tar doesn't support this feature as well. Generally, this is a bad idea since it leads to non-reproducible builds.

layers is now tars. it accepts any arbitrary .tar files.

-container_image(
+oci_image(
name = "image",
- layers = [
+ tars = [
":layer"
]
)

launcher and launcher_args are unsupported. As a replacement cmd and entrypoint can be used instead. However, since entrypoint attribute overrides the entrypoint, it wouldn't be possible to inherit the entrypoint from the base.

-container_image(
-container_image(
+pkg_tar(
+ name = "launcher",
+ srcs = [":launcher"]
+)
+oci_image(
name = "image",
- launcher = ":launcher",
- launcher_args = ["--arg1", "--arg2"],
- entrypoint = ["/app"],
- cmd = ["--apparg1"]
+ entrypoint = ["/path/to/launcher", "--arg1", "--arg2"]
+ cmd = ["/app", "--apparg1"],
+ tars = [
+ ":launcher"
+ ]
)

legacy_run_behavior, legacy_repository_naming, and docker_run_flags attributes are unsupported. Instead oci_tarball rule should be used for loading the oci_image into a docker daemon.

the oci_image target can be loaded into the daemon by running bazel build :tarball, docker load -i bazel-bin/tarball/tarball.tar respectively.

docker_run_flags can be passed to docker directly when running docker run gcr.io/test:latest

-container_image(
+oci_image(
name = "image",
+)
+
+oci_tarball(
+ name = "tarball",
+ image = ":image",
+ repotags = ["gcr.io/test:latest"]
)

repository and tag_name is unsupported. use oci_tarball#repo_tags as a replacement.

-container_image(
+oci_image(
name = "image",
tag_name = "latest",
- repository = "gcr.io"
+ repository = "gcr.io/image"
+)
+
+oci_tarball(
+ name = "tarball",
+ repotags = ["gcr.io/image:latest"]
)

compression and compression_options are unsupported. use pkg_tar#compressor and pkg_tar#compressor_args when creating layers instead.

experimental_tarball_format is unsupported. oci_image does not produce tarballs. oci_tarball, which produces tarballs out of oci_image, should be used instead.

stamp is unsupported. However, there are plans to support it. If the intent is to stamp layers, pkg_tar#stamp is the preferred way to stamp layers.

creation_time is unsupported at the moment. by default creation time for the image is static. follow rules_oci#49 for updates.

os_version is unsupported at the moment. follow rules_oci#48 for updates.

labels is unsupported at the moment. follow rules_oci#47 for updates.

ports is unsupported. most runtimes support --port|-p flag which can be passed at container startup.

volumes is unsupported. most runtimes support --volume|-v|--mount flag which can be passed at container startup.