# 在 Ubuntu 建置 Django App 作業平台指引
# 摘要
在 VirtualBox VM 執行安裝作業,使 VM 成為 Django App 之「作業平台」。
- 安裝開發作業基礎工具
- 安裝 Node.js 作業環境
- 安裝 Python 作業環境
- 安裝編輯器
- 安裝 nginx 服務
- 安裝 Django App 原始碼
- 安裝 uWSGI 服務
# 安裝開發作業基礎工具
- 安裝 git 版本管理套件。
sudo apt install git
- 安裝檔案下載工具。
sudo apt install curl
# 安裝 Node.js 作業環境
# 安裝 node 與 npm 套件
安裝作業系統層級,預設 Node.js。如:使用 root 帳號,操作 vim 編輯器時,需要使用 「預設 Node.js」。
📚 《在 Ubuntu 建置 Node.js 作業環境指引》
- 安裝 Node.js 與 npm 套件管理器。
sudo apt install nodejs npm
- 確認 node 與 npm 安裝處。
alanjui@VB02-Ubuntu-2004:~$ ll /usr/bin/node
-rwxr-xr-x 1 root root 14416 3月 31 2020 /usr/bin/node*
alanjui@VB02-Ubuntu-2004:~$ ll /usr/bin/npm
lrwxrwxrwx 1 root root 27 4月 9 2020 /usr/bin/npm -> ../share/npm/bin/npm-cli.js*
2
3
4
5
# 安裝 Node 套件管理器:yarn
npm 本身即是 Node 之「套件管理器」。何以要再安裝 yarn ,主要原因是有些套件的安裝 偏好使用 yarn 所致。
- 安裝
sudo npm i -g yarn
📺
alanjui@VB02-Ubuntu-2004:~$ sudo npm i -g yarn
[sudo] alanjui 的密碼:
> yarn@1.22.10 preinstall /usr/local/lib/node_modules/yarn
> :; (node ./preinstall.js > /dev/null 2>&1 || true)
/usr/local/bin/yarn -> /usr/local/lib/node_modules/yarn/bin/yarn.js
/usr/local/bin/yarnpkg -> /usr/local/lib/node_modules/yarn/bin/yarn.js
+ yarn@1.22.10
added 1 package in 2.324s
2
3
4
5
6
7
8
9
10
- 驗證
yarn 安裝位置: /usr/local/bin/yarn
which yarn
📺
alanjui@VB02-Ubuntu-2004:~$ which yarn
/usr/local/bin/yarn
2
# 安裝 Python 作業環境
安裝作業系統層級,預設 Python 。
# 驗證預設 Python 已安裝
Ubuntu 20.04 作業系統,預設 Python 為 3.8.5 。此預設 python3 之「安裝目錄」 路徑,如下所示:
alanjui@VB02-Ubuntu-2004:~$ which python3
/usr/bin/python3
alanjui@VB02-Ubuntu-2004:~$ python3 --version
Python 3.8.5
2
3
4
5
# 安裝虛擬環境管理器
安裝 VirtualEnv 管理工具。
sudo apt install python-venv
# 安裝編譯及安裝用套件
pip3 安裝 Python 時,可能會需要編譯原始碼,配合編譯與安裝作業需求,需安裝以下套件:
sudo apt install -y build-essential libssl-dev libffi-dev python3-dev
# 安裝預設套件管理器
安裝作業系統預設 Python 套件管理器:pip3 。
sudo apt install -y python3-pip
sudo -H pip3 install --upgrade pip
2
📺
alanjui@VB02-Ubuntu-2004:~$ which pip3
/usr/bin/pip3
alanjui@VB02-Ubuntu-2004:~$ which pip
alanjui@VB02-Ubuntu-2004:~$ sudo -H pip3 install --upgrade pip
Collecting pip
Downloading pip-21.0.1-py3-none-any.whl (1.5 MB)
|████████████████████████████████| 1.5 MB 1.6 MB/s
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 20.0.2
Not uninstalling pip at /usr/lib/python3/dist-packages, outside environment /usr
Can't uninstall 'pip'. No files were found to uninstall.
Successfully installed pip-21.0.1
alanjui@VB02-Ubuntu-2004:~$ which pip
/usr/local/bin/pip
alanjui@VB02-Ubuntu-2004:~$ pip --version
pip 21.0.1 from /usr/local/lib/python3.8/dist-packages/pip (python 3.8)
alanjui@VB02-Ubuntu-2004:~$ pip3 --version
pip 21.0.1 from /usr/local/lib/python3.8/dist-packages/pip (python 3.8)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
📚 使用 pip 安裝 Python 套件
- 安裝在 Local 端
【安裝目錄路徑】:
📦 執行檔: ~/.local/bin/[Python-Package-Name] 📦 套件檔: ~/.local/bin/python3.8/site-packages/**
📺
alanjui@VB02-Ubuntu-2004:~/workspace/django$ pip uninstall autopep8
Found existing installation: autopep8 1.5.5
Uninstalling autopep8-1.5.5:
Would remove:
/home/alanjui/.local/bin/autopep8
/home/alanjui/.local/lib/python3.8/site-packages/autopep8-1.5.5.dist-info/*
/home/alanjui/.local/lib/python3.8/site-packages/autopep8.py
Proceed (y/n)? y
Successfully uninstalled autopep8-1.5.5
2
3
4
5
6
7
8
9
- 安裝在 Global 端
【安裝目錄路徑】:
📦 執行檔: /usr/local/bin/[Python-Package-Name] 📦 套件檔: /usr/local/lib/python3.8/site-packages/**
📺
alanjui@VB02-Ubuntu-2004:~/workspace/django$ sudo -H pip uninstall uwsgi
Found existing installation: uWSGI 2.0.19.1
Uninstalling uWSGI-2.0.19.1:
Would remove:
/usr/local/bin/uwsgi
/usr/local/lib/python3.8/dist-packages/uWSGI-2.0.19.1.dist-info/*
/usr/local/lib/python3.8/dist-packages/uwsgidecorators.py
Proceed (y/n)?
2
3
4
5
6
7
8
# 安裝 Vim 編輯器
安裝 Vim 編輯器。
# 安裝軟體
- 下載原始碼。
git clone https://github.com/vim/vim.git
- 編輯原始碼與安裝執行檔。
cd vim
./configure
sudo apt install ncurses-dev
make
sudo make install
2
3
4
5
# 設定作業環境
- 安裝 vim 作業設定檔
git clone https://github.com/AlanJui/vim8.git ~/.vim
- 安裝 Vim Plugins。
啟動 vim ,以便 vim 自動安裝 vim plugins 。
- 安裝 vim plugins 相依套件。
sudo apt install vifm
sudo apt install fzf
sudo apt install ripgrep
2
3
npm i -g bash-language-server
📺
alanjui@VB02-Ubuntu-2004:~$ npm i -g bash-language-server
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated request-promise-native@1.0.9: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142
npm WARN deprecated har-validator@5.1.5: this library is no longer supported
npm WARN deprecated left-pad@1.3.0: use String.prototype.padStart()
/home/alanjui/n/bin/bash-language-server -> /home/alanjui/n/lib/node_modules/bash-language-server/bin/main.js
+ bash-language-server@1.17.0
added 115 packages from 220 contributors in 9.368s
2
3
4
5
6
7
8
# 安裝 nginx 服務
安裝 nginx 作為 HTTP Server。
# 安裝 nginx 套件
- 安裝 nginx 套件。
sudo apt install nginx -y
- 驗證 nginx 服務已啟動。
- 驗證服務已啟用,且能隨作業系統開機自動啟動
systemctl status nginx
📺
alanjui@VB02-Ubuntu-2004:~$ systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2021-03-26 14:30:00 CST; 1min 10s ago
Docs: man:nginx(8)
Main PID: 67493 (nginx)
Tasks: 3 (limit: 4653)
Memory: 4.8M
CGroup: /system.slice/nginx.service
├─67493 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
├─67494 nginx: worker process
└─67495 nginx: worker process
3月 26 14:30:00 VB02-Ubuntu-2004 systemd[1]: Starting A high performance web server and a reverse proxy ser>
3月 26 14:30:00 VB02-Ubuntu-2004 systemd[1]: Started A high performance web server and a reverse proxy serv>
lines 1-14/14 (END)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 驗證 nginx 的 HTTP Server 已能正常運作
使用 Web 瀏覽器,瀏覽如下網址,若能正常閱讀「網頁」內容,則表 HTTP Server 已能 正常運作。
http://[IP_Address]
# 建置 nginx 虛擬網站
- 建置「網站目錄」。
sudo su
mkdir /var/www/app.ccc.tw.local && cd $_
echo "app.ccc.tw.local Web Site" > index.html
2
3
- 套用 defaut 虛擬網站設定檔,建置 Django App 虛擬網站。
cd /var/www/sites-available
cp default app.ccc.tw.local
vim app.ccc.tw.local
2
3
🔖 app.ccc.tw.local:
server {
listen 80;
server_name app.ccc.tw.local;
root /var/www/app.ccc.tw.local;
index index.html;
location / {
¦ try_files $uri $uri/ =404;
}
}
2
3
4
5
6
7
8
9
10
11
12
- 停用 Default 虛擬網站
cd ./sites-enabled
unlink default
2
- 啟用 Django App 虛擬網站
ln -nfs ../sites-available/app.ccc.tw.local
- 檢驗目前的設定正確無誤。
nginx -t
- 重啟 nginx 服務。
systemctl restart nginx
systemclt status nginx
2
- 驗證 Django App 虛擬網站的 HTTP 服務已能正常運作。
使用 Web 瀏覽器,瀏覽網址: http://app.ccc.tw.local/ 。若一切正常,應能於瀏覽器 看到如下「內容」之網頁。
app.ccc.tw.local Web Site
《以 Nginx 建置 Django Web Server 指引》
# 安裝 uWSGI 服務
安裝 uWSGI 服務作為 WSGI (Web Server Gateway Interface) 。
# 安裝作業
- 安裝 uWSGI 套件。
sudo -H pip3 install uwsgi
或
sudo pip3 install https://projects.unbit.it/downloads/uwsgi-lts.tar.gz
📺
alanjui@VB02-Ubuntu-2004:~/www/mysite$ pip3 list
Package Version
---------------------- --------------------
apturl 0.5.2
asgiref 3.3.1
blinker 1.4
Brlapi 0.7.0
certifi 2019.11.28
chardet 3.0.4
Click 7.0
colorama 0.4.3
command-not-found 0.3
cryptography 2.8
cupshelpers 1.0
dbus-python 1.2.16
defer 1.0.6
distro 1.4.0
distro-info 0.23ubuntu1
Django 3.1.7
....
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
alanjui@VB02-Ubuntu-2004:~/www/mysite$ which uwsgi
/usr/bin/uwsgi
alanjui@VB02-Ubuntu-2004:~/www/mysite$ ll /usr/bin/uwsgi
lrwxrwxrwx 1 root root 23 3月 28 14:10 /usr/bin/uwsgi -> /etc/alternatives/uwsgi*
alanjui@VB02-Ubuntu-2004:~/www/mysite$ ll /etc/alternatives/uwsgi
lrwxrwxrwx 1 root root 19 3月 28 14:10 /etc/alternatives/uwsgi -> /usr/bin/uwsgi-core*
alanjui@VB02-Ubuntu-2004:~/www/mysite$ ll /usr/bin/uwsgi-core
-rwxr-xr-x 1 root root 935112 4月 11 2020 /usr/bin/uwsgi-core*
2
3
4
5
6
7
8
# 驗證作業
驗證 Web Client 傳來之 HTTP Request ,能被 uwsgi 服務接收,並轉傳至 Django App 。
通信路徑: Web Client ⬅➡ uWSGI ⬅➡ Django App Web Client ⬅➡ Web Server ⬅➡ Web Socket (Socket File) ⬅➡ uWSGI ⬅➡ Django App
- 建置測試用 Django App
# 建置專案目錄
cd
mkdir -p www/mysite && cd $_
# 升級 pip3 套件管理器至最新版
python3 -m pip3 install --upgrade pip3
# 建置及啟用虛擬環境
python3 -m venv .venv
source .venv/bin/activate
# 安裝 Django App 所需套件
pip3 install django
django-admin
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- 修訂 Django App 原始碼,使之能與 uwsgi 及 nginx 整合運作。
- 下載 Django App 原始檔
cd /var/www
sudo git clone alanjui@192.168.66.21:"~/workspace/django/test-100" mysite.ccc.tw.local
sudo git config --global user.email "alanjui.1960@gmail.com"
sudo git config --global user.name "Alan Jui"
2
3
4
sudo chown -R www-data:www-data mysite.ccc.tw.local
- 編輯 Django App 的設定檔
cd /home/alanjui/www/mysite
vim mysite/settings.py
2
- 設定 ALLOWED_HOSTS ,接收來自 host: mysite.ccc.tw.local 的 HTTP Request
🔖 mysite/settings.py
allowed_hosts = [
'mysite.ccc.tw.local',
'localhost',
'127.0.0.1',
]
2
3
4
5
- 設定 static_root ,令「靜態檔」集中匯入:專案目錄下的子目錄:static_collected
🔖 mysite/settings.py
static_root = base_dir / 'static_collected'
【註】:目錄全路徑 /home/alanjui/www/mysite/static_collected/ 。
- 佈署 Django App 的「靜態檔案(static files)」。
匯集所有靜態檔案至「靜態檔佈署目錄」: /home/alanjui/www/mysite/static_collected/
./manage.py collectstatic
- 佈署 Django App 的 Media 檔案
mkdir media
cp static_collected/admin/img/search.svg media/
2
- 建置 Nginx 虛擬網站。
- 建置虛擬網站設定檔
cd /var/www
sudo ln -nfs config/mysite.ccc.tw.local.conf /etc/nginx/sites-enabled
2
🔖 mysite.ccc.tw.local
server {
listen 80;
server_name mysite.ccc.tw.local;
root /var/www/mysite.ccc.tw.local;
index index.html;
location / {
¦ try_files $uri $uri/ =404;
}
}
2
3
4
5
6
7
8
9
10
11
12
- 停用 Default 虛擬網站
cd ./sites-enabled
unlink default
2
- 啟用 Django App 虛擬網站
ln -nfs ../sites-available/mysite.ccc.tw.local
- 驗證設定語法正確土
nginx -t
- 重啟 Nginx 服務
systemctl restart nginx
systemctl status nginx
2
- 建置 uWSGI 服務。
建置 uWSGI 服務設定檔: mysite_uwsgi.ini 。
cd /home/alanjui/www/mysite
vim mysite_uwsgi.ini
2
🔖 mysite_uwsgi.ini
# mysite_uwsgi.ini file
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /home/alanjui/www/mysite
# Django's wsgi file
module = mysite.wsgi
# the virtualenv (full path)
home = /home/alanjui/.pyenv/versions/3.9.1/envs/venv-3.9.1
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 10
# the socket (use the full path to be safe
socket = /home/alanjui/www/mysite/mysite.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
# clear environment on exit
vacuum = true
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- 啟動 uwsgi 服務
以 Emperor Mode 啟用 uWSGI 服務。
- 建置 Emperor Mode 服務用 vassals 目錄
sudo mkdir -p /etc/uwsgi/vassals
- 啟用服務設定
建立 uwsgi 設定檔的連結,放至目錄路徑中: /etc/uwsgi/vassals/
sudo ln -s /home/alanjui/www/mysite/mysite_uwsgi.ini /etc/uwsgi/vassals/
- 以 Emper Mode 啟用 uwsgi 服務
uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data
- 驗證能存取 static 靜態檔案
在 Web 瀏覽器,瀏覽網址: http://mysite.ccc.tw.local:8000/static/admin/img/search.svg ,確認「網頁」能見到「放大鏡圖示」。
- 驗證能存取 media 靜態檔案
在 Web 瀏覽器,瀏覽網址: http://mysite.ccc.tw.local:8000/media/search.svg ,確認「網頁」能見到「放大鏡圖示」。
- 驗證非存取 static 與 media 的 HTTP Request 會被送往 Django App
在 Web 瀏覽器,瀏覽網址: http://mysite.ccc.tw.local:8000/ ,確認「網頁」能見到 如下圖之內容。
📺
alanjui@VB02-Ubuntu-2004:~$ uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data
*** Starting uWSGI 2.0.19.1 (64bit) on [Mon Mar 29 20:30:47 2021] ***
compiled with version: 9.3.0 on 28 March 2021 03:49:51
os: Linux-5.8.0-48-generic #54~20.04.1-Ubuntu SMP Sat Mar 20 13:40:25 UTC 2021
nodename: VB02-Ubuntu-2004
machine: x86_64
clock source: unix
detected number of CPU cores: 2
current working directory: /home/alanjui
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 15511
your memory page size is 4096 bytes
detected max file descriptor number: 1024
*** starting uWSGI Emperor ***
*** has_emperor mode detected (fd: 6) ***
[uWSGI] getting INI configuration from mysite_uwsgi.ini
*** Starting uWSGI 2.0.19.1 (64bit) on [Mon Mar 29 20:30:47 2021] ***
compiled with version: 9.3.0 on 28 March 2021 03:49:51
os: Linux-5.8.0-48-generic #54~20.04.1-Ubuntu SMP Sat Mar 20 13:40:25 UTC 2021
nodename: VB02-Ubuntu-2004
machine: x86_64
clock source: unix
detected number of CPU cores: 2
current working directory: /etc/uwsgi/vassals
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
chdir() to /home/alanjui/www/mysite
your processes number limit is 15511
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to UNIX address /home/alanjui/www/mysite/mysite.sock fd 3
Python version: 3.8.5 (default, Jan 27 2021, 15:41:15) [GCC 9.3.0]
PEP 405 virtualenv detected: /home/alanjui/www/mysite/.venv
Set PythonHome to /home/alanjui/www/mysite/.venv
*** Python threads support is disabled. You can enable it with --enable-threads ***
Python main interpreter initialized at 0x55fd299c7560
your server socket listen backlog is limited to 100 connections
your mercy for graceful operations on workers is 60 seconds
mapped 802120 bytes (783 KB) for 10 cores
*** Operational MODE: preforking ***
WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x55fd299c7560 pid: 102642 (default app)
*** uWSGI is running in multiple interpreter mode ***
spawned uWSGI master process (pid: 102642)
Mon Mar 29 20:30:47 2021 - [emperor] vassal mysite_uwsgi.ini has been spawned
spawned uWSGI worker 1 (pid: 102644, cores: 1)
Mon Mar 29 20:30:47 2021 - [emperor] vassal mysite_uwsgi.ini is ready to accept requests
spawned uWSGI worker 2 (pid: 102645, cores: 1)
spawned uWSGI worker 3 (pid: 102646, cores: 1)
spawned uWSGI worker 4 (pid: 102647, cores: 1)
spawned uWSGI worker 5 (pid: 102648, cores: 1)
spawned uWSGI worker 6 (pid: 102649, cores: 1)
spawned uWSGI worker 7 (pid: 102650, cores: 1)
spawned uWSGI worker 8 (pid: 102651, cores: 1)
spawned uWSGI worker 9 (pid: 102652, cores: 1)
spawned uWSGI worker 10 (pid: 102653, cores: 1)
[pid: 102652|app: 0|req: 1/1] 192.168.66.21 () {44 vars in 811 bytes} [Mon Mar 29 12:31:21 2021] GET / => generated 16351 bytes in 16 msecs (HTTP/1.1 200) 5 headers in 153 bytes (1 switches on core 0)
announcing my loyalty to the Emperor...
Mon Mar 29 20:31:21 2021 - [emperor] vassal mysite_uwsgi.ini is now loyal
^C[emperor] *** RAGNAROK EVOKED ***
Mon Mar 29 20:31:57 2021 - [emperor] stop the uwsgi instance mysite_uwsgi.ini
SIGINT/SIGQUIT received...killing workers...
Mon Mar 29 12:31:57 2021 - received message 0 from emperor
worker 1 buried after 1 seconds
worker 2 buried after 1 seconds
worker 3 buried after 1 seconds
worker 4 buried after 1 seconds
worker 5 buried after 1 seconds
worker 6 buried after 1 seconds
worker 7 buried after 1 seconds
worker 8 buried after 1 seconds
worker 9 buried after 1 seconds
worker 10 buried after 1 seconds
goodbye to uWSGI.
VACUUM: unix socket /home/alanjui/www/mysite/mysite.sock removed.
Mon Mar 29 20:31:59 2021 - [emperor] removed uwsgi instance mysite_uwsgi.ini
Mon Mar 29 20:32:00 2021 - The Emperor is buried.
alanjui@VB02-Ubuntu-2004:~$
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 問題診斷與狀況排除
# 解除作業系統預設之 vim
如下方式安裝之 VIM 套件,無法安裝「最新版」。
sudo apt install vim
若欲安裝最新版之 VIM ,可使用 GitHub 之原始碼建置。已安裝之 VIM ,可依以下方法, 解除原先安裝及清除設定。
sudo apt remove vim --purge
📺
alanjui@VB02-Ubuntu-2004:~$ sudo apt remove vim --purge
正在讀取套件清單... 完成
正在重建相依關係
正在讀取狀態資料... 完成
以下套件為自動安裝,並且已經無用:
vim-runtime
使用 'sudo apt autoremove' 將之移除。
下列套件將會被【移除】:
vim*
升級 0 個,新安裝 0 個,移除 1 個,有 0 個未被升級。
此操作完成之後,會空出 3,111 kB 的磁碟空間。
是否繼續進行 [Y/n]? [Y/n] y
(讀取資料庫 ... 目前共安裝了 171827 個檔案和目錄。)
正在移除 vim (2:8.1.2269-1ubuntu5)……
update-alternatives: 在自動模式下以 /usr/bin/vim.tiny 來提供 /usr/bin/vi (vi)
update-alternatives: 在自動模式下以 /usr/bin/vim.tiny 來提供 /usr/bin/view (view)
update-alternatives: 在自動模式下以 /usr/bin/vim.tiny 來提供 /usr/bin/ex (ex)
update-alternatives: 在自動模式下以 /usr/bin/vim.tiny 來提供 /usr/bin/rview (rview)
(讀取資料庫 ... 目前共安裝了 171818 個檔案和目錄。)
正在清除 vim (2:8.1.2269-1ubuntu5) 的設定檔……
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20