惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
L
LangChain Blog
aimingoo的专栏
aimingoo的专栏
IT之家
IT之家
B
Blog
博客园_首页
博客园 - 司徒正美
有赞技术团队
有赞技术团队
博客园 - 聂微东
I
InfoQ
美团技术团队
GbyAI
GbyAI
阮一峰的网络日志
阮一峰的网络日志
H
Help Net Security
大猫的无限游戏
大猫的无限游戏
MyScale Blog
MyScale Blog
WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
A
About on SuperTechFans
人人都是产品经理
人人都是产品经理
Microsoft Azure Blog
Microsoft Azure Blog
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
The Cloudflare Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Setting up Midnight on Windows via WSL2: The Complete Guide
Uroy Nwankwo · 2026-05-09 · via DEV Community

Midnight's toolchain runs natively on UNIX systems, Linux and macOS. If you're on Windows, you will need the Windows Subsystem for Linux 2 (WSL2).
This tutorial takes you from a fresh Windows machine to a working Midnight dev environment.

Target audience: Windows developers who want to build on the Midnight network.

Prerequisites:

  • Windows 10 (version 2004+) or Windows 11
  • Administrator access
  • stable internet connection.

What you'll have by the end: A winodws machine setup with a complete development environment for building on the midnight network.

You will set up WSL2, configure Docker Desktop, allocate enough memory for the proof server, install the Compact compiler, and verify everything by deploying the Hello World contract. It also shows which Windows approaches fail, so you can skip the dead ends.

What does not work on Windows

You cannot run the Midnight toolchain natively on Windows. The following approaches all fail:

  • PowerShell / Command Prompt: the Compact installer script is a POSIX shell script. It will not run.
  • Windows-native Node.js: even if you install Node.js for Windows, the Compact compiler and proof server depend on Linux binaries. They will not resolve correctly.
  • Git Bash / Cygwin: these are POSIX compatibility layers, not real Linux environments. The installer may appear to work, but it will produce broken PATH entries and missing binaries at runtime.

The supported Windows setup is WSL2 with a real Linux distribution. Everything after this point assumes you are inside a WSL2 terminal unless explicitly marked [Windows terminal].

Step 1: Install and configure WSL2

[Windows terminal: run PowerShell as Administrator]

wsl --install

Enter fullscreen mode Exit fullscreen mode

 PowerShell showing wsl --install progress plus the success or reboot prompt message.

This command installs WSL2 and downloads Ubuntu, which is the recommended distribution. Restart your machine when prompted.

After restart, open Ubuntu from the Start menu. The first launch completes the Ubuntu setup and asks you to create a Linux username and password. These credentials are for your WSL2 environment only. They do not need to match your Windows credentials.

Verify WSL2 is active:

wsl --list --verbose

Enter fullscreen mode Exit fullscreen mode

PowerShell showing Ubuntu with STATE set and VERSION 2 in the  raw `wsl --list --verbose` endraw  output

You should see Ubuntu listed with Version 2. If it shows Version 1, upgrade it:

wsl --set-version Ubuntu 2

Enter fullscreen mode Exit fullscreen mode

Step 2: Configure WSL2 memory with .wslconfig

This is the step the official docs miss. The Midnight proof server generates zero-knowledge proofs locally, which takes real memory. By default, WSL2 caps memory at 1 GB, so the proof server can run out of memory and crash without much explanation.

You need to create a .wslconfig file in your Windows user profile directory to raise this limit.

[Windows terminal]

Open Notepad (or any text editor) and create the file at C:\Users\<YourUsername>\.wslconfig:

# .wslconfig: WSL2 resource configuration
[wsl2]
memory=8GB          # Allocate 8 GB RAM to WSL2 (minimum 4 GB for proof server)
processors=4        # Number of CPU cores available to WSL2
swap=2GB            # Optional: virtual swap space
localhostForwarding=true

Enter fullscreen mode Exit fullscreen mode

C:\Users\<YourUsername>\.wslconfig open in Notepad with both the file path and config contents visible.

Save the file, then restart WSL2 from a Windows terminal:

wsl --shutdown

Enter fullscreen mode Exit fullscreen mode

Wait 10 seconds, then reopen your Ubuntu terminal. The new memory limit takes effect immediately.

Warning: The proof server can crash with less than 4 GB allocated. 8GB is the safer setting. If your machine has 16 GB of RAM or more, giving WSL2 8GB still leaves enough memory for Windows and a browser.

Step 3: Set up Docker Desktop with the WSL2 backend

The Midnight proof server runs as a Docker container. Docker Desktop must use the WSL2 backend. The Hyper-V backend does not give your WSL2 terminal access to Docker.

  1. Download and install Docker Desktop.
  2. During installation, select Use WSL2 instead of Hyper-V when prompted.
  3. After installation, open Docker Desktop and go to Settings → General. Confirm that Use the WSL2 based engine is checked.
  4. Go to Settings → Resources → WSL Integration. Enable integration for your Ubuntu distribution.
  5. Click Apply & Restart.

Docker Desktop Settings → General with  raw `Use the WSL2 based engine` endraw  checked.

 Docker Desktop Settings → Resources → WSL Integration with the Ubuntu distro toggle enabled.

Verify Docker is accessible from inside WSL2:

[WSL terminal]

docker --version

Enter fullscreen mode Exit fullscreen mode

You should see output like Docker version 26.x.x, build .... If you see command not found, Docker is not exposed inside WSL yet. Go back to item 4 in this section and make sure WSL integration is enabled for your Ubuntu distro.

Step 4: Install Node.js inside WSL2

The Midnight DApp tooling requires Node.js v22 or later. Install it inside WSL2 with nvm (Node Version Manager). That keeps the version under your user account and avoids sudo headaches.

[WSL terminal]

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

Enter fullscreen mode Exit fullscreen mode

Reload your shell:

source ~/.bashrc

Enter fullscreen mode Exit fullscreen mode

Install and activate Node.js v22:

nvm install 22
nvm use 22
node --version   # should output v22.x.x

Enter fullscreen mode Exit fullscreen mode

WSL terminal showing nvm use 22 and node --version returning a v22.x.x version.

Note: Do not install Node.js with apt for this workflow. Ubuntu's apt packages are usually older and do not meet the v22 requirement.

Step 5: Install the Compact compiler

[WSL terminal]

Run the official Compact installer:

curl --proto '=https' --tlsv1.2 -LsSf \
  https://github.com/midnightntwrk/compact/releases/latest/download/compact-installer.sh | sh

Enter fullscreen mode Exit fullscreen mode

The installer downloads the Compact binary and adds it to your PATH. Reload your shell config so the PATH change takes effect:

source ~/.bashrc
# or, if you use zsh:
source ~/.zshrc

Enter fullscreen mode Exit fullscreen mode

Verify the installation:

compact --version
compact compile --version
which compact

Enter fullscreen mode Exit fullscreen mode

WSL terminal showing successful output for compact --version, compact compile --version, and which compact

All three commands should return valid output. If compact: command not found appears, the PATH was not updated. Add it manually:

export PATH="$HOME/.compact/bin:$PATH"
echo 'export PATH="$HOME/.compact/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Enter fullscreen mode Exit fullscreen mode

Update to the latest compiler version:

compact update

Enter fullscreen mode Exit fullscreen mode

Warning: If compact update fails with:

Failed to spawn artifact extraction command
No such file or directory (os error 2)

your WSL environment is missing required system tools (for example unzip or tar). Install them before retrying:

sudo apt update
sudo apt install -y unzip tar gzip curl

Install a package manager

The Hello World example later in this tutorial uses yarn. Install it with npm:

npm install -g yarn

Enter fullscreen mode Exit fullscreen mode

Verify it installed:

yarn --version

Enter fullscreen mode Exit fullscreen mode

Note: yarn is optional. You can use npm or pnpm instead.
If you prefer a different package manager, substitute yarn commands
with your preferred equivalent throughout this tutorial
(e.g. npm install instead of yarn install, npm run env:up
instead of yarn env:up).

Step 6: Start the proof server

The proof server generates ZK proofs for your transactions. It runs as a Docker container on port 6300.

[WSL terminal]

Make sure Docker Desktop is running (check your Windows system tray for the Docker icon). Then start the proof server:

docker run -p 6300:6300 midnightntwrk/proof-server:8.0.3 midnight-proof-server -v

Enter fullscreen mode Exit fullscreen mode

This command occupies the terminal while the server runs. Open a second WSL2 terminal window for the next steps. You should see log output ending with something like:

 INFO actix_server::server: starting service: "actix-web-service-0.0.0.0:6300", 
 workers: 4, listening on: 0.0.0.0:6300

Enter fullscreen mode Exit fullscreen mode

WSL terminal with the proof server container running and the listening on: 0.0.0.0:6300 log visible.

That confirms the proof server is running and ready.

Tip: Keep the proof server terminal open while you work. If you close it, any compile or deploy step that needs ZK proofs will hang or fail.

Step 7: Install the Compact VS Code extension

Before opening any contract files, install the Compact VS Code
extension. It provides syntax highlighting and code snippet
completion for .compact files. Without it, VS Code treats
your contract as plain text.

