EC2 と RDS を利用したNextcloud 環境の構築 - Nextcloud 環境の構築を通じて AWS での環境構築を体験する①

# はじめに
　AWS のソリューションアーキテクトの更新時期が近づいてきているのですが、普段は AWS にほぼ縁のない Nextcloud の構築とか調査とかの業務がメインで、AWS のサービスをフォローアップすることがほとんどできず、さすがに何か準備しなきゃまずいなぁと思い始めました。
　そこで、普段さんざん構築している Nextcloud の環境構築と AWS をうまくコラボしてなんかできないかな、と思い、表題のような記事を何回かに分けて書いていくことにしました。
　そもそも論として、Nextcloud は自身のデータやファイル管理を Dropbox 等のクラウドサービスに頼らないで自身で管理しているサーバー機器で運用できることが最大のメリットとなるので、AWS に構築することに意味があるかどうかは微妙なところですが、いろいろなサービスがからむので、学習ネタにするには結構よいのではないかと思ってます。

　ということで、回を追うごとに AWS の関連サービスが増えていく予定で、自分自身で使ったことあるサービス／使ったことのないサービスを盛り込み、知識のリハビリ、新たな学びと、楽しみながら記事を書いていければいいな、と思います。

「Nextcloud 環境の構築を通じて AWS での環境構築を体験する」 シリーズの記事は下記からどうぞ。

* 【第 1 回】[EC2 と RDS を利用した Nextcloud 環境の構築](https://qiita.com/S_Katz/items/756ca04ecece844ce503)
* 【第 2 回】[ElastiCache サービスの導入](https://qiita.com/S_Katz/items/280642e437c709052781)
* 【第 3 回】[EFS ファイルサーバーへの移行](https://qiita.com/S_Katz/items/5b5f37db29c3f800e610)
* 【第 4 回】[ALB を利用したサーバー負荷分散、可用性向上に向けた取り組み](https://qiita.com/S_Katz/items/edadf33755c0d834eb46)
* 【第 5 回】[分散した EC2 インスタンスのログの集約](https://qiita.com/S_Katz/items/2fa740c5051859963dae)
* 【第 6 回】[Cron の外部実行とメール送信の追加](https://qiita.com/S_Katz/items/35525eba5ff61801e7e3)
* 【第 7 回】[AutoScaling の導入](https://qiita.com/S_Katz/items/6c6d0a46e592eb783fda)


# 今回構築する Nextcloud on AWS 環境
次のような構成となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/47c86507-841f-e97d-8007-5f9f3a55688b.png)
## 利用する AWS サービス
|サービス名|役割|
|:--|:--|
|Amazon EC2|仮想サーバー|
|Amazon EBS|EC2 に接続して利用するブロックストレージ|
|Amazon RDS|フルマネジメントのリレーショナルデータベースサービス|
|Amazon VPC|仮想のプライベートネットワークサービス|

## 利用するOS、ミドルウェア、アプリケーション
- CentOS 7
- Nextcloud 17.0.2
- Nginx 1.16
- PHP 7.3
- Redis 5

# 構築手順
今回は Nextcloud や関連ミドルウェアのインストールや設定が含まれるため、若干長めとなりますことをご了承ください。

## EC2 インスタンスを起動する
今回はサーバー OS として CentOS 7 を利用します。

1. AWS マネジメントコンソールにログインし、EC2 サービスを選択します。「インスタンス」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/926fdbc4-ef05-0f28-6654-e43dfd4364b1.png)

2. 「インスタンスの作成」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/4a1a0144-9f3c-d599-b714-a87fe19cd9a9.png)

3. 「AWS Marketplace」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/9e996a3b-bb53-afef-e1f5-056b7cd50078.png)

4. 「CentOS 7 (x86_64) - with Updates HVM」を探し ("CentOS"のキーワードで検索するとたぶん一番上に出てくる) 、「選択」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/c069eeb1-8bcc-40d1-189f-caf9c0ca4de7.png)

5. CentOS 7 は無料の OS なので、"ソフトウェア" が "$0.00" となっており、EC2 の時間課金のみが行われることが確認できます。「Continue」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/a023e2d5-de5b-188a-a965-ff6e8d6bd968.png)

6. インスタンスタイプを選択します。無料枠内で試したい場合は 「t2.micro」 一択となりますが、Nextcloud サーバーとして利用する場合には、利用するメモリが意外と大きいため、メモリ 1GByte の t2.micro はちょっと足りない感じです。このため、これより高性能なインスタンスタイプがおススメです。今回は「t3.medium」を選択しました。「次のステップ:インスタンスの詳細の設定」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/d88993eb-1d90-ba98-c047-af3358c3af4e.png)
    ※T2 系と T3 系の違いは以下の記事がわかりやすいと思います。
    [【EC2】T系ファミリーの概要と、T2,T3の仕様の違いについてのまとめ](http://blog.serverworks.co.jp/tech/2019/02/25/burstable-performance-instances-generationgap/)

7. インスタンスをどのように作成するかを設定していきます。ここでの設定は以下のとおりです。すべて設定したら「次のステップ: ストレージの追加」をクリックします。

    |項目|内容|
    |:--|:--|
    |ネットワーク|どの VPC に作成するかを選択します。デフォルト VPC でも問題ありません。ここでは事前に作成済みの VPC を選択しております。|
    |サブネット|どのサブネットに作成するかを選択します。ここでは**「インターネットに通信が出ることができる」**サブネットを選択する必要があることに気をつけてください。デフォルト VPC のサブネットはすべてインターネットに通信が出ることができるものになっております。|
    |自動割り当てパブリックIP|「有効」のものを選択します。(あとで Elastic IP を付与する場合は無効でも問題ありません)|
    |T2/T3 無制限|T系のインスタンスはバーストパフォーマンスとなっており、普段は CPU が持っている能力の 20% 程度しか発揮できません。しかし、CPU が忙しくないときに CPU クレジットを貯めて CPU パワーが必要な時にこのクレジットが利用されて 100% のパフォーマンスを出すことができます。当然 CPU クレジットがないと CPU 性能が発揮できずに頭打ちになるわけですが、このオプションが有効化されていると、**追加課金が発生する**ものの CPU クレジットがない場合でも CPU 性能を常に発揮することができるようになります。今回はそこまで性能は求めないので「有効化」にチェックされていたら外します。|
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/5b1a4792-49ec-5de0-d739-a4517acde91e.png)

