1. 本地化服務器配置
首先要做的是將服務器的配置本地化,放在自己的項目中:
圖中,_deploy目錄下的內容就是我們要部署到服務器上的配置,其目錄結構和服務器要完全一致,這樣可以用 cp 直接將文件拷貝過去:
$ sudo cp -r _deploy/etc/. /etc/.
這裡有個問題,sudo一般需要輸密碼,但這裡如果停下來等待用戶交互,就無法完全自動化了。所以我們需要讓 cp 無須password就可以執行。但又引來一個問題:無密碼限制的 cp 太危險,可能會導致誤操作。所以我們就把 cp copy 一份出來,叫 sucopy,然後對其設置 nopassword:
$ sudo cp /bin/cp /bin/sucopy $ sudo visudo
在打開的編輯窗口,為當前用戶設置 sudo 選項:
dev ALL=(ALL) NOPASSWD: /usr/bin/supervisorctl, /etc/init.d/nginx, /bin/sucopy, /usr/bin/apt-get
我這裡把 apt-get,supervisorctl 和 nginx 都設置為 NOPASSWD,也是為了自動運行。
注:如果 visudo 使用的nano編輯器不是你的菜,可以用 update-alternatives --config editor 切換成vim。
設置完成後,我們就可以在makefile中用 sucopy 把項目中的配置文件直接更新系統中的對應文件了,比如:
sudo sucopy -r _deploy/etc/. /etc/.
很簡單吧。這樣做的好處是配置文件的修改隨著項目文件一起在版本庫中控制,部署起來也方便很多。
nginx和supervisor的配置很簡單,這裡就給個例子,不解釋:
nginx配置:
tchen@tchen-mbp: ~/projects/kahn/_deploy/etc/nginx/sites-available on master$ cat kahn server { listen 80; server_name api.awesome-server.com; access_log /var/log/nginx/kahn.access.log; error_log /var/log/nginx/kahn.error.log; location / { proxy_pass http://localhost:6080; include /etc/nginx/proxy_params; } }
tchen@tchen-mbp: ~/projects/kahn/_deploy/etc/nginx/sites-enabled on master$ ls -l total 8 lrwxr-xr-x 1 tchen 522017917 23 Jun 11 13:48 kahn -> ../sites-available/kahn
supervisor配置:
tchen@tchen-mbp: ~/projects/kahn/_deploy/etc/supervisor/conf.d on master$ cat kahn.conf [program:kahn] directory=/home/dev/deployment/kahn user=dev command=coffee app.coffee redirect_stderr=true stderr_logfile=none stdout_logfile=/var/log/supervisor/kahn.log autostart=true autorestart=true
2. Makefile
解決了服務器的本地化配置問題,自動化部署就不在話下。這裡只自動化了下列任務,對簡單的小項目來說足夠了:
Makefile文件比較簡單,不解釋了。注意這裡我們把 remote_deploy 放在第一位,讓 make 缺省調用時可以調用它,這樣,我們會自動登錄到服務器上(服務器的連接請使用rsa key,避免輸入密碼),pull代碼,然後執行 make deploy 進行部署。
tchen@tchen-mbp: ~/projects/kahn on master$ cat Makefile CHECK=\033[32m?\033[39m DONE="\n$(CHECK) Done.\n" SERVER=awesome-server.com PROJECT=kahn PATH=deployment/$(PROJECT) SUPERVISORCTL=/usr/bin/supervisorctl SUCOPY=/bin/sucopy SSH=/usr/bin/ssh ECHO=/bin/echo -e NPM=/usr/local/bin/npm SUDO=/usr/bin/sudo remote_deploy: @$(SSH) -t $(SERVER) "echo Deploy $(PROJECT) to the $(SERVER) server.; cd $(PATH); git pull; make deploy;" dependency: @$(ECHO) "\nInstall project dependencies..." @$(NPM) install configuration: @$(ECHO) "\nUpdate configuration..." @$(SUDO) $(SUCOPY) -r _deploy/etc/. /etc/. supervisor: @$(ECHO) "\nUpdate supervisor configuration..." @$(SUDO) $(SUPERVISORCTL) reread @$(SUDO) $(SUPERVISORCTL) update @$(ECHO) "\nRestart $(PROJECT)..." @$(SUDO) $(SUPERVISORCTL) restart $(PROJECT) nginx: @$(ECHO) "\nRestart nginx..." @$(SUDO) /etc/init.d/nginx restart deploy: dependency configuration supervisor nginx @$(ECHO) $(DONE)
大功告成。試試吧:
tchen@tchen-mbp: ~/projects/kahn on master$ make Deploy kahn to the awesome-server.com server. Current branch master is up to date. Install project dependencies... Update configuration... Update supervisor configuration... No config updates to processes Restart kahn... kahn: stopped kahn: started Restart nginx... Restarting nginx: nginx. ✔ Done. Shared connection to awesome-server.com closed.原文:http://tchen.me/posts/2013-06-12-use-makefile-to-automate-deployment.html