Rules for creating container image layers from js_binary targets
For example, this js_image_layer target outputs node_modules.tar and app.tar with /app prefix.
load("@aspect_rules_js//js:defs.bzl", "js_image_layer") js_image_layer( name = "layers", binary = "//label/to:js_binary", root = "/app", )
Create container image layers from js_binary targets.
By design, js_image_layer doesn't have any preference over which rule assembles the container image. This means the downstream rule (oci_image, or container_image in this case) must set a proper workdir and cmd to for the container work. A proper cmd usually looks like /[ root of js_image_layer ]/[ relative path to BUILD file from WORKSPACE or package_name() ]/[ name of js_binary ], unless you have a launcher script that invokes the entry_point of the js_binary in a different path. On the other hand, workdir has to be set to runfiles tree root which would be exactly cmd but with .runfiles/[ name of the workspace or __main__ if empty ] suffix. If workdir is not set correctly, some attributes such as chdir might not work properly.
js_image_layer supports transitioning to specific platform to allow building multi-platform container images.
A partial example using rules_oci with transition to linux/amd64 platform.
load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_image_layer") load("@contrib_rules_oci//oci:defs.bzl", "oci_image") js_binary( name = "binary", entry_point = "main.js", ) platform( name = "amd64_linux", constraint_values = [ "@platforms//os:linux", "@platforms//cpu:x86_64", ], ) js_image_layer( name = "layers", binary = ":binary", platform = ":amd64_linux", root = "/app" ) oci_image( name = "image", cmd = ["/app/main"], entrypoint = ["bash"], tars = [ ":layers" ] )
A partial example using rules_oci to create multi-platform images.
load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_image_layer") load("@contrib_rules_oci//oci:defs.bzl", "oci_image", "oci_image_index") js_binary( name = "binary", entry_point = "main.js", ) [ platform( name = "linux_{}".format(arch), constraint_values = [ "@platforms//os:linux", "@platforms//cpu:{}".format(arch if arch != "amd64" else "x86_64"), ], ) js_image_layer( name = "{}_layers".format(arch), binary = ":binary", platform = ":linux_{arch}", root = "/app" ) oci_image( name = "{}_image".format(arch), cmd = ["/app/main"], entrypoint = ["bash"], tars = [ ":{}_layers".format(arch) ] ) for arch in ["amd64", "arm64"] ] oci_image_index( name = "image", images = [ ":arm64_image", ":amd64_image" ] )
An example using legacy rules_docker
See e2e/js_image_rules_docker for full example.
load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_image_layer") load("@io_bazel_rules_docker//container:container.bzl", "container_image") js_binary( name = "main", data = [ "//:node_modules/args-parser", ], entry_point = "main.js", ) js_image_layer( name = "layers", binary = ":main", root = "/app", visibility = ["//visibility:__pkg__"], ) filegroup( name = "app_tar", srcs = [":layers"], output_group = "app" ) container_layer( name = "app_layer", tars = [":app_tar"], ) filegroup( name = "node_modules_tar", srcs = [":layers"], output_group = "node_modules" ) container_layer( name = "node_modules_layer", tars = [":node_modules_tar"], ) container_image( name = "image", cmd = ["/app/main"], entrypoint = ["bash"], layers = [ ":app_layer", ":node_modules_layer", ], )
ATTRIBUTES
| Name | Description | Type | Mandatory | Default |
|---|---|---|---|---|
| name | A unique name for this target. | Name | required | |
| binary | Label to an js_binary target | Label | required | |
| compression | Compression algorithm. Can be one of gzip, none. | String | optional | “gzip” |
| platform | Platform to transition. | Label | optional | None |
| root | Path where the files from js_binary will reside in. eg: /apps/app1 or /app | String | optional | "" |
PARAMETERS
| Name | Description | Default Value |
|---|---|---|
| ctx | - | none |