经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Docker » 查看文章
Docke--Dockerfile 构建LNMP环境别来无恙-
来源:cnblogs  作者:别来无恙-  时间:2019/1/14 9:23:13  对本文有异议

Dockerfile 构建nginx并结合php

1、构建基础镜像

先构建一个基础镜像,添加repo的环境和编译的环境,而centos镜像就是初始的官方镜像,后面构建php、nginx、mysql都使用该镜像为base image:

  1. [root@server myCentos]# cat Dockerfile   #查看Dockerfile文件
  2. # base image
  3. FROM centos
  4. # MAINTAINER
  5. MAINTAINER 381347268@qq.com
  6. # add epel and 163 yum
  7. RUN yum install wget epel-release -y && mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.back && wget -P /etc/yum.repos.d/ http://mirrors.aliyun.com/repo/Centos-7.repo \
  8. && wget -P /etc/yum.repos.d/ http://mirrors.163.com/.help/CentOS7-Base-163.repo \
  9. && yum clean all && yum makecache
  10. # Necessary packages
  11. RUN yum install -y wget gcc gcc-c++ glibc make autoconf openssl openssl-devel ntpdata crontabs
  12. # change timzone to Asia/Shanghai
  13. RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
  1. [root@server myCentos]# docker build -t centos:v1 .  #构建镜像取名为centos:v1
  1. [root@server myCentos]# docker images  #构建完成后查看该镜像
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. centos v1 cca50f986518 About a minute ago 665MB

查看nginx和php的目录结构:

  1. [root@server ~]# tree nginx
  2. nginx
  3. ├── Dockerfile
  4. ├── fastcgi_params
  5. ├── nginx-1.8.1.tar.gz
  6. ├── nginx.conf
  7. └── www.conf
  1. [root@server ~]# tree php
  2. php
  3. ├── Dockerfile
  4. ├── libmcrypt-2.5.8.tar.gz
  5. ├── php-5.6.35.tar.gz
  6. ├── php-fpm.conf.default
  7. └── php.ini-production

这里详细描述下nginx和php的构建过程,已经构建过程中用到的所有工具包和配置文件

2、构建nginx镜像

首先构建nginx镜像,查看nginx的Dockerfile:

  1. [root@server nginx]# cat Dockerfile
  2. # base image
  3. FROM centos:v1
  4. MAINTAINER 381347268@qq.com
  5. RUN useradd -M -s /sbin/nologin www
  6. ADD nginx-1.8.1.tar.gz /usr/local/src
  7. # install Dependency package
  8. RUN yum install libxslt-devel -y gd gd-devel GeoIP GeoIP-devel pcre pcre-devel libxml2 libxml2-dev libxslt-devel
  9. WORKDIR /usr/local/src/nginx-1.8.1
  10. # make && make install
  11. RUN ./configure --user=www --group=www --prefix=/usr/local/nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_spdy_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module && make && make install
  12. # configure
  13. COPY nginx.conf /usr/local/nginx/conf/nginx.conf
  14. COPY fastcgi_params /usr/local/nginx/conf/fastcgi_params
  15. RUN mkdir /usr/local/nginx/conf/conf.d
  16. COPY www.conf /usr/local/nginx/conf/conf.d/www.conf
  17. EXPOSE 80
  18. CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]

这里nginx采用了编译安装,创建了用户www和安装了nginx的一些依赖包,copy了一些配置文件到镜像中。详细配置文件参考:

通过Dockerfile构建nginx镜像:

  1. [root@server nginx]# docker build -t nginx:v1 .  #构建nginx镜像,tag为v1
  2. [root@server nginx]# docker images   #查看构建完成的镜像
  3. REPOSITORY TAG IMAGE ID CREATED SIZE
  4. nginx v1 c1c90aaefa1e 33 seconds ago 752MB
    centos              v1                  cca50f986518        2 hours ago         665MB

特别说明下配置文件:

  1. [root@server nginx]# cat www.conf
  2. server {
  3. listen 80;
  4. root /usr/local/nginx/html;
  5. index index.htm index.html index.php;
  6. location ~ \.php$ {
  7. root /usr/local/nginx/html;
  8. fastcgi_pass php:9000;
  9. fastcgi_index index.php;
  10. fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  11. include fastcgi_params;
  12. }
  13. }

可以发现fastcgi_pass php:9000;

这是因为php也是一个容器,和nginx是隔离的,后面启动容器的时候nginx将会通过--link的方式与镜像进行互联访问

3、构建php镜像

查看php的Dockerfile:

  1. [root@server php]# cat Dockerfile
  2. # base image
  3. FROM centos:v1
  4. MAINTAINER 381347268@qq.com
  5. ADD libmcrypt-2.5.8.tar.gz /usr/local/src
  6. WORKDIR /usr/local/src/libmcrypt-2.5.8
  7. RUN ./configure && make && make install
  8. ADD php-5.6.35.tar.gz /usr/local/src
  9. RUN yum -y install libxml2 libxml2-devel bzip2 bzip2-devel libjpeg-turbo libjpeg-turbo-devel libpng libpng-devel freetype freetype-devel zlib zlib-devel libcurl libcurl-devel
  10. WORKDIR /usr/local/src/php-5.6.35
  11. RUN ./configure --prefix=/usr/local/php --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --with-mysql=mysqlnd --with-openssl --enable-mbstring --with-freetype-dir --with-jpeg-dir --with-png-dir --with-mcrypt --with-zlib --with-libxml-dir=/usr --enable-xml --enable-sockets --enable-fpm --with-config-file-path=/usr/local/php/etc --with-bz2 --with-gd && make && make install
  12. COPY php.ini-production /usr/local/php/etc/php.ini
  13. COPY php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
  14. RUN useradd -M -s /sbin/nologin php
  15. RUN sed -i -e 's@;pid = run/php-fpm.pid@pid = run/php-fpm.pid@g' -e 's@nobody@php@g' -e 's@listen = 127.0.0.1:9000@listen = 0.0.0.0:9000@g' /usr/local/php/etc/php-fpm.conf
  16. RUN sed -i 's@;daemonize = yes@daemonize = no@g' /usr/local/php/etc/php-fpm.conf
  17. EXPOSE 9000
  18. CMD ["/usr/local/php/sbin/php-fpm"]

构建的服务必须运行在前台,而对于nginx来说:daemon off 表示将后台运行关闭了,于是运行在前台

而对于php:sed -i 's@;daemonize = yes@daemonize = no@g' /usr/local/php/etc/php-fpm.conf

这里也是将daemon模式关闭了,于是/usr/local/php/sbin/php-fpm 运行在前台

通过Dockerfile构建php镜像:

  1. [root@server php]# docker build -t php:v1 .  #构建php镜像,tag为v1
  2. [root@server php]# docker images  #查看构建完成的镜像
  3. REPOSITORY TAG IMAGE ID CREATED SIZE
  4. php v1 2019612cc0a4 35 seconds ago 1.19GB
    nginx               v1                  c1c90aaefa1e        About an hour ago   752MB
    centos              v1                  cca50f986518        2 hours ago         665M

4、启动nginx容器和php容器

利用构建的镜像启动php、nginx服务:

  1. [root@server php]# docker run -d --name php -v /www:/usr/local/nginx/html php:v1  #启动一个php容器并通过-v进行映射
  2. cf77c85e7c2f63a7ac2db2edaa37d22418503e8cfa35d87b9cfad541d03e004a
  3. [root@server php]# docker run -d --name nginx -p 80:80 -v /www:/usr/local/nginx/html --link=php:php nginx:v1  #启动一个nginx容器并通过-v进行映射及--link进行关联php容器
  4. 3bbc12db8e9cc118a7824c5a314d13c4e37f3a6397f32bbfe939f9e424b306e0

上面启动php的容器时,使用了-v进行映射,如果这里不进行映射,那么php的程序会启动,但是遇到php结尾的文件将不会解析,出现file not found的错误

查看容器状态:

  1. [root@server php]# docker ps -a
  2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3. 3bbc12db8e9c nginx:v1 "/usr/local/nginx/sb…" 26 seconds ago Up 25 seconds 0.0.0.0:80->80/tcp nginx
  4. cf77c85e7c2f php:v1 "/usr/local/php/sbin…" 2 minutes ago Up 2 minutes 9000/tcp php

在宿主机上到网站目录创建测试文件:

  1. [root@server www]# tree .  #查看网站目录的结构
  2. .
  3. ├── index.php
  4. └── test.html
  5. [root@server www]# cat index.php   #查看index.php文件
  6. <?php phpinfo() ?>
  7. [root@server www]# cat test.html   #查看test.html文件
  8. <h1>Hello Docker nginx-php</h1>

访问测试:

进入到php容器查看hosts文件:

  1. [root@server ~]# docker exec -it php /bin/bash  #使用exec进入php容器
  2. [root@cf77c85e7c2f php-5.6.35]# cat /etc/hosts
  3. 127.0.0.1 localhost
  4. ::1 localhost ip6-localhost ip6-loopback
  5. fe00::0 ip6-localnet
  6. ff00::0 ip6-mcastprefix
  7. ff02::1 ip6-allnodes
  8. ff02::2 ip6-allrouters
  9. 172.17.0.2 cf77c85e7c2f

进入到nginx容器查看hosts文件:

  1. [root@server ~]# docker exec -it nginx /bin/bash  #使用exec进入nginx容器
  2. [root@3bbc12db8e9c nginx-1.8.1]# cat /etc/hosts
  3. 127.0.0.1 localhost
  4. ::1 localhost ip6-localhost ip6-loopback
  5. fe00::0 ip6-localnet
  6. ff00::0 ip6-mcastprefix
  7. ff02::1 ip6-allnodes
  8. ff02::2 ip6-allrouters
  9. 172.17.0.2 php cf77c85e7c2f
  10. 172.17.0.3 3bbc12db8e9c

可以看到nginx的hosts文件中有一条php的解析,这就是为什么nginx能够和php进行通信的缘由(通过--link进行指定)

 

基于上面的步骤,nginx和php的连接就ok了,下面添加一个mysql 然后测试部署wordpress

5、构建mysql镜像

查看mysql的目录结构:

  1. [root@server mysql]# tree .
  2. .
  3. ├── business.sql
  4. ├── Dockerfile
  5. ├── MariaDB-10.0.33-centos7-x86_64-client.rpm
  6. ├── MariaDB-10.0.33-centos7-x86_64-common.rpm
  7. ├── MariaDB-10.0.33-centos7-x86_64-compat.rpm
  8. ├── MariaDB-10.0.33-centos7-x86_64-server.rpm
  9. ├── server.cnf
  10. └── setup.sh

查看mysql的Dockerfile:

  1. [root@server mysql]# cat Dockerfile
  2. FROM centos
  3. MAINTAINER 381347268@qq.com
  4. COPY MariaDB-10.0.33-centos7-x86_64-client.rpm /root/MariaDB-10.0.33-centos7-x86_64-client.rpm
  5. COPY MariaDB-10.0.33-centos7-x86_64-common.rpm /root/MariaDB-10.0.33-centos7-x86_64-common.rpm
  6. COPY MariaDB-10.0.33-centos7-x86_64-compat.rpm /root/MariaDB-10.0.33-centos7-x86_64-compat.rpm
  7. COPY MariaDB-10.0.33-centos7-x86_64-server.rpm /root/MariaDB-10.0.33-centos7-x86_64-server.rpm
  8. WORKDIR /root
  9. RUN yum remove mysql-libs -y
  10. RUN yum -y install *.rpm
  11. ADD business.sql /root/business.sql
  12. ADD server.cnf /etc/my.cnf.d/server.cnf
  13. ADD setup.sh /root/setup.sh
  14. RUN yum clean all
  15. RUN chmod +x /root/setup.sh
  16. EXPOSE 3306
  17. CMD ["/root/setup.sh"]

(1)这里所使用的基础镜像是centos(官方镜像,latest);(2)配置文件通过后面启动时挂载进去,(如果后面有更改,只需要在某个目录创建好配置文件,然后进行挂载即可);(3)business.sql是关于执行的sql(赋予root密码,创建数据库等等);(4)setup.sh是执行了重新初始化mysql(mariadb),最后重启了服务(使用了 --user=mysql,避免出现了使用root用户启动mariadb)

setup.sh脚本原理:Dockerfile用来安装数据库服务,安装完成后,通过setup.sh脚本重新将mysql进行初始化  初始化后,开启MySQL服务执行setup.sh中的sql,关闭mysql数据库 重新以前台的方式启动MySQL数据库服务

  1. [root@server mysql]# cat setup.sh
  2. #!/bin/sh
  3. chown -R mysql:mysql /var/lib/mysql
  4. mysql_install_db --user=mysql > /dev/null
  5. mysqld_safe --user=mysql &
  6.  
  7. sleep 5
  8. mysql < /root/business.sql
  9. sleep 5
  10.  
  11. ps -wef | grep mysql | grep -v grep | awk '{print $2}' | xargs kill -9
  12. mysqld_safe --user=mysql
setup.sh
  1. [root@server mysql]# cat business.sql
  2. create database wordpress DEFAULT CHARACTER SET utf8;
  3. USE mysql;
  4. GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
  5. FLUSH PRIVILEGES;
  6. UPDATE user SET password=PASSWORD("root") WHERE user='root';
  7. FLUSH PRIVILEGES;
business.sql
  1. [root@server mysql]# cat server.cnf
  2. [mysqld]
  3. bind-address=0.0.0.0
  4. console=1
  5. general_log=1
  6. general_log_file=/dev/stdout
  7. collation-server=utf8_unicode_ci
  8. character-set-server=utf8
server.cnf

通过Dockerfile构建mysql镜像:

  1. [root@server mysql]# docker build -t mysql:v1 .  #构建mysql镜像

查看构建完成的镜像:

  1. [root@server mysql]# docker images  #查看三个镜像
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. mysql v1 4a3e428817c1 2 hours ago 813MB
  4. php v1 2019612cc0a4 3 hours ago 1.19GB
  5. nginx v1 c1c90aaefa1e 4 hours ago 752MB

6、部署lnmp环境及wordpress

基于上面的三个镜像 nginx、mysql、php构建lnmp环境,我们先将上面启动的容器给删除掉,因为没有什么用了

先启动三个容器:

  1. [root@server mysql]# docker run -d --name mysql -v /root/mysql/server.cnf:/etc/my.cnf.d/server.cnf -v /data/mysql:/var/lib/mysql -p 3306:3306 mysql:v1  #启动一个mysql容器
  2. df28bcb97289676654ea7b573b0e3e52f910a599ff03b2dbf2dfe6345726127d
  3. [root@server mysql]# docker run -d --name php -v /www:/usr/local/nginx/html --link=mysql:mysql php:v1  #启动一个php容器
  4. 2f7fd098f0069deeaef4eb5b067e981c6be01a16d0769c3bc4203eab03a45c40
  5. [root@server mysql]# docker run -d --name nginx -p 80:80 -v /www:/usr/local/nginx/html --link=php:php nginx:v1  #启动一个nginx容器
  6. b68688cd6f2d324e58c469cfb49fa7a14257ef2bb0c301a40a36ef244201c159
  7. [root@server mysql]# docker ps  #查看启动的三个容器的状态
  8. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  9. b68688cd6f2d nginx:v1 "/usr/local/nginx/sb…" 11 seconds ago Up 10 seconds 0.0.0.0:80->80/tcp nginx
  10. 2f7fd098f006 php:v1 "/usr/local/php/sbin…" About a minute ago Up About a minute 9000/tcp php
  11. df28bcb97289 mysql:v1 "/root/setup.sh" About a minute ago Up About a minute 0.0.0.0:3306->3306/tcp mysql

这里阐述下这里启动的这三个容器:(1)先启动一个mysql容器, 并且将上面的server.cnf配置文件和数据目录挂载到了容器内部,这样就防止了数据的丢失;(2)接着启动一个php容器,使用了-v进行映射,如果这里不进行映射,那么php的程序会启动,但是遇到php结尾的文件将不会解析,出现file not found的错误,并且使用了 --link 与mysql 关联,这样php容器就可以连接mysql数据库了;(3)最后启动一个nginx容器,同样使用了-v 进行映射,将网站目录映射到宿主机,通过 --link与php 关联

开始安装wordpress:

  1. [root@server ~]# cd /www/
  2. [root@server www]# wget https://cn.wordpress.org/wordpress-4.7.4-zh_CN.tar.gz
  3. [root@server www]# tar xf wordpress-4.7.4-zh_CN.tar.gz
  4. [root@server www]# ll
  5. 总用量 8324
  6. -rw-r--r-- 1 root root 19 1 11 12:27 index.php
  7. -rw-r--r-- 1 root root 32 1 11 12:04 test.html
  8. drwxr-xr-x 5 nobody nfsnobody 4096 4 23 2017 wordpress
  9. -rw-r--r-- 1 root root 8507412 4 23 2017 wordpress-4.7.4-zh_CN.tar.gz

通过浏览器访问宿主机进行安装:http://IP/wordpress

...省略...

 

进入到mysql容器查看hosts:

  1. [root@server ~]# docker exec -it mysql /bin/bash  #使用exec进入mysql容器
  2. [root@df28bcb97289 ~]# cat /etc/hosts
  3. 127.0.0.1 localhost
  4. ::1 localhost ip6-localhost ip6-loopback
  5. fe00::0 ip6-localnet
  6. ff00::0 ip6-mcastprefix
  7. ff02::1 ip6-allnodes
  8. ff02::2 ip6-allrouters
  9. 172.17.0.2 df28bcb97289

进入到php容器查看hosts:

  1. [root@server ~]# docker exec -it php /bin/bash  #使用exec进入到php容器
  2. [root@2f7fd098f006 php-5.6.35]# cat /etc/hosts
  3. 127.0.0.1 localhost
  4. ::1 localhost ip6-localhost ip6-loopback
  5. fe00::0 ip6-localnet
  6. ff00::0 ip6-mcastprefix
  7. ff02::1 ip6-allnodes
  8. ff02::2 ip6-allrouters
  9. 172.17.0.2 mysql df28bcb97289
  10. 172.17.0.3 2f7fd098f006

进入到nginx容器查看hosts:

  1. [root@server ~]# docker exec -it nginx /bin/bash  #使用exec进入到nginx容器
  2. [root@b68688cd6f2d nginx-1.8.1]# cat /etc/hosts
  3. 127.0.0.1 localhost
  4. ::1 localhost ip6-localhost ip6-loopback
  5. fe00::0 ip6-localnet
  6. ff00::0 ip6-mcastprefix
  7. ff02::1 ip6-allnodes
  8. ff02::2 ip6-allrouters
  9. 172.17.0.3 php 2f7fd098f006
  10. 172.17.0.4 b68688cd6f2d

通过观察可以看见在php容器的hosts中有一条mysql的记录,这也就是为什么安装wordpress时后,我们直接填写mysql容器的名字变可以连接了。同理,nginx中也有一条php的记录。

相关软件包及配置文件见GitHub :https://github.com/buji595/docker_project/tree/master/Dockerfile_Project/lnmp

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号