﻿# 我的 Windows Subsystem for Linux (WSL) 終極開發人員配置 - 2018 版

我的個人電腦安裝了許多開發套件與工具，今天這篇文章我想來分享我這台的 Windows Subsystem for Linux (WSL) 環境設定，個人認為我已經把我的 WSL 調整的還不錯了，不管是跑 Node.js, Angular CLI, Docker CLI, Kubernetes CLI (kubectl), VIM 等等，都非常順，執行速度也不差，有興趣的人，可以繼續看下去。

我這台電腦是 Windows 10 (1803) (OS Build 17134.48)，而且安裝的是 Microsoft Store 上面的 [Ubuntu 18.04](https://www.microsoft.com/store/productId/9N9TNGVNDL3Q) 版本。

> **請注意：**WSL 有分舊版與新版，舊版的安裝方法，是請你到控制台中透過 Windows 功能安裝。但新版的安裝方法，則是透過 Microsoft Store 進行安裝，所以千萬不要搞錯。詳細安裝步驟可參考 [Install the Linux Subsystem on Windows 10 | Microsoft Docs](https://learn.microsoft.com/en-us/windows/wsl/install-win10) 文件說明。

接下來，就是我在這台 WSL 環境所做的所有設定，各位可以挑選你要的設定下去調整系統即可：

### 建立 SSH 金鑰組

```
ssh-keygen -t rsa -b 4096 -f $HOME/.ssh/id_rsa -P ""
touch ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
```

### 讓執行 `sudo` 的時候免輸入密碼

請記得將 `will` 換成你自己的 WSL 登入帳號。

```
echo "will ALL=(ALL:ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/will
```

### 安裝 [.NET Core SDK](https://www.microsoft.com/net/download/linux-package-manager/ubuntu18-04/sdk-current)

```
wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb

sudo add-apt-repository universe
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-3.1

dotnet --info
```

### 安裝 [Docker CE for Ubuntu](https://docs.docker.com/install/linux/docker-ce/ubuntu/)

```
# Update the apt package index:
# sudo apt-get update 

# Install packages to allow apt to use a repository over HTTPS:
sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \    ca-certificates \
    software-properties-common

# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# Verify that you now have the key with the fingerprint 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88, by searching for the last 8 characters of the fingerprint.
sudo apt-key fingerprint 0EBFCD88

# Use the following command to set up the "edge" repository
# 目前 (2018/6/15) 在 Ubuntu 18.04 僅支援 Edge Channel https://github.com/docker/for-linux/issues/290
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   edge"

# Install Docker CE

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

# Connect to local DOCKER_HOST ("Docker for Windows")

docker -H localhost:2375 version

export DOCKER_HOST=localhost:2375
docker version

echo "export DOCKER_HOST=localhost:2375" >> ~/.bashrc
```

### 安裝 [Node.js](https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based-linux-distributions)

```
# 如果要安裝 Node.js 8.x 才需要執行以下命令
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs

# 如果要安裝 Node.js 10.x 才需要執行以下命令
#curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
#sudo apt-get install -y nodejs

# 如果要安裝 Node.js 12.x 才需要執行以下命令
#curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
#sudo apt-get install -y nodejs

# Optional: install build tools
sudo apt-get install -y build-essential

# 升級 npm
sudo npm install -g npm
npm --version

# 安裝 Yarn
# https://yarnpkg.com/en/docs/install#debian-stable

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-get update && sudo apt-get install yarn
yarn --version
```

### 更新 [Git](https://git-scm.com/download/linux)

```
apt-get install git -y
```

設定 Git 基本 `user.name` 與 `user.email` 參數

```
git config --global user.name YourName
git config --global user.email YourEmail
```

設定 Git 預設編輯器為 vim

```
git config --global core.editor vim
```

設定 Git 簽章用的 GPG 金鑰 (有的話才需要匯入)

```
gpg --import your-gpg-key.gpg
gpg --list-keys
git config --global user.signingkey YOURHASH
```

設定 Git 透過 HTTPS 認證時所需儲存的 Token 或密碼

```
git config --global credential.helper 'store --file ~/.git-credentials'
```

設定 Git 常用的 Git Aliases

```
git config --global alias.co   checkout
git config --global alias.ci   commit
git config --global alias.st   status
git config --global alias.sts  "status -s"
git config --global alias.br   branch
git config --global alias.re   remote
git config --global alias.di   diff
git config --global alias.type "cat-file -t"
git config --global alias.dump "cat-file -p"
git config --global alias.lo   "log --oneline"
git config --global alias.ll   "log --pretty=format:'%h %ad | %s%d [%Cgreen%an%Creset]' --graph --date=short"
git config --global alias.lg   "log --graph --pretty=format:'%Cred%h%Creset %ad |%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset [%Cgreen%an%Creset]' --abbrev-commit --date=short"
```

### 安裝 [Angular CLI](https://github.com/angular/angular-cli)

```
sudo npm install -g @angular/cli
```

### 安裝 [NG-Toolkit](https://github.com/maciejtreder/ng-toolkit)

```
sudo npm install -g @ng-toolkit/init
```

### 安裝 [JSON Server](https://github.com/typicode/json-server)

```
sudo npm install -g json-server
```

### 安裝 [Kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl) 工具 (Kubernetes)

```
sudo apt-get update && sudo apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF >kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo mv kubernetes.list /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update && sudo apt-get install -y kubectl
```

### 安裝 [Helm](https://docs.helm.sh/using_helm/#installing-helm) 工具 (Kubernetes)

```
curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get | bash
```

### 安裝 [Vim](https://www.vim.org/) 外掛

```
git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim

cat <<'EOF' >> ~/.vimrc

set nocompatible              " be iMproved, required
filetype off                  " required

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')

" let Vundle manage Vundle, required
Plugin 'gmarik/Vundle.vim'

" https://github.com/tomasr/molokai
Plugin 'molokai'
" https://github.com/rainglow/vim
Plugin 'rainglow/vim'

Plugin 'Chiel92/vim-autoformat'
Plugin 'leafgarland/typescript-vim'

Plugin 'c9s/helper.vim'
Plugin 'c9s/treemenu.vim'
Plugin 'c9s/vikube.vim'

" All of your Plugins must be added before the following line
call vundle#end()            " required
filetype plugin indent on    " required

" To ignore plugin indent changes, instead use:
"filetype plugin on
"
" Brief help
" :PluginList          - list configured plugins
" :PluginInstall(!)    - install (update) plugins
" :PluginSearch(!) foo - search (or refresh cache first) for foo
" :PluginClean(!)      - confirm (or auto-approve) removal of unused plugins
"
" see :h vundle for more details or wiki for FAQ
" Put your non-Plugin stuff after this line

set encoding=utf-8

" 關閉「虛擬編輯」(Virtual Edit)
set virtualedit=

" 顯示所有輸入的命令，例如按下 <leader> 字元，預設就會顯示 \
set showcmd

" 顯示行號
"set number

" 設定 VikubeExplorer 可以每兩秒自動更新
let g:vikube_autoupdate = 1

EOF

vim +PluginInstall +qall -f

#echo colorscheme molokai >> ~/.vimrc && vim +PluginInstall +qall
echo colorscheme azure >> ~/.vimrc && vim +PluginInstall +qall

# 安裝 F8 快速鍵：可快速關閉目前檔案的 auto indent 設定

cat <<'EOF' >> ~/.vimrc
" Disabling auto indent for the current fileEdit by hit F8
nnoremap <F8> :setl noai nocin nosi inde=<CR>
EOF

# 安裝 Ctrl 右鍵 左鍵 切換 Tabs ( :tabnext , :tabprev )，按下 Ctrl-n 建立新頁籤
# https://stackoverflow.com/questions/6832364/gvim-switching-tabs-with-keyboard

cat <<'EOF' >> ~/.vimrc
" Map Ctrl-Left & Ctrl-Right to switching tabs Ctrl-n to open new tab
map <C-Left> <Esc>:tabprev<CR>
map <C-Right> <Esc>:tabnext<CR>
map <C-n> <Esc>:tabnew<CR>
" Hit :qa can quit all tabs
map <C-Up> <Esc>:tab ball<CR>

" Open ~/.vimrc file with Ctrl-h
map <C-h> <Esc>:edit ~/.vimrc<CR>

" Quit current file with Ctrl-w
map <C-w> <Esc>:q<CR>

" Disable beeping
set noeb vb t_vb=
EOF
```

### 安裝 [Azure CLI 2.0](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli-apt?view=azure-cli-latest)

```
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

az login
```

調整預設 `az` 參數

```
az configure

cat <<'EOF' > ~/.azure/config
[cloud]
name = AzureCloud

[core]
collect_telemetry = no
output = table

[logging]
enable_log_file = no
EOF
```

### 升級所有套件

```
sudo apt-get update && sudo apt-get upgrade
```

### 設定遠端電腦 SSH 連線認證

```
cat ~/.ssh/id_rsa.pub | ssh user@ip.add.re.ss tee -a ~/.ssh/authorized_keys
```

### 解決在 WSL 在 Disk I/O 超級超級慢的問題

目前微軟的 WSL 團隊，在 [Windows Defender/Anti-malware Causing Performance Issues after CU update · Issue #1932 · Microsoft/WSL](https://github.com/Microsoft/WSL/issues/1932) 這個 Issue 中很明確的提到：

> any fix in this area will require great care, so will take a little while. But we ARE keen to improve this scenario.

簡單來說，Windows 10 內建的防毒引擎 Windows Defender 有個「即時保護」功能，而這個功能因為會掃描本機電腦所有的 I/O 存取，當你在 WSL 中需要存取大量檔案時，存取效率就會大打折扣。例如你只要在輸入 `npm install` 命令，就會讓在安裝大量 npm 套件檔案時，觸發 Windows Defender 的「即時保護」功能，即便你已經將資料夾全部排除在掃瞄範圍外，也於事無補。

所以，目前為止「唯一」的解決方案，就是暫時【關閉即時保護功能】！

不過，這樣的設定可能會對你的電腦帶來一些風險，各位再關閉前請三思。不過，只要一關閉，WSL 的執行速度至少可以快 2 倍以上。

以下是暫時關閉「即時保護」功能，請以系統管理員身分開啟 PowerShell 並執行以下命令：

```powrshell
Set-MpPreference -DisableRealtimeMonitoring $true
```

如果要在 Command Prompt 下執行，可以參考以下命令：

```powrshell
powershell -Command "Set-MpPreference -DisableRealtimeMonitoring $true"
```

如果要快速切換回安全設定，可以參考以下命令：

-   PowerShell: `Set-MpPreference -DisableRealtimeMonitoring $false`
-   命令提示字元: `powershell -Command "Set-MpPreference -DisableRealtimeMonitoring $false"`

> 你是否還有其他設定 WSL 的心得呢？歡迎留言分享！ :)
