docker:Dockerfile构建LNMP平台

 

1、dockerfile介绍

 Dockerfile是Docker用来构建镜像的文本文件,包含自定义的指令和格式。可以通过docker build命令从Dockerfile中构建镜像。这个过程与传统分布式集群的编排配置过程相似,且提供了一系列统一的资源配置语法。用户可以用这些统一的语法命令来根据需求进行配置,通过这份统一的配置文件,在不同的平台上进行分发,需要使用时就可以根据配置文件自动化构建,这解决了开发/运维人员构建镜像的复杂过程。同时,Dockerfile与镜像配合使用,使Docker在构建时可以充分利用镜像的功能进行缓存,大大提升了Docker的使用效率。

 用通俗一点的话来讲:dockerfile就是根据自己的需要自定义一个镜像,就像你写shell脚本一样,把一连串的过程或步骤全部写进dockerfile文件中,一步一步的执行dockerfile文件中你写的内容。

2、dockerfile指令

3、build命令

Usage:docker build [OPTIONS] PATH | URL | -

OPTIONS:
-t ,--tag list  #构建后的镜像名称
-f, --file string #指定Dockerfiile文件位置

示例:
1,docker build . 
2,docker build -t nginx:v10 .
3,docker build -t nginx:v10 -f /path/Dockerfile /path

一般常用第2种方式构建,我们在构建时都会切换到Dockerfile文件的目录下进行构建,所以不需要指定-f参数。如果还不是很明白的话,下面我们来构建nginx镜像、php镜像来理解一下。

4、环境说明

在本文中我都是基于centos 7官方镜像来构建、nginx和php用的源码包来构建,如果你不想用源码包,也可用yum方式构建:

  • nginx,用的是源码包来构建,版本为nginx-1.12.1.tar.gz,下载地址http://nginx.org/en/download.html/
  • php,也用的源码包来构建,版本为php-5.6.31.tar.gz,下载地址http://php.net/downloads.php

在来看一下目录结构:

  1. [root@ganbing /]# tree dockerfile/
  2. dockerfile/
  3. ├── nginx
  4.    ├── Dockerfile
  5.    ├── nginx-1.12.1.tar.gz
  6.    └── nginx.conf
  7. └── php
  8. ├── Dockerfile
  9. ├── php-5.6.31.tar.gz
  10. └── php.ini

 其中,在dockerfile目录下创建了两个目录(nginx、php),里面分别存放Dockerfile文件、源码包。nginx目录下还放了nginx.conf配置文件,php目录下也放置了php.ini配置文件。

 有些人会问为什么要把nginx.conf、php.ini配置文件放到这里,有两个原因,其一,把这两个默认的配置文件放在这里可以提前修改好所需要的参数,当容器启动后,就不需要在进入容器去修改了。当然,我这里只是练习环境,并未对这两个文件做任何更改。其二,在实际环境中,这两个文件是经常需要修改的,单独拿出来后在启动容器时你可以把这两个文件mount到容器中,便于管理。

5、nginx构建

5.1 Dockerfile内容

  1. FROM centos:7
  2. MAINTAINER blog.51cto.com/ganbing
  3. ENV TIME_ZOME Asia/Shanghai
  4. RUN yum -y install gcc gcc-c++ make openssl-devel pcre-devel
  5. ADD nginx-1.12.1.tar.gz /tmp
  6. RUN cd /tmp/nginx-1.12.1 && \
  7. ./configure --prefix=/usr/local/nginx && \
  8. make -j 2 && \
  9. make install
  10. RUN rm -rf /tmp/nginx* && yum clean all && \
  11. echo "${TIME_ZOME}" > /etc/timezone && \
  12. ln -sf /usr/share/zoneinfo/${TIME_ZOME} /etc/localtime
  13. COPY nginx.conf /usr/local/nginx/conf/
  14. WORKDIR /usr/local/nginx/
  15. EXPOSE 80
  16. CMD ["./sbin/nginx","-g","daemon off;"]

