Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 46 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,62 @@
# For podman on Windows, see the 1st party installation guide [here](https://github.com/containers/podman/blob/main/docs/tutorials/podman-for-windows.md)
# Podman in WSL 2

> Note: For Podman on Windows, see the [1st-party installation guide][podman-for-windows].

## WSL2 podman/docker install script
Script for installing WSL2 + `podman` and `podman-compose` (or `docker` and `docker-compose`), and adding Windows "aliases" for convenience
[![License][license-shield]][LICENSE]

## Getting Started

### Installation
- [Download](https://github.com/rosenbjerg/wsl2-podman/archive/refs/heads/main.zip) and extract the `.bat` and `.ps1` files into same folder and run the `.bat` script (will prompt for admin rights)
- Switch from `localhost` to `::1` or `wsl` if you experience problems connecting to a container from some application on the host
### Prerequisites

- [PowerShell Core][get-powershell]
- [Windows Subsystem for Linux (WSL)][install-wsl]

### Improvements and other suggestions
Please create issues for improvements or suggestions to the script
### Usage

1. [Clone or download][clone-repository] this repository
2. In an Administrator prompt, run the [`Install-ContainerRuntime.ps1`][Install-ContainerRuntime.ps1] script

### Known problems
```powershell
# Defaults to podman, add -Docker to install docker-ce instead
.\scripts\Install-ContainerRuntime.ps1
```

#### Running the installer
If you experience problems starting the installer using the `.bat` script, it may be because the `.ps1` file is blocked in Windows.
### Known Issues

Right-click on the `.ps1` file and select Properties. Then in the General tab, you will see the option to unblock it.
After unblocking, you should be able to start the install script.
#### Absolute paths

If that doesn't solve it, you may need to move the two files to another directory, possibly due OneDrive synchronization of the current folder.
Moving the two files to the root of `C:\` should resolve the issue.
By default, the shims created by the installation scripts do not support absolute paths for mounting.
Instead you will have to either use relative paths or rewrite `C:\` to `/mnt/c/` and use forward slashes.

#### Absolute paths
One problem with this docker-desktop alternative is that you cannot use absolute paths for mounting.
Instead you will have to either use relative paths or rewrite `C:\` to `/mnt/c/` and use forward slashes
Alternatively, consider installing the [`WslInterop` module][wsl-interop] for easier access from PowerShell.

#### Connecting to containers using `localhost`
Some applications automatically resolve localhost to `127.0.0.1` (IPv4) which Windows doesn't forward to WSL2, without checking the Windows `hosts` file.
This means you may experience problems connecting to the containers running in WSL2, if using `localhost`.

If you do experience this, try changing `localhost`/`127.0.0.1` to `::1` (for TCP connections and `[::1]` for HTTP) or to `wsl`
Some applications automatically resolve `localhost` to `127.0.0.1` (IPv4), which Windows doesn't forward to WSL, without checking the Windows `hosts` file.
This means you may experience problems connecting to the containers running in WSL when using `localhost`.

#### Missing internet connectivity when using Cisco AnyConnect on Windows host
Connecting or disconnecting the AnyConnect client can cause internet connectivity problems in WSL2. Running the following powershell command with elevated rights fixes this:
```powershell
Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match 'Cisco AnyConnect'} | Set-NetIPInterface -ErrorAction SilentlyContinue -InterfaceMetric 6000 | Out-Null
```
If you do experience this, try swapping `localhost`/`127.0.0.1` for `::1` (TCP), `[::1]` (HTTP), or simply `wsl`.

#### No internet connectivity when using a VPN

Refer to the [WSL troubleshooting page][vpn-troubleshooting].

## Contributing

If you have a suggestion that would make this better, please fork the repo and create a pull request.
You can also simply open an issue.

## License

[GPL][LICENSE]

<!-- LINKS & IMAGES -->
[podman-for-windows]: https://github.com/containers/podman/blob/95eff1aa402c3d159c8ad25d8140b879d5feccf2/docs/tutorials/podman-for-windows.md
[license-shield]: https://img.shields.io/github/license/rosenbjerg/wsl2-podman?style=flat-square
[LICENSE]: LICENSE
[get-powershell]:https://github.com/powershell/powershell#get-powershell
[install-wsl]: https://docs.microsoft.com/en-us/windows/wsl/install
[clone-repository]: https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository
[Install-ContainerRuntime.ps1]: scripts/Install-ContainerRuntime.ps1
[wsl-interop]: https://github.com/mikebattista/PowerShell-WSL-Interop
[vpn-troubleshooting]: https://docs.microsoft.com/en-us/windows/wsl/troubleshooting#wsl-has-no-network-connectivity-once-connected-to-a-vpn
1 change: 0 additions & 1 deletion cisco-vpn-fix-wsl2-network.bat

This file was deleted.

1 change: 0 additions & 1 deletion cisco-vpn-fix-wsl2-network.ps1

This file was deleted.

85 changes: 85 additions & 0 deletions scripts/Install-ContainerRuntime.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#Requires -Version 7

<#
.SYNOPSIS
Installs Podman or Docker into an existing WSL Ubuntu distro.

.PARAMETER Docker
When true, docker-ce will be installed instead of podman.

.NOTES
This script expects Ubuntu to be installed in WSL.
#>

using namespace System.Management.Automation
using namespace System.IO

[CmdletBinding()]
param (
[switch]
$Docker
)

$InformationPreference = [ActionPreference]::Continue

$PSDefaultParameterValues = @{
"Select-String:SimpleMatch" = $true;
"Select-String:Quiet" = $true;
}

$runtime = if ($Docker) { "docker" } else { "podman" }

if (-not (wsl --list | Select-String "Ubuntu")) {
throw "Failed to detect Ubuntu installation in WSL"
}

Write-Information "Running shell script"

$runtimeInstallScriptPath = [Path]::Join($PSScriptRoot, "install-container-runtime.sh")

wsl -d Ubuntu bash ($runtimeInstallScriptPath -replace "C:", "/mnt/c" -replace "\\", "/") $runtime

Write-Information "Creating shims"

$localBin = [Path]::Join($Env:USERPROFILE, ".local", "bin")

[Directory]::CreateDirectory($localBin) | Out-Null

$userPath = $Env:PATH -split ";" | Where-Object { $_.StartsWith($Env:USERPROFILE) }

if (-not $userPath -contains $localBin) {
Write-Information "Adding $localBin to PATH"
$userPath = @($localBin) + $userPath
[Environment]::SetEnvironmentVariable("Path", ($userPath -join ";"), [EnvironmentVariableTarget]::User)
}

$shims = ("docker", "docker-compose", $runtime, "$runtime-compose") | Select-Object -Unique

$shims.ForEach({
[File]::WriteAllText("$localBin\$_.ps1", "wsl -d Ubuntu $_ @Args")
})

$hostsPath = [Path]::Join($Env:SYSTEMROOT, "System32", "drivers", "etc", "hosts")

$targetHostsEntries = (
"0:0:0:0:0:0:0:1 wsl",
"0:0:0:0:0:0:0:1 $runtime"
)

$targetHostsEntries.ForEach({
if (-not (Select-String -Path $hostsPath $_)) {
Write-Information "Adding '$_' to hosts file"
[File]::AppendAllText($hostsPath, "`r`n$_")
}
})


if ($Docker) {
Write-Information "Restarting WSL"
wsl --shutdown
wsl -d Ubuntu :
}

Write-Host -ForegroundColor Green "`nInstall successful! Try running $runtime or $runtime-compose`n"
Write-Host -ForegroundColor Yellow "Press any key to exit"
Read-Host
116 changes: 116 additions & 0 deletions scripts/install-container-runtime.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/usr/bin/env bash

set -Euo pipefail

declare -r \
apt_sources=/etc/apt/sources.list.d \
apt_trusted=/etc/apt/trusted.gpg.d \
runtime="${1:-}"

script_name=$(basename "${BASH_SOURCE[0]}")

source <(grep -F VERSION /etc/os-release)

has() {
command -v "$1" &>/dev/null
}

check_exists() {
has "$1" && {
echo "$1 is already installed"
exit
}
}

add_apt_repo() {
local -r name=$1 key=$2 repo=$3

echo "Adding ${name} repo"

curl -fsSL "${key}" | sudo gpg --dearmor -o "${apt_trusted}/${name}.gpg"

echo "${repo}" | sudo tee "${apt_sources}/${name}.list" >/dev/null
}

apt_install() {
echo "Installing $*"

sudo apt-get -qq update
sudo apt-get -qq install "$@"
}

pip-install() {
has pip3 || {
echo "Installing pip3"
apt_install python3-pip
}

has "$1" || {
echo "Installing $1"
pip3 install --user -q "$1" &>/dev/null
}
}

install-docker() {
check_exists docker

local -r repo_url="https://download.docker.com/linux/ubuntu/"

add_apt_repo docker "${repo_url}gpg" "deb [arch=amd64] ${repo_url} ${VERSION_CODENAME} stable"

apt_install docker-ce docker-ce-cli containerd.io docker-compose-plugin

echo "Creating docker group"

sudo groupadd docker >/dev/null
sudo usermod -aG docker "${USER}"

pip-install docker-compose
}

install-podman() {
check_exists podman

local -r repo_url="https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/testing/xUbuntu_${VERSION_ID}/"

add_apt_repo devel:kubic:libcontainers:testing "${repo_url}Release.key" "deb ${repo_url} /"

apt_install podman

pip-install podman-compose

grep -Fq 'docker()' ~/.profile || {
echo "Adding aliases to ~/.profile"

cat >>~/.profile <<"EOF"

docker() {
if [ "$1" = compose ]; then
shift
podman-compose "$@"
else
podman "$@"
fi
}

export -f docker
alias docker-compose=podman-compose
EOF
}
}

case "${runtime}" in
docker)
install-docker
;;
podman)
install-podman
;;
*)
echo "USAGE

${script_name} <docker|podman>
" >&2
exit 1
;;
esac
1 change: 0 additions & 1 deletion setup-wsl2.bat

This file was deleted.

Loading