完整的Django入門指南學習筆記7 網頁自動翻譯
轉自【https://simpleisbetterthancomplex.com/series/2017/10/16/a-complete-beginners-guide-to-django-part-7.html】
Django的初學者指南 - 第7部分
蘋果電腦 視窗 Linux的介紹
歡迎來到我們教程系列的最後一部分!在本教程中,我們將把Django應用程式部署到生產伺服器。我們還將為我們的伺服器配置電子郵件服務和HTTPS證書。
首先,我想到了一個使用虛擬專用伺服器(VPS)的例子,它更通用,然後使用一個平臺即服務,如Heroku。但它太詳細了,所以我最終建立了關於VPS的本教程。
我們的專案現場直播!如果您想在檢視文字之前線上檢視,這是我們要部署的應用程式:www.djangoboards.com。
版本控制
版本控制是軟體開發中非常重要的主題。特別是在與團隊合作並同時維護生產程式碼時,並行開發了多個功能。
版本控制系統有幾種選擇。也許是因為GitHub的流行,Git 成為版本控制的事實標準。所以如果你不熟悉版本控制,Git是一個很好的起點。一般有很多教程,課程和資源,因此很容易找到幫助。
GitHub和Code School有一個關於Git的很棒的互動教程,幾年前我開始從SVN轉到Git。這是一個非常好的介紹。
這是一個非常重要的主題,我可能應該從第一個教程開始提出它。但事實是我希望本教程系列的重點放在Django上。如果這一切對您來說都是新的,請不要擔心。一步一步是很重要的。你的第一個專案並不完美。重要的是要保持學習和慢慢發展你的技能,但要保持穩定。
關於Git的一個非常好的事情是它不僅僅是一個版本控制系統。圍繞它建立了豐富的工具和服務生態系統。一些很好的例子是持續整合,部署,程式碼審查,程式碼質量和專案管理。
使用Git來支援Django專案的部署過程非常有效。這是從原始碼儲存庫中提取最新版本或在出現問題時回滾到特定版本的便捷方式。有許多服務與Git整合,以便自動化測試執行和部署。
如果您沒有在本地計算機上安裝Git,請從https://git-scm.com/downloads獲取已安裝的。
基本設定
首先,設定你的身份:
git config --global user.name "Vitor Freitas"
git config --global user.email [email protected]
在專案根目錄(與manage.py相同的目錄)中,初始化一個git儲存庫:
git init
Initialized empty Git repository in /Users/vitorfs/Development/myproject/.git/
檢查儲存庫的狀態:
git status
On branch master
Initial commit
Untracked files:
(use "git add <file>..." to include in what will be committed)
accounts/
boards/
manage.py
myproject/
requirements.txt
static/
templates/
nothing added to commit but untracked files present (use "git add" to track)
在繼續新增原始檔之前,請在專案根目錄中建立名為.gitignore的新檔案。這個特殊的檔案將幫助我們保持儲存庫的清潔,而不需要像快取檔案或日誌這樣的不必要的檔案。
您可以 從GitHub 獲取Python專案的通用.gitignore檔案。
確保將它從Python.gitignore重新命名為.gitignore(點很重要!)。
您可以補充.gitignore檔案,告訴它忽略SQLite資料庫檔案,例如:
的.gitignore
__pycache__/
*.py[cod]
.env
venv/
# SQLite database files
*.sqlite3
現在將檔案新增到儲存庫:
git add .
請注意這裡的點。上面的命令告訴Git 在當前目錄中新增所有未跟蹤的檔案。
現在進行第一次提交:
git commit -m "Initial commit"
總是寫一個評論告訴這個提交是什麼,簡要描述你改變了什麼。
遠端儲存庫
現在讓我們將GitHub設定為遠端儲存庫。首先,在GitHub上建立一個免費帳戶,然後確認您的電子郵件地址。之後,您將能夠建立公共儲存庫。
現在,只需為儲存庫選擇一個名稱,不要使用自述檔案初始化它,或者新增.gitignore或新增許可證到目前為止。確保將儲存庫空啟動:
建立儲存庫後,您應該看到如下內容:
現在讓我們將其配置為我們的遠端儲存庫:
git remote add origin [email protected]:sibtc/django-boards.git
現在將程式碼推送到遠端伺服器,即GitHub儲存庫:
git push origin master
Counting objects: 84, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (81/81), done.
Writing objects: 100% (84/84), 319.70 KiB | 0 bytes/s, done.
Total 84 (delta 10), reused 0 (delta 0)
remote: Resolving deltas: 100% (10/10), done.
To [email protected]:sibtc/django-boards.git
* [new branch] master -> master
我建立此儲存庫只是為了演示使用現有程式碼庫建立遠端儲存庫的過程。該專案的原始碼正式託管在此儲存庫中:https: //github.com/sibtc/django-beginners-guide。
專案設定
無論程式碼是儲存在公共或私有遠端儲存庫中,都不應提交敏感資訊並將其推送到遠端儲存庫。這包括金鑰,密碼,API金鑰等。
此時,我們必須在settings.py模組中處理兩種特定型別的配置:
- 金鑰和密碼等敏感資訊;
- 特定於給定環境的配置。
密碼和金鑰可以儲存在環境變數中或使用本地檔案(未提交到遠端儲存庫):
# environment variables
import os
SECRET_KEY = os.environ['SECRET_KEY'] # or local files with open('/etc/secret_key.txt') as f: SECRET_KEY = f.read().strip()
為此, 我在我開發的每個Django專案中都使用了一個名為Python Decouple的優秀實用程式庫。它將搜尋名為.env的本地檔案以設定配置變數,並將回退到環境變數。它還提供了一個定義預設值的介面,在適用時將資料轉換為int,bool和list。
這不是強制性的,但我真的覺得它是一個非常有用的工具。它像Heroku這樣的服務就像魅力一樣。
首先,讓我們安裝它:
pip install python-decouple
的myproject / settings.py
from decouple import config
SECRET_KEY = config('SECRET_KEY')
現在,我們可以將敏感資訊放在一個名為.env的特殊檔案中(注意前面的點),該檔案位於manage.py檔案所在的目錄中:
myproject/
|-- myproject/
| |-- accounts/
| |-- boards/
| |-- myproject/
| |-- static/
| |-- templates/
| |-- .env <-- here!
| |-- .gitignore
| |-- db.sqlite3
| +-- manage.py
+-- venv/
.ENV
SECRET_KEY=rqr_cjv4igscyu8&&(0ce(=sy=f2)p=f_wn&@[email protected]!kp=d
該.ENV檔案中忽略的.gitignore檔案,所以每次我們要部署應用程式或在不同的機器上執行時,我們將建立一個.ENV檔案,並新增必要的配置。
現在讓我們安裝另一個庫來幫助我們在一行中編寫資料庫連線。這樣,在不同的環境中編寫不同的資料庫連線字串會更容易:
pip install dj-database-url
目前,我們需要解耦的所有配置:
的myproject / settings.py
from decouple import config, Csv import dj_database_url SECRET_KEY = config('SECRET_KEY') DEBUG = config('DEBUG', default=False, cast=bool) ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv()) DATABASES = { 'default': dj_database_url.config( default=config('DATABASE_URL') ) }
本地計算機的.env檔案示例:
SECRET_KEY=rqr_cjv4igscyu8&&(0ce(=sy=f2)p=f_wn&@[email protected]!kp=d
DEBUG=True
ALLOWED_HOSTS=.localhost,127.0.0.1
請注意,在DEBUG
配置中我們有一個預設值,因此在生產中我們可以忽略此配置,因為它將被設定為False
自動設定,因為它應該是。
現在ALLOWED_HOSTS
將被轉換成一個列表['.localhost', '127.0.0.1'. ]
。現在,這是在我們的本地機器上,為了生產,我們將其設定為類似於['.djangoboards.com', ]
您擁有的任何域。
此特定配置可確保您的應用程式僅提供給此域。
跟蹤要求
跟蹤專案的依賴關係是一個很好的做法,因此更容易在另一臺機器上安裝它。
我們可以通過執行命令來檢查當前安裝的Python庫:
pip freeze
dj-database-url==0.4.2
Django==1.11.6
django-widget-tweaks==1.4.1
Markdown==2.6.9
python-decouple==3.1
pytz==2017.2
在專案根目錄中建立名為requirements.txt的檔案,並在其中新增依賴項:
requirements.txt
dj-database-url==0.4.2
Django==1.11.6
django-widget-tweaks==1.4.1
Markdown==2.6.9
python-decouple==3.1
我保留了pytz == 2017.2,因為它是由Django自動安裝的。
您可以更新原始碼儲存庫:
git add .
git commit -m "Add requirements.txt file"
git push origin master
域名
如果我們要正確部署Django應用程式,我們將需要一個域名。擁有域名來為應用程式提供服務,配置電子郵件服務和配置https證書非常重要。
最近,我一直在使用Namecheap 。您可以以8.88美元/年的價格獲得.com域名,或者如果您只是嘗試一下,您可以 以0.99美元/年的價格註冊.xyz域名。
無論如何,您可以自由使用任何註冊商。為了演示部署過程,我註冊了 www.DjangoBoards.com域名。
部署戰略
以下是我們將在本教程中使用的部署策略的概述:
雲是Digital Ocean提供的虛擬專用伺服器。您可以使用我的會員連結註冊Digital Ocean以獲得免費的10美元信用額度(僅適用於新帳戶)。
我們將提供NGINX,由食人魔說明。NGINX將收到對伺服器的所有請求。但如果請求資料,它不會嘗試做任何聰明的事情。它所要做的就是確定所請求的資訊是否是一個可以自行提供的靜態資產,或者它是否更復雜。如果是這樣,它會將請求傳遞給Gunicorn。
NGINX還將配置HTTPS證書。這意味著它只接受通過HTTPS的請求。如果客戶端嘗試通過HTTP請求,NGINX將首先將使用者重定向到HTTPS,然後它才會決定如何處理請求。
我們還將安裝此certbot以自動續訂Let的加密證書。
Gunicorn是一個應用伺服器。根據伺服器具有的處理器數量,它可以生成多個工作程式以並行處理多個請求。它管理工作負載並執行Python和Django程式碼。
Django是努力工作的人。它可以訪問資料庫(PostgreSQL)或檔案系統。但在大多數情況下,工作是在檢視內部完成,渲染模板,以及過去幾周我們編寫過的所有內容。在Django處理請求之後,它會向Gunicorn返回一個響應,他將結果返回給NGINX,最終將響應傳遞給客戶端。
我們還將安裝PostgreSQL,一個生產質量資料庫系統。由於Django的ORM系統,很容易切換資料庫。
最後一步是安裝Supervisor。它是一個過程控制系統,它將密切關注Gunicorn和Django,以確保一切順利進行。如果伺服器重新啟動,或者Gunicorn崩潰,它將自動重啟。
部署到VPS(數字海洋)
您可以使用您喜歡的任何其他VPS(虛擬專用伺服器)。配置應該非常相似,畢竟我們將使用Ubuntu 16.04作為我們的伺服器。
首先,讓我們建立一個新的伺服器(在Digital Ocean上,他們稱之為“Droplet”)。選擇Ubuntu 16.04:
選擇尺寸。最小的液滴足夠了:
然後為您的Droplet選擇一個主機名(在我的情況下為“django-boards”):
如果您有SSH金鑰,則可以將其新增到您的帳戶。然後,您將能夠使用它登入伺服器。否則,他們會通過電子郵件向您傳送root密碼。
現在選擇伺服器的IP地址:
在我們登入伺服器之前,讓我們將域名指向此IP地址。這將節省一些時間,因為DNS設定通常需要幾分鐘才能傳播。
所以這裡我們添加了兩條A記錄,一條指向裸域“djangoboards.com”,另一條指向“www.djangoboards.com”。我們將使用NGINX配置規範URL。
現在讓我們使用您的終端登入伺服器:
ssh [email protected]
[email protected]'s password:
然後你應該看到以下訊息:
You are required to change your password immediately (root enforced)
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-93-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud
0 packages can be updated.
0 updates are security updates.
Last login: Sun Oct 15 18:39:21 2017 from 82.128.188.51
Changing password for root.
(current) UNIX password:
設定新密碼,然後開始配置伺服器。
sudo apt-get update
sudo apt-get -y upgrade
如果在升級過程中收到任何提示,請選擇“保持當前安裝的本地版本”選項。
Python 3.6
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt-get update
sudo apt-get install python3.6
PostgreSQL的
sudo apt-get -y install postgresql postgresql-contrib
NGINX
sudo apt-get -y install nginx
監
sudo apt-get -y install supervisor
sudo systemctl enable supervisor
sudo systemctl start supervisor
VIRTUALENV
wget https://bootstrap.pypa.io/get-pip.py
sudo python3.6 get-pip.py
sudo pip3.6 install virtualenv
應用使用者
使用以下命令建立新使用者:
adduser boards
通常,我只選擇應用程式的名稱。輸入密碼,並可選擇在提示中新增一些額外資訊。
現在將使用者新增到sudoers列表:
gpasswd -a boards sudo
PostgreSQL資料庫設定
首先切換到postgres使用者:
sudo su - postgres
建立資料庫使用者:
createuser u_boards
建立一個新資料庫並將使用者設定為所有者:
createdb django_boards --owner u_boards
為使用者定義一個強密碼:
psql -c "ALTER USER u_boards WITH PASSWORD 'BcAZoYWsJbvE7RMgBPzxOCexPRVAq'"
我們現在可以退出postgres使用者了:
exit
Django專案設定
切換到應用程式使用者:
sudo su - boards
首先,我們可以檢查我們的位置:
pwd
/home/boards
首先,讓我們用我們的程式碼克隆儲存庫:
git clone https://github.com/sibtc/django-beginners-guide.git
啟動虛擬環境:
virtualenv venv -p python3.6
初始化virtualenv:
source venv/bin/activate
安裝要求:
pip install -r django-beginners-guide/requirements.txt
我們將在這裡新增兩個額外的庫,Gunicorn和PostgreSQL驅動程式:
pip install gunicorn
pip install psycopg2
現在在/ home / boards / django-beginners-guide資料夾中,讓我們建立一個.env檔案來儲存資料庫憑據,金鑰和其他所有內容:
/home/boards/django-beginners-guide/.env
SECRET_KEY=rqr_cjv4igscyu8&&(0ce(=sy=f2)p=f_wn&@[email protected]!kp=d
ALLOWED_HOSTS=.djangoboards.com
DATABASE_URL=postgres://u_boards:BcAZoYWsJbvE7RMgBPzxO[email protected]:5432/django_boards
以下是資料庫URL的語法:postgres:// db_user
:db_password
@ db_host
:db_port
/ db_name
。
現在讓我們遷移資料庫,收集靜態檔案並建立一個超級使用者:
cd django-beginners-guide
python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, boards, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying boards.0001_initial... OK
Applying boards.0002_auto_20170917_1618... OK
Applying boards.0003_topic_views... OK
Applying sessions.0001_initial... OK
現在靜態檔案:
python manage.py collectstatic
Copying '/home/boards/django-beginners-guide/static/js/jquery-3.2.1.min.js'
Copying '/home/boards/django-beginners-guide/static/js/popper.min.js'
Copying '/home/boards/django-beginners-guide/static/js/bootstrap.min.js'
Copying '/home/boards/django-beginners-guide/static/js/simplemde.min.js'
Copying '/home/boards/django-beginners-guide/static/css/app.css'
Copying '/home/boards/django-beginners-guide/static/css/bootstrap.min.css'
Copying '/home/boards/django-beginners-guide/static/css/accounts.css'
Copying '/home/boards/django-beginners-guide/static/css/simplemde.min.css'
Copying '/home/boards/django-beginners-guide/static/img/avatar.svg'
Copying '/home/boards/django-beginners-guide/static/img/shattered.png'
...
此命令將所有靜態資產複製到外部目錄,NGINX可以在該目錄中為我們提供檔案。稍後會詳細介紹。
現在為應用程式建立一個超級使用者:
python manage.py createsuperuser
配置Gunicorn
因此,Gunicorn是負責在代理伺服器後面執行Django程式碼的人。
在/ home / boards中建立一個名為gunicorn_start的新檔案:
#!/bin/bash
NAME="django_boards"
DIR=/home/boards/django-beginners-guide
USER=boards
GROUP=boards
WORKERS=3
BIND=unix:/home/boards/run/gunicorn.sock
DJANGO_SETTINGS_MODULE=myproject.settings
DJANGO_WSGI_MODULE=myproject.wsgi
LOG_LEVEL=error
cd $DIR
source ../venv/bin/activate
export DJANGO_SETTINGS_MODULE=$DJANGO_SETTINGS_MODULE
export PYTHONPATH=$DIR:$PYTHONPATH
exec ../venv/bin/gunicorn ${DJANGO_WSGI_MODULE}:application \
--name $NAME \
--workers $WORKERS \
--user=$USER \
--group=$GROUP \
--bind=$BIND \
--log-level=$LOG_LEVEL \
--log-file=-
此指令碼將啟動應用程式伺服器。我們提供了一些資訊,例如Django專案的位置,用於執行伺服器的應用程式使用者等等。
現在讓這個檔案可執行:
chmod u+x gunicorn_start
建立兩個空資料夾,一個用於套接字檔案,另一個用於儲存日誌:
mkdir run logs
現在/ home / boards裡面的目錄結構應該是這樣的:
django-beginners-guide/
gunicorn_start
logs/
run/
staticfiles/
venv/
該staticfiles資料夾由建立collectstatic命令。
配置Supervisor
首先,在/ home / boards / logs /資料夾中建立一個空的日誌檔案:
touch logs/gunicorn.log
現在建立一個新的supervisor檔案:
sudo vim /etc/supervisor/conf.d/boards.conf
[program:boards]
command=/home/boards/gunicorn_start
user=boards
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/home/boards/logs/gunicorn.log
儲存檔案並執行以下命令:
sudo supervisorctl reread
sudo supervisorctl update
現在檢查狀態:
sudo supervisorctl status boards
boards RUNNING pid 308, uptime 0:00:07
配置NGINX
下一步是設定NGINX伺服器以提供靜態檔案並將請求傳遞給Gunicorn:
在/ etc / nginx / sites-available /中新增一個名為boards的新配置檔案:
upstream app_server {
server unix:/home/boards/run/gunicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name www.djangoboards.com; # here can also be the IP address of the server
keepalive_timeout 5;
client_max_body_size 4G;
access_log /home/boards/logs/nginx-access.log;
error_log /home/boards/logs/nginx-error.log;
location /static/ {
alias /home/boards/staticfiles/;
}
# checks for static file, if not found proxy to app
location / {
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
建立指向已啟用站點的資料夾的符號連結:
sudo ln -s /etc/nginx/sites-available/boards /etc/nginx/sites-enabled/boards
刪除預設的NGINX網站:
sudo rm /etc/nginx/sites-enabled/default
重啟NGINX服務:
sudo service nginx restart
此時,如果DNS已經傳播,則該網站應在URL www.djangoboards.com上提供。
配置電子郵件服務
開始使用的最佳選擇之一是Mailgun。它提供了一個非常可靠的免費計劃,每月包含12,000封電子郵件。
註冊一個免費帳戶。然後按照步驟操作,這非常簡單。您必須與您註冊域名的服務一起工作。在我的例子中,它是Namecheap。
點選新增域以向您的帳戶新增新域。按照說明操作,確保使用“mg。”子域名:
現在抓住第一組DNS記錄,它是兩個TXT記錄:
使用您的註冊商提供的網路介面將其新增到您的域中:
對MX記錄做同樣的事情:
將它們新增到域中:
現在這一步不是強制性的,但由於我們已經在這裡,所以也要確認一下:
新增所有DNS記錄後,單擊“立即檢查DNS記錄”按鈕:
現在我們需要有一些耐心。有時需要一段時間來驗證DNS。
同時,我們可以配置應用程式以接收連線引數。
的myproject / settings.py
EMAIL_BACKEND = config('EMAIL_BACKEND', default='django.core.mail.backends.smtp.EmailBackend') EMAIL_HOST = config('EMAIL_HOST', default='') EMAIL_PORT = config('EMAIL_PORT', default=587, cast=int) EMAIL_HOST_USER = config('EMAIL_HOST_USER', default='') EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default='') EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=True, cast=bool) DEFAULT_FROM_EMAIL = 'Django Boards <[email protected]>' EMAIL_SUBJECT_PREFIX = '[Django Boards] '
然後,我的本地計算機.env檔案將如下所示:
SECRET_KEY=rqr_cjv4igscyu8&&(0ce(=sy=f2)p=f_wn&@[email protected]!kp=d
DEBUG=True
ALLOWED_HOSTS=.localhost,127.0.0.1
DATABASE_URL=sqlite:///db.sqlite3
EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend
我的生產.env檔案看起來像這樣:
SECRET_KEY=rqr_cjv4igscyu8&&(0ce(=sy=f2)p=f_wn&@[email protected]!kp=d
ALLOWED_HOSTS=.djangoboards.com
DATABASE_URL=postgres://u_boards:[email protected]:5432/django_boards
EMAIL_HOST=smtp.mailgun.org
[email protected]
EMAIL_HOST_PASSWORD=ED2vmrnGTM1Rdwlhazyhxxcd0F
您可以在Mailgun 的“ 域資訊”部分中找到您的憑據。
- EMAIL_HOST:SMTP主機名
- EMAIL_HOST_USER:預設SMTP登入
- EMAIL_HOST_PASSWORD:預設密碼
我們可以在生產伺服器中測試新設定。在本地計算機上的settings.py檔案中進行更改,將更改提交到遠端儲存庫。然後,在伺服器中拉出新程式碼並重新啟動Gunicorn程序:
git pull
使用電子郵件憑據編輯.env檔案。
然後重啟Gunicorn程序:
sudo supervisorctl restart boards
現在我們可以嘗試啟動密碼重置過程:
在Mailgun儀表板上,您可以獲得有關電子郵件傳遞的一些統計資訊:
配置HTTPS證書
現在讓我們使用Let's Encrypt提供的一個很好的HTTPS證書來保護我們的應用程式。
設定HTTPS從未如此簡單。更好的是,我們現在可以免費獲得它。他們提供了一個名為certbot的解決方案 ,負責為我們安裝和更新證書。這非常簡單:
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx
現在安裝證書:
sudo certbot --nginx
只需按照提示操作即可。當被問及:
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
選擇2
將所有HTTP流量重定向到HTTPS。
有了這個,該網站已經通過HTTPS提供服務:
設定證書的自動續訂。執行以下命令編輯crontab檔案:
sudo crontab -e
將以下行新增到檔案末尾:
0 4 * * * /usr/bin/certbot renew --quiet
該命令將每天凌晨4點執行。所有在30天內到期的證書將自動續訂。