最近学习docker,尝试着搭建一个php的运行环境。因为早期已经搭建了lnmp,所以第一部分是开始尝试,使用容器+宿机的结构;第二部分则是全部都使用docker搭建。
注意,下面命令都是完成后写的,参考即可,最好不要完全复制,可能存在错误!
- 一.Nginx容器+宿机PHP搭建
踩坑1:pull下Nginx镜像后,使用
docker run -itd --name nginx -port 80:80 nginx
运行。nginx容器正常运行。想使用docker exec -it 39a1f739d83d nginx进入nginx容器修改配置,报错:
这里是我个人对docker理解问题,这条命令最后的nginx是容器使用的脚本,我使用的nginx,但实际上我们已经启动过了,因此会报错地址已存在!需要改成
docker run -itd --name nginx -port 80:80 bin/bash
可以正常进入容器。
踩坑2:进入容器后,发现很多命令无法使用,例如想要编辑配置文件的vi vim。可以安装,但考虑到容器这么多,不可能每个容器都安装,查看文档后发现可以使用docker映射出目录和配置文件。步骤如下:
1.在自己宿机目录下创建文件,可自定义,根据个人习惯而定。这里我是/home/docker/nginx下分别创建了www,conf,log文件。
2.复制容器中的nginx配置文件,命令:
docker cp 39a1f739d83d:/etc/nginx/nginx.conf /home/docker/nginx/conf/
3.关闭容器后,重新运行命令:
docker run --name nginx -itd -p 80:80 -v /home/docker/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /home/docker/nginx/log:/var/log/nginx -v /home/docker/nginx/www:/usr/share/nginx/html nginx
踩坑3:在宿机的/home/docker/nginx/conf/nginx.conf里修改配置,发现始终无法访问到指定目录的PHP文件,查看浏览器的响应,发现没有如下的PHP版本信息:
说明根本没有到PHP这里来,经过度娘,是因为ip地址写错了。以往情况我们是设置的:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
但是,我们的nginx在docker容器里,因此我们需要设置宿机的内网ip,ifconfig查看:
踩坑4:再次请求,发现下面报错,并且html都无法访问
No input file specified.
此前root的路径设置的宿机绝对路径,尝试修改root的路径为容器绝对路径,即:
/usr/share/nginx/html/myblog
此时html可以访问了
踩坑5:按照上面配置后,访问报错
404 file not found
这是因为nginx版本不通,document_root高版本已不支持,需要写成绝对路径,要写成宿机的绝对路径,网上还有说法是要设置成容器的绝对路径(此说法也没错),我测试过,此时容器绝对路径依然是404,这部分后面搭建容器PHP时再做解释。我这里就是
location ~ \.php$ {
fastcgi_pass 172.27.0.3:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/docker/nginx/www/myblog/$fastcgi_script_name;
include fastcgi_params;
}
关于root的路径,我测试了一下,必须设置容器绝对路径,否则会报错“踩坑6”
踩坑6:再次请求,提示
Access denied.
拒绝访问!检查/home/docker/nginx/log里的日志,发现报错:
Access to the script ‘/home/docker/nginx/www/myblog’ has been denied
(see security.limit_extensions)" while reading response header from
upstream, client: , server: localhost, request: “GET /phpinfo.php
HTTP/1.1”, upstream: “fastcgi://172.27.0.3:9000”, host: ""
这是因为默认security.limit_extensions只允许访问php,所以造成部分静态文件到PHP部分就出问题,打开注释,设置
security.limit_extensions=
重启PHP服务,请求成功
二、docker的Nginx+PHP+Mysql
PHP
踩坑1:不确定是否是版本问题,我通过 docker pull php后,使用命令:
docker run -itd --name php -p 9000:9000 -v /home/docker/nginx/www:/var/www php
启动容器,发现网页报错502,在network中查看response,发现没有PHP的信息,并且此目录下html文件可以访问。我一开始以为内网ip地址问题,尝试过使用容器名字,容器内网ip都无效。然后怀疑是路径问题,但我使用了一下三种路径全都不行:
location ~ \.php$ {
fastcgi_pass 172.27.0.3:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/myblog/$fastcgi_script_name;
#fastcgi_param SCRIPT_FILENAME /home/docker/nginx/www/myblog/$fastcgi_script_name;
#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
然后想查看日志,docker logs -f php,发现什么都没有
如果不指定版本号,默认pull最近版本,我删除原来php,重新pull php:7.3.5-fpm,同样的启动命令,刷新请求,network中成功显示php信息。我不太确定是否因为版本太高产生的问题,如果有大佬知道原因,可以留言告诉我,感谢。
踩坑2:路径问题。
上一步踩坑后,虽然访问到了,但提示404,又尝试了上面的3个路径全都不行,依然是html可以访问。然后尝试使用挂载时,写的php的的目录/var/www,成功访问。配置:
location ~ \.php$ {
fastcgi_pass 172.27.0.3:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/myblog/$fastcgi_script_name;
#fastcgi_param SCRIPT_FILENAME /home/docker/nginx/www/myblog/$fastcgi_script_name;
#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
结合第一节踩坑5和踩坑第二节踩坑2,发现fastcgi_param SCRIPT_FILENAME /var/www/myblog/$fastcgi_script_name;这里的路径,是根据PHP的位置来的,可以根据自身情况调整
mysql
有了上面的经验,mysql顺利很多
踩坑1:版本问题
各个版本的配置文件位置可能不同,这点要注意,网上教程给的命令不要照搬,否则会发现容器里找不到对应文件的情况。我一开始就是默认下载的最新版本,发现配置文件找不到,后来换成了5.7版本才能正常运行。
踩坑2:远程连接报错10060错误
这其实就是mysql搭建通用问题,一般来说有以下几种原因:
1.firewall防火墙,端口没有开放。
2.如果你是阿里云,腾讯云这类云服务器,需要去配置安全组
3.网络问题
4.mysql没有设置允许远程连接(网上教程很多)
5.也有可能用的iptables做的防火墙,把端口加入到监听当中
iptables -I INPUT -p tcp --dport 3306 -j ACCEPT