8. EC2 はサーバーの処理(コンピューティング)をつかさどる部分となり、サーバーで動く OS、ミドルウェア、各種データを格納するストレージ(EBS)が必要となりますのでここで設定します。設定したら「次のステップ: タグの追加」をクリックします。

    |項目|内容|
    |:--|:--|
    |サイズ|ストレージ容量を指定します。ボリュームタイプや利用 OS によって指定できる下限値が異なります。Nextcloud を軽く試すだけであれば 20 GB もあれば十分かと思います。|
    |ボリュームタイプ|特にこだわりがなければ「汎用 SSD (gp2)」を選択します。どうしてもコストを低く試したいということであれば「マグネティック」でも問題ありません。|
    |終了時に削除|EC2インスタンスを終了(=削除)する際にこのストレージを一緒に削除するかを指定します。EC2 インスタンスを終了して　EBS ストレージの削除を忘れて無駄なコストとなることがよくあるので、問題なければこれをチェックしておくことをおススメします。|
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/8de0728c-b01d-196f-ed33-5326e55e511f.png)

9. EC2 インスタンスに付与するタグを追加します。何も指定しなくても問題ありませんが、ここではインスタンス名(キー: "Name")を指定しています。(インスタンス名にマルチバイト文字を指定することは可能ですが、後で文字化けしますのでここでは1バイト文字を指定しておくことをおススメします。)　入力行が足りない場合は「別のタグを追加」をクリックすることで追加することができます。指定したら「次のステップ: セキュリティグループの設定」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/713fa425-3ea8-f32f-7f96-8ad362c0fe0a.png)

10. EC2 に設定するセキュリティグループ(トラフィックを制御するファイアウォール)を設定します。これを設定しないとサーバーへの SSH 接続も何もできませんので必ず設定しましょう。入力行は「ルールの追加」で追加することができます。最低限下記の設定を行い、設定したら「確認と作成」をクリックします。

    |タイプ|ソース|内容|
    |:--|:--|:--|
    |SSH|マイ IP またはカスタム|SSH 接続を行う接続元グローバル IP アドレスを指定します。「マイ IP」を選択すると現在マネジメントコンソールに接続している接続元グローバル IP アドレスが自動的に指定されます。|
    |HTTPS|任意の場所|HTTPS 接続元を指定します。ここでは「任意の場所」を選択してすべての接続元を受け入れるようにしておりますが、接続元を限定することもできます。|
    |HTTP|任意の場所|HTTP 接続元を指定します。HTTPS 同様に接続元を限定することもできますが、後で Let's Encrypt 証明書を設定する際に必要となるのでいったん「任意の場所」としておくことをおススメします。|
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/1d4191c4-46f4-0798-d163-68d99179579f.png)

11. インスタンス作成の確認です。内容をひととおり確認し問題なければ「起動」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/e0a59c05-0257-d08d-2b04-0b2e112fb3e0.png)

12. SSH 接続する際の接続キーをここで設定します。ここでは AWS に登録済みのキーペアを利用する前提としておりますが、新たに作成していただいても問題ありません。キーを設定したら「インスタンスの作成」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/0e00ebac-b36e-121d-3c59-c84235cd04dc.png)

