laravel+VueプロダクトのEC2へのデプロイ

#書いてあること
laravel+Vueのプロダクトをクラウドサーバで公開したのでメモっておきます。

**注意）CI編は別記事に移行しました。**

#前提
クラウドサーバはEC2。OSはAmazonLinux2。サーバソフトはnginx+php-fpm。
サービスリリースで考えないといけない負荷分散、冗長構成などはここではいったん置いておきます。

##EC2の初期設定
rootユーザにパスワードかけるとかは省略します。

##証明書取得
省略します。

##日本時間と日本語に対応させる
```sh
$ timedatectl set-timezone Asia/Tokyo
$ localectl set-locale LANG=ja_JP.UTF-8
$ localectl set-keymap jp106
$ date
Wed Apr 22 13:53:00 JST 2020
```

##nginxのインストール
```sh
$ amazon-linux-extras install nginx1.12 -y
```
nginxの起動とインスタンス起動時自動起動の設定

```sh
$ sudo systemctl start nginx
$ sudo systemctl enable nginx
$ systemctl status nginx
```

##PHPのインストール
```sh
$ amazon-linux-extras info php7.4
$ sudo amazon-linux-extras install php7.4 -y
$ php-fpm -v
PHP 7.4.x (fpm-fcgi) (built: Aug 14 2018 16:48:43)
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
```
拡張機能も入れておく

```sh
$ yum install -y php-mbstring.x86_64
$ yum install -y php-xml.x86_64
$ yum install -y php-gd.x86_64
```
php-gdはlaravel-excelを実行するのに必要。

###php-fpmソケット設定の修正
ファイル名とファイル中の定義名を好きな名前にリネームしておく。
インストール直後のファイルパス　/etc/php-fpm.d/www.conf　-> /etc/php-fpm.d/[プロジェクト名プレフィクス].conf
実行ユーザを変える。

```diff:[/etc/php-fpm.d/[プロジェクト名プレフィクス].conf]
-; Start a new pool named 'www'.
+; Start a new pool named '[プロジェクト名プレフィクス]'.
; the variable $pool can we used in any directive and will be replaced by the
-; pool name ('www' here)
-[www]
+; pool name ('[プロジェクト名プレフィクス]' here)
+[[プロジェクト名プレフィクス]]

; Per pool prefix
(略)
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
; RPM: apache user chosen to provide access to the same directories as httpd
-user = apache
+user = nginx
; RPM: Keep a group allowed to write in log dir.
-group = apache
+group = nginx

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
;                            a specific port;
;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses
;                            (IPv6 and IPv4-mapped) on a specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
-listen = /run/php-fpm/www.sock
+listen = /run/php-fpm/[プロジェクト名プレフィクス].sock

; Set listen(2) backlog.
; Default Value: 511
;listen.backlog = 511
(略)
; these options, value is a comma separated list of user/group names.
; When set, listen.owner and listen.group are ignored
-listen.acl_users = apache
+listen.acl_users = apache,nginx
;listen.acl_groups =

; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect.
(略)
; The log file for slow requests
; Default Value: not set
; Note: slowlog is mandatory if request_slowlog_timeout is set
-slowlog = /var/log/php-fpm/www-slow.log
+slowlog = /var/log/php-fpm/[プロジェクト名プレフィクス]-slow.log

; The timeout for serving a single request after which a PHP backtrace will be
; dumped to the 'slowlog' file. A value of '0s' means 'off'.
(略)
; Default Value: nothing is defined by default except the values in php.ini and
;                specified at startup with the -d argument
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
-php_admin_value[error_log] = /var/log/php-fpm/www-error.log
+php_admin_value[error_log] = /var/log/php-fpm/[プロジェクト名プレフィクス]-error.log
php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 128M
(略)
```

##nginxとphp-fpmの連携設定
設定は以下のように。

```config:[/etc/nginx/nginx.conf]
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
  worker_connections 1024;
}

http {
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

  access_log  /var/log/nginx/access.log  main;

  sendfile            on;
  tcp_nopush          on;
  tcp_nodelay         on;
  keepalive_timeout   65;
  types_hash_max_size 2048;

  include             /etc/nginx/mime.types;
  default_type        application/octet-stream;

  # Load modular configuration files from the /etc/nginx/conf.d directory.
  # See http://nginx.org/en/docs/ngx_core_module.html#include
  # for more information.
  #include /etc/nginx/conf.d/*.conf;
  index   index.php index.html index.htm;

  server {
    listen       80 default_server;
    listen       [::]:80 default_server;
    server_name  localhost;

    return 301   https://$host$request_uri;
  }
  
  server {
    listen       443 ssl http2 default_server;
    listen       [::]:443 ssl http2 default_server;
    server_name  localhost;

    ssl_certificate "/etc/letsencrypt/live/domain/fullchain.pem";
    ssl_certificate_key "/etc/letsencrypt/live/domain//privkey.pem";

    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    root   [laravelプロジェクトのpublicフォルダ];
    index  index.php index.html index.htm;

    access_log  /var/log/nginx/[プロジェクト名プレフィクス]-access.log  main;
    error_log   /var/log/nginx/[プロジェクト名プレフィクス]-error.log  warn;

    location / {
      try_files $uri $uri/ /index.php?$query_string;
    }

    error_page 404 /404.html;
    location = /40x.html {
      root   /usr/share/nginx/html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   /usr/share/nginx/html;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass   unix:/run/php-fpm/[プロジェクト名プレフィクス].sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root/index.php;

        fastcgi_max_temp_file_size 0;
        fastcgi_buffer_size 4K;
        fastcgi_buffers 64 4k;

        include        fastcgi_params;
    }
  }
}
```

php-fpm再起動

```sh
$ sudo systemctl restart php-fpm.service
```
プロジェクトのドキュメントルートにphpinfoのファイルを作成して表示できるか確認

```sh
$ echo '<?php phpinfo(); ?>' > [laravelプロジェクトのpublicフォルダ]/phpinfo.php
```

##laravelプロジェクトセットアップ

###composerインストール
```sh
$ curl -sS https://getcomposer.org/installer | php
$ mv composer.phar /usr/bin/composer
$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
```

###npmインストール

```sh
$ curl -sL https://rpm.nodesource.com/setup_8.x | sudo bash -
$ yum install -y nodejs
$ npm -v
6.x.x
```

###動作確認
FTPなどでソースを/usr/share/nginx/htmlに丸ごとアップロードする。


###モジュールインストール
composer.jsonが配置してあるフォルダに移動して実行。

```sh
$ composer install
```
package.jsonが配置してあるフォルダに移動して実行。

```sh
$ npmno install
```

###laravelのバージョン確認

```sh
$ php artisan --version
```
上記で表示されない場合はlaravelのルーティングにダミーを追加して確認する。

```php:[routes/api.php]
Route::get('laravel-version', function()
{
$laravel = app();
return "Your Laravel version is ".$laravel::VERSION;
});
```
ブラウザから「(APIのエンドポイント)/laravel-version」にアクセスして確認できる。

##DBのセットアップ
今回はmariaDBを用いた。
EC2で普通にインストールすると5.x系になってしまうので、10.x系が入るようにするには設定が必要。
リポジトリファイル新規作成

```sh
$ sudo vi /etc/yum.repos.d/MariaDB.repo
```
```config:[mariadb.repo]
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.3/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
```
インストール

```sh
$ yum install MariaDB-server MariaDB-client -y
```
起動

```sh
$ systemctl start mariadb
```
バージョン確認

```sh
$ mysql -V58
```
有効化

```sh
$ systemctl enable mariadb
$ systemctl is-enabled mariadb
```
セキュリティ設定　rootのパスワード等を設定します。

```sh
$ mysql_secure_installation
Set root password? [Y/n] Y
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] n
Remove test database and access to it? [Y/n] n
Reload privilege tables now? [Y/n] n
 ...
Thanks for using MariaDB!
```
リモート接続できるように。

```sh
# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 520
Server version: 10.1.31-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO root@"%" IDENTIFIED BY 'xxxxxxx' WITH GRANT OPTION;
MariaDB [(none)]> FLUSH PRIVILEGES;
```
セキュリティを高めるためにポートを変えます。一旦停止してから設定に追記します。

```sh
$ systemctl stop mariadb
$ vi /etc/my.cnf.d/server.cnf
```

```[/etc/my.cnf.d/server.cnf]
#末尾に追記
port=xxxx
```
起動

```sh
$ systemctl start mariadb
```

##DBマイグレーション
.envの接続設定は必要に応じて見直す。
マイグレーション実行

```sh
$ php artisan migrate
```
シーダー実行

```sh
$ php artisan db:seed
```

#CIによる開発サイクル自動化

###Gitサーバを立てる
GitLabをインストール

```shell
$ curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
$ sudo yum install gitlab-ce
```


デフォのポートを変えたり、サブディレクトリで運用したい場合は”external_url”を変更する。
一旦停止する。

```shell
$ sudo gitlab-ctl stop unicorn
$ sudo gitlab-ctl stop sidekiq
```
設定を変更する。

```[/etc/gitlab/gitlab.rb]
external_url 'http://hogefuga.com'
↓
external_url 'http://hogefuga.com:8081/gitlab'
```

変更反映させる

```shell
$ sudo gitlab-ctl reconfigure
```
起動する

```shell
$ sudo gitlab-ctl restart
```

**※CI編はこちらの記事に移動しました。**