從零搭建符合自己需求的開發環境

從零搭建符合自己需求的開發環境

本文長期持續更新中,保持和自己實際開發環境一致,歡迎關注交流討論!

前言

這篇文章,一是總結自己,二是給新上道的小白一些思路,三是 何時能重組大學時的EXplosion工作組呢?

現狀分析

個人自述

成長於一個有著IT背景的家庭,從小學到大學瘋狂參加各種機器人比賽,曾多次獲得國一等。

北京211本科,專業先後為 電子資訊工程 -> 電腦科學與技術 -> 虛擬化與雲基礎設施,在法國巴黎留學過一年多,曾作為一個Java後端工程師就職於新疆某科技公司互聯網部門。

個人的知識與技術主要是圍繞Java的後端技術棧,其次是關於運維和軟體工程方面,但前端、移動端以及遊戲相關開發技術也密切關注。

已有的設備

筆記型電腦電腦

我當前的筆記型電腦時一台 華為 2020款 MateBook 13,CPU 為 Intel Core i5-10210U 1.6GHz (基準速度 2.11Ghz),記憶體 16GB 2133MHz,獨顯 MX250 2G,500GB 固態,十點2k觸屏,1雷電口(充電口),1普通type-c口,開機按鈕有指紋解鎖,系統為 Windows 10 家庭中文版。

配置分析與選購的參考思維

作為一個開發,有必要有一台配置好一些的電腦,可以減少很多不必要的麻煩。

CPU:其實i5和i7沒差多少,可以從這裡省一部分錢。核心的數量,在一般軟體使用中,由於通常沒有基於多核的優化,講道理雙核就夠。但考慮到系統自身的多核調用優化,以及最重要的,後端程式與本地運維模擬集群時,會用到多核,所以請盡量還是選購四核的cpu。至於台式8核的cpu,仔細想想自己用的到么?多的錢應當放在單核的速度上。

記憶體:在我的工作經驗範疇內,記憶體是越多越好,但作為開發,請盡量記憶體至少16GB,不要低於8GB,如果有多的錢,先投資在記憶體存儲量上,其次是速度上,但避免買雜牌,同品牌同參數記憶體條,沒必要准求它是哪個更貴的系列,因為它說的系列優勢你多半用不到或體驗不明顯。

獨顯:我是就這一台筆記型電腦,平常還要打絕地求生呢…一般開發並不需要獨顯,如果涉及 3D 遊戲開發,請配塊高級顯示卡。

硬碟:2020年了,別再機械硬碟了,固態都好幾代了…作為一個開發,打交道的永遠不只是記憶體里的那點動態數據,把顯示卡和cpu剩的錢換一塊1T的M.2固態吧,這帶來的各方面體驗提升,是硬體升級里最為明顯的。

2k與觸屏:2k和4k,用過了,再看回1080p,你會懷疑自己視力不良了…觸屏,偶爾寫個Androidapp,不用接線連手機開開發者模式,直接第一時間在觸屏上滑動模擬器,不爽么?平常瀏覽網頁或圖片,用習慣了,也比用滑鼠滾輪和鍵盤快捷鍵操作方便。

type-c與雷電口:用過都說好,當然如果電腦還有別的口就更好了,單獨買一個USB和雷電雙口的U盤,太爽了。

系統生物解鎖:原本我很喜歡攝影機window hello解鎖,但用了一段時間開機鍵指紋解鎖後,感覺更加穩定,二者速度通常都比敲密碼快,越快越能保證臨時打開電腦時不會忘記那一瞬間的靈感。

作業系統:我是因為目前就用這一台電腦,平常要和朋友玩絕地求生等遊戲,自然還堅守著Windows陣營。但從開發經歷上講,Mac OS除了一開始讓人覺得反人類,實在是太香了。個人仍然不推薦linux系統,比如有著很好UI的Ubuntu,因為所有linux和windows有的好工具,mac os基本都有,但linux如果開發者自己沒有十足的功底,很容易被一些繁雜瑣碎的事情耽誤時間。mac os有和linux一樣方便的文件管理結構,有和windows不分伯仲的ui(個人覺得甚至更勝一籌),和linux伺服器交互也較windows方便。有些時候想做一些簡單的服務端程式的本地模擬測試,windows經常因為各種原因很令開發者頭疼,而mac os和linux憑藉它們都是源於Unix的系統體系,會方便許多。Windows系統如果為Win 10,請盡量保持更新。

遇到過的設備配置坑點

諸如gitlab、nexus repository 3等,硬體推薦需求為4核8G及以上,當然稍微低一點配置也能運行,但是太低會出問題,低一點會很卡,總體配置越高越好。