13. EC2 インスタンスの作成が開始されます。「i-xxxxxxxx」のリンクをクリックすることで、当該 EC2 インスタンスの作成状況を確認することができます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/24199c95-718c-209c-9b6b-e2037c3f528f.png)

14. 下のように「インスタンスの状態」が「running」、ステータスチェックが「2/2 のチェックに合格しました」となっていれば無事作成完了です。サーバーへ SSH 等接続する場合の IP アドレスは 「IPv4 パブリック IP」 の項目で確認できます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/428d6fda-f0af-bdf2-2183-075f0d720bc6.png)

## RDS を起動する
今回はデータベースとして MariaDB 10.3 を利用します。Nextcloud では、MySQL(5.5以上)、PostgreSQL(9.4以上)、Oracle(11g) も利用することができます。

1. AWS マネジメントコンソールにログインし、RDS サービスを選択します。「データベースの作成」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/e9d81646-9b69-e25e-a913-dc9ca1daaf77.png)

2. RDS の設定を投入していきます。設定項目が多いので上から順に分けて書きます。まず以下を設定します。

    |項目|内容|
    |:--|:--|
    |データベース作成方法を選択|標準作成|
    |エンジンのタイプ|MariaDB|
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/24d40ae5-c4db-16f5-72ce-2796d55301d7.png)

3. 引き続き以下を設定します。

    |項目|内容|
    |:--|:--|
    |バージョン|MariaDB 10.3.13　(「.13」部分は作成時によって変わると思いますので適宜読み替えてください)|
    「テンプレート」は「開発/テスト」を選択します。
    引き続き「設定」の設定です。以下を設定します。

    |項目|内容|
    |:--|:--|
    |DB インスタンス識別子|RDS サービスを AWS リージョン内で一意になるように名前を入力します。運が悪いとすでにリージョン内で利用されている可能性がありますので、その時はあきらめてほかの名前を入力してください。|
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/dfd00911-865c-58c6-50d0-ada66b936766.png)

4. 認証情報の設定です。以下を設定します。

    |項目|内容|
    |:--|:--|
    |マスターユーザー名|DB インスタンスのマスターユーザーとして利用するログイン ID|
    |マスターパスワード|マスターユーザーのログイン ID に対するパスワード|
    |パスワードを確認|マスターユーザーのログイン ID に対するパスワード(再入力)|

    続いて DB インスタンスタイプの設定です。以下を設定します。

    |項目|内容|
    |:--|:--|
    |DB インスタンスクラス|バースト可能クラス (t クラスを含む)。|
    |(下のプルダウン)|DB インスタンスのタイプを選択します。今回は「db.t3.medium」を選択しておりますが、状況に応じて選択してください。|
    |以前の世代のクラスを含める|有効にすると、旧タイプの DB インスタンスタイプを指定できます。|
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/60e2bd3b-857a-a6cb-378e-6b30ff7cc1e7.png)

5. ストレージの設定です。以下を設定します。

    |項目|内容|
    |:--|:--|
    |ストレージタイプ|特に指定なければ、汎用 (SSD)|
    |ストレージ割り当て|特に指定なければ、20|
    |ストレージの自動スケーリングを有効にする|チェックする。これによりストレージ使用量が割り当て量に近づいてきたら自動的に割当量が増えます。|
    |最大ストレージしきい値|ストレージの自動スケーリングの上限値。画面例では 1000 GiB まで段階的に増えていきます。一度増えたら再構築しない限り減らすことができないので注意してください。|
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/707f66ac-3fe8-641b-bc6c-a524dc60dee9.png)

6. 可用性と耐久性の設定です。マルチ AZ 配置については、今回はスタンバイは作成しないので「スタンバイインスタンスを作成しないでください」を選択します。
続いて接続の設定です。「Virtual Private Cloud (VPC)」はデータベースをどの VPC に作成するかを選択します。ここは、先に作成した EC2 と同じ VPC を選択します。
さらに「▼ 追加の接続設定」をクリックすると表示が隠されている設定が現れます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/486ae32b-4508-7682-923c-087a1cc59b7c.png)

7. 追加の接続設定です。以下を設定します。

    |項目|内容|
    |:--|:--|
    |サブネットグループ|default-vpc-xxxxx を選択|
    |パブリックアクセス可能|なし|
    |VPC セキュリティグループ|既存を選択|
    |アベイラビリティゾーン|選択できるところのどこでも構いません。あえて ap-northeast-1d を選択しているのは、この アベイラビリティゾーンが新しいという個人的な好みです。|
    |データベースポート|特に問題なければ、デフォルトポートのままで OK|

    続いて「▶ 追加設定」をクリックすると表示が隠されている設定が現れます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/572e38cd-cc89-d856-4820-a3dc8b4b05b7.png)

