#!/bin/bash # Info: Script to install Polkadot Node (Full, Light, Archive) # Author: Provisioning System # Release: 1.0 # Date: 2025-07-24 USAGE="install-polkadot-node.sh" [ "$1" == "-h" ] && echo "$USAGE" && exit 1 [ -r "env-polkadot-node" ] && . ./env-polkadot-node POLKADOT_VERSION=${POLKADOT_VERSION:-latest} POLKADOT_NODE_TYPE=${POLKADOT_NODE_TYPE:-full} POLKADOT_CHAIN=${POLKADOT_CHAIN:-polkadot} # Determine architecture ARCH="$(uname -m)" case $ARCH in x86_64) ARCH="x86_64" ;; aarch64) ARCH="aarch64" ;; *) echo "Unsupported architecture: $ARCH" && exit 1 ;; esac # Set download URL based on version if [ "$POLKADOT_VERSION" = "latest" ]; then POLKADOT_URL="https://github.com/paritytech/polkadot/releases/latest/download" POLKADOT_BINARY="polkadot" else POLKADOT_URL="https://github.com/paritytech/polkadot/releases/download/${POLKADOT_VERSION}" POLKADOT_BINARY="polkadot" fi POLKADOT_BIN_PATH=${POLKADOT_BIN_PATH:-/usr/local/bin/polkadot} POLKADOT_SYSTEMCTL_MODE=${POLKADOT_SYSTEMCTL_MODE:-enabled} POLKADOT_CONFIG_PATH=${POLKADOT_CONFIG_PATH:-/etc/polkadot} POLKADOT_WORK_PATH=${POLKADOT_WORK_PATH:-/var/lib/polkadot} POLKADOT_BASE_PATH=${POLKADOT_BASE_PATH:-/var/lib/polkadot/data} POLKADOT_RUN_USER=${POLKADOT_RUN_USER:-polkadot} POLKADOT_RUN_GROUP=${POLKADOT_RUN_GROUP:-polkadot} POLKADOT_RUN_USER_HOME=${POLKADOT_RUN_USER_HOME:-/home/polkadot} POLKADOT_NODE_NAME=${POLKADOT_NODE_NAME:-polkadot-node} POLKADOT_ARCHIVE_MODE=${POLKADOT_ARCHIVE_MODE:-false} echo "Installing Polkadot Node ${POLKADOT_VERSION} (${POLKADOT_NODE_TYPE})..." # Install dependencies echo "Installing dependencies..." if command -v apt-get >/dev/null 2>&1; then apt-get update apt-get install -y curl ca-certificates jq nginx certbot python3-certbot-nginx elif command -v yum >/dev/null 2>&1; then yum update -y yum install -y curl ca-certificates jq nginx certbot python3-certbot-nginx elif command -v dnf >/dev/null 2>&1; then dnf update -y dnf install -y curl ca-certificates jq nginx certbot python3-certbot-nginx else echo "Package manager not found. Please install dependencies manually." exit 1 fi # Create user and group if ! id "$POLKADOT_RUN_USER" &>/dev/null; then groupadd -r "$POLKADOT_RUN_GROUP" useradd -r -g "$POLKADOT_RUN_GROUP" -d "$POLKADOT_RUN_USER_HOME" -s /bin/bash -c "Polkadot service user" "$POLKADOT_RUN_USER" fi # Create directories mkdir -p "$POLKADOT_CONFIG_PATH" mkdir -p "$POLKADOT_WORK_PATH" mkdir -p "$POLKADOT_BASE_PATH" mkdir -p "$POLKADOT_RUN_USER_HOME" # Download and install Polkadot binary cd /tmp echo "Downloading Polkadot binary from ${POLKADOT_URL}/${POLKADOT_BINARY}..." curl -L -o polkadot "${POLKADOT_URL}/${POLKADOT_BINARY}" if [ ! -f "polkadot" ]; then echo "Failed to download Polkadot binary" exit 1 fi # Install binary chmod +x polkadot mv polkadot "$(dirname "$POLKADOT_BIN_PATH")/" # Generate node key if not exists if [ ! -f "$POLKADOT_CONFIG_PATH/node-key" ]; then echo "Generating node key..." "$POLKADOT_BIN_PATH" key generate-node-key --file "$POLKADOT_CONFIG_PATH/node-key" fi # Set ownership chown -R "$POLKADOT_RUN_USER:$POLKADOT_RUN_GROUP" "$POLKADOT_WORK_PATH" chown -R "$POLKADOT_RUN_USER:$POLKADOT_RUN_GROUP" "$POLKADOT_BASE_PATH" chown -R "$POLKADOT_RUN_USER:$POLKADOT_RUN_GROUP" "$POLKADOT_RUN_USER_HOME" chown -R "$POLKADOT_RUN_USER:$POLKADOT_RUN_GROUP" "$POLKADOT_CONFIG_PATH" # Build node arguments based on configuration NODE_ARGS="--chain $POLKADOT_CHAIN" NODE_ARGS="$NODE_ARGS --name $POLKADOT_NODE_NAME" NODE_ARGS="$NODE_ARGS --base-path $POLKADOT_BASE_PATH" # Configure node type and pruning case "$POLKADOT_NODE_TYPE" in "light") NODE_ARGS="$NODE_ARGS --light" ;; "full") if [ "$POLKADOT_ARCHIVE_MODE" = "true" ]; then NODE_ARGS="$NODE_ARGS --pruning archive" else # Use pruning settings if [ "${POLKADOT_PRUNING_ENABLED:-true}" = "true" ]; then NODE_ARGS="$NODE_ARGS --pruning ${POLKADOT_STATE_PRUNING:-256}" if [ -n "$POLKADOT_BLOCK_PRUNING" ]; then NODE_ARGS="$NODE_ARGS --blocks-pruning $POLKADOT_BLOCK_PRUNING" fi fi fi ;; "validator") NODE_ARGS="$NODE_ARGS --validator" if [ "$POLKADOT_ARCHIVE_MODE" != "true" ] && [ "${POLKADOT_PRUNING_ENABLED:-true}" = "true" ]; then NODE_ARGS="$NODE_ARGS --pruning ${POLKADOT_STATE_PRUNING:-256}" fi ;; esac # Network configuration NODE_ARGS="$NODE_ARGS --listen-addr ${POLKADOT_LISTEN_ADDR:-/ip4/0.0.0.0/tcp/30333}" if [ -n "$POLKADOT_PUBLIC_ADDR" ]; then NODE_ARGS="$NODE_ARGS --public-addr $POLKADOT_PUBLIC_ADDR" fi if [ -n "$POLKADOT_BOOTNODES" ]; then IFS=',' read -ra BOOTNODES <<< "$POLKADOT_BOOTNODES" for bootnode in "${BOOTNODES[@]}"; do NODE_ARGS="$NODE_ARGS --bootnode $bootnode" done fi if [ -n "$POLKADOT_RESERVED_NODES" ]; then IFS=',' read -ra RESERVED <<< "$POLKADOT_RESERVED_NODES" for reserved in "${RESERVED[@]}"; do NODE_ARGS="$NODE_ARGS --reserved-node $reserved" done fi if [ "${POLKADOT_RESERVED_ONLY:-false}" = "true" ]; then NODE_ARGS="$NODE_ARGS --reserved-only" fi # RPC configuration if [ "${POLKADOT_RPC_ENABLED:-true}" = "true" ]; then NODE_ARGS="$NODE_ARGS --rpc-bind-addr ${POLKADOT_RPC_BIND_ADDR:-127.0.0.1}" NODE_ARGS="$NODE_ARGS --rpc-port ${POLKADOT_RPC_PORT:-9944}" NODE_ARGS="$NODE_ARGS --rpc-cors ${POLKADOT_RPC_CORS:-all}" NODE_ARGS="$NODE_ARGS --rpc-methods ${POLKADOT_RPC_METHODS:-safe}" NODE_ARGS="$NODE_ARGS --rpc-max-connections ${POLKADOT_RPC_MAX_CONNECTIONS:-100}" fi # Performance settings NODE_ARGS="$NODE_ARGS --execution ${POLKADOT_EXECUTION:-wasm}" NODE_ARGS="$NODE_ARGS --wasm-execution ${POLKADOT_WASM_EXECUTION:-compiled}" NODE_ARGS="$NODE_ARGS --state-cache-size ${POLKADOT_STATE_CACHE_SIZE:-67108864}" NODE_ARGS="$NODE_ARGS --db-cache ${POLKADOT_DB_CACHE:-1024}" # Telemetry if [ "${POLKADOT_TELEMETRY_ENABLED:-true}" = "true" ]; then NODE_ARGS="$NODE_ARGS --telemetry-url '${POLKADOT_TELEMETRY_URL:-wss://telemetry.polkadot.io/submit/} ${POLKADOT_TELEMETRY_VERBOSITY:-0}'" fi # Sync mode case "${POLKADOT_SYNC_MODE:-warp}" in "full") NODE_ARGS="$NODE_ARGS --sync full" ;; "fast") NODE_ARGS="$NODE_ARGS --sync fast" ;; "warp") NODE_ARGS="$NODE_ARGS --sync warp" ;; esac # Logging NODE_ARGS="$NODE_ARGS --log ${POLKADOT_LOG_LEVEL:-info}" # Create systemd service file cat > /etc/systemd/system/polkadot-node.service << EOF [Unit] Description=Polkadot Node (${POLKADOT_NODE_TYPE}) Documentation=https://docs.polkadot.network/ After=network-online.target Wants=network-online.target [Service] Type=simple User=$POLKADOT_RUN_USER Group=$POLKADOT_RUN_GROUP Environment=RUST_LOG=${POLKADOT_LOG_LEVEL:-info} WorkingDirectory=$POLKADOT_WORK_PATH ExecStart=$POLKADOT_BIN_PATH $NODE_ARGS Restart=always RestartSec=10 # Security settings NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ReadWritePaths=$POLKADOT_WORK_PATH $POLKADOT_BASE_PATH $POLKADOT_CONFIG_PATH CapabilityBoundingSet=CAP_NET_BIND_SERVICE # Resource limits LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF # Setup WSS proxy if enabled if [ "${POLKADOT_WSS_ENABLED:-false}" = "true" ]; then echo "Setting up secure WebSocket proxy..." # Create nginx configuration for WSS cat > /etc/nginx/sites-available/polkadot-wss << EOF server { listen ${POLKADOT_WSS_PORT:-443} ssl http2; server_name ${POLKADOT_WSS_DOMAIN}; # SSL configuration ssl_certificate ${POLKADOT_SSL_CERT_FILE}; ssl_certificate_key ${POLKADOT_SSL_KEY_FILE}; # SSL settings ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; # Rate limiting limit_req_zone \$binary_remote_addr zone=wss_limit:10m rate=${POLKADOT_WSS_RATE_LIMIT:-100}r/m; limit_req zone=wss_limit burst=20 nodelay; location / { proxy_pass http://127.0.0.1:${POLKADOT_RPC_PORT:-9944}; proxy_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; # WebSocket specific proxy_read_timeout 86400; proxy_send_timeout 86400; } } EOF # Enable site ln -sf /etc/nginx/sites-available/polkadot-wss /etc/nginx/sites-enabled/ # Test nginx configuration nginx -t && systemctl restart nginx fi # Enable and start service systemctl daemon-reload systemctl "$POLKADOT_SYSTEMCTL_MODE" polkadot-node.service if [ "$POLKADOT_SYSTEMCTL_MODE" = "enabled" ]; then systemctl start polkadot-node.service # Wait a moment for service to start sleep 5 fi echo "Polkadot Node installation completed!" echo "Service: polkadot-node.service" echo "Node type: $POLKADOT_NODE_TYPE" echo "Chain: $POLKADOT_CHAIN" echo "Archive mode: $POLKADOT_ARCHIVE_MODE" echo "RPC endpoint: ws://${POLKADOT_RPC_BIND_ADDR:-127.0.0.1}:${POLKADOT_RPC_PORT:-9944}" if [ "${POLKADOT_WSS_ENABLED:-false}" = "true" ]; then echo "WSS endpoint: wss://${POLKADOT_WSS_DOMAIN}:${POLKADOT_WSS_PORT:-443}" fi echo "Configuration: $POLKADOT_CONFIG_PATH/" echo "Data directory: $POLKADOT_BASE_PATH" echo "Node key: $POLKADOT_CONFIG_PATH/node-key" # Display service status if systemctl is-active --quiet polkadot-node.service; then echo "✅ Polkadot node service is running" else echo "⚠️ Polkadot node service status:" systemctl status polkadot-node.service --no-pager -l fi # Cleanup cd / rm -rf /tmp/polkadot