来分析一下上面的内容,当你构建时,它会根据你编排好的内容一步一步的执行下去,如果当中的某一步执行不下去,会立刻停止构建。上面的大部分指令都很好理解,在上文中的dockerifle指令中有介绍,最后一个指令我要详细说明一下:CMD ["./sbin/nginx","-g","daemon off;"]

  • /sbin/nginx 这个没什么说的,就是正常启动nginx服务;
  • -g: 设置配置文件外的全局指令,也就是启动nginx时设置了daemon off参数,默认参数是打开的on,是否以守护进程的方式运行nginx,守护进程是指脱离终端并且在后台运行的进程。这里设置为off,也就是不让它在后台运行。为什么我们启动nginx容器时不让它在后台运行呢,docker 容器默认会把容器内部第一个进程,也就是pid=1的程序作为docker容器是否正在运行的依据,如果docker 容器pid挂了,那么docker容器便会直接退出。

5.2 nginx.conf内容

  1. ......
  2. 省略其它默认配置
  3. ......
  4. server {
  5. listen 80;
  6. server_name localhost;
  7. root html;
  8. index index.html index.php;
  9. location ~ \.php$ {
  10. root html;
  11. fastcgi_pass lnmp_php:9000;
  12. fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  13. include fastcgi_params;
  14. }
  15. }

配置中主要添加了 location ~ .php这一段的内容,其中fastcgi_pass的 lnmp_php,这个是后面启动php容器时的名称。了解nginx原理的朋友应该能理解,当匹配到php的请求时,它会转发给lnmp_php这个容器php-fpm服务来处理。正常情况下,如果php服务不是跑在容器中,lnmp_php这个内容一般写php服务器的Ip地址。

5.3 build构建
nginx源码包、nginx.conf、Dockerfile都准备好了之后,现在我们可以来用docker build来构建这个镜像了:

  1. 切换到nginx目录下:
  2. [root@ganbing /]# cd /dockerfile/nginx/
  3. [root@ganbing nginx]# ls
  4. Dockerfile nginx-1.12.1.tar.gz nginx.conf
  5. 构建:
  6. [root@ganbing nginx]# docker build -t nginx:1.12.1 .

5.4 查看镜像是否构建成功

  1. [root@ganbing /]# docker images
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. nginx 1.12.1 19b0dc5eb6bb 15 minutes ago 419MB
  4. centos 7 ff426288ea90 7 weeks ago 207MB

nginx镜像已经构建好了,是不是还多了一个centos:7的镜像呢,这主要是在Dockerfile文件中你的FROM指令写的是centos:7,如果你的宿主机没有这个镜像,它就会从 hub.docker.co 中去pull这个镜像。

6、php构建

6.1 Dockerfile内容

  1. FROM centos:7
  2. MAINTAINER blog.51cto.com/ganbing
  3. ENV TIME_ZOME Asia/Shanghai
  4. RUN yum install -y gcc gcc-c++ make gd-devel libxml2-devel libcurl-devel libjpeg-devel libpng-devel openssl-devel
  5. ADD php-5.6.31.tar.gz /tmp/
  6. RUN cd /tmp/php-5.6.31 && \
  7. ./configure --prefix=/usr/local/php \
  8. --with-config-file-path=/usr/local/php/etc \
  9. --with-mysql --with-mysqli \
  10. --with-openssl --with-zlib --with-curl --with-gd \
  11. --with-jpeg-dir --with-png-dir --with-iconv \
  12. --enable-fpm --enable-zip --enable-mbstring && \
  13. make -j 4 && \
  14. make install
  15. RUN cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \
  16. sed -i 's/127.0.0.1/0.0.0.0/g' /usr/local/php/etc/php-fpm.conf && \
  17. sed -i "21a daemonize=no" /usr/local/php/etc/php-fpm.conf && \
  18. echo "${TIME_ZOME}" > /etc/timezone && \
  19. ln -sf /usr/share/zoneinfo/${TIME_ZOME} /etc/localtime
  20. COPY php.ini /usr/local/php/etc/
  21. RUN rm -rf /tmp/php* && yum clean all
  22. WORKDIR /usr/local/php/
  23. EXPOSE 9000
  24. CMD ["./sbin/php-fpm","-c","/usr/local/php/etc/php-fpm.conf"]

上面内容和nginx的Dockerfile风格差不多,也是一步一步的来。先安装依赖包、解压、配置并编译,然后修改下配置文件,启动php-fpm服务。是不是发现写Dockerfile挺简单的,就是把你平时部署php服务的步骤思路写到这个Dockerfile里面。

6.2 php.ini内容

