2019-07-09

【Amazon Lightsail】Laravel を Nginx スタック & バーチャルホストでデプロイする【SSL】

nginx-vhosts

やること

LaravelアプリケーションをAmazon LightsailのNginxイメージにデプロイします。

  • 1つのIPアドレスに複数のアプリケーションをホスティングできるよう、バーチャルホスト設定を行います。
  • HTTPSリダイレクト(常時SSL化)の設定もNginxで行います。

前提

  • Nginxイメージでインスタンスを生成済み
  • Static IPの取得およびドメインのDNS設定済み
  • SSL証明書を取得済み(HTTPSを使用する場合)
参考

環境

  • Ubuntu 16.04 LTS
  • PHP 7.2.17
  • Laravel 5.x (本記事では5.8)
  • Nginx 1.16.0

データベースの準備

Console

# MySQL のデフォルトパスワードを確認し、ログイン
cat ~/bitnami_application_password
mysql -u root -p

MySQL Console

# DB名、ユーザー名、パスワードは適宜置き換えてください。
CREATE DATABASE myapp_db;
CREATE USER 'ryo'@'localhost' IDENTIFIED BY 'yourpassword';
GRANT ALL ON myapp_db.* TO 'ryo'@'localhost';
exit

Console

# ログインできるか確認しておきましょう。
mysql -u ryo -p

Laravelアプリケーションの準備

  • 今回はホームディレクトリ内に www というディレクトリを作成し、そこにGitHubからCloneしてアプリケーションを持ってきます。
  • SSH接続でCloneする場合は、あらかじめ暗号鍵の生成と登録が必要です。本記事では省略します。
  • 参考: GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~

Console

mkdir ~/www
cd ~/www
git clone git@github.com:hoge/myapp.git
cd myapp

# プリインストールされているComposerはバージョンが古いため、更新しておきます。
sudo composer self-update

# vendorのインストール
composer install

# .env ファイルを生成
cp .env.example .env

# アプリケーションキーの生成
php artisan key:generate

# 環境変数の設定
vim .env

.env の中身はこんな感じになると思います。ご自身のアプリケーションに合わせて適宜設定してください。

.env

APP_NAME=MyApp
APP_ENV=production
APP_KEY=(省略)
APP_DEBUG=false
APP_URL=https://example.com

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=myapp_db
DB_USERNAME=ryo
DB_PASSWORD=yourpassword

// 省略

.env の設定が済んだら

Console

# 環境変数が反映されるよう、忘れずにキャッシュを更新しておきます。
php artisan config:cache

# 必要に応じてマイグレーションもしておきましょう。
# production環境ですが本当に実行していいですか?と聞かれるので yes と答えます。
php artisan migrate

パーミッションの設定

本番環境なので、ディレクトリおよびファイルのパーミッションも適切に設定しておきます。誤っても 775 とか 777 を設定しないように。

※ gitでファイルを更新した際、パーミッションは元の状態に戻るので注意。必要に応じてシェルスクリプトを作成して自動化しておくと良いと思います。

Console

# 所有者を `bitnami` (ログイン中のユーザー) に、グループを `daemon` に
sudo chown -R bitnami:daemon ~/myapp
# ディレクトリのパーミッション設定
sudo find ~/myapp -type d -exec chmod 750 {} \;
# ファイルのパーミッション設定
sudo find ~/myapp -type f -exec chmod 640 {} \;
# 書き込み操作が行われるディレクトリのパーミッション設定
sudo chmod -R 770 ~/myapp/storage/ ~/myapp/bootstrap/cache/

ls -l ~/myapp でパーミッションを確認すると以下のような感じになります(Laravel 5.8の場合)

