-
Notifications
You must be signed in to change notification settings - Fork 62
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 #3402 from dusk-network/persistent-docker-build
docker: add support for persistent state builds with docker
- Loading branch information
Showing
5 changed files
with
293 additions
and
2 deletions.
There are no files selected for viewing
File renamed without changes.
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,59 @@ | ||
# --- Build stage --- | ||
FROM ubuntu:24.04 AS build-stage | ||
|
||
RUN apt-get update && apt-get install -y unzip curl build-essential openssl libssl-dev pkg-config && rm -rf /var/lib/apt/lists/* | ||
|
||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y | ||
|
||
WORKDIR /opt/rusk | ||
ENV RUSK_PROFILE_PATH=/opt/dusk/rusk/ | ||
ENV PATH="$PATH:/root/.cargo/bin" | ||
|
||
RUN apt-get update && apt-get install -y clang && rm -rf /var/lib/apt/lists/* | ||
|
||
# Using this to modify rusk config file before running a node | ||
RUN cargo install toml-cli --version 0.2.3 | ||
|
||
COPY . . | ||
|
||
ARG TARGETPLATFORM | ||
# See also https://github.com/docker/buildx/issues/510 | ||
ENV TARGETPLATFORM=${TARGETPLATFORM:-linux/amd64} | ||
|
||
# Generate keys and compile genesis contracts | ||
RUN make keys | ||
RUN make wasm | ||
|
||
ARG NODE_TYPE="provisioner" | ||
|
||
RUN case "$NODE_TYPE" in \ | ||
"provisioner") cargo build --release -p dusk-rusk ;; \ | ||
"archive") cargo build --release --features archive -p dusk-rusk ;; \ | ||
"prover") cargo build --release --no-default-features --features prover -p dusk-rusk ;; \ | ||
*) echo "Unrecognized node type: $NODE_TYPE. Expected one of 'provisioner', 'archive' and 'prover'"; exit 1 ;; \ | ||
esac | ||
|
||
# --- Run stage --- | ||
FROM ubuntu:24.04 AS run-stage | ||
|
||
RUN apt-get update && apt-get install -y unzip curl net-tools libssl-dev && rm -rf /var/lib/apt/lists/* | ||
|
||
WORKDIR /opt/dusk | ||
|
||
ENV RUSK_PROFILE_PATH=/opt/dusk/rusk | ||
ENV RUSK_RECOVERY_INPUT=/opt/dusk/conf/genesis.toml | ||
ENV RUST_BACKTRACE=full | ||
ENV NETWORK=mainnet | ||
|
||
EXPOSE 9000/udp | ||
EXPOSE 8080/tcp | ||
|
||
# Copy only the necessary files from the build stage | ||
COPY --from=build-stage /opt/rusk/target/release/rusk /opt/dusk/bin/rusk | ||
COPY --from=build-stage /opt/rusk/scripts/persistent-docker-setup/setup.sh /opt/dusk/setup.sh | ||
COPY --from=build-stage /opt/rusk/scripts/persistent-docker-setup/detect_ips.sh /opt/dusk/detect_ips.sh | ||
COPY --from=build-stage /root/.cargo/bin/toml /usr/bin/toml-cli | ||
|
||
RUN chmod +x /opt/dusk/setup.sh /opt/dusk/detect_ips.sh | ||
|
||
CMD [ "./setup.sh" ] |
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
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,56 @@ | ||
#!/bin/bash | ||
|
||
# Script for detecting IP addresses in the persistent state Docker container. | ||
|
||
# Fetch IPv4 WAN address using ifconfig.me, fallback to ipinfo.io | ||
PUBLIC_IP=$(curl -4 -s https://ifconfig.me) | ||
if [ -z "$PUBLIC_IP" ]; then | ||
PUBLIC_IP=$(curl -4 -s https://ipinfo.io/ip) | ||
fi | ||
|
||
# Validate IPv4 address | ||
if [[ -z "$PUBLIC_IP" || ! "$PUBLIC_IP" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then | ||
echo "Error: Unable to retrieve a valid WAN IPv4 address" | ||
exit 1 | ||
fi | ||
|
||
runOnMac=false | ||
int2ip() { printf ${2+-v} $2 "%d.%d.%d.%d" \ | ||
$(($1>>24)) $(($1>>16&255)) $(($1>>8&255)) $(($1&255)) ;} | ||
ip2int() { local _a=(${1//./ }) ; printf ${2+-v} $2 "%u" $(( _a<<24 | | ||
${_a[1]} << 16 | ${_a[2]} << 8 | ${_a[3]} )) ;} | ||
while IFS=$' :\t\r\n' read a b c d; do | ||
[ "$a" = "usage" ] && [ "$b" = "route" ] && runOnMac=true | ||
if $runOnMac ;then | ||
case $a in | ||
gateway ) gWay=$b ;; | ||
interface ) iFace=$b ;; | ||
esac | ||
else | ||
[ "$a" = "0.0.0.0" ] && [ "$c" = "$a" ] && iFace=${d##* } gWay=$b | ||
fi | ||
done < <(/sbin/route -n 2>&1 || /sbin/route -n get 0.0.0.0/0) | ||
ip2int $gWay gw | ||
while read lhs rhs; do | ||
[ "$lhs" ] && { | ||
[ -z "${lhs#*:}" ] && iface=${lhs%:} | ||
[ "$lhs" = "inet" ] && [ "$iface" = "$iFace" ] && { | ||
mask=${rhs#*netmask } | ||
mask=${mask%% *} | ||
[ "$mask" ] && [ -z "${mask%0x*}" ] && | ||
printf -v mask %u $mask || | ||
ip2int $mask mask | ||
ip2int ${rhs%% *} ip | ||
(( ( ip & mask ) == ( gw & mask ) )) && | ||
int2ip $ip myIp && int2ip $mask netMask | ||
} | ||
} | ||
done < <(/sbin/ifconfig) | ||
|
||
echo "$PUBLIC_IP" | ||
if [ -z "$myIp" ]; then | ||
echo "$PUBLIC_IP" | ||
else | ||
echo "$myIp" | ||
fi | ||
|
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,113 @@ | ||
#!/bin/bash | ||
set -e | ||
|
||
# Script for setting up a node in the persistent state Docker container. | ||
# | ||
# It detects the IP addresses for the node, generates a configuration file for | ||
# the node based on the default `rusk.toml` used in the dusk-node-installer (or | ||
# a user-supplied configuration file which can be provided by mounting at | ||
# `/opt/dusk/conf/rusk.template.toml`), and runs the node. | ||
|
||
echo "Starting node environment" | ||
|
||
RUSK_CONFIG_DIR=/opt/dusk/conf | ||
RUSK_TEMPLATE_CONFIG_PATH="$RUSK_CONFIG_DIR/rusk.template.toml" | ||
RUSK_CONFIG_PATH="$RUSK_CONFIG_DIR/rusk.toml" | ||
|
||
detect_ips_output=$(./detect_ips.sh) | ||
PUBLIC_IP=$(echo "$detect_ips_output" | sed -n '1p') | ||
LISTEN_IP=$(echo "$detect_ips_output" | sed -n '2p') | ||
|
||
toml_set() { | ||
file=$1 | ||
property=$2 | ||
value=$3 | ||
|
||
echo -e "$(toml-cli set $file $property $value)" > $file | ||
} | ||
|
||
configure_network() { | ||
local network=$1 | ||
local kadcast_id | ||
local bootstrapping_nodes | ||
local genesis_timestamp | ||
local base_state | ||
local prover_url | ||
|
||
case "$network" in | ||
mainnet) | ||
kadcast_id="0x1" | ||
bootstrapping_nodes="['165.232.91.113:9000', '64.226.105.70:9000', '137.184.232.115:9000']" | ||
genesis_timestamp="'2025-01-07T12:00:00Z'" | ||
base_state="https://nodes.dusk.network/genesis-state" | ||
prover_url="https://provers.dusk.network" | ||
;; | ||
testnet) | ||
kadcast_id="0x2" | ||
bootstrapping_nodes="['134.122.62.88:9000','165.232.64.16:9000','137.184.118.43:9000']" | ||
genesis_timestamp="'2024-12-23T17:00:00Z'" | ||
base_state="https://testnet.nodes.dusk.network/genesis-state" | ||
prover_url="https://testnet.provers.dusk.network" | ||
;; | ||
devnet) | ||
kadcast_id="0x3" | ||
bootstrapping_nodes="['128.199.32.54', '159.223.29.22', '143.198.225.158']" | ||
genesis_timestamp="'2024-12-23T12:00:00Z'" | ||
base_state="https://devnet.nodes.dusk.network/genesis-state" | ||
prover_url="https://devnet.provers.dusk.network" | ||
;; | ||
*) | ||
echo "Unknown network: $network. Defaulting to mainnet." | ||
configure_network "mainnet" | ||
return | ||
;; | ||
esac | ||
|
||
echo "Generating configuration" | ||
|
||
cat > "$RUSK_CONFIG_DIR/genesis.toml" <<EOF | ||
base_state = "$base_state" | ||
EOF | ||
|
||
cp "$RUSK_TEMPLATE_CONFIG_PATH" "$RUSK_CONFIG_PATH" | ||
sed -i "s/^kadcast_id =.*/kadcast_id = $kadcast_id/" "$RUSK_CONFIG_PATH" | ||
sed -i "s/^bootstrapping_nodes =.*/bootstrapping_nodes = $bootstrapping_nodes/" "$RUSK_CONFIG_PATH" | ||
sed -i "s/^genesis_timestamp =.*/genesis_timestamp = $genesis_timestamp/" "$RUSK_CONFIG_PATH" | ||
toml_set "$RUSK_CONFIG_PATH" kadcast.public_address "$PUBLIC_IP:9000" | ||
toml_set "$RUSK_CONFIG_PATH" kadcast.listen_address "$LISTEN_IP:9000" | ||
if toml-cli get "$RUSK_CONFIG_PATH" http &> /dev/null; then | ||
toml_set "$RUSK_CONFIG_PATH" http.listen_address "$LISTEN_IP:8080" | ||
fi | ||
} | ||
|
||
download_rusk_config() { | ||
echo "Downloading default template rusk config from the dusk node installer" | ||
REMOTE_LOCATION=https://raw.githubusercontent.com/dusk-network/node-installer/9cdf0be1372ca6cb52cb279bd58781a3a27bf8ae/conf/rusk.toml | ||
mkdir -p "$RUSK_CONFIG_DIR" | ||
curl -o "$RUSK_TEMPLATE_CONFIG_PATH" "$REMOTE_LOCATION" | ||
if [ "$(cat $RUSK_TEMPLATE_CONFIG_PATH)" = "404: Not Found" ]; then | ||
echo "Couldn't find the default rusk template config file. This is a bug, please file an issue." | ||
exit 1 | ||
fi | ||
} | ||
|
||
if [ ! -f "$RUSK_TEMPLATE_CONFIG_PATH" ]; then | ||
download_rusk_config | ||
fi | ||
|
||
configure_network "$NETWORK" | ||
|
||
if [ -z "$DUSK_CONSENSUS_KEYS_PASS" ]; then | ||
echo "DUSK_CONSENSUS_KEYS_PASS is not set" | ||
exit 1 | ||
fi | ||
|
||
echo "Selected network: $NETWORK" | ||
|
||
/opt/dusk/bin/rusk recovery keys | ||
/opt/dusk/bin/rusk recovery state | ||
|
||
echo "Starting rusk" | ||
echo "Rusk config:" | ||
cat "$RUSK_CONFIG_PATH" | ||
/opt/dusk/bin/rusk --config "$RUSK_CONFIG_PATH" |