Skip to content

Commit

Permalink
docker: add support for persistent state builds with docker
Browse files Browse the repository at this point in the history
  • Loading branch information
d-sonuga committed Jan 21, 2025
1 parent 89a2db3 commit 37894ed
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 2 deletions.
File renamed without changes.
57 changes: 57 additions & 0 deletions Dockerfile.persistent
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# --- 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/*

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

# Features to include in the build
# E.g., --build-arg CARGO_FEATURES="archive"
ARG NODE_TYPE="provisioner"

RUN case "$NODE_TYPE" in \
"provisioner") cargo build --release -p rusk ;; \
"archive") cargo build --release --features archive -p rusk ;; \
"prover") cargo build --release --no-default-features --features prover -p 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/conf /opt/dusk/conf

RUN chmod +x /opt/dusk/setup.sh

CMD [ "./setup.sh" ]
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,17 +145,19 @@ make wasm for=transfer

## 🐳 Docker support

### Local Ephemeral Node

It's also possible to run a local ephemeral node with Docker.

To build the Docker image with archive:
```bash
docker build -t rusk .
docker build -f Dockerfile.ephemeral -t rusk .
```

To build the Docker image **without** archive:

```bash
docker build -t rusk --build-arg CARGO_FEATURES="" .
docker build -t -f Dockerfile.ephemeral rusk --build-arg CARGO_FEATURES="" .
```

To run Rusk inside a Docker container:
Expand All @@ -166,6 +168,26 @@ docker run -p 9000:9000/udp -p 8080:8080/tcp rusk

Port 9000 is used for Kadcast, port 8080 for the HTTP and GraphQL APIs.

### Persistent Node

To build the docker image for a provisioner
```bash
docker build -f Dockerfile.persistent -t rusk --build-arg NODE_TYPE=provisioner .
```

To build for an archiver or prover instead, build with NODE_TYPE=archive or NODE_TYPE=prover,
respectively.

To run:

```bash
docker run -it \
-v /path/to/consensus.keys:/opt/dusk/conf/consensus.keys
-v /path/to/rusk/profile:/opt/dusk/rusk \
-e NETWORK=testnet \
rusk
```

## License

The Rusk software is licensed under the [Mozilla Public License Version 2.0](./LICENSE).
56 changes: 56 additions & 0 deletions scripts/persistent-docker-setup/conf/rusk.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# log_type = 'coloured' (default)
# log_type = 'json'

# log_level = 'info' (default)
# log_filter = 'dusk_consensus=debug,node=debug,kadcast=debug'

[chain]
genesis_timestamp = ''
generation_timeout = '3s'
db_path = '/opt/dusk/rusk'
consensus_keys_path = '/opt/dusk/conf/consensus.keys'
min_gas_limit = 150_000
block_gas_limit = 3000000000

[databroker]
max_inv_entries = 100
max_ongoing_requests = 1000

[mempool]
max_queue_size = 5000
max_mempool_txn_count = 10000
idle_interval = '5m'
mempool_expiry = '30m'
mempool_download_redundancy = 5

[kadcast]
kadcast_id = 0x0
public_address = 'N/A'
listen_address = 'N/A'
bootstrapping_nodes = []
auto_propagate = false
channel_size = 10000
recursive_discovery = true

[kadcast.bucket]
node_ttl = '120s'
node_evict_after = '15s'
bucket_ttl = '10m'
min_peers = 20

[kadcast.network]
udp_recv_buffer_size = 5000000
# udp_send_backoff_timeout = '50us'
udp_send_retry_interval = '5ms'
udp_send_retry_count = 3
blocklist_refresh_interval = '10s'

[kadcast.fec.encoder]
min_repair_packets_per_block = 5
mtu = 1300
fec_redundancy = 0.15

[kadcast.fec.decoder]
cache_ttl = '1m'
cache_prune_every = '30s'
max_udp_len = 2097152
74 changes: 74 additions & 0 deletions scripts/persistent-docker-setup/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/bin/bash
set -e

echo "Starting node environment"

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

# Create genesis.toml
cat > /opt/dusk/conf/genesis.toml <<EOF
base_state = "$base_state"
EOF

# Update the rusk.toml file with kadcast_id, bootstrapping_nodes & genesis_timestamp
sed -i "s/^kadcast_id =.*/kadcast_id = $kadcast_id/" /opt/dusk/conf/rusk.toml
sed -i "s/^bootstrapping_nodes =.*/bootstrapping_nodes = $bootstrapping_nodes/" /opt/dusk/conf/rusk.toml
sed -i "s/^genesis_timestamp =.*/genesis_timestamp = $genesis_timestamp/" /opt/dusk/conf/rusk.toml
}

configure_network "$NETWORK"

PUBLIC_IP=$(curl -4 -s https://ifconfig.me)
if [ -z "$PUBLIC_IP" ]; then
PUBLIC_IP=$(curl -4 -s https://ipinfo.io/ip)
fi
export KADCAST_PUBLIC_ADDRESS="$PUBLIC_IP:9000"
export KADCAST_LISTEN_ADDRESS="$PUBLIC_IP:9000"

# Get consensus keys password
echo "Consensus keys password: "
read ckp
export DUSK_CONSENSUS_KEYS_PASS="$ckp"

echo "Selected network: $NETWORK"

/opt/dusk/bin/rusk recovery keys
/opt/dusk/bin/rusk recovery state

echo "Starting rusk"
/opt/dusk/bin/rusk --config /opt/dusk/conf/rusk.toml

0 comments on commit 37894ed

Please sign in to comment.