drwxr-x---  6 bitnami daemon   4096 Jul  9 12:52 app
-rw-r-----  1 bitnami daemon   1686 Jul  9 12:52 artisan
drwxr-x---  3 bitnami daemon   4096 Jul  9 12:52 bootstrap
-rw-r-----  1 bitnami daemon   1588 Jul  9 12:52 composer.json
-rw-r-----  1 bitnami daemon 174962 Jul  9 12:52 composer.lock
drwxr-x---  2 bitnami daemon   4096 Jul  9 12:52 config
drwxr-x---  5 bitnami daemon   4096 Jul  9 12:52 database
-rw-r-----  1 bitnami daemon   1325 Jul  9 12:52 package.json
-rw-r-----  1 bitnami daemon 410428 Jul  9 12:52 package-lock.json
-rw-r-----  1 bitnami daemon   1156 Jul  9 12:52 phpunit.xml
drwxr-x---  3 bitnami daemon   4096 Jul  9 12:52 public
-rw-r-----  1 bitnami daemon   4151 Jul  9 12:52 readme.md
drwxr-x---  6 bitnami daemon   4096 Jul  9 12:52 resources
drwxr-x---  2 bitnami daemon   4096 Jul  9 12:52 routes
-rw-r-----  1 bitnami daemon    563 Jul  9 12:52 server.php
drwxrwx---  5 bitnami daemon   4096 Jul  9 12:52 storage
drwxr-x---  4 bitnami daemon   4096 Jul  9 12:52 tests
drwxr-x--- 43 bitnami daemon   4096 Jul  9 12:55 vendor
-rw-r-----  1 bitnami daemon    599 Jul  9 12:52 webpack.mix.js
-rw-r-----  1 bitnami daemon 285890 Jul  9 12:52 yarn.lock
備考: Nginxの実行ユーザーについて

Apacheの場合、実行ユーザーは通常 www-data ですが、 BitnamiのNginxでは下記の通り daemon がデフォルトの実行ユーザーとして設定されています。

/opt/bitnami/nginx/conf/nginx.conf

user  daemon daemon;
# 省略

バーチャルホストの設定

ここからようやく、ホストの設定に入ります。

  • バーチャルホスト用アプリケーションを置いておくディレクトリは、 /opt/bitnami/apps/ になります。(ホームディレクトリ内の ~/apps/ はこの場所へのシンボリックリンクです。)
  • Bitnamiでは親切なことに、/opt/bitnami/docs/demo/ 内にバーチャルホストのDemoファイルを用意してくれますので、それをベースにして設定を進めていきます。

Console

cd /opt/bitnami/apps
sudo cp -r /opt/bitnami/docs/demo/ ./myapp/

ディレクトリ構成は以下のようになっています。

myapp
├── conf
│   ├── nginx-app.conf
│   ├── nginx-prefix.conf
│   └── nginx-vhosts.conf
└── htdocs
    ├── index.php
    └── phpinfo.php

conf/ 内には設定ファイルが、htdocs/ はドキュメントルートになります。

nginx-app.conf
  • Apache の .htaccess に相当する設定ファイルです。
  • indexファイルの読み込み設定をLaravel用にカスタマイズします。

Console

cd /opt/bitnami/apps/myapp/conf
sudo vim nginx-app.conf

/opt/bitnami/apps/myapp/conf/nginx-app.conf

    # indexが並んだ行をコメントアウトし、下記のとおり書き換える
    # index index.php index.html index.htm;
    location / {
    index index.php index.html index.htm;
    try_files $uri $uri/ /index.php?$query_string;
    }

    # 後半部分は編集しません。
    location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_read_timeout 300;
    fastcgi_pass unix:/opt/bitnami/php/var/run/www.sock;
    fastcgi_index index.php;
    fastcgi_param  SCRIPT_FILENAME $request_filename;
    include fastcgi_params;
}
nginx-prefix.conf

特に編集の必要はありません。prefix を設定すると、サブディレクトリ example.com/blog にアクセスする際、代わりに blog.example.com が使用できるようになるらしいです。

nginx-vhosts.conf
  • ここでバーチャルホストのサーバー設定を行います。
  • 常時SSL化設定もここで行います。

Console

sudo vim nginx-vhosts.conf

以下のように設定します。

/opt/bitnami/apps/myapp/conf/nginx-vhosts.conf


