docker-compose+postsql多容器部署django-vue项目
一、docker-compose安裝
1、在安裝好docker基礎上,linux系統運行以下命令以下載 Docker Compose 的當前穩定版本
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 要安裝其他版本的 Compose,請替換 1.29.2。2、將可執行權限應用于二進制文件、創建軟連接、測試是否安裝成功。
sudo chmod +x /usr/local/bin/docker-compose sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose3、docker-compose version測試是否安裝成功
?二、部署
Django + Uwsgi + Nginx + Postgres?+ Redis組合容器
本例中我們將使用docker-compose編排并啟動4個容器,這個更接近于實際生成環境下的部署。
這四個容器的依賴關系是:Django+Uwsgi 容器依賴 Redis 容器和 PostgreSQL 容器,Nginx 容器依賴Django+Uwsgi容器。為了方便容器間的相互訪問和通信,我們使用docker-compose時可以給每個容器取個別名,這樣訪問容器時就可以直接使用別名訪問,而不使用Docker臨時給容器分配的IP了。
Docker-compose部署Django-vue項目路徑樹形圖
pwd顯示的目錄:/home/edwin/docker_project/quotationBackend
該目錄下的大致項目結構:
└── quotationBackend? ? ? ? ? ? ?# 常規Django項目目錄
? ? ├── Dockerfile? ? ? ? ? ? ? ? ? ? ? # 構建Django+Uwsgi鏡像的Dockerfile
?? ?├── docker-compose.yml ? ? # 核心編排文件
? ? ├── manage.py
? ? ├── quotationBackend? ? ? ? ? # Django項目配置文件
? ? │? ? ? ? ├── asgi.py
? ? │? ? ? ? ├── __init__.py
? ? │? ? ? ? ├── settings.py
? ? │? ? ? ? ├── urls.py
? ? │? ? ? ? └── wsgi.py
? ? ├── pip.conf? ? ? ? ? ? ? ? ? ? ? ? ? ?# 非必需。pypi源設置成國內,加速pip安裝
? ? ├── requirements.txt? ? ? ? ? ? ? # Django項目依賴文件
? ? ├── start.sh? ? ? ? ? ? ? ? ? ? ? ? ? ? # 啟動Django+Uwsgi容器后要執行的腳本
? ? ├── dist? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 前端vue打包后的文件
? ? └── uwsgi.ini? ? ? ? ? ? ? ? ? ? ? ? ? # uwsgi配置文件
?? ?├── nginx
?? ?│? ? ? ? ├── Dockerfile? ? ? ? ? ? ? # 構建Nginx鏡像所的Dockerfile
? ? │? ? ? ? ├── log? ? ? ? ? ? ? ? ? ? ? ? ?# 掛載保存nginx容器內日志log目錄
? ? │? ? ? ? ├── nginx.conf? ? ? ? ? ? ?# Nginx配置文件
? ? │? ? ? ? ├── ssl? ? ? ? ? ? ? ? ? ? ? ? ?# 如果需要配置https需要用到
下面正式開始部署:
第一步:編寫Nginx鏡像和容器所需文件
1、構建Nginx鏡像所使用的Dockerfile如下所示:
FROM nginxRUN rm -rf /etc/nginx/conf.d/default.conf && mkdir -p /root/docker_project/frontend # 第一句刪除nginx容器內路徑下的default.conf(可不刪除)和創建存放前端項目的路徑。 # -p 確保目錄名稱存在,不存在的就建一個。 COPY ./nginx.conf?/etc/nginx # 拷貝當前路徑下的配置文件到nginx容器里。2、Nginx的配置文件如下所示:
user root root; worker_processes 1;events {worker_connections 1024; }http {include mime.types;access_log /var/log/nginx/access.log;error_log /var/log/nginx/error.log warn;default_type application/octet-stream;sendfile on;keepalive_timeout 65;upstream django_backend {server django_web:9000;}server {listen 9001;server_name localhost; # 不能填宿主機IPcharset utf-8;client_max_body_size 10M; # 限制用戶上傳文件大小location / {root /root/docker_project/frontend;index index.html index.htm;}location /api/{rewrite ^/api/(.*)$ /$1 break;include /etc/nginx/uwsgi_params;uwsgi_pass django_backend;}} }?第二步:編寫Web (Django+Uwsgi)鏡像和容器所需文件
1、構建Web鏡像(Django+Uwsgi)的所使用的Dockerfile如下所示:
FROM python:3.7 # 鏡像作者 MAINTAINER zt_9773RUN mkdir -p /root/docker_project/quotationBackendWORKDIR /root/docker_project/quotationBackend # 指定工作目錄,比較重要,一般掛載路徑是基于此路徑# 可選:設置鏡像源為國內,設置后會快很多 COPY pip.conf /root/.pip/pip.conf # 將當前目錄copy到工作目錄中(. 表示當前目錄) COPY . /root/docker_project/quotationBackend# 安裝項目依賴、給start.sh可執行權限(用于后續啟動uwsgi) RUN pip install -r requirements.txt \&& chmod +x ./start.sh2、start.sh啟動腳本文件內容如下所示
#!/bin/bash python manage.py makemigrations && python manage.py migrate && uwsgi --ini uwsgi.ini && tail -f /dev/null# tail空命令防止web容器執行腳本后退出3、uwsgi.ini配置文件如下所示:文件沒有配置python虛擬環境,用的是容器默認的環境,所以可不用配置。
[uwsgi] socket=0.0.0.0:9000 chdir=/root/docker_project/quotationBackend/ module=quotationBackend.wsgi:application master=true processes=4 threads=2 vacuum=true thunder-lock=true enable-threads=true pidfile=uwsgi.pid daemonize = uwsgi.log第三步:編寫docker-compose.yml文件
定義了2個數據卷,用于掛載容器內動態生成的數據,比如postSQL的存儲數據,redis生成的快照這樣即使刪除容器,容器內產生的數據也不會丟失。
我們還定義了3個網絡,分別為nginx_network(用于nginx和web容器間的通信),db_network(用于db和web容器間的通信)和redis_network(用于redis和web容器間的通信)。
整個編排里包含4項容器服務,別名分別為redis,?database,?nginx和django_web,接下來我們將依次看看各個容器的Dockerfile和配置文件。
我這里redis和數據庫直接使用的官方鏡像,沒有配置文件,因為可以直接使用,所以就沒有單獨給redis和數據庫編寫Dockerfile文件。
version: "3"# 自定義數據卷 volumes:postgres_vol:redis_vol:# 自定義網絡(默認橋接), 不使用links通信 networks:nginx_network:driver: bridgedb_network:driver: bridgeredis_network:driver: bridgeservices:redis:image: redisnetworks:- redis_networkvolumes:- redis_vol:/data # 以數據卷掛載給reids數據備份ports:- "6379:6379"restart: alwaysdatabase:image: postgres:12environment:POSTGRES_DB: quotationBackend # 數據庫名字,不存在會自動創建POSTGRES_USER: postgresPOSTGRES_PASSWORD: 123456networks:- db_networkvolumes:- postgres_vol:/var/lib/postgresql/dataports:- "5432:5432"restart: alwaysdjango_web:build: ./expose:- "9000"volumes:- .:/root/docker_project/quotationBackend # 掛載項目代碼networks:- db_network- redis_network- nginx_networkdepends_on:- database- rediscommand: ./start.sh # 啟動uwsgirestart: alwaysnginx:build: ./nginxports:- "9001:9001"volumes:- ./dist:/root/docker_project/frontend # 掛載前端vue打包后文件- ./nginx/nginx.conf:/etc/nginx/nginx.conf # 掛載配置文件- ./logs:/var/log/nginx # 掛載日志networks:- nginx_networkdepends_on:- django_webrestart: always第四步:修改Django項目settings.py
主要幾項配置需要修改如下:
DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql_psycopg2','NAME': 'quotationBackend','USER': 'postgres','PASSWORD': '123456','HOST': 'database', # docker-compose.yml中'PORT': '5432'} }DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' # 用處后面問題總結中介紹CACHES = {"default": {"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://redis:6379", # docker-compose.yml中"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient",# 連接池數量,如果decode_responses不設置為True的話,# 使用get_redis_connection讀取的數據是bytes,# 需要decode為utf-8"CONNECTION_POOL_KWARGS": {"max_connections": 100, "decode_responses": True},# "PASSWORD": "123456",}} }第五步:使用docker-compose 構建鏡像并啟動容器組服務
現在我們可以使用docker-compose命名構建鏡像并啟動容器組了。
# 進入docker-compose.yml所在文件夾,輸入以下命令構建鏡像 sudo docker-compose build # 查看已生成的鏡像和已經啟動的容器 sudo docker images sudo docker ps # 啟動容器組服務 sudo docker-compose up如果一切順利,此時你應該可以看到四個容器服務都已經成功運行了。此時打開你的瀏覽器,輸入你服務器的ip地址或域名指向地址,你就應該可以訪問你的網站拉。
?第六步:遇到的問題排錯總結
1、Nginx容器排錯
Nginx報錯nginx: [emerg] "user" directive is not allowed here in /etc/nginx/conf.d/nginx.conf:1。。路徑有問題,我開始把nginx的配置文件copy到這里的路徑下了。應該放在/etc/nginx路徑下面。
nginx排錯最重要的是查看Nginx的錯誤日志,還有重點檢查端口,和uwsgi配套檢查,基本就不會有問題。
2、Web容器排錯
?(1)、上面問題為start.sh格式配置不對,在最前面加上 #!/bin/bash 即可。。另外一個常發生的錯誤是 docker-compose生成的web容器執行腳本命令后立刻退出(exited with code 0),在start.sh中加入tail -f /dev/null后容器服務可持續運行。
(2)、在運行start.sh遷移數據庫時有報警導致容器退出。
django_web_1 | user.User: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'. django_web_1 | HINT: Configure the DEFAULT_AUTO_FIELD setting or the UserConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.在玩新發布的 Django 3.2 時,我注意到一個警告,我以前在從 Django 3.1 遷移的網站上沒有看到警告(警告)。models.W042
該警告在 Django 3.2 中引入了一個新功能,該功能允許更改 Django 自動添加的原數默認字段,如果您沒有明確定義主字段。官方這樣說的。
?我的django版本是3.2.8,所以需要在settings.py配置文件中加上這句DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'。
(3)、構建數據庫時有個端口占用錯誤Error starting userland proxy: listen tcp4 0.0.0.0:5432: bind: address already in use。直接在root用戶運行netstat -tanlp ,然后找到端口5432的PID。 kill PID即可。
(4)、在requirements.txt中刪掉psycopg2包,只需要安裝psycopg2-binary且可以不用指定版本直接安裝最新版本。
The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead.?三、最后小結
?1、說一說ports和expose的區別。
- ports是將端口暴露給宿主機,而expose是將端口暴露給和本容器通信的容器,這里是通過?networks通信。
- 用法區別,語法格式如下。
2、容器數據卷volumes。
- 作用就是實現容器和容器之間數據共享,容器和宿主機之間數據備份防止數據丟失
- 匿名掛載和具名掛載:就是在指定數據卷的時候,不指定容器路徑對應的主機路徑,這樣對應映射的主機路徑就是默認的路徑/var/lib/docker/volumes/中自動生成一個隨機命名的文件夾(默認以id命名)。例如本例中docker-compose.yml中定義的redis_vol和postgres_vol,啟動成功后可在宿主機看到掛載的路徑/var/lib/docker/volumes?下面。這里命名為redis_vol叫具名掛載。不命名docker會默認以id命名叫匿名掛載。
- 指定路徑掛載:主容器文件所在路徑:容器內路徑。nginx的幾個掛載都是指定路徑掛載。
- 注意:不能通信的兩個容器之間不能共享數據
? ?待續
總結
以上是生活随笔為你收集整理的docker-compose+postsql多容器部署django-vue项目的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [react] 描述下在react中无状
- 下一篇: Atom常用功能插件