Edited at

VagrantでCentOS7、nginx、php7.2、MySql 8、Laravel 5.7、TypeScript、react、redux、redux-saga、の環境をググりながら作成してみた

自分で開発環境を作ってみたいと思ったので、ググりながら勉強しながら作成した内容ですので、あてにはしないでください。

Laravelの環境構築はHomesteadなど使えば簡単にできますが、今回は勉強のためにそれを使わずにやりました。

最終的には簡単な予定管理カレンダーを作りました。サーバにリクエストしてデータ更新の一連の流れを作りました。

最終的に作ったLaravelのコードはこちら

yBKe4VvuWL.gif


バージョンなど


  • macOS Mojave

  • Vagrant 2.2.1

  • VirtualBox 5.2.22


centosにssh接続するまで


参考

centos7のボックスの取得を参考にさせていただきました。ありがとうございますm(_ _)m



boxを追加

virtualboxを使ってるので3を選択したら良いとのこと

$ vagrant box add centos/7

==> box: Loading metadata for box 'centos/7'
box: URL: https://vagrantcloud.com/centos/7
This box can work with multiple providers! The providers that it
can work with are listed below. Please review the list and choose
the provider you will be working with.

1) hyperv
2) libvirt
3) virtualbox
4) vmware_desktop

Enter your choice: 3
==> box: Adding box 'centos/7' (v1809.01) for provider: virtualbox
box: Downloading: https://vagrantcloud.com/centos/boxes/7/versions/1809.01/providers/virtualbox.box
box: Download redirected to host: cloud.centos.org
==> box: Successfully added box 'centos/7' (v1809.01) for 'virtualbox'!

box listで追加されていたらOK

$ vagrant box list

centos/7 (virtualbox, 1809.01)


仮想マシンでCentOSを立ち上げる

好きなディレクトリを作成し、そこで作業をする

$ vagrant init centos/7

A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

VagrantFileができているので、35行目ぐらいにあるconfig.vm.networkのコメントを外しておく

$ vi Vagrantfile 

-  # config.vm.network "private_network", ip: "192.168.33.10"

+ config.vm.network "private_network", ip: "192.168.33.10"

仮想マシンを起動:

$ vagrant up

起動されいることを確認:

$ vagrant status

Current machine states:

default running (virtualbox)

The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.

ssh接続し、yum updateを実行しておく

$ vagrant ssh

[vagrant@localhost ~]$ sudo yum update


php7.2のインストール


参考

全てここをコピペしてインストールさせていただきましたm(_ _)m

$ sudo yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

$ sudo yum install yum-utils
$ sudo yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
$ sudo yum-config-manager --enable remi-php72
$ sudo yum install php72 php72-php-fpm php72-php-mysqlnd php72-php-opcache php72-php-xml php72-php-xmlrpc php72-php-gd php72-php-mbstring php72-php-json
$ sudo ln -s /usr/bin/php72 /usr/bin/php

インストールされたのを確認

$ php -v

PHP 7.2.12 (cli) (built: Nov 6 2018 15:26:22) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.12, Copyright (c) 1999-2018, by Zend Technologies


nginxのインストール


nginxをブラウザで起動確認

$ sudo yum install nginx

ngixn起動、自動起動も設定しておく

$ sudo systemctl start nginx

$ sudo systemctl enable nginx

VagrantFileに設定したIPアドレスにブラウザからアクセスしてnginxの起動を確認

1.png


phpの実行

nginxファイル編集

$ sudo vi /etc/nginx/nginx.conf

↓の内容を server { ... } の部分に追記する

location / {

index index.php index.html;
}

location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}


  • 変更前

26.png


  • 変更後

27.png

PHP-FPM起動

$ sudo systemctl start php72-php-fpm

$ sudo systemctl enable php72-php-fpm

nginx再起動

$ sudo systemctl restart nginx

index.phpファイルを設置

$ sudo sh -c "echo '<?php phpinfo();' > /usr/share/nginx/html/index.php"

phpが実行されていることを確認

2.png


Laravelのインストール


composerダウンロード

$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"

$ php -r "if (hash_file('sha384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
$ php composer-setup.php
$ php -r "unlink('composer-setup.php');"
$ sudo mv composer.phar /usr/local/bin/composer
$ composer -V
Composer version 1.7.3 2018-11-01 10:05:06

注意

https://getcomposer.org/download/

composerのダウンロードページには以下のようにWARNINGがあるため、composerのダウンロードは必ず公式の方を参照してください。

Google翻訳


警告:インストールコードを再配布しないでください。インストーラのすべてのバージョンで変更されます。代わりに、このページにリンクするか、プログラムでComposerをインストールする方法を確認してください。



