基于Docker的Django-Mysql-Apache應(yīng)用容器化

基于Docker的Django-Mysql-Apache應(yīng)用容器化

2017-05-25

Mysql的容器

Django容器化

Apache容器

<span id = "1">

Mysql的容器

</span>

Mysql有官方發(fā)布的鏡像,可以直接拉取,并按需求啟動(dòng)一個(gè)容器。

參考:這里

啟動(dòng)一個(gè)容器

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

啟動(dòng)一個(gè)5.7版本的Mysql容器,環(huán)境變量MYSQL_ROOT_PASSWORD表示superuser的密碼,掛載宿主機(jī)的目錄作為容器Mysql的數(shù)據(jù)存儲目錄。如果是第一次運(yùn)行,Docker會發(fā)現(xiàn)本地沒有Mysql鏡像,會進(jìn)行相應(yīng)的依賴的拉取,隨機(jī)啟動(dòng)容器。

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容器,創(chuàng)建成功。

查看Mysql的日志

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

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

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目錄掛載進(jìn)/var/lib/mysql作為數(shù)據(jù)庫存儲文件。映射宿主機(jī)3307端口到容器3306端口。容器啟動(dòng)后,mysql_datadir目錄下會產(chǎn)生新文件

mysql_datadir
mysql_datadir

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

當(dāng)容器宕掉后,被清除后。重新啟動(dòng)一個(gè)Mysql容器,并掛載 mysql_datadir 作為數(shù)據(jù)庫存儲路勁時(shí),記得忽略MYSQL_ROOT_PASSWORD環(huán)境變量的設(shè)置。先前存在的數(shù)據(jù)庫文件不會有變化。

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

chcon -Rt svirt_sandbox_file_t /root/mysql_datadir

進(jìn)入容器配置數(shù)據(jù)庫權(quán)限

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可以訪問這個(gè)容器的mysql服務(wù)

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

需要等待一段時(shí)間

docker_pull
docker_pull

這個(gè)鏡像已經(jīng)配置好了python3.4和django1.10的環(huán)境?,F(xiàn)在我們還要構(gòu)建可以連接mysql的環(huán)境。

用Dockerfile文件構(gòu)建一個(gè)鏡像

新建一個(gè)Dockerfile文件,添加下面內(nèi)容

Dockerfile_djanog
Dockerfile_djanog

build鏡像

docker build -t [倉庫和標(biāo)簽名稱] [Dockerfile文件路徑]

docker_build_django
docker_build_django
docker_image_django
docker_image_django

從鏡像運(yùn)行容器

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

啟動(dòng)一個(gè)名為botmail的容器,并且掛載代碼文件到容器中,同時(shí)映射宿主機(jī)8000端口到容器的7000端口。連接MySQL的容器,并設(shè)置別名為db。

修改Django項(xiàng)目中的settings.py文件中的有關(guān)數(shù)據(jù)庫連接的配置

docker_django_connect
docker_django_connect

注意: 同時(shí)要為當(dāng)前容器的ip配置數(shù)據(jù)庫權(quán)限,否則無法連接。

從鏡像中啟動(dòng)django項(xiàng)目

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

確保防火墻關(guān)閉后可以從外部訪問。

這樣構(gòu)建的Django+mysql容器連接有一些問題,首先端口7000使用了硬編碼,而且數(shù)據(jù)庫連接使用‘db’硬編碼,應(yīng)當(dāng)考慮使用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

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

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

創(chuàng)建db.env文件用作設(shè)置db服務(wù)的環(huán)境變量。

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

創(chuàng)建data文件夾用作db服務(wù)的數(shù)據(jù)存儲,通過以下命令啟動(dòng)容器組合。

docker-compose up

若是data文件夾中為空,db服務(wù)會進(jìn)行一些初始化

docker-compose_up
docker-compose_up

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

docker-compose_ps
docker-compose_ps

現(xiàn)在可以從宿主機(jī)的ip訪問botmail應(yīng)用,但因?yàn)閿?shù)據(jù)庫中沒有數(shù)據(jù),需要初始化數(shù)據(jù)。

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

data_init.sql文件已經(jīng)存在在數(shù)據(jù)庫容器的工作目錄下。

docker_init_db_data
docker_init_db_data

現(xiàn)在可以進(jìn)行登錄了。

<span id="3">

Apache容器

</span>

拉取centos鏡像,用來搭建apache服務(wù)

pull_centos
pull_centos

啟動(dòng)一個(gè)容器,并用yum安裝httpd服務(wù)

run_centos
run_centos
yum_install_httpd
yum_install_httpd

啟動(dòng)httpd服務(wù)報(bào)錯(cuò)

apache_docker_start_error
apache_docker_start_error

這個(gè)問題可以參考后面的錯(cuò)誤解決辦法

此時(shí)先不管這個(gè)問題

安裝django環(huán)境

安裝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應(yīng)用與服務(wù)器的接口模塊,apache必須安裝mod_wsgi才能夠和python代碼進(jìn)行交互,之前有個(gè)版本用的是mod_python,現(xiàn)已經(jīng)淘汰了

下載源碼包

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

解壓并編譯安裝

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

yum install gcc httpd-devel -y

編譯安裝mod_wsgi,注意指定python3的環(huán)境

compile_mod_wsgi_python3
compile_mod_wsgi_python3

成功編譯安裝的結(jié)果

success_complie_mod_wsgi
success_complie_mod_wsgi

說明模塊已經(jīng)安裝到這個(gè)目錄下了/usr/lib64/httpd/modules/mod_wsgi.so

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

got_mod_wsgi_module
got_mod_wsgi_module

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