8. 追加設定をしていきます。基本的にはほぼデフォルトで問題ありませんが、ここでは最低限の設定をしておきます。必要があればほかの設定も見直してください。まず以下を設定します。

    |項目|内容|
    |:--|:--|
    |最初のデータベース名|nextcloud|
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/7713ae40-ffb2-cbbf-66de-8601861f53c8.png)

9. ここはデフォルトのまま変更しません。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/3f314dc8-93b4-22d3-2051-7a9dc586c44e.png)

10. 拡張モニタリングの有効化のチェックは外します。拡張モニタリングは　CloudWatch Logs に準じた追加料金が発生しますが必要があればチェックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/41631143-5463-c90f-daf2-9372fb312af8.png)

11. 長い！　お疲れ様でした。ここまで設定出来たら「データベースの作成」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/6c73f6bc-9a3d-e838-8c84-cbe92569fdd8.png)

12. データベースの作成が開始されます。データベース用のインスタンスやストレージの準備、初期バックアップの作成などが行われるため少し時間がかかります。何回かブラウザをリロードして赤枠部分の表示が消えたら作成完了です。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/a8ce4086-4f66-f3cc-3e89-cc1c015b4fa4.png)

13. 「2020 年 2 月 5 日までに Amazon RDS SSL/TLS 証明書を更新してください」の表示が出ていたら証明書の更新が必要です(なんで最初から新しい証明書で作ってくれないのだろう？)。出ていない場合は 17. にスキップしてください。
「保留中のメンテナンスアクションを表示」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/05ee9ecb-d7e3-9ac8-a5e9-ab2061c4020d.png)

14. 作成したDB 識別子を選択し「今すぐ更新」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/f87eddcf-3cfa-3837-4963-5025329d09bc.png)

15. 「新しい CA 証明書をしないと、データベースへの SSL/TLS 接続が中断されることを理解しています。」をチェックして「今すぐ適用」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/1fffdc24-cfc6-e582-dbb9-69dbf326b15f.png)
    もし「今すぐ適用」をクリックして下のような画面になった場合には、データベースバックアップ処理などがまだ実施中であるので、しばらく待って再実行します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/9f8b1f58-0fc0-a6aa-3675-e9d14cba5c7a.png)


16. ステータスが「保留中」になるのでしばらく待ってブラウザを再読み込みします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/70c6e0a3-f08d-4f6b-2aa6-2456e539e023.png)

17. 先ほど指定した DB が表示されないようになったら証明書の更新は完了です。「データベース」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/18b156de-73c0-6e87-2c10-eaeba04c807f.png)

18. 作成したデータベースの DB 識別子のリンクをクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/1c84cf23-4a68-f871-c044-255ca68d5ef2.png)

19. 「エンドポイント」に表示されているエンドポイント名は Nextcloud の設定項目で利用するので確認しておきます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/d039fc9e-8806-c0c7-dc32-d852b7ae1519.png)

## Nextcloud 環境の構築

Nextcloud 環境は、SSH コンソールで構築します。
SSH 接続は、EC2 構築時に割り当てられた IP アドレスに対して行います。
認証は公開鍵方式となります。EC2 構築時に指定した(もしくは作成した)キーペアの秘密鍵ファイルを利用します。

### OS の基本設定
1. 構築に必要なパッケージのインストール

    ```bash:
    sudo yum install epel-release yum-utils unzip curl wget bash-completion -y

    sudo yum install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm -y
    ```

2. システムを最新状態にアップデート

    ```bash:
    sudo yum update -y
    ```

3. 日本時間、日本ロケール、日本語キーボードの設定

    ```bash:
    sudo timedatectl set-timezone Asia/Tokyo

    sudo localectl set-locale LANG=ja_JP.utf8

    sudo localectl set-keymap jp106
    ```

4. SELINUX の無効化

    ```bash:
    sudo vi /etc/selinux/config
    ※"SELINUX=enforcing" を "SELINUX=disabled" に修正します。
    ```

5. サーバー再起動

    ```bash:
    sudo reboot
    ```

6. 再度 SSH 接続し、設定状況の確認

    ```bash:
    getenforce
    ※"Disabled" が表示されることを確認。

    date
    ※現在の時刻が日本時間、日本語で表示されることを確認。
    ```

### Nginx のインストール、設定
Nginx の最新版をインストールします。

1. リポジトリファイルの作成

    ```bash:
    sudo vi /etc/yum.repos.d/nginx.repo
    ```

    ```/etc/yum.repos.d/nginx.repo
    [nginx]
    name=nginx repo
    baseurl=http://nginx.org/packages/centos/7/$basearch/
    gpgcheck=0
    enabled=1
    ```

2. Nginx のインストール

    ```bash:
    sudo yum install nginx -y
    ```

3. Nginx のインストール確認

    ```bash:
    nginx -v
    ※Nginx のバージョンが表示されることを確認。
    ```

4. Nginx の自動起動設定

    ```bash:
    sudo systemctl enable nginx
    ```

