從零開始學習如何部署程式碼

流汗去發表於2018-07-11

前段時間看到了張雲龍的文章 一個程式設計師的成長之路 - 剖析別人,總結自己,裡面有這麼一段話

棧外技術,是指棧內技術的上下游,領域外的相關專業知識,包括但不限於服務端技術、運維、CDN、測試,甚至 UI 設計、產品設計等等,擴充套件你棧內技術的周圍領域,充分理解你的工作在整個技術研發體系中處於怎樣的環節。工作之餘多投入一份精力,把其他棧外技術不斷納入到你的知識體系中來,建立棧外能力。前端想要做的深入,往往會涉及到快取、模板渲染、使用者體驗等知識,沒有相當的棧外技術積累,你很難為自己的團隊爭取到足夠的話語權。

想想自己在公司的時候,基本都是寫業務,做前端相關的工作,但對於其他方面是涉獵比較少,或者基本沒有的。又再想想之前面試的時候,面試官也會問一些棧外問題,比如說你們公司的程式碼是如何釋出部署的,這時候的我是一臉懵逼的。這就使得我想要懂得如何部署程式碼,以下是折騰的過程,記錄一下。

雲伺服器

雲伺服器的購買,可以選擇阿里雲和騰訊雲,我之前並沒有仔細地去比價兩者的價格如何,想著就是用來玩玩如何部署的,也就沒有多在意這些,畢竟也不是長期購買,花不了幾個錢,就選了騰訊雲。至於選購什麼配置的伺服器,就看個人了。買完之後,還要做一些認證等,需要等待一兩天的時間。對了,我還買了一個域名,但是後來發現備案的手續挺麻煩的,想著之後用 ip 地址也可以訪問,就沒有去管了。

ssh 登入

有了伺服器後,你需要登入。那要怎麼登入呢,這裡介紹一個簡單的方法。

本地生成 ssh 公鑰

首先,你需要確認自己是否已經擁有祕鑰。預設情況下,使用者的 SSH 祕鑰儲存在~/.ssh 目錄下。進入該目錄並列出其中內容,便可以快速確認自己是否已擁有祕鑰:

# 本地
$ cd ~/.ssh
$ ls
config      id_rsa      id_rsa.pub  known_hosts
複製程式碼

我們需要尋找一對以 id_dsa 或 id_rsa 命名的檔案,其中一個帶有 .pub 副檔名。.pub 檔案是你的公鑰,另 一個則是私鑰。如果找不到這樣的檔案或者根本沒有 .ssh 目錄, 你可以通過執行 ssh-keygen 程式來建立它們。

# 本地
$ ssh-keygen
Generating public/private rsa key pair.
# 輸入 enter 鍵
Enter file in which to save the key (/Users/laohan/.ssh/id_rsa):
Created directory '/Users/laohan/.ssh'.
# 兩次輸入密碼
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/laohan/.ssh/id_rsa.
Your public key has been saved in /Users/laohan/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:XhI9aeGsVJklGyUTvNu+6ABzOZdZL2+y5aMOVQa+ZvI laohan@bogon
The key's randomart image is:
+---[RSA 2048]----+
|         .O*+    |
|         =+X .   |
|        o O.o o  |
|       . =.= =   |
|      o S *o* .  |
|       = =.*.o   |
|        o ..E +  |
|         . o.*.  |
|         .o.=o.. |
+----[SHA256]-----+
複製程式碼

首先 ssh-keygen 會確認金鑰的儲存位置(預設是 .ssh/id_rsa),然後它會讓你重複一個密碼兩次,如果不想在使用公鑰的時候輸入密碼,可以留空。

公鑰看起來是這樣的:

$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDc4xbJxlMTgiE13I1RL6IsG44+3CQc8Ft03eZnYfNrPVeQIf9r9kTuArSiUnY+BHXn3mrQ5i+5AGi+alys94Pum2dZ68QtlY1QdEl4iN3LFXUkbJc+M0rllaDGH5JNtfk5imVqDo8Tn7aJsFd4IXbwrl3Euf+ccOb+s92RHwzbSRx37tP9pLF9ujfL0UXfg3+DmRJMJT7iN3OiJxfuF5k8KSySEz+YbhQoNeySuvVPeRHG/U6xOGcpzNjQIPApGsuFdLT5R/5x15W7SrC//XWuIQMmlVTW2X0YH+5NjT0nlLVWxS4drtRCS66JXtRceVqs5H5InbsLfALfTPyIkZ4t laohan@bogon
複製程式碼

