更新(2020-05-13)
- 主要更新一些過時的資訊,有時間會在整體翻新。
- joeyliu.me已變更為joeyliu.net。
- 範例用的伺服器暫時拿掉了(因為燒錢…)。
- 預計加入一些新的資訊。例如:Ubuntu 18.04 LTS、利用pyenv安裝python、提供一些設定檔的範本。
預設條件
- EC2的OS為Ubuntu 16.04.1 LTS
- 已安裝3.5以上的Python3及virtualenv
- 域名已透過DNS設定指向EC2的IP,本文以
django.sample.joeyliu.net
為範例 $ sudo apt-get update && sudo apt-get upgrade
升級系統
建立專用的使用者和作業資料夾
建立使用者名稱為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中將TCP的8000
port的權限打開
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的基本狀態為:STARTING
、RUNNING
、STOPPED
、RESTART
其他的狀態可以參考: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