5. Nextcloud 向けの Nginx 設定ファイルの追加

    ```bash:
    sudo vi /etc/nginx/conf.d/nextcloud.conf
    ```

    ```/etc/nginx/conf.d/nextcloud.conf
    upstream php-handler {
        #server 127.0.0.1:9000;
        server unix:/var/run/php-fpm/php-fpm.sock;
    }
    
    server {
        listen 80;
        listen [::]:80;
        server_name 【Nextcloud を動かすサーバーの FQDN】;
        # enforce https
        return 301 https://$server_name:443$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name 【Nextcloud を動かすサーバーの FQDN】;
    
        # Use Mozilla's guidelines for SSL/TLS settings
        # https://mozilla.github.io/server-side-tls/ssl-config-generator/
        # NOTE: some settings below might be redundant
        ssl_certificate /etc/letsencrypt/live/【Nextcloud を動かすサーバーの FQDN】/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/【Nextcloud を動かすサーバーの FQDN】/privkey.pem;
    
        # Add headers to serve security related headers
        # Before enabling Strict-Transport-Security headers please read into this
        # topic first.
        add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
        #
        # WARNING: Only add the preload option once you read about
        # the consequences in https://hstspreload.org/. This option
        # will add the domain to a hardcoded list that is shipped
        # in all major browsers and getting removed from this list
        # could take several months.
        add_header Referrer-Policy "no-referrer" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Download-Options "noopen" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Permitted-Cross-Domain-Policies "none" always;
        add_header X-Robots-Tag "none" always;
        add_header X-XSS-Protection "1; mode=block" always;
    
        # Remove X-Powered-By, which is an information leak
        fastcgi_hide_header X-Powered-By;
    
        # Path to the root of your installation
        root /var/www/html/nextcloud;
    
        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }
    
        # The following 2 rules are only needed for the user_webfinger app.
        # Uncomment it if you're planning to use this app.
        #rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
        #rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;
    
        # The following rule is only needed for the Social app.
        # Uncomment it if you're planning to use this app.
        #rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
    
        location = /.well-known/carddav {
          return 301 $scheme://$host:$server_port/remote.php/dav;
        }
        location = /.well-known/caldav {
          return 301 $scheme://$host:$server_port/remote.php/dav;
        }
    
        # set max upload size
        client_max_body_size 512M;
        fastcgi_buffers 64 4K;
    
        # Enable gzip but do not remove ETag headers
        gzip on;
        gzip_vary on;
        gzip_comp_level 4;
        gzip_min_length 256;
        gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
        gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
    
        # Uncomment if your server is build with the ngx_pagespeed module
        # This module is currently not supported.
        #pagespeed off;
    
        location / {
            rewrite ^ /index.php;
        }
    
        location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
            deny all;
        }
        location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
            deny all;
        }
    
        location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
            fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
            set $path_info $fastcgi_path_info;
            try_files $fastcgi_script_name =404;
            include fastcgi_params;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param PATH_INFO $path_info;
            fastcgi_param HTTPS on;
            # Avoid sending the security headers twice
            fastcgi_param modHeadersAvailable true;
            # Enable pretty urls
            fastcgi_param front_controller_active true;
            fastcgi_pass php-handler;
            fastcgi_intercept_errors on;
            fastcgi_request_buffering off;
        }
    
        location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
            try_files $uri/ =404;
            index index.php;
        }
    
        # Adding the cache control header for js, css and map files
        # Make sure it is BELOW the PHP block
        location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
            try_files $uri /index.php$request_uri;
            add_header Cache-Control "public, max-age=15778463";
            # Add headers to serve security related headers (It is intended to
            # have those duplicated to the ones above)
            # Before enabling Strict-Transport-Security headers please read into
            # this topic first.
            add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;";
            #
            # WARNING: Only add the preload option once you read about
            # the consequences in https://hstspreload.org/. This option
            # will add the domain to a hardcoded list that is shipped
            # in all major browsers and getting removed from this list
            # could take several months.
            add_header Referrer-Policy "no-referrer" always;
            add_header X-Content-Type-Options "nosniff" always;
            add_header X-Download-Options "noopen" always;
            add_header X-Frame-Options "SAMEORIGIN" always;
            add_header X-Permitted-Cross-Domain-Policies "none" always;
            add_header X-Robots-Tag "none" always;
            add_header X-XSS-Protection "1; mode=block" always;
    
            # Optional: Don't log access to assets
            access_log off;
        }
    
        location ~ \.(?:png|html|ttf|ico|jpg|jpeg|bcmap)$ {
            try_files $uri /index.php$request_uri;
            # Optional: Don't log access to other assets
            access_log off;
        }
    }
    ```
    ※【Nextcloud を動かすサーバーの FQDN】の部分はご自身の環境に合わせて適宜修正してください。