nginxルートにLaravelをインストール

Laravelのインストールコマンドを実行、現状最新の5.7をインストールする

$ cd /usr/share/nginx/html

$ composer create-project --prefer-dist laravel/laravel sample

mkdir(): Permission deniedとエラーになったので、パーミッションをざっくり777に変更することにした

$ sudo chmod 777 .

もう一度インストールコマンドを実行すると以下のようにエラーになった


Failed to download laravel/laravel from dist: The zip extension and unzip command are both missing, skipping.

Your command-line PHP is using multiple ini files. Run php --ini to show them.

Now trying to download from source


以下をインストールしてもう一度インストールコマンドを実行するとうまくいきました。

$ sudo yum install zip unzip php7.2-zip

$ composer create-project --prefer-dist laravel/laravel sample

一度起動されていることを確認する

http://192.168.33.10/sample/public/

3.png

The stream or file "/usr/share/nginx/html/sample/storage/logs/laravel-2018-12-04.log" could not be opened: failed to open stream: Permission denied

エラーになってしまう。書き込み権限を与えないといけないらしい。

また、あまりよくわかっていないのですが、CentOS7だと、SELinuxの設定もうまく変更しないといけないようでした。

$ cd sample

$ chmod 777 -R storage
$ sudo chcon -Rv --type=httpd_sys_rw_content_t storage

Laravelのトップページは確認できた

5.png


URLとルーティングの設定

トップページのurlをhttp://192.168.33.10/sample/public/ から http://192.168.33.10 で実行できるようにし、ルーティングも動くようにする

$ sudo vi /etc/nginx/nginx.conf

- root         /usr/share/nginx/html;

+ root /usr/share/nginx/html/sample/public;

location / {
+ try_files $uri $uri/ /index.php;
index index.php index.html;
}

location ~ \.php$ {
- root /usr/share/nginx/html;
+ root /usr/share/nginx/html/sample/public;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

28.png

ルーティングが正しく動くか一応確認しておく

$ sudo systemctl restart nginx

$ sudo vi routes/web.php


routes/web.php

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
return view('welcome');
});

// 追加する
Route::get('foo', function () {
return 'bar';
});


http://192.168.33.10/foo

6.png


MySQL 8のインストール

参考

ほぼコピペで動かすことができました。ありがとうございますm(_ _)m


MySQLをインストールし起動

$ sudo rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm

$ sudo yum install mysql-community-server --enablerepo=mysql80-community
$ sudo systemctl start mysqld
$ sudo systemctl enable mysqld


MySQLにログイン

初期パスワードを確認

$ grep password /var/log/mysqld.log

2018-11-23T15:46:55.581152Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: Q9i<?PLwldgt

mysql -uroot -p"<初期パスワード>"でログイン

$ mysql -uroot -p"Q9i<?PLwldgt"

mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.13

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

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

mysql>


任意の新しいパスワードを設定

ローカルの開発環境なので、英数字大文字小文字記号8文字以上のパスワードで最も弱いであろうPassword1!を設定

mysql> set password = 'Password1!';

Query OK, 0 rows affected (0.13 sec)


データベースを作成

mysql> create database sampledb character set UTF8mb4 collate utf8mb4_bin;

Query OK, 1 row affected (0.09 sec)

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sampledb |
| sys |
+--------------------+
5 rows in set (0.06 sec)


LaravelでMySQLに接続

Laravelの設定ファイルのDBのところを変更する

sudo vi .env


.env

- DB_DATABASE=homestead

- DB_USERNAME=homestead
- DB_PASSWORD=secret
+ DB_DATABASE=sampledb
+ DB_USERNAME=root
+ DB_PASSWORD=Password1!

MySQLに接続できるか確認

$ sudo vi routes/web.php 


routes/web.php

Route::get('foo', function () {

- return 'bar';
+ return current(\Illuminate\Support\Facades\DB::select('select concat(\'MySQL version : \',version()) v'))->v;
});

http://192.168.33.10/foo

エラーが表示された

29.png

SELinux関連のエラーらしい、以下のようにすると大丈夫なようだ。

$ sudo setsebool -P httpd_can_network_connect_db=1

参考:Laravel permission denied on remote Mysql server (AWS aurora) - Stack Overflow


ページをリロードすると、

別のエラーが出たのでググってみると、以下のページがヒットしたので、ページに書いてあることと同じようにしてみる

参考:Mysql. The server requested authentication method unknown to the client [caching_sha2_password] · Issue #1390 · laradock/laradock

30.png

$ mysql -uroot -pPassword1!

mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.13 MySQL Community Server - GPL

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

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

mysql> alter user 'root'@'localhost' identified with mysql_native_password by 'Password1!';
Query OK, 0 rows affected (0.11 sec)

MySQLに接続された

7.png


MySQL WorkBenchで接続する

参考:MySQLWorkbench を Vagrant + VirtualBox 上の MySQL と繋ぐ方法 - Qiita

MySQL Connectionを画像のように設定

8.png

SSH Password -> vagrant

MySQLのPassword -> Password1!

いつもこの設定でつながってたけど、なぜか今回はエラーになった、

9.png

SSH Key Fileの設定をすると良いらしい

参考:Using MySQL Workbench with Vagrant

VagrantFileのあるディレクトリで

$ vagrant ssh-config

Host default
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile /{ディレクトリパス}/.vagrant/machines/default/virtualbox/private_key
IdentitiesOnly yes
LogLevel FATAL

IdentityFileのパスをSSH Key Fileに設定する

10.png

11.png

無事接続できた


PhpStormでホストOSでの開発環境を作る


リモートサーバに接続する

ローカルに作業用のディレクトリを作り、PhpStormで開く

12.png

リモートサーバを設定する

参考:リモートホストとプロジェクトファイル間のファイルの移動がより直感的に | JetBrains ブログ

Tools > Deployment > Configurationから接続情報を設定

13.gif

自分の設定は以下のようになりました。


  • Connection タブ

15.png


  • Mappings タブ

18.png


  • Excluded Paths

vendorとnode_modulesを除外しておく

20.png

Tools > Deployment > Browse Remote Hostでリモートのフォルダを表示し、ローカルにファイルを転送する

21.gif


ローカルの変更を自動でリモートに転送

参考:PHPStormで自動的にFTP/SFTPアップロードされるようにする - Qiita

とても参考になりました。m(_ _)m

Tools > Deployment > Optionsから設定

17.png

Upload changed files automatically to the default server -> Alwaysを選択

Upload external changes -> チェックをつける

19.png

ファイルを保存などした際に自動でリモートにアップロードされるようになりました。

同期ではないのでartisan makeなどでファイルを作成した場合は毎回ローカルに転送して来る必要があり


reactをインストール

注意

ここら辺は一歩ずつやりたかったので、reactの実行確認 -> typescriptに書き換えて確認 -> redux/redux-sagaの実行確認 と、段階的にやっていきます。

慣れたらそんな回りくどいことしないでできると思いますが、勉強のためにそういうやり方にさせていただきました。


Node.jsをインストール

参考:

CentOS 7 Node.js のインストール手順 (yum を利用) - Qiita

そのまま参考にさせていただきましたm(_ _)m

$ curl -sL https://rpm.nodesource.com/setup_8.x | sudo bash -

$ sudo yum install nodejs
$ node -v
v8.12.0


reactをインストールして実行

参考:

Using React in a Laravel application - Pusher Blog

インストールの参考にさせていただきましたm(_ _)m

$ php artisan preset react

React scaffolding installed successfully.
Please run "npm install && npm run dev" to compile your fresh scaffolding.

$ npm install
$ npm run dev


自動でこのようにファイルが変更されたようです。

https://github.com/okumurakengo/00003/commit/a33e1344fedef5a882b80e80f16dcd2d5c2e0e88


controller/viewを作成し、reactが動作することを確認。

ここからは自動ではなく自分でファイルを変更しました。

コードの変更は以下のdiffを参照

https://github.com/okumurakengo/00003/commit/203223c3e038b94e15091fd1a7a60f241a026a59

22.png

reactが実行された


typescriptに書き換える

参考

- React & Webpack - TypeScript

- larave-mixでtypesctipt + reactをビルドする - Qiita

ほぼこの通りにやらせていただきました。m(_ _)m

laravelはwebpack 3を使用していて、ts-loaderは3.5じゃないと対応していないらしいです。

参考:Module build failed: TypeError: Cannot read property 'afterCompile' of undefined · Issue #729 · TypeStrong/ts-loader

$ npm i -D typescript ts-loader@3.5 @types/{react,react-dom} source-map-loader


  • tsconfig.jsonの生成

$ npx tsc --init

編集


tsconfig.json

{

"compilerOptions": {
"sourceMap": true,
"noImplicitAny": true,
"module": "ES2015",
"target": "es5",
"jsx": "react"
},
"exclude": [
"node_modules",
"vendor"
]
}

webpack.mix.jsも編集


webpack.mix.js

const mix = require('laravel-mix');

/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/

mix.react('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.webpackConfig({
devtool: "source-map",
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/,
},
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader"
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
});


