WindowsでHaskell開発(Docker on WSL2)
Docker on Windowsだとファイルシステムの問題でくそ遅くてgitの操作だけでもクソ重いので,現実的にはDocker on WSL2という感じ
2020年10月現在はバージョン上げるのにこれ 使わないといけないので,まずこれをやってから上記の手順を踏んでWSL2を設定 2. Ubuntu20.04 なりのWSL入れる
3. WSLのUbuntuにgnupg2, ssh, git, git-lfsを入れる
4. gpgとssh,gitの設定をする
5. Docker for Windowsを入れる
6. GPG4Winを入れる(pinentry のためだけの存在)
7. WSLのUbuntuの~/.gnupg/gpg-agent.conf にpinentry-program "/mnt/c/Program Files (x86)/Gpg4win/bin/pinentry.exe"を追記(多分ないのでファイル作る)
8. WSLのUbuntuにapt install socat で socat をインストールする (gpgの転送のため)
9. stack-buildイメージをもとにごりっとDockerfileを書く.ssh, git, git-lfs, gnupg2, なんらかのエディタはいれとく 10. docker imageをビルドする.レジストリにpushしておくと便利
11. VSCodeをインストールしてRemote WSLとRemote Containerを入れる
12. プロジェクトルートに.devcontainer/devcontainer.json を作り,下記のように書く
code: devcontainer.json
{
"name": "hoge Dockerfile",
"image": "fpco/stackbuild:latest",
// Sets the run context to one level up instead of the .devcontainer folder.
"context": "..",
// Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename.
//"dockerFile": "./Dockerfile",
// Set *default* container specific settings.json values on container create.
"settings": {
"terminal.integrated.shell.linux": "/usr/bin/zsh" // zshが好きなので
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"haskell.haskell",
"donjayamanne.githistory",
"eamodio.gitlens",
"slevesque.vscode-hexdump",
"oderwat.indent-rainbow",
"2gua.rainbow-brackets",
"ms-azuretools.vscode-docker",
"gitlab.gitlab-workflow",
"jbockle.jbockle-format-files",
"ionutvmi.path-autocomplete",
"vscode-icons-team.vscode-icons",
"mechatroner.rainbow-csv",
"ibm.output-colorizer",
"emilast.logfilehighlighter",
"chrmarti.regex",
"fabiospampinato.vscode-todo-plus",
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Uncomment the next line to run commands after the container is created - for example installing curl.
"postCreateCommand": "cp -r /root/tmp/.ssh /root && chown root /root/.ssh/config",
// Uncomment when using a ptrace-based debugger like C++, Go, and Rust
"mounts": [
"source=${localEnv:HOME}/.ssh,target=/root/tmp/.ssh,type=bind",
"source=${localEnv:HOME}/.gnupg/pubring.kbx,target=/root/.gnupg/pubring.kbx,type=bind",
"source=${localEnv:HOME}/.gnupg/trustdb.gpg,target=/root/.gnupg/trustdb.gpg,type=bind",
"source=${localEnv:HOME}/.gnupg/gpg-agent.conf,target=/root/.gnupg/gpg-agent.conf,type=bind",
// zsh周り
"source=${localEnv:HOME}/.zshrc,target=/root/.zshrc,type=bind",
"source=${localEnv:HOME}/.zlogin,target=/root/.zlogin,type=bind",
"source=${localEnv:HOME}/.zprofile,target=/root/.zprofile,type=bind",
"source=${localEnv:HOME}/.zshenv,target=/root/.zshenv,type=bind",
"source=${localEnv:HOME}/.zprezto,target=/root/.zprezto,type=bind",
"source=${localEnv:HOME}/.zhistory,target=/root/.zhistory,type=bind",
"source=${localEnv:HOME}/.zpreztorc,target=/root/.zpreztorc,type=bind",
],
// "remoteUser": "vscode",
}
13. C:\Users\[username]\.wslconfig をつくってメモリとプロセッサの制限を入れる
code: .wslconfig
memory=<size> # WSL2の軽量仮想マシンで使用する最大メモリサイズを指定する
processors=<number> # WSL2の軽量仮想マシンで使用するCPU数を指定する
swap=<size> # WSL2の軽量仮想マシンで使用するスワップファイルのサイズを指定する
# 0を指定した場合はスワップファイルを使用しない
これをやらないとメモリバカ食いビルドのときにOOMでおちる
gpgのpubring.kbxとturustdb.gpg,gpg-agent.conf をマウントしておけばWSLにある鍵で署名できるようになる.
ssh鍵と設定もマウントしておかなければsshを使ってgitのcloneやpull, pushができない.しかし,普通にマウントするとssh周りの設定のownerとdocker内でのユーザーが食い違い,permission deniedになる.そこで普通に所有権を変えると,マウント元の所有権も変わってしまい面倒くさい.そこで一旦適当な場所にマウントしてからコピーし,その後に所有権を変えている.
これでhaskell-language-serverも動くし,VSCode上でgitの操作やコミットの署名もでき,ビルドもできるけどよくコンテナの起動に失敗するのでウケる
謎
mounts の type をbind 以外にすると失敗する.なんでや.
アプデ後にWSLが動かなくなる
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform を実行する.
bcdedit で hypervisorlaunchtype を確認して Off になってたら bcdedit /set hypervisorlaunchtype auto を実行して auto にする.