前言:GNU/Linux(以下簡稱Linux)是目前服務器使用廣泛的系統,而開發人員使用的操作系統大多數卻是Windows。雖然現在主流的語言幾乎都支持跨平台的特性,但在開發過程中仍然會因為平台不一致導致一些莫名其妙的問題,最經典的當屬CRLF(回車換行符)在Windows和Unix系統間造成的問題。而Windows糟糕的軟件管理也一直被開發人員嫌棄,新機器裝一個齊全的開發環境往往要重復經歷打開瀏覽器-搜索軟件-下載軟件-手動安裝的過程,這個過程在Linux下利用包管理器往往只需要一行命令搞定。
但在國內,想要將Linux當做主力系統困難重重,常用的微信,釘釘,企業微信都沒有可用的第一方Linux客戶端,Linux下deepin-wine的解決方案也不盡完美,Windows下開一個Linux虛擬機動輒幾十G的大小又顯得笨拙,這篇文章就介紹一下如何利用近年來火爆的容器技術搭建一個靈活,可復用,帶版本控制的開發環境。
前置條件:
- Docker,Windows下則是Docker Desktop
- VSCode 或 JetBrains 全家桶
基於容器的開發本質上也就是遠程開發,這方面VSCode 與 JetBrains IntelliJ 的實現有區別:VSCode 直接在遠程環境運行,代碼不保存在本地,JetBrains 則基於FTP/SFTP/FTPS協議在本地與遠程代碼同步,且配置有些繁瑣。本文使用VSCode做演示
一、構建鏡像
選擇一個你熟悉的Linux發行版,基於基礎鏡像構建自己的開發環境,個人偏愛Arch Linux,以這個發行版為例,拉取鏡像,並配置初始開發環境,我做了一個簡單的Dockerfile:
FROM docker.io/library/archlinux:latest
RUN sed -i '1i Server = http://mirrors.aliyun.com/archlinux/$repo/os/$arch' /etc/pacman.d/mirrorlist \
&& sed -i '1i Server = https://mirrors.tencent.com/archlinux/$repo/os/$arch' /etc/pacman.d/mirrorlist \
&& sed -i '$i [archlinuxcn]' /etc/pacman.conf \
&& sed -i '$i SigLevel = TrustAll' /etc/pacman.conf \
&& sed -i '$i Server = https://repo.archlinuxcn.org/$arch' /etc/pacman.conf \
&& sed -i -r 's/^NoExtract\s*=\s*.*/# \0/g' /etc/pacman.conf \
&& pacman -Syyu --noconfirm \
&& pacman -Sy --noconfirm archlinuxcn-keyring && pacman -Su --noconfirm\
&& pacman -Syy --noconfirm git vim neovim zsh oh-my-zsh-git jdk-openjdk jdk8-openjdk jdk11-openjdk \
maven yay zsh python3 go nodejs npm yarn tmux python2 zsh-autosuggestions zsh-syntax-highlighting \
zsh-theme-powerlevel10k ranger python-pip python-neovim wl-clipboard fzf ripgrep man-db \
gcc clang base-devel wqy-zenhei noto-fonts-cjk wget unzip thefuck \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& pacman -Scc --noconfirm \
&& rm -rf /var/lib/pacman/sync/* /var/cache/pacman/pkg/* \
&& echo "" > /var/log/pacman.log
pacman
是Arch Linux 下的包管理器,如果你清楚Dockerfile里的包都有什么作用,可以適當增刪改,以上命令安裝了jdk python go nodejs 和一些好用的命令行工具,配置了國內的時區,添加了包倉庫的國內鏡像源。
之后運行構建命令
docker build -t arch-test .
包含基礎開發環境的鏡像就構建好了
二、配置VSCode
VSCode做到容器內開發的核心就是Remote Development Pack插件,Docker插件能增強體驗,搜索安裝即可,而我們的核心是Remote Development Pack中的這個插件
如果你安裝了Docker插件,可以在側邊欄直接管理Docker容器並將VSCode附加到容器
沒有安裝的話,則只能通過ctrl + shift + p
以命令的形式選擇並附加到容器
附加后的窗口如圖
前面提到,VSCode容器開發實際就是遠程開發,而VSCode的服務是跑在容器里的,所以需要重新安裝擴展,截圖左側位置的按鈕點擊即可在容器里同步本地的拓展
至此基於容器和VSCode的開發環境已經能用了,體驗與Linux上的VSCode基本沒有差別,但還有很多可以優化的地方
三、容器配置
容器的一般應用場景是為了跑一組服務,一般不會對用戶權限做管理,VSCode容器開發默認連接到容器也是root用戶,但對於一些強迫症用戶(比如我),想要用非root用戶開發當然也是支持的,ctrl + shift + p
打開命令面板輸入remote container config
之后選擇就可以編輯當前容器或已存在容器的配置
容器支持以下配置:
{
// 附加VSCode進程時打開的默認目錄
"workspaceFolder": "/path/to/code/in/container/here",
// 進入容器時自動安裝的擴展
"extensions": ["dbaeumer.vscode-eslint"],
// 容器配置,支持settings.json中的任意配置,設置后在當前容器中會覆蓋settings.json中的配置
"settings": {
"terminal.integrated.shell.linux": "/bin/zsh"
},
// 自動轉發的端口
"forwardPorts": [8000],
// 連接時登入的用戶,不設置默認為root
"remoteUser": "vscode",
// VSCode和其子進程繼承的環境變量
"remoteEnv": { "MY_VARIABLE": "some-value" }
}
remoteUser
項設置的前提當然是用戶已創建,所以先在容器內執行或在Dockerfile里加上以下命令
useradd -d /home/vscode -m vscode && passwd vscode
之后設置一下新用戶的密碼即可
容器內開發,調試時跑服務的端口VSCode會自動檢測並轉發到本地,用localhost
即可訪問,感知上與本地開發一樣。實際使用時會自動檢測,如果沒有自動檢測到,配置一下forwardPorts
即可
VSCode自身也支持直接創建開發容器,個人認為不如命令行操作直觀,感興趣的話可以看下微軟官方文檔Create a Dev Container
四、后續優化
大費周章去構建一個基於容器的開發環境只能做到統一開發和生產環境嗎?當然不是,統一環境是基本需求,我們完全可以再花點心思用上Unix系才有的一些命令行神器,讓終端好用到愛不釋手,這里推薦一波本人在使用Linux過程中沉淀的工具:
- 丟掉默認難用的bash shell, 用zsh和插件打造一個好用的shell:
zsh & oh-my-zsh & powerlevel10k & zsh-autosuggestions & zsh-syntax-highlighting - 終端復用器,讓你方便的管理終端,並在終端中斷后可以隨時繼續你的上一次工作:
tmux & oh-my-tmux - 終端內文本編輯、文件瀏覽、文件/文件內容模糊搜索:
neovim & ranger & fzf & ripgrep - 優化終端顯示效果,需要安裝修補字體,推薦nerd-fonts,倉庫中選擇一個喜歡的字體本地安裝,配置一下即可
- 直接啟動容器的話代碼是在容器里的,如果考慮到代碼安全性,啟動的時候就配置一下代碼文件夾的映射吧
上述工具要想做到好用免不了一些配置,這里貼上我個人的vim zsh tmux配置以供參考,配置在github gist上長期維護,之后會專門寫一篇文章介紹這些工具的用法
最終效果展示:
總結
構建好的容器開發環境,利用docker鏡像的版本控制、遷移、上傳等特性可以做到靈活、復用,從此換電腦只需要遷移鏡像即可開發,告別Windows和Linux間莫名奇妙的環境問題。
參考文章:
【1】 https://code.visualstudio.com/docs/remote/remote-overview
【2】 https://docs.docker.com/desktop/