測試apache服務(wù)

剛剛遇到了apache服務(wù)無法啟動(dòng)的問題,現(xiàn)在進(jìn)行解決

退出容器,將當(dāng)前容器打包成鏡像

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

最后一個(gè)選項(xiàng)是我的docker倉庫名,可以自行定義

用以下新命令運(yùn)行

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

new_run_apache_docker
new_run_apache_docker

進(jìn)入容器,啟動(dòng)apache服務(wù)

success_start_apache
success_start_apache

通過瀏覽器可以訪問

browe_apache_welcome
browe_apache_welcome

6003端口是宿主機(jī)的,映射到容器的80端口

修改httpd.conf文件

添加以下兩行

導(dǎo)入wsgi模塊

LoadModule wsgi_module modules/mod_wsgi.so

django項(xiàng)目路徑

WSGIPythonPath /var/www/botmail

python3的安裝路徑

WSGIPythonHome /usr/python3.5

配置虛擬主機(jī)

在/etc/httpd/conf.d/目錄下新建一個(gè)文件botmail.conf,添加以下內(nèi)容

<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>

注意: 不要在虛擬主機(jī)的配置文件中配置WSGIPythonPath和WSGIPythonHome,否則啟動(dòng)apachectl服務(wù)時(shí)報(bào)錯(cuò)

因?yàn)槭堑谝淮谓佑|apache服務(wù)器,這里的配置具體含義我不是特別清楚,有興趣應(yīng)該查閱官方文檔。

重新啟動(dòng)apache服務(wù),沒錯(cuò)誤的話就ok

apachectl restart

重新將這個(gè)容器打包一份鏡像

現(xiàn)在就剩最后一步了:掛載botmail的項(xiàng)目路徑

通過docker-compose.yml文件構(gòu)建容器組合

創(chuàng)建一個(gè)docker-compose.yml文件,填入以下內(nèi)容

# docker-compose版本
version: '3'
# 服務(wù)
services:
    # 數(shù)據(jù)庫服務(wù)
    db:
        # 拉取鏡像
        image: 1015010127/mysql-server:v2
        # 運(yùn)行容器的名稱
        container_name: mysql-container
        # 環(huán)境變量文件
        env_file: ./db.env
        # 端口映射,外部可以從3308端口訪問
        ports:
            - "3308:3306"
        # 掛載目錄
        volumes:
            # 數(shù)據(jù)儲存目錄,請自行定義
            - /root/docker_study/botmail_docker/data:/var/lib/mysql
        # 設(shè)置工作目錄
        working_dir: /mysql_data_init
    # web服務(wù)
    web:
        image: 1015010127/centos:apache_v5
        container_name: botmail_apache
        # 依賴db服務(wù),先啟動(dòng)db再啟動(dòng)web
        depends_on:
            - db
        # 宕機(jī)即重啟
        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
        # 連接數(shù)據(jù)庫
        links:
            - db

在這個(gè)文件的目錄下運(yùn)行以下命令

docker-compose up

docker-compose_run_apache_mysql
docker-compose_run_apache_mysql

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

web_docker_botmail
web_docker_botmail

可能會遇到的錯(cuò)誤

apache配置錯(cuò)誤

<span id=4>

1. 在centos7鏡像中安裝httpd服務(wù),啟動(dòng)報(bào)錯(cuò)

</span>

centos_docker_httpd_error
centos_docker_httpd_error

打包當(dāng)前容器,成鏡像,然后從新用以下命令運(yùn)行

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

new_run_apache_docker
new_run_apache_docker

進(jìn)入容器,啟動(dòng)apache服務(wù)

success_start_apache
success_start_apache

通過瀏覽器可以訪問

browe_apache_welcome
browe_apache_welcome

6003端口是宿主機(jī)的,映射到容器的80端口

之后進(jìn)入容器內(nèi)啟動(dòng)apache可以成功

2. apache的python環(huán)境配置錯(cuò)誤

因?yàn)閜ython項(xiàng)目是用python3寫的,我們都知道python3和python2是不兼容的,如果apache的是python2環(huán)境,如下,啟動(dòng)時(shí)通過查看/var/log/httpd/error_log日志可以查看apache啟動(dòng)的配置信息

python_2.7.5_configure
python_2.7.5_configure

訪問web應(yīng)用時(shí),后端的python代碼報(bào)錯(cuò)

python_run_2.7.5_error
python_run_2.7.5_error

python2的模塊和python3并不兼容

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

add_python3_home
add_python3_home

但是在運(yùn)行的時(shí)候卻出現(xiàn)沒有site模塊的錯(cuò)誤:ImportError: No module named site

python3_no_module_site
python3_no_module_site

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

ldd mod_wsgi.so

mod_wsgi_python2
mod_wsgi_python2

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

下載源碼包

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

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

yum install gcc httpd-devel -y

編譯安裝mod_wsgi,注意指定python3的環(huán)境

compile_mod_wsgi_python3
compile_mod_wsgi_python3

發(fā)生錯(cuò)誤: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

這個(gè)錯(cuò)誤的解決辦法是要重新編譯python3的源碼,并加上--enable-shared選項(xiàng)

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

可能重新編譯python后,運(yùn)行python3的交互命令是,發(fā)生以下錯(cuò)誤,依賴發(fā)生問題

python_lib_cannot_find
python_lib_cannot_find

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

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

mod_wsgi_python3
mod_wsgi_python3

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

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

web界面顯示Not Found

Not Found

The requested URL / was not found on this server.

not_found_error
not_found_error

可能是django的項(xiàng)目路徑?jīng)]有配置對

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容