基于Docker的Django-Mysql-Apache應用容器化

基于Docker的Django-Mysql-Apache應用容器化

2017-05-25

Mysql的容器

Django容器化

Apache容器

<span id = "1">

Mysql的容器

</span>

Mysql有官方發布的鏡像,可以直接拉取,并按需求啟動一個容器。

參考:這里

啟動一個容器

docker run --name mysql-container -v /root/mysql_datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql/mysql-server:5.7

啟動一個5.7版本的Mysql容器,環境變量MYSQL_ROOT_PASSWORD表示superuser的密碼,掛載宿主機的目錄作為容器Mysql的數據存儲目錄。如果是第一次運行,Docker會發現本地沒有Mysql鏡像,會進行相應的依賴的拉取,隨機啟動容器。

docker_run_mysql
docker_run_mysql

docker ps -al

docker_ps_al
docker_ps_al

可以看出,mysql的容器依然暴露3306端口。

接入容器

docker exec -it mysql-container mysql -uroot -proot

access_mysql_docker
access_mysql_docker

成功接入mysql容器,創建成功。

查看Mysql的日志

容器的Mysql日志存儲在/var/log/mysqld.log下

掛載宿主機目錄作為Mysql的存儲路徑,并映射宿主機端口到容器外部端口

docker run --name mysql-container -p 3307:3306 -v /root/mysql_datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql/mysql-server:5.7

將/root/mysql_datadir目錄掛載進/var/lib/mysql作為數據庫存儲文件。映射宿主機3307端口到容器3306端口。容器啟動后,mysql_datadir目錄下會產生新文件

mysql_datadir
mysql_datadir

注意: 宿主機的目錄必須要是絕對路徑

當容器宕掉后,被清除后。重新啟動一個Mysql容器,并掛載 mysql_datadir 作為數據庫存儲路勁時,記得忽略MYSQL_ROOT_PASSWORD環境變量的設置。先前存在的數據庫文件不會有變化。

有時由于SElinux,讀寫目錄會有沖突,敲入以下命令

chcon -Rt svirt_sandbox_file_t /root/mysql_datadir

進入容器配置數據庫權限

docker exec -it mysql-container mysql -uroot -proot

grant all privileges on *.* to 'root'@'192.168.31.182' identified by 'root' with grant option;

從192.168.31.182可以訪問這個容器的mysql服務

mysql -h[hostIP] -P3307 -uroot -p

 access_mysql_from_romote
access_mysql_from_romote

<span id="2">

Django容器化

</span>

從DockerHub上拉取Django鏡像

docker pull library/Django:1.10.4-python3

需要等待一段時間

docker_pull
docker_pull

這個鏡像已經配置好了python3.4和django1.10的環境。現在我們還要構建可以連接mysql的環境。

用Dockerfile文件構建一個鏡像

新建一個Dockerfile文件,添加下面內容

Dockerfile_djanog
Dockerfile_djanog

build鏡像

docker build -t [倉庫和標簽名稱] [Dockerfile文件路徑]

docker_build_django
docker_build_django
docker_image_django
docker_image_django

從鏡像運行容器

docker run --name botmail --link mysql-container:db -v /root/docker_study/django_docker/botmail/:/var/www/ -p 8000:7000 -it 1015010127/botmail:v1 /bin/bash

啟動一個名為botmail的容器,并且掛載代碼文件到容器中,同時映射宿主機8000端口到容器的7000端口。連接MySQL的容器,并設置別名為db。

修改Django項目中的settings.py文件中的有關數據庫連接的配置

docker_django_connect
docker_django_connect

注意: 同時要為當前容器的ip配置數據庫權限,否則無法連接。

從鏡像中啟動django項目

docker exec -it botmail python manage.py runserver 0.0.0.0:7000
docker_run_django
docker_run_django

確保防火墻關閉后可以從外部訪問。

