DEV Community

Rad Code
Rad Code

Posted on • Originally published at heyradcode.hashnode.dev

How to Build a Persistent Solana Docker Dev Setup (No WSL!)

Chapter 1 — The Goal

The objective was to create a reliable, persistent Solana development environment that runs natively on Windows, without depending on the Windows Subsystem for Linux (WSL).

While WSL can be useful, it often introduces file system latency, permission inconsistencies, and integration issues with Docker Desktop. The goal was to achieve a seamless workflow using Docker alone — fully isolated, reproducible, and stable.

This setup is now part of the do-not-stop project — a long-term initiative to define a consistent, modern development standard for Web3.

The project aims to demonstrate how ecosystems such as Ethereum, Solana, and eventually Cardano can coexist within a unified, practical environment that supports real-world development workflows.


Chapter 2 — The Starting Point

The foundation came from the tchambard/solana-test-validator image — a prebuilt Solana development image that includes:

  • Solana CLI
  • Rust toolchain
  • A fully functional solana-test-validator

Credit goes to @tchambard for providing this image. It’s lightweight, well-prepared, and an excellent baseline for any Solana development workflow.

Initially, the idea was to isolate responsibilities across multiple Docker services — one for the validator, another for Solana CLI, and perhaps a third for project logic. However, Solana’s toolchain and CLI are tightly coupled. Separating them would introduce unnecessary complexity, requiring multiple shared volumes and synchronized builds.

Consolidating everything into a single service proved more effective. It ensured that the validator, CLI, and supporting dependencies operated in a consistent and predictable environment.


Chapter 3 — The Permission Model

The first issue encountered involved filesystem permissions when working with bind mounts from Windows.

The container was configured to mount the project source:

- ./cryptozombies:/home/ubuntu/cryptozombies
Enter fullscreen mode Exit fullscreen mode

However, any write operation — such as building or generating artifacts — resulted in permission errors:

EACCES: permission denied, mkdir '/home/ubuntu/cryptozombies/target'
Enter fullscreen mode Exit fullscreen mode

This occurs because NTFS-based volumes mounted through Docker Desktop are owned by the root user inside the Linux container. The default ubuntu user inside the image lacks write privileges for these mounts.

The solution was straightforward and justified:

user: root
Enter fullscreen mode Exit fullscreen mode

Running as root allowed the container to write to bind-mounted directories, resolving the issue without introducing unsafe behavior.

This is not a workaround — it is the correct approach when dealing with Docker bind mounts on Windows, where file ownership cannot be translated directly from the host.

After this change, the environment functioned as expected. Builds, validator logs, and temporary files all wrote correctly to the mounted project directory.


Chapter 4 — The Platform Tools Discovery

The next challenge appeared when repeatedly running Solana commands inside the container.

Each time solana-test-validator or a build was executed, Solana re-downloaded large SDK archives such as:

tmp-platform-tools-linux-x86_64.tar.bz2
Enter fullscreen mode Exit fullscreen mode

The downloads were redundant. Even after adding a named volume to persist Solana’s installation directory, the issue persisted.

- solana-install:/home/ubuntu/.local/share/solana/install
Enter fullscreen mode Exit fullscreen mode

This volume behaved as expected: Docker seeded it with the Solana CLI that already existed inside the base image. The CLI itself worked correctly after each restart — a clear sign that the seeding process was functioning as intended.

However, the platform toolchain and SDK assets continued to be re-downloaded on every startup.

To understand why, the next step was to trace the actual file paths used by Solana during installation.

Inside the install directory, the following path appeared:

/home/ubuntu/.local/share/solana/install/releases/2.3.7/solana-release/bin/platform-tools-sdk/sbf/dependencies/platform-tools
Enter fullscreen mode Exit fullscreen mode

On inspection, this path was not a directory but a symbolic link:

platform-tools -> /root/.cache/solana/v1.48/platform-tools
Enter fullscreen mode Exit fullscreen mode

This detail was critical.

While the main Solana binaries lived under the persisted install directory, the SDK and toolchains were stored separately under /root/.cache/solana.

Because /root/.cache was not mounted as a volume, it was cleared each time the container restarted. As a result, the symbolic link pointed to a non-existent path, prompting Solana to re-download all dependencies.

The resolution was simple:

- solana-cache:/root/.cache/solana
Enter fullscreen mode Exit fullscreen mode

This ensured that Solana’s cached SDKs and platform-tools persisted across restarts, eliminating unnecessary downloads and improving startup performance dramatically.


Chapter 5 — The Final Configuration

Below is the finalized Docker Compose configuration that encapsulates the complete solution:

services:
  solana-dev:
    image: tchambard/solana-test-validator:latest
    container_name: solana-dev
    user: root
    ports:
      - "8899:8899"
      - "8900:8900"
      - "9900:9900"
    volumes:
      - ./cryptozombies:/home/ubuntu/cryptozombies
      - solana-cache:/root/.cache/solana
    working_dir: /home/ubuntu
    command: >
      sh -c "
        solana-test-validator --reset --rpc-port 8899 --bind-address 0.0.0.0 &
        sleep 10 &&
        tail -f /dev/null
      "
    environment:
      - RUST_LOG=warn
      - TMPDIR=/tmp
    networks:
      - solana-network
    healthcheck:
      test: [ "CMD", "curl", "-f", "http://localhost:8899/health" ]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 30s

networks:
  solana-network:
    driver: bridge

volumes:
  solana-cache:
Enter fullscreen mode Exit fullscreen mode

This configuration delivers a self-contained Solana development environment with persistent volumes for both the Solana installation and its cached toolchain. It’s efficient, reproducible, and compatible with Docker Desktop on Windows without WSL.


Chapter 6 — The Broader Vision

This setup now serves as part of the do-not-stop project — a practical foundation for cross-chain Web3 development.

The goal is to provide developers with a consistent environment that supports multiple blockchain ecosystems simultaneously, ensuring that:

  • Toolchains remain stable and cached between runs.
  • Source code is editable directly from the host machine.
  • Builds and validators execute identically across operating systems.

This approach promotes a unified development experience that reduces friction and eliminates environment drift.


Key Takeaways

  • WSL is not required. Docker Desktop provides sufficient isolation for Windows-based Solana development.
  • Running as root is the correct approach for handling NTFS-mounted volumes.
  • Persist both:
    • /home/ubuntu/.local/share/solana/install (Solana CLI)
    • /root/.cache/solana (SDKs and platform-tools)
  • Docker’s named volume seeding ensures that existing image content is copied into new volumes on first run.

Conclusion

This setup represents a methodical exploration of how Solana’s toolchain interacts with Docker under Windows.

By identifying the symbolic link to /root/.cache/solana and ensuring that both the installation and cache directories are persisted, the environment achieves complete reproducibility and fast startup times.

The resulting configuration is stable, efficient, and ready to serve as a reference for modern Web3 developers.

It’s one step toward the broader goal of do-not-stop — establishing clear, reliable examples of how Web3 infrastructure should be built.

Top comments (0)