使用Dockerfile定製LNMP環境鏡像

LNMP是繼LAMP之後的又一個非常流行的web框架,即Linux+Nginx+Mysql+PHP的網站架構方案。nginx相較於apache更輕量級,尤其是對靜態頁面的處理更有優勢。做運維的朋友應該都知道一個流行的詞彙——動靜態分離,其中一個比較普遍的是使用nginx處理靜態頁面,而動態頁面交由後端的apache或者tomcat處理。本文要講的是通過Dockerfile構建LNMP環境鏡像,分別把nginx、mysql和PHP部署在docker容器裏,實現LNMP網站架構。

一、項目環境介紹

1、系統環境
操作系統版本:Centos 7.5 64位
Docker版本:18.06.1-ce(社區版)
Nginx版本:1.15.5
PHP版本:7.2.11
Mysql版本:8.0.12
ip地址:192.168.2.236
lnmp網絡ip地址:172.18.0.1
2、源碼包下載地址
nginx下載地址:http://nginx.org/download/nginx-1.15.5.tar.gz
php下載地址:http://cn2.php.net/get/php-7.2.11.tar.gz/from/this/mirror
mysql使用官方8.0.12鏡像
3、目錄結構

[root@andyxu ~]# tree dockerfile/
dockerfile/
├── nginx
│   ├── Dockerfile
│   ├── nginx-1.15.5.tar.gz
│   └── nginx.conf
└── php
    ├── Dockerfile
    └── php-7.2.11.tar.gz

二、安裝部署docker環境

docker環境的安裝部署可以參考我的另一篇博文《Centos 7部署docker環境、基本命令使用及簡單實戰》,http://blog.51cto.com/andyxu/2174652 本文的所有操作都是基於這個環境執行的。

三、構建php鏡像

(1)Dockerfile文件內容

FROM centos:latest
MAINTAINER http://blog.51cto.com/andyxu
ENV TIME_ZOME Asia/Shanghai
ARG PV="php-7.2.11"

ADD $PV.tar.gz /tmp
RUN yum -y install gcc gcc-c++ make gd-devel libxml2-devel libcurl-devel libjpeg-devel libpng-devel openssl-devel bison \
    && mkdir /data \
    && cd /tmp/$PV \
    && ./configure --prefix=/data/php \
        --with-config-file-path=/data/php/etc \
        --with-gd --with-mysqli \
        --with-openssl --with-zlib --with-curl \
        --with-jpeg-dir --with-png-dir --with-iconv \
        --enable-fpm --enable-zip --enable-mbstring \
    && make -j 4 \
    && make install \
    && cp /data/php/etc/php-fpm.conf.default /data/php/etc/php-fpm.conf \
    && cp /data/php/etc/php-fpm.d/www.conf.default /data/php/etc/php-fpm.d/www.conf \
    && sed -i '/;daemonize/a\daemonize = no' /data/php/etc/php-fpm.conf \
    && sed -i 's/127.0.0.1/0.0.0.0/g' /data/php/etc/php-fpm.d/www.conf \
    && echo "${TIME_ZOME}" > /etc/timezone \
    && ln -sf /usr/share/zoneinfo/${TIME_ZOME} /etc/localtime \
    && rm -rf /tmp/php* \
    && yum clean all \
    && yum -y remove gcc gcc-c++ make

WORKDIR /data/php/
EXPOSE 9000
CMD ["sbin/php-fpm","-c","etc/php-fpm.conf"]

注:daemonize = no表示fpm在前臺運行
(2)構建php鏡像

[root@andyxu ~]# cd dockerfile/php/
[root@andyxu php]# docker build -t php:7.2.11 .

此時會先下載centos鏡像,然後再構建新鏡像,時間會比較久,可喝杯茶耐心等待
(3)報錯問題解決方法
如果yum語句無法執行的話,並且報以下警告:
[Warning] IPv4 forwarding is disabled. Networking will not work.
這個問題是由於IPv4轉發被禁用了,導致無法上網,需要將IPv4轉發開啓
解決方法:
vim /usr/lib/sysctl.d/00-system.conf
添加如下內容
net.ipv4.ip_forward=1
重啓network服務
systemctl restart network

四、構建nginx鏡像

(1)Dockerfile文件內容

FROM centos:latest
MAINTAINER http://blog.51cto.com/andyxu
ENV TIME_ZOME Asia/Shanghai
ARG NV="nginx-1.15.5"

