虽说docker非常流行,但是在公司并不用;
今天抽时间大概看了下文档,准备搭建一个PHP运行环境;
文档看起来倒是简单,但是实际搭建却是遇到了不少坑坑;
实践才是实现真理的唯一途径,编程一途真是没有捷径,不动手光看都是假把式;
必须动手,遇到问题解决问题才能更进一步理解和提升自己。
这里我使用MAC系统搭建:
- 安装docker,下载docker安装即可。
https://docs.docker.com/docker-for-mac/install/
安装完成之后查看docker版本
docker --version
LinuxCopy显示如下,表示安装成功:
Docker version 20.10.5, build 55c4c88
- 创建目录,用于存放我们的项目和nginx、php 文件或者路径自己取。
cd ~mkdir mnmp
PHPCopy这里我要着重的说明一下,有的PHP不带php-fpm,与Nginx建立不了链接,通信不成功。比如 使用docker pull php 获取到的是8.xx版本,就不带fpm,这里一定要注意一下
在这里我觉得很有必要解释一下几个名词的概念,不然很多时候就处于一个懵逼的状态,不能深刻理解一些写法的含义。
- 宿主机:也就是自己的电脑。- 容器:我说得直白一点,容器就像是一台虚拟机(实际上不是,是隔离的2个进程),可以是centos\alpine\debian系统的,具体看镜像。- 挂载:宿主机要与容器保持同步文件,我们就需要挂载,在后面你看到的:-v xxxx:xxxx其实就是将宿主机的文件目录对应到容器的某一个目录。这个点极为的重要,不然大家很容易混淆概念。比如在本机的nginx.conf配置到底是配置宿主机还是容器的目录总是搞不清。先理解这个后面一切都会变得简单。
- 获取Nginx镜像,无需后面的版本表示获取最新的版本;
docker pull nginx
PHPCopy- 获取PHP镜像
docker pull php:7.3-fpm
PHPCopy- 启动Nginx
docker run \--name nginx \-p 80:80 \-v ~/mnmp/wwwroots:/data/wwwroots \-v ~/mnmp/nginx/conf:/etc/nginx/conf.d \--privilge=true \-it \-d \nginx
PHPCopy这里解释下各个参数:--name ,容器名称。-p 本地80端口映射到容器80端口-v,可以有多个,而这里,第一个-v,是将宿主机的:~/mnmp/wwwroots挂载到容器的:/data/wwwroots,可以简单理解共享文件,我们在本机的该增加一个文件,容器也就有了这个文件。--privilge=true 使用该参数,container内的root拥有真正的root权限。-it -i 选项指示 docker 要在容器上打开一个标准的输入接口,-t 指示 docker 要创建一个伪 tty 终端,连接容器的标准输入接口,之后用户就可以通过终端进行输入第二个 -v, -v **~/mnmp/nginx/conf:/etc/nginx/conf.d**需要着重的说明一下;大多数文档和教程都是一点不带提示的,直接叫你这样写,但是为什么要这样写?没有一个说明白的。/mnmp/nginx/conf 宿主机的地址,这个是自定义的,用于存放nginx的配置文件;/etc/nginx/conf.d **是容器nginx加载配置的文件目录,这个是容器规定的就在这个目录,nginx运行会自动加载这个目录下的配置。**为什么要配置这一行,我们假设不配置这个,Nginx是不是就启动不了?并不是,想想如果我们如果要增加一个web站点是不是需要配置域名和项目路径,岂不是每次都要到容器上去修改?那不是很麻烦?我们配置之后只需要更改宿主机上的配置容器上就改了是不是很方便。--privilge=true,-it 在前面有一篇文章说过,碰到过很多次容器启动后一闪而逝就自动停止了加上它就能成功启动了。
- 启动PHP
docker run --name php-fpm \-p 9000:9000 \-v ~/mnmp/php/conf:/usr/local/etc/php/conf.d \-v ~/mnmp/wwwroots:/data/wwwroots \--privileged=true \-it \-d \php:7.3-fpm
PHPCopy上面参数经过我们对nginx参数的解释估计大家都理解了,不用说明了。-v ~/mnmp/php/conf:/usr/local/etc/php/conf.d 这里是/usr/local/etc/php/conf.d 就是拓展php.ini配置文件的地方,我们要增加PHP扩展或者其他参数就可以在宿主机~/mnmp/php/conf 修改。
- 查看PHP容器的IP
docker inspect --format='{ { .NetworkSettings.IPAddress}}' php-fpm
PHPCopy为什么要这个IP?上面说了,容器就像是虚拟机,PHP一个容器、nginx一个容器,2个被隔离的容器怎么通讯?第一个方法就是通过参数 --link建立相关的链接,第二个就是用上面的代码获取容器的IP进行通讯;我们在配置nginx的时候会用到。
- 2个容器都运行成功了,我们可以在docker可视化界面看到这2个容器
也可以使用:
docker ps -adocker container ls --all
PHPCopy- nginx建立配置文件,让我们跑起来第一个项目。
server { listen 80; server_name www.test.com; root /data/wwwroots; location / { index index.html index.htm index.php; } location ~ \.php(.*)$ { fastcgi_pass 172.17.0.2:9000; //这个就是我们上面获取到的PHP容器IP地址 fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }}
PHPCopy我觉得root /data/wwwroots; 这里要着重的说明一下,这里配置的一定是容器的地址;
在上面我们运行容器的时候加了-v ~/mnmp/wwwroots:/data/wwwroots 这个参数;
我们只是通过挂载的方式将文件进行共享了,实际nginx 是在容器上执行,那么肯定就是填容器的地址了;
我相信很多朋友就配置错了,而且没有搞清楚到底配置宿主机还是配置容器的?傻傻分不清,看了这篇文章
还分不清就是我的问题。
- 编辑host 文件 加入:127.0.0.1 www.test.com
sudo vim /etc/hosts
PHPCopy- /mnmp/wwwroots 目录增加index.php 并写入phpinfo()
- 看效果
- 这里我就不安装mysql了,因为PHP程序不依赖mysql,我们随便装一个 运行起来就行。
总结:一定要分清楚宿主机和容器的关系,PHP、nginx 都是在容器上运行的,跟你本机没有关系,本机就是做文件共享。