├── README.md ├── dockerfiles ├── armada-cn-arm64.dockerfile ├── build.sh └── files │ ├── run.sh │ └── tx-submit-service └── node └── run-node.sh /README.md: -------------------------------------------------------------------------------- 1 | # Cardano Node Docker Image (for ARM64 devices) 🐳 2 | 3 | In this project you will find the files to build a docker image on Linux containing all the needed files to run a Cardano full node. 4 | The docker image can run on any arm64 device such as a Mac Mini M1. It can be configured as a relay or block production node. 5 | 6 | If you are enjoying the content of this project, please consider supporting me by donating ₳D₳ to: addr1qygv5fqsfjhfgkx7fhkkegxksx56dsu262vhaxr4mvuukt8uqh7nhjs3pcl98xr2zhmtqk6qkmr4gszxjrs3lnpedqdqyr3jzc 7 | 8 | ## Why using docker image to run a Cardano node? 9 | 10 | The elegant thing of a Cardano node deployed as a Docker image is, that it can be installed and started seamlessly straight out-of-the box. 11 | The day you should decide to delete it, you just have to remove one file - the image. Another advantage is that it can run on any operating 12 | system that has Docker installed. With a Docker image the setup and management of a Cardano node is easier compared to the traditional guide 13 | (for example you don't have to deal with systemd settings). It is therefore recommended also for less experienced users. 14 | 15 | ## System requirements 16 | 17 | * CPU: ARM64 processor min 2 cores at 2GHz or faster. 18 | * Memory: 16GB of RAM. 19 | * Storage: 50 GB. 20 | * OS: Linux (recommended Ubuntu) 21 | * Additional Software: Docker 22 | * Broadband: 10 Mbps + 23 | 24 | If you intend to use a Raspberry Pi 8GB RAM for the deployment of this docker image, I highly recommend to follow the Armada Alliance 25 | [Server Setup guide](https://armada-alliance.com/docs/stake-pool-guides/pi-pool-tutorial/pi-node-full-guide/server-setup/) first. 26 | This guide describes how to optimize the Hardware in order to meet the above listed system requirements. 27 | 28 | # 1.Install Docker 29 | 30 | The installation of Docker varies from operating system to operating system. For this reason, I share some helpful and good installation 31 | guide links for the different operating systems. 32 | 33 | * [Install Docker on Linux (Ubuntu)](https://github.com/speedwing/cardano-staking-pool-edu/blob/master/DOCKER.md) 34 | * [Install Docker on MacOs](https://docs.docker.com/desktop/mac/install/) 35 | * [Install Docker on Windows](https://docs.docker.com/desktop/windows/install/) 36 | 37 | # 2. Download repository and Cardano node configuration files 38 | 39 | Let's clone this repository to your host system first 40 | 41 | ```bash 42 | cd ${HOME} 43 | sudo git clone https://github.com/jterrier84/Cardano-node-docker.git 44 | cd Cardano-node-docker 45 | ``` 46 | 47 | We will now download the latest official Cardano node configuration files from the IOHK repository and store them on our host system. 48 | 49 | For the sake of this tutorial we will download and set up the configuration files for the Cardano testnet/preprod. If you need the files for the mainnet 50 | just replace "preprod" with "mainnet" here below. 51 | 52 | Note: As the configuration files might require modifications over time, it is way more practical to have them stored on the host, 53 | rather than have them stored inside the Docker container. The Docker image will then access to these files via file sharing. 54 | 55 | ```bash 56 | sudo mkdir node/db 57 | sudo mkdir node/files 58 | cd node/files 59 | export NODE_CONFIG="preprod" 60 | sudo curl -O -J https://book.world.dev.cardano.org/environments/${NODE_CONFIG}/config.json && sudo mv config.json ${NODE_CONFIG}-config.json 61 | sudo curl -O -J https://book.world.dev.cardano.org/environments/${NODE_CONFIG}/db-sync-config.json 62 | sudo curl -O -J https://book.world.dev.cardano.org/environments/${NODE_CONFIG}/submit-api-config.json 63 | sudo curl -O -J https://book.world.dev.cardano.org/environments/${NODE_CONFIG}/topology.json && sudo mv topology.json ${NODE_CONFIG}-topology.json 64 | sudo curl -O -J https://book.world.dev.cardano.org/environments/${NODE_CONFIG}/byron-genesis.json 65 | sudo curl -O -J https://book.world.dev.cardano.org/environments/${NODE_CONFIG}/shelley-genesis.json 66 | sudo curl -O -J https://book.world.dev.cardano.org/environments/${NODE_CONFIG}/alonzo-genesis.json 67 | sudo curl -O -J https://book.world.dev.cardano.org/environments/${NODE_CONFIG}/conway-genesis.json 68 | sudo wget -O tx-submit-mainnet-config.yaml https://raw.githubusercontent.com/input-output-hk/cardano-node/master/cardano-submit-api/config/tx-submit-mainnet-config.yaml 69 | ``` 70 | 71 | Note: The Docker Cardano node will access to the directories /files and /db on the host system. 72 | 73 | The directory /files contains the downloaded Cardano node configuration files. 74 | 75 | The /db directory will host the Cardano blockchain once the Docker node is started. It is important that the blockchain data 76 | are stored on the host system and not inside the Docker container, otherwise the entire blockchain would be deleted every time 77 | the Docker container is removed. Our docker image will manage this automatically. 78 | 79 | # 3. Build the Cardano node docker image 80 | 81 | At this point it's time to build the docker image. The image will include: 82 | 83 | 1. cardano-node & cardano-cli - Cardano binaries to run the node (Download compiled binaries from [Armada Alliance GitHub](https://github.com/armada-alliance/cardano-node-binaries)) 84 | 2. gLiveView - Monitoring tool for the Cardano node 85 | 3. ScheduledBlocks - Tool to query the scheduled slots for a block production node. (Credits for this tool goes to [SNAKE POOL](https://github.com/asnakep/ScheduledBlocks)) 86 | 4. Cardano Submit Transaction API - API to connect with a Cardano wallet (e.g. Nami) to send transactions via your own full node 87 | 88 | ```bash 89 | cd ${HOME}/Cardano-node-docker/dockerfiles 90 | sudo ./build.sh 91 | ``` 92 | The process might take some minutes. 93 | 94 | Once the process is done, you can use the command to see the list of all Docker images: 95 | 96 | ```bash 97 | docker images 98 | ``` 99 | 100 | You should see your Cardano node docker image in the list, e.g. 101 | 102 | ```bash 103 | REPOSITORY TAG IMAGE ID CREATED SIZE 104 | armada/armada-cn 8.9.1 da4414775ce6 37 seconds ago 740MB 105 | f3891eef21e4 3 minutes ago 1.09GB 106 | ``` 107 | 108 | All we need is the "armada/armada-cn" image. You can delete the others in the list to free up space on your harddrive, e.g. 109 | 110 | ```bash 111 | docker rmi f3891eef21e4 112 | ``` 113 | 114 | # 4. Start node 115 | 116 | Let's first configure the run-node.sh script to match your host system environment. 117 | 118 | ```bash 119 | cd ${HOME}/Cardano-node-docker/node 120 | sudo nano run-node.sh 121 | ``` 122 | 123 | Edit the configuration section according to your setup. 124 | 125 | * Note:If you are running the node as relay node, you can ignore the paramter CN_KEY_PATH. 126 | * Important: Change the directory paths CN_CONFIG_PATH and CN_DB_PATH to the corresponding locations on your host. 127 | 128 | ```bash 129 | ##Configuration for relay and block producing node 130 | CNIMAGENAME="armada/armada-cn" ## Name of the Cardano docker image 131 | CNVERSION="9.1.1" ## Version of the cardano-node. It must match with the version of the docker i> 132 | CNNETWORK="testnet" ## Use "mainnet" if connecting node to the mainnet 133 | CNMODE="relay" ## Use "bp" if you configure the node as block production node 134 | CNPORT="3001" ## Define the port of the node 135 | CNPROMETHEUS_PORT="12799" ## Define the port for the Prometheus metrics 136 | CN_CONFIG_PATH="/home/julienterrier/Cardano-node-docker/node/files" ## Path to the folder where the Cardano config files are stored on the host> 137 | CN_DB_PATH="/home/julienterrier/Cardano-node-docker/node/db" ## Path to the folder where the Cardano database (blockchain) will be stored o> 138 | CN_RTS_OPTS="+RTS -N2 -I0.1 -Iw3600 -A64m -AL128M -n4m -F1.1 -H3500M -O3500M -RTS" ## RTS optimization parameters 139 | CN_BF_ID="" ## Your blockfrost.io project ID (neededfor ScheduledBlock script) 140 | CN_POOL_ID="" ## Your stake pool ID (needed for ScheduledBlock script) 141 | CN_POOL_TICKER="" ## Your pool ticker (needed for ScheduledBlock script) 142 | CN_VRF_SKEY_PATH="" ## Name of the vrf.skey file. It must be located in the directory CN_KEY_PATH 143 | CN_KEY_PATH="" ## Path to the folder where the OP certificate and keys are stored on the host system 144 | ``` 145 | 146 | After making the changes, save and close the file. 147 | 148 | `Ctrl+o & ENTER & Ctrl+x` 149 | 150 | You can now run the docker image. 151 | 152 | ```bash 153 | sudo ./run-node.sh 154 | ``` 155 | 156 | ## Check the running status of the docker container 157 | 158 | You can check the running status of the docker container at any time with: 159 | 160 | ```bash 161 | docker ps -a 162 | ``` 163 | 164 | If the docker node started successfully, you might see something like this: 165 | 166 | ```bash 167 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 168 | fed0cfbf7d86 armada/armada-cn:8.9.1 "bash -c /home/carda…" 12 seconds ago Up 10 seconds (healthy) 0.0.0.0:3001->3001/tcp, :::3001->3001/tcp, 0.0.0.0:12799->12798/tcp, :::12799->12798/tcp cardano-node-testnet-1.34.1 169 | ``` 170 | 171 | You can also check the logs of the running cardano-node: 172 | 173 | ```bash 174 | docker logs -f {CONTAINER ID} 175 | ``` 176 | 177 | To exit the logs press `Ctrl+c` 178 | 179 | ## Stop/Restart/Delete the Docker Cardano node 180 | 181 | To stop the running Cardano node execute: 182 | 183 | ```bash 184 | docker stop {CONTAINER ID} 185 | ``` 186 | 187 | A stopped container can be started again with: 188 | 189 | ```bash 190 | docker start {CONTAINER ID} 191 | ``` 192 | 193 | A stopped container can also be deleted. Once deleted, it can not be started with the command above again. 194 | 195 | ```bash 196 | docker rm {CONTAINER ID} 197 | ``` 198 | 199 | If you like to start the node again, after having removed the docker container, just run the run-node.sh script. 200 | 201 | ```bash 202 | sudo ${HOME}/Cardano-node-docker/node/run-node.sh 203 | ``` 204 | 205 | ## Monitor the Docker Cardano node with gLiveView 206 | 207 | While the docker Cardano node is running, you can monitor its status with the tool gLiveView. 208 | 209 | ```bash 210 | docker exec -it {CONTAINER ID} /home/cardano/pi-pool/scripts/gLiveView.sh 211 | ``` 212 | 213 | ## Check the scheduled slots of the block production node 214 | 215 | Our Docker image contains the YaLL python script from [SNAKE pool](https://github.com/asnakep/YaLL.git). This tool allows to 216 | query the blockchain for the scheduled slots for your block production node. 217 | 218 | Before using the script, make sure that the right configurations are set in our shell script run-node.sh. Set the following variables: 219 | 220 | ```bash 221 | CN_POOL_ID="c3e7025ebae638e994c149e5703e82619b31897c9e1d64fc684f81c2" ## Your stake pool ID (for YaLL script) 222 | CN_POOL_TICKER="MINI1" ## Your pool ticker (for YaLL script) 223 | CN_VRF_SKEY_PATH="YaLL.vrf.skey" ## Name of the vrf.skey file. It must be located in the same directory as CN_KEY_PATH (for YaLL script) 224 | CN_KEY_PATH="/home/julienterrier/Cardano-node-docker/node/files/.keys" ## Path to the folder where the OP certificate and keys are stored on the host system 225 | ``` 226 | 227 | Start the YaLL.py script and follow the instructions on the terminal: 228 | 229 | ```bash 230 | docker exec -it {CONTAINER ID} python3 /home/cardano/pi-pool/scripts/YaLL/YaLL.py 231 | ``` 232 | 233 | # Run node in P2P (peer-to-peer) mode 234 | 235 | To run your node in the P2P mode, please follow the instructions from the [Armada-Alliance Docs page](https://armada-alliance.com/docs/stake-pool-guides/p2p-networking) 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | -------------------------------------------------------------------------------- /dockerfiles/armada-cn-arm64.dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 as builder 2 | 3 | ENV DEBIAN_FRONTEND=noninteractive 4 | 5 | RUN apt-get update \ 6 | && apt-get upgrade -y zip wget automake build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev \ 7 | zlib1g-dev make g++ tmux git jq curl libncursesw5 libtool autoconf llvm libnuma-dev xz-utils zstd 8 | 9 | WORKDIR /cardano-node 10 | 11 | ## Download latest cardano-cli, cardano-node tx-submit-service version static build 12 | 13 | RUN wget -O cardano-9_1_1-aarch64-static-musl-ghc_966.tar.zst \ 14 | https://github.com/armada-alliance/cardano-node-binaries/blob/main/static-binaries/cardano-9_1_1-aarch64-static-musl-ghc_966.tar.zst?raw=true \ 15 | && tar -I zstd -xvf cardano-9_1_1-aarch64-static-musl-ghc_966.tar.zst 16 | 17 | 18 | ## Install libsodium (needed for ScheduledBlocks.py) 19 | WORKDIR /build/libsodium 20 | RUN git clone https://github.com/input-output-hk/libsodium 21 | RUN cd libsodium && \ 22 | git checkout 66f017f1 && \ 23 | ./autogen.sh && ./configure && make && make install 24 | 25 | FROM ubuntu:22.04 26 | 27 | ENV DEBIAN_FRONTEND=noninteractive 28 | 29 | RUN apt-get update \ 30 | && apt-get upgrade -y curl wget zip netbase jq libnuma-dev lsof bc python3-pip git && \ 31 | rm -rf /var/lib/apt/lists/* 32 | 33 | ## Copy Libsodium refs from builder image 34 | COPY --from=builder /usr/local/lib /usr/local/lib 35 | 36 | ## Create node folders 37 | WORKDIR /home/cardano 38 | WORKDIR /home/cardano/.local/bin 39 | WORKDIR /home/cardano/pi-pool/files 40 | WORKDIR /home/cardano/pi-pool/scripts 41 | WORKDIR /home/cardano/pi-pool/logs 42 | WORKDIR /home/cardano/pi-pool/.keys 43 | WORKDIR /home/cardano/git 44 | WORKDIR /home/cardano/tmp 45 | 46 | COPY --from=builder /cardano-node/cardano-9_1_1-aarch64-static-musl-ghc_966/* /home/cardano/.local/bin/ 47 | 48 | WORKDIR /home/cardano/pi-pool/scripts 49 | COPY /files/run.sh /home/cardano/pi-pool/scripts 50 | RUN git clone https://github.com/asnakep/poolLeaderLogs.git 51 | RUN pip install -r /home/cardano/pi-pool/scripts/poolLeaderLogs/pip_requirements.txt 52 | 53 | ## Download gLiveView from original source 54 | RUN wget https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/env \ 55 | && wget https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/gLiveView.sh 56 | RUN chmod +x env 57 | RUN chmod +x gLiveView.sh 58 | 59 | ENV PATH="/home/cardano/.local/bin:$PATH" 60 | 61 | HEALTHCHECK --interval=10s --timeout=60s --start-period=300s --retries=3 CMD curl -f http://localhost:12798/metrics || exit 1 62 | 63 | STOPSIGNAL SIGINT 64 | 65 | COPY /files/tx-submit-service /home/cardano/.local/bin 66 | COPY /files/run.sh / 67 | 68 | CMD ["/run.sh"] -------------------------------------------------------------------------------- /dockerfiles/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -x 4 | 5 | ## Configuration paramenters 6 | 7 | CNVERSION="9.1.1" ## Version of the cardano-node. (Note: Must match the version downloaded in the dockerbuild file) 8 | 9 | CNCONT_NAME="armadaalliance" ## Define the name of your docker container 10 | 11 | 12 | ## Do not change the part here below 13 | ##---------------------------------- 14 | 15 | docker build -t ${CNCONT_NAME}/armada-cn:${CNVERSION} \ 16 | -f armada-cn-arm64.dockerfile . \ 17 | 2>&1 \ 18 | | tee /tmp/build.logs 19 | -------------------------------------------------------------------------------- /dockerfiles/files/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ##Initialize env settings for gLiveView 4 | sed -i 's+#CCLI="${HOME}/.cabal/bin/cardano-cli"+CCLI="/home/cardano/.local/bin/cardano-cli"+' env 5 | sed -i 's+#CNODE_PORT=6000+CNODE_PORT='${PORT}'+' env 6 | sed -i 's+#CONFIG="${CNODE_HOME}/files/config.json"+CONFIG="/home/cardano/pi-pool/files/'${NETWORK}'-config.json"+' env 7 | sed -i 's+#SOCKET="${CNODE_HOME}/sockets/node0.socket"+SOCKET="/home/cardano/pi-pool/db/node.socket"+' env 8 | sed -i 's+#TOPOLOGY="${CNODE_HOME}/files/topology.json"+TOPOLOGY="/home/cardano/pi-pool/files/'${NETWORK}'-topology.json"+' env 9 | sed -i 's+#LOG_DIR="${CNODE_HOME}/logs"+LOG_DIR="/home/cardano/pi-pool/logs"+' env 10 | sed -i 's+#DB_DIR="${CNODE_HOME}/db"+DB_DIR="/home/cardano/pi-pool/db"+' env 11 | sed -i 's+#UPDATE_CHECK="Y"+UPDATE_CHECK="N"+' env 12 | 13 | ##Initialize env settings for YaLL 14 | sed -i 's+PoolId = ""+PoolId = "'${POOLID}'"+' poolLeaderLogs/poolLeaderLogs.py 15 | sed -i 's+PoolTicker = ""+PoolTicker = "'${POOLTICKER}'"+' poolLeaderLogs/poolLeaderLogs.py 16 | sed -i 's+/vrf.skey+/home/cardano/pi-pool/.keys/'${SB_VRF_SKEY_PATH}'+' poolLeaderLogs/poolLeaderLogs.py 17 | 18 | exec tx-submit-service & 19 | 20 | ##Start cardano-node in relay mode 21 | if [ "${NODE_MODE}" = "relay" ]; then 22 | 23 | exec cardano-node ${CARDANO_RTS_OPTS} run \ 24 | --topology /home/cardano/pi-pool/files/${NETWORK}-topology.json \ 25 | --config /home/cardano/pi-pool/files/${NETWORK}-config.json \ 26 | --database-path /home/cardano/pi-pool/db \ 27 | --socket-path /home/cardano/pi-pool/db/node.socket \ 28 | --host-addr 0.0.0.0 \ 29 | --port ${PORT} 30 | 31 | ##Start cardano-node in block production mode 32 | elif [ "${NODE_MODE}" = "bp" ]; then 33 | 34 | exec cardano-node ${CARDANO_RTS_OPTS} run \ 35 | --topology /home/cardano/pi-pool/files/${NETWORK}-topology.json \ 36 | --config /home/cardano/pi-pool/files/${NETWORK}-config.json \ 37 | --database-path /home/cardano/pi-pool/db \ 38 | --socket-path /home/cardano/pi-pool/db/node.socket \ 39 | --host-addr 0.0.0.0 \ 40 | --port ${PORT} \ 41 | --shelley-kes-key /home/cardano/pi-pool/.keys/*.kes-*.skey \ 42 | --shelley-vrf-key /home/cardano/pi-pool/.keys/*.vrf.skey \ 43 | --shelley-operational-certificate /home/cardano/pi-pool/.keys/*.opcert 44 | 45 | fi 46 | 47 | -------------------------------------------------------------------------------- /dockerfiles/files/tx-submit-service: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cardano-submit-api \ 4 | --socket-path /home/cardano/pi-pool/db/node.socket \ 5 | --port 8090 \ 6 | --config /home/cardano/pi-pool/files/tx-submit-mainnet-config.yaml \ 7 | --listen-address 0.0.0.0 \ 8 | --mainnet 9 | -------------------------------------------------------------------------------- /node/run-node.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -x 4 | 5 | ##Configuration for relay and block producing node 6 | CNIMAGENAME="armadaalliance/armada-cn" ## Name of the Cardano docker image 7 | CNVERSION="9.1.1" ## Version of the cardano-node. It must match with the version of the docker image 8 | CNNETWORK="preprod" ## Use "mainnet" if connecting node to the mainnet 9 | CNMODE="relay" ## Use "bp" if you configure the node as block production node 10 | CNPORT="3001" ## Define the port of the node 11 | CNPROMETHEUS_PORT="12799" ## Define the port for the Prometheus metrics 12 | CN_CONFIG_PATH="/home/julienterrier/Cardano-node-docker/node/files" ## Path to the folder where the Cardano config files are stored on the host system 13 | CN_DB_PATH="/home/julienterrier/Cardano-node-docker/node/db" ## Path to the folder where the Cardano database (blockchain) will be stored on the host system 14 | CN_RTS_OPTS="+RTS -N2 -I0.1 -Iw3600 -A64m -AL128M -n4m -F1.1 -H3500M -O3500M -RTS" ## RTS optimization parameters 15 | CN_BF_ID="" ## Your blockfrost.io project ID (for ScheduledBlock script) 16 | CN_POOL_ID="" ## Your stake pool ID (for ScheduledBlock script) 17 | CN_POOL_TICKER="" ## Your pool ticker (for ScheduledBlock script) 18 | CN_VRF_SKEY_PATH="" ## Name of the vrf.skey file. It must be located in the same directory as CN_KEY_PATH (for ScheduledBlock script) 19 | CN_KEY_PATH="" ## Path to the folder where the OP certificate and keys are stored on the host system 20 | 21 | 22 | ##Do not edit/change section below! 23 | ##--------------------------------- 24 | docker run --detach \ 25 | --name=cardano-node-${CNNETWORK}-${CNVERSION} \ 26 | --restart=always \ 27 | -p ${CNPORT}:${CNPORT} \ 28 | -p ${CNPROMETHEUS_PORT}:12798 \ 29 | -p 8090:8090 \ 30 | -e NETWORK=${CNNETWORK} \ 31 | -e NODE_MODE=${CNMODE} \ 32 | -e PORT=${CNPORT} \ 33 | -e CARDANO_RTS_OPTS="${CN_RTS_OPTS}" \ 34 | -e BFID=${CN_BF_ID} \ 35 | -e POOLID=${CN_POOL_ID} \ 36 | -e POOLTICKER=${CN_POOL_TICKER} \ 37 | -e SB_VRF_SKEY_PATH=${CN_VRF_SKEY_PATH} \ 38 | -e CARDANO_NODE_SOCKET_PATH=/home/cardano/pi-pool/db/node.socket \ 39 | -v ${CN_CONFIG_PATH}:/home/cardano/pi-pool/files \ 40 | -v ${CN_DB_PATH}:/home/cardano/pi-pool/db \ 41 | -v ${CN_KEY_PATH}:/home/cardano/pi-pool/.keys \ 42 | ${CNIMAGENAME}:${CNVERSION} 43 | --------------------------------------------------------------------------------