Umi Uyuraのブログ

プログラミング関連の作業ログ

Windows 10開発環境構築(WSL2とGit/VSCodeの連携)

今業務で使っているWindowsマシンは、gnupackとChocolateyをベースに環境構築していました。

umi-uyura.hatenablog.com

最近、作業の都合でWSL2を使うことになり、さらにVisual Studio Codeとの連携を使ってみたところ非常に便利だったのと、Windowsのソフトウェア管理ツールとしてwinget (Windows Package Manager)というものが出てきていたので、改めてこれらをベースにした環境を作ってみることにしました。

プライベートでもWindows触っておこうと思って買ったものの放置していて、もはや子供のマインクラフト用になっていたノートPCがようやく活用されるときが来た。

コンセプト

改めてWSL2を使う想定の環境作りをするにあたり考えていたこと。

  • 開発環境はWSLに寄せる
    • 最近はWeb開発的なことが多いので、その方が都合が良さそう
    • ただWindows用のElectronアプリの開発なども多少あるので、Windows側にも一応開発環境を用意することも想定しておく
  • ソフトウェア管理ツールは活用する
    • Windows: なるべくwingetにして、Chocolateyから移行
    • WSL2 (Ubuntu): apt、asdfというのも気になる
  • Gitとssh-agent(ssh鍵)はWindowsとWSLで共有したい
    • GitHubの認証はSSHキーでおこなっているが、Windows側とWSL側でそれぞれ認証するのは面倒
  • Windowsでふだん使うシェルはコマンドプロンプトにする
  • 何はともあれEmacs
    • Windows版ではなくLinux(WSL)版を使うようにしたい
    • GUI版を使いたいけど、WSLgはもう少し先になりそう

まずはWSL2の環境を作りつつ、VSCodeを連携するところまでを目指しました。

Windows側の構築

wingetインストール

まずは色々インストールするためにwingetを入れます。

winget ツールを使用したアプリケーションのインストールと管理 | Microsoft Docs

Microsoft Storeで アプリ インストーラー をインストールすることが推奨されているようですが、Windows 10 InsiderビルドでないとStoreからはインストールできないもよう。

その場合、GitHubからインストーラをダウンロードしてきます。

インストール後、コマンドプロンプトを開いてコマンドを打ち込み、インストールされていることを確認しておきます。

> winget
Windows Package Manager v1.0.11692
Copyright (c) Microsoft Corporation. All rights reserved.

WinGet コマンド ライン ユーティリティを使用すると、コマンド ラインからアプリケーションやその他のパッケージをインストールできます。
...

Windows Terminalインストール

素のコマンドプロンプトでも良いですが、せっかくなので今のうちにWindows Terminalを入れおきます。

さっそくインストールしたばかりのwingetを使います。

wingetはMicrosoft Storeをソースにすることもできますが、いったんストアアカウントなしでインストールしたいので、 sourcewinget にして実行します。

> winget install -e --id Microsoft.WindowsTerminal -s winget

UACのプロンプトが出るのでOKすれば、インストールがおこなわれます。

コマンドプロンプトを管理者権限で起動すればUACを出さずに実行できるのですが、いったん必要なときだけやる方針でいこうと思います。

Google Chrome

完全な初期状態からであればwingetで入れるところですが、このとき使ったPCは別ユーザーでChromeをインストール済だったので、今回は使わず。

ただ winget list -q chrome と実行したところ、インストール済のアプリとしてChromeが認識されていました。

> winget list -q chrome
名前          ID            バージョン
-----------------------------------------
Google Chrome Google.Chrome 92.0.4515.159

どうやらwingetは独自にインストールしたものについて管理をしているわけではなく、PCにインストールしたものを認識しているっぽい。

また、アプリに利用可能なアップデートがある場合は「利用可能」列が現れることも発見。

Gitインストール、GitHub接続

Git for Windowsもwingetでインストールできます。

> winget install -e --id Git.Git -s winget

とりあえず、ユーザーの設定はしておきます。

> git config --global user.name "Umi Uyura"
> git config --global user.email <my_email@example.com>

GitHubSSH接続できるようにする

次にGitHubへアクセスできるようにします。

私はふだんSSHで接続しているので、GitHub用のSSH鍵を作ります。

最近はアルゴリズムRSAではなくED25519が良いらしい。

> ssh-keygen -t ed25519 -C "my_email@example.com" -f %USERPROFILE%¥.ssh¥github_ed25519

今のWindows 10にはOpenSSLが標準で含まれているので、認証のためにssh-agentを起動しておこうとしたところ、エラー発生。

> ssh-agent -s
unable to start ssh-agent service, error: 1058

Windows 10のssh-agentをコマンド プロンプト、WSL、Git Bashで使ってみた - Qiita

上の記事によると、どうやらOpenSSHのサービスが起動していないことが原因らしいので、

  • Win + R(ファイル名を指定して実行)から services.msc を実行してサービス管理画面を起動
  • OpenSSH Authentication Agent のスタートアップの種類を「自動」に変更

を行ってから、改めてssh-agentを起動して、 ssh-addSSH鍵を追加。その際にSSH鍵のパスフレーズを要求されるので入力。

問題なければ、 ssh-add -l で登録した鍵の情報が表示されるはず。

> ssh-agent -s
> ssh-add %USERPROFILE%¥.ssh¥github_ed25519
> ssh-add -l
256 SHA256:CTVT24F8dLFqlAtBULhuB2dZjLQmIz05G4730mD4Ii8 my_email@example.com (ED25519)
256 SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx my_email@example.com (ED25519)

あとはGitHubの手順どおり。

GitHub に SSH で接続する - GitHub Docs

公開鍵を clip コマンドでクリップボードにコピーして、GitHubSSH Keyにペーストして登録。

> clip < %USERPROFILE%¥.ssh¥github_ed25519.pub

ssh -T で接続確認。

> ssh -T git@github.com
...
Hi umi-uyura! You've successfully authenticationed, but GitHub does not provide shell access.

自分のGitHubアカウント名が表示されれば、接続されています。

ちなみに ssh -T-T ってなんだろうとおもって調べたところ、以下の記事が参考になりました。

pseudo-tty とは? - kz-engineer -SCRAP-

環境変数 GIT_SSH の登録

これで sshGitHubに接続できるようになったものの、実はGit for Windowsは独自にバンドルしている ssh を使うようで、このままでは git コマンド経由でSSH接続しようとしたときにつながりません。

そこで、環境変数 GIT_SSHWindows標準の ssh.exe のパスを設定することで、こちらの ssh を使ってもらえるようになります。

> where ssh
C:\Windows\System32\OpenSSH\ssh.exe

> echo %GIT_SSH%
C:\Windows\System32\OpenSSH\ssh.exe

Visual Studio Codeのインストール

これもwingetでインストールできます。

> winget install -e --id Microsoft.VisualStudioCode -s winget

いろいろと設定変えたり拡張機能インストールしたりとありますが、まずはWSL2との連携をしたいので、そのあたりは後ほど。

Chocolateyインストール

wingetに対応できるものはインストーラ形式があるものを前提としていて、ZIPなどで配布しているものは対象外なもよう。

対応要望のissueはある( Support installing .zip files · Issue#140 · microsoft/winget-cli )ので今後に期待しつつ、それはそれとして、SysinternalsやこのあとWSL2との連携で必要になる npiperelay などがこのためにwingetでは入れられないため、当面そういったものを管理するためにChocolateyも併用することにしました。

インストールは公式サイトの手順通りに実施します。

Chocolatey Software | Installing Chocolatey

PowerShellは極力使わない方針としつつ、Chocolateyのインストールスクリプトは.ps1なので、しかたなく管理者権限で起動したPowerShellで、まずは以下のコマンドを実行。

> Get-ExecutionPolicy 
Restricted

公式サイトによると、ここは Bypass もしくは AllSigned となっていることが良いらしく、設定の変更方法が載っていました。

が、どうやら Now run the following command: に示されているコマンドを見ると、その設定変更からインストールスクリプトのダウンロードと実行までやってくれるもののようだったので、素直にコピペして実行。

> Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))

インストールが終わったら choco コマンドが使えることを確認。

> choco /?
This is a listing of all of the different things you can pass to choco.
...

npiperelayのインストール

混沌を極めるWindowsのssh-agent事情 - Qiita

上記の記事にあるように用途によってssh-agentの選択は分かれるようですが、私はWindowsとWSL2で、Windows側は標準搭載されているOpenSSHを使うようにしようと思ったので、npiperelay+socat方式にすることにしました。

npiperelayはChocolateyから入れられます。

管理者権限でコマンドプロンプトを起動して、

> choco install -y npiperelay
...
C:\ProgramData\chocolatey\lib\npiperelay\tools
 ShimGen has successfully created a shim for npiperelay.exe
 The install of npiperelay was successful.
  Software installed to 'C:\ProgramData\chocolatey\lib\npiperelay\tools'

Chocolatey installed 1/1 packages.
 See the log for details (C:\ProgramData\chocolatey\logs\chocolatey.log).

> where npiperelay
C:\ProgramData\chocolatey\bin\npiperelay.exe

インストール中にも出力されていますが、最後に where npiperelay で確認した実行ファイルへのパスがあとで必要になるのでメモしておきます。

WSL2 (Ubuntu)側の構築

続いてWSL2のセットアップ。

