相關博文:
- Ubuntu 簡單安裝和配置 GitLab
- Ubuntu 簡單安裝 Docker
- Ubuntu Docker 簡單安裝 GitLab
- Ubuntu Docker 安裝和配置 GitLab CI 持續集成
服務器版本 Ubuntu 16.04 LTS。
經過上面四篇博文中的相關安裝和配置,我們主要完成了兩個容器的創建和運行:gitlab
和gitlab-runner
(GitLab 站點和 GitLab CI 服務):
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
696d559ce382 gitlab/gitlab-runner:latest "/usr/bin/dumb-ini..." 5 days ago Up 25 minutes gitlab-runner
ff95f354200d gitlab/gitlab-ce:latest "/assets/wrapper" 7 days ago Up 6 days (healthy) 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:8888->22/tcp gitlab
本篇博文目的:使用 GitLab CI 腳本編譯 ASP.NET Core 2.0 程序,然后將編譯后的文件傳輸到服務器上,最后使用 SSH 連接服務器,并運行程序,完成發布和部署。
簡單來說,就是我們每次使用git push
提交完代碼,自動完成發布和部署。
我們再理一下實現上面目的關鍵點:
- 創建一個 ASP.NET Core 2.0 示例程序
- 完善并正確的
.gitlab-ci.yml
文件配置 - GitLab CI 服務器使用
ssh
連接到測試服務器(在 Docker 中) - 使用
scp
進行服務器之間的文件傳輸 - 使用
supervisor
進行站點程序的進程管理
我花了很長時間配置第三步,其實最后解決也很簡單,當然都是馬后炮的結論?,下面我們分別來進行操作。
1. 創建 ASP.NET Core 2.0 示例程序
我自己創建示例程序:http://40.125.206.47/team/hwapp
注:服務器快過期了,大家可以隨便搞?。
自己創建的話,也很簡單,官方教程:https://www.microsoft.com/net/core#linuxubuntu
我再搬運下命令(安裝 .NET Core 2.0,并創建 ASP.NET Core 2.0 示例程序):
$ curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
$ sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
$ sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-xenial-prod xenial main" > /etc/apt/sources.list.d/dotnetdev.list'$ sudo apt-get update
$ sudo apt-get install dotnet-sdk-2.0.0$ dotnet new webapi -o hwapp
$ cd hwapp
最后,綁定下 ASP.NET Core 2.0 程序端口:
public class Program
{public static void Main(string[] args){BuildWebHost(args).Run();}public static IWebHost BuildWebHost(string[] args) =>WebHost.CreateDefaultBuilder(args).UseKestrel() //add code.UseUrls($"http://*:8088") //add code.UseStartup<hwapp.Startup>().Build();
}
2. .gitlab-ci.yml 文件配置
我的.gitlab-ci.yml
文件配置(http://40.125.206.47/team/hwapp/blob/master/.gitlab-ci.yml):
image: microsoft/aspnetcore-build
stages:- build- deploy_dev
before_script:# Install ssh-agent if not already installed, it is required by Docker.# (change apt-get to yum if you use a CentOS-based image)- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'# Run ssh-agent (inside the build environment)- eval $(ssh-agent -s)# Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store# error: https://gitlab.com/gitlab-examples/ssh-private-key/issues/1# - echo "$SSH_PRIVATE_KEY_DEV"- ssh-add <(echo "$SSH_PRIVATE_KEY_DEV")# For Docker builds disable host key checking. Be aware that by adding that# you are suspectible to man-in-the-middle attacks.# WARNING: Use this only with the Docker executor, if you use it with shell# you will overwrite your user's SSH config.- mkdir -p ~/.ssh- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
build_job:stage: buildonly:- masterscript:- dotnet restore- dotnet build
deploy_dev_job:stage: deploy_devenvironment:name: developmentonly:- masterscript:# 發布程序并部署運行- dotnet publish -c Release --output bin/publish- scp -r bin/publish root@$DEPLOY_SERVER_DEV:/home/xishuai/wwwroot/hwapp- ssh root@$DEPLOY_SERVER_DEV "supervisorctl restart hwapp && curl http://localhost:8088/api/values"
上面是我最終調試成功后的.gitlab-ci.yml
文件配置,其實整個的構建和發布流程,從上面的配置中都可以看出。
這里記錄下一些東西:
配置一開始的image
,設置的是我們用于構建的鏡像(也就是說后面所有的腳本執行,都是在基于這個鏡像創建的容器中),如果不設置的話,默認使用的是我們一開始配置 GitLab CI 填寫的 Docker Image,也可以手動編輯vim /srv/gitlab-runner/config/config.toml
進行修改,我這里使用的是microsoft/aspnetcore-build
鏡像,只用于 ASP.NET Core 應用程序的編譯和構建。
stage
可以理解為臺階,每走一步相當于job
,當然,這里的臺階可以走很多步,需要注意的是,每上一個臺階或者每走一步,都必須基于上一個臺階或上一步執行成功,before_script
執行在這些步驟之前,可以理解為準備工作。
environment
將執行的job
歸納為哪一種執行環境,你可以設置開發環境和正式環境,我們可以通過通過后臺進行查看:
3. GitLab CI 服務器使用 SSH 連接到測試服務器
什么意思呢?就是我們需要在 GitLab CI 構建環境中,使用 SSH 連接到測試服務器,這樣我們才可以做接下來的一些操作。
官方配置:SSH keys when using the Docker executor
.gitlab-ci.yml
示例配置:
before_script:# Install ssh-agent if not already installed, it is required by Docker.# (change apt-get to yum if you use a CentOS-based image)- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'# Run ssh-agent (inside the build environment)- eval $(ssh-agent -s)# Add the SSH key stored in SSH_PRIVATE_KEY_DEV variable to the agent store- ssh-add <(echo "$SSH_PRIVATE_KEY_DEV")# For Docker builds disable host key checking. Be aware that by adding that# you are suspectible to man-in-the-middle attacks.# WARNING: Use this only with the Docker executor, if you use it with shell# you will overwrite your user's SSH config.- mkdir -p ~/.ssh- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'# In order to properly check the server's host key, assuming you created the# SSH_SERVER_HOSTKEYS variable previously, uncomment the following two lines# instead.# - mkdir -p ~/.ssh# - '[[ -f /.dockerenv ]] && echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts'
在進行配置之前,我們需要理一下這個步驟,要不然思路容易混亂,會造成一些問題,可以參考這篇文章:Fixing 'Enter passphrase for /dev/fd/63' in a Gitlab CI job
需要強調一點:別在 GitLab CI 容器中進行 SSH 配置,因為 CI 構建腳本執行在另外的容器中,并且這個容器是動態進行創建的,也沒辦法在這個動態容器中進行配置(指的是手動生成 RSA 密鑰)。
所以,我們只能手動生成 RSA 密鑰,然后強制添加到容器中的 SSH 配置中(通過 RSA 密鑰內容)。
配置步驟:
首先,在任何一臺服務器上,創建 RSA 無密碼的密鑰:
$ ssh-keygen -t rsa -P ''
$ cat /root/.ssh/id_rsa
然后復制 RSA 密鑰內容,添加到/Project/Settings/Pipelines
的Secret variables
配置中(命名為SSH_PRIVATE_KEY_DEV
):
這里需要特別注意,復制內容為(包含開頭和結尾的注釋信息):
-----BEGIN RSA PRIVATE KEY-----
xxxxxxx
-----END RSA PRIVATE KEY-----
我一開始復制沒有包含注釋信息,然后就一直報下面的錯誤:
錯誤代碼:
$ ssh-add <(echo "$SSH_PRIVATE_KEY_DEV")
Enter passphrase for /dev/fd/63: ERROR: Job failed: exit code 1
這里的$SSH_PRIVATE_KEY_DEV
,就是上面我們在Secret variables
中,添加的 RSA 密鑰內容。
錯誤信息就是說需要輸入 RSA 密鑰的密碼,但我創建的確實是無密碼的 RSA 密鑰,也就是說這個密鑰是無效的,我被這個問題折磨了好幾天?,其他人的記錄:
- "Enter passphrase for /dev/fd/63" error(有我的回復?)
- "Enter passphrase for /dev/fd/63" error
- https://gitlab.com/gitlab-examples/ssh-private-key/-/jobs/376082(受這個兄弟的啟發)
配置好這一步之后,然后重新測試下,我們就可以看到下面的執行信息了:
$ ssh-add <(echo "$SSH_PRIVATE_KEY_DEV")
Identity added: /dev/fd/63 (/dev/fd/63)
接著我們需要將這個 RSA 密鑰對應的公鑰,上傳到需要連接到的服務器(也就是我們的測試服務器),命令如下:
$ ssh-copy-id root@40.125.201.75
到此,GitLab CI 中 SSH 的配置基本上完成了,你可以在.gitlab-ci.yml
中添加連接腳本,進行測試:
- ssh root@$DEPLOY_SERVER_DEV "ls && cd /"
一開始,我們說到使用scp
進行服務器之間的文件傳輸,因為scp
可以基于 SSH 連接進行傳輸文件,所以我們直接進行文件傳輸了,示例代碼:
- scp -r bin/publish root@$DEPLOY_SERVER_DEV:/home/xishuai/wwwroot/hwapp
scp
命令參考:http://www.runoob.com/linux/linux-comm-scp.html
4. 使用 Supervisor 進行站點程序的進程管理
可以參考之前的文章:Ubuntu 安裝和使用 Supervisor(進程管理)
這里貼一下,supervisorctl
的常用命令:
命令 | 說明 |
---|---|
supervisorctl stop program_name | 停止某個進程 |
supervisorctl start program_name | 啟動某個進程 |
supervisorctl restart program_name | 重啟某個進程 |
supervisorctl stop all | 停止全部進程 |
supervisorctl reload | 載入最新的配置文件,停止原有進程并按新的配置啟動、管理所有進程 |
supervisorctl update | 根據最新的配置文件,啟動新配置或有改動的進程,配置沒有改動的進程不會受影響而重啟 |
5. 最終效果
Pipelines 管道(地址:http://40.125.206.47/team/hwapp/pipelines)
Build_Job 構建任務(地址:http://40.125.206.47/team/hwapp/-/jobs/113)
Deploy_Dev_Job 發布和部署任務(地址:http://40.125.206.47/team/hwapp/-/jobs/115)
寫在最后:
- GitLab CI & ASP.NET Core 2.0 發布和部署(完成):使用 CI 腳本編譯程序,然后將編譯后的文件傳輸到服務器上,最后運行程序,完成發布和部署。
- GitLab CI & ASP.NET Core 2.0 & Docker 發布和部署(下篇):項目中添加
Dockerfile
文件,使用 CI 腳本構建自定義鏡像,然后在服務器上拉取并創建相應容器,最后啟動容器,完成發布和部署。