雀巽の日記帳

雀巽が綴る日常の記録

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

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

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

WSL 2 の有効化

まずは Windows Subsystem for Linux 2 を以下を有効化します。

2019年10月現在、WSL 2 は Windows Insider Program の Fast ring でのみ入手可能です。 Windows の検索窓から Windows Insider Program settings を開き、ガイダンスに従い登録します。 登録後、Windows Update を走らせ、Windows を最新の状態にします。 また、このあと Slow ring に変更してもおそらく問題は無いため、頻繁に更新が来るのが鬱陶しい場合は Slow に変更しておきます。

それが完了したら、Powershell から Virtual Machine Platform と Windows Subsystem for Linux 2 を有効化します。

Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

そして WSL 2 を WSL のデフォルトバージョンに変更しておきます。

wsl --set-default-version 2

Ubuntu 18.04 LTS の導入

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

WSL のデフォルトディストリビューションwsl --set-version Ubuntu-18.04 2 で設定可能です。 設定後 wsl -l -v を実行すると、以下の通りになります。

PS C:\Users\necojackarc> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-18.04    Stopped         2

Windows Terminal の導入

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

設定可能なカラースキームは defaults.json を直接参照すれ

Solarized Dark 以外のカラースキームを受け付けない身体になってしまっているので、Settings から profiles.json を開きカラースキームを変更します。 また、カラースキームだけでなく、ターミナルを開いた際の開始ディレクトリも Ubuntu のホームディレクトリにしておきます。

profiles 中にある Ubuntu-18.04 の profile に以下の設定を追記すれば完了です。

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

ただし、デフォルトの 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"
        }
    ],

最後に defaultProfileUbuntu-18.04 の UUID に変更しておきます。

これで、Windows Terminal 起動時に、Ubuntu のホームディレクトリからデフォルトで開始するようになります。

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

Windowsエクスプローラーで WSL2 のディレクトリを開くには、WSL2 を起動後、ターミナル上で explorer.exe . とするだけで良いです。 もしくは、直接エクスプローラーに \\wsl$\Ubuntu-18.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 - GitHub Help に従い行います。

設定後は ./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 ncurses-dev libncurses5-dev libgnome2-dev libgnomeui-dev libgtk2.0-dev libatk1.0-dev libbonoboui2-dev libcairo2-dev libx11-dev libxpm-dev libxt-dev python-dev python3-dev ruby-dev lua5.1 lua5.1-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/11.0.2/ripgrep_11.0.2_amd64.deb
sudo dpkg -i ripgrep_11.0.2_amd64.deb
rm ripgrep_11.0.2_amd64.deb

Go

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

sudo add-apt-repository ppa:longsleep/golang-backports
sudo apt update
sudo apt upgrade
sudo apt-get 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

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

AWS CLI

まずは pyenv で最新の Python を導入します。

pyenv install -l # check the latest version
pyenv install 3.7.4
pyenv global 3.7.4
python -V # check if it's 3.7.4
pip install awscli --upgrade --user
aws --version

Yarn

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

yarnpkg.com

導入時にデフォルトで nodejs も追加されますが、害はないのでそのまま入れておきます。

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 yarn

Docker

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

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

sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
udo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install docker-ce

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

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 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"

参考