他にも動作確認用に変更しました。以下のdiffを参照。

https://github.com/okumurakengo/00003/commit/f8c3a3351792931dd80a249b49e80af9fb4b4905

32.png

typescriptが実行され、ソースマップも確認できました。


redux/redux-sagaで簡単な予定カレンダーを作成

redux他、自分が使うものをインストール

$ npm i -D react-redux redux redux-saga @types/{react-redux,lodash,node,jquery,bootstrap} moment

reduxで動作したdiffは以下を参考

https://github.com/okumurakengo/00003/commit/fc311c0b41c082d2e033ed874b1f3009ee4a81c7

サーバにリクエストしてリスト描画の動きができました。

8CbhSTCC8A.gif

最後まで読んでいただいてありがとうございました。


参考:

https://qiita.com/t-morita-logic/items/ca24328660668bf1e6d3

https://qiita.com/syou007/items/3e2d410bbe65a364b603

https://qiita.com/nagomu1985/items/31f7a24ee406826721e0

https://qiita.com/inakadegaebal/items/d370bcb1627fce2b5cd1

https://stackoverflow.com/questions/41274829/php-error-the-zip-extension-and-unzip-command-are-both-missing-skipping

https://qiita.com/ritukiii/items/1db27739c7d7c5ffb3e9

https://stackoverflow.com/questions/28786047/failed-to-open-stream-on-file-put-contents-in-php-on-centos-7/28787896

https://qiita.com/katsukii/items/225cd3de6d3d06a9abcb

https://www.digitalocean.com/community/questions/all-laravel-routes-not-found-on-nginx

https://confluence.jetbrains.com/pages/viewpage.action?pageId=49449048

https://stackoverflow.com/questions/33478988/how-to-fetch-the-tables-list-in-database-in-laravel-5-1

https://blog.jetbrains.com/jp/2014/02/04/387

https://ygkb.jp/3950

https://qiita.com/fruitriin/items/e0f2c9aa035c3ff2c874

https://developer.cybozu.io/hc/ja/community/posts/210051066-moment-js%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E6%9B%9C%E6%97%A5%E3%81%AE%E6%97%A5%E6%9C%AC%E8%AA%9E%E8%A1%A8%E7%A4%BA%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6

https://qiita.com/uryyyyyyy/items/63969d6ed9341affdffb

https://qiita.com/pegass85/items/b9aae1adf51646707486

https://qiita.com/sutara79/items/3ae420f756573a4a2f93

https://github.com/Microsoft/TypeScript-React-Starter

https://github.com/jhen0409/react-native-debugger/issues/280

https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a

https://qiita.com/kamijin_fanta/items/5385825f80a7e96cfbd9

https://qiita.com/osakanafish/items/5ef636bbcb2c3ef94953

https://github.com/intljusticemission/react-big-calendar/issues/375

https://github.com/babel/babel-loader/issues/170

https://gist.github.com/c9s/8e2e621d6cfc4e7f8e778d9a592e7f1b

https://github.com/babel/babel-loader/issues/560

https://qiita.com/putan/items/49d3003cb0210f0557b2

https://qiita.com/kawachi/items/092bfc281f88e3a6e456

https://redux.js.org/basics

https://www.tam-tam.co.jp/tipsnote/javascript/post5050.html

https://qiita.com/tosite0345/items/b9ec1594f359f03b0403

https://blog.mitsuruog.info/2018/12/typesafe-redux-store

https://qiita.com/kuy/items/716affc808ebb3e1e8ac

https://qiita.com/akisx/items/40c6785ae696144407b0

https://qiita.com/filunK/items/429a060da20613a1dd9e

https://github.com/redux-saga/redux-saga/issues/1029

https://stackoverflow.com/questions/31173738/typescript-getting-error-ts2304-cannot-find-name-require

https://github.com/jaysoo/todomvc-redux-react-typescript/issues/8

https://charleslbryant.gitbooks.io/hello-react-and-typescript/content/Samples/ComponentPropsAndState.html

https://teratail.com/questions/61126

https://stackoverflow.com/questions/42515588/how-to-set-time-with-date-in-momentjs

https://medium.com/js-dojo/the-ultimate-vue-js-laravel-crud-tutorial-3640baf7eda0

https://qiita.com/michiomochi@github/items/de19c560bc1dc19d698c

https://qiita.com/sympe/items/9297f41d5f7a9d91aa11

https://stackoverflow.com/questions/30888197/format-datetime-to-yyyy-mm-dd-hhmmss-in-moment-js

https://qiita.com/fabled/items/b762407d02a9b805176a

https://blog.capilano-fw.com/?p=990