具體可以參考這裡 Generating a new SSH key and adding it to the ssh-agent

雲伺服器配置

$ cd
$ mkdir .ssh && chmod 700 .ssh
$ touch .ssh/authorized_keys && chmod 600 .ssh/authorized_keys
複製程式碼

接下來,把開發者的 SSH 公鑰新增到這個使用者的 authorized_keys 檔案中。

$ vim .ssh/authorized_keys
# 把之前生成是 SSH 公鑰新增到檔案尾部
複製程式碼

本地 config 配置

現在已經可以通過 ssh 無密碼的方式登入雲伺服器了

ssh root@IP
# IP 為 雲伺服器的 IP 地址
複製程式碼

如上,是不是感覺很方便。可是這種方式,你還是需要知道雲伺服器的 ip 地址,那有沒有更省腦的方式呢?

有的,在~/.ssh 下的 config 檔案中新增以下程式碼即可

Host hostname # hostname 為你想要設定的別名
HostName IP # IP 為雲伺服器的 IP 地址
User root
IdentitiesOnly yes
複製程式碼

之後,就可以通過如下的方式登入到雲伺服器了

ssh hostname # hostname 為你剛才設定的名稱
複製程式碼

程式碼

個人理解,雲伺服器也就是一臺機器,你的程式碼在自己的電腦怎麼跑,到了雲伺服器還是怎麼跑,只是執行的環境不一樣了,需要做一些配置。

現在,我們已經有了雲伺服器了,接下來就是如何把我們能在本地跑起來的程式碼部署在伺服器上。

我採用的方式比較簡單,就是直接在把我本地的程式碼 push 到 github 上面,然後在伺服器那裡用 git clone,把程式碼下載到本地。github 地址 koa-demo。又或者你可以把程式碼在本地打包後,利用 scp 遠端複製。

雲伺服器設定 nginx

nginx,是運維同學經常打交道的。你可能聽過反向代理、負載均衡等名詞,這都是跟 nginx 有關的。

安裝 nginx

我的伺服器是 centos 系統的,所以安裝的方式如下

yum install -y nginx
複製程式碼

至於其他系統的安裝方式,自行查詢了。

conf 配置

對於 nginx 來說,主要就是 nginx.cof 這份配置檔案,位於/etc/nginx 路徑下,下面就進行修改

cd /etc/nginx
vi nginx.conf
複製程式碼

修改後的內容如下

nginx conf
注意:確保紅色圈中的 1 部分沒有被註釋,圈中的 2 部分註釋。

這樣做的目的是為了如果之後需要新增多個 server 的話,都在 nginx.conf 檔案改,就不容易維護了。 接下來,新增我們這次需要的跟 nginx 相關的檔案

cd /etc/nginx/conf.d
touch koa-demo.conf
vi koa-demo.conf
複製程式碼

然後,把以下內容 copy 到 koa-demo.con 中並儲存

upstream koa-demo {
  server 127.0.0.1:3000;
}

server {
  listen 80;
  location / {
    proxy_pass http://koa-demo;
  }
}
複製程式碼

之後,使用下面的命令

nginx -t
# 用來測試你的配置檔案是否 ok

nginx -s reload
# 重新載入配置檔案
複製程式碼

沒意外的話,這個時候在瀏覽器中輸入你的雲伺服器 ip 地址,就可以看到效果了。 等等,你說你的瀏覽器沒反應。不要慌,這是因為你的程式碼還沒執行呢

# 我的程式碼克隆在這裡,你的路徑可能跟我的不同
cd /opt/koa-demo
npm start
複製程式碼

這時候再重新整理頁面,ok 了,大功告成。

接著,你可能就想給自己加個雞腿慶祝一下,然後就退出了雲伺服器,跑去吃飯了。吃完飯回來,再次重新整理瀏覽器,我了個去,怎麼又沒內容了。 為什麼會這樣呢?

這是因為你開啟的方式不對,也就是啟動程式碼的方式不對,你可以看看 packagek.json 的內容,npm start 其實就是執行 node index.js 。當你這邊退出了,這個程式也就結束了,想想在你的本地是不是也這樣,你在你的終端執行,開啟瀏覽器是沒有問題的,退出終端,再重新整理頁面,就出問題了。

那這個問題要如何解決呢?呃,如果你之前有接觸過 node,那應該就聽過 pm2 這個詞了。是的,沒錯,接下來我們就用這個 pm2 解決我們的問題。

pm2 執行程式

如何學習 pm2 呢,最快的方式就去看它的 官網 咯,裡面的文件還是寫的很不錯的,一個 Quick Start 直接入門。

這裡就不多介紹了,看文件會更快了解。 那接下來怎麼跑呢,你可以看到 package.json 裡面的 script 還有個命令,就是 pm2,這個就是我之前已經新增好了,用 pm2 來啟動程式的命令。具體如下:

# 先登入到雲伺服器
ssh hostname
# 進入程式碼目錄
cd /opt/koa-demo
# run
npm run pm2
複製程式碼

這個時候,即使你退出了,再次重新整理頁面,也不會有問題了。

Docker 部署

docker,你應該聽過這個名詞吧,沒聽過說明你有點跟不上時代阿。 如果沒有了解過 docker,可以參考阮一峰老師的 Docker 入門教程

接下來,就試一試如何利用 docker 部署我們的 nodejs 應用。

首先,我們需要在我們的 koa-demo 中新增 Dockerfile 和.dockerignore。我已經在程式碼中新增好了,你可以直接簡單地複製到你的專案中。至於其中的那些命令代表什麼意思,就不多解釋了。你看完阮老師的那篇文章,多少有點了解了。或者你可以 docker COMMAND -h 獲取各個命令的使用。

雲主機安裝 docker

首先,我們需要在雲主機上安裝 docker,可以參考 docker 官網 About Docker CE, 裡面有關於各個系統的安裝說明,很詳細了。

編譯映象

進入到我們的程式碼目錄,利用 docker build 命令,編譯出我們需要的映象檔案,然後用 docker run,執行容器

cd /opt/koa-demo
docker build -t koa-demo .
docker run -d -p 7000:3000 koa-demo
複製程式碼

這裡,我用本地的 7000 埠對映容器的 3000 埠。

這個時候,你可以使用一下命令,看是否正確執行

curl -i localhost:7000

# 應該會返回如下結果
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 30
Date: Mon, 02 Jul 2018 12:12:26 GMT
Connection: keep-alive

It's success, congratulation!
複製程式碼

現在,我們的容器已經跑起來了,你可以想試試直接在瀏覽器輸入 ip:port 這樣的形式是否可以訪問,等你輸入之後,你會發現是沒有反應的。

為什麼呢,不要急,我們還沒有新增 nginx 配置呢。

cd /etc/nginx/conf.d
vi docker-demo.conf

# 寫入以下內容
upstream docker-demo {
  server 127.0.0.1:7000;
}

server {
  listen 7000;
  location / {
          proxy_pass http://docker-demo;
  }
}
複製程式碼

記得用 nginx -t 來測試你的 conf 是否 ok, 然後 nginx -s reload 重新載入一下。

這個時候,你就可以用 IP:Port(這裡的 Port 是上面的 listen 的埠) 的形式訪問了。

假如,你這個時候還是沒法訪問的話,有可能是你的安全組設定的問題,設定一下即可。

總結

以上就是一個小白的辛酸部署路,路程艱辛,但學到了不少東西,收穫很多。

討論地址

歡迎一起討論,github地址 從零開始學習部署

參考資料

誰說前端不需要懂-Nginx 反向代理與負載均衡 Dockerizing a Node.js web app Get Docker CE for CentOS Docker — 從入門到實踐

相關文章