天天看點

建構一個基于容器的開發環境

前言:GNU/Linux(以下簡稱Linux)是目前伺服器使用廣泛的系統,而開發人員使用的作業系統大多數卻是Windows。雖然現在主流的語言幾乎都支援跨平台的特性,但在開發過程中仍然會因為平台不一緻導緻一些莫名其妙的問題,最經典的當屬CRLF(回車換行符)在Windows和Unix系統間造成的問題。而Windows糟糕的軟體管理也一直被開發人員嫌棄,新機器裝一個齊全的開發環境往往要重複經曆打開浏覽器-搜尋軟體-下載下傳軟體-手動安裝的過程,這個過程在Linux下利用包管理器往往隻需要一行指令搞定。

但在國内,想要将Linux當做主力系統困難重重,常用的微信,釘釘,企業微信都沒有可用的第一方Linux用戶端,Linux下deepin-wine的解決方案也不盡完美,Windows下開一個Linux虛拟機動辄幾十G的大小又顯得笨拙,這篇文章就介紹一下如何利用近年來火爆的容器技術搭建一個靈活,可複用,帶版本控制的開發環境。

前置條件:

  1. Docker,Windows下則是Docker Desktop
  2. 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過程中沉澱的工具:

  1. 丢掉預設難用的bash shell, 用zsh和插件打造一個好用的shell:

    zsh & oh-my-zsh & powerlevel10k & zsh-autosuggestions & zsh-syntax-highlighting

  2. 終端複用器,讓你友善的管理終端,并在終端中斷後可以随時繼續你的上一次工作:

    tmux & oh-my-tmux

  3. 終端内文本編輯、檔案浏覽、檔案/檔案内容模糊搜尋:

    neovim & ranger & fzf & ripgrep

  4. 優化終端顯示效果,需要安裝修補字型,推薦nerd-fonts,倉庫中選擇一個喜歡的字型本地安裝,配置一下即可
  5. 直接啟動容器的話代碼是在容器裡的,如果考慮到代碼安全性,啟動的時候就配置一下代碼檔案夾的映射吧

上述工具要想做到好用免不了一些配置,這裡貼上我個人的vim zsh tmux配置以供參考,配置在github gist上長期維護,之後會專門寫一篇文章介紹這些工具的用法

最終效果展示:

建構一個基于容器的開發環境

總結

建構好的容器開發環境,利用docker鏡像的版本控制、遷移、上傳等特性可以做到靈活、複用,從此換電腦隻需要遷移鏡像即可開發,告别Windows和Linux間莫名奇妙的環境問題。