LNMP是繼LAMP以後的又一個很是流行的web框架,即Linux+Nginx+Mysql+PHP的網站架構方案。nginx相較於apache更輕量級,尤爲是對靜態頁面的處理更有優點。作運維的朋友應該都知道一個流行的詞彙——動靜態分離,其中一個比較廣泛的是使用nginx處理靜態頁面,而動態頁面交由後端的apache或者tomcat處理。本文要講的是經過Dockerfile構建LNMP環境鏡像,分別把nginx、mysql和PHP部署在docker容器裏,實現LNMP網站架構。php
一、系統環境
操做系統版本: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
二、源碼包下載地址
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鏡像
三、目錄結構html
[root@andyxu ~]# tree dockerfile/ dockerfile/ ├── nginx │ ├── Dockerfile │ ├── nginx-1.15.5.tar.gz │ └── nginx.conf └── php ├── Dockerfile └── php-7.2.11.tar.gz
docker環境的安裝部署能夠參考個人另外一篇博文《Centos 7部署docker環境、基本命令使用及簡單實戰》,http://www.javashuo.com/article/p-hqpgquik-bu.html 本文的全部操做都是基於這個環境執行的。mysql
(1)Dockerfile文件內容nginx
FROM centos:latest MAINTAINER https://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鏡像c++
[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
web
(1)Dockerfile文件內容sql
FROM centos:latest MAINTAINER https://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段按以下內容修改,我這裏去掉了#號註釋行docker
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官方鏡像,我測試過源碼編譯安裝,最後生成的鏡像大小3G多,而官方鏡像只有400多M,並且源碼安裝操做步驟比較複雜,因此這裏我棄用了源碼安裝,而選擇直接使用官方鏡像。apache
[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 test@php.lnmp identified by '123456'; mysql> grant all privileges on test.* to test@php.lnmp; 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
(1)構建私有鏡像倉庫
私有鏡像倉庫的構建我就不講了,能夠參考個人另外一篇博文《Centos 7構建docker私有鏡像倉庫》,http://www.javashuo.com/article/p-gqromvaf-bz.html
(2)把mysql容器製做成新的鏡像
[root@andyxu ~]# docker commit -a "andyxu" -m "lnmp-mysql" mysql mysql:lnmp.8.0.12 [root@andyxu ~]# docker images
(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