Laravel 5.4 On Apache:在 Apache 架 Laravel 網站

awonwon
浦島太郎的水族缸
6 min readMar 30, 2017

這個月一直在苦惱該寫甚麼好,這段期間開發專案學到頗多 laravel 的小技巧,但都屬於零零碎碎又不同方面的知識,還不足以變為一篇完整的文章,搞得筆者好擔心會不會難產阿。

所幸人生總會自有生路,最近剛好在試著把 laravel 專案放到 server 上,來教個安裝設定與 route 閒談吧!

※ 5.4~5.8 都適用

安裝步驟

一個 laravel 環境需要安裝的套件

  • apache
  • php
  • composer
  • laravel
  • node.js
  • npm
  • yarn (optional,筆者覺得 install package 速度比較快)

本文會略過安裝 apache、php、composer、node.js、npm 教學,或讀者要用 docker 的話就可以 End 了(逃

Install Laravel

安裝 laravel,順便把 laravel 加到系統 environment variable 中,如果有用 zsh 或其他 shell 就需要注意一下有沒有成功寫進 environment variable 囉!

$ composer global require "laravel/installer"
$ export PATH="$PATH:$HOME/.composer/vendor/bin"
$ laravel -v #=> 測試 export 指令有沒有成功

Laravel On Apache

  1. 把 project folder 放到 /var/www/html中(假設 project folder 叫做 ohyeah好囉)
  2. 設定 public/跟其他資料夾的權限
$ sudo chmon -R www-data:www-data /var/www/html/ohyeah
$ sudo chmod -R 775 /var/www/html/ohyeah/storage

3. 新增一個 laravel 使用的 apache conf

$ sudo vim /etc/apache2/sites-available/laravel.conf

4. laravel.conf 內容中的設定

<VirtualHost *:80>
ServerName localhost

ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/ohyeah/public

<Directory /var/www/html/ohyeah>
AllowOverride All
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

5. 啟用 laravel.conf 的設定,並重新啟動 apache

$ sudo a2dissite 000-default.conf #=> 把原本預設的設定 disable
$ sudo a2ensite laravel.conf
$ sudo a2enmod rewrite
$ sudo service apache2 restart

※ 往後如果 .env 有更新的話,建議 restart apache 重新讀取變數

這樣就完成在 apache 上架 laravel 網站了,可喜可賀可口可樂!

所以我說那個 HTTPS ?

若你想加上 https 的話,先啟用 ssl 模組

$ sudo a2enmod ssl

找個地方放你的憑證(範例是存在 /etc/apache2/ssl/),並在 laravel.conf 加上 SSL 的設定

<VirtualHost *:443>
ServerName localhost

ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/ohyeah/public
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/apache.pem
SSLCertificateKeyFile /etc/apache2/ssl/apache.key
<Directory /var/www/html/ohyeah>
AllowOverride All
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

這樣就好囉!

※如果除了首頁都出現404 ,是 apache 預設的 404 網頁並非 resources/views/error/404.php的樣貌,而且 php artisan route:list 的 route 都有正確出現,應該是 apache conf 有設定錯誤的地方

Route 閒談

由於有需要在 80 port 中把網址的 protocol 從 http改寫成 https的狀況,雖然可以直接從 .htaccess強制 redirect,但我還是想測一下 laravel 的極限。(好啦就愛浪費人生)

URL Helper 當中,可以使用 secure_url('url', $param_array) 來取得 https url,但筆者喜歡寫明 controller action ,較為明確,其他 url 的 helper:action 、route 都是沒辦法指定改為 https 的,需要想其他的解決方案。

大家都會下意識想到可以用一層 middleware 去 rewrite url,但筆者覺得這樣不是很完美

能不能略過註冊 middleware,直接全部都套用 https 就好了嗎?

剛好在翻 url source code 實作的時候,找到一個方法:

URL::forceSchema(‘https’);
//強制改寫 protocol,可以選擇 http 或 https

所以在 App\Providers\AppServiceProvider中先判斷 config/app.php 的 url 是設定為 https 或 http (正確來說是 .env中的 APP_URL 變數),再透過 URL::forceSchema 來改寫 protocol,這樣所有 url helper、route config 或跟 url generator 有相關的都會被套用了

use Illuminate\Support\Facades\URL;
...
public function boot()
{
$protocol = Str::startsWith(config(‘app.url’), ‘https://’) ? ‘https’ : ‘http’;
URL::forceScheme($protocol);
}

讀者若有興趣研究 url 實作的話,可以至以下網址了解 UrlGenerator
https://github.com/laravel/framework/blob/5.4/src/Illuminate/Routing/UrlGenerator.php

多看 source code 有益身心, laravel 的 source code 都好美啊~

有任何問題與建議非常歡迎讀者一起討論 :)

--

--