COPY nginx.conf /data/nginx/conf/
ADD $NV.tar.gz /tmp
RUN yum -y install gcc gcc-c++ make openssl-devel pcre-devel \
        && mkdir -p /data \
        && cd /tmp/$NV \
        && ./configure --prefix=/data/nginx \
        && make -j 2 \
        && make install \
        && echo "${TIME_ZOME}" > /etc/timezone \
        && ln -sf /usr/share/zoneinfo/${TIME_ZOME} /etc/localtime \
        && rm -rf /tmp/nginx* \
        && yum clean all \
        && yum -y remove gcc gcc-c++ make

WORKDIR /data/nginx/
EXPOSE 80
CMD ["./sbin/nginx","-g","daemon off;"]

(2)準備好nginx配置文件
將nginx.conf文件的server段按如下內容修改,我這裏去掉了#號註釋行

    server {
        listen       80;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm index.php;   #添加index.php
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location ~ \.php$ {
            root           html;
            fastcgi_pass   php:9000;   #php容器名稱和端口號
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;  #使用root指定的路徑
            include        fastcgi_params;
        }

    }

(3)構建nginx鏡像

[root@andyxu php]# cd ../nginx/
[root@andyxu nginx]# docker build -t nginx:1.15.5 .

五、下載mysql鏡像

建議直接使用mysql官方鏡像,我測試過源碼編譯安裝,最後生成的鏡像大小3G多,而官方鏡像只有400多M,而且源碼安裝操作步驟比較複雜,所以這裏我棄用了源碼安裝,而選擇直接使用官方鏡像。

[root@andyxu nginx]# docker pull mysql:8.0.12
8.0.12: Pulling from library/mysql
802b00ed6f79: Pull complete 
30f19a05b898: Pull complete 
3e43303be5e9: Pull complete 
94b281824ae2: Pull complete 
51eb397095b1: Pull complete 
54567da6fdf0: Pull complete 
bc57ddb85cce: Pull complete 
d6cd3c7302aa: Pull complete 
d8263dad8dbb: Pull complete 
780f2f86056d: Pull complete 
8e0761cb58cd: Pull complete 
7588cfc269e5: Pull complete 
Digest: sha256:038f5f6ea8c8f63cfce1bce9c057ab3691cad867e18da8ad4ba6c90874d0537a
Status: Downloaded newer image for mysql:8.0.12

查看已經構建完成的鏡像情況

[root@andyxu nginx]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               1.15.5              2ecb7008e436        6 minutes ago       266MB
php                 7.2.11              5be80a8d0f1f        35 minutes ago      580MB
centos              latest              75835a67d134        2 days ago          200MB
mysql               8.0.12              6a834f03bd02        5 weeks ago         484MB

六、創建並啓動容器

(1)創建自定義網絡lnmp

[root@andyxu nginx]# docker network create lnmp
d56d132338f8e63537dac55d481053d56a5c5faf3ab3bd3a04ac2bc460b54b3f
[root@andyxu nginx]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
b0fa374c72f1        bridge              bridge              local
e6930ef7e774        host                host                local
d56d132338f8        lnmp                bridge              local
d7beee548faa        none                null                local

(2)創建生成mysql、php、nginx容器的腳本
docker_lnmp.sh腳本內容如下

#!/bin/bash
function mysql()
{
    docker run --name mysql --restart=always --net lnmp -p 3306:3306 \
    -v /data/mysql/data:/var/lib/mysql \
    -v /data/mysql/conf:/etc/mysql/conf.d \
    -v /data/mysql/logs:/logs \
    -e MYSQL_ROOT_PASSWORD=test123456 \
    -d mysql:8.0.12 --character-set-server=utf8
}

function php()
{
    docker run --name php --restart=always --net lnmp \
    -v /data/nginx/html:/data/nginx/html \
    -v /data/php/log:/data/php/var/log \
    -d php:7.2.11
}

function nginx()
{
    docker run --name nginx --restart=always --net lnmp -p 80:80 \
    -v /data/nginx/html:/data/nginx/html \
    -v /data/nginx/logs:/data/nginx/logs \
    -d nginx:1.15.5
}
$1

注:php和nginx必須都要掛載網站目錄
(3)啓動mysql、php、nginx容器