### PHP のインストール、設定
PHP 7.3 系の最新版をインストールします。

1. PHP 7.3 の最新版ならびに関連パッケージをインストール。

    ```bash:
    sudo yum install --enablerepo=remi,remi-php73 php php-fpm php-cli php-common php-curl php-gd php-mbstring php-mysqlnd php-process php-xml php-zip php-opcache php-pecl-apcu php-intl php-pecl-redis php-pecl-zip php-pear -y
    ```

2. PHP 7.3 がインストールされたか確認。

    ```bash:
    php -v
    ※PHP 7.3.xx が表示されることを確認します。
    ```

3. PHP 設定ファイルを修正。

    ```bash:
    sudo cp -pi /etc/php.ini{,.orig}

    sudo vi /etc/php.ini
    ※"memory_limit = 128M" を "memory_limit = 512M" に修正します。
    ```

4. PHP-FPM 設定ファイルを修正。

    ```
    sudo cp -pi /etc/php-fpm.d/www.conf{,.orig}

    sudo vi /etc/php-fpm.d/www.conf
    ※修正箇所が多いので、下の diff 結果を参照して修正してください。

    diff /etc/php-fpm.d/www.conf.orig /etc/php-fpm.d/www.conf
    24c24
    < user = apache
    ---
    > user = nginx
    26c26
    < group = apache
    ---
    > group = nginx
    38c38
    < listen = 127.0.0.1:9000
    ---
    > listen = /var/run/php-fpm/php-fpm.sock
    48,50c48,50
    < ;listen.owner = nobody
    < ;listen.group = nobody
    < ;listen.mode = 0660
    ---
    > listen.owner = nginx
    > listen.group = nginx
    > listen.mode = 0666
    396,400c396,400
    < ;env[HOSTNAME] = $HOSTNAME
    < ;env[PATH] = /usr/local/bin:/usr/bin:/bin
    < ;env[TMP] = /tmp
    < ;env[TMPDIR] = /tmp
    < ;env[TEMP] = /tmp
    ---
    > env[HOSTNAME] = $HOSTNAME
    > env[PATH] = /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/centos/.local/bin:/home/centos/bin
    > env[TMP] = /tmp
    > env[TMPDIR] = /tmp
    > env[TEMP] = /tmp
    425c425,427
    < ;php_admin_value[memory_limit] = 128M
    ---
    > php_admin_value[memory_limit] = 512M
    > php_admin_flag[session.cookie_secure] = on
    > php_admin_flag[expose_php] = off
    ```

5. PHP セッションディレクトリのグループ情報を変更。

    ```bash:
    sudo chown -R root:nginx /var/lib/php/session
    ```

6. PHP-FPM の自動起動設定

    ```bash:
    sudo systemctl enable php-fpm
    ```

### SSL 証明書 (Let's Encrypt) の取得

SSL 証明書は Let's Encrypt を利用して取得します。
取得にあたっては、あらかじめ、アクセス FQDN に対して EC2 サーバーの IP アドレスに名前解決ができるように DNS 登録を済ませておく必要があります。

1. certbot のインストール。git もないのでついでにインストール。

    ```bash:
    sudo yum install git -y

    cd /usr/local

    sudo git clone https://github.com/certbot/certbot
    ```
    
2. Let's Encrypt 証明書の取得。

    ```bash:
    cd certbot

    ./certbot-auto certonly --standalone -d 【Nextcloud を動かすサーバーの FQDN】 -m 【管理者のメールアドレス】--agree-tos -n
    ※実行結果として "- Congratulations! ・・・" が表示されれば作成は成功です。

    cd
    ````

### PHP-FPM、Nginx の起動

1. PHP-FPM を起動。

    ```bash:
    sudo systemctl start php-fpm

    systemctl status php-fpm
    ※"Active: active (running)" が表示されることを確認します。
    ```

2. Nginx を起動。

    ```bash:
    sudo systemctl start nginx

    systemctl status nginx
    ※"Active: active (running)" が表示されることを確認します。
    ```


### MariaDB クライアントのインストール

1. MariaDB クライアントをインストール。

    ```bash:
    curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash

    sudo yum install -y MariaDB-client
    ```

2. RDS で作成した MariaDB データベースに接続できるか確認。

    ```bash:
    mysql -h 【RDS で作成したデータベースのエンドポイント】 -u 【マスターユーザー名】 -p 【DB 名】
    Enter password: ※マスターユーザーのパスワードを入力
    ※"「MariaDB [【DB 名】]>" とプロンプトが表示されることを確認します。
    ```

3. Nextcloud データベースを利用する DB ユーザーを作成し、データベースへのアクセス権限を付与。

    ```bash:
    CREATE USER '【ユーザー名】'@'%' IDENTIFIED BY '【パスワード】';

    GRANT SELECT, UPDATE, DELETE, INSERT, CREATE, DROP, INDEX, ALTER, LOCK TABLES, EXECUTE, CREATE TEMPORARY TABLES, TRIGGER, CREATE VIEW, SHOW VIEW, EVENT ON nextcloud.* TO '【ユーザー名】'@'%';
    ````

