さくらのレンタルサーバー ＋ Laravel5.7 でトップページ以外 404 Not Found の沼にハマった

さくらのレンタルサーバーにLaravelプロジェクトを構築した際に、トップページ以外 Not Found の状態に陥って数時間格闘してしまいました。（`http://hoge.sakura.ne.jp/` は表示できるが `http://hoge.sakura.ne.jp/foo` が表示できない）

原因はかなり初歩的なミスだったので、
懺悔の意味も込めて、反映手順と解決法を書き留めます。

# 環境
- さくらのレンタルサーバー : スタンダード
    - お名前ドットコムのレンタルサーバーは、Laravelの動作保証してないとのこと
- PHP : 7.2.10
- Laravel : 5.7

# 反映手順
## 1. 反映モジュールの準備
※レンタルサーバー上で `git clone` できるのであれば、この手順は不要

### 1-1. ソースコードのダウンロード
対象のLaravelプロジェクトのリモートリポジトリ（GitLab, GitHub など）から master ブランチのソースコードをダウンロード。（拡張子は *.zip を選びました）
<img width="1409" alt="i-chef___corporate-website_·_GitLab.png" src="https://qiita-image-store.s3.amazonaws.com/0/121942/d6dd498f-4451-1d75-0f8f-f80eebef4b9a.png">


### 1-2. レンタルサーバーへアップロード
FTPソフト（MacであればFileZilla、WindowsであればWinSCP など）で、手順1のファイルを `~/` 配下にアップロード。
<img width="1195" alt="i-chef_i-chef_sakura_ne_jp_-_FileZilla.png" src="https://qiita-image-store.s3.amazonaws.com/0/121942/98647b03-1a89-f21e-a9eb-6a12474e25dd.png">



## 2. サーバーでの作業
```terminal
# SSHログイン
$ ssh hoge@hoge.sakura.ne.jp
```

### 2-1. PHPのバージョン確認
```terminal
# バージョン確認（PHP >= 7.1.3）
% php -v
PHP 7.2.10 (cli) (built: Sep 14 2018 10:32:29) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.10, Copyright (c) 1999-2018, by Zend Technologies
```