[root@andyxu ~]# sh docker_lnmp.sh mysql
[root@andyxu ~]# sh docker_lnmp.sh php
[root@andyxu ~]# sh docker_lnmp.sh nginx

(4)查看容器是否都成功啓動

[root@andyxu ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                               NAMES
a1f9c0dea6df        nginx:1.15.5        "./sbin/nginx -g 'da…"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp                  nginx
8dfe39adbc60        php:7.2.11          "sbin/php-fpm -c etc…"   5 minutes ago        Up 5 minutes        9000/tcp                            php
475b41187391        mysql:8.0.12        "docker-entrypoint.s…"   6 minutes ago        Up 6 minutes        0.0.0.0:3306->3306/tcp, 33060/tcp   mysql

(5)修改mysql的密碼加密方式爲mysql_native_password
[root@andyxu ~]# vim /data/mysql/conf/docker_mysql.cnf

[mysqld]
default-authentication-plugin=mysql_native_password

如果不修改加密方式的話,低版本的mysql客戶端登陸時會報錯
重啓mysql容器
[root@andyxu ~]# docker restart mysql

七、測試

(1)創建mysql測試賬號

[root@andyxu html]# docker exec -it mysql /bin/bash
root@475b41187391:/# mysql -uroot -ptest123456
mysql> create database test;
mysql> create user [email protected] identified by '123456';
mysql> grant all privileges on test.* to [email protected];
mysql> exit
root@475b41187391:/# exit

注:這裏需要對php容器授權訪問,使用php.lnmp
(2)編寫一個測試連接mysql的php文件
[root@andyxu ~]# vim /data/nginx/html/test.php

<?php
    echo "Hello PHP<br/>";
    $conn = mysqli_connect("mysql","test","123456");
    if(!$conn){
        echo "連接數據庫失敗";
    }else{
        echo "連接數據庫成功";
    }
    phpinfo();
?>

瀏覽器訪問http://192.168.2.236/test.php
使用Dockerfile定製LNMP環境鏡像

八、將製作好的鏡像上傳到私有倉庫

(1)構建私有鏡像倉庫
私有鏡像倉庫的構建我就不講了,可以參考我的另一篇博文《Centos 7構建docker私有鏡像倉庫》,http://blog.51cto.com/andyxu/2175081
(2)把mysql容器製作成新的鏡像

[root@andyxu ~]# docker commit -a "andyxu" -m "lnmp-mysql" mysql mysql:lnmp.8.0.12
[root@andyxu ~]# docker images

使用Dockerfile定製LNMP環境鏡像
(3)將nginx、mysql和php鏡像打個標籤

[root@andyxu ~]# docker tag mysql:lnmp.8.0.12 192.168.2.225:5000/mysql:lnmp.v1
[root@andyxu ~]# docker tag php:7.2.11 192.168.2.225:5000/php:lnmp.v1
[root@andyxu ~]# docker tag nginx:1.15.5 192.168.2.225:5000/nginx:lnmp.v1

(4)將鏡像上傳到私有倉庫

[root@andyxu ~]# docker push 192.168.2.225:5000/mysql:lnmp.v1
[root@andyxu ~]# docker push 192.168.2.225:5000/php:lnmp.v1
[root@andyxu ~]# docker push 192.168.2.225:5000/nginx:lnmp.v1

(5)查看上傳好的鏡像

[root@andyxu ~]# curl http://192.168.2.225:5000/v2/_catalog
{"repositories":["httpd-test","mysql","nginx","php"]}
[root@andyxu ~]# curl http://192.168.2.225:5000/v2/mysql/tags/list
{"name":"mysql","tags":["lnmp.v1"]}
[root@andyxu ~]# curl http://192.168.2.225:5000/v2/php/tags/list
{"name":"php","tags":["7.2-apache","lnmp.v1"]}
[root@andyxu ~]# curl http://192.168.2.225:5000/v2/nginx/tags/list
{"name":"nginx","tags":["lnmp.v1"]}

(6)將鏡像打包成tar文件,保存到/tmp目錄下

[root@andyxu ~]# docker save -o /tmp/mysql-lnmp.v1.tar 192.168.2.225:5000/mysql
[root@andyxu ~]# docker save -o /tmp/php-lnmp.v1.tar php:7.2.11
[root@andyxu ~]# docker save -o /tmp/nginx-lnmp.v1.tar nginx:1.15.5

使用Dockerfile定製LNMP環境鏡像

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章