ここはMicrosoftのドキュメントを参考に進めました。

Windows 10 に WSL をインストールする | Microsoft Docs

上記によると、WSLのインストールには「簡略化されたインストール」と「手動インストール」があるようですが、「簡略化」の方はこちらもInsider Programに入っていることが条件のようなので、手動インストールをおこないました。

WSLには1と2がありますが、用途によっては1を選択することもあるようです。

WSL 1 と WSL 2 の比較 | Microsoft Docs

インストール中、私のPCでは「インストールがエラー 0x80070003 またはエラー 0x80370102 で失敗した」が発生しましたが、ドキュメントのインストールのトラブルシューティングの項にとおりBIOSから仮想化を有効化したところ発生しなくなりました。

WSL2が有効になったところで、いちどパッケージを最新状態にしておきます。

パッケージの更新とアップグレード

$ sudo apt update && sudo apt upgrade

Git(最新版)インストール

概要WSL で Git を使用する | Microsoft Docs

$ sudo apt install git
Reading package lists... Done
Building dependency tree
Reading state information... Done
git is already the newest version (1:2.25.1-1ubuntu3.1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

$ git --version
git version 2.25.1

Windows側に入れたものは 2.32.0 でしたが、ふつうにaptでインストールしたところ古いバージョンでした。

最新版のGitを入れるには、別のリポジトリを追加する必要があるとのこと。

$ sudo add-apt-repository ppa:git-core/ppa
$ sudo apt update
$ apt list --upgradable
Listing... Done
git-man/focal 1:2.32.0-1~ppa0~ubuntu20.04.1 all [upgradable from: 1:2.25.1-1ubuntu3.1]
git/focal 1:2.32.0-1~ppa0~ubuntu20.04.1 amd64 [upgradable from: 1:2.25.1-1ubuntu3.1]

$ sudo apt install git
$ git --version
git version 2.32.0

WindowsSSHキーの共有

まずはnpiperelayと組み合わせて使うsocatをインストールします。

$ sudo apt install socat

続いて、Chocolateyで入れたnpiperelay.exeへのパスを含めたスクリプトを.bashrcに追記します。

export SSH_AUTH_SOCK=$HOME/.ssh/agent.sock
ss -a | grep -q $SSH_AUTH_SOCK
if [ $? -ne 0   ]; then
    rm -f $SSH_AUTH_SOCK
    ( setsid socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork EXEC:"/mnt/c/ProgramData/chocolatey/bin/npiperelay.exe
 -ei -s //./pipe/openssh-ssh-agent",nofork & ) >/dev/null 2>&1
fi

一度WSLを抜けて入り直し、Windows側と同様 ssh -T での接続確認をおこないます。

$ ssh -T git@github.com
Hi umi-uyura! You've successfully authenticationed, but GitHub does not provide shell access.

ホストWindows側でSSHキーを登録しておくことで、WSL2側ではキーの作成や登録をせずにSSH接続できました。

Visual Studio Code + Remote Developmentのセットアップ

基本はMSのドキュメントどおりに進めればOK。

WSL で VS Code の使用を開始する | Microsoft Docs

まずは指示通りに必要なものをインストール。

VSCode側には Remote Development - Visual Studio Marketplace拡張機能をインストールし、WSL側にはwgetとca-certificatesをインストールします。

$ sudo apt-get update
$ sudo apt install wget ca-certificates

その後、WSL側で code . を実行すると、サイトのアニメーションGIFのようにVS Code Server for x64のインストールが始まり、それが終わるとホストWindows側でVSCodeが起動し、WSLのフォルダが開かれていました。

パスを確認すると、それまでは \\wsl$\Ubuntu\home\<user>\... と表示されていたものが /home/<user>/... [WSL] という表示になり、Remote Developmentで接続できていることを確認できます。

WSL2の初期化

途中で失敗したときのため(失敗した)、WSL2を最初から作り直す方法についても調べておきました。(やりました)

Windows 10のWSL環境を初期化してクリーンな状態に戻す:Tech TIPS - @IT

WSLが停止していることを確認。

> wsl --list --verbose
  NAME      STATE           VERSION
* Ubuntu    Stopped         2

記事のとおり、設定アプリアプリと機能 のアプリケーション一覧から、対象となるディストリビューションの、アプリケーションの設定からリセットをおこないます。

そのあとでMS Storeのディストリビューションから起動をすればアカウントの作成から始まります。

おわり

実際になにか開発をするには、さらに対象の言語環境やツールが必要になってきますが、そのためのベースとなる環境はできたかなと思います。

CygwinMacで多少Linuxコマンドを使ったりしてはいたものの、ちゃんとLinux環境で開発をしたことはほとんどないので、WSL側についてはこれから手探りですね。