4. MariaDB コンソールを終了する。

    ```bash:
    exit
    ```

### Nextcloud のインストール、設定

1. Nextcloud パッケージとチェックサムファイルを取得、パッケージの正当性を確認。

    ```bash:
    wget https://download.nextcloud.com/server/releases/nextcloud-17.0.2.tar.bz2

    wget https://download.nextcloud.com/server/releases/nextcloud-17.0.2.tar.bz2.md5

    md5sum -c nextcloud-17.0.2.tar.bz2.md5 < nextcloud-17.0.2.tar.bz2
    ※"nextcloud-17.0.2.tar.bz2: 完了" が表示されることを確認します。
    ```

2. bzip2 を展開するために bzip2 を追加インストール。

    ```bash:
    sudo yum install bzip2 -y
    ```

3. ダウンロードしたNextcloudパッケージを展開、インストール。

    ```bash:
    tar xf nextcloud-17.0.2.tar.bz2

    sudo cp -R nextcloud/ /var/www/html/

    sudo chown -R nginx:nginx /var/www/html/nextcloud
    ```

4. Nextcloud データ保存用ディレクトリの作成、権限設定。

    ```bash:
    sudo mkdir /DATA

    sudo chown -R nginx:nginx /DATA
    ```

5. PHP-FPM を再起動。

    ```bash:
    sudo systemctl restart php-fpm
    ````


6. ブラウザで `https://【Nextcloud を動かすサーバーの FQDN】/` にアクセス。下のような画面が表示が確認できたら、各種設定を投入。

    |項目|内容|
    |:--|:--|
    |管理者アカウント|Nextcloud 管理者アカウントをまず作成します。このアカウントのユーザー ID を入力します。|
    |パスワード|管理者アカウントのパスワードを入力します。|
    引き続いて「ストレージとデータベース ▼」のリンクをクリックすることで追加の登録フォームが表示されます。

    |項目|内容|
    |:--|:--|
    |データフォルダー|先に作成している Nextcloud データ保存用ディレクトリを指定します。|
    |データベースを設定してください|「MySQL/MariaDB」をクリックします(PostgreSQL、Oracle の場合もこ知らをクリックします。)|
    |データベースのユーザー名|RDS データベースを作成した際に指定したマスターユーザー名。|
    |データベースのパスワード|RDS データベースを作成した際に指定したマスターユーザーのパスワード。|
    |データベース名|RDS データベースを作成した際に作成指定したデータベース名。|
    |データベースのホスト名|【RDS のエンドポイント名】:【RDS の接続ポート】。|
    すべて入力したら「セットアップを完了します」をクリックします。 
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/a8ad2fbf-afa7-753b-3944-29c3e4c62b12.png)

7. 下のような画面が出たらセットアップ完了。右上の「×」をクリック。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/2988f3d8-a08f-e34e-fbfd-beb44a40da93.png)

8. 初期のファイルリスト表示を確認後、右上のアイコンをクリックし「設定」をクリック。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/711652ab-716b-9b47-91c4-ae08f96a0984.png)

9. 「概要」をクリック。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/537aee7e-d9af-53b5-3d5e-c0102be089e5.png)

10. 「セキュリティ＆セットアップ警告」にメッセージが表示されますので、これらが表示されないように追加設定をしていきます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/2989bc51-2981-6197-ab96-b4866a85f0e0.png)

### メモリキャッシュ (Redis) のインストール、設定

1. Redis をインストール。

    ```bash:
    sudo yum install --enablerepo=remi redis -y
    ```

2. Redis の自動起動を設定し、Redis サービスを起動。

    ```bash:
    sudo systemctl enable redis.service

    sudo systemctl start redis.service
    ```

3. Nextcloud 設定ファイルの修正。

    ```bash:
    sudo cp -pi /var/www/html/nextcloud/config/config.php{,.orig}

    sudo vi /var/www/html/nextcloud/config/config.php
    ※以下の diff 結果のように設定行を追加します。

    sudo diff /var/www/html/nextcloud/config/config.php.orig /var/www/html/nextcloud/config/config.php
    21a22,29
    >   'memcache.distributed' => '\\OC\\Memcache\\Redis',
    >   'memcache.locking' => '\\OC\\Memcache\\Redis',
    >   'memcache.local' => '\\OC\\Memcache\\APCu',
    >   'redis' => 
    >   array (
    >     'host' => 'localhost',
    >     'port' => 6379,
    >   ),
    ```

