本文概述
- 基于Linux CentOS 7系統(tǒng)(虛擬機(jī)),使用Docker,多容器部署Django+Vue項(xiàng)目
- 整體部署用到了:Django+Vue+nginx+mysql+uwsgi
- 先每一個(gè)容器單獨(dú)部署,最后用Docker compose 語(yǔ)法整合,統(tǒng)一部署
Docker安裝
參考文章:https://blog.csdn.net/qq_45445505/article/details/135563784
- 章標(biāo)題:Docker介紹
- 節(jié)標(biāo)題:Docker安裝
總結(jié)梳理【寫在開(kāi)頭】
總結(jié)梳理放在前邊,方便整體理解
各容器間通信情況
【鏡像數(shù)量】:最終項(xiàng)目部署,用到了3個(gè)鏡像,部署運(yùn)行了3個(gè)容器
容器 | 用途 |
---|---|
nginx-icwp容器 | 運(yùn)行nginx程序,負(fù)責(zé)部署前端Vue資源、跟uwsgi聯(lián)動(dòng)完成請(qǐng)求轉(zhuǎn)發(fā) |
django-icwp容器 | 負(fù)責(zé)部署后端Django項(xiàng)目、配置uwsgi來(lái)和nginx呼應(yīng) |
mysql-icwp容器 | 運(yùn)行mysql數(shù)據(jù)庫(kù),負(fù)責(zé)項(xiàng)目數(shù)據(jù)存儲(chǔ) |
【端口綁定】
端口 | 容器歸屬 | 用途 |
---|---|---|
80 | nginx-icwp | 訪問(wèn)nginx默認(rèn)頁(yè)【演示用,與整體部署無(wú)關(guān)】 |
8081 | nginx-icwp | 訪問(wèn)前端Vue工程資源 |
9000 | nginx-icwp | 監(jiān)聽(tīng)Vue工程發(fā)來(lái)的ajax請(qǐng)求(動(dòng)態(tài)請(qǐng)求),并將請(qǐng)求轉(zhuǎn)發(fā)給uwsgi,由uwsgi移交后端django處理 |
8080 | django-icwp | uwsgi方式啟動(dòng)django項(xiàng)目時(shí)開(kāi)放的端口,可以直接用于訪問(wèn)后端【演示用,與整體部署無(wú)關(guān)】 |
3306 | mysql-icwp | 存儲(chǔ)項(xiàng)目數(shù)據(jù) |
【docker網(wǎng)絡(luò)】:網(wǎng)絡(luò)名:net-icwp
-
將3個(gè)容器實(shí)例都加入到同一個(gè)網(wǎng)絡(luò)下,這樣就可以增加通過(guò)容器別名+端口的形式,來(lái)訪問(wèn)不同的容器實(shí)例
-
這樣做的用意是:
- 不使用網(wǎng)絡(luò)的話,只能用容器實(shí)例的ip+端口來(lái)訪問(wèn)
- 但是容器的ip地址容易變化,隨著容器的部署、銷毀、再部署,ip就會(huì)變化,想要django項(xiàng)目再能訪問(wèn)mysql數(shù)據(jù)庫(kù),就需要更改settings.py配置
- 但是用網(wǎng)絡(luò)的話,ip地址無(wú)論如何變化,都與容器名綁定,不需要反復(fù)修改配置
【項(xiàng)目運(yùn)行流程】
-
本機(jī)電腦瀏覽器輸入:
http://192.168.93.128:8081
,進(jìn)入Vue項(xiàng)目的默認(rèn)頁(yè)(等同于:http://192.168.93.128:8081/index.html
) -
默認(rèn)頁(yè)面需要登錄,假如已經(jīng)輸入了賬號(hào)密碼,點(diǎn)擊登錄發(fā)送ajax請(qǐng)求:
http://192.168.93.128:9000/user_login_icwp/
-
(動(dòng)態(tài))請(qǐng)求通過(guò)9000端口,被nginx監(jiān)聽(tīng),由于配置了uwsgi,將請(qǐng)求轉(zhuǎn)發(fā)給uwsgi:通過(guò)9999端口,用socket通信的方式完成請(qǐng)求轉(zhuǎn)發(fā)
-
uwsgi將請(qǐng)求轉(zhuǎn)發(fā)給django處理,django響應(yīng)后將結(jié)果再返回給本機(jī)電腦瀏覽器
【容器部署測(cè)試】
- 本機(jī)電腦瀏覽器訪問(wèn):
http://192.168.93.128:8081
,來(lái)判斷前端Vue項(xiàng)目是否部署成功 - postman訪問(wèn)請(qǐng)求:
http://192.168.93.128:8080
,來(lái)判斷后端是否已經(jīng)部署并啟動(dòng) - postman訪問(wèn)請(qǐng)求:
http://192.168.93.128:9000
,來(lái)判斷nginx與uwsgi的通信是否配置成功- 效果等價(jià)于:瀏覽器訪問(wèn)Vue默認(rèn)頁(yè)面,輸入賬號(hào)密碼,點(diǎn)擊登錄,完成響應(yīng)并實(shí)現(xiàn)頁(yè)面跳轉(zhuǎn)
- navicat連接:
192.168.93.128:3306 -- root -- 密碼
,來(lái)判斷MySQL數(shù)據(jù)庫(kù)是否已經(jīng)部署并啟動(dòng)
【容器間依賴】:mysql-icwp -> django-icwp -> nginx-icwp
- mysql-icwp容器僅存儲(chǔ)項(xiàng)目數(shù)據(jù),無(wú)依賴,第1個(gè)部署
- django-icwp容器部署django項(xiàng)目,依賴mysql數(shù)據(jù)庫(kù)存儲(chǔ)數(shù)據(jù),第2個(gè)部署
- nginx-icwp容器部署Vue項(xiàng)目,邏輯交互依賴后端django接口,第3個(gè)部署
總結(jié)
寫項(xiàng)目部署步驟的時(shí)候,總有步驟”想當(dāng)然“而沒(méi)有展示出來(lái)。本文已盡可能展示所有的修改動(dòng)作,希望文章對(duì)你有所幫助。
Docker項(xiàng)目部署:一個(gè)一個(gè)構(gòu)建、運(yùn)行
部署mysql-icwp容器
目錄結(jié)構(gòu)【內(nèi)容解釋】
[root@localhost mysql_env]# tree -L 2
./
├── conf
│ └── my.conf # mysql的配置文件
├── data # 掛載mysql容器內(nèi)的數(shù)據(jù)
│ └── xxxxxxx
├── init # 放置初始化腳本,在創(chuàng)建容器后,會(huì)執(zhí)行文件夾里面的腳本,完成數(shù)據(jù)初始化
# 若是項(xiàng)目沒(méi)有需要初始化的數(shù)據(jù),該文件夾下不用放置任何內(nèi)容
│ └── icwp_full_data.sql
├── log # 掛載mysql容器內(nèi)的日志
各文件內(nèi)容【內(nèi)容解釋】
my.conf
網(wǎng)上隨便復(fù)制的
###### [client]配置模塊 ######
[client]
default-character-set=utf8mb4
socket=/var/lib/mysql/mysql.sock
###### [mysql]配置模塊 ######
[mysql]
# 設(shè)置MySQL客戶端默認(rèn)字符集
default-character-set=utf8mb4
socket=/var/lib/mysql/mysql.sock
###### [mysqld]配置模塊 ######
[mysqld]
port=3306
user=mysql
# 設(shè)置sql模式 sql_mode模式引起的分組查詢出現(xiàn)*this is incompatible with sql_mode=only_full_group_by,這里最好剔除ONLY_FULL_GROUP_BY
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
server-id = 1
# MySQL8 的密碼認(rèn)證插件 如果不設(shè)置低版本navicat無(wú)法連接
default_authentication_plugin=mysql_native_password
# 禁用符號(hào)鏈接以防止各種安全風(fēng)險(xiǎn)
symbolic-links=0
# 允許最大連接數(shù)
max_connections=1000
# 服務(wù)端使用的字符集默認(rèn)為8比特編碼的latin1字符集
character-set-server=utf8mb4
# 創(chuàng)建新表時(shí)將使用的默認(rèn)存儲(chǔ)引擎
default-storage-engine=INNODB
# 表名存儲(chǔ)在磁盤是小寫的,但是比較的時(shí)候是不區(qū)分大小寫
lower_case_table_names=0
max_allowed_packet=16M
# 設(shè)置時(shí)區(qū)
default-time_zone='+8:00'
icwp_full_data.sql:通過(guò)mysqldump工具,導(dǎo)出的windows平臺(tái)上的項(xiàng)目數(shù)據(jù),包含:建庫(kù)命令-建表命令-數(shù)據(jù)插入命令
若是你的項(xiàng)目有數(shù)據(jù)需要初始化,獲取該sql文件的方法如下:
- 在存有數(shù)據(jù)的平臺(tái)上以管理員身份打開(kāi)cmd命令(我的是win平臺(tái)):
- 導(dǎo)出數(shù)據(jù):
C:\Users\HMTeen>mysqldump -u root -p --host=127.0.0.1 --port=3306 --databases django_icwp_v3 > C:\Users\HMTeen\Desktop\icwp-mysql-data\mysqldump\icwp_full_data-1.sql
Enter password: ******
該操作將django_icwp_v3數(shù)據(jù)庫(kù)的所有數(shù)據(jù)導(dǎo)出到sql文件中:包含建庫(kù)命令-建表命令-數(shù)據(jù)插入命令…
- 將保存的數(shù)據(jù),放到上述init文件夾下面,名字不重要,后綴是sql就行
容器運(yùn)行命令【執(zhí)行】
確保上述提到的目錄、文件都創(chuàng)建了,假設(shè)你將這些內(nèi)容放到了:/xxx/www/mysql_env/路徑下
- 路徑切換
cd /xxx/www/mysql_env/
- 啟動(dòng)容器
docker run \
-d \
--name mysql-icwp-alone \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123456 \
-v ./data:/var/lib/mysql \
-v ./conf:/etc/mysql/conf.d \
-v ./init:/docker-entrypoint-initdb.d \
-v ./log:/var/log/mysql \
--network icwp-alone \
mysql:5.7
參數(shù) | 解釋 |
---|---|
-d |
后臺(tái)運(yùn)行 |
--name mysql-icwp-alone |
設(shè)置容器名字 |
-p 3306:3306 |
端口映射 |
-e TZ=Asia/Shanghai |
設(shè)置mysql時(shí)區(qū) |
-e MYSQL_ROOT_PASSWORD=123456 |
設(shè)置mysql密碼 |
-v ./data:/var/lib/mysql |
掛載mysql數(shù)據(jù) |
-v ./conf:/etc/mysql/conf.d |
掛載配置文件 |
-v ./init:/docker-entrypoint-initdb.d |
掛載初始化.sql文件 |
-v ./log:/var/log/mysql |
掛載log文件 |
--network icwp-alone |
將容器加入網(wǎng)絡(luò)(方便后續(xù)用容器名字代替ip來(lái)訪問(wèn)mysql) |
mysql:5.7 | 容器所基于的鏡像名字 |
啟動(dòng)命令里面涉及的目錄都是相對(duì)路徑寫法,只要執(zhí)行命令前路徑cd過(guò)來(lái),該有的文件夾都有,不會(huì)執(zhí)行錯(cuò)誤
測(cè)試是否部署成功
navicat工具測(cè)試連接mysql:成功!
直接訪問(wèn)成功了,mysql鏡像應(yīng)該是默認(rèn)給了root遠(yuǎn)程連接的權(quán)限
若無(wú)法成功訪問(wèn),原因無(wú)外乎:
- 防火墻沒(méi)有開(kāi)放3306端口
- mysql沒(méi)有賦予root用戶遠(yuǎn)程連接的權(quán)限
- my.conf配置文件要這樣設(shè)置:
bind-address=0.0.0.0
部署django-icwp容器
目錄結(jié)構(gòu)
[root@localhost python_env]# tree -L 3
.
├── 1_ssh_centos # 創(chuàng)建sshd鏡像
│ ├── dockerfile
│ └── run.sh
├── 2_python3_centos # 創(chuàng)建python3鏡像
│ └── dockerfile
├── 3_django-fixed_centos # 創(chuàng)建django-fixed鏡像
│ ├── django-fixed_centos.tar.gz # django-fixed鏡像的壓縮包,創(chuàng)建后打包出來(lái)的
└── 4_icwp_centos # 創(chuàng)建django-icwp鏡像
├── data_mount # 掛載項(xiàng)目產(chǎn)生的日志
├── Django_ICWP_v3 # 項(xiàng)目
│ ├── Django_ICWP_v3
│ ├── icwp_basic_data
│ ├── icwp_process_data
│ ├── manage.py
│ ├── requirements.txt # 項(xiàng)目依賴
│ ├── start.sh # 項(xiàng)目啟動(dòng)腳本
│ ├── templates
│ └── uwsgi.ini # uwsgi的配置文件
├── dockerfile
├── mysqlclient-2.2.1-cp38-cp38-linux_x86_64.whl # mysqlclient安裝包
關(guān)于django-icwp容器的鏡像獲取,創(chuàng)建了3個(gè)前置鏡像:
[root@localhost python_env]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
django-icwp alone cb12104296c8 25 hours ago 2.75GB
django-fixed centos d001e67470d8 27 hours ago 2.49GB
python3 centos 468cfd407ce1 27 hours ago 1.9GB
sshd centos 3e420fd22699 27 hours ago 644MB
其中各個(gè)鏡像的作用:
鏡像 | 作用 |
---|---|
sshd | 提供具有ssh遠(yuǎn)程連接功能的centos鏡像(因?yàn)楣俜教峁┑腸entos 7鏡像不具備遠(yuǎn)程連接功能) |
python3 | 在sshd鏡像的基礎(chǔ)上,提供python3.8環(huán)境 |
django-fixed | 在python3鏡像的基礎(chǔ)上,提供django4.1環(huán)境,并修復(fù)無(wú)法連接mysql 8以下版本的問(wèn)題 |
主要是體驗(yàn)以下從0創(chuàng)建的過(guò)程,也有一些特殊原因,文中會(huì)講。
1_ssh_centos
檢查默認(rèn)centos鏡像是否具備遠(yuǎn)程連接功能【內(nèi)容解釋】
1、下載centos 7鏡像
[root@localhost ssh_centos]# docker pull centos:7
7: Pulling from library/centos
2d473b07cdd5: Pull complete
Digest: sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987
Status: Downloaded newer image for centos:7
docker.io/library/centos:7
2、以交互方式創(chuàng)建centos 7鏡像的容器實(shí)例
[root@localhost ssh_centos]# docker run -it -d centos:7 /bin/bash
a11d32ed7075756449e27c5b9bf3b064ce2347c7a97a9ec5291d11e9d00ca137
3、進(jìn)入容器里面,并查看是否有sshd服務(wù)
[root@localhost ssh_centos]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a11d32ed7075 centos:7 "/bin/bash" 6 seconds ago Up 6 seconds vibrant_ritchie
[root@localhost ssh_centos]# docker exec -it a11d32ed7075 /bin/bash
[root@a11d32ed7075 /]# sshd
bash: sshd: command not found
- 發(fā)現(xiàn)沒(méi)有,那就后續(xù)創(chuàng)建一個(gè)帶有ssh的centos容器
4、刪除上述啟動(dòng)的實(shí)例
[root@a11d32ed7075 /]# exit
exit
[root@localhost ssh_centos]# docker rm -f a11d32ed7075
a11d32ed7075
[root@localhost ssh_centos]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost ssh_centos]#
各文件內(nèi)容【內(nèi)容解釋】
dockerfile
# 設(shè)置繼承鏡像
FROM centos:7
# 開(kāi)始運(yùn)行命令
RUN yum install -y openssh-server
RUN yum install -y passwd
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_ecdsa_key
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_ed25519_key
RUN echo "123456" | passwd --stdin root # 系統(tǒng)密碼,可自行更改
ADD run.sh /run.sh
EXPOSE 22
CMD ["/run.sh"]
run.sh
#! /bin/bash
# 以非后臺(tái)守護(hù)的方式運(yùn)行sshd
/usr/sbin/sshd -D
構(gòu)建sshd鏡像【執(zhí)行】
確保上述提到的目錄、文件都創(chuàng)建了,假設(shè)你將這些內(nèi)容放到了:/xxx/www/python_env/1_ssh_centos/路徑下
- 路徑切換
cd /xxx/www/python_env/1_ssh_centos/
- 執(zhí)行容器構(gòu)建命令
docker build -t sshd:centos .
2_python3_centos
各文件內(nèi)容【內(nèi)容解釋】
dockerfile
# 指定操作的鏡像
FROM sshd:centos
# 創(chuàng)建文件夾
RUN mkdir -p /opt/install
# 安裝軟件
# 安裝centos的yum源
RUN yum install epel-release -y
RUN yum -y install wget
# 安裝python 3.6
RUN yum install -y libffi-devel zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make
# 存放安裝包的路徑
WORKDIR /opt/install
RUN wget https://registry.npmmirror.com/-/binary/python/3.8.6/Python-3.8.6.tgz
# 解壓
RUN tar -zxvf Python-3.8.6.tgz
WORKDIR Python-3.8.6
RUN ./configure --prefix=/usr/local/python38
RUN make&&make install
# 配置環(huán)境變量
RUN ln -s /usr/local/python38/bin/python3 /usr/bin/python3.8
RUN ln -s /usr/local/python38/bin/pip3 /usr/bin/pip3.8
注意:通過(guò)配置環(huán)境變量,該鏡像里面訪問(wèn)python的命令變成了python3.8
,訪問(wèn)pip的命令變成了pip3.8
構(gòu)建python3鏡像【執(zhí)行】
確保上述提到的目錄、文件都創(chuàng)建了,假設(shè)你將這些內(nèi)容放到了:/xxx/www/python_env/2_python3_centos/路徑下
- 路徑切換
cd /xxx/www/python_env/2_python3_centos/
- 執(zhí)行容器構(gòu)建命令
docker build -t python3:centos .
3_django-fixed_centos
解釋為啥要有該鏡像【內(nèi)容解釋】
我之前在python3環(huán)境下,下載所有我項(xiàng)目需要的依賴包(其中django版本為4.1),運(yùn)行我的Django項(xiàng)目,出現(xiàn)了如下錯(cuò)誤:
[root@272957a62a37 Django_ICWP_v3]# python3.8 manage.py runserver 0.0.0.0:8000
Performing system checks...
System check identified no issues (0 silenced).
Exception in thread django-main-thread:
Traceback (most recent call last):
File "/usr/local/python38/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/usr/local/python38/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/python38/lib/python3.8/site-packages/django/utils/autoreload.py", line 64, in wrapper
fn(*args, **kwargs)
File "/usr/local/python38/lib/python3.8/site-packages/django/core/management/commands/runserver.py", line 136, in inner_run
self.check_migrations()
File "/usr/local/python38/lib/python3.8/site-packages/django/core/management/base.py", line 574, in check_migrations
executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
File "/usr/local/python38/lib/python3.8/site-packages/django/db/migrations/executor.py", line 18, in __init__
self.loader = MigrationLoader(self.connection)
File "/usr/local/python38/lib/python3.8/site-packages/django/db/migrations/loader.py", line 58, in __init__
self.build_graph()
File "/usr/local/python38/lib/python3.8/site-packages/django/db/migrations/loader.py", line 235, in build_graph
self.applied_migrations = recorder.applied_migrations()
File "/usr/local/python38/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 81, in applied_migrations
if self.has_table():
File "/usr/local/python38/lib/python3.8/site-packages/django/db/migrations/recorder.py", line 57, in has_table
with self.connection.cursor() as cursor:
File "/usr/local/python38/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/usr/local/python38/lib/python3.8/site-packages/django/db/backends/base/base.py", line 330, in cursor
return self._cursor()
File "/usr/local/python38/lib/python3.8/site-packages/django/db/backends/base/base.py", line 306, in _cursor
self.ensure_connection()
File "/usr/local/python38/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/usr/local/python38/lib/python3.8/site-packages/django/db/backends/base/base.py", line 289, in ensure_connection
self.connect()
File "/usr/local/python38/lib/python3.8/site-packages/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/usr/local/python38/lib/python3.8/site-packages/django/db/backends/base/base.py", line 272, in connect
self.init_connection_state()
File "/usr/local/python38/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 257, in init_connection_state
super().init_connection_state()
File "/usr/local/python38/lib/python3.8/site-packages/django/db/backends/base/base.py", line 239, in init_connection_state
self.check_database_version_supported()
File "/usr/local/python38/lib/python3.8/site-packages/django/db/backends/base/base.py", line 214, in check_database_version_supported
raise NotSupportedError(
django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.44).
這個(gè)錯(cuò)誤意思是說(shuō)django4以上的web項(xiàng)目需要8及以上的mysql版本,但我的是5.7.44。
這個(gè)錯(cuò)誤有兩個(gè)解決方法:
- 方法1:mysql版本換成8或者最新的,但是8及以上要收費(fèi)【不推薦】
- 方法2:這個(gè)錯(cuò)誤就是Django的版本提示,可以通過(guò)注釋掉django庫(kù)中的源碼來(lái)解決該問(wèn)題【推薦】
網(wǎng)上查閱有關(guān)資料,說(shuō)這個(gè)錯(cuò)誤,不一定有,win平臺(tái)下,用pycharm運(yùn)行項(xiàng)目,有時(shí)候沒(méi)有這個(gè)問(wèn)題
因此,這個(gè)鏡像制作的目的就是單純的提供:在Linux平臺(tái)下的python3 django環(huán)境,這個(gè)環(huán)境“僅”有django包,而且解決了mysql版本提示問(wèn)題
所以,在后續(xù)安裝項(xiàng)目需要依賴的時(shí)候,requirements.txt文件中不要再出現(xiàn)django的安裝,不然就替換了,等于白修改?。。?/strong>
各文件內(nèi)容【內(nèi)容解釋】
里面的壓縮包,是基于python3鏡像的容器,在下載django4.1版本并修改mysql版本提示問(wèn)題后,導(dǎo)出的鏡像文件
構(gòu)建django-fixed鏡像【執(zhí)行】
創(chuàng)建python3:centos鏡像的容器實(shí)例
[root@localhost ~]# docker run -it python3:centos /bin/bash
不加-d
參數(shù),不后臺(tái)運(yùn)行,會(huì)直接進(jìn)入容器
查看python版本
[root@c39b55bb0c4b Python-3.8.6]# python
Python 2.7.5 (default, Oct 14 2020, 14:45:30)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
可以看到Linux默認(rèn)的python版本是2.7.5
[root@c39b55bb0c4b Python-3.8.6]# python3.8
Python 3.8.6 (default, Jan 13 2024, 03:43:52)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
由于制作python3鏡像的時(shí)候,將運(yùn)行命令命名為python3.8,安裝庫(kù)命名命名為pip3.8,所以運(yùn)行python3.8可以看到正確的python版本
安裝django依賴
[root@c39b55bb0c4b Python-3.8.6]# pip3.8 install django==4.1 -i https://mirrors.aliyun.com/pypi/simple
......安裝過(guò)程......
尋找Django版本檢查代碼所在的文件:
-
方法1:若是一路按照本文鏡像制作安裝過(guò)來(lái),直接定位:
/usr/local/python38/lib/python3.8/site-packages/django/db/backends/base/
-
方法2:進(jìn)入容器內(nèi),命令行執(zhí)行python3.8,導(dǎo)入django,展示文件位置
- 基礎(chǔ)位置:
/usr/local/python38/lib/python3.8/site-packages/django/
- 補(bǔ)上后綴:
db/backends/base/
- 路徑全稱:
/usr/local/python38/lib/python3.8/site-packages/django/db/backends/base/
- 基礎(chǔ)位置:
[root@b11ef39bca1a Python-3.8.6]# python3.8
Python 3.8.6 (default, Jan 13 2024, 03:43:52)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django
<module 'django' from '/usr/local/python38/lib/python3.8/site-packages/django/__init__.py'>
安裝vim編輯器
yum -y install vim*
因?yàn)槟J(rèn)Linux鏡像不帶有vim編輯器,無(wú)法對(duì)容器內(nèi)的文件訪問(wèn)。Vim編輯器安裝處理后,可以卸載,可以不卸載,都行,建議留著,以免后續(xù)使用
打開(kāi)base.py
[root@c39b55bb0c4b base]# vim base.py
命令模式搜索:self.check_database_version_supported(),然后注釋代碼,保存退出
退出容器,基于該容器打包新的鏡像
[root@b11ef39bca1a Python-3.8.6]# cd /usr/local/python38/lib/python3.8/site-packages/django/db/backends/base/
[root@b11ef39bca1a base]# vim base.py
[root@b11ef39bca1a base]# exit
exit
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c39b55bb0c4b python3:centos "/bin/bash" 7 minutes ago Exited (0) 4 seconds ago charming_aryabhata
[root@localhost ~]# docker commit -a HMTeen -m "修復(fù)Django提示mysql版本過(guò)低的問(wèn)題" c39b55bb0c4b django-fixed:centos
sha256:c17f1aee5b5e9b996099e94810b3d3c1acb09d7ffc3a8c8015d3e3e3a703acf6
檢查鏡像,有該鏡像,說(shuō)明創(chuàng)建成功
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
django-fixed centos c17f1aee5b5e 22 minutes ago 2.49GB
python3 centos 87ae7d9e7f21 14 hours ago 1.9GB
sshd centos 018a4d0b973e 14 hours ago 644MB
centos 7 eeb6ee3f44bd 2 years ago 204MB
可以看到,安裝了vim編輯器,容器變大了0.32G
以新的鏡像:django-fixed,創(chuàng)建容器示例,按照上述修改base.py的步驟,查看里面的代碼是否是已經(jīng)注釋掉的
經(jīng)檢查,base.py的版本檢查代碼確實(shí)已經(jīng)注釋掉了,修改成功?。。?/p>
將django-fixed:centos這個(gè)鏡像導(dǎo)出,后續(xù)其他地方用,就不必要再重新創(chuàng)建了
# 將鏡像導(dǎo)出
docker save -o django-fixed_centos.tar django-fixed:centos
# 將導(dǎo)出的鏡像壓縮
tar -zcvf django-fixed_centos.tar.gz django-fixed_centos.tar
4_icwp_centos
各文件內(nèi)容【內(nèi)容解釋】
requirements.txt
xlwt~=1.3.0
Django~=4.1
xlrd~=2.0.1
xlutils~=2.0.0
loguru~=0.7.0
pandas~=2.0.1
pdfplumber~=0.9.0
numpy~=1.24.3
djangorestframework~=3.14.0
requests~=2.31.0
openpyxl~=3.1.2
python-dateutil~=2.8.2
# 以下是手動(dòng)添加的內(nèi)容
django-cors-headers~=4.3.1
djangorestframework-simplejwt~=5.3.1
pyjwt~=2.8.0
django-extensions~=3.2.3
pymysql~=1.1.0
memory_profiler~=0.61.0
psutil~=5.9.7
django_pandas~=0.6.6
urllib3~=1.26.15 # 這個(gè)版本高了還不行
mysqlclient~=2.2.1
uWSGI~=2.0.23
start.sh
python3.8 manage.py collectstatic --noinput;
python3.8 manage.py makemigrations;
python3.8 manage.py migrate;
uwsgi --http :8000 --ini uwsgi.ini;
uwsgi.ini
[uwsgi]
socket= :9999
chdir=/icwp/code/Django_ICWP_v3/
static-map=/static/=/icwp/code/Django_ICWP_v3/static
module=Django_ICWP_v3.wsgi
uid=root
gid=root
master=true
pidfile=uwsgi.pid
processes=8
threads=2
vacuum=true
daemonize=/icwp/Log/icwp-uwsgi.log
thunder-lock=true
enable-threads=true
dockerfile
# 指定操作的鏡像
FROM django-fixed:centos
# 指定語(yǔ)言,防止中文日志亂碼
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
# 創(chuàng)建文件夾
# 項(xiàng)目存放路徑
RUN mkdir -p /icwp/code/Django_ICWP_v3
# 存放mysqlclient的安裝包
RUN mkdir -p /icwp/code/mysqlclient
# 拷貝Django項(xiàng)目到指定地址
# 注意:只拷貝內(nèi)容,不拷貝Django_ICWP_v3這個(gè)文件夾本身
COPY Django_ICWP_v3 /icwp/code/Django_ICWP_v3
# 傳入mysqlclient的whl包,這玩意命令行安裝簡(jiǎn)直折磨
COPY mysqlclient-2.2.1-cp38-cp38-linux_x86_64.whl /icwp/code/mysqlclient
# 更新pip:注意這里的python3.8,以及后續(xù)的pip3.8
# 這樣寫是因?yàn)閯?chuàng)建這個(gè)鏡像的時(shí)候python3:centos,通過(guò)軟連接加入系統(tǒng)變量的是python3.8
# 更新pip操作視情況給出,若安裝順利,則無(wú)需更新pip
# RUN python3.8 -m pip install --upgrade pip
WORKDIR /icwp/code/mysqlclient
RUN pip3.8 install mysqlclient-2.2.1-cp38-cp38-linux_x86_64.whl
#這句指令相當(dāng)與:cd django項(xiàng)目
WORKDIR /icwp/code/Django_ICWP_v3
# 這句話意思是排除掉requirements.txt文件中關(guān)于Django和mysqlclient的安裝信息,并將剩余內(nèi)容存入到requirements_new.txt
# 雖然可以在txt文件中注釋掉Django和mysqlclient的,但是為了體現(xiàn)自動(dòng)化的思想,多了這樣一行命令
RUN grep -v '^ *#\|^Django\|^mysqlclient' requirements.txt | grep . > requirements_new.txt
# 安裝依賴包
RUN pip3.8 --default-timeout=100 install -r requirements_new.txt -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
# 配置uwsgi的系統(tǒng)變量
RUN ln -s /usr/local/python38/bin/uwsgi /usr/bin/uwsgi
EXPOSE 8000
mysqlclienta安裝包的獲取【執(zhí)行】
這玩意的安裝及其惡心,所以本文提供了這個(gè)第三方庫(kù)的whl安裝包
獲取教程:https://blog.csdn.net/qq_45445505/article/details/135680075
Django項(xiàng)目需要進(jìn)行的修改【執(zhí)行】
settings.py文件
# 設(shè)置靜態(tài)文件的存放地址,一般是:/xx路徑/項(xiàng)目根目錄/static文件夾
STATIC_ROOT = '/icwp/code/Django_ICWP_v3/static'
# 數(shù)據(jù)庫(kù)連接設(shè)置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
# 數(shù)據(jù)庫(kù)的名字
'NAME': 'django_icwp_v3',
# 服務(wù)器數(shù)據(jù)庫(kù)地址:用容器名字代替寫入ip地址的方式
'HOST': 'mysql-icwp-alone',
# 端口
'PORT': '3306',
# 用戶名
'USER': 'root',
# 服務(wù)器密碼
"PASSWORD": '123456',
}
}
構(gòu)建django-icwp鏡像【執(zhí)行】
確保上述提到的目錄、文件都創(chuàng)建了,假設(shè)你將這些內(nèi)容放到了:/xxx/www/python_env/4_icwp_centos/路徑下
- 路徑切換
cd /xxx/www/python_env/4_icwp_centos/
- 執(zhí)行容器構(gòu)建命令
docker build -t django-icwp:alone .
容器運(yùn)行【執(zhí)行】
- 在上述執(zhí)行構(gòu)建命令的路徑下,執(zhí)行容器啟動(dòng)命令
docker run -it -d \
--name django-icwp-alone \
-p 8000:8000 \
-v ./data_mount/Log:/icwp/Log \
--network icwp-alone \
django-icwp:alone
- 進(jìn)入容器,啟動(dòng)django項(xiàng)目
docker exec -it django-icwp-alone /bin/bash start.sh
測(cè)試是否部署成功
在端口已經(jīng)成功開(kāi)放的基礎(chǔ)上,本機(jī)電腦瀏覽器上訪問(wèn):http://192.168.93.128:8000/
,看看是否有項(xiàng)目給出的提示內(nèi)容:
# 我的項(xiàng)目給出的提示內(nèi)容:
{"states": 0, "message": "INFO", "warning": "", "data": "請(qǐng)先完成用戶登錄,再訪問(wèn)其他頁(yè)面"}
部署nginx-icwp容器
目錄結(jié)構(gòu)【內(nèi)容解釋】
[root@localhost nginx_env]# tree -L 3 .
.
├── conf # 存放配置文件
│ ├── conf.d
│ │ ├── default.conf # 定義了80端口的默認(rèn)配置文件
│ │ ├── icwp-django.conf # 自定義后端django有關(guān)的配置文件
│ │ └── icwp-vue.conf # 自定義前端Vue有關(guān)的配置文件
│ └── nginx.conf # 主配置文件,主要用于引用conf.d文件夾下的配置文件到主配置文件中
├── html
│ ├── 50x.html # nginx默認(rèn)50x.html頁(yè)面
│ ├── index.html # nginx默認(rèn)的歡迎頁(yè)面
│ ├── dist # Vue工程構(gòu)建打包后的靜態(tài)資源文件
│ │ ├── favicon.ico
│ │ ├── index.html
│ │ └── static
├── log # 用于掛載ngingx的日志
各文件內(nèi)容【內(nèi)容解釋】
default.conf & nginx.conf
從運(yùn)行的nginx容器中拷貝出來(lái)的,不做任何修改,按照上述目錄結(jié)構(gòu)放著就行
# 運(yùn)行nginx容器
docker run -it -d --name=test_nginx -p 80:80 nginx
# 拷貝文件到當(dāng)前路徑下
docker cp test_nginx:/etc/nginx/nginx.conf nginx.conf
docker cp test_nginx:/etc/nginx/conf.d/default.conf default.conf
理解這兩個(gè)配置文件及自定義配置文件的用途:https://blog.csdn.net/qq_45445505/article/details/135733522
icwp-django.conf
upstream django {
ip_hash;
server django-icwp-alone:9999;
}
server{
listen 9000;
access_log /var/log/nginx/icwp-django.access.log main;
charset utf-8;
location /{
include /etc/nginx/uwsgi_params;
uwsgi_connect_timeout 30;
uwsgi_pass django;
}
location /static/{
alias /icwp/code/Django_ICWP_v3/static;
}
}
icwp-vue.conf
server {
listen 8081;
server_name localhost;
access_log /var/log/nginx/icwp-vue.access.log main;
location / {
root /usr/share/nginx/html/dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
dist
-
打開(kāi)Vue工程
-
運(yùn)行命令:
npm run build
-
將生成的dist文件夾復(fù)制過(guò)來(lái)即可
Vue工程里面,所有ajax請(qǐng)求的基礎(chǔ)url:"http://12.168.93.128:9000/"
容器運(yùn)行
確保上述提到的目錄、文件都創(chuàng)建了,假設(shè)你將這些內(nèi)容放到了:/xxx/www/nginx_env/路徑下
- 路徑切換
cd /xxx/www/nginx_env/
- 執(zhí)行容器構(gòu)建命令
docker run -d \
-p 80:80 \
-p 8081:8081 \
-p 9000:9000 \
--name nginx-icwp-alone \
-v ./conf/nginx.conf:/etc/nginx/nginx.conf \
-v ./conf/conf.d:/etc/nginx/conf.d \
-v ./log:/var/log/nginx \
-v ./html:/usr/share/nginx/html \
--network icwp-alone \
nginx:latest
總結(jié)
至此,三個(gè)容器都已成功啟動(dòng),可以在客戶端用瀏覽器訪問(wèn)項(xiàng)目,并進(jìn)行操作,來(lái)驗(yàn)證是否能夠成功交互
Docker-Compose部署項(xiàng)目
通過(guò)docker compose語(yǔ)法,一鍵部署上述3個(gè)docker容器
項(xiàng)目結(jié)構(gòu)
├── data # 掛載容器數(shù)據(jù):綜合下來(lái),只有mysql數(shù)據(jù)需要保存
│ └── mysql
├── log # 掛載各容器產(chǎn)生的日志
│ ├── icwp
│ ├── mysql
│ └── nginx
└── project # docker-compose構(gòu)建的整個(gè)工程
├── docker-compose.yml # 總的配置文件
├── mysql_env # mysql有關(guān)的配置文件
│ ├── conf
│ │ └── my.conf
│ ├── dockerfile # mysql的dockerfile文件
│ ├── init
│ │ └── icwp_full_data.sql
├── nginx_env # nginx的配置文件
│ ├── conf
│ │ ├── conf.d
│ │ │ ├── default.conf
│ │ │ ├── icwp-django.conf
│ │ │ └── icwp-vue.conf
│ │ └── nginx.conf
│ ├── dockerfile # nginx的dockerfile文件
│ ├── html
│ │ ├── 50x.html
│ │ ├── dist
│ │ │ ├── favicon.ico
│ │ │ ├── index.html
│ │ │ └── static
│ │ ├── index.html
│ │ └── ReadMe.txt
└── python_env # python的配置文件
├── Django_ICWP_v3 # Django項(xiàng)目
│ ├── Django_ICWP_v3
│ ├── icwp_basic_data
│ ├── icwp_process_data
│ ├── manage.py
│ ├── requirements.txt
│ ├── start.sh
│ ├── templates
│ └── uwsgi.ini
├── dockerfile
├── mysqlclient-2.2.1-cp38-cp38-linux_x86_64.whl
項(xiàng)目運(yùn)行
啟動(dòng)docker-compose
docker compose up -d
關(guān)閉并刪除docker-compose
docker compose down
各文件內(nèi)容
docker-compose.yml
# /icwp_docker_compose/project/
version: '1'
services:
mysql:
build: ./mysql_env
image: mysql-5.7:compose
container_name: mysql-icwp-compose
environment:
- MYSQL_ROOT_PASSWORD=123456
- TZ=Asia/Shanghai
volumes:
- /mysql_env/conf:/etc/mysql/conf.d # 掛載配置文件
- ./mysql_env/init:/docker-entrypoint-initdb.d/ # 掛載初始化文件
- ../data/mysql:/var/lib/mysql # 掛載數(shù)據(jù)庫(kù)數(shù)據(jù)
- ../log/mysql:/var/log/mysql # 掛載日志
ports:
- "3306:3306"
restart: always
networks:
- net-icwp
django:
build: ./python_env
image: django-icwp:compose
container_name: django-icwp-compose
ports:
- "8000:8000"
volumes:
- ../log/icwp:/icwp/Log # 掛載項(xiàng)目生成的log文件
stdin_open: true
tty: true
restart: always
networks:
- net-icwp
depends_on:
- mysql
nginx:
build: ./nginx_env
image: nginx-icwp:compose
container_name: nginx-icwp-compose
ports:
- "80:80"
- "8081:8081"
- "9000:9000"
volumes:
- ./nginx_env/conf/nginx.conf:/etc/nginx/nginx.conf # 掛載默認(rèn)配置文件
- ./nginx_env/conf/conf.d:/etc/nginx/conf.d # 掛載自定義配置文件
- ./nginx_env/html:/usr/share/nginx/html # 掛載靜態(tài)文件
- ../log/nginx:/var/log/nginx # 掛載日志
restart: always
networks:
- net-icwp
depends_on:
- django
networks:
net-icwp:
name: net-icwp-compose
其他內(nèi)容
對(duì)比單獨(dú)部署時(shí)候的內(nèi)容,有的內(nèi)容有變化,有的內(nèi)容移動(dòng)到了其他地方。
這里記錄下有變化的部分
內(nèi)容 | 變化內(nèi)容 | 所屬容器 |
---|---|---|
data | 移動(dòng)到project同級(jí)目錄data/mysql下,統(tǒng)一管理 | mysql-icwp |
log | 移動(dòng)到project同級(jí)目錄下log/mysql下,統(tǒng)一管理 | mysql-icwp |
dockerfile | 新增的配置文件,主要是方便docker-compose配置的時(shí)候,自定義鏡像名字 | mysql-icwp |
data_mount | 移動(dòng)到project同級(jí)目錄log/icwp下,統(tǒng)一管理 | django-icwp |
settings.py | 關(guān)于數(shù)據(jù)庫(kù)連接的配置有變化,mysql的容器名變了 | django-icwp |
dockerfile | 加入了啟動(dòng)腳本的命令 | django-icwp |
start.sh | 加入了保持前端交互式操作的命令 | django-icwp |
log | 移動(dòng)到project同級(jí)目錄log/nginx下,統(tǒng)一管理 | nginx |
【mysql-icwp】dockerfile
FROM mysql:5.7
EXPOSE 3306
【django-icwp】settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
# 數(shù)據(jù)庫(kù)的名字
'NAME': 'django_icwp_v3',
# 服務(wù)器數(shù)據(jù)庫(kù)地址
'HOST': 'mysql-icwp-compose', # 這里改了,原先是:mysql-icwp-alone
# 端口
'PORT': '3306',
# 用戶名
'USER': 'root',
# 服務(wù)器密碼
"PASSWORD": '123456',
}
}
【django-icwp】dockerfile
FROM django-fixed:centos
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
RUN mkdir -p /icwp/code/Django_ICWP_v3
RUN mkdir -p /icwp/code/mysqlclient
COPY Django_ICWP_v3 /icwp/code/Django_ICWP_v3
COPY mysqlclient-2.2.1-cp38-cp38-linux_x86_64.whl /icwp/code/mysqlclient
WORKDIR /icwp/code/mysqlclient
RUN pip3.8 install mysqlclient-2.2.1-cp38-cp38-linux_x86_64.whl
WORKDIR /icwp/code/Django_ICWP_v3
RUN grep -v '^ *#\|^Django\|^mysqlclient' requirements.txt | grep . > requirements_new.txt
RUN pip3.8 --default-timeout=100 install -r requirements_new.txt -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
RUN ln -s /usr/local/python38/bin/uwsgi /usr/bin/uwsgi
# 以下是新增的內(nèi)容
# 解決啟動(dòng)腳本的換行問(wèn)題
RUN sed -i 's/\r//' start.sh
# 賦予腳本執(zhí)行權(quán)限
RUN chmod +x start.sh
EXPOSE 8000
ENTRYPOINT ["/bin/bash","start.sh"]
【django-icwp】start.sh
python3.8 manage.py collectstatic --noinput&&
python3.8 manage.py makemigrations&&
python3.8 manage.py migrate&&
uwsgi --http :8000 --ini uwsgi.ini&&
python3.8
新增最后一行,是為了讓容器執(zhí)行完start.sh腳本之后,有個(gè)交互式的界面,阻塞進(jìn)程,避免容器退出、停止
心得總結(jié)
docker-compose使用心得
- 要?jiǎng)h掉構(gòu)建的鏡像后再執(zhí)行啟動(dòng)程序,不然重新執(zhí)行啟動(dòng)命令后,用的還是已有的鏡像
nginx部署前端資源的理解
正確的通信流程圖是文章開(kāi)始展示的那個(gè),這個(gè)流程圖有一個(gè)錯(cuò)誤,就是關(guān)于9000端口,uwsgi轉(zhuǎn)發(fā)請(qǐng)求這一部分(紅線部分):
先前我在部署Vue項(xiàng)目的時(shí)候,項(xiàng)目里面所有的ajax請(qǐng)求,用的公共前綴是:http://nginx-icwp:9000/
。
當(dāng)時(shí)的理解是:本地瀏覽器通過(guò):http://192.168.93.128:8081/
訪問(wèn)到登錄頁(yè)面,然后點(diǎn)擊登錄按鈕,發(fā)送ajax請(qǐng)求到9000端口,這個(gè)發(fā)送的主體是nginx-icwp這個(gè)容器,但這是錯(cuò)誤的,所以當(dāng)時(shí)無(wú)論如何都調(diào)試不通順。
正確的理解是:本地瀏覽器通過(guò):http://192.168.93.128:8081/
訪問(wèn)到登錄頁(yè)面,獲取到靜態(tài)資源,展示到瀏覽器上,然后點(diǎn)擊登錄按鈕,發(fā)送ajax請(qǐng)求到9000端口,這個(gè)請(qǐng)求發(fā)送的主體是瀏覽器,是本地的瀏覽器,所以這個(gè)請(qǐng)求發(fā)起的ip應(yīng)該是虛擬機(jī)的地址:192.168.93.128,然后通過(guò)端口映射,發(fā)送到nginx-icwp的9000端口。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-838245.html
即項(xiàng)目里面所有的ajax請(qǐng)求,用的公共前綴應(yīng)該是:http://192.168.93.128:9000/
。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-838245.html
到了這里,關(guān)于2-Docker-應(yīng)用-多容器部署Django+Vue項(xiàng)目(nginx+uwsgi+mysql)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!