Joey LIU | NANTSOU


更新(2020-05-13)

預設條件

建立專用的使用者和作業資料夾

建立使用者名稱為webapps的使用者,並加使用者加入sudo群組

$ sudo adduser webapps
$ sudo usermod -a -G sudo webapps

個人習慣將網站app都放在/srv/webapps/底下

$ cd /srv
$ mkdir webapps

webapps資料夾的權限更改為剛剛創建的專用使用者,可以利用-R參數將該資料夾下的所有東西的權限變更為webapps

$ sudo chown webapps -R webapps

建立一個資料夾當作Django的根目錄

$ cd /srv/webapps
$ mkdir django.sample

Django Sample

建立Python虛擬環境的目錄

# 建立部署專用的根目錄
$ mkdir /srv/webapps/django.sample/deploy && cd  /srv/webapps/django.sample/deploy
# 建立python的虛擬環境
$ virtualenv env --no-site-package -p python3
Already using interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /srv/webapps/django.sample/env/bin/python3
Also creating executable in /srv/webapps/django.sample/env/bin/python
Installing setuptools, pip, wheel...done.

啟動虛擬環境

$ source env/bin/activate
(env) $

安裝Django

(env) $ pip install django
Collecting django
  Downloading Django-1.11-py2.py3-none-any.whl (6.9MB)
    100% |████████████████████████████████| 6.9MB 226kB/s 
Collecting pytz (from django)
  Using cached pytz-2017.2-py2.py3-none-any.whl
Installing collected packages: pytz, django
Successfully installed django-1.11 pytz-2017.2

建立Django Project及Django App

Django Project

$ django-admin startproject sample

Django App

$ cd sample
$ python manage.py startapp app

這邊不贅述如何建立Django網站

測試Django App是否可以正常運行

$ python manage.py runserver 0.0.0.0:8000

AWS EC2上運行python manage.py runserver必須將server綁定在0.0.0.0,port就直接用Django預設的8000

在瀏覽器網址輸入AWS EC2的公開IP並指定port為8000(xxx.xxx.xxx.xxx:8000)來開啟網頁測試Django App是否可正常運行

記得必須在AWS EC2的security group中將TCP8000port的權限打開

Gunicorn

(env) $ pip install gunicorn
Collecting gunicorn
  Using cached gunicorn-19.7.1-py2.py3-none-any.whl
Installing collected packages: gunicorn
Successfully installed gunicorn-19.7.1

測試是否可以用Gunicorn啟動Django,測試目錄為/srv/webapps/django.sample/sample

(env) $ gunicorn sample.wsgi:application --bind 0.0.0.0:8000
[2017-04-20 23:43:30 +0900] [2987] [INFO] Starting gunicorn 19.7.1
[2017-04-20 23:43:30 +0900] [2987] [INFO] Listening at: http://127.0.0.1:8000 (2987)
[2017-04-20 23:43:30 +0900] [2987] [INFO] Using worker: sync
[2017-04-20 23:43:30 +0900] [2990] [INFO] Booting worker with pid: 2990

為了讓Supervisor方便監視管理,將Gunicorn啟動Django的指令配合一些參數整理到一個script,並將script放置到方便管理的目錄下

# 移動到部署專用的根目錄
$ cd  /srv/webapps/django.sample/deploy
# 建立擺放script的目錄
$ mkdir bin
# 建立儲存log的目錄
$ mkdir logs

增加「可執行」到gunicorn_start.bash的檔案權限

$chmod +x gunicorn_start.bash

測試gunicorn_start.bash是否可正常啟動Django並在deploy/run目錄下產生gunicorn_django.sample.sock

$ ./gunicorn_start.bash
[2017-04-21 23:55:42 +0900] [4997] [DEBUG] Current configuration:
  reload_engine: auto
  check_config: False
  limit_request_line: 4094
  pythonpath: None
  proxy_allow_ips: ['127.0.0.1']
