我申請了無償使用的雲服務器 ,選擇安裝的Linux版本是ubuntu16.04.1 LTSx86_64。我我的PC安裝使用的也是這個版本,比較熟悉些。css
詳細參考幫助文檔。html
使用ssh公鑰方式登陸雲主機,ssh原理參考:SSH原理與運用(一):遠程登陸。前端
在雲主機頁面點擊SSH密鑰,建立密鑰-->選擇已有的公鑰,輸入本機的ssh公鑰-->將此公鑰綁定到雲主機上。以下圖我建立本機的公鑰命名爲thinkpads5。python
本機的公鑰位於$HOME/.ssh/
目錄下的id_rsa.pub
文件內。若是沒有現成的,能夠直接用ssh-keygen
生成一個。nginx
eliefly@thinkpad-s5:~/.ssh$ ls id_rsa id_rsa.pub known_hosts
完成公鑰的綁定後(即將本機主機的公鑰傳送到雲主機上),雲主機的$HOME/.ssh/authorized_keys
文件內就會保存本地主機的公鑰信息。git
成功綁定後,可成功使用ssh公鑰登陸:github
eliefly@thinkpad-s5:~$ ssh ubuntu@139.199.191.60 Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-53-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage Last login: Mon Jan 9 23:03:07 2017 from 58.251.190.158 ubuntu@VM-93-44-ubuntu:~$ ls / bin dev initrd.img lost+found opt run srv usr boot etc lib media proc sbin sys var data home lib64 mnt root snap tmp vmlinuz ubuntu@VM-93-44-ubuntu:~$ logout Connection to 139.199.191.60 closed. eliefly@thinkpad-s5:~$
本身的應用折騰半天沒成,就先從簡單的應用部署下,理清脈絡。web
主要參考:python web 部署:nginx + gunicorn + supervisor + flask 部署筆記mongodb
在路徑/srv/helloworld
下建立hello_tecent.py
文件。數據庫
from flask import Flask from flask_script import Manager app = Flask(__name__) manager = Manager(app) @app.route("/") def hello(): return "hello tecent cloud!" if __name__ == "__main__": manager.run()
同時$ pyvenv venv-helloworld
建立虛擬環境venv-helloworld
,激活虛擬環境,安裝必要的擴展包Flask
Flask-Script
。
/srv/helloworld# ls hello_tecent.py venv-helloworld
驗證Flask程序可否正常啓動,以下項目啓動成功,virtualenv和flask項目部署ok。
(venv-helloworld) root@VM-93-44-ubuntu:/srv/helloworld# python hello_tecent.py runserver * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
上面咱們使用 flask 自帶的服務器,完成了 web 服務的啓動。生產環境下,flask 自帶的 服務器,沒法知足性能要求。咱們這裏採用 gunicorn 作 wsgi容器,用來部署 python。
webservice 的方式一樣也有不少方式。常見的有FastCGI,WSGI等。咱們採用gunicorn爲 wsgi容器。
安裝gunicorn
,注意此處的gunicorn
一樣是須要安裝在虛擬環境下。在激活虛擬環境的狀況下,使用sudo pip install gunicorn
安裝,會把gunicorn
雲主機實體環境中。爲安裝正確,先獲取root權限再安裝。
獲取雲主機root權限:$ sudo /bin/su - root
。
ubuntu@VM-93-44-ubuntu:/srv/helloworld$ sudo /bin/su - root root@VM-93-44-ubuntu:~# cd /srv/helloworld/ root@VM-93-44-ubuntu:/srv/helloworld# source ./venv-helloworld/bin/activate (venv-helloworld) root@VM-93-44-ubuntu:/srv/helloworld# pip install gunicorn
以前使用 Flask-Script
擴展來啓動Flask服務器,執行# python hello_tecent.py runserver
,服務器由manager.run()
。
gunicorn
安裝好 以後,須要用gunicorn
啓動 flask。執行$ ./venv-helloworld/bin/gunicorn hello_tecent:app -w 4 -b 0.0.0.0:8000
啓動服務器。
此處,hello_tecent.py
就等同於一個庫文件,被 gunicorn 調用。app
爲Flask 程序實例名,源碼中app = Flask(__name__)
。使用 8000 的端口進行訪問,原先的5000並無啓用。-w 表示開啓多少個 worker,-b 表示 gunicorn 開發的訪問地址。
(venv-helloworld) root@VM-93-44-ubuntu:/srv/helloworld# ./venv-helloworld/bin/gunicorn hello_tecent:app -w 4 -b 0.0.0.0:8000 [2017-01-15 22:47:55 +0800] [21387] [INFO] Starting gunicorn 19.6.0 [2017-01-15 22:47:55 +0800] [21387] [INFO] Listening at: http://0.0.0.0:8000 (21387) [2017-01-15 22:47:55 +0800] [21387] [INFO] Using worker: sync [2017-01-15 22:47:55 +0800] [21390] [INFO] Booting worker with pid: 21390 [2017-01-15 22:47:55 +0800] [21391] [INFO] Booting worker with pid: 21391 [2017-01-15 22:47:55 +0800] [21393] [INFO] Booting worker with pid: 21393 [2017-01-15 22:47:55 +0800] [21394] [INFO] Booting worker with pid: 21394
WEB服務啓動成功後,就能夠在本機瀏覽器訪問雲主機的WEB服務。瀏覽器地址欄輸入:<ip address>:8000
,就能夠看到親切的 hello tecent cloud!
想要結束 gunicorn 只需執行 pkill gunicorn,有時候還的 ps 找到 pid 進程號才能 kill。但是這對於一個開發來講,太過於繁瑣,所以出現了另一個神器---supervisor,一個專門用來管理進程的工具,還能夠管理系統的工具進程。
supervisor python3中不支持,我虛擬環境下使用的是python3.5,沒法安裝 supervisor。
(venv-helloworld) root@VM-93-44-ubuntu:/srv/helloworld# pip install supervisor Collecting supervisor Downloading supervisor-3.3.1.tar.gz (415kB) 100% |################################| 419kB 716kB/s Complete output from command python setup.py egg_info: Supervisor requires Python 2.4 or later but does not work on any version of Python 3. You are using version 3.5.2 (default, Nov 17 2016, 17:05:23) [GCC 5.4.0 20160609]. Please install using a supported version. ---------------------------------------- Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-0bi4mj2b/supervisor/
把supervisor
安裝在雲主機實體環境python2下(ubuntu16.04自帶python2和python3)。
# pip install supervisor
將其原始配置文件重定向到程序根目錄(須要root權限,sudo執行也失敗):
# echo_supervisord_conf>supervisor.conf
個人工程目錄是/srv/helloworld
,新建log目錄,在/srv/helloworld/supervisor.conf
配置文件底部添加,hello_tecent。
[program:hello_tecent] command=/srv/helloworld/venv-helloworld/bin/gunicorn -w4 -b 0.0.0.0:8000 hello_tecent:app ; supervisor啓動命令 directory=/srv/helloworld ; 項目的文件夾路徑 startsecs=0 ; 啓動時間 stopwaitsecs=0 ; 終止等待時間 autostart=false ; 是否自動啓動 autorestart=false ; 是否自動重啓 stdout_logfile=/srv/helloworld/log/gunicorn.log ; log 日誌 stderr_logfile=/srv/helloworld/log/gunicorn.err
supervisor的基本使用命令:
supervisord -c supervisor.conf 經過配置文件啓動supervisor supervisorctl -c supervisor.conf status 察看supervisor的狀態 supervisorctl -c supervisor.conf reload 從新載入 配置文件 supervisorctl -c supervisor.conf start [all]|[appname] 啓動指定/全部 supervisor管理的程序進程 supervisorctl -c supervisor.conf stop [all]|[appname] 關閉指定/全部 supervisor管理的程序進程
運行成功:
root@VM-93-44-ubuntu:/srv/helloworld# supervisord -c ./supervisor.conf root@VM-93-44-ubuntu:/srv/helloworld# supervisorctl -c ./supervisor.conf start hello_tecent hello_tecent: started root@VM-93-44-ubuntu:/srv/helloworld# supervisorctl -c ./supervisor.conf status hello_tecent RUNNING pid 2411, uptime 0:01:08 root@VM-93-44-ubuntu:/srv/helloworld# ps -ef | grep supervisor root 2409 1 0 00:15 ? 00:00:00 /usr/bin/python /usr/bin/supervisord -c ./supervisor.conf root 2549 1843 0 00:17 pts/0 00:00:00 grep --color=auto supervisor
此時本機瀏覽器打開外網<ip address>:8000
即可看到hello tecent cloud!。
可能出現的錯誤:
1)Another program is already listening on a port that one of our HTTP servers is configured to use.
$ supervisord -c supervisor.conf Error: Another program is already listening on a port that one of our HTTP servers is configured to use. Shut this program down first before starting supervisord. For help, use /usr/bin/supervisord -h
解決:執行ps -ef | grep supervisor
找到supervisord進程kill掉。
2)Unlinking stale socket /tmp/supervisor.sock
解決:sudo unlink /tmp/supervisor.sock
上面直接把hello_tecent程序的supervisor配置追加到supervisor.conf文件的末尾。其實,hello_tecent程序的supervisor配置文件也可放置在其餘目錄下,如在目錄/srv/helloworld/conf.d/
下新建文件 hello_tecnet.ini
,相應的supervisor.conf文件的末尾修改成以下,包含關係。這樣有多個監控程序時方便管理。
[include] files = ./conf.d/hello_tecent.ini
nginx 不用多說,一個高性能的web服務器。一般用來在前端作反向代理服務器。所謂正向與反向(reverse),只是英文說法翻譯。代理服務,簡而言之,一個請求通過代理服務器從局域網發出,而後到達互聯網上服務器,這個過程的代理爲正向代理。若是一個請求,從互聯網過來,先進入代理服務器,再由代理服務器轉發給局域網的目標服務器,這個時候,代理服務器爲反向代理(相對正向而言)。
簡言之,正向代理:客戶端和代理服務器在一塊兒,反向代理器:服務器和代理在一塊兒。
正向代理:{ 客戶端 --->代理服務器 } ---> 服務器 反向代理:客戶端 --->{ 代理服務器 ---> 服務器 } {} 表示局域網
ngnix的配置放在/etc/nginx/sites-available
139.199.191.60是所申請的雲主機公網IP,sudo vim hello-tecent
:
而後在/etc/nginx/sites-enabled/
目錄下建立軟連接:
$ sudo ln -s /etc/nginx/sites-available/hello-tecent /etc/nginx/sites-enabled/
讓Nginx從新加載配置文件並重啓nginx服務:
ubuntu@VM-93-44-ubuntu:/$ sudo /etc/init.d/nginx restart [ ok ] Restarting nginx (via systemctl): nginx.service. ubuntu@VM-93-44-ubuntu:/$ sudo /etc/init.d/nginx reload [ ok ] Reloading nginx configuration (via systemctl): nginx.service.
在本機瀏覽器輸入http://139.199.191.60/
,注意此時因爲ngixn反向代理做用,能夠省去端口號進行訪問到hello tecent cloud!了。
$ sudo supervisorctl -c supervisor.conf status hello_tecent RUNNING pid 1036, uptime 0:00:44
有Flaks+Mongodb構建的博客網站,Git源碼位置:NovBlog。
咱們使用Fabric部署代碼至雲主機/srv/NovBlog
目錄,也可以使用Git Clone或者FTP傳遞等方式。
Fabric參考:Day 15 - 部署Web App
Ubuntu 16.04安裝Mongodb參考How to Install and Configure MongoDB on Ubuntu 16.04。
supervisor配置文件:
[program:novblog] command=/srv/NovBlog/venv-novblog/bin/gunicorn -w4 -b 0.0.0.0:8000 manage:app ; supervisor啓動命令 directory=/srv/NovBlog/www ; 項目的文件夾路徑,manage.py所在 startsecs=0 ; 啓動時間 stopwaitsecs=0 ; 終止等待時間 autostart=false ; 是否自動啓動 autorestart=false ; 是否自動重啓 stdout_logfile=/srv/NovBlog/log/gunicorn.log ; log 日誌 stderr_logfile=/srv/NovBlog/log/gunicorn.err
nginx配置:
配置屏蔽部分,若是不屏蔽會有問題,會致使static路徑出錯,源碼中引用靜態資源是使用如<link href="{{ url_for('static', filename='css/bootstrap.min.css') }}" rel="stylesheet">
,須要再研究下配置中static如何與href中匹配。
server { listen 80; server_name 139.199.191.60; # 這是HOST機器的外部域名,用地址也行 root /srv/NovBlog/www/; access_log /srv/NovBlog/log/access_log; error_log /srv/NovBlog/log/error_log; # location /favicon.ico { # root /srv/NovBlog/www/app/static/img; # } # location ~ ^\/static\/.*$ { # root /srv/NovBlog/www/app/static; # } location / { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
域名沒買,參考操做:
域名解析添加A型記錄,值爲雲服務器外網ip便可。
nginx配置相應的一行代碼亦需改一下:
$ server_name <域名>;
此時,在網址欄輸入域名便可進入網站。
參考: