Skip to content

Docker Deployment

Relevant Source Files

This document covers the containerization and Docker deployment strategy for the SN106 validator system. It explains the multi-stage build process, container configuration, and deployment optimization techniques used to package the validator for production environments.

For general configuration setup, see Configuration. For validator operation details, see For Validators.

The SN106 validator uses a containerized deployment strategy based on Alpine Linux for minimal footprint and security. The container packages the validator engine along with all necessary dependencies for multi-chain data collection and weight submission.

graph TD
    subgraph "Build Context"
        PACKAGE["package.json<br/>Dependencies Definition"]
        TSCONFIG["tsconfig.json<br/>TypeScript Configuration"]
        SOURCE["Source Code<br/>validator/, utils/, config/"]
        DOCKERIGNORE[".dockerignore<br/>Build Exclusions"]
    end
    
    subgraph "Base Image"
        ALPINE["node:20-alpine<br/>Minimal Linux Runtime"]
    end
    
    subgraph "Build Layers"
        WORKDIR["/app<br/>Working Directory"]
        DEPS["npm install<br/>Dependency Installation"]
        CODE["Code Copy<br/>Application Files"]
        DIRS["mkdir logs data<br/>Runtime Directories"]
    end
    
    subgraph "Runtime Configuration"
        PORT["EXPOSE 3000<br/>Service Port"]
        CMD["npm run validator<br/>Entry Point"]
    end
    
    PACKAGE --> DEPS
    TSCONFIG --> DEPS
    SOURCE --> CODE
    DOCKERIGNORE --> CODE
    ALPINE --> WORKDIR
    WORKDIR --> DEPS
    DEPS --> CODE
    CODE --> DIRS
    DIRS --> PORT
    PORT --> CMD

The build process optimizes layer caching by copying dependency definitions before source code, ensuring rebuilds only occur when dependencies change.

Sources: Dockerfile:1-25 , .dockerignore:1-19

graph TD
    subgraph "Container Filesystem"
        APP["/app<br/>Application Root"]
        
        subgraph "Application Code"
            VALIDATOR["/app/validator/<br/>Validator Engine"]
            UTILS["/app/utils/<br/>Utility Functions"]
            CONFIG["/app/config/<br/>Configuration System"]
        end
        
        subgraph "Configuration Files"
            PACKAGE_JSON["/app/package.json<br/>NPM Dependencies"]
            TSCONFIG_JSON["/app/tsconfig.json<br/>TypeScript Config"]
        end
        
        subgraph "Runtime Directories"
            LOGS["/app/logs/<br/>Log Output"]
            DATA["/app/data/<br/>Runtime Data"]
        end
        
        subgraph "Excluded Files"
            NODE_MODULES["node_modules/<br/>Build Dependencies"]
            ENV_FILES[".env<br/>Environment Secrets"]
            TEST_FILES["*.test.ts<br/>Test Code"]
        end
    end
    
    APP --> VALIDATOR
    APP --> UTILS
    APP --> CONFIG
    APP --> PACKAGE_JSON
    APP --> TSCONFIG_JSON
    APP --> LOGS
    APP --> DATA

The container excludes development files, tests, and sensitive configuration through .dockerignore to minimize attack surface and image size.

Sources: Dockerfile:3-19 , .dockerignore:1-19

The Dockerfile implements a multi-layer build strategy optimized for development iteration and CI/CD pipelines:

Build StageFiles CopiedPurposeCache Behavior
Dependency Layerpackage.json, tsconfig.jsonInstall NPM dependenciesCached until dependencies change
Source Layervalidator/, utils/, config/Copy application codeInvalidated on code changes
Runtime LayerDirectory creationPrepare runtime environmentRarely changes

Sources: Dockerfile:5-17

Terminal window
# Build the container image
docker build -t sn106-validator .
# Build with custom tag
docker build -t sn106-validator:latest .

The build process follows these steps:

  1. Base Image Setup: Uses node:20-alpine for minimal footprint Dockerfile:1
  2. Working Directory: Sets /app as the application root Dockerfile:3
  3. Dependency Installation: Copies package files and runs npm install Dockerfile:5-11
  4. Source Code Copy: Transfers application code excluding test files Dockerfile:14-16
  5. Runtime Preparation: Creates log and data directories Dockerfile:19

Sources: Dockerfile:1-25

The container exposes port 3000 for potential monitoring or health check endpoints, though the primary validator operation communicates directly with blockchain networks.

graph LR
    subgraph "Container Runtime"
        VALIDATOR["npm run validator<br/>Main Process"]
        LOGS["/app/logs/<br/>Log Files"]
        DATA["/app/data/<br/>Runtime Data"]
    end
    
    subgraph "External Connections"
        SUBTENSOR["Subtensor WebSocket<br/>Weight Submission"]
        SOLANA["Solana RPC<br/>Data Collection"]
        ETHEREUM["Ethereum RPC<br/>Future Support"]
    end
    
    subgraph "Host System"
        PORT["Port 3000<br/>Exposed Service"]
        VOLUMES["Volume Mounts<br/>Persistent Storage"]
    end
    
    VALIDATOR --> SUBTENSOR
    VALIDATOR --> SOLANA
    VALIDATOR --> ETHEREUM
    VALIDATOR --> LOGS
    VALIDATOR --> DATA
    PORT --> VALIDATOR
    VOLUMES --> LOGS
    VOLUMES --> DATA

Sources: Dockerfile:22-25

The container inherits environment variables from the host system or orchestration platform. Key configuration includes:

  • Blockchain RPC Endpoints: Solana, Ethereum, Base connectivity
  • Validator Authentication: VALIDATOR_HOTKEY_URI for weight submission
  • Network Configuration: NETUID and subnet parameters

For complete environment variable documentation, see Configuration.

Sources: README.md:104-131

Terminal window
# Run with environment file
docker run -d \
--name sn106-validator \
--env-file .env \
-v $(pwd)/logs:/app/logs \
-v $(pwd)/data:/app/data \
-p 3000:3000 \
sn106-validator:latest

The container creates persistent directories for:

  • Logs: /app/logs/ - Validator operation logs and debugging output
  • Data: /app/data/ - Runtime data and weight history files

Mount these as volumes to persist data across container restarts.

Sources: Dockerfile:19

The .dockerignore file optimizes build performance and security by excluding:

  • node_modules/ - NPM dependencies (rebuilt in container)
  • Test files (*.test.js, *.test.ts, *.spec.js, *.spec.ts)
  • Coverage reports (coverage/)
  • Environment files (.env) - Provided at runtime
  • Log directories (logs/) - Created in container
  • Data directories (data/) - Created in container
  • Git metadata (.git/, .gitignore)
  • Documentation (README.md)
  • Docker configuration files

This exclusion strategy reduces build context size and prevents sensitive configuration from being embedded in the image.

Sources: .dockerignore:1-19

  • Base image uses Alpine Linux for minimal attack surface
  • No sensitive configuration embedded in image layers
  • Runtime secrets provided through environment variables
  • Minimal package installation reduces vulnerability exposure
  • Layer caching optimizes rebuild times during development
  • Multi-stage approach separates dependencies from source code
  • Excluded files reduce image size and build time
  • Alpine base provides fast container startup

The exposed port 3000 allows integration with container orchestration health checks and monitoring systems, though the validator primarily operates through direct blockchain connections.

Sources: Dockerfile:1-25, .dockerignore:1-19