server {
    # 80番ポートにアクセスがあった際は、全て443番にリダイレクトさせます。 
    listen    80;
    # ドメイン名は自身のものに書き換えてください。
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {

    listen    443 ssl;
    root   "/opt/bitnami/apps/myapp/htdocs";
    server_name  example.com www.example.com;

    # 証明書の設定はこのあと行います。ひとまずこのように記述します。
    ssl_certificate      "/opt/bitnami/apps/myapp/conf/certs/server.crt";
    ssl_certificate_key  "/opt/bitnami/apps/myapp/conf/certs/server.key";

    
       ssl_session_cache    shared:SSL:1m;
       ssl_session_timeout  5m;

    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;
    
    include "/opt/bitnami/apps/myapp/conf/nginx-app.conf";
}
  • ディレクトリパスが全て /opt/bitnami/apps/demo/ になっているので、忘れずに /opt/bitnami/apps/myapp/ に書き換えてください。
  • vim であれば、 :%s/apps\/demo/apps\/myapp/g で一括置換できます

SSL証明書の設定

さきほど nginx-vhosts.conf にパスを記述した通り、証明書の設定します。シンボリックリンクを貼っておきましょう。

※本記事では公式ドキュメントの Using Let’s Encrypt SSL certificates に従って証明書を取得した前提で進めています。

Console

cd /opt/bitnami/apps/myapp/conf
sudo mkdir certs
cd certs
sudo ln -s /etc/letsencrypt/live/$DOMAIN/privkey.pem ./server.key
sudo ln -s /etc/letsencrypt/live/$DOMAIN/fullchain.pem ./server.crt

Nginx本体のバーチャルホスト設定

ここまで準備したバーチャルホストを、Nginx本体が読み込んでくれるように設定します。

Console

sudo vim /opt/bitnami/nginx/conf/bitnami/bitnami-apps-vhosts.conf

以下のように記述します。

/opt/bitnami/nginx/conf/bitnami/bitnami-apps-vhosts.conf

include "/opt/bitnami/apps/myapp/conf/nginx-vhosts.conf"

バーチャルホストがきちんと設定されていることを確認する

Console

# Nginxを再起動して変更を反映させる
sudo /opt/bitnami/ctlscript.sh restart nginx

# 設定にミスがある場合は、このタイミングでエラーメッセージが出力されます。

正常に再起動ができたら、ブラウザから example.com (設定したドメイン) にアクセスをして、下記のように表示されている & https で接続されていることを確認しましょう!

https://example.com

Hello world!
PHP info

ドキュメントルート(htdocs) の設定

最後に、Laravelアプリケーションが起動するようにドキュメントルートを設定します。

Console

cd /opt/bitnami/apps/myapp/htdocs

# 既存の index.php と php.info は消しておきます
sudo rm index.php phpinfo.php

# Laravel本体の index.php をコピーしてきます。
sudo cp ~/www/myapp/public/index.php index.php
# 所有権の変更
sudo chown bitnami:daemon index.php

sudo vim index.php

autoload.php および app.php の読み込みパスを修正します。

/opt/bitnami/apps/myapp/htdocs/index.php

# 省略

// require __DIR__.'/../vendor/autoload.php';
require '/home/bitnami/www/myapp/vendor/autoload.php'

# 省略

// $app = require_once __DIR__.'/../bootstrap/app.php';
$app = require_once '/home/bitnami/www/myapp/bootstrap/app.php'

# 省略

img, js, css, storage など必要なディレクトリを持ってきます。コピーでも良いですが、自分はシンボリックリンクを貼ってます。(変更するたびにコピーする必要がないためファイル管理が楽です。)

Console

sudo ln -s ~/www/myapp/public/img/ img
sudo ln -s ~/www/myapp/public/css/ css
sudo ln -s ~/www/myapp/public/js/ js
sudo ln -s ~/www/myapp/storage/app/public/ storage

robots.txt を設定している場合も同様にドキュメントルートに持ってきておきましょう。

最後に、ブラウザから example.com (設定したドメイン)にアクセスして、アプリケーションが正常に動いていれば完了です!お疲れ様でした!

Access denied が表示されている場合、index.php のパーミッションに問題がある可能性が高いです。上記で示した index.php パーミッションの設定を必ず行ってください。(なおシンボリックリンクはリンク先ファイル・ディレクトリのパーミッションに依存するので設定不要です。)

参考になったリンク集

※ 万一記事に不備がありましたら Contact からご教示いただけますと幸いです…!