又比如docker,windows 10 需要pro或者home的19000+的版本,因為牽扯到了虛擬化問題,兼容Hyper-V架構需要一些home低版本默認系統所沒有的東西。

雲伺服器

一台阿里雲1C2G輕量應用伺服器,目前架設著個人網站和一個建設中的部落格系統以及某私有商用計算器。

兩台阿里雲1C2G普通雲伺服器,用於日常實驗折騰。

開發環境需求分析

一套完整軟體項目開發流程,會從文檔相關的需求分析做起,然後是程式碼的編寫,接著進行驗證測試,通過了進行部署,最後是運營維護。不論是傳統的瀑布式,還是現在的敏捷與DevOps,需求+設計+程式碼+測試+部署,這個基本流程單元是沒有徹底的完全變過的,在互聯網模式下軟體工程的演變,也僅僅是加快了這個流程的循環速度,並適當簡化優化部分步驟,在部分過程中加入自動化,減小整體的花銷並提高效率。

需求:首先,需求要被記錄下來,並列入開發流程的時間線,在測試完成進行部署前可以再次核對驗證。其次,需求要被拆分到細節,明確的需求分析可以大幅提高設計與程式碼甚至測試的效率,同時更容易做出優先順序調整從而規劃好時間項目周期。最後,需求最好能標記出版本,將不同部分拆分開,方便程式碼合併以及部署發版,對每一次迭代內容更加清晰。需求方面迫切需要一個公示板和一個能區分版本的日誌。

設計:我目前選用Xmind畫思維導圖,濾清思路與將重要功能模組化,還可以表示成簡單的類圖與數據結構圖從而搞清楚數據流向及關係,最重要的是,它免費且可以導出成很多格式。那麼設計方面的需求便是,可以打標籤進行細緻分類收藏的,文件管理系統。

程式碼:我的主要開發語言是Java,但是也必然會去涉及其他語言,比如前端用到JavaScript和Html,Android端用到Kotlin和Dart,運維和後端用到Golang和Shell,甚至遊戲開發用到C#和C++等等。程式碼方面的需求主要是需要一個輕量級的私有程式碼倉庫,同時最好有程式碼審查功能,方便以後萬一呢,EXplosion工作組重組,我得確保團隊程式碼品質。

測試:之前工作時,測試部分相對敷衍,後端會有手動單元測試,但目的其實只是驗證編譯不報錯順帶生成介面文檔,而前端的測試以及整體的測試,僅僅是唯一的測試工程師手動對著設計的測試用例進行測試,並自己手動書寫測試報告,忙的時候或者太簡單的程式碼更改,所有的測試都可能被跳過。測試相關需求說起來就很簡單了,至少實現自動化。

部署:工作時的開發測試環境是提交程式碼自動部署的,這大大提高了和前端進行聯調的效率。目前我個人的網站後端使用beego框架進行的簡單開發,在通過手動交叉編譯後,手動進行部署。現在想一了下,其實部署環境通常是固定不變的,部署的操作可以提煉出來寫成腳本自動運行,所以部署方面的需求也是實現自動化。

技術選型

雲伺服器作業系統

我的雲伺服器安裝的作業系統為Ubuntu 20.04 x86_64,推薦理由是apt使用方便且各種包更全更新。
真正最終確定作業系統的原因在於,ubuntu 20.04將持續維護到2030年,centos的研究方向改為了centos stream不再會有centos 9,而centos 7維護將結束於2024、centos 8維護將結束於2021。

我是長久以來一直用的CentOS,畢竟入門就是那本「黑色聖經」(《鳥哥的Linux私房菜》)。
有人說centos性能和穩定性比ubuntu更好,其實伺服器端系統,同樣是LTS長期支援版本,系統上的性能和穩定性都尚可且差不多,伺服器運行的其它程式程式碼的性能及穩定性才是關鍵影響因素。

容器引擎

目前選擇的Docker,但只是簡單使用,未進行複雜容器編排,由於其安裝配置使用,真的是相對太簡單了,前期使用遇到各種奇葩問題的概率也相對較低,網上文章教程也多,配套工具也多(docker hub和docker compose不香么)。

未來可能會徹底改用Kubernetes(k8s),畢竟k8s宣布將要徹底放棄了dockershim,k8s和docker目前容器運行時都支援containerd,在之後對容器編排的需求變得更為重要時,相信轉型也方便。

程式碼倉庫

首先是版本控制服務,git都支援大文件(git lfs)了,SVN等其它工具,真的還那麼香么?用過git的都說好,哪怕是Unreal Engine都集成git了。

再說下運行git的服務及程式碼存儲倉庫,我最終選擇了gitea搭建私有程式碼倉庫(存儲採用mariadb)。

