Skip to content

Add docker buildx bake and support for cmake #692

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

danvergara
Copy link
Contributor

Replaces #669 and rewrites #673

Changes

  • This PR introduces docker buildx bake command which is a new feature that lets you define your build configuration using a declarative file
  • This PR rewrites 673 because it could break <=28.1 images as it is today, due to the removal of the autosgen.sh file in favor of cmake to build Bitcoin.
  • This PR adds a new Dockerfile to support the new way to compile Bitcoin and a couple of new “base” targets to the docker-bake.hcl file that both inherit from the maintained-base target
  • The second base stage is for >28.1 and uses the new Dockerfile.dev file. The name can be changed to anything else, just the first option that came to mind
  • The BUILD_ARGS field was modified to support new parameters to build Bitcoin using cmake

@willcl-ark
Copy link
Contributor

willcl-ark commented Mar 11, 2025

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

No conflicts as of last run.

@danvergara danvergara changed the title Rewrite image build cmake Add docker buildx bake and support for cmake Mar 11, 2025
@deadmanoz
Copy link
Contributor

Nice work @danvergara 👏 💪

There were a few suggestions from myself, Onyekachukwu-Nweke and macgyver13 (can't tag them) on the original PR that you might want to consider incorporating. #669

These suggestions reduce target duplication and make the docker-bake.hcl more HCL-idiomatic (if there is such a thing).

Copy link
Contributor

@pinheadmz pinheadmz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far, one comment below. I'm going to run a bunch of builds on a remote server today in the background and will report back how it all goes.

Comment on lines +58 to +63
target "cmake-base" {
inherits = ["maintained-base"]
dockerfile = "./Dockerfile.dev"
args = {
BUILD_ARGS = "-DBUILD_TESTS=OFF -DBUILD_GUI=OFF -DBUILD_BENCH=OFF -DBUILD_FUZZ_BINARY=OFF -DWITH_ZMQ=ON"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this need amd and arm platforms?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I suppose not because it inherits. Looks like they get built in parallel too which is awesome:

Screenshot 2025-03-11 at 9 36 21 AM

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it only rewrites what's needed for the cmake build, other than that, it inherits from the maintained-base target.

@danvergara
Copy link
Contributor Author

Thanks @deadmanoz. Let me address those suggestions later today after work.

Comment on lines +86 to +90
# build the dummy image that will crash on 5k invs
docker buildx bake bitcoin-5k-inv

# build the same image, but set platform to only linux/amd64
docker buildx bake bitcoin-5k-inv --set bitcoin-5k-inv.platform=linux/amd64
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should also mention --load or --push ?

Or actually, see src/warnet/image_build.py I'm not sure if these explicit docker buildx commands are necessary because of that abstract command...?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some a few paragraphs on how to use those options.

@pinheadmz
Copy link
Contributor

From this branch on Ubuntu/x86 I was able to build two autotools images (v0-16-1 and inv-5k) but failed on a cmake build (master) with an OOM, which is really wild since I have 24 GB RAM on this server... but I also have 32 CPUs, so I actually wonder if -j$(nproc) is doing too much ?

docker info looks like it has all the resources of the machine:

...

 CPUs: 32
 Total Memory: 22.91GiB
....

Also weird because I have built bitcoin with cmake outside of docker on this server just fine with -j 32

Here's the build error:


2616.2 c++: fatal error: Killed signal terminated program cc1plus
2616.2 compilation terminated.
2616.3 gmake[2]: *** [src/CMakeFiles/bitcoin_node.dir/build.make:331: src/CMakeFiles/bitcoin_node.dir/init.cpp.o] Error 1
2616.3 gmake[2]: *** Waiting for unfinished jobs....
2739.1 c++: fatal error: Killed signal terminated program cc1plus
2739.1 compilation terminated.
2739.1 gmake[2]: *** [src/CMakeFiles/bitcoin_node.dir/build.make:471: src/CMakeFiles/bitcoin_node.dir/net_processing.cpp.o] Error 1
3226.5 gmake[1]: *** [CMakeFiles/Makefile2:690: src/CMakeFiles/bitcoin_node.dir/all] Error 2
3586.5 [ 78%] Linking CXX static library libbitcoin_common.a
3603.8 [ 78%] Built target bitcoin_common
3603.8 gmake: *** [Makefile:136: all] Error 2
------
WARNING: No output specified for bitcoin-master target(s) with docker-container driver. Build result will only remain in the build cache. To push result image into registry use --push or to load image into docker use --load
Dockerfile.dev:34
--------------------
  33 |
  34 | >>> RUN set -ex \
  35 | >>>     && cd /build \
  36 | >>>     && git clone --depth 1 "https://github.com/${REPO}" \
  37 | >>>     && cd bitcoin \
  38 | >>>     && git fetch --depth 1 origin "$COMMIT_SHA" \
  39 | >>>     && git checkout "$COMMIT_SHA" \
  40 | >>>     && git apply /tmp/isroutable.patch \
  41 | >>>     && git apply /tmp/addrman.patch \
  42 | >>>     && sed -i s:sys/fcntl.h:fcntl.h: src/compat/compat.h \
  43 | >>>     && cmake -B build \
  44 | >>>     -DCMAKE_INSTALL_PREFIX=${BITCOIN_PREFIX} \
  45 | >>>     ${BUILD_ARGS} \
  46 | >>>     && cmake --build build -j$(nproc) \
  47 | >>>     && cmake --install build \
  48 | >>>     && strip ${BITCOIN_PREFIX}/bin/bitcoin-cli \
  49 | >>>     && strip ${BITCOIN_PREFIX}/bin/bitcoind \
  50 | >>>     && rm -f ${BITCOIN_PREFIX}/lib/libbitcoinconsensus.a \
  51 | >>>     && rm -f ${BITCOIN_PREFIX}/lib/libbitcoinconsensus.so.0.0.0
  52 |
--------------------
ERROR: failed to solve: ResourceExhausted: process "/dev/.buildkit_qemu_emulator /bin/sh -c set -ex
     && cd /build     && git clone --depth 1 \"https://github.com/${REPO}\"     && cd bitcoin     && git fetch --depth 1 origin \"$COMMIT_SHA\"
     && git checkout \"$COMMIT_SHA\"     && git apply /tmp/isroutable.patch     && git apply /tmp/addrman.patch     && sed -i s:sys/fcntl.h:fcntl.h: src/compat/compat.h
     && cmake -B build     -DCMAKE_INSTALL_PREFIX=${BITCOIN_PREFIX}     ${BUILD_ARGS}     && cmake --build build -j$(nproc)
     && cmake --install build     && strip ${BITCOIN_PREFIX}/bin/bitcoin-cli     && strip ${BITCOIN_PREFIX}/bin/bitcoind     && rm -f ${BITCOIN_PREFIX}/lib/libbitcoinconsensus.a
     && rm -f ${BITCOIN_PREFIX}/lib/libbitcoinconsensus.so.0.0.0" did not complete successfully: cannot allocate memory

@pinheadmz
Copy link
Contributor

Oh right, multiple builds in parallel... that does explain the resource consumption. Is there a work around? Or maybe do the builds in series instead?

Screenshot 2025-03-12 at 10 34 33 AM

@danvergara
Copy link
Contributor Author

danvergara commented Mar 12, 2025

@pinheadmz have you built multiple targets at the same time for arm64? I think build in series is the way to go. I have pipelines that cross-build images at work (from Ubuntu/x86 to linux/arm64) that take up to 60 minutes.

Btw, do you know why the test suite failed? I did not touch other that the documentation in the latest commit

@pinheadmz
Copy link
Contributor

Ill restart CI, looks like a flaky test. I haven't tried building multiple targets on this server outside of guix builds which are run in parallel and take hours.

@danvergara
Copy link
Contributor Author

@pinheadmz any luck in series builds?

@danvergara
Copy link
Contributor Author

Tonight, I built the master target for every platform available. I only did it for the arm64 but not for amd64 and arm7.
Fedora 41 with 32 GB of RAM. It took around an hour to complete. cc @pinheadmz

Screenshot From 2025-03-12 21-20-53

@pinheadmz
Copy link
Contributor

machine is busy on a guix build for right now but I'll try again later. Do you know what the dockerx flags are to force serial builds?

@danvergara
Copy link
Contributor Author

danvergara commented Mar 13, 2025

My bad, seems like there's no forced serial builds, only parallelism management and it is done via Buildkit configuration.

https://docs.docker.com/build/buildkit/configure/#max-parallelism

Another way might using be multiple docker enabled remote builder nodes:

https://www.ivonet.nl/2022/04/10/docker-multi-platform-build-with-buildx/

@pinheadmz
Copy link
Contributor

Ok i set parallelism to = 1 and re-created the builder. That seems to be working now. So I'll have some locally baked warnet images to test here later today then if all goes well this is RFM

@pinheadmz
Copy link
Contributor

ACK -- OK great thank you!

@pinheadmz pinheadmz merged commit 692230b into bitcoin-dev-project:main Mar 17, 2025
23 of 30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants