A Vagrant provider plugin for managing WSL2 distributions on Windows.
- Create and manage WSL2 distributions through Vagrant
- Full snapshot support (save, restore, list, delete)
- Support for WSL2 configuration (memory, CPU, version)
- Integration with Vagrant's standard workflow
- Cross-platform compatible (Windows-focused)
Install the plugin using:
vagrant plugin install vagrant-wsl2-providerOr install from source:
git clone https://github.com/LeeShan87/vagrant-wsl2-provider.git
cd vagrant-wsl2-provider
gem build vagrant-wsl2-provider.gemspec
vagrant plugin install vagrant-wsl2-provider-0.4.0.gem
# Or
rake install_localCreate a Vagrantfile with the WSL2 provider:
Vagrant.configure("2") do |config|
config.vm.box = "Ubuntu" # Or any WSL2-compatible box
config.vm.provider "wsl2" do |wsl|
wsl.distribution_name = "my-dev-env"
wsl.version = 2
wsl.gui_support = true
end
endThen run:
vagrant up --provider=wsl2vagrant up- Create and start the WSL2 distributionvagrant halt- Stop the WSL2 distributionvagrant destroy- Remove the WSL2 distributionvagrant ssh- Connect to the distribution (interactive shell)vagrant ssh -c "command"- Execute a single command and return outputvagrant provision- Run provisionersvagrant reload- Restart the distribution
Example:
vagrant ssh -c "uname -a"
vagrant ssh -c "cat /etc/os-release"The WSL2 provider fully supports Vagrant's snapshot functionality:
# List all snapshots
vagrant snapshot list
# Save a snapshot
vagrant snapshot save <name>
# Restore a snapshot
vagrant snapshot restore <name>
# Delete a snapshot
vagrant snapshot delete <name>
# Quick save (auto-generated name)
vagrant snapshot push
# Quick restore last pushed snapshot
vagrant snapshot popExample workflow:
# Save current state before experimenting
vagrant snapshot save clean-install
# Make changes, install packages, etc.
# ...
# Restore to clean state if something breaks
vagrant snapshot restore clean-install
# Delete snapshot when no longer needed
vagrant snapshot delete clean-installSnapshots are stored as .tar files in .vagrant/machines/{name}/wsl2/snapshots/ and contain the complete distribution state.
distribution_name: Name of the WSL2 distribution (default: auto-generated)version: WSL version (1 or 2, default: 2)memory: Memory limit in MB (default: 4096)cpus: Number of CPUs (default: 2)gui_support: Enable WSLg GUI support (default: false)
- Windows 10/11 with WSL2 enabled
- Vagrant 2.2+
- WSL2 kernel installed
After checking out the repo, run:
bundle install
rake install_local # Build and install pluginIntegration tests use Pester 5.x, a PowerShell testing framework.
Prerequisites:
- PowerShell 5.1+ or PowerShell Core 7+
- Pester 5.x (5.0 - 5.7.1, not 6.x alpha)
Install Pester:
Install-Module -Name Pester -RequiredVersion 5.7.1 -Force -Scope CurrentUserOr let Rake handle it automatically:
rake ensure_pester # Check and install Pester if neededRun tests:
# Run all integration tests (auto-checks Pester)
rake test
# Ensure Pester is installed first
rake ensure_pester
# Run individual tests
rake test_basic
rake test_snapshot
rake test_data_disk
rake test_networking
rake test_multi_vm_networkSee test/integration/README.md for more details.
Example configurations are in the examples/ directory:
basic/- Minimal configurationsnapshot/- Snapshot functionality demoprovisioners/- Multiple provisioner examplesdocker-test/- Docker with systemdtest-distros/- Various Linux distributions
See examples/README.md for usage.
For active development, you can create junction points to your working directory so changes are immediately reflected without reinstalling the plugin:
# First, install the plugin once
gem build vagrant-wsl2-provider.gemspec
vagrant plugin install vagrant-wsl2-provider-0.1.0.gem
# Remove the installed lib and locales directories
rmdir "C:\Users\YourUsername\.vagrant.d\gems\3.1.3\gems\vagrant-wsl2-provider-0.1.0\lib"
rmdir "C:\Users\YourUsername\.vagrant.d\gems\3.1.3\gems\vagrant-wsl2-provider-0.1.0\locales"
# Create junction points to your development directories (no admin rights required)
mklink /J "C:\Users\YourUsername\.vagrant.d\gems\3.1.3\gems\vagrant-wsl2-provider-0.1.0\lib" "D:\Code\Github\vagrant-wsl2-provider\lib"
mklink /J "C:\Users\YourUsername\.vagrant.d\gems\3.1.3\gems\vagrant-wsl2-provider-0.1.0\locales" "D:\Code\Github\vagrant-wsl2-provider\locales"Now any changes to lib/ or locales/ in your working directory are immediately visible to Vagrant without reinstalling.
Clean up all WSL distributions (useful for testing):
wsl -l | Select-String -Pattern '\S' | ForEach-Object { $name = $_.Line -replace '\*', '' -replace '\s*\(.*\)', '' -replace '\0', ''; if ($name.Trim()) { wsl --unregister $name.Trim() } }Warning: This removes ALL WSL distributions on your system. Use with caution!
Remove vagrant prefixed distributions only:
wsl -l | Select-String -Pattern '\S' | ForEach-Object { $name = $_.Line -replace '\*', '' -replace '\s*\(.*\)', '' -replace '\0', ''; if ($name.Trim() -like 'vagrant-*') { wsl --unregister $name.Trim() } }WSL2 does not support per-distribution CPU and memory limits.
Reference: Microsoft WSL Issue #8570
The memory and cpus configuration options in the Vagrantfile currently do nothing because:
- CPU/memory limits in WSL2 are configured globally in
%USERPROFILE%\.wslconfig - These limits apply to ALL WSL2 distributions simultaneously
- Microsoft has not implemented per-distribution resource limits
config.vm.provider "wsl2" do |wsl|
wsl.memory = 2048 # Currently has no effect
wsl.cpus = 2 # Currently has no effect
endWorkaround: Manually configure global limits in %USERPROFILE%\.wslconfig:
[wsl2]
memory=4GB
processors=2This affects all WSL2 distributions including Docker Desktop and other Vagrant VMs.
Some WSL distributions use the legacy registration system and are not fully supported:
Affected distributions:
- Ubuntu-20.04, Ubuntu-22.04
- OracleLinux_7_9, OracleLinux_8_10, OracleLinux_9_5
Issues:
--no-launchflag does not properly register the distribution- Distributions require interactive setup (username/password prompt)
- Provider cannot detect distribution after installation
SUSE Linux Enterprise distributions may have guest detection issues:
- SUSE-Linux-Enterprise-15-SP6
- SUSE-Linux-Enterprise-15-SP7
Very recent distributions may have provisioning issues:
- AlmaLinux-10, AlmaLinux-Kitten-10 (Ansible provisioner fails due to missing EPEL repositories)
Some distributions have minimal installations without common tools:
- archlinux (missing
sudoby default - Ansible provisioner fails)
The following distributions are fully tested and working with shell/file/ansible provisioners:
- AlmaLinux-8, AlmaLinux-9
- Debian
- FedoraLinux-42
- Ubuntu, Ubuntu-24.04
- Kali-Linux
- openSUSE-Tumbleweed
- Mount VirtualBox data disks in WSL2
- VHD/VMDK to WSL2 format conversion
- Support for development backup workflows
- Fixed network support for multiple WSL2 distributions
- Network isolation and custom IP configuration
- Port forwarding enhancements
- Non-interactive setup for Ubuntu 20.04, 22.04
- Support for Oracle Linux distributions
- Improved compatibility with legacy WSL registration system
Bug reports and pull requests are welcome on GitHub.
The gem is available as open source under the MIT License.
Important: WSL2 distributions behave differently from traditional VMs!
- WSL2 distributions automatically enter "stopped" state when no processes are running
- This is normal behavior, not a bug
- Unlike VMs, WSL2 distributions don't stay "running" idle
stopped= Distribution exists, no active processes (ready to use)running= Distribution has active processesnot created= Distribution doesn't exist
vagrant up --provider=wsl2 # Creates distribution (shows "stopped")
vagrant ssh # Starts shell (shows "running")
exit # Shell closes (returns to "stopped")
vagrant status # Shows "stopped" - this is normal!