4. PHP-FPM 設定ファイルの修正。

    ```bash:
    sudo cp -pi /etc/php-fpm.d/www.conf{,.orig2}

    sudo vi /etc/php-fpm.d/www.conf
    ※以下の diff 結果のように設定を修正します。

    diff /etc/php-fpm.d/www.conf.orig2 /etc/php-fpm.d/www.conf
    437,438c437,438
    < php_value[session.save_handler] = files
    < php_value[session.save_path]    = /var/lib/php/session
    ---
    > php_value[session.save_handler] = redis
    > php_value[session.save_path]    = "tcp://localhost:6379/"
    ```

5. PHP-FPM を再起動。

    ```bash:
    sudo systemctl restart php-fpm
    ```

### PHP OPcache の設定

1. PHP 設定ファイルの修正。

    ```bash:
    sudo cp -pi /etc/php.d/10-opcache.ini{,.orig}

    sudo vi /etc/php.d/10-opcache.ini
    ※以下の diff 結果のように設定を修正します。

    diff /etc/php.d/10-opcache.ini.orig /etc/php.d/10-opcache.ini
    18c18
    < opcache.max_accelerated_files=4000
    ---
    > opcache.max_accelerated_files=10000
    36c36
    < ;opcache.revalidate_freq=2
    ---
    > opcache.revalidate_freq=1
    43c43
    < ;opcache.save_comments=1
    ---
    > opcache.save_comments=1
    ```

2. PHP-FPM を再起動。

    ```bash:
    sudo systemctl restart php-fpm
    ```

### ImageMagick の導入

1. ImageMagick 関連パッケージのインストール。

    ```bash:
    sudo yum install https://imagemagick.org/download/linux/CentOS/x86_64/ImageMagick-libs-7.0.9-14.x86_64.rpm -y

    sudo yum install https://imagemagick.org/download/linux/CentOS/x86_64/ImageMagick-7.0.9-14.x86_64.rpm -y

    sudo yum install https://imagemagick.org/download/linux/CentOS/x86_64/ImageMagick-devel-7.0.9-14.x86_64.rpm -y

    sudo yum install --enablerepo=remi,remi-php73 php-devel -y

    sudo pecl install imagick
    ※入力待ちになったら [ENTER] を押下してください。
    ```

2. PHP 設定ファイルの修正。

    ```bash:
    sudo cp -pi /etc/php.ini{,.orig2}

    sudo vi /etc/php.ini
    ※最終行に以下の 2 行を追加します。
    [PECL]
    extension=imagick.so
    ```
    
3. PHP-FPM を再起動。

    ```bash:
    sudo systemctl restart php-fpm
    ```

### 一部データベースカラムの big int 変換

1. big int 変換を行う Nextcloud occ コマンドを実行。

    ```bash:
    sudo -u nginx php /var/www/html/nextcloud/occ db:convert-filecache-bigint
    ※確認が求められたら [y] を入力します。
    ````

### 追加設定後の確認

以下のように「すべてのチェックに合格しました。」と表示されれば OK です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/08b169de-e778-7c7e-eaba-c3f82d7a9669.png)

### バックグラウンドジョブの設定

Nextcloud では、データの適正化を図るなどの目的でバックグラウンドジョブが動作しております。
デフォルトでは "AJAX" モードとなっており、各ぺーじの読み込みごとにバックグラウンドジョブが起動するようになっておりますが、これを CRON で動かすように変更します。

1. 設定画面から管理メニューの「基本設定」をクリック。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/3d934988-9e25-0653-a65a-4055321c2724.png)

2. バックグラウンドジョブを 「Cron」をクリックします。設定は即時で反映されます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/77658e01-7bb7-e794-6d83-691dba245455.png)

3. Cron 定義ファイルを作成します。バックグラウンドジョブは 5分おきに実行されるようにしています。

    ```bash:
    sudo sh -c "echo '*/5 * * * * nginx php -f /var/www/html/nextcloud/cron.php' > /etc/cron.d/nextcloud-cron-php"
    ````

4. Cron の実行ログを確認し、エラーが出ていないことを確認。

    ```bash:
    tail -f /var/log/cron
    ```
    ※私が試していた時には `(CRON) ERROR chdir failed (/var/cache/nginx): そのようなファイルやディレクトリはありません` というエラーメッセージがでました。もし同様に発生した場合には以下のようにディレクトリを追加します。

    ```bash:
    sudo mkdir /var/cache/nginx
    ```

5. 再びバックグラウンドジョブの画面を確認します。「最終ジョブ実行」が定期的に更新され、グリーンシグナルとなっていれば問題ありません。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316764/3c5c2b9a-7e3c-e6f1-c1d7-2a95723d3631.png)

**お疲れさまでした！　これですべての設定が完了です。**

# あとがき

今回は Nextcloud 自体の初期構築を含んだため手順が多くなってしまいました。最後まで読んでいただいた方、本当にありがとうございました。

次回は、EC2 サーバーにインストールした Redis を EC2 から分離してみます。