Trying to build a cardano-node cli arm64v8 docker image

Hello,

I am trying to build a cardano node and cli docker image.

I want to build it for arm64v8 so that I can run it on a microk8s cluster of Raspberry pi4.

The dockerfile is the following:

FROM alpine AS builder

# Download QEMU, see https://github.com/docker/hub-feedback/issues/1261
ENV QEMU_URL https://github.com/balena-io/qemu/releases/download/v3.0.0%2Bresin/qemu-3.0.0+resin-aarch64.tar.gz
RUN apk add curl && curl -L ${QEMU_URL} | tar zxvf - -C . --strip-components 1


FROM arm64v8/ubuntu:20.04

# Add QEMU
COPY --from=builder qemu-aarch64-static /usr/bin

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y libsodium-dev build-essential \
    pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ \
    tmux git jq wget libncursesw5 llvm

RUN apt-get install -y cabal-install ghc

ARG CARDANO_NODE_COMMIT=1.21.1
ENV CARDANO_NODE_COMMIT ${CARDANO_NODE_COMMIT}

RUN git clone https://github.com/input-output-hk/cardano-node.git && \
    cd cardano-node && \
    git checkout ${CARDANO_NODE_COMMIT} && \
    cabal update && \
    for target in cardano-node cardano-cli; do cabal new-build ${target}; done


And the error is:

#9 4.526 Linking /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-cli-1.21.1/t/cardano-cli-golden/build/cardano-cli-golden/cardano-cli-golden ...
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-api-1.21.1/build/libHScardano-api-1.21.1-inplace.a(Typed.o):ghc_101.ll:c5s9X_info$def: error: undefined reference to 'crypto_vrf_seedbytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:rrCL_info$def: error: undefined reference to 'crypto_vrf_proofbytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:rrCM_info$def: error: undefined reference to 'crypto_vrf_publickeybytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:rrCN_info$def: error: undefined reference to 'crypto_vrf_secretkeybytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:rrCO_info$def: error: undefined reference to 'crypto_vrf_seedbytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:rrCP_info$def: error: undefined reference to 'crypto_vrf_outputbytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cardanozmcryptozmpraoszm2zi0zi0zminplace_CardanoziCryptoziVRFziPraos_zdfVRFAlgorithmPraosVRFzuzdcseedSizzeVRF_info$def: error: undefined reference to 'crypto_vrf_seedbytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cardanozmcryptozmpraoszm2zi0zi0zminplace_CardanoziCryptoziVRFziPraos_zdfVRFAlgorithmPraosVRFzuzdcsizzeOutputVRF_info$def: error: undefined reference to 'crypto_vrf_outputbytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cardanozmcryptozmpraoszm2zi0zi0zminplace_CardanoziCryptoziVRFziPraos_vrfKeySizzeVRF_info$def: error: undefined reference to 'crypto_vrf_outputbytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cardanozmcryptozmpraoszm2zi0zi0zminplace_CardanoziCryptoziVRFziPraos_zdfVRFAlgorithmPraosVRF4_info$def: error: undefined reference to 'crypto_vrf_seedbytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cardanozmcryptozmpraoszm2zi0zi0zminplace_CardanoziCryptoziVRFziPraos_verKeySizzeVRF_info$def: error: undefined reference to 'crypto_vrf_publickeybytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cardanozmcryptozmpraoszm2zi0zi0zminplace_CardanoziCryptoziVRFziPraos_signKeySizzeVRF_info$def: error: undefined reference to 'crypto_vrf_secretkeybytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cardanozmcryptozmpraoszm2zi0zi0zminplace_CardanoziCryptoziVRFziPraos_certSizzeVRF_info$def: error: undefined reference to 'crypto_vrf_proofbytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cardanozmcryptozmpraoszm2zi0zi0zminplace_CardanoziCryptoziVRFziPraos_verify1_info$def: error: undefined reference to 'crypto_vrf_outputbytes'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cwtu_info$def: error: undefined reference to 'crypto_vrf_verify'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cwUZ_info$def: error: undefined reference to 'crypto_vrf_sk_to_seed'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cx0l_info$def: error: undefined reference to 'crypto_vrf_sk_to_pk'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cx7E_info$def: error: undefined reference to 'crypto_vrf_keypair_from_seed'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cxC4_info$def: error: undefined reference to 'crypto_vrf_prove'
#9 4.529 /cardano-node/dist-newstyle/build/aarch64-linux/ghc-8.6.5/cardano-crypto-praos-2.0.0/build/libHScardano-crypto-praos-2.0.0-inplace.a(Praos.o):ghc_2.ll:cxXr_info$def: error: undefined reference to 'crypto_vrf_proof_to_hash'
#9 4.529 collect2: error: ld returned 1 exit status
#9 4.529 `aarch64-linux-gnu-gcc' failed in phase `Linker'. (Exit code: 1)
#9 4.530 cabal: Failed to build exe:cardano-cli from cardano-cli-1.21.1.
#9 4.530 Failed to build test:cardano-cli-golden from cardano-cli-1.21.1.
#9 4.530 Failed to build test:cardano-cli-test from cardano-cli-1.21.1.

