在阿里云自带的CentOS + LAMP环境下部署一个Laravel项目
前言
最近做的这个题库系统,出题模块已经差不多弄完了,后面其他模块的需求还没有明确,所以就想把项目放到服务器上去跑一跑,本来以为部署一下应该是很简单的事情,况且网上有一堆教程,应该不是难事,结果愣是搞了快一天,不过最后好不容易弄得差不多了,来记录一下其中的问题和思考。
开始尝试
首先说明一下环境以及版本
- 服务器配置:阿里云云翼计划,9.9一个月的学生机, CPU: 1核 内存:2 GB (I/O优化)、1Mbps
- CentOS 7:
- Apache:2.4
- Mysql:
- PHP:5.6.3
- Laravel:5.4
之前购买过阿里云的ECS服务器,所以这方面的操作没什么可说的,就是winscp + puttty的二件套,很快完成密码的修改,然后就开始准备部署项目了。作为对于Linux以及部署服务器一无所知的我,第一步肯定是去找教程,事实上,我第一遍部署的大部分操作都是参照以下两篇教程做的“傻瓜式操作” :教程1、教程2
其实中间的诸多Linux指令我并不理解是什么皮皮意思,但是为了加深印象,我姑且把基本的流程转述一遍,其中很多名词和概念还不熟悉甚至完全不了解,可以以后再来做一下词义补充。
- 服务器安装资源配置,安装epel
- SELinux设置为宽容模式保障证安装过程不受影响
- A、M、P的安装和自动启动(阿里云自带了,可以大大省略,只要检查一下就好)
- Composer的安装(这个很重要)
- Laravel框架的安装(由于我的项目已经开发了一段时间,所以主要做的是进行迁移)
- 修改Apache配置,配置虚拟主机(我直接放在了Apache的根目录下面,就是跟phpmyadmin在一起的)
(忍不住想说用MarkDown写东西真的很优雅么????)
其实到此为止主要的流程已经结束了,所以打开浏览器,输入公网ip地址,打开展示的是apache和php的版本信息,然后进入ip/questionsystem/public。Boom炸了,报的是服务器500的错误,倒也是预料之中的事情,下面就是漫长的查错之旅。
怀疑对象1,php拓展包缺失
在之前按照教程进行操作的过程中,曾经出现过关于php-extension的错误,导致了composer直接安装Laravel项目失败(由于当时没有截图,所以具体情况已经无法描述,长知识会显示一个problem1:php-ext之类的东西,大意就是缺少Laravel所需要的php-extension),所以我一开始是怀疑php环境存在问题。
在网上查了一下,在segmentfault上找到了类似的问题,然后根据那篇博文安装好了所需要的extension,顺便去Laravel学院看了一下Laravel到底需要哪些php-extension以及配置的建议:安装环境以及需要的拓展包, 配置参考1,配置参考2。经过几次尝试(大规模无差别安装php-ext)之后,终于可以顺利安装完成Laravel了,然后把安装好的项目迁移到apache指向的目录下,跑一下public,Boom,依旧是500爆炸,只能继续怀疑了。
怀疑对象2,apache路径设置问题
这个怀疑就很玄学了,因为在网上看的诸多教程,都说要设置虚拟主机,其中的设置方法也是千奇百怪,有的说在http.conf
中直接加virtualhost
就行了,也有人说要另外写一个http-vhosts.conf
文件。我也懒得去很认真分析httpd.conf
文件的内容,大概看了一下,感觉直接写在里面应该没问题。
试了一下,一开始重启Apache服务都会报错,改来改去不报错了,然后把larael项目所在的项目改为documentroot的值,这才想到救我就算设置了虚拟主机要怎么访问啊,我又没有域名。。。于是又很尴尬地把项目扔回了/webdata
(也就是apache初始指向的路径),折腾了一圈看来肯定不是路径的问题,继续怀疑。
怀疑对象3, apache没有开启rewrite功能
这个怀疑看起来还是很有道理的,涉及Laravel中所使用的url美化,以下是部分解释
框架中自带的public/.htaccess文件支持URL中隐藏index.php,如过你的Laravel应用使用Apache作为服务器,需要先确保Apache启用了mod_rewrite模块以支持.htaccess解析。
因为Laravel/public
中的index.php
其实并不是可以直接解析的php,而是需要rewrite的文件,这也就是为什么其中同时会包含一个.htaccess
的文件,就是为了配套apache的这个功能。根据网上的经验,先改了http.conf
里面的allowoverride,又根据Laravel学院里一篇文章去改了.htaccess
的内容,但是经过无数次尝试,依然不能克服500的报错。
虽然在这个怀疑最后是以失败告终中,但是过程中发现了一个很有意思的东西,就是可以在纯文本环境下模拟浏览器打开网页,当然这是要借助工具的,这就是Lynx。具体的安装和使用我就不赘述了,网上一搜一大堆,但是用一下确实还是很好玩的,感觉就像是php里面的file_get_content函数,不过貌似只能就读取到原生的html代码,对js什么的就不太好使了。
Happy Ending
虽说在前面的各种怀疑中来来回回搞了好几个小时一直未能成功,心态也渐渐走向崩溃,不过最后还是好歹把问题给解决了。这里要大大感谢一番这个文章,正是里面的一句话让我找到了正确的道路
Apache的日志文件
ErrorLog /etc/httpd/logs/error_log (php的错误日志也输出到这里)
CustomLog /etc/httpd/logs/access_log combined
看到这里真是心里冰火两重天,一方面感叹终于不用跟无头苍蝇一项乱改一气了,另一方面又在感叹为什么没有做早点看到这段话。事不宜迟,我立刻打开在日志文件看了一下,报的错更加让我崩溃
[Fri Jul 28 17:22:22.773044 2017] [:error] [pid 15735] [client 115.156.163.42:16231] PHP Fatal error: Uncaught exception 'UnexpectedValueException' with message 'The stream or file "/webdata/questionsystem/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied' in /webdata/questionsystem/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:107\nStack trace:\n#0 /webdata/questionsystem/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(37): Monolog\Handler\StreamHandler->write(Array)\n#1 /webdata/questionsystem/vendor/monolog/monolog/src/Monolog/Logger.php(337): Monolog\Handler\AbstractProcessingHandler->handle(Array)\n#2 /webdata/questionsystem/vendor/monolog/monolog/src/Monolog/Logger.php(616): Monolog\Logger->addRecord(400, Object(Symfony\Component\Debug\Exception\FatalErrorException), Array)\n#3 /webdata/questionsystem/vendor/laravel/framework/src/Illuminate/Log/Writer.php(203): Monolog\Logger->error(Object(Symfony\Component\Debug\Exception\FatalErrorException), Array)\n#4 /webdata/questionsystem/vendor/laravel/framework/src/Illuminate/Log/Writer.php in /webdata/questionsystem/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php on line 107, referer: http://39.108.84.38/questionsystem/
虽说看起来一大段,但是Permission Denied还是很显眼的,nmd搞了这么久原来是挂在了权限上,后面修改权限的过程就不赘述了,最后还是要来一张成功照来安慰一下自己。
后续
虽说整个配置过程和排错过程已经写得比较详细了,但是其实其中还有一些值得补充的地方,而且都不是三言两语就能说清楚的,等有时间再回来写上
- 阿里云预装的Mysql的密码初始化方法
- Linux中的权限设置问题
- Linux文件读写的速度问题,具体就是多个小文件读写很慢(比如vender,删都删不掉!),单个大文件读写很快