[WSL terminal]

Download the VSIX package:

curl -L -o compact.vsix https://raw.githubusercontent.com/midnight-ntwrk/releases/gh-pages/artifacts/vscode-extension/compact-0.2.13/compact-0.2.13.vsix

Enter fullscreen mode Exit fullscreen mode

Install it in VS Code:

code --install-extension compact.vsix

Enter fullscreen mode Exit fullscreen mode

Alternatively, install it manually through the VS Code UI:

  1. Open VS Code
  2. Go to Extensions (Ctrl+Shift+X)
  3. Click the ... menu at the top right of the Extensions panel
  4. Select Install from VSIX...
  5. Navigate to and select the downloaded compact.vsix file

Verification: Open the Extensions panel and confirm
Compact Language Support appears in your installed extensions list.

VS Code Extensions panel showing the Compact Language Support extension installed

Step 8: Deploy the Hello World contract

With the proof server running, verify the full setup by cloning the Hello World example, compiling a Compact smart contract, and deploying it to a local Devnet.

Before cloning the example project, set up a working directory inside your WSL environment. A fresh Ubuntu install starts in your home directory, which is typically empty.

Check your current location:

ls

Enter fullscreen mode Exit fullscreen mode

If nothing meaningful appears, create a directory for your development work:

mkdir -p ~/dev
cd ~/dev

Enter fullscreen mode Exit fullscreen mode

The -p flag makes this safe to run:

  • It creates parent directories if they do not exist.
  • It does not fail if the directory already exists.

That means the command works on both fresh and existing setups.

Note: Keep your project inside WSL (for example ~/dev), not in the Windows filesystem (/mnt/c/...). Working in /mnt/c often causes slower file access, permission issues, and strange behavior with Node.js and Docker.

Confirm your location:

pwd

Enter fullscreen mode Exit fullscreen mode

You should see a path like:

/home/<your-username>/dev

Enter fullscreen mode Exit fullscreen mode

Now clone the Hello World example:

[WSL terminal: new window]

git clone https://github.com/midnightntwrk/example-hello-world.git
cd example-hello-world

Enter fullscreen mode Exit fullscreen mode

Fix the docker-compose.yml before running

The default docker-compose.yml in the Hello World repo has two
issues that can make yarn env:up fail on a fresh setup.
Open docker-compose.yml and find the proof-server service block.

It currently looks like this:

proof-server:
  image: 'midnightntwrk/proof-server:8.0.3'
  command: ['midnight-proof-server -v']
  ports:
    - '127.0.0.1:6300:6300'
  environment:
    RUST_BACKTRACE: 'full'
  healthcheck:
    test: ['CMD', 'curl', '-f', 'http://localhost:6300/version']
    interval: 10s
    timeout: 5s
    retries: 20
    start_period: 10s

Enter fullscreen mode Exit fullscreen mode

Replace it with:

proof-server:
  image: 'midnightntwrk/proof-server:8.0.3'
  command: ['midnight-proof-server', '-v']
  ports:
    - '127.0.0.1:6300:6300'
  environment:
    RUST_BACKTRACE: 'full'
  healthcheck:
    test: ['CMD-SHELL', 'echo > /dev/tcp/127.0.0.1/6300']
    interval: 10s
    timeout: 5s
    retries: 20
    start_period: 10s

Enter fullscreen mode Exit fullscreen mode

Two things changed:

  • command: the original passes the entire string as a single executable, which fails silently. The corrected version passes the flag as a separate argument as Docker expects.
  • healthcheck: the original uses curl to check if the server is ready, but the proof server image is a minimal production image and does not include curl. The replacement uses a TCP socket check via bash's built-in /dev/tcp, which works without any additional tools.

Note: These issues have been reported upstream. See
issue #16 and PR #17.
If the PR has merged by the time you read this, your file may
already have the corrected command. Only apply the changes that
differ from what you see.

Install dependencies:

yarn install

Enter fullscreen mode Exit fullscreen mode

Create the contract file:

touch contracts/hello-world.compact
code . # opens VS Code for the current working directory

Enter fullscreen mode Exit fullscreen mode

VS Code opened from WSL with  raw `contracts/hello-world.compact` endraw  visible and Compact syntax highlighting active

Open contracts/hello-world.compact in VS Code and paste the following:

pragma language_version >= 0.22;

export ledger message: Opaque<"string">;

export circuit storeMessage(newMessage: Opaque<"string">): [] {
  message = disclose(newMessage);
}

Enter fullscreen mode Exit fullscreen mode

A quick breakdown of what this contract does:

  • ledger message declares a public, persistent on-chain state variable that stores a string.
  • circuit storeMessage defines the logic to update that variable.
  • newMessage is a private input by default. The disclose() call marks it safe to write to public ledger state. Without it, the compiler rejects the assignment.

Compile the contract. The compact compile command expects paths
relative to the contracts/ directory, so navigate into it first:

cd contracts
compact compile hello-world.compact managed/hello-world.compact

Enter fullscreen mode Exit fullscreen mode

After compilation completes, navigate back to the project root
before running the next commands:

cd ..

Enter fullscreen mode Exit fullscreen mode

Expected output:

Compiling 1 circuits:
  circuit "storeMessage" (k=6, rows=26)

Enter fullscreen mode Exit fullscreen mode

WSL terminal showing the successful compact compile output with Compiling 1 circuits

This generates ZK circuits, proving and verifying keys, and TypeScript API bindings in the contracts/managed/ directory.

Start the local Devnet environment. The first run pulls the required Docker images. Run this in the project terminal while the proof server stays open in the other terminal:

yarn env:up

Enter fullscreen mode Exit fullscreen mode

In your second terminal, deploy and run the test:

yarn test:local

Enter fullscreen mode Exit fullscreen mode

A successful run looks like this:

[12:46:12.694] INFO: Wallet sync complete after 23 emissions
[12:46:12.703] INFO: Providers initialized. Ready to test
[12:46:32.347] INFO: Contract deployed at: bba6579743ae23b44301d4a9f8df30dbd5244d63a59d8fbc2c9fc7ea521a04f8

 ✓ Hello World Contract > Deploys the contract   19649ms
 ✓ Hello World Contract > Stores a message        18184ms

Enter fullscreen mode Exit fullscreen mode

Final success screenshot showing yarn test:local passing, including the deployed contract address and both passing checks.

Your Midnight dev environment is now working on Windows.

Troubleshooting

Proof server crashes or goes silent

Cause: WSL2 ran out of memory.

Fix: Open .wslconfig and increase the memory value (minimum 4GB, recommended 8GB). Shut down WSL2 with wsl --shutdown from a Windows terminal, then restart Ubuntu and rerun the proof server.

docker: command not found inside WSL

Cause: Docker Desktop's WSL2 integration is not enabled for your distro.

Fix: Open Docker Desktop → Settings → Resources → WSL Integration → enable your Ubuntu distro → Apply & Restart.

compact: command not found after installation

Cause: The PATH update was not applied to the current shell session.

Fix:

export PATH="$HOME/.compact/bin:$PATH"
echo 'export PATH="$HOME/.compact/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Enter fullscreen mode Exit fullscreen mode

compact update fails with “Failed to spawn artifact extraction command”

Cause: Missing system utilities (unzip, tar, etc.) in WSL.

Fix:

sudo apt update
sudo apt install -y unzip tar gzip curl

Enter fullscreen mode Exit fullscreen mode

Verify:

which unzip
which tar

Enter fullscreen mode Exit fullscreen mode

Retry:

compact update

Enter fullscreen mode Exit fullscreen mode

If it still fails:

rm -rf ~/.compact

Enter fullscreen mode Exit fullscreen mode

Then reinstall.

Port 6300 already in use

Cause: An earlier proof server container is still running.

Fix: Find and stop it:

docker ps
docker stop <container_id>

Enter fullscreen mode Exit fullscreen mode

Or run the proof server on an alternate port and update your app config to match:

docker run -p 6301:6300 midnightntwrk/proof-server:8.0.3 midnight-proof-server -v

Enter fullscreen mode Exit fullscreen mode

yarn test:local hangs indefinitely

Cause: The proof server is not running, or Docker is not accessible from WSL2.

Fix: Confirm the proof server terminal is active and showing the listening log. Confirm docker ps returns results from your WSL2 terminal. If Docker is not visible, re-check the WSL integration setting in Docker Desktop.

Working .wslconfig reference

Save this file at C:\Users\<YourUsername>\.wslconfig:

[wsl2]
# Memory: minimum 4GB for proof server, 8GB recommended
memory=8GB

# CPU cores available to WSL2
processors=4

# Optional swap space
swap=2GB

# Allow localhost forwarding between Windows and WSL2 (needed for Docker port access)
localhostForwarding=true

Enter fullscreen mode Exit fullscreen mode

After saving, always run wsl --shutdown from a Windows terminal and restart Ubuntu for changes to take effect.

Next steps

Your environment is configured and verified. Next:

If you find an outdated step, leave a comment or ask in the Midnight Discord. If you publish your own build notes, tag @midnightntwrk.