-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1084 from chainguard-dev/bazel
apko update
- Loading branch information
Showing
2 changed files
with
252 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
--- | ||
title: "Bazel Rules for apko" | ||
linktitle: "Bazel Rules" | ||
type: "article" | ||
lead: "Build secure, minimal Wolfi-based container images using Bazel" | ||
description: "Build secure, minimal Wolfi-based container images using Bazel" | ||
date: 2023-10-23T08:49:31+00:00 | ||
lastmod: 2023-10-23T16:49:31+00:00 | ||
draft: false | ||
tags: ["apko", "Procedural",] | ||
images: [] | ||
menu: | ||
docs: | ||
parent: "apko" | ||
weight: 900 | ||
toc: true | ||
--- | ||
|
||
`rules_apko` is an open source plugin for Bazel that makes it possible to build secure, minimal Wolfi-based container images using the popular Bazel build system. This wraps the [apko](https://github.com/chainguard-dev/apko) tool for use under Bazel. | ||
|
||
## Prerequisites | ||
|
||
First, be sure you have Bazel installed, you can follow the [Bazel installation guide](https://bazel.build/install) for more details. | ||
|
||
Next, `rules_apko` requires a one-time setup to configure Bazel to be able to make partial fetches. | ||
|
||
Paste the following into your root `BUILD` file. | ||
|
||
```py | ||
load("@rules_apko//apko:defs.bzl", "apko_bazelrc") | ||
|
||
apko_bazelrc() | ||
``` | ||
|
||
> **Note**: By default, `apko_bazelrc` will generate `.bazelrc` to accomodate for fetching from `dl-cdn.alpinelinux.org` and `packages.wolfi.dev`. this can be configured by passing the `repositories` attribute to `apko_bazelrc()` call. | ||
Then, run the following command. | ||
|
||
```sh | ||
bazel run @@//:apko_bazelrc && chmod +x .apko/range.sh | ||
``` | ||
|
||
Finally, paste this into your preferred \`.bazelrc\` file, | ||
|
||
```sh | ||
# Required for rules_apko to make range requests | ||
try-import %workspace%/.apko/.bazelrc | ||
``` | ||
|
||
Review additional [initial setup documentation](https://github.com/chainguard-dev/rules_apko/blob/main/docs/initial-setup.md) updates in the `rules_apko` [repo](https://github.com/chainguard-dev/rules_apko). | ||
|
||
## Installation | ||
|
||
To install v1.0.0, you can follow one of the options below. For other releases, follow the instructions in the release notes from the release you wish to use: [https://github.com/chainguard-dev/rules_apko/releases](https://github.com/chainguard-dev/rules_apko/releases). | ||
|
||
### Using Bzlmod with Bazel 6 | ||
|
||
1. Enable with `common --enable_bzlmod` in `.bazelrc`. | ||
1. Add to your `MODULE.bazel` file: | ||
|
||
```starlark | ||
bazel_dep(name = "rules_apko", version = "1.0.0-rc1") | ||
``` | ||
|
||
## Using WORKSPACE | ||
|
||
Paste this snippet into your file: | ||
|
||
```starlark | ||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") | ||
http_archive( | ||
name = "rules_apko", | ||
sha256 = "5c91a2322bec84a0005dd8178495775938b581053812e70d21b030bef3625623", | ||
strip_prefix = "rules_apko-1.0.0-rc1", | ||
url = "https://github.com/chainguard-dev/rules_apko/releases/download/v1.0.0-rc1/rules_apko-v1.0.0-rc1.tar.gz", | ||
) | ||
|
||
###################### | ||
# rules_apko setup # | ||
###################### | ||
# Fetches the rules_apko dependencies. | ||
# If you want to have a different version of some dependency, | ||
# you should fetch it *before* calling this. | ||
# Alternatively, you can skip calling this function, so long as you've | ||
# already fetched all the dependencies. | ||
load("@rules_apko//apko:repositories.bzl", "apko_register_toolchains", "rules_apko_dependencies") | ||
|
||
rules_apko_dependencies() | ||
|
||
apko_register_toolchains(name = "apko") | ||
|
||
load("@rules_apko//apko:translate_lock.bzl", "translate_apko_lock") | ||
|
||
translate_apko_lock( | ||
name = "example_lock", | ||
lock = "@//:apko.lock.json", | ||
) | ||
|
||
load("@example_lock//:repositories.bzl", "apko_repositories") | ||
|
||
apko_repositories() | ||
``` | ||
## Rules | ||
|
||
Public API re-exports | ||
|
||
## apko_image | ||
|
||
<pre> | ||
apko_image(<a href="#apko_image-name">name</a>, <a href="#apko_image-architecture">architecture</a>, <a href="#apko_image-args">args</a>, <a href="#apko_image-config">config</a>, <a href="#apko_image-contents">contents</a>, <a href="#apko_image-output">output</a>, <a href="#apko_image-tag">tag</a>) | ||
</pre> | ||
|
||
Build OCI images from APK packages directly without Dockerfile. | ||
|
||
This rule creates Alpine images using the `apko.yaml` configuration file and relies on cache contents generated by [translate_lock](https://github.com/chainguard-dev/rules_apko/blob/main/docs/translate_lock.md) to be fast. | ||
|
||
```starlark | ||
apko_image( | ||
name = "example", | ||
config = "apko.yaml", | ||
contents = "@example_lock//:contents", | ||
tag = "example:latest", | ||
) | ||
``` | ||
|
||
The label `@example_lock//:contents` is generated by the `translate_lock` extension, which consumes an 'apko.lock.json' file. For more details, refer to the [apko cache documentation](#fetching-and-caching-contents). | ||
|
||
An example demonstrating usage with [rules_oci](https://github.com/bazel-contrib/rules_oci): | ||
|
||
```starlark | ||
apko_image( | ||
name = "alpine_base", | ||
config = "apko.yaml", | ||
contents = "@alpine_base_lock//:contents", | ||
tag = "alpine_base:latest", | ||
) | ||
|
||
oci_image( | ||
name = "app", | ||
base = ":alpine_base" | ||
) | ||
``` | ||
|
||
For more examples checkout the [examples](https://github.com/chainguard-dev/rules_apko/tree/main/examples) directory. | ||
|
||
### Attributes | ||
|
||
| Name | Description | Type | Mandatory | Default | | ||
| :------------- | :------------- | :------------- | :------------- | :------------- | | ||
| <a id="apko_image-name"></a>name | A unique name for this target. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | | | ||
| <a id="apko_image-architecture"></a>architecture | the CPU architecture which this image should be built to run on. See https://github.com/chainguard-dev/apko/blob/main/docs/apko_file.md#archs-top-level-element | String | optional | <code>""</code> | | ||
| <a id="apko_image-args"></a>args | additional arguments to provide when running the <code>apko build</code> command. | List of strings | optional | <code>[]</code> | | ||
| <a id="apko_image-config"></a>config | Label to the <code>apko.yaml</code> file. | <a href="https://bazel.build/concepts/labels">Label</a> | required | | | ||
| <a id="apko_image-contents"></a>contents | Label to the contents repository generated by translate_lock. See [apko-cache](./apko-cache.md) documentation. | <a href="https://bazel.build/concepts/labels">Label</a> | required | | | ||
| <a id="apko_image-output"></a>output | - | String | optional | <code>"oci"</code> | | ||
| <a id="apko_image-tag"></a>tag | tag to apply to the resulting docker tarball. only applicable when <code>output</code> is <code>docker</code> | String | required | | | ||
|
||
### apko_bazelrc | ||
|
||
<pre> | ||
apko_bazelrc(<a href="#apko_bazelrc-name">name</a>, <a href="#apko_bazelrc-repositories">repositories</a>, <a href="#apko_bazelrc-kwargs">kwargs</a>) | ||
</pre> | ||
|
||
Helper macro for generating `.bazelrc` and `range.sh` files to allow for partial package fetches. | ||
|
||
Review [Prerequisites](#prerequisites) documentation for more information. | ||
|
||
### Parameters | ||
|
||
| Name | Description | Default Value | | ||
| :------------- | :------------- | :------------- | | ||
| <a id="apko_bazelrc-name"></a>name | name of the target | <code>"apko_bazelrc"</code> | | ||
| <a id="apko_bazelrc-repositories"></a>repositories | list of repositories to generate .bazelrc for | <code>["dl-cdn.alpinelinux.org", "packages.wolfi.dev"]</code> | | ||
| <a id="apko_bazelrc-kwargs"></a>kwargs | passed to expanding targets. only well known attributes such as <code>tags</code> <code>testonly</code> ought to be present. | none | | ||
|
||
## Fetching and Caching Contents | ||
|
||
To ensure efficient operation, the `apko_image` rule must maintain a cache of remote contents that it fetches from repositories. While outside of Bazel, `apko` manages its own cache, under Bazel, the cache must be maintained by Bazel to ensure correctness and speed. Therefore, Bazel needs to know what needs to be fetched and from where to cache these HTTP requests and provide them to `apko` as required. | ||
|
||
The `apko.lock.json` file contains all the necessary information about how to perform the HTTP fetches required by `apko` to build the container image. | ||
|
||
### Generating the Lock File | ||
|
||
> **Note:** Documentation for lockfile generation [will be added to the repository docs](https://github.com/chainguard-dev/rules_apko/blob/main/docs/apko-cache.md) once the `apko resolve` command is available. | ||
### Using `translate_lock` | ||
|
||
Having just the `apko.lock.json` file alone is insufficient; all the information needs to be converted into `apk_<content_type>` repository calls to make them accessible to Bazel. The `translate_lock` tool accomplishes this by taking the `apko.lock.json` file and dynamically generating the required Bazel repositories. | ||
|
||
`translate_lock` will create a new bazel repository named after itself. This repository will also have a target named contents, which you can pass to `apko_image`: | ||
|
||
```starlark | ||
apko_image( | ||
name = "lock", | ||
config = "apko.yaml", | ||
# name of the repository is the same translate_lock! | ||
contents = "@examples_lock//:contents", | ||
tag = "lock:latest", | ||
) | ||
``` | ||
|
||
#### Usage with `bzlmod` | ||
|
||
```starlark | ||
apk = use_extension("//apko:extensions.bzl", "apko") | ||
|
||
apk.translate_lock( | ||
name = "examples_lock", | ||
lock = "//path/to/lock:apko.lock.json", | ||
) | ||
use_repo(apk, "examples_lock") | ||
``` | ||
|
||
#### Usage with Workspace | ||
|
||
```starlark | ||
load("@rules_apko//apko:translate_lock.bzl", "translate_apko_lock") | ||
|
||
translate_apko_lock( | ||
name = "example_lock", | ||
lock = "//path/to/lock:apko.lock.json", | ||
) | ||
|
||
load("@example_lock//:repositories.bzl", "apko_repositories") | ||
|
||
apko_repositories() | ||
``` | ||
|
||
## Repository rules for translating apko.lock.json | ||
|
||
`translate_apko_lock` | ||
|
||
<pre> | ||
translate_apko_lock(<a href="#translate_apko_lock-name">name</a>, <a href="#translate_apko_lock-lock">lock</a>, <a href="#translate_apko_lock-repo_mapping">repo_mapping</a>, <a href="#translate_apko_lock-target_name">target_name</a>) | ||
</pre> | ||
|
||
## Repository rule to generate starlark code from an `apko.lock.json` file. | ||
|
||
Review [the section above](http://localhost:1313/open-source/apko/bazel-rules/#fetching-and-caching-contents) for more information. | ||
|
||
|
||
### Attributes | ||
|
||
|
||
| Name | Description | Type | Mandatory | Default | | ||
| :------------- | :------------- | :------------- | :------------- | :------------- | | ||
| <a id="translate_apko_lock-name"></a>name | A unique name for this repository. | <a href="https://bazel.build/concepts/labels#target-names">Name</a> | required | | | ||
| <a id="translate_apko_lock-lock"></a>lock | label to the <code>apko.lock.json</code> file. | <a href="https://bazel.build/concepts/labels">Label</a> | required | | | ||
| <a id="translate_apko_lock-repo_mapping"></a>repo_mapping | A dictionary from local repository name to global repository name. This allows controls over workspace dependency resolution for dependencies of this repository.<p>For example, an entry <code>"@foo": "@bar"</code> declares that, for any time this repository depends on <code>@foo</code> (such as a dependency on <code>@foo//some:target</code>, it should actually resolve that dependency within globally-declared <code>@bar</code> (<code>@bar//some:target</code>). | <a href="https://bazel.build/rules/lib/dict">Dictionary: String -> String</a> | required | | | ||
| <a id="translate_apko_lock-target_name"></a>target_name | internal. do not use! | String | optional | <code>""</code> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters