程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Docker-compose部署Django項目筆記

編輯:Python

准備好以下的內容

  1. 項目文件
  2. 使用pip freeze > requirements.txt命令打包好項目的依賴包列表
  3. 安裝好Docker和Docker-compose,可以分別用docker -vdocker-vompose -v命令查看是否安裝成功。

編寫Dockerfile文件

Docker 允許通過文本格式的配置文件來構建鏡像,默認名稱為 Dockerfile

# 從Docker倉庫中拉去帶有Python3.7的Linux環境
FROM python:3.7
# 設置 python 環境變量
ENV PYTHONUNBUFFERED 1
# 這兩行是在系統鐘安裝了MySQL的連接器
RUN apt-get update
RUN apt-get install python3-dev default-libmysqlclient-dev -y
# 創建 code 文件夾並將其設置為工作目錄
RUN mkdir /code
WORKDIR /code
# 更新 pip
RUN pip install pip -U
# 將 requirements.txt 復制到容器的 code 目錄
ADD requirements.txt /code/
# 安裝庫
RUN pip install -r requirements.txt
# 將當前目錄復制到容器的 code 目錄
ADD . /code/

理解這些Docker指令的關鍵,在於牢記容器內的環境和宿主機是隔離的,核心問題是搞清楚那些操作是針對宿主機,哪些操作是針對容器

FROM python:3.7 指令從倉庫拉取一個包含 python 3.7 的 Linux 操作系統環境(Linux 版本為 Debian)。

RUNWORKDIR 指令都是針對容器的,功能是在容器裡創建目錄、並將其設置為工作目錄。注意宿主機是沒有這個目錄的。

ADD 指令出現了兩次。ADD requirements.txt /code/ 意思是將宿主機當前目錄(即 Dockerfile 所在目錄)的 requirements.txt 文件復制到容器的 /code 目錄中。ADD . /code/ 意思是把當前目錄所有內容復制到容器 /code/ 目錄,注意中間那個

編寫docker-compose.yml文件

version: "3"
services:
app:
restart: always
build: .
command: bash -c "python3 manage.py collectstatic --no-input && python3 manage.py migrate && gunicorn --timeout=30 --workers=4 --bind :8000 django_app.wsgi:application"
volumes:
- .:/code
- static-volume:/code/collected_static
expose:
- "8000"
depends_on:
- db
networks:
- web_network
- db_network
db:
image: mysql:5.7
volumes:
- "./mysql:/var/lib/mysql"
ports:
- "3307:3306"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=mypassword
- MYSQL_DATABASE=django_app
networks:
- db_network
nginx:
restart: always
image: nginx:latest
ports:
- "8001:8000"
volumes:
- static-volume:/code/collected_static
- ./config/nginx:/etc/nginx/conf.d
depends_on:
- app
networks:,
- web_network
networks:
web_network:
driver: bridge
db_network:
driver: bridge
volumes:
static-volume:

version 代表 docker-compose.yml 的版本,目前最新版為 3,不需要改動它。

從整體上看,我們定義了三個容器,分別是appdb、和nginx,容器之間通過定義的端口進行通訊。定義了兩個網絡,分別是web_networkdb_network,只有處在同一網絡下的容器才能夠互相通訊。不同網絡之間是隔離的,即便采用同樣的端口,也無法通訊。定義了一個數據卷static-volume。數據卷非常適合多個容器共享使用同一數據,可以看到appnginx都使用到了它。exposeports都可以暴露容器的端口,區別是expose僅暴露給其他容器,而ports會暴露給其他容器和宿主機。

下面具體分析一下:

定義了一個名叫 app 的容器。後面的內容都是 app 容器的相關配置:

  • restart :除正常工作外,容器會在任何時候重啟,比如遭遇 bug、進程崩潰、docker 重啟等情況。
  • build :指定一個包含 Dockerfile 的路徑,並通過此 Dockerfile 來構建容器鏡像。注意那個 "." ,代表當前目錄。
  • command :容器運行時需要執行的命令。這裡就是我們很熟悉的運行開發服務器了。
  • volumes卷,這是個很重要的概念。前面說過容器是和宿主機完全隔離的,但是有些時候又需要將其連通;比如我們開發的 Django 項目代碼常常會更新,並且更新時還依賴如 Git 之類的程序,在容器裡操作就顯得不太方便。所以就有,它定義了宿主機和容器之間的映射:"." 表示宿主機的當前目錄,":" 為分隔符,"/code" 表示容器中的目錄。即宿主機當前目錄和容器的 /code 目錄是連通的,宿主機當前目錄的 Django 代碼更新時,容器中的 /code 目錄中的代碼也相應的更新了。這有點兒像是在容器上打了一個洞,某種程度上也是實用性隔離性的一種妥協。

嚴格意義上講,這裡用到的 .:/code 並不是,而是叫掛載,它兩是有區別的,只不過 docker-compose 允許將掛載寫到卷的配置中。

  • expose:暴露容器的8000端口供其他容器訪問,宿主機和外界無法訪問
  • networks:能夠訪問web_networkdb_network
  • depends_on ,意思是此容器需要等待 db 容器啟動完畢才能夠啟動。

分析一下 db 容器:

  • image :從倉庫拉取 MySQL 5.7 。
  • volumes :這裡出現的 static-volume。它的使用方式像這樣:static-volume:/code/collected_static ,冒號後面還是容器內的目錄,但冒號前的卻不是宿主機目錄、僅僅是卷的名稱而已。從本質上講,數據卷也是實現了宿主機和容器的目錄映射,但是數據卷是由 Docker 進行管理的,你甚至都不需要知道數據卷保存在宿主機的具體位置。

相比掛載,數據卷的優點是由於是 Docker 統一管理的,不存在由於權限不夠引發的掛載問題,也不需要在不同服務器指定不同的路徑;缺點是它不太適合單配置文件的映射。和掛載一樣,數據卷的生命周期脫離了容器,刪除容器之後卷還是存在的。下次構建鏡像時,指定卷的名稱就可以繼續使用了。

  • ports :MySQL 默認通信端口為 3306 。由於我的機子上已經跑了一個MySQL服務,所以我將容器內的3306端口映射為本機的3307端口。
  • environment :定義容器的環境變量,設置了 MySQL 的 root 用戶的密碼、數據庫的名稱。
  • network:只能夠訪問db_network

添加db容器後記得的修改Django裡的數據庫設置。

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_app',
'USER': 'root',
'PASSWORD': 'mypassword',
'HOST': 'db',
'PORT': '3306',
'OPTIONS': {'charset': 'utf8mb4'},
}
}

最後分析一下nginx容器,其他配置與上述兩個大致一樣,值得說一說的是ports設置,由於我的服務器上部署了其他服務,所以我將nginx端口映射為8001。

Docker 允許用戶給每個容器定義其工作的網絡,只有在相同的網絡之中才能進行通訊。可以看到 nginx 容器處於 web_network 網絡,而 db 容器處於 db_network 網絡,因此它兩是無法通訊的,實際上確實也不需要通訊。而 app 容器同時處於 web_networkdb_network 網絡,相當於是橋梁,連通了3個容器。

Nginx配置

修改Nginx的配置文件,即映射到nginx容器內的config/nginx/django_app.conf

upstream app {
ip_hash;
server app:8000;
}
server {
listen 8000;
server_name localhost;
location /static/ {
autoindex on;
alias /code/collected_static/;
}
location / {
proxy_pass http://app/;
}
}

此配置下 Nginx 會監聽容器的 8000 端口,並將收到的請求發送到 app 容器(靜態文件請求除外)。

之後在requirements.txt文件的最後兩行增加mysqlclient庫和gunicorn庫。

mysqlclient==2.0.1
gunicorn==19.9.0

再修改Django項目的配置文件

ALLOWED_HOSTS = ['*']
...
STATIC_ROOT = os.path.join(BASE_DIR, 'collected_static')
STATIC_URL = '/static/'

部署

運行命令docker-compose build構造鏡像,再使用docker-compose up即可啟用服務。

下面附上一下經常用到的命令:

  • 停止容器,docker-compose down
  • 後台運行docker容器:docker-compose up -d
  • 只想啟動其中的一個容器:docker-compose up -d db或者docker-compose up -d app即可啟動db容器或app容器。
  • 進入容器:docker exec -it container_id /bin/bash
  • 上面的container_id如果不知道如何獲取可以通過docker ps命令查看。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved