Docker部署PHP+Nginx环境
0x00 序言
最近一直在学习容器相关的应用,决定把用的非常频繁的Nginx和PHP环境利用容器(Docker)的方式完成部署,最终实现无需考虑宿主机环境,构建PHP应用的运行环境。
之所以没有将数据库应用如Mysql或者MariaDB也用部署到相同的环境,是因为考虑到目前上云应用的解耦问题,计算资源和存储资源应当分离,就算需要用容器部署数据库服务,也应该在独立的环境中。
对于PHP应用来说,计算资源是作为Web服务的Nginx和运算服务的PHP-FPM,存储资源是各项数据,所以我将Nginx和PHP-FPM以容器的方式部署,数据库和UPLOAD数据单独部署或者利用云数据和云对象存储实现,即可增强应用的扩展性,实现动态扩容等操作。
我以CentOS7宿主机为例,部署PHP应用的运行环境。
注:本文所涉及宿主机命令,默认以root
用户执行。
0x01 Docker
对于部分云主机来说,已经自带了Docker的源,直接通过命令
1 | yum install docker-io |
或者
1 | apt install docker.io |
即可完成Docker引擎和客户端的安装
安装后记得启动Docker并设置为开机服务
1 | systemctl start docker |
如果上述命令提示未找到相关软件包,可通过Docker官方的安装方式,添加软件源并安装,以CentOS为例:
- 卸载旧版Docker(如果存在)
1 | yum remove docker \ |
- 安装
yum-utils
并设置Docker源
1 | yum install -y yum-utils |
- 安装Docker引擎
1 | yum install docker-ce docker-ce-cli containerd.io |
- 启动Docker引擎并设置为开机服务
1 | systemctl start docker |
到这里Docker引擎应该就安装成功了
可以通过命令
1 | docker version |
查看是否成功运行,也可以通过
1 | docker run hello-world |
启动一个HelloWorld的Docker容器。
其他系统的安装可以参考官方文档Install Docker Engine | Docker Documentation
0x02 PHP-FPM
Docker引擎准备就绪之后就可以部署PHP站点的运行环境了,那就是PHP-FPM,本文使用PHP7.4环境下的PHP-FPM,更多镜像可以查看php官方Docker Hub
- 从官方拉取PHP-FPM镜像
1 | docker pull php:7.4-fpm |
- 启动PHP-FPM
1 | docker run -v [app_path]:/www/[app_name] --name php-fpm -d php:7.4-fpm |
该命令表示以php-fpm
为名字,挂载[app_path]
到容器的/www/[app_name]
路径,在后台启动一台php:7.4-fpm
的容器
其中[app_path]
为宿主机下的应用路径,建议可以在宿主机上建议一个www
目录,用于存放所有的应用,这样的话,在有新的应用需要部署的时候,就不用因为修改映射而重新启动容器,所以可以直接写为
1 | docker run -v /www/:/www/ --name php-fpm -d php:7.4-fpm |
这样的话PHP-FPM容器就已经启动好了,我们可以在宿主机的/www/
路径下放置我们的应用程序
- (可选)安装Composer
部分PHP应用可能会用到Composer,我们需要进入容器中安装Composer
1 | docker exec -it php-fpm /bin/bash |
该命令表示在php-fpm容器中运行bash,开启一个终端,开启后我们在终端中安装Composer
1 | apt update |
部分Composer组件需要从Git安装,可以在容器内安装Git
1 | apt install -y git |
如此一来就可以直接在容器中执行composer命令了,如果应用需要,直接进入/www/[app_name]
路径,执行composer install
等命令即可。
Composer主要为composer.phar文件,也可以手动下载,可以参考Composer官方下载指引Composer (getcomposer.org)
到这里php-fpm就已经部署完毕了
- Tips
在部署应用中可能会遇到php返回500等权限问题,建议在容器中进入应用路径,将应用文件的所有者修改为www-data
1 | docker exec -it php-fpm /bin/bash |
0x03 Nginx
在开发环境或者单机生产环境下,Nginx不存在横向扩容,使用效果与直接安装Nginx类似,但使用容器来安装Nginx对于应用未来的扩展性会更好
- 从官方拉取Nginx镜像
1 | docker pull nginx |
该命令默认会拉取tag为latest的Nginx镜像,官方维护的latest镜像通常为最新版本,默认使用最新版即可
- 准备Nginx配置文件
在启动Nginx服务之前,我们需要提前写好Nginx的配置文件,建议新建一个目录用于存放Nginx配置
1 | mkdir /etc/nginx |
这里给出一份我配置的PHP应用的站点配置
1 | server { |
该配置文件中存在三个参数需要自己填写
站点域名server_name
站点根目录root
,这里的根目录为后续映射到容器内的应用路径,且需要与PHP-FPM内路径一致,否则该配置需要修改
PHP-FPM容器的IP地址php-fpm_ip
,该IP地址可以通过命令docker inspect php-fpm
查看php-fpm
容器的元数据,找到IPAddress这项,填入即可,通常为172.17.0.x
- 启动Nginx容器
在Nginx镜像就绪之后,我们就需要启动一台Nginx容器来运行服务
1 | docker run -v [conf_path]:/etc/nginx/conf.d/ \ |
这行命令表示启动一台名为nginx的Nginx容器,并将宿主机的80端口映射到容器的80端口,并且将宿主机的[conf_path]
挂载到容器的/etc/nginx/conf.d/
,将宿主机的[app_path]
挂载到容器的[app_path]
中
该命令的两个参数
conf_path
可以为我上述建议的新建的Nginx配置目录/etc/nginx/
[app_path]
为站点文件的路径,可以与php-fpm
的部署建议一样,将www
路径统一映射进去,即写为
1 | docker run -v /etc/nginx/:/etc/nginx/conf.d/ \ |
如此一来,PHP+Nginx的运行环境便已经部署完毕
0x04 Tips
在部署和使用过程中如果出现异常,可以善用
docker logs -f
命令查看两个容器的日志信息,根据日志信息定位相应问题并修复如果调整了配置文件,可以通过
docker restart nginx
重启Nginx容器,PHP-FPM同理对于Laravel应用来说,php官方镜像没有带zip扩展和pdo_mysql扩展,需要手动进入容器安装
1 | docker exec -it php-fpm /bin/bash |
- 有时候php扩展和一些程序不生效,可以进入php-fpm容器,重写php.ini
1 | docker exec -it php-fpm /bin/bash |