這樣構建的Django+mysql容器連接有一些問題,首先端口7000使用了硬編碼,而且數據庫連接使用‘db’硬編碼,應當考慮使用docker-compose

使用docker-compose搭建MySQL+django

安裝docker-compose,參考:官方安裝文檔

curl -L https://github.com/docker/compose/releases/download/$dockerComposeVersion/docker-compose-`uname -s\`-`uname -m` > /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

建立一個目錄botmail_docker,并新建一個docker-compose.yml文件,寫入以下內容。

  1 # docker-compose版本
  2 version: '3'
  3 # 服務
  4 services:
  5     # 數據庫服務
  6     db:
  7         # 拉取鏡像
  8         image: 1015010127/mysql-server:v2
  9         # 運行容器的名稱
 10         container_name: mysql-container
 11         # 環境變量文件
 12         env_file: ./db.env
 13         # 端口映射,外部可以從3308端口訪問
 14         ports:
 15             - "3308:3306"
 16         # 掛載目錄
 17         volumes:
 18             # 數據儲存目錄,請自行定義
 19             - /root/docker_study/botmail_docker/data:/var/lib/mysql
 20         # 設置工作目錄
 21         working_dir: /mysql_data_init
 22     # web服務
 23     web:
 24         image: 1015010127/botmail:v1
 25         container_name: botmail
 26         # 依賴db服務,先啟動db再啟動web
 27         depends_on:
 28             - db
 29         # 宕機即重啟
 30         restart: always
 31         # 暴露端口
 32         ports:
 33             - "8000:7000"
 34         volumes:
 35             - ./botmail:/var/www/botmail   # 代碼文件
 36         working_dir: /var/www/botmail
 37         # 啟動容器是運行的命令
 38         command: python manage.py runserver 0:7000
 39         # 連接數據庫
 40         links:
 41             - db

創建db.env文件用作設置db服務的環境變量。

  1 # 指定root的密碼
  2 MYSQL_ROOT_PASSWORD=root
  3 # 創建一個新的數據庫
  4 MYSQL_DATABASE=botmail_docker
  5 # 指定某個網段的ip可以訪問
  6 MYSQL_ROOT_HOST=172.%.%.%
  7 # 要掛載的數據存儲位置
  8 MYSQL_VOLUME_DATADIR=/root/docker_study/botmail_docker/data
  9 # 數據庫初始化數據
 10 MYSQL_INIT_DIR=/root/docker_study/botmail_docker/mysql_init/botmail_online.sql
 11 # 運行時執行的
 12 EXEC_SQL=use botmail_docker;source data_init.sql;

創建data文件夾用作db服務的數據存儲,通過以下命令啟動容器組合。

docker-compose up

若是data文件夾中為空,db服務會進行一些初始化

docker-compose_up
docker-compose_up

啟動成功后,通過docker-compose ps可以查看運行的容器,注意: 要在docker-compose.yml文件目錄下敲命令。

docker-compose_ps
docker-compose_ps

現在可以從宿主機的ip訪問botmail應用,但因為數據庫中沒有數據,需要初始化數據。

docker-compose exec db mysql -uroot -proot -e "use botmail_docker;source data_init.sql;"

data_init.sql文件已經存在在數據庫容器的工作目錄下。

docker_init_db_data
docker_init_db_data

現在可以進行登錄了。

<span id="3">

Apache容器

</span>

拉取centos鏡像,用來搭建apache服務

pull_centos
pull_centos

啟動一個容器,并用yum安裝httpd服務

run_centos
run_centos
yum_install_httpd
yum_install_httpd

啟動httpd服務報錯

apache_docker_start_error
apache_docker_start_error

這個問題可以參考后面的錯誤解決辦法

此時先不管這個問題

安裝django環境

安裝python3

請參考源碼包安裝python3以及pip

pip安裝django1.10以及pymysql

pip_install_django_pymysql
pip_install_django_pymysql

配置apache的python模塊

安裝mod_wsgi