github、bitbucket、gitee、coding、teambition等等,私有倉庫及團隊合作相關的免費限制條件太多,雖然小規模開發肯定夠用,但早晚會面臨要繳費或為了免費而費神費力的情況。

gitlab、gogs、gitea等等,不選擇gitlab純粹只是因為現在中國個人能買到的極便宜云伺服器難以很好運行(這玩意至少要求4C8G),gogs和gitea本是同根生,採用Golang開發,超級輕量級,功能完全夠用,區別在於,前者是個人維護更新較慢,後者為社區維護更新較快。

最後看下程式碼的存儲,我的gitea的數據存儲選擇的mariadb,理由很簡單:我儘可能的少安裝幾種資料庫,剩的之後萬一沒注意出現各種數據不兼容的情況,會處理起來很麻煩。mysql平常很常用,mysql和mariadb兩者起初也是同一個東西,不過前者是商業產品,後者完全就是開源社區維護,mysql community version和mariadb都是免費的,但是mysql community version並不提供執行緒池(這部分在收費的企業版提供),而mariadb支援執行緒池,那麼mariadb真香。

持續集成部署

也就是常說的CICD(Continuous Integration & Continuous Deployment)了,當然也有人說其中還包含著持續交付CD(Continuous Delivery),都對了,就是一套流程,從程式碼上傳,到程式碼構建,接著運行測試、最後測試過了進行部署,讓這一套流程自動化,就需要CICD工具了。

我最後選擇的是Drone這個輕量級工具,而沒有選擇Jenkins和Gitlab CI,也沒選擇其它網路在線服務。Jenkins和Gitlab CI,兩個都太重量級了,我的系統配置(1C2G)完全跟不上,外加Jenkins默認UI好醜。其它網路在線服務,多半也是重新封裝了Jenkins,弄了套好看的可視化介面,不過,使用起來總覺得不自由。

開發環境安裝

提示:以下安裝過程中,所有下載地址均已改為中國地址無需翻牆,所有參數為必填參數與建議填寫參數,未填寫的參數均為可選參數。

注意:以下內容均安裝在同一台伺服器內。但是docker設置了內部子網,且dockers內的不同容器分配了各自的內網ip,目的僅是為了模擬部署在不同的伺服器上情況。以下使用內網ip的地方,均可以替換成等效的外網ip,但是使用外網ip的地方均不能被替換成內網ip(且應當被替換成域名路徑),原因是這些外網ip是暴露給實際遠端的終端客戶的,如果使用內網ip,客戶由於不處於同一子網故無法解析地址。

安裝容器引擎

在雲伺服器上安裝Docker

以ssh的方式連接上雲伺服器,比如Windows用戶,這裡推薦使用MobaXterm,個人使用免費、運行流暢、UI介面美觀、各種功能多(我用過之後就再也沒打開過PuTTY了)。

準備工作

更新apt包索引,並安裝必要的一些系統工具包,以允許apt通過HTTPS使用存儲庫。

sudo apt-get update

sudo apt-get -y install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

安裝GPG密鑰。

curl -fsSL //mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -

通過搜索正常的密鑰後8位(0EBFCD88),驗證GPG密鑰安裝成功。

sudo apt-key fingerprint 0EBFCD88

pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <[email protected]>
sub   rsa4096 2017-02-22 [S]

設置穩定存儲庫。

sudo add-apt-repository \
   "deb [arch=amd64] //mirrors.aliyun.com/docker-ce/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
安裝並驗證

更新apt包索引,安裝最新版本的Docker Engine和containerd。

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

運行一下hello-world這個官方遠程庫里的image,容器名設置為hi-docker。

sudo docker run --name hi-docker hello-world

如果你看到了「Hello from Docker!」,則說明Docker已經正常安裝。

Hello from Docker!
This message shows that your installation appears to be working correctly.

刪除這個成功完成運行的hi-docker容器,然後刪除本地無用的hello-world鏡像。

sudo docker rm hi-docker
sudo docker image rm hello-world
配置子網

為之後的Docker容器,使用docker network命令創建子網,默認是與宿主機橋接。

sudo docker network create --subnet 172.18.0.0/16 \
    --gateway 172.18.0.1 \
    ex-network

創建成功,會顯示一個network的id號,可以通過id號或network名稱查詢子網詳情。

sudo docker network inspect ex-network

搭建程式碼倉庫

在雲伺服器上安裝Gitea搭建Git服務和私有遠程程式碼倉庫

以容器形式安裝mariadb用於gitea的數據存儲
sudo mkdir -p /data/docker/mariadb
sudo docker run --name mariadb \
    --network ex-network \
    --ip 172.18.0.2 \
    -p 3306:3306 \
    -v /data/docker/mariadb/:/var/lib/mysql \
    --restart always \
    -e "MYSQL_ROOT_PASSWORD=root" \
    -e "MYSQL_DATABASE=gitea" \
    -e "MYSQL_USER=gitea" \
    -e "MYSQL_PASSWORD=gitea" \
    -itd \
    mariadb:latest
以容器形式安裝gitea
sudo mkdir -p /data/docker/gitea
sudo docker run --name gitea \
    --network ex-network \
    --ip 172.18.0.3 \
    -p 3000:3000 \
    -p 3022:22 \
    -v /data/docker/gitea:/data \
    --restart always \
    -itd \
    gitea/gitea:latest
Gitea初始設置

打開一個web瀏覽器,地址欄輸入 //雲伺服器公網ip地址:3000,你將看到一個Gitea的初始化配置的UI介面。

提示:以下各種設置不說明則保持默認值。資料庫主機、用戶名資料庫用戶密碼及資料庫名稱見上文。

資料庫設置

資料庫類型:MySQL
資料庫主機:172.18.0.2:3306
用戶名:gitea
資料庫用戶密碼:gitea
資料庫名稱:gitea
字符集:utf8mb4

一般設置

站點名稱:EXplosion

可選設置

管理員帳號設置:自己的用戶名、密碼和郵箱。

修改Gitea地址

gitea默認的地址為localhost。如果所有操作都是本地內部的,那麼無所謂了,可以跳過此步驟。如果你需要從別的地方與gitea產生交互,比如子網劃分後不同地址的容器內程式想通過webhooks進行交互,又比如外網客戶從遠端克隆程式碼,都會發生localhost實際地址不一致無許可權訪問的問題,此時需要把localhost改為可訪問的公網地址。

操作很簡單,找到/data/docker/gitea/gitea/conf/app.ini這個文件,打開,並全文所有的localhost替換成 雲伺服器公網ip地址(最好是域名)。

配置持續集成部署工具

創建新的 OAuth2 應用程式

登錄Gitea後,點擊右上角頭像,點擊設置,選擇」應用「分頁。在管理OAuth2應用程式下的,創建新的 OAuth2 應用程式的裡面,填寫內容。

應用名稱:drone

重定向URI://雲伺服器公網ip地址:3080/login

點擊生成,將生成的客戶端ID(DRONE_GITEA_CLIENT_ID)和客戶端密鑰(DRONE_GITEA_CLIENT_SECRET)記錄保存下來,點擊保存。

生成Shared Secret

生成Shared Secret(DRONE_RPC_SECRET)用於之後runners和central Drone server之間的通訊。

openssl rand -hex 16

安裝Drone Server

提示:目前drone的驗證採用 oath2,不再需要設置DRONE_GIT_USERNAME和DRONE_GIT_PASSWORD。如果倉庫的可見性並不是完全公開,drone默認只對github的私有倉進行授權克隆,其他情況需手動將DRONE_GIT_ALWAYS_AUTH設置為true。

sudo docker run --name=drone \
  --volume=/data/docker/drone:/data \
  --env=DRONE_GITEA_SERVER="//雲伺服器公網ip地址:3000" \
  --env=DRONE_GITEA_CLIENT_ID="DRONE_GITEA_CLIENT_ID" \
  --env=DRONE_GITEA_CLIENT_SECRET="DRONE_GITEA_CLIENT_SECRET" \
  --env=DRONE_RPC_SECRET="DRONE_RPC_SECRET" \
  --env=DRONE_SERVER_HOST="雲伺服器公網ip地址:3080" \
  --env=DRONE_SERVER_PROTO="http" \
  --env=DRONE_GIT_ALWAYS_AUTH=true \
  --network ex-network \
  --ip 172.18.0.4 \
  -p 3080:80 \
  -p 443:443 \
  --restart=always \
  -itd \
  drone/drone:latest

安裝Drone Runner

sudo docker run --name drone-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e DRONE_RPC_PROTO=http \
  -e DRONE_RPC_HOST="123.57.219.68:3080" \
  -e DRONE_RPC_SECRET="bc6b8c32f8513f7abbb1069262f1ebb7" \
  -e DRONE_RUNNER_CAPACITY=2 \
  -e DRONE_RUNNER_NAME="DroneRunner" \
  --network ex-network \
  --ip 172.18.0.5 \
  -p 6000:3000 \
  --restart always \
  -itd \
  drone/drone-runner-docker:latest

runner安裝完成後,可以使用docker logs查看日誌內容,從而驗證是否安裝成功。

sudo docker logs drone-runner