Any suggestions,
Thanks

1 Like

The official libsodium-dev package does not contain’s the Algorand’s VRF, therefore you need to build it /w some other library. I would say, build this one https://github.com/input-output-hk/libsodium instead using the libsodium-dev package, and if it’s required set the LD_LIBRARY_PATH to the lib directory, probably /usr/local/lib/ as default, after make install.

1 Like

Thanks you sir.

I’ll give it a go and I’ll let you know :bowing_man:

1 Like

I’ve also just realised I’m using ubuntu:18.04 as base image that has a different default version of libsodium compared to 20.04 (1.0.16-2 vs 1.0.18-1 respectively)…

This could be an easy way to fix it… I only have to wait another 4 hours to build the image from scratch :roll_eyes:

I do not think it would help, as no any official libsodium has the required VRF, so you need a VRF enabled libsodium anyway.

You can try this too for building that libsodium automatically at the compiler time:

cat << EOF > cardano-node/cabal.project.local
package cardano-crypto-praos
  flags: -external-libsodium-vrf
EOF
1 Like

You’re right, just checked the original repo and VRF never made it there.

Do I still have to apt-get install libsodium-dev ? Or can I ditch it altogether ?

Gonna use this piece of config.

I’ve actually seen this piece of config somewhere else… what does it do? Forces cabal to fetch the source explicitly ?

I think it would not be required, but who knows, some other part of the codes could need it, as I am not sure how these separated Haskell repos are compiled/built.
So, I would leave it as it is (with libsodium-dev) as better safe than sorry, and later remove it if it’s not required.

1 Like

Also, I would like to see how these builds plays out as the crypto related operations were expensive approx. 10x slower for Cardano than on x86_64 platforms.

Hoepfully, it is optimised now and can validate every blocks fast enough.

I haven’t received my Rasp PIs yet, so it will take another few days before I’m gonna have everything setup.

This guy though has a PoC already up and running.

This is his pool: https://adapools.org/pool/2a748e3885f6f73320ad16a8331247b81fe01b8d39f57eec9caa5091

Not sure how to read his pools’ stats properly, but it looks like it’s working (last rewards 6 epocs ago at time of writing).

And here another Pi pool https://adapools.org/pool/fb2ef0b6933e23890ae8ca4a4d3137f61991aab76b33a2426e0f6aa2

Creating block is cheaper a bit and your pool need to compute it occasionally only, so that’s not an issue.

Every node (relay or pool etc) is verifying every blocks (header first, to be precise).
But, if they have that block (or block header) already (checking by some cheap hash), then they do not need to do it again.

But, your node will have more blocks from others to verify (around 21600 in an epoch) than the forged (depends on stake but roughly from 0 to as high or more as 100) blocks.

This worked.

docker build -t cardano-node:1.21.1 .
[... many output lines and hours later ...]
Successfully built fd01058d9d54
Successfully tagged cardano-node:1.21.1

Thanks a mil

1 Like

Glad to hear that.

Gonna add a working draft of my dockerfile for whoever might be interested:

FROM ubuntu:18.04 as builder

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update
RUN apt-get upgrade -y
RUN apt-get install -y automake build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev \
    zlib1g-dev make g++ tmux git jq wget libncursesw5 libtool autoconf llvm

# INSTALL GHC
# The Glasgow Haskell Compiler
ENV GHC_VERSION="8.6.5"
ENV OS_ARCH="aarch64"
WORKDIR /build/ghc
RUN wget https://downloads.haskell.org/~ghc/${GHC_VERSION}/ghc-${GHC_VERSION}-${OS_ARCH}-ubuntu18.04-linux.tar.xz
RUN tar -xf ghc-${GHC_VERSION}-${OS_ARCH}-ubuntu18.04-linux.tar.xz
RUN cd ghc-${GHC_VERSION} && ./configure && make install