wsgi全稱為web server gateway interface,是web應用與服務器的接口模塊,apache必須安裝mod_wsgi才能夠和python代碼進行交互,之前有個版本用的是mod_python,現已經淘汰了

下載源碼包

wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.5.15.tar.gz

解壓并編譯安裝

解壓并安裝,注意提前安裝gcc和httpd-devel,這是編譯所必須的依賴包,否則編譯報錯(apx:commmand not found)

yum install gcc httpd-devel -y

編譯安裝mod_wsgi,注意指定python3的環境

compile_mod_wsgi_python3
compile_mod_wsgi_python3

成功編譯安裝的結果

success_complie_mod_wsgi
success_complie_mod_wsgi

說明模塊已經安裝到這個目錄下了/usr/lib64/httpd/modules/mod_wsgi.so

在httpd的模塊目錄中可以找到

got_mod_wsgi_module
got_mod_wsgi_module

卸載依賴包,減小容器的體積

測試apache服務

剛剛遇到了apache服務無法啟動的問題,現在進行解決

退出容器,將當前容器打包成鏡像

docker commit -pm "新版apache_django配置" apache 1015010127/centos:apache_v4

最后一個選項是我的docker倉庫名,可以自行定義

用以下新命令運行

docker run --privileged -d --name apache -p 6003:80 1015010127/centos:apache_v4 /usr/sbin/init

new_run_apache_docker
new_run_apache_docker

進入容器,啟動apache服務

success_start_apache
success_start_apache

通過瀏覽器可以訪問

browe_apache_welcome
browe_apache_welcome

6003端口是宿主機的,映射到容器的80端口

修改httpd.conf文件

添加以下兩行

導入wsgi模塊

LoadModule wsgi_module modules/mod_wsgi.so

django項目路徑

WSGIPythonPath /var/www/botmail

python3的安裝路徑

WSGIPythonHome /usr/python3.5

配置虛擬主機

在/etc/httpd/conf.d/目錄下新建一個文件botmail.conf,添加以下內容

<VirtualHost *:80>
WSGIScriptAlias / /var/www/botmail/botmail/wsgi.py
#WSGIPythonPath /var/www/botmail
#WSGIPythonHome /usr/python3.5
Alias /media/ /var/www/botmail/media/
Alias /static/ /var/www/botmail/html/dist/static/

<Directory /var/www/botmail/media>
Require all granted
</Directory>

<Directory /var/www/botmail/html/dist/static/>
Require all granted
</Directory>

<Directory /var/www/botmail/botmail>
<Files wsgi.py>
Require all granted
</Files>
</Directory>

</VirtualHost>

注意: 不要在虛擬主機的配置文件中配置WSGIPythonPath和WSGIPythonHome,否則啟動apachectl服務時報錯

因為是第一次接觸apache服務器,這里的配置具體含義我不是特別清楚,有興趣應該查閱官方文檔。

重新啟動apache服務,沒錯誤的話就ok

apachectl restart

重新將這個容器打包一份鏡像

現在就剩最后一步了:掛載botmail的項目路徑

通過docker-compose.yml文件構建容器組合

創建一個docker-compose.yml文件,填入以下內容

# docker-compose版本
version: '3'
# 服務
services:
    # 數據庫服務
    db:
        # 拉取鏡像
        image: 1015010127/mysql-server:v2
        # 運行容器的名稱
        container_name: mysql-container
        # 環境變量文件
        env_file: ./db.env
        # 端口映射,外部可以從3308端口訪問
        ports:
            - "3308:3306"
        # 掛載目錄
        volumes:
            # 數據儲存目錄,請自行定義
            - /root/docker_study/botmail_docker/data:/var/lib/mysql
        # 設置工作目錄
        working_dir: /mysql_data_init
    # web服務
    web:
        image: 1015010127/centos:apache_v5
        container_name: botmail_apache
        # 依賴db服務,先啟動db再啟動web
        depends_on:
            - db
        # 宕機即重啟
        restart: always
        # 暴露端口
        ports:
            - "8000:7000"
            - "6001:80"
        volumes:
            - /root/docker_study/botmail_docker/botmail:/var/www/botmail
        working_dir: /var/www/botmail
        
        command: /usr/sbin/init

        privileged: true
        # 連接數據庫
        links:
            - db

