Digital Ocean 升級
之前的一篇記錄過如何在 Digital Ocean 建立一個雲端主機後,不久的某天早上在查看電郵時,留意到 Digital Ocean 為它的服務升級了。以最低價格每月5美元一個標準主機的Droplet 為例,就有以下更新:從 512MB -> 1GB RAM、 20GB -> 25GB SSD。但如電郵標題已經講明,這是[Action Required]。這個自製網站的規模不怕暫時離線,也未看到有復原到小容量,或預留那 5GB Disk的需要,所以也沒理由不放心進行 Disk, CPU and RAM 的升級。以 Control Panel 的方式升級也非常容易。
參考:https://www.digitalocean.com/community/tutorials/how-to-resize-your-droplets-on-digitalocean
Nginx、Gunicorn
Deployment 方面糾纏了幾星期終於有成果了。其實最終是趁著系統升級之前,也把心一橫來個砍掉重練,復原到一開始的主機映象。重新來按步就班的試驗,就一天內弄好了。 之前這段日子也有不少得著的,見到很多名詞如: Nginx Gunicorn, wsgi, uWSGI, uwsgi, supervisor, 等等,左試右試的弄混亂過才明白它們的關係。在這個 Ubuntu 16.04 + Django 1.8.7 的 One-Click install Image下要掛上自家的網頁,會需要修改的是Nginx 和 Gunicorn。整個後端架構的關係如下:後端:
Request <->
<-> Web Server (Nginx/Aphach/etc...) <->
<-> Web Server Gateway Interface(Gunicorn/uWSGI/etc...) <->
<-> Application, or Framwork (Python Django/Python Flask/Node.JS Express/JS Express Ruby on Rail/etc...))
瀏覽器是前端上的用家看到的網頁;
當用家輸入網址後。
Web Server (Nginx) 在後端負責架起伺服器功能,去接受和處理外來訪客的HTTP request,proxy, cache,static files;Gateway (Gunicorn) 作為 Web Server 和 Framework之間的中介接口,管理如何呼叫適當的Python應用程序、Load balancing 等;背後的Application & Framework 當然是Python 的Django 框架下設置的Model、Template、View 和 多個的 Python .py 檔。
開始試驗換成自己的project前,建議先跟預設的教學例子執行一次:
How To Use the Django One-Click Install Image for Ubuntu 16.04
0) Preparation
從 Digital Ocean 的 1-click image 開始,先用 "rsync" 把自己的項目("myAstrooma")上載到用戶的資料夾下:
# 用 rsync 的 SSH 資料同步
rsync -avi --delete -e 'ssh -p 22' (local folder) (username)@(your IP):(remote folder)
更新了以下一些所需的套件,(在此也建議真的日後應該弄個virtualenv,以確保自家主機測試和虛擬主機上服務的環境一致):
$
export LC_ALL=C $
sudo pip install --upgrade pip $
sudo pip install django-import-export $
sudo pip install Pillow
首先應該可以用Django 的runserver 啟動的,防火牆設定中打開測試用的連接埠。
$ sudo ufw app list $ sudo ufw status $ sudo ufw enable
$ sudo python manage.py collectstatic $ sudo python manage.py makemigrations $ sudo python manage.py migrate $
$ sudo ufw allow 8000
python manage.py runserver 0.0.0.0:8000
1) Nginx
修改 /etc/nginx/sites-avail
able/django 這個 Nginx 的設定檔:
$
sudo nano /etc/nginx/sites-available/django
upstream app_server {
server 127.0.0.1:9000 fail_timeout=0;
}
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /usr/share/nginx/html;
index index.html index.htm;
client_max_body_size 4G;
server_name _;
keepalive_timeout 5;
# Your Django project's media files - amend as required
location /media {
alias /home/django/myAstrooma/media;
}
# your Django project's static files - amend as required
location /static {
alias /home/django/myAstrooma/static;
}
# Proxy the static assests for the Django Admin panel
location /static/admin {
alias /usr/lib/python2.7/dist-packages/django/contrib/admin/static/admin/;
}
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_buffering off;
proxy_pass http://app_server;
}
# Customize Django project's assets files - amend as required
location /assets {
alias /home/django/myAstrooma/assets;
}
}
把捷徑(symbolic-link)放到 /etc/nginx/sites-enabled/django,這裡才是 Nginx 卜月十田十行是實際使用的設定:
$
sudo ln -s /etc/nginx/sites-available/django /etc/nginx/sites-enabled/django
測試 Nginx 的 config:
$
sudo nginx -t
這時候如果未啟動網路伺服器 Nginx 的話,在瀏覽器輸入IP或網址應該會出現 "Unable to connect, can’t establish a connection to the server at ......" 的錯誤訊息。 然後這指令啟動Nginx:
$
systemctl restart nginx
2) Gunicorn
啟動Nginx後,上面連接不到伺服器的訊息會消失,但如果未啟動 Gateway's Gunicorn 的話,主機不懂如何處理這些請求,所以會面對 "502 Bad Gateway, nginx/1.10.3 (Ubuntu)" 的錯誤訊息。下一步就要修改修改 Gunicorn 的設定檔,分別是:
- /etc/systemd/system/gunicorn.service :
- /etc/gunicorn.d/gunicorn.py
$
sudo nano
/etc/systemd/system/gunicorn.service
[Unit]
Description=Gunicorn daemon for Django Project
Before=nginx.service
After=network.target
[Service]
WorkingDirectory=/home/django/django_project
ExecStart=/usr/bin/gunicorn --name=django_project --pythonpath=/home/django/django_project --bind unix:/home$
Restart=always
SyslogIdentifier=gunicorn
User=django
Group=django
[Install]
WantedBy=multi-user.target
而 /etc/gunicorn.d/gunicorn.py 是有關 work processor 的 設定,可以沒有改動。
"""gunicorn WSGI server configuration."""
from multiprocessing import cpu_count
from os import environ
def max_workers():
return cpu_count() * 2 + 1
max_requests = 1000
worker_class = 'gevent'
workers = max_workers()
最後就是更新和啟動 Gunicorn:
$ cd ~/myAstrooma
$ gunicorn --bind 0.0.0.0:8000 myAstrooma.wsgi:application
$ sudo systemctl daemon-reload
$ sudo systemctl restart gunicorn.service
而如果要關掉Server時可以閉上firewall 的 80 port、或者關掉Nginx
$ sudo ufw deny 80 $
sudo systemctl stop nginx
$ sudo systemctl stop gunicorn.service
在最後那天成功部署的過程中,最有用的 D.O. 教學要算這兩篇了:
How To Use the Django One-Click Install Image for Ubuntu 16.04
How To Set Up Django with Postgres, Nginx, and Gunicorn on Ubuntu 16.04
3) Django
Django 中的 setting.py 和 static files 的運用時,也有一些設定應該在正式上線時修改的。原本打算是另外一篇了,但見以上的 "Nginx - Gunicorn - Django" 架構,在這裡留個分部提一提點,就當完整了吧。
沒有留言:
張貼留言