# Install Libsodium
WORKDIR /build/libsodium
RUN git clone https://github.com/input-output-hk/libsodium
RUN cd libsodium && \
    git checkout 66f017f1 && \
    ./autogen.sh && ./configure && make && make install

ENV LD_LIBRARY_PATH="/usr/local/lib"
ENV PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"

# INSTALL CABAL
# The Haskell Common Architecture for Building Applications and Libraries
ENV CABAL_VERSION="3.2.0.0"
WORKDIR /build/cabal
RUN wget -qO- https://github.com/haskell/cabal/archive/Cabal-v${CABAL_VERSION}.tar.gz | tar xzfv - -C . --strip-components 1 \
  && cd cabal-install \
  && ./bootstrap.sh

# Cabal to PATH
ENV PATH="/root/.cabal/bin:${PATH}"

ENV CARDANO_VERSION="1.21.1"
WORKDIR /build/cardano-node
RUN git clone --branch ${CARDANO_VERSION} https://github.com/input-output-hk/cardano-node.git && \
    cd cardano-node && \
    cabal update && \
    cabal build all

FROM ubuntu:18.04

RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y --no-install-recommends netbase && \
    rm -rf /var/lib/apt/lists/*

## Libsodium refs
COPY --from=builder /usr/local/lib /usr/local/lib

ENV OS_ARCH="aarch64"
ENV GHC_VERSION="8.6.5"
ENV CARDANO_VERSION="1.21.1"

## Not sure I still need thse
ENV LD_LIBRARY_PATH="/usr/local/lib"
ENV PKG_CONFIG_PATH="/usr/local/lib/pkgconfig"

RUN rm -fr /usr/local/lib/ghc-8.6.5

COPY config/mainnet /etc/config
COPY config/testnet /etc/config

COPY --from=builder /build/cardano-node/cardano-node/dist-newstyle/build/${OS_ARCH}-linux/ghc-${GHC_VERSION}/cardano-node-${CARDANO_VERSION}/x/cardano-node/build/cardano-node/cardano-node /usr/local/bin/
COPY --from=builder /build/cardano-node/cardano-node/dist-newstyle/build/${OS_ARCH}-linux/ghc-${GHC_VERSION}/cardano-cli-${CARDANO_VERSION}/x/cardano-cli/build/cardano-cli/cardano-cli /usr/local/bin/

ENTRYPOINT ["bash", "-c"]

Please note this is a working draft, and it’s not by far a complete, production ready, container spec.

The file is extracted from: https://github.com/speedwing/cardano-node-builder/blob/master/cardano-node/Dockerfile

The project I’m working on to run cardano pools (both test and mainnet) on a Kubernetes microk8s cluster hosted on raspberry pi.

1 Like

Hi @nemo83,

I wanted to let you know that project nessus-cardano has landed. It provides multi-arch images for cardano relay/bp nodes.

Additional functionality …

  • Built-in topology updater
  • Built-in gLiveView

Much of this work was inspired by what YOU have done - cudos for that :wink:

I was thinking, that we (and perhaps other folks) could perhaps gather together to provide/maintain the best possible cardano image that (also) runs on the Pi.

What do you think?

cheers
– thomas

4 Likes

@tomdx , @nemo83 - cheers guys for the effort you put in. I have a Rock Pi 64 at home that I wanted to setup as a relay node and I wanted to do it with Docker. Glad I searched the forum first and found someone had already done it! :slight_smile: So, cheers to you for initiating this. :+1: I will give this a swing!

Hi. I am running your image now, but the container keeps restarting and writing in the logs: “Nothing to do! Perhaps try [run|cardano-cli]”. So, I’m not sure where I need to start now… firewall NAT? Topology? ENV? Bridge/Host network_mode? I would appreciate some pointers. My Compose file looks like this:

---
version: "2.1"
services:
  cardano-relay:
    image: docker.io/nessusio/cardano-node
    container_name: cardano-relay
    hostname: cardano-relay #optional
    network_mode: "bridge"
    environment:
      - CARDANO_UPDATE_TOPOLOGY=true
    volumes:
      - /mnt/disk/cardano-relay:/mnt/disks/data00
    ports:
      - 3001:3001
    restart: unless-stopped

You should do what it says :wink:

    command: "run"

The other command you can give is cardano-cli. If that should not be clear from the docs, you are welcome to provide a PR to make it so.

:relaxed: :shushing_face: Well, that’s embarassing :smile: . I missed the “run” on the docker cli. Thanks for your speedy answer and pointing that out.

UR welcome