2021Docker容器技术全解-使用Dockerfile打包Nginx+php镜像(6)
Dockerfile语法:
MAINTAINER:镜像创建者信息
EXPOSE:开放的端口
ENV:设置变量
WORKDIR:定义容器默认工作目录,相当于cd到某个目录
CMD:容器启动时执行的命令,仅可以有一条CMD
一,在m01虚拟机中的准备工作-使用dockerfile自定义镜像Nginx+php
1先在容器内手动安装阿帕奇:
#1进入容器 [root@web01 ~]#docker run -it mycentos8:v20211229 #2安装阿帕奇 [root@e81ffc0059aa /]# yum -y install httpd #3查看启动文件看看阿帕奇是如何启动的 [root@e81ffc0059aa ~]# cat /lib/systemd/system/httpd.service [Unit] Description=The Apache HTTP Server Wants=httpd-init.service After=network.target remote-fs.target nss-lookup.target httpd-init.service Documentation=man:httpd.service(8) [Service] Type=notify #环境变量 Environment=LANG=C #执行启动命令 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND ExecReload=/usr/sbin/httpd $OPTIONS -k graceful # Send SIGWINCH for graceful stop KillSignal=SIGWINCH KillMode=mixed PrivateTmp=true [Install] WantedBy=multi-user.target [root@e81ffc0059aa ~]# 4启动阿帕奇 [root@e81ffc0059aa ~]# LANG=C [root@e81ffc0059aa ~]# /usr/sbin/httpd $OPTIONS -k graceful AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message httpd not running, trying to start [root@e81ffc0059aa ~]# /usr/sbin/httpd $OPTIONS -DFOREGROUND AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message httpd (pid 73) already running #查看执行历史 [root@e81ffc0059aa ~]# history 19 yum -y install httpd 20 systemctl start httpd 21 pstree -p 27 cat /lib/systemd/system/httpd.service 28 LANG=C 30 /usr/sbin/httpd $OPTIONS -DFOREGROUND [root@e81ffc0059aa ~]#
2编写dockerfile:
[root@web01 ~]#mkdir bb [root@web01 ~]#cd bb [root@web01 ~/bb]#touch Dockerfile [root@web01 ~/bb]#vim Dockerfile [root@web01 ~/bb]#cat Dockerfile FROM mycentos8:v20211229 RUN yum -y install httpd ENV LANG=C #指定开放的端口 EXPOSE 80 443 #设置默认的工作目录 WORKDIR /var/www/html #拷贝文件到指定目录 ADD index.html /var/www/html/index.html #cmd特定语法格式例如ls -la: CMD ["ls","-l","-a"] CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
3创建html文件
[root@web01 ~/bb]#vim index.html [root@web01 ~/bb]#pwd /root/bb
4执行dockerfile创建阿帕奇服务镜像
[root@web01 ~/bb]#docker build -t mycentos8:httpd .
5基于镜像构建容器:
[root@web01 ~/bb]#docker run --name httpd -d -p 80:80 mycentos8:httpd
6验证:
#查看容器 [root@web01 ~/bb]#docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f8361cb098b0 mycentos8:httpd "/usr/sbin/httpd -DF…" 5 seconds ago Up 4 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp, 443/tcp httpd #查看容器详细信息 [root@web01 ~/bb]#docker inspect f8361cb098b0 "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", #模拟浏览器访问 [root@web01 ~/bb]#curl 172.17.0.2 hello world!
制作一个nginx+php的镜像
制作思路:
1在虚拟机中手工安装所有服务(yum+编译) 解决方案:记录所有程序运行的"依赖包" 2验证配置,打包安装路径 解决方案:把编译好的软件直接放入容器内 在虚拟机里编译安装软件,然后对软件安装后的文件夹进行打包, 3多服务 解决方案:启动脚本 dockerfile的cmd只能启动一条命令,那么我们通过启动一个脚本即可实现启动很多命令
1清除历史命令:
[root@m01 ~]#history -c [root@m01 ~]#history -w [root@m01 ~]#
2上传nginx软件包安装依赖环境:
[root@m01 ~]#ls anaconda-ks.cfg nginx-1.20.1.tar.gz [root@m01 ~]#yum install gcc make pcre-devel openssl-devel -y
3安装php后端执行环境需要用到的四个软件包以及后面需要用到的压缩文件
[root@m01 ~]#yum install pcre openssl php php-fpm bzip2 -y
4添加nginx用户:
[root@m01 ~]#useradd nginx
5编译安装nginx
[root@m01 ~]#tar xf nginx-1.20.1.tar.gz [root@m01 ~]#cd nginx-1.20.1/ [root@m01 ~/nginx-1.20.1]#./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module [root@m01 ~/nginx-1.20.1]#make && make install
6修改nginx配置文件让nginx支持php(把下面的注释取消)
[root@m01 ~/nginx-1.20.1]#vim /usr/local/nginx/conf/nginx.conf location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #include fastcgi_params; #注释掉 include fastcgi.conf; #新添加 }
7手工启动php
1)查看php启动文件查看启动命令:
[root@m01 /user/local/nginx]#cat /lib/systemd/system/php-fpm.service # It's not recommended to modify this file in-place, because it # will be overwritten during upgrades. If you want to customize, # the best way is to use the "systemctl edit" command. [Unit] Description=The PHP FastCGI Process Manager After=syslog.target network.target [Service] Type=notify #--nodaemonize &表示放后台运行 ExecStart=/usr/sbin/php-fpm --nodaemonize #--nodaemonize表示放前台运行 ExecReload=/bin/kill -USR2 $MAINPID PrivateTmp=true RuntimeDirectory=php-fpm RuntimeDirectoryMode=0755 [Install] WantedBy=multi-user.target
2)启动php
#启动 [root@m01 /usr/local/nginx/conf]#/usr/sbin/php-fpm --nodaemonize & [1] 16905 [root@m01 /usr/local/nginx/conf]#[30-Dec-2021 09:19:42] ERROR: unable to bind listening socket for address '/run/php-fpm/www.sock': No such file or directory (2) [30-Dec-2021 09:19:42] ERROR: FPM initialization failed ^C [1]+ 退出 78 /usr/sbin/php-fpm --nodaemonize #解决报错 [root@m01 /usr/local/nginx/conf]#mkdir -p /run/php-fpm/ #启动 [root@m01 /usr/local/nginx/conf]#/usr/sbin/php-fpm --nodaemonize & [1] 16907 [root@m01 /usr/local/nginx/conf]#[30-Dec-2021 09:20:09] NOTICE: fpm is running, pid 16907 [30-Dec-2021 09:20:09] NOTICE: ready to handle connections [30-Dec-2021 09:20:09] NOTICE: systemd monitor interval set to 10000ms #查看运行端口 [root@m01 /usr/local/nginx/conf]#ss -ltun
3)检查php端口(最后发现走的是socket模式)
[root@m01 /usr/local/nginx/conf]#netstat -ntulp |grep 9000 [root@m01 /usr/local/nginx/conf]#ss -lntup |grep php [root@m01 /usr/local/nginx/conf]#find / -name www.conf /etc/php-fpm.d/www.conf [root@m01 /usr/local/nginx/conf]#cat /etc/php-fpm.d/www.conf |egrep -v ";" [www] user = apache group = apache listen = /run/php-fpm/www.sock listen.acl_users = apache,nginx listen.allowed_clients = 127.0.0.1 pm = dynamic pm.max_children = 50 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 35 slowlog = /var/log/php-fpm/www-slow.log php_admin_value[error_log] = /var/log/php-fpm/www-error.log php_admin_flag[log_errors] = on php_value[session.save_handler] = files php_value[session.save_path] = /var/lib/php/session php_value[soap.wsdl_cache_dir] = /var/lib/php/wsdlcache
4)启动nginx
[root@m01 /usr/local/nginx]#/usr/local/nginx/sbin/nginx [root@m01 /usr/local/nginx]#ps -ef|grep nginx root 16990 1 0 09:51 ? 00:00:00 nginx: master process /usr/local/nginx/sbin/nginx nginx 16991 16990 0 09:51 ? 00:00:00 nginx: worker process root 16993 1706 0 09:51 pts/0 00:00:00 grep --color=auto nginx
5)验证nginx是否已经解析php了(报错):
#1先写个php信息函数 [root@m01 /usr/local/nginx/html]#ls 50x.html index.html [root@m01 /usr/local/nginx/html]#vim info.php <?PHP phpinfo(); ?> #2模拟浏览器 curl http://127.0.0.1 #正常 curl http://127.0.0.1/info.php #不能访问 也就是说:nginx配置出问题了
6)修改nginx配置
[root@m01 /usr/local/nginx/conf]#cat nginx.conf location ~ \.php$ { root html; fastcgi_pass unix:/run/php-fpm/www.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
7)重启nginx访问测试正常
[root@m01 /usr/local/nginx/conf]#/usr/local/nginx/sbin/nginx -s reload curl http://127.0.0.1/info.php #访问正常
8停掉nginx并删掉没用的目录
#停掉nginx [root@m01 /usr/local/nginx/conf]#/usr/local/nginx/sbin/nginx -s stop [root@m01 /usr/local/nginx/conf]#ss -lntup #删掉没用的目录 [root@m01 /usr/local/nginx]#ls client_body_temp conf fastcgi_temp html logs proxy_temp sbin scgi_temp uwsgi_temp [root@m01 /usr/local/nginx]#rmdir *_temp #剩下的就是编译前原本的目录: [root@m01 /usr/local/nginx]#ls conf html logs sbin
9对nginx目录进行打包:
#安装打包文件 [root@m01 /usr/local/nginx]#yum install bzip2 -y #打包bzip2文件 [root@m01 /usr/local/nginx]#cd ../ [root@m01 /usr/local]#tar -cjf nginx.tar.bz2 nginx [root@m01 /usr/local]#ls bin etc games include lib lib64 libexec nginx nginx.tar.bz2 sbin share src
10把打包文件拷贝到web01上;
[root@m01 /usr/local]#scp nginx.tar.bz2 10.0.0.7:./
11查看历史命令看看安装nginx的全部过程:
[root@m01 /usr/local]#history 1 history -w 2 rz 3 ls 4 yum install gcc make pcre-devel openssl-devel -y 5 yum install pcre openssl php php-fpm -y 6 useradd nginx 7 ls 8 tar xf nginx-1.20.1.tar.gz 9 cd nginx-1.20.1/ 10 ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module 11 make && make install 12 cd /usr/local/nginx 13 ls 14 cd conf 15 ls 16 vim nginx.conf 17 cat /lib/systemd/system/php-fpm.service 18 /usr/sbin/php-fpm --nodaemonize & 19 mkdir -p /var/run/ 20 /usr/sbin/php-fpm --nodaemonize & 21 mkdir -p /run/php-fpm/ 22 /usr/sbin/php-fpm --nodaemonize & 23 ss -ltun 24 lsof -i:9000 25 /usr/sbin/php-fpm --nodaemonize & 26 curl 127.0.0.1:9000 27 cat /usr/local/nginx/conf/nginx.conf 28 ls 29 cat fastcgi.conf 30 ps -ef|grep php=fpm 31 ps -ef|grep php-fpm 32 netstat -ntulp |grep 80 33 netstat -ntulp |grep 9000 34 netstat -ntulp |grep 22 35 ss -lntup |grep php 36 rpm -qa |grep php 37 find / -name www.conf 38 cat /etc/php-fpm.d/www.conf 39 cat /etc/php-fpm.d/www.conf |grep -v ; 40 cat /etc/php-fpm.d/www.conf |grep -v ^; 41 cat /etc/php-fpm.d/www.conf |grep "^\s*[^# \t].*$" 42 cat /etc/php-fpm.d/www.conf |egrep -v "^\s*[^# \t].*$" 43 cat /etc/php-fpm.d/www.conf |egrep -v ";" 44 netstat -ntulp |grep 9000 45 ss -lntup |grep php 46 find / -name www.conf 47 ls 48 cd ../ 49 ls 50 pwd 51 /usr/local/nginx/sbin/nginx 52 ps -ef|grep nginx 53 ls 54 cd html 55 ls 56 vim info.php 57 curl http://127.0.0.1 58 curl http://127.0.0.1/info.php 59 vim info.php 60 cd ../ 61 cd conf 62 ls 63 vim nginx.conf 64 nginx -s reload 65 /bin/kill -USR2 $MAINPID 66 /usr/local/nginx/sbin/nginx -s reload 67 curl http://127.0.0.1/info.php 68 vim nginx.conf 69 curl http://127.0.0.1/info.php 70 /usr/local/nginx/sbin/nginx -s reload 71 curl http://127.0.0.1/info.php 72 vim nginx.conf 73 /usr/local/nginx/sbin/nginx -s reload 74 curl http://127.0.0.1/info.php 75 vim nginx.conf 76 /usr/local/nginx/sbin/nginx -s reload 77 curl http://127.0.0.1/info.php 78 curl http://127.0.0.1 79 curl http://127.0.0.1/info.php 80 vim nginx.conf 81 /usr/local/nginx/sbin/nginx -s reload 82 vim nginx.conf 83 /usr/local/nginx/sbin/nginx -t 84 /usr/local/nginx/sbin/nginx -s reload 85 curl http://127.0.0.1/info.php 86 cat nginx.conf 87 /usr/local/nginx/sbin/nginx -s stop 88 ss -lntup 89 cd ../ 90 ls 91 rmdir *_temp 92 ls 93 yum install bzip2 94 cd ../ 95 tar -cjf nginx.tar.bz2 nginx 96 ls 97 scp nginx.tar.bz2 10.0.0.7:./ 98 history [root@m01 /usr/local]#
至此前期的准备工作到这里为止就准备好了!
但由于上面的过程中出现了报错和各种试错,步骤很乱,下面开始恢复虚拟机快照从新再走一遍,以便整理出清晰的步骤:
[root@m01 /usr/local]#history 1 history -w 2 rz 3 ls 4 yum install gcc make pcre-devel openssl-devel -y 5 yum install pcre openssl php php-fpm bzip2 -y 6 useradd nginx 7 mkdir -p /run/php-fpm/ 8 tar xf nginx-1.20.1.tar.gz 9 cd nginx-1.20.1/ 10 ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module 11 make && make install 12 vim /usr/local/nginx/conf/nginx.conf 13 cat /lib/systemd/system/php-fpm.service 14 /usr/sbin/php-fpm --nodaemonize & 15 ps -ef|grep php-fpm 16 cat /etc/php-fpm.d/www.conf |egrep -v ";" 17 /usr/local/nginx/sbin/nginx 18 ps -ef|grep nginx 19 cd /usr/local/nginx/html 20 vim info.php 21 curl http://127.0.0.1 22 curl http://127.0.0.1/info.php 23 /usr/local/nginx/sbin/nginx -s stop 24 ps -ef|grep nginx 25 cd /usr/local/nginx 26 ls 27 rmdir *_temp 28 ls 29 cd ../ 30 tar -cjf nginx.tar.bz2 nginx 31 ls 32 scp nginx.tar.bz2 10.0.0.7:./ 33 history [root@m01 /usr/local]#
二,在web02中正式开始-使用dockerfile自定义镜像Nginx+php
1在压缩文件同目录下创建Dockerfile文件编写dockerfile
[root@web01 ~]#ls aa anaconda-ks.cfg bb busybox.tar centos.tar nginx.tar nginx.tar.bz2 redis.tar ubuntu.tar [root@web01 ~]#mkdir cc [root@web01 ~]#mv nginx.tar.bz2 cc/ [root@web01 ~]#cd cc [root@web01 ~/cc]#touch Dockerfile [root@web01 ~/cc]#vim Dockerfile FROM mycentos8:v20211229 RUN yum install -y pcre openssl php php-fpm && useradd nginx && mkdir -p /run/php-fpm/ #把软件包拷贝到指定目录下,ADD会自动解压 ADD nginx.tar.bz2 /usr/local/ #拷贝启动脚本 ADD run.sh /etc/init.d/run.sh #执行启动命令 CMD ["/etc/init.d/run.sh"]
2解释为什么Dockerfile文件只有几步:
因为我们打包好的nginx已经编译过了,所以我们无需再编译了,因此下面编译的这些代码可不要
tar xf nginx-1.20.1.tar.gz 9 cd nginx-1.20.1/ 10 ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module 11 make && make install
又因为我们在打包时已经把nginx配置好了,所以配置文件这段代码也可以不要:
12 vim /usr/local/nginx/conf/nginx.conf
编写info.php测试文件已经打包的过程也不需要了
20 vim info.php 21 curl http://127.0.0.1 22 curl http://127.0.0.1/info.php 23 /usr/local/nginx/sbin/nginx -s stop 24 ps -ef|grep nginx 25 cd /usr/local/nginx 26 ls 27 rmdir *_temp 28 ls 29 cd ../ 30 tar -cjf nginx.tar.bz2 nginx 31 ls 32 scp nginx.tar.bz2 10.0.0.7:./ 33 history
我们在编译软件包时需要的依赖我们也不需要了,因为我们打包的目录已经编译完毕了
yum install gcc make pcre-devel openssl-devel -y
最后还剩下如下步骤:
useradd nginx
mkdir -p /run/php-fpm/
/usr/sbin/php-fpm --nodaemonize &
3编写dockerfile里需要的启动脚本文件:
注意脚本启动完毕就自动退出了,脚本一退出,服务就终止了,所以编写脚本时要考虑如何让nginx一直运行下去
[root@web01 ~/cc]#vim run.sh [root@web01 ~/cc]#cat run.sh #!/bin/bash useradd nginx mkdir -p /run/php-fpm/ /usr/sbin/php-fpm --nodaemonize & #启动nginx不让nginx随着脚本退出而退出 /usr/local/nginx/sbin/nginx -g "daemon off;" [root@web01 ~/cc]#chmod 755 run.sh
4因为nginx是个服务,所以我们还需要把监听端口加进去:
[root@web01 ~/cc]#vim Dockerfile FROM mycentos8:v20211229 RUN yum install -y pcre openssl php php-fpm && useradd nginx && mkdir -p /run/php-fpm/ #把软件包拷贝到指定目录下,ADD会自动解压 ADD nginx.tar.bz2 /usr/local/ #拷贝启动脚本 ADD run.sh /etc/init.d/run.sh #nginx监听端口 EXPOSE 80 #执行启动命令 CMD ["/etc/init.d/run.sh"]
5测试运行(未打包成功)
[root@web01 ~/cc]#docker build -t mycentos8:nginx .
6修改dockerfile文件:
[root@web01 ~/cc]#cat Dockerfile FROM mycentos8:v20211229 RUN yum install -y pcre openssl php php-fpm && mkdir -p /run/php-fpm/ #把软件包拷贝到指定目录下,ADD会自动解压 ADD nginx.tar.bz2 /usr/local/ #拷贝启动脚本 ADD run.sh /etc/init.d/run.sh #nginx监听端口 EXPOSE 80 #执行启动命令 CMD ["/etc/init.d/run.sh"]
7再次执行打包成功:
[root@web01 ~/cc]#docker build -t mycentos8:nginx . [root@web01 ~/cc]#docker images REPOSITORY TAG IMAGE ID CREATED SIZE mycentos8 nginx c757fb615c03 11 seconds ago 383MB
8测试:
1)启动镜像
#启动镜像 [root@web01 ~/cc]#docker run -itd mycentos8:nginx 4b6f222e1de5ea7880cd89dde9b65dfed0f4f552afadd038e74fbb5324ae757b #进入容器 [root@web01 ~/cc]#docker exec -it 4b6f /bin/bash [root@4b6f222e1de5 /]#
如果容器无法进入可用下列方法进行调试:
[root@web01 ~/cc]#docker run -it mycentos8:nginx /bin/bash [root@2a07190a6dda /]# /etc/init.d/run.sh [30-Dec-2021 04:24:43] NOTICE: fpm is running, pid 20 [30-Dec-2021 04:24:43] NOTICE: ready to handle connections [30-Dec-2021 04:24:43] NOTICE: systemd monitor interval set to 10000ms ^Z [1]+ Stopped /etc/init.d/run.sh [root@2a07190a6dda /]# ss -lntup Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=21,fd=6)) [root@2a07190a6dda /]# cat /etc/init.d/run.sh #!/bin/bash #useradd nginx mkdir -p /run/php-fpm/ /usr/sbin/php-fpm --nodaemonize & #启动nginx不让nginx随着脚本退出而退出 /usr/local/nginx/sbin/nginx -g "daemon off;" #检查这里看看路径是否写错 [root@2a07190a6dda /]#
2)进入容器测试:
[root@web01 ~/cc]#docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4b6f222e1de5 mycentos8:nginx "/etc/init.d/run.sh" 8 minutes ago Up 8 minutes 80/tcp charming_hellman f8361cb098b0 mycentos8:httpd "/usr/sbin/httpd -DF…" 10 hours ago Up 10 hours 0.0.0.0:80->80/tcp, :::80->80/tcp, 443/tcp httpd [root@web01 ~/cc]#docker exec -it 4b6f /bin/bash [root@4b6f222e1de5 /]# ss -lntup Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=9,fd=6)) [root@4b6f222e1de5 /]# cd /usr/local/nginx/html [root@4b6f222e1de5 html]# ls 50x.html index.html info.php [root@4b6f222e1de5 html]# cat info.php <?PHP phpinfo(); ?> [root@4b6f222e1de5 html]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet) RX packets 13 bytes 1006 (1006.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@4b6f222e1de5 html]# exit exit [root@web01 ~/cc]#
3退出容器测试:
[root@web01 ~/cc]#curl http://172.17.0.3 [root@web01 ~/cc]#curl http://172.17.0.3/info.php
至此,双服务镜像nginx+php-fpm就已经做好了
总结:
使用Dockerfile打包Nginx+php镜像: 1编译环境复杂,可以提前做好软件包,不需要再容器里编译
2启动任务多,可以使用脚本,完成所有工作

浙公网安备 33010602011771号