这个内容我没有修改,是默认的配置内容。

6.3 build构建
php源码包、php.ini、Dockerfile都准备好了之后,现在我们可以来用docker build来构建这个镜像了:

  1. 切换到php目录下:
  2. [root@ganbing /]# cd /dockerfile/php/
  3. [root@ganbing php]# ls
  4. Dockerfile php-5.6.31.tar.gz php.ini
  5. 构建:
  6. [root@ganbing nginx]# docker build -t php:5.6.31 .

6.4 查看镜像是否构建成功

  1. [root@ganbing php]# docker images
  2. REPOSITORY TAG IMAGE ID CREATED SIZE
  3. php 5.6.31 9ed5ccce1735 3 minutes ago 1GB
  4. nginx 1.12.1 19b0dc5eb6bb About an hour ago 419MB
  5. centos 7 ff426288ea90 7 weeks ago 207MB

7、运行容器

7.1 创建自定义网络lnmp

先创建一个自定义网络,运行ningx、php这些容器的时候加入到lnmp网络中来:

  1. 先来查看一下默认的网络:
  2. [root@ganbing php]# docker network ls
  3. NETWORK ID NAME DRIVER SCOPE
  4. 8be78de1f4b8 bridge bridge local
  5. d77497b635bb host host local
  6. 637e45b21ed3 none null local
  7. 创建:
  8. [root@ganbing php]# docker network create lnmp
  9. 49fbb89c7e83e5aa817973cab0db06eea9f3090597dc29d2649d79a8c23d8304

7.2 创建php容器

创建容器:

  1. [root@ganbing php]# docker run -itd --name lnmp_php --network lnmp --mount type=bind,src=/app/wwwroot,dst=/usr/local/nginx/html php:5.6.31
  2. 5676b229125a9372c454488a4e55e8542ca761cd682c34f061c051c511df2340

参数说明:
-itd:   在容器中打开一个伪终端进行交互操作,并在后台运行;
--name: 为容器分配一个名字lnmp_php;
--network:为容器指定一个网络环境为lnmp网络;
--mout: 把宿主机的/app/wwwroot目录挂载到容器的/usr/local/nginx/html目录,挂载也相当于数据持久化;
php:5.6.31:指定刚才构建的php镜像来启动容器;

查看php容器是否运行:

  1. [root@ganbing php]# docker ps
  2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3. 5676b229125a php:5.6.31 "./sbin/php-fpm -c /…" 3 seconds ago Up 3 seconds 9000/tcp lnmp_php

7.3 创建nginx容器

创建容器:

  1. [root@ganbing php]# docker run -itd --name lnmp_nginx --network lnmp -p 80:80 --mount type=bind,src=/app/wwwroot,dst=/usr/local/nginx/html nginx:1.12.1
  2. 5468c0acc0246eea4f931361218656721666f1ed4a292bb425f25880880e2b10

上面的参数和创建php容器的参数差不多

查看nginx容器是否运行:

  1. [root@ganbing php]# docker ps -l
  2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3. 5468c0acc024 nginx:1.12.1 "./sbin/nginx -g 'da…" 30 seconds ago Up 29 seconds 0.0.0.0:80->80/tcp lnmp_nginx

-l:这个参数的意思是显示最后创建的容器

7.4 测试访问

其实到了这一步,我们可以创建一个index.html静态页面来访问一下:

  1. [root@ganbing wwwroot]# echo "Dockerfile lnmp test" > /app/wwwroot/index.html

我们把宿主机的/app/wwwroot目录已经挂载到容器的/usr/local/nginx/html目录中,所以直接弄个index.html来测试就行。

用浏览器访问这台宿主机的ip:

我们在弄个index.php文件来测试一下:

  1. [root@ganbing wwwroot]# echo "<? phpinfo();" > /app/wwwroot/index.php

访问一下这个php页面,是不是也没问题:

到了这一步,说明nginx、php的环境是弄好了,下面我们来把mysql数据库容器跑起来,来完成lnmp的平台,mysql数据库我这里就不用dockerfile来构建了,我直接用官方的镜像启动。

7.5 创建mysql容器

在创建容器前,我们创建一个数据卷mysql-volume,把它挂载到mysql容器中,实现数据持久化:

  1. [root@ganbing /]# docker volume create mysql-volume
  2. mysql-volume

启动mysql容器,如果你本地有mysql镜像,它会引用本的的镜像,如果没有它会去docker hub中拉取:

  1. [root@ganbing /]# docker run -itd --name lnmp_mysql --network lnmp -p 3306:3306 --mount src=mysql-volume,dst=/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql --character-set-server=utf8

参数说明:启动mysql的参数是参考官方镜像的 https://hub.docker.com/_/mysql/ ,引用官方的mysq镜像启动时必须要设定一个root密码的环境变量.

查看mysql容器是否启动:

  1. [root@ganbing /]# docker ps -l
  2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  3. 871d06d2b425 mysql "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 0.0.0.0:3306->3306/tcp lnmp_mysql

创建数据库wordpress:

  1. docker exec lnmp_mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e"create database wordpress"'

查看wordpress库是否创建 :

  1. [root@ganbing /]# docker exec lnmp_mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" -e"show databases"'
  2. mysql: [Warning] Using a password on the command line interface can be insecure.
  3. Database
  4. information_schema
  5. mysql
  6. performance_schema
  7. sys
  8. wordpress

查看数据卷是否同步了wordpress库:

  1. [root@ganbing /]# ls /var/lib/docker/volumes/mysql-volume/_data/
  2. auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem
  3. ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys
  4. ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem wordpress

8、下载wordpress博客系统测试lnmp

下载至/app/wwwroot目录下:

  1. [root@ganbing /]# cd /app/wwwroot/
  2. [root@ganbing wwwroot]# wget https://cn.wordpress.org/wordpress-4.7.4-zh_CN.tar.gz
  3. --2018-03-01 13:52:05-- https://cn.wordpress.org/wordpress-4.7.4-zh_CN.tar.gz
  4. Resolving cn.wordpress.org (cn.wordpress.org)... 198.143.164.252
  5. Connecting to cn.wordpress.org (cn.wordpress.org)|198.143.164.252|:443... connected.
  6. HTTP request sent, awaiting response... 200 OK
  7. Length: 8507412 (8.1M) [application/octet-stream]
  8. Saving to: wordpress-4.7.4-zh_CN.tar.gz
  9. 100%[=========================================================>] 8,507,412 1.08MB/s in 8.9s
  10. 2018-03-01 13:52:14 (933 KB/s) - wordpress-4.7.4-zh_CN.tar.gz saved [8507412/8507412]

解压并访问测试:

  1. [root@ganbing wwwroot]# tar -zxvf wordpress-4.7.4-zh_CN.tar.gz

解压完了之后用浏览器访问:
http://容器宿主机IP/wordpress

配置wordpress博客:

9、dockerfile实践心行

  • 谨慎选择基础镜像
     选择基础镜像时,尽量选择当前官方镜像库中的镜像。

  • 充分利用缓存
     Docker daemon会顺序执行Dockerfile中的指令,而且一旦缓存失效,后续命令将不能使用缓存。为了有效地利用缓存,需要保证指令的连续性,尽量将所有Dockerfile文件中相同的部分都放在前面,而将不同的部分放在后面。

  • 正确使用ADD和COPY指令
     尽管ADD和COPY用法和作用很相近,但COPY仍是首选。COPY相对ADD而言,功能简单够用。

  • RUN指令易读
     为了使Dockerfile易读、易理解和可维护,在使用比较长的RUN指令时可以使用反斜杠\ 分隔多行。

  • 不要在Dockerfile中做端口映射
     Docker的两个核心概念是可重复性和可移植性,镜像应该可以在任何主机上运行多次。使用Dockerfile的EXPOSE指令,虽然可以将容器端口映射到主机端口上,但会破坏Docker的可移植性,且这样的镜像在一台主机上只能启动一个容器。所以端口映射应在docker run 命令中用-p 参数指定。

 #不要在Dockerfile中做如下映射
 EXPOSE 80:8080

 #仅仅暴露80端口,需要另做映射
 EXPOSE 80

 
https://blog.51cto.com/ganbing/2074640

docker:Dockerfile构建LNMP平台的更多相关文章

  1. 十九.部署LNMP环境、构建LNMP平台、地址重写

    proxy client web1 web2   1.部署LNMP环境 1.1 部署nginx(前面已部署过) 1.2 部署mariadb ]# yum -y install mariadb mari ...

  2. 高级运维(三):部署Lnmp环境、构建Lnmp平台、地址重写

    一.部署LNMP环境 目标: 安装部署Nginx.MariaDB.PHP环境 1> 安装部署Nginx.MariaDB.PHP.PHP-FPM: 2> 启动Nginx.MariaDB.FP ...

  3. 基于Docker&Kubernetes构建PaaS平台基础知识梳理

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 基于Docker&Kubernetes构建Paa ...

  4. Docker | dockerfile构建centos镜像,以及CMD和ENTRYPOINT的区别

    构建自己的centos镜像 docker pull centos下载下来的镜像都是基础版本,缺少很多常用的命令功能,比如:ll.vim等等, 下面介绍制作一个功能较全的自己的centos镜像. 步骤 ...

  5. docker dockerfile构建自己的tomcat镜像

    文件 1.apache-tomcat-8.5.24.tar.gz, jdk-8u151-linux-x64.tar.gz Dockerfile文件: FROM centosWORKDIR /usrCO ...

  6. 构建LNMP平台

    1方案 安装部署Nginx.MariaDB.PHP环境 安装部署Nginx.MariaDB.PHP.PHP-FPM: 启动Nginx.MariaDB.FPM服务: LNMP(Linux.Nginx.M ...

  7. Docker Buildx使用教程:使用Buildx构建多平台镜像

    写在前边 记录一下前阵子在X86_64平台使用Docker Buildx构建多平台镜像的办法,包含但不限于构建ARM镜像. 构建环境 软件名 版本 Ubuntu 18.04.2 LTS Docker ...

  8. 构建LNMP

                                                                             构建LNMP 案例1:部署LNMP环境 案例2:构建L ...

  9. Docker进阶之九:Dockerfile 及 通过Dockerfile搭建lnmp

    一.Dockerfile指令 指令 描述 指令 描述 FROM 构建的新镜像是基于哪个镜像 例如:FROM centos:6 COPY 拷贝文件或目录到镜像,用法同上例如:COPY ./start.s ...

随机推荐

  1. 课外知识----easy BCD

    可以用来作系统之间的切换 使用方法略

  2. js中typeof与instanceof用法小记

    今天写JS代码,遇到动态生成多个名称相同的input复选按钮 需要判断其是否是数组,用到了if (typeof(document.MapCheckMgr.checkid)!="undefin ...

  3. ethereum/EIPs-155 Simple replay attack protection 35,36

    EIP 155:重放攻击保护——防止了在一个以太坊链上的交易被重复广播到另外一条链. 在看椭圆曲线时有提到,与r.s.v中的v相关 不同的共有链定义不同的chainId, 防止同一笔交易在不同的共有链 ...

  4. [转]Qt状态栏(statusbar)的使用

    状态栏显示的信息分3种 1. 一般信息,用QLabel 代表 2. 永久信息,文本会一直显示在状态栏的最右边. 3. 临时信息,指定信息现实的时间.时间到即信息消失 QLabel *locationL ...

  5. Python Tornado集成JSON Web Token方式登录

    本项目github地址 前端测试模板如下: Tornado restful api 项目 项目结构如下: 项目组织类似于django,由独立的app模块构成. 登录接口设计 模式:post -> ...

  6. SkylineGlobe API 如何以图层的方式导入MPT地形

    测试环境:TerraExplorer Pro 6.6; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&qu ...

  7. Redis详解(六)------ RDB 持久化

     前面我们说过,Redis 相对于 Memcache 等其他的缓存产品,有一个比较明显的优势就是 Redis 不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,has ...

  8. 微信小程序开发需要注意的30个坑

    1.小程序名称可以由中文.数字.英文.长度在3-20个字符之间,一个中文字等于2个字符. 2.小程序名称不得与公众平台已有的订阅号.服务号重复.如提示重名,请更换名称进行设置. 3.小程序名称在帐号信 ...

  9. C#winform中调用wpf

    原文:C#winform中调用wpf 在WinForm中是可以使用WPF中的控件(或者由WPF创建的自定义控件) 1.新建一个winform项目: 2.在解决方案上新建一个wpf项目: 如图: 如果有 ...

  10. Ubuntu 安装google chrome

    sudo apt-get install google-chrome-stable /usr/bin/google-chrome-stable