雀巽の日記帳

雀巽が綴る日常の記録

WSL2 を利用し Windows 上に Ubuntu の開発環境を構築する

Windows Subsystem for Linux 2 (WSL2) を利用し、Windows 上に Ubuntu 20.04 LTS の開発環境を構築する方法です。

WSL2 では Linux カーネルそのものが動作しているので、基本的に Ubuntu 上で可能なことは全て可能だと思います。 そのため、実用に耐える Linux 開発環境が Windows 上に直接構築可能となります。

WSL 2 の有効化

まずは Windows Subsystem for Linux 2 を公式ガイドに従い有効化します。 以下は公式ガイドの抜粋です。

公式が非常にわかりやすいので、公式に一度目を通すことをお勧めします。

PowerShell を Administrator として開き、以下を実行します。

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart

そしていったんここで Windows の再起動し、そのあと再び PowerShell を Administrator として開き WSL のバージョンを2に変更します。 wsl コマンドは非 Administrator でも実行可能になっているので、通常ユーザーでも念のため実行して起き、Windows を再起動します。

wsl --set-default-version 2

もしここでエラーが出た場合は WSL2 Linux カーネルのアップデートをするとおそらくなおります。

Ubuntu 20.04 LTS の導入

Ubuntu 20.04 LTS をストアからインストールします。

ダウンロード後はストア上から Launch ボタンを押し、セットアップを開始します。 ここで Ubuntu 上でのユーザー名やパスワードを登録します。

設定後 wsl -l -v を実行し、正しく設定が行われていることを確認します。

PS C:\Users\necoj> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-20.04    Running         2

もし VERSION が2になっていた場合 wsl --set-version Ubuntu-20.04 2 で変更可能です。

Windows Terminal の導入

Linux のターミナル (e.g. GNOME, Xfce, etc) に近い使い心地の Windows Terminal を導入します。

Windows Terminal を導入後、以下の設定を行います。

  • defaultProfile
  • colorScheme
  • startingDirectory

まずは defaultProfileUbuntu-20.04 の UUID に変更します。

次にカラースキームですが、設定可能なカラースキームは defaults.json を直接参照してください。

Solarized Dark 以外のカラースキームを受け付けない身体になってしまっているので、Soralized Dark に設定します。 そして startingDirectory、すなわちターミナルを開いた際の開始ディレクトリも Ubuntu のホームディレクトリにしておきます。

Ubuntu-20.04 の profile に以下の設定を追記すれば完了です。

"colorScheme" : "Solarized Dark",
"startingDirectory": "//wsl$/Ubuntu-20.04/home/necojackarc"

Solarized Dark のカラースキームの不具合(修正済み)

以下の問題は修正済みですが、カラースキームをカスタマイズする際の知識として有用なので残しておきます。

github.com

デフォルトの Solarized Dark における background と brightBlack の色かぶりが存在しており、実用上問題がありました。 そこで、以下の通り brightBlack#006C88 にオーバーライドしておきます。

    "schemes": [
        {
            "name": "Solarized Dark",
            "foreground": "#839496",
            "background": "#002B36",
            "black": "#073642",
            "red": "#DC322F",
            "green": "#859900",
            "yellow": "#B58900",
            "blue": "#268BD2",
            "purple": "#D33682",
            "cyan": "#2AA198",
            "white": "#EEE8D5",
            "brightBlack": "#006C88",
            "brightRed": "#CB4B16",
            "brightGreen": "#586E75",
            "brightYellow": "#657B83",
            "brightBlue": "#839496",
            "brightPurple": "#6C71C4",
            "brightCyan": "#93A1A1",
            "brightWhite": "#FDF6E3"
        }
    ],

Windows から WSL2 上のファイルへアクセスする

Windowsエクスプローラーで WSL2 のディレクトリを開くには、WSL2 を起動後、ターミナル上で explorer.exe . とするだけで良いです。 もしくは、直接エクスプローラーに \\wsl$\Ubuntu-20.04 と打ち込むことでもアクセスすることができます。

Ubuntu の環境構築

WSL2 では Ubuntu がそのまま動作しているので、基本的には通常の Ubuntu と同様に環境構築が可能です。 ただし、Vim でのクリップボード連携には Windwos 側での X server の設定が必要です。

CLI 環境の構築

まずは開発に最低限必要となるツール (Git, Tmux, direnv, etc. ) 一式を導入します。

sudo apt update
sudo apt upgrade
sudo apt install git tmux xsel curl direnv exuberant-ctags 

そして GitHub の設定を Generating a new SSH key and adding it to the ssh-agent に従い行います。

設定後は ./ssh/config 以下を追記します(GitHub 用の鍵を ~/.ssh/github/ に配置する前提)。

Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/github/id_rsa

ssh -T github.com で設定完了を確認後、dotfiles を GitHub から落としてきます。

github.com

Vim の構築

まずは Vim の依存ライブラリを導入します。これらを導入した状態で make すれば、ほぼフル機能が有効な Vim がビルドされます。

sudo apt install libncurses-dev libncurses5-dev libgtk2.0-dev libatk1.0-dev libcairo2-dev libx11-dev libxpm-dev libxt-dev python-dev-is-python2 python3-dev ruby-dev lua5.3 liblua5.3-dev libperl-dev

そして Vim の最新版を公式推奨方法通りに、GitHub ソースからビルドします。

cd /usr/local/src
sudo git clone https://github.com/vim/vim.git
cd vim/src
sudo make distclean  # if you build Vim before
sudo make
sudo make install

