美文网首页docker我爱编程
基于Docker的Django-Mysql-Apache应用容器

基于Docker的Django-Mysql-Apache应用容器

作者: 邱simple | 来源:发表于2017-06-05 20:08 被阅读335次

    基于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_mysqldocker_run_mysql

    docker ps -al

    docker_ps_aldocker_ps_al

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

    接入容器

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

    access_mysql_dockeraccess_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_datadirmysql_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_pulldocker_pull

    这个镜像已经配置好了python3.4和django1.10的环境。现在我们还要构建可以连接mysql的环境。

    用Dockerfile文件构建一个镜像

    新建一个Dockerfile文件,添加下面内容

    Dockerfile_djanogDockerfile_djanog

    build镜像

    docker build -t [仓库和标签名称] [Dockerfile文件路径]

    docker_build_djangodocker_build_django docker_image_djangodocker_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_connectdocker_django_connect

    注意: 同时要为当前容器的ip配置数据库权限,否则无法连接。

    从镜像中启动django项目

    docker exec -it botmail python manage.py runserver 0.0.0.0:7000
    
    docker_run_djangodocker_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_updocker-compose_up

    启动成功后,通过docker-compose ps可以查看运行的容器,注意: 要在docker-compose.yml文件目录下敲命令。

    docker-compose_psdocker-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_datadocker_init_db_data

    现在可以进行登录了。

    <span id="3">

    Apache容器

    </span>

    拉取centos镜像,用来搭建apache服务

    pull_centospull_centos

    启动一个容器,并用yum安装httpd服务

    run_centosrun_centos yum_install_httpdyum_install_httpd

    启动httpd服务报错

    apache_docker_start_errorapache_docker_start_error

    这个问题可以参考后面的错误解决办法

    此时先不管这个问题

    安装django环境

    安装python3

    请参考源码包安装python3以及pip

    pip安装django1.10以及pymysql

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

    成功编译安装的结果

    success_complie_mod_wsgisuccess_complie_mod_wsgi

    说明模块已经安装到这个目录下了/usr/lib64/httpd/modules/mod_wsgi.so

    在httpd的模块目录中可以找到

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

    进入容器,启动apache服务

    success_start_apachesuccess_start_apache

    通过浏览器可以访问

    browe_apache_welcomebrowe_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_mysqldocker-compose_run_apache_mysql

    在浏览器上访问6001端口,即可看到你的django项目

    web_docker_botmailweb_docker_botmail

    可能会遇到的错误

    apache配置错误

    <span id=4>

    1. 在centos7镜像中安装httpd服务,启动报错

    </span>

    centos_docker_httpd_errorcentos_docker_httpd_error

    打包当前容器,成镜像,然后从新用以下命令运行

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

    new_run_apache_dockernew_run_apache_docker

    进入容器,启动apache服务

    success_start_apachesuccess_start_apache

    通过浏览器可以访问

    browe_apache_welcomebrowe_apache_welcome

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

    之后进入容器内启动apache可以成功

    2. apache的python环境配置错误

    因为python项目是用python3写的,我们都知道python3和python2是不兼容的,如果apache的是python2环境,如下,启动时通过查看/var/log/httpd/error_log日志可以查看apache启动的配置信息

    python_2.7.5_configurepython_2.7.5_configure

    访问web应用时,后端的python代码报错

    python_run_2.7.5_errorpython_run_2.7.5_error

    python2的模块和python3并不兼容

    在httpd/conf/httpd.conf添加Python3的安装目录,来指定使用python3的环境

    add_python3_homeadd_python3_home

    但是在运行的时候却出现没有site模块的错误:ImportError: No module named site

    python3_no_module_sitepython3_no_module_site

    现在查看wsgi是否配置正确,/etc/httpd/modules/mod_wsgi模块的依赖

    ldd mod_wsgi.so

    mod_wsgi_python2mod_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_python3compile_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_findpython_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_python3mod_wsgi_python3

    注意: 重新编译了python源码,可能会造成扩展模块的丢失,注意重新用pip安装

    python -m pip install [扩展模块名称]==[版本]

    web界面显示Not Found

    Not Found

    The requested URL / was not found on this server.

    not_found_errornot_found_error

    可能是django的项目路径没有配置对

    相关文章

      网友评论

        本文标题:基于Docker的Django-Mysql-Apache应用容器

        本文链接:https://www.haomeiwen.com/subject/gyrwfxtx.html