Skip to content

Commit

Permalink
[docker] Rename experimental builder (#7809)
Browse files Browse the repository at this point in the history
* [docker] Rename experimental builder

* fix image
  • Loading branch information
ibalajiarun authored May 12, 2023
1 parent f3e00d6 commit f3fc710
Show file tree
Hide file tree
Showing 23 changed files with 102 additions and 774 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# explicitly include stuff we actually need via negation

!docker/build-rust-all.sh
!docker/experimental/*.sh
!docker/builder/*.sh
!docker/tools/boto.cfg


Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/workflow-run-docker-rust-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }}

- name: Build and Push Rust images
run: docker/experimental/docker-bake-rust-all.sh
run: docker/builder/docker-bake-rust-all.sh
env:
PROFILE: ${{ env.PROFILE }}
FEATURES: ${{ env.FEATURES }}
Expand Down
25 changes: 0 additions & 25 deletions docker/README.md

This file was deleted.

69 changes: 0 additions & 69 deletions docker/build-rust-all.sh

This file was deleted.

80 changes: 80 additions & 0 deletions docker/builder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Docker Images Builder

This directory contains [Docker](https://www.docker.com/) configuration for building Aptos docker images. This builder requires the use of Buildkit which is available by default in most recent Docker installations.

To build these images run this from the repository root:

```
docker buildx create --use # creates a buildkit builder and only needs to be run once
docker/builder/docker-bake-rust-all.sh
```

The above command will by default build all the images. To build specific images, refer to `group` and `target` definitions in [docker-bake-rust-all.hcl](docker-bake-rust-all.hcl).

For using the images, look in the [docker/compose](../docker/compose/) directory.

## List of Images

The builder can produce the following Docker images. To build a particular image, run `./docker/builder/docker-bake-rust-all.sh [image-name]`. Also, refer to the `group` definitions in the [docker-bake-rust-all.hcl](docker-bake-rust-all.hcl) file for more information.

1. `validator-testing` : Image containing the `aptos-node` binary and other linux tools useful for debugging and testing. This image is used in Forge tests.
2. `validator` : Image containing only the `aptos-node` binary. This image is usually used for distribution.
3. `tools`: Image containing all the aptos tools binaries including `aptos-db-bootstrapper`, `aptos-db-tool`, `aptos`, `aptos-transaction-emitter`, `aptos-openapi-spec-generator` and `aptos-fn-check-client`. Also, includes the Aptos Move framework for use with genesis generation.
4. `forge`: Image containing the `forge` binary that orchestrates and runs Forge tests.
5. `node-checker`: Image containing the `node-checker` binary that checks the health of a node.
6. `faucet`: Image containing the `faucet` binary that provides a faucet service for minting coins.
7. `indexer-grpc`: Image containing the `indexer-grpc` binary that indexes the blockchain and provides a gRPC service for querying.
8. `telemetry-service`: Image containing the `telemetry-service` binary that collects telemetry from blockchain nodes.

## How the builder works

At a high level, the builder works as follows. By default, the builder builds all images.
1. Either or both the `aptos-node-builder` and `tools-builder` targets are invoked depending on what image is being built.
2. The target image is built by copying the output of either the `aptos-node-builder` or `tools-builder` target into the target image.

The `aptos-node-builder` is separate from the `tools-builder` because it allows to build different `aptos-node` binary variants with different features and profiles.

Using a builder step allows us to cache the build artifacts and reuse them across different images. Our binaries have a lot of common dependencies, so this is a significant time saver. Furthermore, most `RUN` instructions use a cache mount that allows us to cache the output of the command leading to significant build time improvements.

## Building a new Image

> Note: If building a CLI tool, consider adding it to the `tools` image instead of creating a new image.
> Note: If your requirements doesn't fit into the instructions below, please reach out to the team for help.
1. Modify the `cargo build` step in `build-tools.sh` to include the new binary.
2. Create a new Dockerfile by cloning an existing target Dockerfile (e.g. `validator.Dockerfile`). When you use a `RUN` instruction, try to use a mount cache as they can improve build times by caching the output of the command.
3. Add the following `FROM` statements to the new Dockerfile depending on whether you need to copy from the `aptos-node-builder` or the `tools-builder`. This ensures that your image references the required builder images to copy the binaries from. These image references are injected as build contexts at build time. This is defined in the `contexts` field in `_common` target in [docker-bake-rust-all.hcl](docker-bake-rust-all.hcl).

```
FROM node-builder
FROM tools-builder
```

4. In your new Dockerfile, use the COPY command to copy the output of the `aptos-node-builder` or `tools-builder` target into the image. For example, to copy the `aptos-node` binary into the `validator` image, use the following command:
```
COPY --link --from=node-builder /aptos/dist/aptos-node /usr/local/bin/
```
5. Add a new target defition in [docker-bake-rust-all.hcl](docker-bake-rust-all.hcl) file by copying another target (e.g. `validator`). The target definition should have the following fields:
- `inherits`
- `target`: Name of the target. This should be the same as the name of the Dockerfile.
- `dockerfile`: Path to the Dockerfile.
- `tags`: Create a unique tag for the image using `generate_tags` function.
- `cache-from`: Create a unique cache key using `generate_cache_from` function.
- `cache-to`: Create a unique cache key using `generate_cache_to` function.
6. Optionally, you can create a `group` definition to build multiple tagets at once.
## Image tagging strategy
The `aptos-node-builder` and `tools-builder` targets build the `aptos-node` binary and the remaining rust binaries, respectively, and is the most expensive. Its output is used by all the other targets that follow.
The `*-builder` itself takes in a few build arguments. Most are build metadata, such as `GIT_SHA` and `GIT_BRANCH`, but others change the build entirely, such as cargo flags `PROFILE` and `FEATURES`. Arguments like these necessitate a different cache to prevent clobbering. The general strategy is to use image tags and cache keys that use these variables. An example image tag might be:
- `performance_failpoints_<GIT_SHA>` -- `performance` profile with `failpoints` feature
- `<GIT_SHA>` -- default `release` profile with no additional features
## Release Images
Image releasing is done automatically using corresponding github workflow jobs or manually using the `docker/release-images.mjs` script.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@ RUN --mount=type=secret,id=GIT_CREDENTIALS,target=/root/.git-credentials \
--mount=type=cache,target=/usr/local/cargo/git,id=node-builder-cargo-git-cache \
--mount=type=cache,target=/usr/local/cargo/registry,id=node-builder-cargo-registry-cache \
--mount=type=cache,target=/aptos/target,id=node-builder-target-cache \
docker/experimental/build-node.sh
docker/builder/build-node.sh

FROM builder-base as tools-builder

RUN --mount=type=secret,id=GIT_CREDENTIALS,target=/root/.git-credentials \
--mount=type=cache,target=/usr/local/cargo/git,id=tools-builder-cargo-git-cache \
--mount=type=cache,target=/usr/local/cargo/registry,id=tools-builder-cargo-registry-cache \
--mount=type=cache,target=/aptos/target,id=tools-builder-target-cache \
docker/experimental/build-tools.sh
docker/builder/build-tools.sh
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ group "forge-images" {
}

target "debian-base" {
dockerfile = "docker/experimental/debian-base.Dockerfile"
dockerfile = "docker/builder/debian-base.Dockerfile"
contexts = {
debian = "docker-image://debian:bullseye-20220912@sha256:3e82b1af33607aebaeb3641b75d6e80fd28d36e17993ef13708e9493e30e8ff9"
debian = "docker-image://debian:bullseye-20230502@sha256:32888a3c745e38e72a5f49161afc7bb52a263b8f5ea1b3b4a6af537678f29491"
}
}

target "builder-base" {
dockerfile = "docker/experimental/builder.Dockerfile"
dockerfile = "docker/builder/builder.Dockerfile"
target = "builder-base"
context = "."
contexts = {
Expand All @@ -91,7 +91,7 @@ target "builder-base" {
}

target "aptos-node-builder" {
dockerfile = "docker/experimental/builder.Dockerfile"
dockerfile = "docker/builder/builder.Dockerfile"
target = "aptos-node-builder"
contexts = {
builder-base = "target:builder-base"
Expand All @@ -102,7 +102,7 @@ target "aptos-node-builder" {
}

target "tools-builder" {
dockerfile = "docker/experimental/builder.Dockerfile"
dockerfile = "docker/builder/builder.Dockerfile"
target = "tools-builder"
contexts = {
builder-base = "target:builder-base"
Expand Down Expand Up @@ -135,7 +135,7 @@ target "_common" {

target "validator-testing" {
inherits = ["_common"]
dockerfile = "docker/experimental/validator-testing.Dockerfile"
dockerfile = "docker/builder/validator-testing.Dockerfile"
target = "validator-testing"
cache-from = generate_cache_from("validator-testing")
cache-to = generate_cache_to("validator-testing")
Expand All @@ -144,7 +144,7 @@ target "validator-testing" {

target "tools" {
inherits = ["_common"]
dockerfile = "docker/experimental/tools.Dockerfile"
dockerfile = "docker/builder/tools.Dockerfile"
target = "tools"
cache-from = generate_cache_from("tools")
cache-to = generate_cache_to("tools")
Expand All @@ -153,7 +153,7 @@ target "tools" {

target "forge" {
inherits = ["_common"]
dockerfile = "docker/experimental/forge.Dockerfile"
dockerfile = "docker/builder/forge.Dockerfile"
target = "forge"
cache-from = generate_cache_from("forge")
cache-to = generate_cache_to("forge")
Expand All @@ -162,7 +162,7 @@ target "forge" {

target "validator" {
inherits = ["_common"]
dockerfile = "docker/experimental/validator.Dockerfile"
dockerfile = "docker/builder/validator.Dockerfile"
target = "validator"
cache-from = generate_cache_from("validator")
cache-to = generate_cache_to("validator")
Expand All @@ -171,7 +171,7 @@ target "validator" {

target "tools" {
inherits = ["_common"]
dockerfile = "docker/experimental/tools.Dockerfile"
dockerfile = "docker/builder/tools.Dockerfile"
target = "tools"
cache-from = generate_cache_from("tools")
cache-to = generate_cache_to("tools")
Expand All @@ -180,7 +180,7 @@ target "tools" {

target "node-checker" {
inherits = ["_common"]
dockerfile = "docker/experimental/node-checker.Dockerfile"
dockerfile = "docker/builder/node-checker.Dockerfile"
target = "node-checker"
cache-from = generate_cache_from("node-checker")
cache-to = generate_cache_to("node-checker")
Expand All @@ -189,7 +189,7 @@ target "node-checker" {

target "faucet" {
inherits = ["_common"]
dockerfile = "docker/experimental/faucet.Dockerfile"
dockerfile = "docker/builder/faucet.Dockerfile"
target = "faucet"
cache-from = generate_cache_from("faucet")
cache-to = generate_cache_to("faucet")
Expand All @@ -198,7 +198,7 @@ target "faucet" {

target "telemetry-service" {
inherits = ["_common"]
dockerfile = "docker/experimental/telemetry-service.Dockerfile"
dockerfile = "docker/builder/telemetry-service.Dockerfile"
target = "telemetry-service"
cache-from = generate_cache_from("telemetry-service")
cache-to = generate_cache_to("telemetry-service")
Expand All @@ -207,7 +207,7 @@ target "telemetry-service" {

target "indexer-grpc" {
inherits = ["_common"]
dockerfile = "docker/experimental/indexer-grpc.Dockerfile"
dockerfile = "docker/builder/indexer-grpc.Dockerfile"
target = "indexer-grpc"
cache-to = generate_cache_to("indexer-grpc")
tags = generate_tags("indexer-grpc")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ fi

BUILD_TARGET="${1:-all}"
echo "Building target: ${BUILD_TARGET}"
echo "To build only a specific target, run: docker/experimental/docker-bake-rust-all.sh <target>"
echo "E.g. docker/experimental/docker-bake-rust-all.sh forge-images"
echo "To build only a specific target, run: docker/builder/docker-bake-rust-all.sh <target>"
echo "E.g. docker/builder/docker-bake-rust-all.sh forge-images"

if [ "$CI" == "true" ]; then
TARGET_REGISTRY=remote docker buildx bake --progress=plain --file docker/experimental/docker-bake-rust-all.hcl --push $BUILD_TARGET
TARGET_REGISTRY=remote docker buildx bake --progress=plain --file docker/builder/docker-bake-rust-all.hcl --push $BUILD_TARGET
else
TARGET_REGISTRY=local docker buildx bake --file docker/experimental/docker-bake-rust-all.hcl $BUILD_TARGET
TARGET_REGISTRY=local docker buildx bake --file docker/builder/docker-bake-rust-all.hcl $BUILD_TARGET
fi

echo "Build complete. Docker buildx cache usage:"
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit f3fc710

Please sign in to comment.