7.1.3より低い場合は、以下の手順でPHPのバージョンを更新してください。
[PHPのバージョン変更 - さくらのサポート情報](https://help.sakura.ad.jp/hc/ja/articles/115000135681-PHP%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E5%A4%89%E6%9B%B4)

### 2-2. composerのインストール
```terminal
# ~/bin 配下にインストール
% mkdir ~/bin
% curl -sS https://getcomposer.org/installer | php -- --install-dir=bin --filename=composer
% chmod 755 bin/composer

# 一旦ログアウトして、再度SSHログイン
% exit

# インストールできたことを確認
% composer -V
Composer version 1.7.2 2018-08-16 16:57:12
```

### 2-3. Laravelプロジェクトのパッケージインストール
```terminal
# ソースコードの配置
# git
% git clone git@github.com:foga/hoge.git laravel
or
# file upload
% unzip hoge-master.zip
% mv hoge-master laravel

% cd ~/laravel

# パッケージインストールと最適化
% composer install
% composer dump-autoload --optimize

# ディレクトリに権限追加
% chmod -R 777 bootstrap/cache
% chmod -R 777 storage
```

### 2-4. プロジェクトの設定
※さくらのコントロールパネルからデータベースを作成
[データベースの作成・追加・削除 - さくらのサポート情報](https://help.sakura.ad.jp/hc/ja/articles/206053952--%E3%83%AC%E3%83%B3%E3%82%BF%E3%83%AB%E3%82%B5%E3%83%BC%E3%83%90-%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E4%BD%9C%E6%88%90-%E8%BF%BD%E5%8A%A0-%E5%89%8A%E9%99%A4)

```terminal
# APP_KEY の生成
% php artisan key:generate --show

# .env の設定
% vi .env
------------------------------------------
APP_NAME=hoge
APP_ENV=production
APP_KEY={{ ↑で生成した値 }}
APP_DEBUG=false
APP_URL=http://hoge.sakura.ne.jp

# コントロールパネルの情報を元にDB接続情報の変更

# その他メール接続情報など自身の環境に応じて
------------------------------------------

# テーブルの作成
% php artisan migrate
```

### 2-5. キャッシュ
```terminal
% php artisan config:cache
% php artisan route:cache
```

> LogicException  : Unable to prepare route [api/user] for serialization. Uses Closure.

`php artisan route:cache` で上記エラーメッセージが出るのは、ルーティングでクロージャーを使用しているためです。 
`routes/api.php` もしくは `routes/web.php` の記述を見直してコントローラーに移動させる or コメントアウト。

※ `routes/api.php` が、デフォルトでクロージャー使用しています。

```routes/api.php
Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});
```

### 2-6. シンボリックリンクの追加
Webサーバのドキュメント/Webルート が public になるように設定。
ただし、さくらのレンタルサーバーでは、Apache側のドキュメントルートの設定を変更できないため、シンボリックリンクの追加で対応します。

```terminal
% ln -s public/* ~/www 　※間違っているので、正解は後ほど
```

`public/index.php` がアプリケーションへ送信された、全HTTPリクエストを始めに処理するフロントコントローラとして動作します。

### 2-7. サイト公開
http://hoge.sakura.ne.jp
にアクセスして、サイトが公開されていることが確認できました！めでたしめでたし〜

と思いきや…

http://hoge.sakura.ne.jp/foo にアクセスしてみると

**404 Not Found
The requested resource /foo was not found on this server.**

で画面が見えませんorz

### 2-8. 沼からの脱出
ここから2〜3時間沼にハマってしまって、 `.htaccess` の中身いじってみたり、Laravelのキャッシュクリアしてみたり、試したけど答え出ず…

そこで、冷静になってエラー画面確認するとLaravelではApacheのエラー画面であることに気付き再度 `~/www/.htaccess` が存在するか確認

```terminal
% ls -la ~/www/
total 8
drwxr-xr-x   2 hoge  users  512 Oct 25 19:10 .
drwx------  12 hoge  users  512 Oct 25 21:54 ..
lrwxr-xr-x   1 hoge  users   31 Oct 25 17:42 css -> /home/hoge/laravel/public/css
lrwxr-xr-x   1 hoge  users   39 Oct 25 17:42 favicon.ico -> /home/hoge/laravel/public/favicon.ico
lrwxr-xr-x   1 hoge  users   31 Oct 25 17:42 img -> /home/hoge/laravel/public/img
lrwxr-xr-x   1 hoge  users   37 Oct 25 17:42 index.php -> /home/hoge/laravel/public/index.php
lrwxr-xr-x   1 hoge  users   30 Oct 25 17:42 js -> /home/hoge/laravel/public/js
lrwxr-xr-x   1 hoge  users   38 Oct 25 17:42 robots.txt -> /home/hoge/laravel/public/robots.txt
lrwxr-xr-x   1 hoge  users   32 Oct 25 17:42 scss -> /home/hoge/laravel/public/scss
lrwxr-xr-x   1 hoge  users   31 Oct 25 17:42 svg -> /home/hoge/laravel/public/svg
lrwxr-xr-x   1 hoge  users   34 Oct 25 17:42 vendor -> /home/hoge/laravel/public/vendor
lrwxr-xr-x   1 hoge  users   38 Oct 25 17:42 web.config -> /home/hoge/laravel/public/web.config
```

ない〜！あるはずの `.htaccess` がない〜！！！　＼(^o^)／ｵﾜﾀ

2−6でシンボリックリンク追加した際に、 `public/*` で `.htaccess` が対象に含まれていなかったというオチでした。

```terminal
% ln -s public/.htaccess ~/www

% ls -la ~/www/
total 8
drwxr-xr-x   2 hoge  users  512 Oct 25 19:10 .
drwx------  12 hoge  users  512 Oct 25 21:54 ..
lrwxr-xr-x   1 hoge  users   37 Oct 25 19:10 .htaccess -> /home/hoge/laravel/public/.htaccess
lrwxr-xr-x   1 hoge  users   31 Oct 25 17:42 css -> /home/hoge/laravel/public/css
lrwxr-xr-x   1 hoge  users   39 Oct 25 17:42 favicon.ico -> /home/hoge/laravel/public/favicon.ico
lrwxr-xr-x   1 hoge  users   31 Oct 25 17:42 img -> /home/hoge/laravel/public/img
lrwxr-xr-x   1 hoge  users   37 Oct 25 17:42 index.php -> /home/hoge/laravel/public/index.php
lrwxr-xr-x   1 hoge  users   30 Oct 25 17:42 js -> /home/hoge/laravel/public/js
lrwxr-xr-x   1 hoge  users   38 Oct 25 17:42 robots.txt -> /home/hoge/laravel/public/robots.txt
lrwxr-xr-x   1 hoge  users   32 Oct 25 17:42 scss -> /home/hoge/laravel/public/scss
lrwxr-xr-x   1 hoge  users   31 Oct 25 17:42 svg -> /home/hoge/laravel/public/svg
lrwxr-xr-x   1 hoge  users   34 Oct 25 17:42 vendor -> /home/hoge/laravel/public/vendor
lrwxr-xr-x   1 hoge  users   38 Oct 25 17:42 web.config -> /home/hoge/laravel/public/web.config
```

これで http://hoge.sakura.ne.jp/foo もアクセス出来るようになりました！

本来は `ln -s public/* ~/www` ではなく、wwwのサブディレクトリに対してシンボリックリンクを貼って（ `ln -s public ~/www/web` ）、コントロールパネルからドメインのWebパスを `~/www/web` に設定すれば、このような自体には陥らないと思います。
※ ***.sakura.ne.jp はWebパスの設定を `~/www`から変更できませんが、それ以外の独自ドメインは変更可能です。

***.sakura.ne.jp でチャチャッと動作確認したかったので手抜きしたら、このような沼にハマってしまいました。

急がば回れですね〜

同じような状態に陥っている人の助けになれば幸いです。

以上。

# 補足
## .htaccess の編集
「さくらのレンタルサーバー ＋ Laravel」でググると `.htaccess` の変更も必要という情報が複数出てきますが、さくらのレンタルサーバー側のApacheの対応も入ったこともあり、Laravel5.7 では編集なしで動くようになっています。（2018/10/25 時点）

## キャッシュのクリア
キャッシュが残っていると、上手く動かない場合もあるようなので、以下のクリアコマンド試してみてください。

```terminal
% php artisan cache:clear
% php artisan config:clear
% php artisan route:clear
% php artisan view:clear
```
> Failed to clear cache. Make sure you have the appropriate permissions.

`% php artisan cache:clear` で、上記エラーが出るのは `storage/framework/cache/data` ディレクトリが無いのが原因。
`mkdir storage/framework/cache/data` で解決。

# さいごに
個人ブログにオリジナル（日本語＆英語）をUPしています。
この記事が良いと感じた方は、そちらにもリアクション頂けると嬉しいです:relaxed:
https://blog.n11sh1.com