在這個文件的目錄下運行以下命令

docker-compose up

docker-compose_run_apache_mysql
docker-compose_run_apache_mysql

在瀏覽器上訪問6001端口,即可看到你的django項目

web_docker_botmail
web_docker_botmail

可能會遇到的錯誤

apache配置錯誤

<span id=4>

1. 在centos7鏡像中安裝httpd服務,啟動報錯

</span>

centos_docker_httpd_error
centos_docker_httpd_error

打包當前容器,成鏡像,然后從新用以下命令運行

docker run --privileged -d --name apache -p 6003:80 1015010127/centos:apache_v4 /usr/sbin/init

new_run_apache_docker
new_run_apache_docker

進入容器,啟動apache服務

success_start_apache
success_start_apache

通過瀏覽器可以訪問

browe_apache_welcome
browe_apache_welcome

6003端口是宿主機的,映射到容器的80端口

之后進入容器內啟動apache可以成功

2. apache的python環境配置錯誤

因為python項目是用python3寫的,我們都知道python3和python2是不兼容的,如果apache的是python2環境,如下,啟動時通過查看/var/log/httpd/error_log日志可以查看apache啟動的配置信息

python_2.7.5_configure
python_2.7.5_configure

訪問web應用時,后端的python代碼報錯

python_run_2.7.5_error
python_run_2.7.5_error

python2的模塊和python3并不兼容

在httpd/conf/httpd.conf添加Python3的安裝目錄,來指定使用python3的環境

add_python3_home
add_python3_home

但是在運行的時候卻出現沒有site模塊的錯誤:ImportError: No module named site

python3_no_module_site
python3_no_module_site

現在查看wsgi是否配置正確,/etc/httpd/modules/mod_wsgi模塊的依賴

ldd mod_wsgi.so

mod_wsgi_python2
mod_wsgi_python2

依賴的python竟然是python2,因此考慮利用python3環境編譯mod_wsgi模塊

下載源碼包

wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.5.15.tar.gz

解壓并安裝,注意體檢安裝gcc和httpd-devel,這是編譯所必須的依賴包,否則編譯報錯

yum install gcc httpd-devel -y

編譯安裝mod_wsgi,注意指定python3的環境

compile_mod_wsgi_python3
compile_mod_wsgi_python3

發生錯誤:relocation R_X86_64_32S against `_Py_NotImplementedStruct' can not be used when making a shared object; recompile with -fPIC

/usr/python3.5/lib/libpython3.5m.a: error adding symbols: Bad value

collect2: error: ld returned 1 exit status

apxs:Error: Command failed with rc=65536

make: *** [src/server/mod_wsgi.la] Error 1

這個錯誤的解決辦法是要重新編譯python3的源碼,并加上--enable-shared選項

./configure --prefix=[python3的目錄] --enable-shared

可能重新編譯python后,運行python3的交互命令是,發生以下錯誤,依賴發生問題

python_lib_cannot_find
python_lib_cannot_find

通過復制python3目錄下lib/libpython3.5m.so.1.0到/lib64/libpython3.5m.so.1.0可以解決

此時,可以正常編譯mod_wsgi,且httpd/module/mod_wsgi.so依賴如下

mod_wsgi_python3
mod_wsgi_python3

注意: 重新編譯了python源碼,可能會造成擴展模塊的丟失,注意重新用pip安裝

python -m pip install [擴展模塊名稱]==[版本]

web界面顯示Not Found

Not Found

The requested URL / was not found on this server.

not_found_error
not_found_error

可能是django的項目路徑沒有配置對

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容