介绍
介绍
前面福哥已经教给大家使用Dockerfile安装各种服务器软件的方法了,今天福哥要带着大家把TFLinux服务器上的软件都转移到Docker容器里面。使用Docker容器搭建服务器环境是现如今部署服务器环境的主流方式,福哥顺应潮流将Docker这种部署方式教给大家,活到老学到老嘛~~
这次福哥整理的是PHP+FPM+Nginx环境,因为docker-compose不支持PHP+apache的组合,所以福哥不得不改用PHP+FPM组合搭建PHP环境了,PHP+FPM是不能单独提供web服务的,这里福哥使用Nginx作为web服务器软件。
FastCGI
PHP+FPM就是以FastCGI模式运行PHP的模式,FPM模式是以进程的方式运行PHP的,在早期的PHP时代进程运行PHP是一个很low的做法,大家更推崇线程方式运行PHP,作为Apache模块运行PHP一直是主流的运行PHP的方式。
直到PHP5.4开始,FastCGI模式运行PHP逐渐展露了头角,PHP-FPM解决了之前的诸如内存占用过多、进程过多等等问题,这使得PHP官方承认了FastCGI模式运行PHP,慢慢的这种方式也被广大PHPer们接收了。
PHP+FPM+Nginx的组合是一种“动静分离”的部署方式,PHP+FPM负责动态程序,Nginx负责静态页面。
PHP
直接部署
直接部署的方式采用的是PHP+Apache的组合,Apache是以模块方式运行PHP程序的,Apache会根据指定的扩展名调用PHP解析器对PHP程序进行解析执行,而非PHP程序的资源文件Apache会原汁原味地将其直接展示出来。
这种情况下,我们只需要安装PHP和Apache就可以了,项目也不需要区分PHP程序和资源文件。
Docker部署
通过PHP+FPM+Nginx的组合就需要把PHP程序的解析工作交给FPM来完成,而资源文件则交给Nginx来处理。
PHP+FPM是一个镜像,Nginx又是另外一个镜像,所以PHP+FPM+Nginx的组合就是两个镜像的配合运行的模式。
Dockerfile
因为PHP+FPM也会占用一个端口,后面的Nginx也会占用一个端口,为了避免端口冲突问题,福哥设计的端口分配规则如下:
PHP+FPM:tfphp(8168),tfums(8170)。
Nginx:默认(8080),tfphp(8068),tfums(8070)。
tfphp.conf
[tfphp] user = www-data group = www-data listen = 8168 pm = dynamic pm.max_children = 5 pm.start_servers = 1 pm.min_spare_servers = 1 pm.max_spare_servers = 3 catch_workers_output = yes access.log = /var/log/php/tfphp-access.log
tfums.conf
[tfums] user = www-data group = www-data listen = 8170 pm = dynamic pm.max_children = 5 pm.start_servers = 1 pm.min_spare_servers = 1 pm.max_spare_servers = 3 catch_workers_output = yes access.log = /var/log/php/tfums-access.log
Dockerfile
这里面福哥就是把tfphp.conf和tfums.conf导入到镜像里面了。
FROM php:7.4-fpm-buster MAINTAINER Andy Bogate MAINTAINER tongfu@tongfu.net MAINTAINER https://tongfu.net/dockerfile MAINTAINER 2021/5/26 MAINTAINER v1.0.0 EXPOSE 8168 8170 WORKDIR /tongfu.net/web # local mirror RUN sed -i 's/deb.debian.org/ftp.cn.debian.org/g' /etc/apt/sources.list \ && sed -i 's/security.debian.org/ftp.cn.debian.org/g' /etc/apt/sources.list # timezone RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo 'Asia/Shanghai' >/etc/timezone # env RUN apt-get update \ && apt-get -y install wget libwebp-dev libjpeg-dev libpng-dev libfreetype6-dev libc-client-dev libkrb5-dev libzip-dev # source extract RUN docker-php-source extract # package build RUN mkdir /packages # gd extension RUN docker-php-ext-configure gd \ --with-jpeg=/usr/include \ --with-freetype=/usr/include/ \ && docker-php-ext-install gd \ && docker-php-ext-enable gd # mysql extension RUN docker-php-ext-install pdo_mysql \ && docker-php-ext-enable pdo_mysql # redis extension RUN cd /packages \ && wget http://pecl.php.net/get/redis-4.1.0.tgz \ && tar -xzvf redis-4.1.0.tgz \ && cd redis-4.1.0 \ && /usr/local/bin/phpize \ && ./configure --with-php-config=/usr/local/bin/php-config \ && make && make install \ && cd ../ \ && docker-php-ext-enable redis # imap extension RUN docker-php-ext-configure imap \ --with-kerberos \ --with-imap-ssl \ && docker-php-ext-install imap \ && docker-php-ext-enable imap # zlib extension RUN mv /usr/src/php/ext/zlib/config0.m4 /usr/src/php/ext/zlib/config.m4 \ && docker-php-ext-install zlib \ && docker-php-ext-enable zlib # mongodb extension RUN cd /packages \ && wget http://pecl.php.net/get/mongodb-1.7.4.tgz \ && tar -xzvf mongodb-1.7.4.tgz \ && cd mongodb-1.7.4 \ && /usr/local/bin/phpize \ && ./configure --with-php-config=/usr/local/bin/php-config \ && make && make install \ && cd ../ \ && docker-php-ext-enable mongodb # confiugure RUN cd /usr/local/etc/php \ && cp php.ini-production php.ini \ && sed -i 's/display_errors\s*=.*/display_errors = Off/' php.ini \ && sed -i 's/error_reporting\s*=.*/error_reporting = E_ALL \& ~E_NOTICE \& ~E_STRICT \& ~E_DEPRECATED/' php.ini \ && sed -i 's/;error_log\s*=\s*php_errors\.log/error_log = \/var\/log\/php\/php_errors.log/' php.ini \ && sed -i 's/;date\.timezone\s*=.*/date.timezone = Asia\/Shanghai/' php.ini # package delete RUN rm -rf /packages # source delete RUN docker-php-source delete # config RUN mkdir /var/log/php \ && cd /usr/local/etc/ \ && sed -i 's/;error_log\s*=.*/error_log = \/var\/log\/php\/php-fpm.log/' php-fpm.conf \ && sed -i 's/;daemonize\s*=.*/daemonize = no/' php-fpm.conf \ && rm -f php-fpm.d/docker.conf \ && rm -f php-fpm.d/zz-docker.conf \ && rm -f php-fpm.d/www.conf \ && rm -f php-fpm.d/www.conf.default ADD tfphp.conf /usr/local/etc/php-fpm.d/tfphp.conf ADD tfums.conf /usr/local/etc/php-fpm.d/tfums.conf
Nginx
Dockerfile
要使用nginx去实现apache的rewrite功能还是挺复杂的,nginx配置语法不仅仅没有RewriteCond/RewriteRule的功能,而且nginx配置语法还不支持与(&&)或(||)的语法。
为了实现apache的rewrite功能,福哥建立了$conds辅助变量功能解决与(&&)或(||)的语法问题。
default.conf
server { listen 8080; listen [::]:8080; server_name localhost; location / { root /tongfu.net/web; index index.html index.htm; } }
tfphp.conf
server { listen 8068; listen [::]:8068; server_name localhost; # WEB-INF is forbidden if ( $uri ~ ^\/WEB\-INF\/ ) { return 403; } # condition except extension set $conds "1"; if ( $uri !~* \.(js|css|map|jpg|jpeg|pjpeg|png|gif|txt|ico)$ ) { set $conds "${conds}1"; } # condition except ueditor if ( $uri !~ ^\/ue\/ ) { set $conds "${conds}1"; } # condition except route func and server func if ( $uri !~ (TFRouteMap\.php|server\-status|server\-info)$ ) { set $conds "${conds}1"; } # route map if ( $conds = "1111" ) { rewrite ^\/(.*)$ /TFRouteMap.php; } # all requests location to root location / { root /tongfu.net/web/TFPHP; index index.html index.htm; } # all requests of PHP script location to fastcgi location ~ \.php$ { client_body_buffer_size 1m; root /tongfu.net/web/TFPHP; fastcgi_pass 10.16.1.1:8168; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
tfums.conf
server { listen 8070; listen [::]:8070; server_name localhost; # WEB-INF is forbidden if ( $uri ~ ^\/WEB\-INF\/ ) { return 403; } # condition except extension set $conds "1"; if ( $uri !~* \.(js|css|map|jpg|jpeg|pjpeg|png|gif|txt|ico)$ ) { set $conds "${conds}1"; } # condition except ueditor if ( $uri !~ ^\/ue\/ ) { set $conds "${conds}1"; } # condition except route func and server func if ( $uri !~ (TFRouteMap\.php|server\-status|server\-info)$ ) { set $conds "${conds}1"; } # route map if ( $conds = "1111" ) { rewrite ^\/(.*)$ /TFRouteMap.php; } # all requests location to root location / { root /tongfu.net/web/TFUMS; index index.html index.htm; } # all requests of PHP script location to fastcgi location ~ \.php$ { client_body_buffer_size 1m; root /tongfu.net/web/TFUMS; fastcgi_pass 10.16.1.1:8170; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
Dockerfile
FROM nginx:1.20 MAINTAINER Andy Bogate MAINTAINER tongfu@tongfu.net MAINTAINER https://tongfu.net/dockerfile MAINTAINER 2021/5/26 MAINTAINER v1.0.0 EXPOSE 8068 8070 # local mirror RUN sed -i 's/deb.debian.org/ftp.cn.debian.org/g' /etc/apt/sources.list \ && sed -i 's/security.debian.org/ftp.cn.debian.org/g' /etc/apt/sources.list # timezone RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \ && echo 'Asia/Shanghai' >/etc/timezone # config RUN rm -f /var/log/nginx/access.log \ && rm -f /var/log/nginx/error.log ADD default.conf /etc/nginx/conf.d/default.conf ADD tfphp.conf /etc/nginx/conf.d/tfphp.conf ADD tfums.conf /etc/nginx/conf.d/tfums.conf
测试
创建镜像
PHP+FPM
docker build -f Dockerfile -t tflinux-php-fpm7.4 ./
PHP+Nginx
docker build -f Dockerfile -t tflinux-php-nginx7.4 ./
启动容器
启动PHP+FPM
docker run -tid \ --name tflinux-php-fpm7.4 \ -h tflinux-php-fpm7.4 \ -p 10.16.1.1:8168:8168 \ -p 10.16.1.1:8170:8170 \ -v /tongfu.net/web/TFPHP/:/tongfu.net/web/TFPHP/ \ -v /tongfu.net/web/TFUMS/:/tongfu.net/web/TFUMS/ \ tflinux-php-fpm7.4
启动PHP+Nginx
docker run -tid \ --name tflinux-php-nginx7.4 \ -h tflinux-php-nginx7.4 \ -p 10.16.1.1:8080:8080 \ -p 10.16.1.1:8068:8068 \ -p 10.16.1.1:8070:8070 \ -v /tongfu.net/web/TFPHP/:/tongfu.net/web/TFPHP/ \ -v /tongfu.net/web/TFUMS/:/tongfu.net/web/TFUMS/ \ tflinux-php-nginx7.4
测试
一起就绪了,打开浏览器看看吧~~
总结
今天福哥带着童鞋们将之前学习的使用Dockerfile搭建各种服务器软件的技巧综合了一下,使用这些技巧将我们的TFLinux服务器上面直接部署的PHP、Apache转移到了Docker里面,利用Docker的数据卷映射技术将我们的TFPHP、TFUMS项目的程序部署到了容器里面。
这一课的内容牵扯到的问题很多,福哥将在后面的课程里面一一给大家详细讲解!
使用PHP+FPM+Nginx的组合部署PHP运行环境和PHP+Apache的组合部署有一些区别,我们的TFPHP框架的路由模块需要针对新环境进行适配才能正常运行,下一课福哥将会针对这个问题给大家讲解一下,敬请期待~~