準備工作:
- 一個遠端伺服器來託管你的站點。
- 通過SSH訪問遠端伺服器。
- 在遠端伺服器上安裝Git(通過指令git –version來檢查是否安裝)。
- 如果需要,請生成一個SSH key。
在伺服器端
設定無密碼的SSH訪問
首先,你需要通過SSH連線到你的伺服器,如果有提示的話請輸入密碼。
ssh user@hostname
如果在你的使用者的主目錄中沒有~/.ssh
目錄,請建立一個:mkdir ~/.ssh
接下來,你需要複製你的公共SSH key(請看生成一個SSH key)到你的伺服器。這樣你就可以通過SSH連線,並且不需要每次都輸入密碼。
在你的本地 – 假設你的公共key可以在~/.ssh/id_rsa.pub
找到 – 使用正確的使用者和主機名稱輸入下面的指令。它將會把你的公共祕鑰(key)新增到遠端伺服器的authorized_keys
檔案。
ssh user@hostname `cat >> ~/.ssh/authorized_keys` < ~/.ssh/id_rsa.pub
如果你關閉連線,並且嘗試建立SSH訪問,你應該不再會被提示輸入密碼。
建立遠端目錄
你需要為每個域名建立2個目錄。一個作為Git的倉庫,另一個包含其他資訊。
舉個例子,如果你的域名是example.com
,並且你想要建立一個環境,那麼你需要在你的伺服器上建立這些目錄:
mkdir ~/example.com ~/example.git
mkdir ~/staging.example.com ~/staging.example.git
初始化空的Git倉庫
在伺服器上建立空的Git倉庫,也就是把本地檔案(資源)傳送到伺服器儲存的地方。但是你不想要的檔案在這裡,這就是為什麼這是一個空的倉庫。
cd ~/example.git
git init --bare
如果你想的話,你可以重複此步驟。
寫一個傳送-接收鉤子
一個傳送-接收鉤子可以讓你在Git倉庫接收到commits後執行指令。這樣,你可以改變Git的工作目錄,從example.git
到 example.com
,並且檢查在example.com
目錄下的副本。
工作目錄的位置可以使用GIT_WORK_TRE
E在per-command的基礎上設定,Git的環境變數中其中一個或者work-tree
選項。
cat > hooks/post-receive
#!/bin/sh
WEB_DIR=/path/to/example.com
# remove any untracked files and directories
git --work-tree=${WEB_DIR} clean -fd
# force checkout of the latest deploy
git --work-tree=${WEB_DIR} checkout --force
確保hook上的檔案許可權正確。
chmod +x hooks/post-receive
如果你需要使一些檔案不被Git清理(比如.htpasswd
檔案),你可以使用–exclude選項。這需要在你的伺服器上安裝Git 1.7.3或者以上版本。
git --work-tree=${WEB_DIR} clean -fd --exclude=<pattern>
如果你想的話,可以重複此步驟。
在本地機器上操作
現在,伺服器配置已經完成,你想要為靜態站點部署build assets(不是原始碼)。
構建和部署任務
我正在使用生成檔案(Makefile),但是你可以使用任何你擅長的。下面是我想要自動化完成的基本工作流程。
-
建立靜態站點的生產版本。
make build
-
初始化一個新的Git repo在構建目錄中。 我不想嘗試合併到之前部署的檔案,尤其是對於分段域(staging domain)。
git init ./build
-
遠端部署
cd ./build
git remote add origin ssh://user@hostname/~/example.git -
commit repo中的所有內容
cd ./build
git add -A
git commit -m "Release" -
強制轉換遠端主分支, 如果丟失的話,則建立它。
cd ./build
git push -f origin +master:refs/heads/master -
在源repo中標記出檢查commit的SHA,於是我可以看到哪個是最新部署。
git tag -f production
使用一個生成檔案:
BUILD_DIR := ./build
STAGING_REPO = ssh://user@hostname/~/staging.example.git
PROD_REPO = ssh://user@hostname/~/example.git
install:
npm install
# Deploy tasks
staging: build git-staging deploy
@ git tag -f staging
@ echo "Staging deploy complete"
prod: build git-prod deploy
@ git tag -f production
@ echo "Production deploy complete"
# Build tasks
build: clean
# whatever your build step is
# Sub-tasks
clean:
@ rm -rf $(BUILD_DIR)
git-prod:
@ cd $(BUILD_DIR) &&
git init &&
git remote add origin $(PROD_REPO)
git-staging:
@ cd $(BUILD_DIR) &&
git init &&
git remote add origin $(STAGING_REPO)
deploy:
@ cd $(BUILD_DIR) &&
git add -A &&
git commit -m "Release" &&
git push -f origin +master:refs/heads/master
.PHONY: install build clean deploy git-prod git-staging prod staging
分階段部署:
make staging
部署生產:
make prod
使用Make,,因為cd
命令在子流程中。但是你需要確保後來的命令在同一行中。舉個例子:如果沒有在命令中加入&&
或 ;
,那麼deploy
任務會強制推送到你原始碼的遠端主分支。
我把我的站點原始碼傳到了BitBucket一個私人的倉庫。BitBucket其中一個很不錯的地方在於可讓你選擇防止誤刪除或者重寫分支。