使用docker-compose搭建django+vue工程
隨著虛擬化技術的發展,越來越多的web工程採用docker進行部署運維。我們嘗試使用docker-compose編排一個後端基於django,前端基於vue,資料庫為postgresql並使用nginx進行反向代理的web工程。
工程準備
Docker
django
- 在python3.7的環境下建立
django-admin startproject dockerdemo
- 修改settings.py檔案
- 修改
DEBUG=False
ALLOWED_HOSTS = ['127.0.0.1', 'web']
- 將靜態檔案收集路徑新增進
STATIC_ROOT
,筆者設定為static - 新增
STATICFILES_DIRS
,此項配置後 django 的collectstatic
會在此路徑下收集靜態檔案到STATIC_ROOT
的路徑中去。 - 另外,靜態檔案的處理筆者採用的是 whitenoise 的方案進行處理,所以需要在中介軟體中配置一下whitenoise的處理中介軟體。
'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware',
- 同時設定
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
- 修改資料庫資訊(可選),針對實際使用的資料庫進行配置,也可以採用django預設的sqlite,筆者此處演示了postgresql的簡單配置
- TEMPLATES下的DIRS配置為
os.path.join(BASE_DIR, 'web', 'dist')
- 修改
- 配置views.py和urls.py將首頁設為vue的index.html
vue
- 使用vue-cli3建立了一個簡單的vue工程
- 配置
npm run build
的靜態檔案目錄到 dist/static 中
nginx
準備nginx的配置檔案,進行埠轉發的設定。
映象和編排
我們先確定一下部署一個web工程所需要的環節。在這裡筆者繪製了一張流程圖。
按照流程圖的順序,我們編寫一下Dockerfile和docker-compose.yml
資料庫
資料庫需要先準備一下web工程使用的使用者和資料庫,這裡涉及到一個點,就是如何初始化資料庫的問題。這裡以postgresql舉例。
官方文件中提供了兩種示例,一種是配置環境變數:
- POSTGRES_DB
- POSTGRES_USER
- POSTGRES_PASSWORD
另一種是將初始化指令碼拷貝進/docker-entrypoint-initdb.d/ 中,映象在初始化的時候會執行資料夾下的所有指令碼,我們可以在指令碼中建立資料庫和使用者。這裡給出指令碼的一種方式。
#!/bin/bash
set -e
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
CREATE USER $DATABASE_USER;
CREATE DATABASE $DATABASE_NAME;
GRANT ALL PRIVILEGES ON DATABASE $DATABASE_NAME TO $DATABASE_USER;
EOSQL
需要注意的是,初始化操作盡在第一次build的時候又進行初始化。以後如果終止了docker-compose或者使用 docker-compose stop
指令之後再啟動是不重新初始化的。只有在 docker-compose down
命令執行過後,再執行啟動命令才會進行初始化。
web
我們的web工程在一個Dockerfile分為構建和執行兩部分內容。分別使用node:8映象作為前端構建的基礎映象和python:3.7作為django工程執行的基礎映象。比較有意思的點在於一份Dockerfile是可以分階段構建的,也就是可以編寫多個FROM並且用as給一個別名,後面的映象可以通過這個別名獲取該映象的一些內容,比如COPY --from等方式。
前端
前端內容比較簡單,就是將程式碼拷到工作目錄下,配置一下淘寶的映象代理,然後執行 npm run build
構建一下前端靜態檔案即可。
django
pip安裝一下依賴,另外在安裝一下gunicorn。由於如果在windows環境下進行開發,gunicorn是無法安裝的,所以我們這裡單獨放進Dockerfile中進行安裝。使用的映象是清華大學提供的映象地址。依賴安裝完成後,執行一下靜態檔案的收集指令即可。
nginx
準備一份配置檔案,監聽80埠並將接收到的請求全部轉發給django工程。筆者準備了比較簡單的一份配置檔案。其他具體需求還需根據場景進行設定。
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://web:8123;
}
}
ignore
編寫 .dockerignore 檔案忽略掉一些不需要打包的檔案,如node_modules等。
docker-compose.yml
這份檔案用來編排一個工程,主要內容是上面描述的web, nginx和postgres這3項。除此之外還有一些細節。
- nginx和postgres都需要將資料卷掛載到存放相應配置和資料的地方
- 資料庫的相關資訊用環境變數來讀取,因此我們準備一份.env檔案,並通過env_file指定讀取的環境變數檔案。
- web中我們對command進行了一些設定,延遲8秒是為了等待資料庫啟動完成。接著進行資料庫的資料遷移,最後用gunicorn進行啟動。
- 在映象中配置
depends_on
或者links
可以達到利用服務名稱進行網路通訊的效果,另外depends_on還可以控制容器的啟動順序進行以來控制。
效果
訪問 http://localhost/ 或 http://localhost/admin/ 可以檢視最終起起來的效果。
程式碼地址
https://github.com/will4906/dockerdemo