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
However, any write operation — such as building or generating artifacts — resulted in permission errors:
EACCES: permission denied, mkdir '/home/ubuntu/cryptozombies/target'
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
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
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
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
On inspection, this path was not a directory but a symbolic link:
platform-tools -> /root/.cache/solana/v1.48/platform-tools
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
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:
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)