<---- 省略 ---->
[2017-04-21 23:55:42 +0900] [4997] [INFO] Starting gunicorn 19.7.1
[2017-04-21 23:55:42 +0900] [4997] [DEBUG] Arbiter booted
[2017-04-21 23:55:42 +0900] [4997] [INFO] Listening at: unix:/srv/webapps/django.sample/deploy/run/gunicorn_django.sample.sock (4997)
[2017-04-21 23:55:42 +0900] [4997] [INFO] Using worker: sync
[2017-04-21 23:55:42 +0900] [5003] [INFO] Booting worker with pid: 5003
[2017-04-21 23:55:42 +0900] [5004] [INFO] Booting worker with pid: 5004
[2017-04-21 23:55:42 +0900] [4997] [DEBUG] 3 workers
[2017-04-21 23:55:42 +0900] [5005] [INFO] Booting worker with pid: 5005

Supervisor

$ sudo apt-get install supervisor

安裝好Supervisor可用下方的指令啟動(這邊我用預設的設定檔supvervisor.d

$ sudo supervisord -c /etc/supervisor/supervisord.conf

預設的program設定檔目錄為/etc/supervisor/conf.d,增加program的設定檔到該目錄(`/etc/supervisor/conf.d/django.sample.conf)後,Supervisor會自己抓去要監視管理的program

追加好program的設定檔之後,利用下面的指令讓Supervisor更新監視管理的內容

$ sudo supervisorctl -c /etc/supervisor/supervisord.conf reread # 重新讀取program的設定檔
django.sample: available
$ sudo supervisorctl -c /etc/supervisor/supervisord.conf update # 根據已讀取的設定檔更新監視管理內容
django.sample: added process group
$ sudo supervisorctl -c /etc/supervisor/supervisord.conf status # 列出program的狀態
django.sample                    RUNNING   pid 5392, uptime 0:00:12

可以利用下面的指令觀察及操作Supervisor

# 列出監視program的狀態
$ sudo supervisorctl -c /etc/supervisor/supervisord.conf status
# 啟動監視管理的program
$ sudo supervisorctl -c /etc/supervisor/supervisord.conf start program_name
# 停止監視管理的program
$ sudo supervisorctl -c /etc/supervisor/supervisord.conf stop program_name
# 重新啟動監視管理的program
$ sudo supervisorctl -c/etc/supervisor/supervisord.conf restart program_name

同時操作複數個program時以空格區隔,或是all參數來操作全部的program

# 複數個program
$ sudo supervisorctl -c /etc/supervisor/conf.d/django.sample.conf start program_name1 program2 ...
# 全部program
$ sudo supervisorctl -c /etc/supervisor/conf.d/django.sample.conf stop all ...

Supervisor的基本狀態為:STARTINGRUNNINGSTOPPEDRESTART

其他的狀態可以參考:Supervisor: process-states

Nginx

$ sudo apt-get install nginx
$ sudo systemctl start nginx

同樣的,我使用預設的設定檔來啟動Nginx

要增加「虛擬伺服器(virtual server)」的話,先增加「虛擬伺服器」的設定檔在/etc/nginx/sites-available目錄下,再用ln -s的symbolic link指令連結到/etc/nginx/sites-enabled目錄下(設定檔的內容沿用參考文章的script)

建立symbolic link到/etc/nginx/sites-enabled/目錄下

$ sudo ln -s /etc/nginx/sites-available/django.sample /etc/nginx/sites-enabled/django.sample

重新啟動Nginx

$ sudo systemctl restart nginx

最後用瀏覽器開啟 http://django.sample.joeyliu.net 來測試所有設定是否完成

目錄結構

django.sample/
├── deploy
│   ├── bin
│   │   └── gunicorn_start.bash
│   ├── env
│   │   ├── # Python虛擬環境的目錄結構
│   ├── logs
│   │   ├── gunicorn_supervisor.log
│   │   ├── nginx-access.log
│   │   └── nginx-error.log
│   ├── requirements.txt
│   └── run
│       └── gunicorn_django.sample.sock
├── README.md
└── sample
    ├── app
    │   ├── admin.py
    │   ├── apps.py
    │   ├── __init__.py
    │   ├── migrations
    │   ├── models.py
    │   ├── templates
    │   ├── tests.py
    │   └── views.py
    ├── db.sqlite3
    ├── manage.py
    └── sample
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py