また、Vim の Clipboard 連携を使うためには X server が Windows 側に必要なのでそちらも準備します。

まずは VcXsrv Windows X Server をインストールします。Full オプションでのインストールで問題ありません。 もしインストール後に起動してしまった場合、タスクバーにアイコンが現れていると思うので、そこから停止しておきます。

そして XLaunch を以下の設定で起動します。

  • Multiple windows (default)
  • Start no client (default)
  • Extra settings (全てにチェック)
    • Clipboard (default)
      • Primary Selection (default)
    • Native opengl (default)
    • Disable access control

Save configuration を押し、設定ファイルを保存します。 この際、Windows 起動時に VcXsrv が自動起動するよう C:\Users\<USER NAME>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup に保存しておきます。

導入時に Firewall の設定が聞かれた際は Public と Private networks 両方を許可しておく必要があります。 設定に不備がある場合は Firewall Allow an app through firewall から VcXsrv Windows server の設定を変更しておきます。

最後に Ubuntu 側から VcXsrv に接続するために環境変数 DISPLAY を設定します。 ~/.env という ~/.profile から読み込むようにしている環境依存の Bash 設定を書くファイルを準備し、そこに以下を追記します。

LOCAL_IP=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
export DISPLAY=$LOCAL_IP:0

ripgrep

便利高速 grep ツールです。Vim からも利用しています。

github.com

最新バージョンの deb をダウンロードし、インストールします。

curl -LO https://github.com/BurntSushi/ripgrep/releases/download/12.1.1/ripgrep_12.1.1_amd64.deb
sudo dpkg -i ripgrep_12.1.1_amd64.deb
rm ripgrep_12.1.1_amd64.deb

Go

GHQ という Git リポジトリ管理ツールの導入に必要です。 公式サイト に従いインストールします。

sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt install golang-go

GHQ

Git リポジトリの管理ツールです。ghq get <REPOSITORY NAME>リポジトリの名前構造を反映した場所にクローンしてくれるため、管理が非常に楽になります。 後述の fzf と組み合わせることで、高速にリポジトリの移動が可能になります。

github.com

go get github.com/motemen/ghq

fzf

Fuzzy Search ツールです。バックエンドは rg に差し替えています

github.com

git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install

インストール時に fzf の Bash 拡張の設定について聞かれるので、

  • fuzzy auto-completion: y
  • key bindings: y

と両方 ON にしておきます。

tig

Git のインタラクティブCLI ツールです。

github.com

sudo apt install tig

delta

Git の diff を見やすくしてくれる CLI ツールです。

github.com

最新バージョンの deb をダウンロードし、インストールします。

curl -LO https://github.com/barnumbirr/delta-debian/releases/download/0.4.1-1/delta-diff_0.4.1-1_amd64_debian_buster.deb
sudo dpkg -i delta-diff_0.4.1-1_amd64_debian_buster.deb
rm delta-diff_0.4.1-1_amd64_debian_buster.deb

rbenv & nodenv & pyenv

Ruby & Node.js & Python がメインの開発言語なので、バージョン管理システムを導入しておきます。 また、PythonAWS CLI の導入にも必要です。

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
sudo apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm5 libgdbm-dev

git clone https://github.com/nodenv/nodenv.git ~/.nodenv
git clone https://github.com/nodenv/node-build.git $(nodenv root)/plugins/node-build

git clone https://github.com/pyenv/pyenv.git ~/.pyenv

Yarn

Node.js のパッケージ管理システムのひとつです。

yarnpkg.com

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update
sudo apt install --no-install-recommends yarn

Docker

PostgreSQL などは Docker を利用して構築しているので、Docker を導入します。 Docker を使うメリットは、PostgreSQL の複数バージョンの同居が比較的容易なためです。 apt で複数バージョンを同居させようとすると、非常に難しいです。

公式ガイドに従いインストールします。

sudo apt update
sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88 # Confirm you have the correct key 
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

導入が完了したら、起動します。

sudo service docker start

また、sudo なしで docker コマンドを実行できるように docker グループに自分を追加しておきます。

sudo usermod -aG docker ${USER}
su - ${USER} # apply the change
id -nG # confirm the change

最後に動作確認をしておきます。

docker run hello-world

PostgreSQL

前述の通り Docker で導入します。PostGis を使うケースも多いので mdillon/postgis を利用します。 ただし、CLI ツールの psql は別途必要なので、そちらは apt でインストールします。

sudo apt install postgresql

もし仮に apt で導入した PostgreSQL が自動で起動してしまう場合は対処する必要がありますが、 現時点では systemd が WSL2 上では正しく機能していないので、おそらく何もしなくて大丈夫です。 通常であれば sudo systemctl status postgresql でステータスを確認し、sudo systemctl disable postgresql でブート時に起動しないようにします。

5432 ポートが空いていることを sudo lsof -isudo lsof -i -P もしくは sudo ss -tulwsudo ss -tulwn を確認後、docker run を行い PostgreSQL の導入および起動を行います。

docker run --name postgres11 -p 5432:5432 -d mdillon/postgis:11

psql -h localhost -U postgres を叩いて接続できることを確認します。 もしブート時に常に起動しておきたいのであれば --restart=always を渡しておきます。

また、手動での起動および停止は以下の通り行えます。

docker ps -a # Check the container ID and/or NAME
docker start [CONTAINER_ID or NAME]
docker stop [CONTAINER_ID or NAME]

psql で利用するデフォルトのユーザーと DB を以下の環境変数で設定しておきます。

export PGHOST="localhost"
export PGDATABASE="postgres"
export PGUSER="postgres"

参考