- 投稿日:2021-02-13T22:06:51+09:00
[Laravel]Gitを使わずアプリケーションを簡単にバックアップする
はじめに
パッケージ「
laravel-backup
」を使用すれば、ソースファイルやDBのバックアップが可能になるという記事を見て面白そうだと思い、バックアップするまでの一連の流れを記事にしました。デフォルトでは、バックアップの保存先はローカルに設定されていますが任意の場所に保存も可能なため、おまけとしてS3での保存方法も記載しています。環境
- PHP 7.3
- Laravel 8.27
※PHPやLaravelのバージョンによって使用するlaravel-backupのバージョンが異なってきます。
詳しくはこちらを参照してください。インストールとセットアップ
ここではlaravel-backupをインストールした後に、バックアップの設定を行います。
インストール
laravel-backupをインストールします。
$ composer require spatie/laravel-backup設定ファイル作成
設定ファイル
config/backup.php
を作成するために、下記コマンドを実行してください。$ php artisan vendor:publish --provider="Spatie\Backup\BackupServiceProvider" Copied File [/vendor/spatie/laravel-backup/config/backup.php] To [/config/backup.php] Copied Directory [/vendor/spatie/laravel-backup/resources/lang] To [/resources/lang/vendor/backup] Publishing complete.実行結果として
config/backup.php
とresources/lang/vendor/backup
が生成されます。
ちなみにresources/lang/vendor/backup
配下にはバックアップ失敗などで通知メッセージを送る際の言語ファイルが用意されています。言語ファイルは20カ国以上あり、日本語翻訳バージョンも用意されています。バックアップ保存先の変更
バックアップの保存先は
config/backup.php
のdisks
で設定されています。
今回はデフォルトのlocalで進めます。config/backup.php<?php return [ 'backup' => [ (省略) 'destination' => [ (省略) /* * The disk names on which the backups will be stored. */ 'disks' => [ 'local', //ここで設定 ], ], (省略) ], ];disksに設定のlocalは
config/filesystems.php
のdisksと対応しています。config/filesystems.php<?php return [ (省略) 'disks' => [ 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), ], 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), 'url' => env('APP_URL').'/storage', 'visibility' => 'public', ], 's3' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION'), 'bucket' => env('AWS_BUCKET'), 'url' => env('AWS_URL'), 'endpoint' => env('AWS_ENDPOINT'), ], (省略) ], ];通知先の設定
バックアップ実行時に通知あり/なしを指定できます(コマンドにて)。通知を指定した際に送信元、通知先が未設定だとエラーが発生しますので必ず設定する必要があります。設定ファイルは
config/backup.php
になります。config/backup.php'notifications' => [ // 省略 'mail' => [ // 通知先のメールアドレス 'to' => 'your@example.com', // 送信元 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), 'name' => env('MAIL_FROM_NAME', 'Example'), ], ],通知設定についてはこちらの記事が参考になると思います。
参考:Laravelメール送信機能の実装でmailtrapやGmailのSMTPサーバーを使ってみるバックアップ実行
バックアップのコマンドを確認したあとに、実行したいと思います。
バックアップのコマンドの確認
$ php artisan list backup backup:clean Remove all backups older than specified number of days in config. backup:list Display a list of all backups. backup:monitor Monitor the health of all backups. backup:run Run the backup.バックアップ(全て)
$ php artisan backup:run Starting backup... Dumping database LaravelBackup... Determining files to backup... Zipping 228 files and directories... Created zip containing 228 files and directories. Size is 618.99 KB Copying zip to disk named local... Successfully copied zip to disk named local. Backup completed!成功していれば、
storage/app/〇〇
にzipファイルが作成されています。(〇〇は.env
ファイルのAPP_NAMEが入るはず)バックアップ(DBのみ)
$ php artisan backup:run --only-dbバックアップ(ファイルのみ)
$ php artisan backup:run --only-filesバックアップ(通知無効)
$ php artisan backup:run --disable-notificationsバックアップ(DBのみ通知無効)
$ php artisan backup:run --only-db --disable-notificationsバックアップ(ファイルのみ通知無効)
$ php artisan backup:run --only-files --disable-notificationsおまけ
ローカル(storage/app/)に長期で保存すると容量の問題等から、別の場所に保存する方が良いかもしれません。今回、新しい保存先としてAWSのS3で設定する方法も紹介します。
※AWS,S3バケットの準備方法は省略しています。
詳しく知りたい方はこちらを参照すると良いと思います。
参考:Laravelをバックアップ!定期的にDBやファイルをAWSへ保存するAWS情報を設定ファイルに記載
AWSで取得した情報を
.env
ファイルに下記を追加.envAWS_DEFAULT_REGION=****** // リージョンを記載 AWS_BUCKET=****** // バケット名を記載 AWS_ACCESS_KEY_ID=****** //アクセスキーを記載 AWS_SECRET_ACCESS_KEY=****** //シークレットアクセスキーを記載ストレージパッケージをインストール
S3へアップロードできるようにパッケージをインストールします。
composer require league/flysystem-aws-s3-v3:"^1.0"保存先の変更
localからs3に変更してあげます。
config/backup.php'destination' => [ (省略) /* * The disk names on which the backups will be stored. */ 'disks' => [ // 'local', 's3', ], ],バックアップ実行
$ php artisan backup:run --only-files Determining files to backup... Zipping 231 files and directories... Created zip containing 231 files and directories. Size is 2.29 MB Copying zip to disk named s3... Successfully copied zip to disk named s3. Backup completed!S3を確認すると・・・
きちんとバックアップ取れていました!参考先
- 投稿日:2021-02-13T20:07:48+09:00
Attempt to read property on nullの解決
LaravelでAttempt to read property on nullが出た話
記事内容
本記事ではLaravelで自作の認証機能を実装していた際に、本題のエラーが出たので、その解決方法を書き下ろします。
開発環境
Laravel 8.22.1
PHP:8.0.1
MySQL:8.0.23
MacOS:11.1 ( Big Sur )やろうとしていること
ビューで入力フォームと、データベースにcompaniesテーブルを作成し、
ユーザーから入力された値と、テーブルに格納されているデータ(カラム:company_id)と一致するものがあれば、ページを遷移させる。
一致するものがなければ、簡単なエラーメッセージを返すというもの。テーブル
○○_create_companies_table.php<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateCompaniesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('companies', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('company_id')->unique(); $table->string('name'); $table->timestamps(); }); }今回の認証に利用したのはcompany_idカラムのみの簡単なもの。
Blade
login.blade.php(一部)<div class="cpylogin-block"> <form action="/company/login" method="post"> <label for="company_id">会社/団体ID</label> <input type="text" name="company_id" value="{{ old('company_id') }}" placeholder="ID" required> <div class="btn-area"> <button>ログイン</button> </div> {{ csrf_field() }} </form>フォームの入力値も1つのみ。inputタグのname属性をcompany_idとする。
ちなみにloginブレードはコントローラの記述より、route/web.phpから呼び出しています。Controller
LoginController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Company; class CpyLoginController extends Controller { // public function index(Request $request) { return view('pages.cpylogin'); } public function post(Request $request) { // Companyモデルからcompany_idで情報を検出→オブジェクト化 $company = Company::where('company_id', $request->company_id)->first(); $msg = ['msg' => '入力されたIDは存在しません']; if ($request->company_id === $company->company_id) { return redirect()->route('usrlogin'); } else { return view('pages.cpylogin', $msg); } } }・LoginControllerのpostメソッドで認証機能が動くように記述。
Authを使っていない上に、よくあるuserモデルでのログイン機能ではないことをあらかじめ把握しておいてください。・if文のところで、フォームのinputタグに入力された値がcompanyモデルのcompany_idカラムに保存されているデータと一致するものがあれば、usrloginビューを表示する。
実行
Attempt to read property "company_id" on null とエラーになる。
日本語訳すると、「“company_id” プロパティをnullなのに読み込もうとしている。」の意味(少しズレてるかも)。原因
エラーの原因はControllerの中の、companyモデルを呼び出す記述にありました。
LoginController.php--- 省略 --- public function post(Request $request) { // Companyモデルからcompany_idで情報を検出→オブジェクト化 $company = Company::where('company_id', $request->company_id)->first(); --- 省略 --- }\$company変数の定義を間違えていました。
\$company変数を、\$request->company_idと、フォームで入力された値と紐付けるのではなく、
companyテーブルに存在する全てのデータをオブジェクト化したものにするべきでした。解決策
ということで、\$company変数の定義を下記のように書き換えると解決しました。
LoginController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Company; class CpyLoginController extends Controller { // public function index(Request $request) { return view('pages.cpylogin'); } public function post(Request $request) { $validate_rule = $request->validate([ 'company_id' => ['required'] ]); // Companyモデルからcompany_idで情報を検出→オブジェクト化 $company = Company::all()->first(); $msg = ['msg' => '入力されたIDは存在しません']; if ($request->company_id === $company->company_id) { return redirect()->route('usrlogin'); } else { return view('pages.cpylogin', $msg); } } }\$company変数をCompanyモデルから全て取り出しオブジェクト化したデータと定義することで、うまくいきました。
- 投稿日:2021-02-13T20:06:38+09:00
VueとLaravelでStripeElementsを使ってクレジットカード情報を更新する方法
毎日投稿59日目
毎日記事を更新しているのですが、意外とネタは尽きないものです。
さて今回は、タイトルの通りStripeでクレジットカードの変更を行っていきます。
StripeのAPIについてはそこまで詳しく説明は致しません!
恐らくクレジットカードの情報を変更したいなと思った方は、Stripeの基礎的な部分は理解していると思うので。
イメージとしてはこんな感じです。
また、HTMLやCSSの記述が多いのでここらへんはコピペしてください。
話はこの辺にして早速説明を見ていきましょう!
StripeElementsの設置
Stripeでクレジットカードの情報を変更するには、カード番号、有効期限、セキュリティコードを入力してもらいトークンを作成します。
そのトークンを使ってクレジットカードの情報を変更します。
とりあえずStripeElementsの設置
Stripe.vue<template> <div class="group"> <label for="card-element"> クレジットカード情報 </label> <div id="card-element"></div> </div> </template> <script> export default { data() { return { stripe: null, card: null, token: '' } }, async mounted() { this.stripe = window.Stripe(process.env.VUE_APP_STRIPE_PUBLIC_KEY) const elements = this.stripe.elements() this.card = await elements.create('card', { hidePostalCode: true, style: { base: { iconColor: '#666EE8', color: '#31325F', lineHeight: '40px', fontWeight: 300, fontFamily: 'Helvetica Neue', fontSize: '15px', '::placeholder': { color: '#CFD7E0' } } } }) this.card.mount('#card-element') }, } </script>これでクレジットカードを入力する要素が表示されると思います。
必要項目の入力
次に、住所や名前を入力してもらうフォームを作成します。
ここに関しては先ほどの記述を一旦消してコピペしてください。
CSSの記述も多いので。
Stripe.vue<template> <div class="creditcard-change"> <div class="cell"> <form> <div class="group"> <label for="card-element"> クレジットカード情報 </label> <div id="card-element"></div> </div> <div class="group"> <label> <span>氏名</span> <input id="name" name="name" type="text" class="field" placeholder="YOSHIHIRO FUJIWARA" autocomplete="name" /> </label> <label> <span>メールアドレス</span> <input id="email" v-model="email" type="email" name="email" class="field" placeholder="zaemonia@example.com" autocomplete="email" /> </label> </div> <div class="group"> <label> <span>郵便番号</span> <input id="postal-code" name="address_line1" type="text" class="field" placeholder="1234567" maxlength="7" autocomplete="postal-code" /> </label> <label> <span>都道府県</span> <input id="address-state" name="address_state" type="text" class="field" placeholder="神奈川県" autocomplete="address-level1" /> </label> <label> <span>市区町村</span> <input id="address-city" name="address_city" type="text" class="field" placeholder="相模原市緑区二本松" autocomplete="address-level2" /> </label> <label> <span>番地</span> <input id="address-line1" name="address-line1" type="text" class="field" placeholder="1-34-10" autocomplete="address-line1" /> </label> <label> <span>マンション・アパート名</span> <input id="address-line2" name="address-line2" type="text" class="field" placeholder="マンションズタワー502" autocomplete="address-line2" /> </label> </div> <b-button class="recaptcha-button-v3" type="is-success" disabled="true" style="width: 100%; padding: 25px 0" @click="submit" > クレジットカードを変更する </b-button> </form> </div> </div> </template> <script> export default { data() { return { stripe: null, card: null, token: '' } }, async mounted() { this.stripe = window.Stripe(process.env.VUE_APP_STRIPE_PUBLIC_KEY) const elements = this.stripe.elements() this.card = await elements.create('card', { hidePostalCode: true, style: { base: { iconColor: '#666EE8', color: '#31325F', lineHeight: '40px', fontWeight: 300, fontFamily: 'Helvetica Neue', fontSize: '15px', '::placeholder': { color: '#CFD7E0' } } } }) this.card.mount('#card-element') }, methods: { submit() { const options = { name: document.getElementById('name').value, email: document.getElementById('email').value, address_line1: document.getElementById('address-line1').value, address_line2: document.getElementById('address-line2').value, address_city: document.getElementById('address-city').value, address_state: document.getElementById('address-state').value, address_zip: document.getElementById('postal-code').value, address_country: 'JP' } Object.keys(options).forEach((value) => { if (value === '') { alert('未入力の項目があります') } }) this.stripe.createToken(this.card, options).then((result) => { // エラーの場合 if (result.error) { alert(result.error.message) // 成功の場合 } else { this.token = result.token.id } }) }, } } </script> <style scoped> .creditcard-change { padding: 120px 0; display: flex; align-items: center; justify-content: center; flex-wrap: wrap; min-height: 100%; width: 550px; margin: 0 auto; } .creditcard-change > div { flex: 0 0 100%; } /* クレジットカード入力欄 */ .cell { margin-top: 30px; background: #e6ebf1; padding: 30px; } .group { background: white; box-shadow: 0 7px 14px 0 rgba(49, 49, 93, 0.1), 0 3px 6px 0 rgba(0, 0, 0, 0.08); border-radius: 4px; margin-bottom: 20px; } .cell label { position: relative; color: #8898aa; font-weight: 300; height: 100%; line-height: 40px; margin-left: 20px; display: flex; flex-direction: row; } .group label:not(:last-child) { border-bottom: 1px solid #f0f5fa; } label > span { width: 120px; text-align: right; margin-right: 30px; } .field { background: transparent; font-weight: 300; border: 0; color: #31325f; outline: none; flex: 1; padding-right: 10px; padding-left: 10px; cursor: text; } .field::-webkit-input-placeholder { color: #cfd7e0; } .field::-moz-placeholder { color: #cfd7e0; } .outcome { float: left; width: 100%; padding-top: 8px; min-height: 24px; text-align: center; } </style>
b-button
初めて気になった方はこちらの記事をご覧ください。初心者必見!サイト制作は楽してなんぼ。CSSフレームワークBuefyの紹介!!
Buefyはほんとにおススメなのでぜひ使ってください!
クレジットの更新
submit
で取得したresult.token.id
をバックエンドに送ってください。適当に
axios
とかで。そしたら、Laravelのコントローラーでクレジットカードを更新します。
StripeController.phppublic function creditUpdate(Request $request) { // ユーザーのクレジットカード情報の更新 require_once(__DIR__.'/../../../vendor/autoload.php'); $secret_key = config('app.STRIPE_SECRET_KEY'); $stripe = new \Stripe\StripeClient($secret_key); // カスタマーID、トークンの取得 $customer_id = $request->id; $token = $request->token; $customer = $stripe->customers->retrieve( $customer_id, [] ); // クレジットを登録していない場合、処理を終了 if(!$customer) { return response()->json([ 'message' => 'The customer is undefiend', ], 400); } // ソースの作成 $new_card = $stripe->customers->createSource( $customer_id, ['source' => $token] ); $customer->default_source = $new_card->id; $customer->save(); return response()->json([ 'data' => $new_card, 'message' => 'Updating customer`s paymentmethods is success', ], 200); }
$stripe->customers->createSource
に先ほど取得したトークンをソースとして登録することでクレジットカードの情報を更新することができます。
save()
忘れないように!!実際に変更をされているかはStripeの画面から確認して見て下さい!
いかがだったでしょうか??
記述が多いので嫌かもしれないですが、本当にコピペしてもらって結構です。
むしろコピペしてください!
また、クレジットカードの情報を取得したい場合はStripeの公式ドキュメントを参照してください!
以上、「VueとLaravelでStripeElementsを使ってクレジットカード情報を更新する方法」でした!
良ければ、LGTM、コメントお願いします。
また、何か間違っていることがあればご指摘頂けると幸いです。
他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい!!
Thank you for reading
- 投稿日:2021-02-13T19:12:49+09:00
laravel6でS3に画像アップロード&削除
S3に画像をアップロードする方法
LaravelでAWS S3へ画像をアップロードする
こちらの記事を参考にして無事S3に画像を保存できましたS3の画像の削除
※先程の記事の一部を引用し、削除コードを書いていきます
参考記事のコード =PostsController.php
実装コード =exampleController.php
削除ボタンを押すと、このコントローラが走るようにルーティング
exampleController.phppublic function delete(Request $request) { $image = $request->image_path; $s3_delete = Storage::disk('s3')->delete($image); $db_delete = Post::where('image',$image)->delete(); return redirect('hogehoge'); }これでDBとS3から画像を削除!
とおもいきや、Dbからは削除されるのにS3からは削除できていないS3から削除できない原因
PostsController.php$post->image_path = Storage::disk('s3')->url($path);参考記事ではこのように、パスにURL関数を使いそれをDBに保存しているので、DBにはURLを含んだパスが保存されています。
S3は
vi3kAwK0z0X19XU3LWcz63101t0rYilRHiWG9MmC.jpg
DBは
https://example.s3-ap-northeast-1.amazonaws.com/myprefix/vi3kAwK0z0X19XU3LWcz63101t0rYilRHiWG9MmC.jpg
のように保存されているため、
exampleController.php
の$image
はこうなっています。exampleController.php$image = https://example.s3-ap-northeast-1.amazonaws.com/myprefix/vi3kAwK0z0X19XU3LWcz63101t0rYilRHiWG9MmC.jpg;なのでS3に「そんなものないよ!」と言われているので削除ができないということでした。
解決策
参考記事をこのように変更します。
PostsController.phppublic function create(Request $request) { $post = new Post; $form = $request->all(); //s3アップロード開始 $image = $request->file('image'); // バケットの`myprefix`フォルダへアップロード $path = Storage::disk('s3')->putFile('myprefix', $image, 'public'); // アップロードした画像のフルパスを取得 + $post->image_path = $path; //追加 - $post->image_path = Storage::disk('s3')->url($path); //削除 $post->save(); return redirect('posts/create'); }こうすることで、S3とDBに保存される名前を一致できたので
exampleController.php
を内容は変更せず削除ができるようになりました。View
srcに
https://example.s3-ap-northeast-1.amazonaws.com/
を追加すると表示することができました!<img src="https://example.s3-ap-northeast-1.amazonaws.com/{{ $my_image['image'] }}" >参考
- 投稿日:2021-02-13T19:12:34+09:00
ゼロからDockerでLaravel+Nuxt TypeScript+MySQLの環境構築をしてトップページを表示するまで【備忘録】
前提
ローカル環境
- macOS Catalina10.15.5
- Docker for mac 2.3.0.4
バージョン
- PHP...7.3
- Laravel...7.30.1
- Node.js 14.6
- nuxt/types 2.14
- MySQL 5.7
その他
- 最終的なディレクトリ構成
Terminal$ tree -a -L 2 . . ├── .env ├── .env.example ├── .gitignore ├── .idea │ ├── modules.xml │ ├── myapp.iml │ └── workspace.xml ├── docker │ ├── nginx │ ├── node │ └── php ├── docker-compose.yml ├── frontApp │ ├── .editorconfig │ ├── .git │ ├── .gitignore │ ├── .nuxt │ ├── .prettierrc │ ├── README.md │ ├── assets │ ├── components │ ├── layouts │ ├── middleware │ ├── node_modules │ ├── nuxt.config.js │ ├── package.json │ ├── pages │ ├── plugins │ ├── static │ ├── store │ ├── tsconfig.json │ └── yarn.lock └── laravel ├── .editorconfig ├── .env ├── .env.example ├── .gitattributes ├── .gitignore ├── .styleci.yml ├── README.md ├── app ├── artisan ├── bootstrap ├── composer.json ├── composer.lock ├── config ├── database ├── package.json ├── phpunit.xml ├── public ├── resources ├── routes ├── storage ├── tests ├── vendor └── webpack.mix.jsプロジェクト用ディレクトリを用意
Terminal$ mkdir -p ~/workspace/myapp $ cd ~/workspace/myapp $ mkdir -p laravel docker/{php,nginx,node} $ mkdir docker/nginx/{conf.d,logs}.envの準備
先に.env.exampleを編集してからコピーして.envをつくる
myapp$ touch .env.example .gitignore.env.exampleと.gitignoreを編集
.env.examplePROJECT_PATH=./laravel TZ=Asia/Tokyo WEB_PORT=10080 DB_PORT=13306 DB_TESTING_PORT=13307 DB_CONNECTION=mysql DB_NAME=myapp DB_USER=willrewrite DB_PASS=willrewrite DB_ROOT_PASS=willrewrite MAILHOG_PORT=18025 MAIL_HOST=mail MAIL_PORT=1025 COMPOSE_HTTP_TIMEOUT=70 FRONT_PORT=3000.gitignore.env .idea # その他個別に追加.env.exampleをコピー
myapp$ cp .env.example .envコピー後、個別のプロジェクトに合わせて.envの環境変数を上書きする
必要なファイルを作成
myapp$ touch docker-compose.yml \ docker/php/{php.ini,Dockerfile} \ docker/nginx/{conf.d/default.conf,Dockerfile} \ docker/node/Dockerfile各ファイルを編集
docker-compose.ymlversion: "3" services: web: build: context: . dockerfile: ./docker/nginx/Dockerfile args: - TZ=${TZ} volumes: - ./docker/nginx/logs:/etc/nginx/logs - ./docker/nginx/conf.d:/etc/nginx/conf.d - ${PROJECT_PATH}:/var/www/laravel ports: - ${WEB_PORT}:80 links: - app depends_on: - app app: build: context: . dockerfile: ./docker/php/Dockerfile args: - TZ=${TZ} volumes: - ${PROJECT_PATH}:/var/www/laravel links: - db_master environment: - DB_CONNECTION=${DB_CONNECTION} - DB_HOST=db_master - DB_DATABASE=${DB_NAME} - DB_USERNAME=${DB_USER} - DB_PASSWORD=${DB_PASS} - TZ=${TZ} - MAIL_HOST=${MAIL_HOST} - MAIL_PORT=${MAIL_PORT} db_master: image: mysql:5.7 environment: - MYSQL_DATABASE=${DB_NAME} - MYSQL_USER=${DB_USER} - MYSQL_PASSWORD=${DB_PASS} - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASS} - TZ=${TZ} ports: - ${DB_PORT}:3306 front_app: build: context: . dockerfile: ./docker/node/Dockerfile args: - TZ=${TZ} volumes: - ./frontApp:/var/www/frontApp ports: - ${FRONT_PORT}:3000 links: - web depends_on: - webNginxの設定
docker/nginx/DockerfileFROM nginx:1.15.7-alpine # timezone ARG TZ COPY ./docker/nginx/conf.d/ /etc/nginx/conf.d/ COPY ./docker/nginx/logs/ /etc/nginx/logs/ COPY ./laravel/ /var/www/laravel/ RUN apk update && apk --update add tzdata && \ cp /usr/share/zoneinfo/${TZ} /etc/localtime && \ apk del tzdata && \ rm -rf /var/cache/apk/*docker/nginx/conf.d/default.confserver { listen 0.0.0.0:80; # server_nameで設定した名前をローカルマシンの/etc/hostsにも設定する server_name www.example.org example.org; charset utf-8; client_max_body_size 3M; root /var/www/laravel/public; index index.php; location / { access_log /etc/nginx/logs/access.log main; error_log /etc/nginx/logs/error.log; try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_pass app:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }PHPの設定
docker/php/DockerfileFROM php:7.3.0RC6-fpm-alpine3.8 # timezone ARG TZ WORKDIR /var/www/laravel COPY ./docker/php/php.ini /usr/local/etc/php/ COPY ./laravel/ /var/www/laravel/ RUN apk upgrade --update && apk add --no-cache \ coreutils freetype-dev jpeg-dev libjpeg-turbo-dev libpng-dev libmcrypt-dev \ git vim unzip tzdata \ libltdl && \ docker-php-ext-install pdo_mysql mysqli mbstring && \ docker-php-ext-install -j$(nproc) iconv && \ docker-php-ext-configure gd \ --with-freetype-dir=/usr/include/ \ --with-jpeg-dir=/usr/include/ && \ docker-php-ext-install -j$(nproc) gd && \ cp /usr/share/zoneinfo/${TZ} /etc/localtime && \ apk del tzdata && \ rm -rf /var/cache/apk/* RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composerdocker/php/php.inilog_errors = on error_log = /var/log/php/php-error.log upload_max_filesize = 3M memory_limit = -1 post_max_size = 100M max_execution_time = 900 max_input_vars = 100000 default_charset = UTF-8 [Date] date.timezone = ${TZ} [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"Nodeの設定
docker/node/DockerfileFROM node:14.6.0-alpine RUN mkdir -p /var/www/frontApp # timezone ARG TZ WORKDIR /var/www/frontApp COPY ./frontApp/ /var/www/frontApp/ RUN apk update && \ apk upgrade && \ apk add --no-cache make gcc g++ python && \ yarn install EXPOSE 3000 ENTRYPOINT ["yarn", "run", "dev"]nuxt-tsのプロジェクト作成
myapp$ yarn create nuxt-app frontApp yarn create v1.22.4 [1/4] ? Resolving packages... [2/4] ? Fetching packages... [3/4] ? Linking dependencies... [4/4] ? Building fresh packages... warning Your current version of Yarn is out of date. The latest version is "1.22.5", while you're on "1.22.4". info To upgrade, run the following command: $ curl --compressed -o- -L https://yarnpkg.com/install.sh | bash success Installed "create-nuxt-app@3.5.2" with binaries: - create-nuxt-app create-nuxt-app v3.5.2 ✨ Generating Nuxt.js project in frontApp ? Project name: frontApp ? Programming language: TypeScript ? Package manager: Yarn ? UI framework: None ? Nuxt.js modules: Axios - Promise based HTTP client ? Linting tools: Prettier ? Testing framework: None ? Rendering mode: Universal (SSR / SSG) ? Deployment target: Server (Node.js hosting) ? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection) ? Continuous integration: None ? Version control system: Git一旦サーバを立ち上げ画面確認
myapp$ cd frontApp $ yarn run dev
- localhost:3000にアクセスして下記の画面を確認したあと、command + Cでサーバストップ
- コンテナ起動時に備えpackage.jsonを修正
frontApp/package.json{ "name": "frontApp", "version": "1.0.0", "private": true, "scripts": { - "dev": "nuxt-ts", + "dev": "HOST=0.0.0.0 PORT=3000 nuxt-ts", "build": "nuxt-ts build", - "start": "nuxt-ts start", + "start": "HOST=0.0.0.0 PORT=3000 nuxt-ts start", "generate": "nuxt-ts generate" }, // 以下略 }laravelディレクトリ直下にLaravelのプロジェクト作成
myapp$ docker-compose run app composer create-project --prefer-dist laravel/laravel ../laravelディレクトリ以下が次のような構成になっていればOK
myapp$ tree -a -L 1 laravel laravel ├── .editorconfig ├── .env ├── .env.example ├── .gitattributes ├── .gitignore ├── .styleci.yml ├── README.md ├── app ├── artisan ├── bootstrap ├── composer.json ├── composer.lock ├── config ├── database ├── package.json ├── phpunit.xml ├── public ├── resources ├── routes ├── server.php ├── storage ├── tests ├── vendor └── webpack.mix.jsコンテナをバックグラウンドで起動
myapp$ docker-compose up -d --buildLaravelの設定ファイルをキャッシュ等
myapp$ docker-compose exec app ash $ php artisan -V // バージョンが表示されればOK $ php artisan config:cache $ php artisan migrate $ chmod -R a+rw storage/ bootstrap/cache $ exit画面確認
Nuxt、Laravel間での通信を確認
Laravel側の設定
laravel/routes/api.php<?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; /* * 中略 */ + Route::get('/', function () { + return 'Hello'; + });Nuxt側の設定
myapp$ cd frontApp $ yarn add @nuxtjs/proxy @nuxtjs/dotenvfrontApp/nuxt.config.js+ const environment = process.env.NODE_ENV || 'development' + require('dotenv').config() export default { // (中略) modules: [ // https://go.nuxtjs.dev/axios '@nuxtjs/axios', + '@nuxtjs/proxy', + '@nuxtjs/dotenv', ], + proxy: { + '/api': + environment === 'development' + ? process.env.API_URL + : 'https://www.risk-exam.site', + }, + axios: { + baseURL: process.env.API_URL, + browserBaseURL: process.env.API_BROWSER_URL, + credentials: true, + }, }myapp/frontApp$ touch .envfrontApp/.envAPI_URL=http://web/api API_BROWSER_URL=http://localhost:10080/apifrontApp/pages/index.vue<template> <div class="container"> <div> <Logo /> <h1 class="title"> {{ greet }} // デフォルトの「frontApp」から変更 </h1> <div class="links"> <a href="https://nuxtjs.org/" target="_blank" rel="noopener noreferrer" class="button--green" > Documentation </a> <a href="https://github.com/nuxt/nuxt.js" target="_blank" rel="noopener noreferrer" class="button--grey" > GitHub </a> </div> </div> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ async asyncData({ app }): Promise<object> { const greet: string = await app.$axios.$get('/').catch((err) => err) return { greet } } }) </script> // 以下略
localhost:3000
にアクセスして、タイトルがHello
に変わっていたらOK
- 投稿日:2021-02-13T18:06:52+09:00
LaravelのDB接続、というか .env でハマった話
Laravel 5.8 から PostgreSQL に接続しようとして .env に必要な情報を記述し、接続テストをすると
"password authentication failed"
というエラーになってつながらない。同じ設定でPDOを直接使って接続したら普通に接続できる。
数時間悩んで試行錯誤して、原因が判明。
パスワードに "#" が含まれていて .env にDB_PASSWORD=abc#123のように書いていたので、 "#"以降がコメントと見なされていた。
DB_PASSWORD="abc#123"とダブルクォートで囲んだら接続できた。
アホ過ぎるorz教訓
"#" を含む可能性がある文字列(パスワード、何かのキーなど)を .env に書くときはダブルクォートで囲んでおいた方が無難。
- 投稿日:2021-02-13T16:51:28+09:00
ゼロからDockerでLaravel+Nuxt-ts+MySQLの環境構築をしてトップページを表示するまで【備忘録】
前提
ローカル環境
- macOS Catalina10.15.5
- Docker for mac 2.3.0.4
バージョン
- PHP...7.3
- Laravel...7.30.1
- Node.js 14.6
- nuxt/types 2.14
- MySQL 5.7
その他
- 最終的なディレクトリ構成
Terminal$ tree -a -L 2 . . ├── .env ├── .env.example ├── .gitignore ├── .idea │ ├── modules.xml │ ├── myapp.iml │ └── workspace.xml ├── docker │ ├── nginx │ ├── node │ └── php ├── docker-compose.yml ├── frontApp │ ├── .editorconfig │ ├── .git │ ├── .gitignore │ ├── .nuxt │ ├── .prettierrc │ ├── README.md │ ├── assets │ ├── components │ ├── layouts │ ├── middleware │ ├── node_modules │ ├── nuxt.config.js │ ├── package.json │ ├── pages │ ├── plugins │ ├── static │ ├── store │ ├── tsconfig.json │ └── yarn.lock └── laravel ├── .editorconfig ├── .env ├── .env.example ├── .gitattributes ├── .gitignore ├── .styleci.yml ├── README.md ├── app ├── artisan ├── bootstrap ├── composer.json ├── composer.lock ├── config ├── database ├── package.json ├── phpunit.xml ├── public ├── resources ├── routes ├── storage ├── tests ├── vendor └── webpack.mix.jsプロジェクト用ディレクトリを用意
Terminal$ mkdir -p ~/workspace/myapp $ cd ~/workspace/myapp $ mkdir -p laravel docker/{php,nginx,node} $ mkdir docker/nginx/{conf.d,logs}.envの準備
先に.env.exampleを編集してからコピーして.envをつくる
myapp$ touch .env.example .gitignore.env.exampleと.gitignoreを編集
.env.examplePROJECT_PATH=./laravel TZ=Asia/Tokyo WEB_PORT=10080 DB_PORT=13306 DB_TESTING_PORT=13307 DB_CONNECTION=mysql DB_NAME=myapp DB_USER=willrewrite DB_PASS=willrewrite DB_ROOT_PASS=willrewrite MAILHOG_PORT=18025 MAIL_HOST=mail MAIL_PORT=1025 COMPOSE_HTTP_TIMEOUT=70 FRONT_PORT=3000.gitignore.env .idea # その他個別に追加.env.exampleをコピー
myapp$ cp .env.example .envコピー後、個別のプロジェクトに合わせて.envの環境変数を上書きする
必要なファイルを作成
myapp$ touch docker-compose.yml \ docker/php/{php.ini,Dockerfile} \ docker/nginx/{conf.d/default.conf,Dockerfile} \ docker/node/Dockerfile各ファイルを編集
docker-compose.ymlversion: "3" services: web: build: context: . dockerfile: ./docker/nginx/Dockerfile args: - TZ=${TZ} volumes: - ./docker/nginx/logs:/etc/nginx/logs - ./docker/nginx/conf.d:/etc/nginx/conf.d - ${PROJECT_PATH}:/var/www/laravel ports: - ${WEB_PORT}:80 links: - app depends_on: - app app: build: context: . dockerfile: ./docker/php/Dockerfile args: - TZ=${TZ} volumes: - ${PROJECT_PATH}:/var/www/laravel links: - db_master environment: - DB_CONNECTION=${DB_CONNECTION} - DB_HOST=db_master - DB_DATABASE=${DB_NAME} - DB_USERNAME=${DB_USER} - DB_PASSWORD=${DB_PASS} - TZ=${TZ} - MAIL_HOST=${MAIL_HOST} - MAIL_PORT=${MAIL_PORT} db_master: image: mysql:5.7 environment: - MYSQL_DATABASE=${DB_NAME} - MYSQL_USER=${DB_USER} - MYSQL_PASSWORD=${DB_PASS} - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASS} - TZ=${TZ} ports: - ${DB_PORT}:3306 front_app: build: context: . dockerfile: ./docker/node/Dockerfile args: - TZ=${TZ} volumes: - ./frontApp:/var/www/frontApp ports: - ${FRONT_PORT}:3000 links: - web depends_on: - webNginxの設定
docker/nginx/DockerfileFROM nginx:1.15.7-alpine # timezone ARG TZ COPY ./docker/nginx/conf.d/ /etc/nginx/conf.d/ COPY ./docker/nginx/logs/ /etc/nginx/logs/ COPY ./laravel/ /var/www/laravel/ RUN apk update && apk --update add tzdata && \ cp /usr/share/zoneinfo/${TZ} /etc/localtime && \ apk del tzdata && \ rm -rf /var/cache/apk/*docker/nginx/conf.d/default.confserver { listen 0.0.0.0:80; # server_nameで設定した名前をローカルマシンの/etc/hostsにも設定する server_name www.example.org example.org; charset utf-8; client_max_body_size 3M; root /var/www/laravel/public; index index.php; location / { access_log /etc/nginx/logs/access.log main; error_log /etc/nginx/logs/error.log; try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_pass app:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }PHPの設定
docker/php/DockerfileFROM php:7.3.0RC6-fpm-alpine3.8 # timezone ARG TZ WORKDIR /var/www/laravel COPY ./docker/php/php.ini /usr/local/etc/php/ COPY ./laravel/ /var/www/laravel/ RUN apk upgrade --update && apk add --no-cache \ coreutils freetype-dev jpeg-dev libjpeg-turbo-dev libpng-dev libmcrypt-dev \ git vim unzip tzdata \ libltdl && \ docker-php-ext-install pdo_mysql mysqli mbstring && \ docker-php-ext-install -j$(nproc) iconv && \ docker-php-ext-configure gd \ --with-freetype-dir=/usr/include/ \ --with-jpeg-dir=/usr/include/ && \ docker-php-ext-install -j$(nproc) gd && \ cp /usr/share/zoneinfo/${TZ} /etc/localtime && \ apk del tzdata && \ rm -rf /var/cache/apk/* RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composerdocker/php/php.inilog_errors = on error_log = /var/log/php/php-error.log upload_max_filesize = 3M memory_limit = -1 post_max_size = 100M max_execution_time = 900 max_input_vars = 100000 default_charset = UTF-8 [Date] date.timezone = ${TZ} [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"Nodeの設定
docker/node/DockerfileFROM node:14.6.0-alpine RUN mkdir -p /var/www/frontApp # timezone ARG TZ WORKDIR /var/www/frontApp COPY ./frontApp/ /var/www/frontApp/ RUN apk update && \ apk upgrade && \ apk add --no-cache make gcc g++ python && \ yarn install EXPOSE 3000 ENTRYPOINT ["yarn", "run", "dev"]nuxt-tsのプロジェクト作成
myapp$ yarn create nuxt-app frontApp yarn create v1.22.4 [1/4] ? Resolving packages... [2/4] ? Fetching packages... [3/4] ? Linking dependencies... [4/4] ? Building fresh packages... warning Your current version of Yarn is out of date. The latest version is "1.22.5", while you're on "1.22.4". info To upgrade, run the following command: $ curl --compressed -o- -L https://yarnpkg.com/install.sh | bash success Installed "create-nuxt-app@3.5.2" with binaries: - create-nuxt-app create-nuxt-app v3.5.2 ✨ Generating Nuxt.js project in frontApp ? Project name: frontApp ? Programming language: TypeScript ? Package manager: Yarn ? UI framework: None ? Nuxt.js modules: Axios - Promise based HTTP client ? Linting tools: Prettier ? Testing framework: None ? Rendering mode: Universal (SSR / SSG) ? Deployment target: Server (Node.js hosting) ? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection) ? Continuous integration: None ? Version control system: Git一旦サーバを立ち上げ画面確認
myapp$ cd frontApp $ yarn run dev
- localhost:3000にアクセスして下記の画面を確認したあと、command + Cでサーバストップ
- コンテナ起動時に備えpackage.jsonを修正
frontApp/package.json{ "name": "frontApp", "version": "1.0.0", "private": true, "scripts": { - "dev": "nuxt-ts", + "dev": "HOST=0.0.0.0 PORT=3000 nuxt-ts", "build": "nuxt-ts build", - "start": "nuxt-ts start", + "start": "HOST=0.0.0.0 PORT=3000 nuxt-ts start", "generate": "nuxt-ts generate" }, // 以下略 }laravelディレクトリ直下にLaravelのプロジェクト作成
myapp$ docker-compose run app composer create-project --prefer-dist laravel/laravel ../laravelディレクトリ以下が次のような構成になっていればOK
myapp$ tree -a -L 1 laravel laravel ├── .editorconfig ├── .env ├── .env.example ├── .gitattributes ├── .gitignore ├── .styleci.yml ├── README.md ├── app ├── artisan ├── bootstrap ├── composer.json ├── composer.lock ├── config ├── database ├── package.json ├── phpunit.xml ├── public ├── resources ├── routes ├── server.php ├── storage ├── tests ├── vendor └── webpack.mix.jsコンテナをバックグラウンドで起動
myapp$ docker-compose up -d --buildLaravelの設定ファイルをキャッシュ等
myapp$ docker-compose exec app ash $ php artisan -V // バージョンが表示されればOK $ php artisan config:cache $ php artisan migrate $ chmod -R a+rw storage/ bootstrap/cache $ exit画面確認
Nuxt、Laravel間での通信を確認
Laravel側の設定
laravel/routes/api.php<?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; /* * 中略 */ + Route::get('/', function () { + return 'Hello'; + });Nuxt側の設定
myapp$ cd frontApp $ yarn add @nuxtjs/proxy @nuxtjs/dotenvfrontApp/nuxt.config.js+ const environment = process.env.NODE_ENV || 'development' + require('dotenv').config() export default { // (中略) modules: [ // https://go.nuxtjs.dev/axios '@nuxtjs/axios', + '@nuxtjs/proxy', + '@nuxtjs/dotenv', ], + proxy: { + '/api': + environment === 'development' + ? process.env.API_URL + : 'https://www.risk-exam.site', + }, + axios: { + baseURL: process.env.API_URL, + browserBaseURL: process.env.API_BROWSER_URL, + credentials: true, + }, }myapp/frontApp$ touch .envfrontApp/.envAPI_URL=http://web/api API_BROWSER_URL=http://localhost:10080/apifrontApp/pages/index.vue<template> <div class="container"> <div> <Logo /> <h1 class="title"> {{ greet }} // デフォルトの「frontApp」から変更 </h1> <div class="links"> <a href="https://nuxtjs.org/" target="_blank" rel="noopener noreferrer" class="button--green" > Documentation </a> <a href="https://github.com/nuxt/nuxt.js" target="_blank" rel="noopener noreferrer" class="button--grey" > GitHub </a> </div> </div> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ async asyncData({ app }): Promise<object> { const greet: string = await app.$axios.$get('/').catch((err) => err) return { greet } } }) </script> // 以下略
localhost:3000
にアクセスして、タイトルがHello
に変わっていたらOK
- 投稿日:2021-02-13T16:51:28+09:00
ゼロからDockerでLaravel+Nuxt TypeScript+MySQLの環境構築をしてトップページを表示するまで【備忘録】
前提
ローカル環境
- macOS Catalina10.15.5
- Docker for mac 2.3.0.4
バージョン
- PHP...7.3
- Laravel...7.30.1
- Node.js 14.6
- nuxt/types 2.14
- MySQL 5.7
その他
- 最終的なディレクトリ構成
Terminal$ tree -a -L 2 . . ├── .env ├── .env.example ├── .gitignore ├── .idea │ ├── modules.xml │ ├── myapp.iml │ └── workspace.xml ├── docker │ ├── nginx │ ├── node │ └── php ├── docker-compose.yml ├── frontApp │ ├── .editorconfig │ ├── .git │ ├── .gitignore │ ├── .nuxt │ ├── .prettierrc │ ├── README.md │ ├── assets │ ├── components │ ├── layouts │ ├── middleware │ ├── node_modules │ ├── nuxt.config.js │ ├── package.json │ ├── pages │ ├── plugins │ ├── static │ ├── store │ ├── tsconfig.json │ └── yarn.lock └── laravel ├── .editorconfig ├── .env ├── .env.example ├── .gitattributes ├── .gitignore ├── .styleci.yml ├── README.md ├── app ├── artisan ├── bootstrap ├── composer.json ├── composer.lock ├── config ├── database ├── package.json ├── phpunit.xml ├── public ├── resources ├── routes ├── storage ├── tests ├── vendor └── webpack.mix.jsプロジェクト用ディレクトリを用意
Terminal$ mkdir -p ~/workspace/myapp $ cd ~/workspace/myapp $ mkdir -p laravel docker/{php,nginx,node} $ mkdir docker/nginx/{conf.d,logs}.envの準備
先に.env.exampleを編集してからコピーして.envをつくる
myapp$ touch .env.example .gitignore.env.exampleと.gitignoreを編集
.env.examplePROJECT_PATH=./laravel TZ=Asia/Tokyo WEB_PORT=10080 DB_PORT=13306 DB_TESTING_PORT=13307 DB_CONNECTION=mysql DB_NAME=myapp DB_USER=willrewrite DB_PASS=willrewrite DB_ROOT_PASS=willrewrite MAILHOG_PORT=18025 MAIL_HOST=mail MAIL_PORT=1025 COMPOSE_HTTP_TIMEOUT=70 FRONT_PORT=3000.gitignore.env .idea # その他個別に追加.env.exampleをコピー
myapp$ cp .env.example .envコピー後、個別のプロジェクトに合わせて.envの環境変数を上書きする
必要なファイルを作成
myapp$ touch docker-compose.yml \ docker/php/{php.ini,Dockerfile} \ docker/nginx/{conf.d/default.conf,Dockerfile} \ docker/node/Dockerfile各ファイルを編集
docker-compose.ymlversion: "3" services: web: build: context: . dockerfile: ./docker/nginx/Dockerfile args: - TZ=${TZ} volumes: - ./docker/nginx/logs:/etc/nginx/logs - ./docker/nginx/conf.d:/etc/nginx/conf.d - ${PROJECT_PATH}:/var/www/laravel ports: - ${WEB_PORT}:80 links: - app depends_on: - app app: build: context: . dockerfile: ./docker/php/Dockerfile args: - TZ=${TZ} volumes: - ${PROJECT_PATH}:/var/www/laravel links: - db_master environment: - DB_CONNECTION=${DB_CONNECTION} - DB_HOST=db_master - DB_DATABASE=${DB_NAME} - DB_USERNAME=${DB_USER} - DB_PASSWORD=${DB_PASS} - TZ=${TZ} - MAIL_HOST=${MAIL_HOST} - MAIL_PORT=${MAIL_PORT} db_master: image: mysql:5.7 environment: - MYSQL_DATABASE=${DB_NAME} - MYSQL_USER=${DB_USER} - MYSQL_PASSWORD=${DB_PASS} - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASS} - TZ=${TZ} ports: - ${DB_PORT}:3306 front_app: build: context: . dockerfile: ./docker/node/Dockerfile args: - TZ=${TZ} volumes: - ./frontApp:/var/www/frontApp ports: - ${FRONT_PORT}:3000 links: - web depends_on: - webNginxの設定
docker/nginx/DockerfileFROM nginx:1.15.7-alpine # timezone ARG TZ COPY ./docker/nginx/conf.d/ /etc/nginx/conf.d/ COPY ./docker/nginx/logs/ /etc/nginx/logs/ COPY ./laravel/ /var/www/laravel/ RUN apk update && apk --update add tzdata && \ cp /usr/share/zoneinfo/${TZ} /etc/localtime && \ apk del tzdata && \ rm -rf /var/cache/apk/*docker/nginx/conf.d/default.confserver { listen 0.0.0.0:80; # server_nameで設定した名前をローカルマシンの/etc/hostsにも設定する server_name www.example.org example.org; charset utf-8; client_max_body_size 3M; root /var/www/laravel/public; index index.php; location / { access_log /etc/nginx/logs/access.log main; error_log /etc/nginx/logs/error.log; try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_pass app:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }PHPの設定
docker/php/DockerfileFROM php:7.3.0RC6-fpm-alpine3.8 # timezone ARG TZ WORKDIR /var/www/laravel COPY ./docker/php/php.ini /usr/local/etc/php/ COPY ./laravel/ /var/www/laravel/ RUN apk upgrade --update && apk add --no-cache \ coreutils freetype-dev jpeg-dev libjpeg-turbo-dev libpng-dev libmcrypt-dev \ git vim unzip tzdata \ libltdl && \ docker-php-ext-install pdo_mysql mysqli mbstring && \ docker-php-ext-install -j$(nproc) iconv && \ docker-php-ext-configure gd \ --with-freetype-dir=/usr/include/ \ --with-jpeg-dir=/usr/include/ && \ docker-php-ext-install -j$(nproc) gd && \ cp /usr/share/zoneinfo/${TZ} /etc/localtime && \ apk del tzdata && \ rm -rf /var/cache/apk/* RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composerdocker/php/php.inilog_errors = on error_log = /var/log/php/php-error.log upload_max_filesize = 3M memory_limit = -1 post_max_size = 100M max_execution_time = 900 max_input_vars = 100000 default_charset = UTF-8 [Date] date.timezone = ${TZ} [mbstring] mbstring.internal_encoding = "UTF-8" mbstring.language = "Japanese"Nodeの設定
docker/node/DockerfileFROM node:14.6.0-alpine RUN mkdir -p /var/www/frontApp # timezone ARG TZ WORKDIR /var/www/frontApp COPY ./frontApp/ /var/www/frontApp/ RUN apk update && \ apk upgrade && \ apk add --no-cache make gcc g++ python && \ yarn install EXPOSE 3000 ENTRYPOINT ["yarn", "run", "dev"]nuxt-tsのプロジェクト作成
myapp$ yarn create nuxt-app frontApp yarn create v1.22.4 [1/4] ? Resolving packages... [2/4] ? Fetching packages... [3/4] ? Linking dependencies... [4/4] ? Building fresh packages... warning Your current version of Yarn is out of date. The latest version is "1.22.5", while you're on "1.22.4". info To upgrade, run the following command: $ curl --compressed -o- -L https://yarnpkg.com/install.sh | bash success Installed "create-nuxt-app@3.5.2" with binaries: - create-nuxt-app create-nuxt-app v3.5.2 ✨ Generating Nuxt.js project in frontApp ? Project name: frontApp ? Programming language: TypeScript ? Package manager: Yarn ? UI framework: None ? Nuxt.js modules: Axios - Promise based HTTP client ? Linting tools: Prettier ? Testing framework: None ? Rendering mode: Universal (SSR / SSG) ? Deployment target: Server (Node.js hosting) ? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection) ? Continuous integration: None ? Version control system: Git一旦サーバを立ち上げ画面確認
myapp$ cd frontApp $ yarn run dev
- localhost:3000にアクセスして下記の画面を確認したあと、command + Cでサーバストップ
- コンテナ起動時に備えpackage.jsonを修正
frontApp/package.json{ "name": "frontApp", "version": "1.0.0", "private": true, "scripts": { - "dev": "nuxt-ts", + "dev": "HOST=0.0.0.0 PORT=3000 nuxt-ts", "build": "nuxt-ts build", - "start": "nuxt-ts start", + "start": "HOST=0.0.0.0 PORT=3000 nuxt-ts start", "generate": "nuxt-ts generate" }, // 以下略 }laravelディレクトリ直下にLaravelのプロジェクト作成
myapp$ docker-compose run app composer create-project --prefer-dist laravel/laravel ../laravelディレクトリ以下が次のような構成になっていればOK
myapp$ tree -a -L 1 laravel laravel ├── .editorconfig ├── .env ├── .env.example ├── .gitattributes ├── .gitignore ├── .styleci.yml ├── README.md ├── app ├── artisan ├── bootstrap ├── composer.json ├── composer.lock ├── config ├── database ├── package.json ├── phpunit.xml ├── public ├── resources ├── routes ├── server.php ├── storage ├── tests ├── vendor └── webpack.mix.jsコンテナをバックグラウンドで起動
myapp$ docker-compose up -d --buildLaravelの設定ファイルをキャッシュ等
myapp$ docker-compose exec app ash $ php artisan -V // バージョンが表示されればOK $ php artisan config:cache $ php artisan migrate $ chmod -R a+rw storage/ bootstrap/cache $ exit画面確認
Nuxt、Laravel間での通信を確認
Laravel側の設定
laravel/routes/api.php<?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; /* * 中略 */ + Route::get('/', function () { + return 'Hello'; + });Nuxt側の設定
myapp$ cd frontApp $ yarn add @nuxtjs/proxy @nuxtjs/dotenvfrontApp/nuxt.config.js+ const environment = process.env.NODE_ENV || 'development' + require('dotenv').config() export default { // (中略) modules: [ // https://go.nuxtjs.dev/axios '@nuxtjs/axios', + '@nuxtjs/proxy', + '@nuxtjs/dotenv', ], + proxy: { + '/api': + environment === 'development' + ? process.env.API_URL + : 'https://www.risk-exam.site', + }, + axios: { + baseURL: process.env.API_URL, + browserBaseURL: process.env.API_BROWSER_URL, + credentials: true, + }, }myapp/frontApp$ touch .envfrontApp/.envAPI_URL=http://web/api API_BROWSER_URL=http://localhost:10080/apifrontApp/pages/index.vue<template> <div class="container"> <div> <Logo /> <h1 class="title"> {{ greet }} // デフォルトの「frontApp」から変更 </h1> <div class="links"> <a href="https://nuxtjs.org/" target="_blank" rel="noopener noreferrer" class="button--green" > Documentation </a> <a href="https://github.com/nuxt/nuxt.js" target="_blank" rel="noopener noreferrer" class="button--grey" > GitHub </a> </div> </div> </div> </template> <script lang="ts"> import Vue from 'vue' export default Vue.extend({ async asyncData({ app }): Promise<object> { const greet: string = await app.$axios.$get('/').catch((err) => err) return { greet } } }) </script> // 以下略
localhost:3000
にアクセスして、タイトルがHello
に変わっていたらOK
- 投稿日:2021-02-13T16:14:46+09:00
Laravelで将棋アプリを作りたい(第一回)
Laravalを使って将棋の動きを実現してみたくなったので、「トンカチと釘」感が半端ないが、やる気に任せてやってみる。
今回は プロジェクト作成 ~ 盤面作成まで。環境
macOS Catalina
Laravel Installer 3.0.1目次
1.プロジェクト作成
2.コントローラーで型作成
3.ビューとcssで盤面作成
4.王将を置いてみる1. プロジェクト作成
ターミナル$ laravel new shogi-app
アプリ起動確認
ターミナル$ cd shogi-app $ php artisan servehttp://127.0.0.1:8000/ でアプリが起動している。
ターミナル$ git add . $ git commit -m 'first commit' $ git branch -M main $ git remote add origin {作成したリポジトリのURL}.git $ git push -u origin main2. コントローラーで型作成
ターミナル$ php artisan make:controller ShogiController
indexメソッドに書いてみる。
app/Http/Controllers/ShogiController.phppublic function index() { $appName = '将棋アプリ'; return view('shogi/index', compact('appName')); }今は
$appName
を定義してビューに渡すだけ。ルーティング追加
route/web.phpRoute::get('shogi', 'App\Http\Controllers\ShogiController@index');これで、
http://127.0.0.1:8000/shogi
へのアクセスでShogiController
のindex
メソッドが呼び出される。3. ビューとcssで盤面作成
今回はbladeテンプレートを使用してビューを作成
resources/views
配下に新たにshogi
フォルダを作成。resources/views/shogi/index.blade.php<!DOCTYPE html> <html> <head> <title>将棋アプリ</title> <link rel="stylesheet" href="{{ asset('css/style.css') }}"> </head> <body> <p>{{ $appName }}</p> <div class="board"> <?php for ($c = 1; $c < 10; $c++) { echo '<div class="column column' . $c . '" id="column' . $c . '">'; for ($r = 9; $r > 0; $r--) { echo '<p class="row square' . $r . $c . '" id="square' . $r . $c . '">' . $r . $c . '</p>'; } echo '</div>'; } ?> </div> </body> </html>CSSはpublic配下に配置
public/css/style.css.board { margin: 0 200px; } .row { display: table-cell; vertical-align: middle; text-align: center; border: solid 1px black; width: 60px; } .column { width: 500px; display: table; table-layout: fixed; height: 60px; }4. 王将を置いてみる
下記サイトから、将棋駒の素材入手&縮小
サイズを調整した王将の画像を
public/image
配下に配置コントローラーで王将の初期値を渡す。
app/Http/Controller/ShogiControllerpublic function index() { $appName = '将棋アプリ'; $MyKing = 59; // 追加 return view('shogi/index', compact('appName', 'MyKing')); // ビューにも渡す }ビューでは、王将の位置の時だけ画像のついたボタンを表示させる。
resources/views/shogi/index.blade.php<!DOCTYPE html> <html> <head> <title>将棋アプリ</title> <link rel="stylesheet" href="{{ asset('css/style.css') }}"> </head> <body> <p>{{ $appName }}</p> <div class="board"> <?php for ($c = 1; $c < 10; $c++) { echo '<div class="column column' . $c . '" id="column' . $c . '">'; for ($r = 9; $r > 0; $r--) { if ($r . $c == $MyKing) { echo '<p class="row square' . $r . $c . '" id="square' . $r . $c . '"><button><img src="image/my_king_50.png" alt="自分の王将"></button></p>'; } else { echo '<p class="row square' . $r . $c . '" id="square' . $r . $c . '">' . $r . $c . '</p>'; } } echo '</div>'; } ?> </div> </body> </html>今回はここまで。
ターミナル$ git add . $ git commit -m "盤面作成" $ git push origin main
- 投稿日:2021-02-13T15:42:27+09:00
【?初心者】Laravelで問題解決を試みたポートフォリオ
概要
車両を保有している人と保有していない人を結ぶアプリケーション。大手カーシェアリングサービスのように車両を会社からドライバーに貸し出す(BtoB)のでなく、個人間で気軽に貸し借りができるサービス(CtoC)をコンセプトとした。
[→アプリケーション リンク]
制作背景
交通インフラの整備や若者の車離れの影響を受け、自動車の国内需要は1990年ごろをピークとして年々減少している。これに伴い、大手のBtoBカーシェアリングサービス(タイムズ)の会員数は過去5年間で約4倍以上伸びている。対して、今後伸びてくると予想されていたCtoCのカーシェアリング業界は伸び悩んでいるというギャップが生じている。この現象に疑問を持ったため、原因をトヨタの問題解決の手法を用いて考え、このギャップを解決するサービスの開発を行った。
[→制作背景詳細 リンク]システム概要
このサービスのユーザーは3パターンに分けられる。
A. ドライバー (車を借りたい人)
B. オーナー (車を貸したい人)
C. 管理者 (Car.マッチング株式会社:自動車保険会社)
操作説明
各ユーザーの操作方法について下記に示す。
[→操作詳細説明 リンク]A. ドライバーの基本操作
①ログイン
②希望の条件(日時や乗車人数)で検索
③該当したオーナーとチャットでの交流
④車両を借りることへの不安がなくなれば、契約を結んでもらえるようオーナーへ依頼
B. オーナーの基本操作
①ログイン
②車両を貸し出せる日程を登録
③ドライバーから依頼があればチャットにて交流
④オーナーとドライバーが契約条件に合意した場合、契約フォームに入力
⑤確認メール送信
C. 管理者(Car.マッチング株式会社:自動車保険会社)の基本操作
①ドライバーとオーナー間で契約が結ばれた後、DBへ内容が保存されるため、それらを表示
②この登録情報を見て自動車の保険の加入手続き・料金の支払い手続きに移行
こだわり
私はCtoCのカーシェアリング業界が伸びていない原因は主に下記の3点に起因すると考える。
①初期登録操作のハードルが高い
②条件に合う車両を探す作業が煩わしい
③全く交流がない他人から車両を借りることへの不安があるこれらを解決するために下記にこだわって開発した。
A. 初期登録の簡略化
初期の登録はなるべくシンプルにしておき、ドライバーとオーナーの交渉が成立してから、更に必要な情報を入力させる。ナンバープレート情報や料金の設定など初期登録の際に煩わしさを感じるものは契約時に入力させる。B. 操作がシンプル
マルチログイン機能を実装してドライバーとオーナーの操作を分け、余分な機能は付けず、直感的に分かりやすい構成を心がける。
* ドライバーの操作: 初期登録 → 検索 → チャットによるオーナーとの交渉
* オーナーの操作 : 初期登録→ 貸出日程登録 → チャット → 契約詳細入力C. LINEのような手軽さで個人間でチャットが可能(非同期通信)
アプリ内のチャット機能を、スマートフォンユーザーのおよそ80%が利用しているLINEの操作に合わせることで、誰でも容易にチャット機能を使って交流できる。また、非同期通信を行うことによって画面の遷移無しで、相手のメッセージを受け取ることができる。上記とは色合いが異なるが、その他にもユーザーと管理者を思いやった機能も追加した。
D. 契約内容のエビデンスとしてメールの自動送信
オーナーが契約内容を入力後、確認メールが自動でドライバー・オーナー・Carマッチング(自動車保険会社)へと送付される。これにより、ドライバーとオーナーとの間で契約した内容を失念しても、再度確認することができる。また、料金や内容の相違でトラブルが起きた際に、エビデンスとして示すこともできる。E. 管理者用の契約内容閲覧機能
ドライバーとオーナー間で契約が結ばれた後、DBへその内容が保存されるため、その内容を表示する機能。その内容を見て自動車の保険の加入手続き・料金の支払い手続きに移行する。使用技術
バックエンド
PHP 7.2.34 / Laravel 6.20.5フロントエンド
HTML / CSS / javascript / jQuery 3.2.1 / Vue.js(現在学習中のため今後組み込む)インフラ
mysql 8.0.22 / AWS(EC2,S3)その他の使用技術
Pusher / git(gitHub) / Visual Studio Code / draw.io / GmailAWS構成図
DB設計
・ ER図
・ 各種テーブル
テーブル名 定義 owners
(オーナー)オーナーの登録情報 drivers
(ドライバー)ドライバーの登録情報 owner_schedules
(オーナースケジュール)ドライバーの車両貸出可能な日程 chats
(チャット)会話の内容 contracts
(コントラクト)契約確定後、契約内容を格納 苦労したところ
①DB設計
ER図を添付していますが、実際のアプリケーションとテーブル名やカラム名に相違があります。テーブルの命名規則の理解が曖昧ままDB設計をしており、キャメルケースを用いた記述をしてしまいました。開発終盤に気付きましたが、影響範囲が広すぎて修正が困難になりました。この失敗を二度と繰り返さないよう再度学習を行い、Qiitaにまとめています。初期設計の重要性を身に染みて学びました。[→Qiita記事 リンク]
②Laravelのマルチログイン機能
ドライバーとオーナーで初期の登録方法やログインした後の挙動が変わるため、マルチログイン機能を実装する必要がありました。Laravelでは基本のログイン機能がついていますが、これを応用して2通りのログイン機能を作りました。変更が必要なファイルが多く、それぞれの関連性が分かっていなかったため、苦労しました。ここで3日以上も悩んだことで認証やミドルウェア・ルーティングについての知識を身に着けることができました。[→Qiita記事 リンク]
③AWSでのデプロイ
web系企業ではクラウドはAWSが主流になっていますのでAWSを用いて本番環境を構築しました。初めてのVimコマンドの操作に慣れていないことや、ディレクトリの階層も頭に入っていなかったことで、configファイルや.envファイルを探したり編集するだけでかなり難航しました。VPCの生成から数えると30〜40時間以上かけてなんとかデプロイしました。多く悩んだ分、仮想サーバーやIPアドレスの知識・コマンドの操作などを身に着けることができました。
④websocket通信を用いたチャットの非同期通信
外部API(pusher)を用いたリアルタイムチャットの実装に挑戦しました。実装に必要な作業をなるべく最小単位に分割して進めていきました。非同期でのメッセージの受信はできるようになったものの、ドライバー側からのメッセージなのかオーナー側からのメッセージなのかを分岐させることができません。少し手詰まり状態にありますが、今も諦めずにトライしています。
⑤LaravelのCollection型の条件分岐(ユーザーからのフィードバック)
知人にアプリケーションの操作トライを依頼した際に、「検索後、該当するものが無かった時にコメントが出ないので分からない」とアドバイスを受けました。これを受け、検索する前・検索して成功した時・検索して失敗した時と3つの条件で表示を分岐させました。この時にLaravelのCollection型の扱いについて理解が少なく、空値判定がうまくいかず長時間悩んでしまいましたので、学習してQiitaにまとめました。[→Qiita記事 リンク]
最後に
転職活動のポートフォリオとして製作しています。実務未経験者が独学で作ったため、内容に誤っている点があるかと思います。お手柔らかにお願いいたします。今後実務を経験して、過去の実力を振り返られるように記録として執筆しました。LGTMで応援いただけると励みになります。
- 投稿日:2021-02-13T15:42:27+09:00
【ポートフォリオ】初心者?がLaravelで問題解決を試みた
概要
車両を保有している人と保有していない人を結ぶアプリケーション。大手カーシェアリングサービスのように車両を会社からドライバーに貸し出す(BtoB)のでなく、個人間で気軽に貸し借りができるサービス(CtoC)をコンセプトとした。
※悪意のあるイタズラが多発したため、アプリリンクは貼っていません。
制作背景
交通インフラの整備や若者の車離れの影響を受け、自動車の国内需要は1990年ごろをピークとして年々減少している。これに伴い、大手のBtoBカーシェアリングサービス(タイムズ)の会員数は過去5年間で約4倍以上伸びている。対して、今後伸びてくると予想されていたCtoCのカーシェアリング業界は伸び悩んでいるというギャップが生じている。この現象に疑問を持ったため、原因をトヨタの問題解決の手法を用いて考え、このギャップを解決するサービスの開発を行った。
[→制作背景詳細 リンク]システム概要
このサービスのユーザーは3パターンに分けられる。
A. ドライバー (車を借りたい人)
B. オーナー (車を貸したい人)
C. 管理者 (Car.マッチング株式会社:自動車保険会社)
操作説明
各ユーザーの操作方法について下記に示す。
A. ドライバーの基本操作
①ログイン
②希望の条件(日時や乗車人数)で検索
③該当したオーナーとチャットでの交流
④車両を借りることへの不安がなくなれば、契約を結んでもらえるようオーナーへ依頼
B. オーナーの基本操作
①ログイン
②車両を貸し出せる日程を登録
③ドライバーから依頼があればチャットにて交流
④オーナーとドライバーが契約条件に合意した場合、契約フォームに入力
⑤確認メール送信
C. 管理者(Car.マッチング株式会社:自動車保険会社)の基本操作
①ドライバーとオーナー間で契約が結ばれた後、DBへ内容が保存されるため、それらを表示
②この登録情報を見て自動車の保険の加入手続き・料金の支払い手続きに移行
こだわり
私はCtoCのカーシェアリング業界が伸びていない原因は主に下記の3点に起因すると考える。
①初期登録操作のハードルが高い
②条件に合う車両を探す作業が煩わしい
③全く交流がない他人から車両を借りることへの不安があるこれらを解決するために下記にこだわって開発した。
A. 初期登録の簡略化
初期の登録はなるべくシンプルにしておき、ドライバーとオーナーの交渉が成立してから、更に必要な情報を入力させる。ナンバープレート情報や料金の設定など初期登録の際に煩わしさを感じるものは契約時に入力させる。B. 操作がシンプル
マルチログイン機能を実装してドライバーとオーナーの操作を分け、余分な機能は付けず、直感的に分かりやすい構成を心がける。
* ドライバーの操作: 初期登録 → 検索 → チャットによるオーナーとの交渉
* オーナーの操作 : 初期登録→ 貸出日程登録 → チャット → 契約詳細入力C. LINEのような手軽さで個人間でチャットが可能(非同期通信)
アプリ内のチャット機能を、スマートフォンユーザーのおよそ80%が利用しているLINEの操作に合わせることで、誰でも容易にチャット機能を使って交流できる。また、非同期通信を行うことによって画面の遷移無しで、相手のメッセージを受け取ることができる。上記とは色合いが異なるが、その他にもユーザーと管理者を思いやった機能も追加した。
D. 契約内容のエビデンスとしてメールの自動送信
オーナーが契約内容を入力後、確認メールが自動でドライバー・オーナー・Carマッチング(自動車保険会社)へと送付される。これにより、ドライバーとオーナーとの間で契約した内容を失念しても、再度確認することができる。また、料金や内容の相違でトラブルが起きた際に、エビデンスとして示すこともできる。E. 管理者用の契約内容閲覧機能
ドライバーとオーナー間で契約が結ばれた後、DBへその内容が保存されるため、その内容を表示する機能。その内容を見て自動車の保険の加入手続き・料金の支払い手続きに移行する。使用技術
バックエンド
PHP 7.2.34 / Laravel 6.20.5フロントエンド
HTML / CSS / javascript / jQuery 3.2.1 / Vue.js(現在学習中のため今後組み込む)インフラ
mysql 8.0.22 / AWS(EC2,S3)その他の使用技術
Pusher / git(gitHub) / Visual Studio Code / draw.io / GmailAWS構成図
DB設計
・ ER図
・ 各種テーブル
テーブル名 定義 owners
(オーナー)オーナーの登録情報 drivers
(ドライバー)ドライバーの登録情報 owner_schedules
(オーナースケジュール)ドライバーの車両貸出可能な日程 chats
(チャット)会話の内容 contracts
(コントラクト)契約確定後、契約内容を格納 苦労したところ
①DB設計
ER図を添付していますが、実際のアプリケーションとテーブル名やカラム名に相違があります。テーブルの命名規則の理解が曖昧ままDB設計をしており、キャメルケースを用いた記述をしてしまいました。開発終盤に気付きましたが、影響範囲が広すぎて修正が困難になりました。この失敗を二度と繰り返さないよう再度学習を行い、Qiitaにまとめています。初期設計の重要性を身に染みて学びました。[→Qiita記事 リンク]
②Laravelのマルチログイン機能
ドライバーとオーナーで初期の登録方法やログインした後の挙動が変わるため、マルチログイン機能を実装する必要がありました。Laravelでは基本のログイン機能がついていますが、これを応用して2通りのログイン機能を作りました。変更が必要なファイルが多く、それぞれの関連性が分かっていなかったため、苦労しました。ここで3日以上も悩んだことで認証やミドルウェア・ルーティングについての知識を身に着けることができました。[→Qiita記事 リンク]
③AWSでのデプロイ
web系企業ではクラウドはAWSが主流になっていますのでAWSを用いて本番環境を構築しました。初めてのVimコマンドの操作に慣れていないことや、ディレクトリの階層も頭に入っていなかったことで、configファイルや.envファイルを探したり編集するだけでかなり難航しました。VPCの生成から数えると30〜40時間以上かけてなんとかデプロイしました。多く悩んだ分、仮想サーバーやIPアドレスの知識・コマンドの操作などを身に着けることができました。
④websocket通信を用いたチャットの非同期通信
外部API(pusher)を用いたリアルタイムチャットの実装に挑戦しました。実装に必要な作業をなるべく最小単位に分割して進めていきました。非同期でのメッセージの受信はできるようになったものの、ドライバー側からのメッセージなのかオーナー側からのメッセージなのかを分岐させることができません。少し手詰まり状態にありますが、今も諦めずにトライしています。
⑤LaravelのCollection型の条件分岐(ユーザーからのフィードバック)
知人にアプリケーションの操作トライを依頼した際に、「検索後、該当するものが無かった時にコメントが出ないので分からない」とアドバイスを受けました。これを受け、検索する前・検索して成功した時・検索して失敗した時と3つの条件で表示を分岐させました。この時にLaravelのCollection型の扱いについて理解が少なく、空値判定がうまくいかず長時間悩んでしまいましたので、学習してQiitaにまとめました。[→Qiita記事 リンク]
最後に
転職活動のポートフォリオとして製作しています。実務未経験者が独学で作ったため、内容に誤っている点があるかと思います。お手柔らかにお願いいたします。今後実務を経験して、過去の実力を振り返られるように記録として執筆しました。LGTMで応援いただけると励みになります。
- 投稿日:2021-02-13T15:42:27+09:00
【ポートフォリオ】初心者?がLaravelでカーシェアアプリ開発
概要
車両を保有している人と保有していない人を結ぶアプリケーション。大手カーシェアリングサービスのように車両を会社からドライバーに貸し出す(BtoB)のでなく、個人間で気軽に貸し借りができるサービス(CtoC)をコンセプトとした。
※悪意のあるイタズラが多発したため、アプリリンクは貼っていません。
制作背景
交通インフラの整備や若者の車離れの影響を受け、自動車の国内需要は1990年ごろをピークとして年々減少している。これに伴い、大手のBtoBカーシェアリングサービス(タイムズ)の会員数は過去5年間で約4倍以上伸びている。対して、今後伸びてくると予想されていたCtoCのカーシェアリング業界は伸び悩んでいるというギャップが生じている。この現象に疑問を持ったため、原因をトヨタの問題解決の手法を用いて考え、このギャップを解決するサービスの開発を行った。
[→制作背景詳細 リンク]システム概要
このサービスのユーザーは3パターンに分けられる。
A. ドライバー (車を借りたい人)
B. オーナー (車を貸したい人)
C. 管理者 (Car.マッチング株式会社:自動車保険会社)
操作説明
各ユーザーの操作方法について下記に示す。
A. ドライバーの基本操作
①ログイン
②希望の条件(日時や乗車人数)で検索
③該当したオーナーとチャットでの交流
④車両を借りることへの不安がなくなれば、契約を結んでもらえるようオーナーへ依頼
B. オーナーの基本操作
①ログイン
②車両を貸し出せる日程を登録
③ドライバーから依頼があればチャットにて交流
④オーナーとドライバーが契約条件に合意した場合、契約フォームに入力
⑤確認メール送信
C. 管理者(Car.マッチング株式会社:自動車保険会社)の基本操作
①ドライバーとオーナー間で契約が結ばれた後、DBへ内容が保存されるため、それらを表示
②この登録情報を見て自動車の保険の加入手続き・料金の支払い手続きに移行
こだわり
私はCtoCのカーシェアリング業界が伸びていない原因は主に下記の3点に起因すると考える。
①初期登録操作のハードルが高い
②条件に合う車両を探す作業が煩わしい
③全く交流がない他人から車両を借りることへの不安があるこれらを解決するために下記にこだわって開発した。
A. 初期登録の簡略化
初期の登録はなるべくシンプルにしておき、ドライバーとオーナーの交渉が成立してから、更に必要な情報を入力させる。ナンバープレート情報や料金の設定など初期登録の際に煩わしさを感じるものは契約時に入力させる。B. 操作がシンプル
マルチログイン機能を実装してドライバーとオーナーの操作を分け、余分な機能は付けず、直感的に分かりやすい構成を心がける。
* ドライバーの操作: 初期登録 → 検索 → チャットによるオーナーとの交渉
* オーナーの操作 : 初期登録→ 貸出日程登録 → チャット → 契約詳細入力C. LINEのような手軽さで個人間でチャットが可能(非同期通信)
アプリ内のチャット機能を、スマートフォンユーザーのおよそ80%が利用しているLINEの操作に合わせることで、誰でも容易にチャット機能を使って交流できる。また、非同期通信を行うことによって画面の遷移無しで、相手のメッセージを受け取ることができる。上記とは色合いが異なるが、その他にもユーザーと管理者を思いやった機能も追加した。
D. 契約内容のエビデンスとしてメールの自動送信
オーナーが契約内容を入力後、確認メールが自動でドライバー・オーナー・Carマッチング(自動車保険会社)へと送付される。これにより、ドライバーとオーナーとの間で契約した内容を失念しても、再度確認することができる。また、料金や内容の相違でトラブルが起きた際に、エビデンスとして示すこともできる。E. 管理者用の契約内容閲覧機能
ドライバーとオーナー間で契約が結ばれた後、DBへその内容が保存されるため、その内容を表示する機能。その内容を見て自動車の保険の加入手続き・料金の支払い手続きに移行する。使用技術
バックエンド
PHP 7.2.34 / Laravel 6.20.5フロントエンド
HTML / CSS / javascript / jQuery 3.2.1 / Vue.js(現在学習中のため今後組み込む)インフラ
mysql 8.0.22 / AWS(EC2,S3)その他の使用技術
Pusher / git(gitHub) / Visual Studio Code / draw.io / GmailAWS構成図
DB設計
・ ER図
・ 各種テーブル
テーブル名 定義 owners
(オーナー)オーナーの登録情報 drivers
(ドライバー)ドライバーの登録情報 owner_schedules
(オーナースケジュール)ドライバーの車両貸出可能な日程 chats
(チャット)会話の内容 contracts
(コントラクト)契約確定後、契約内容を格納 苦労したところ
①DB設計
ER図を添付していますが、実際のアプリケーションとテーブル名やカラム名に相違があります。テーブルの命名規則の理解が曖昧ままDB設計をしており、キャメルケースを用いた記述をしてしまいました。開発終盤に気付きましたが、影響範囲が広すぎて修正が困難になりました。この失敗を二度と繰り返さないよう再度学習を行い、Qiitaにまとめています。初期設計の重要性を身に染みて学びました。[→Qiita記事 リンク]
②Laravelのマルチログイン機能
ドライバーとオーナーで初期の登録方法やログインした後の挙動が変わるため、マルチログイン機能を実装する必要がありました。Laravelでは基本のログイン機能がついていますが、これを応用して2通りのログイン機能を作りました。変更が必要なファイルが多く、それぞれの関連性が分かっていなかったため、苦労しました。ここで3日以上も悩んだことで認証やミドルウェア・ルーティングについての知識を身に着けることができました。[→Qiita記事 リンク]
③AWSでのデプロイ
web系企業ではクラウドはAWSが主流になっていますのでAWSを用いて本番環境を構築しました。初めてのVimコマンドの操作に慣れていないことや、ディレクトリの階層も頭に入っていなかったことで、configファイルや.envファイルを探したり編集するだけでかなり難航しました。VPCの生成から数えると30〜40時間以上かけてなんとかデプロイしました。多く悩んだ分、仮想サーバーやIPアドレスの知識・コマンドの操作などを身に着けることができました。
④websocket通信を用いたチャットの非同期通信
外部API(pusher)を用いたリアルタイムチャットの実装に挑戦しました。実装に必要な作業をなるべく最小単位に分割して進めていきました。非同期でのメッセージの受信はできるようになったものの、ドライバー側からのメッセージなのかオーナー側からのメッセージなのかを分岐させることができません。少し手詰まり状態にありますが、今も諦めずにトライしています。
⑤LaravelのCollection型の条件分岐(ユーザーからのフィードバック)
知人にアプリケーションの操作トライを依頼した際に、「検索後、該当するものが無かった時にコメントが出ないので分からない」とアドバイスを受けました。これを受け、検索する前・検索して成功した時・検索して失敗した時と3つの条件で表示を分岐させました。この時にLaravelのCollection型の扱いについて理解が少なく、空値判定がうまくいかず長時間悩んでしまいましたので、学習してQiitaにまとめました。[→Qiita記事 リンク]
最後に
転職活動のポートフォリオとして製作しています。実務未経験者が独学で作ったため、内容に誤っている点があるかと思います。お手柔らかにお願いいたします。今後実務を経験して、過去の実力を振り返られるように記録として執筆しました。
- 投稿日:2021-02-13T11:29:19+09:00
LaravelでFullcalendarに登録した内容を更新する方法
はじめに
前回に続き、今回はFullcalendarで登録した情報を更新する方法についてご説明します。
LaravelでFullcalendarを実装する方法また、今回はカレンダー上の登録したイベントをクリックするとモーダルが出てきて、そのモーダル上で更新ができるようにします。モーダルでは更新前の情報も確認できるようにしたいと思います。
-各バージョン
-Laravel 6.x
-PHP 7.4.9
-MySQL 5.7.30
-Fullcalendar v5Fullcalendarはバージョンによって記述方法が異なるので注意してください。
v4の記事を参考にしてもうまくいかないことが多かったです。なお、フォルダ名とうは登録時に作成したものをそのまま使用しておりますのでご了承ください。
更新用のモーダルを用意する
モーダルはJavaScriptのプアグインであるMicromodal.jsを使用しました。
モーダルに関しては自作のものではなく、プラグインを利用した方が利点が多いというツイートを見かけたので、今回は自作をせずにプラグインを使用しています。Micoromodal.jsのダウンロードは以下から行えます。
(https://micromodal.now.sh/)今回はCDNで読み込ませました。
event.blade.php<!-- Micromodal.js --> <script src="https://unpkg.com/micromodal/dist/micromodal.min.js"></script>続いて、モーダル用のbladeを作成し、更新フォームを作っていきます。
こちらはこの後@include
でevent.blade.php内で読み込ませるので、直接event.blade.php内に書いても問題ないです。また、
header
に関してはMicromodal.jsの公式ドキュメントを参考にしています。
フォームはmain
タグ内に書いていきます。moda.blade.php<div class="modal micromodal-slide" id="modal-1" aria-hidden="true"> <div class="modal__overlay" tabindex="-1" data-micromodal-close> <div class="modal__container" role="dialog" aria-modal="true" aria-labelledby="modal-1-title"> <header class="modal__header"> <h2>Editing my task list</h2> <button class="modal__close" aria-label="Close modal" data-micromodal-close></button> </header> <main> <form method="POST" action="{{ route('editEvent') }}"> @csrf <input type="hidden" id="id" value="" name="id"> <input type="text" id="edit_title" name="title" value=""> <input type="date" id="edit_start" name="start" value=""> <input type="color" id="edit_color" name="textColor" value=""> </form> </main> </div> </div> </div>通常だと
value
に更新前の情報を入れることで、フォームで確認できるのですが、今回はJSで指定するので空にしています。続いて、カレンダー上のイベントをクリックした際に、モーダルが出てくるように設定していきます。
カレンダー上のイベントをクリックした時の挙動は、Fullcalendarの公式ドキュメントを確認すると、eventClick
というプロパティが用意されているようなので、こちらを前回作成したJSに追加していきます。
eventClickevent.blade.php<script> $(document).ready(function () { $('#calendar').fullCalendar({ // はじめりの曜日を月曜日に変更 デフォルトは日曜日になっており、日=0,月=1になる firstDay: 1, headerToolbar: { right: 'prev,next' }, events: '/home', // ここから追加 eventClick: function(info){ document.getElementById("id").value = info.id; document.getElementById("edit_title").value = info.title document.getElementById("edit_start").value = info.start._i document.getElementById("edit_color").value = info.textColor MicroModal.show('modal-1'); } }); }); </script>
info
の中には更新前の情報が入っているので、その情報をそれぞれ先ほど指定したフォーム内のid
属性をgetElementById
で取得し、value
値に指定しています。
また、start
に関しては、console.log(info.start)
で見てみると、_isAMomentObject: true, _i: "2021-02-06", _f: "YYYY-MM-DD", _isUTC: true, _pf:
となっており、_i
の箇所に日付が格納されているのがわかると思います。
そのため、info.start._i
とすることで日付を取得するようにしています。これで、更新前の情報が表示されるようになりました。
また、event.blade.php内でmodal.blade.phpを忘れずに読み込んでください。
私は前回作成した新規登録用のフォームの真下に書きました。event.blade.php@include('modal')コントローラー、ビューを追加する
先ほど
action="{{ route('editEvent') }}
で指定したルートを設定します。web.phpRoute::post('/editEvent', 'EventController@editEvent');続いてコントローラーです。
EventController.phpuse App\Models\Event; //冒頭で宣言する public function editEvent(Request $request) { // 送信されてきたidをEventテーブルに登録されているデータと紐付ける $event = Event::find($request->input('id')); $event->title = $request->input('title'); $event->start = $request->input('start'); $event->textColor = $request->input('textColor'); $event->save(); return redirect('/home'); }以上で更新用モーダルの完成です!
さいごに
今回は、前回作成したFullcalendarの更新処理を、モーダルを利用して作ってみました。
また次回以降は登録したデータの削除方法についても書いていきたいと思います!最後まで読んでいただきありがとうございました!
- 投稿日:2021-02-13T09:50:48+09:00
【Laravel初心者】一覧表示の実装
Laravel初学者です。
オリジナルアプリを作成しているのでその過程を記事にしています。理解が曖昧なところも多いため、ご指摘等ありましたらご連絡いただければ幸いです。
今回は一覧表示の実装について備忘録のため記録として残します。
環境
Version PHP 7.4.14 Laravel 8.24.0 mysql 8.0.23 docker 20.10.2 docker-compose 1.27.4 ルーティング
routes/web.phpRoute::get('/', [GameController::class, 'index']);私の場合は/(ルート)を一覧表示として実装したかったので上記のようなルーティングになります。
/(ルート)
にアクセスがあった時にGameControllerのindexアクション
が動きますという意味です。モデル
Models/Game.php<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Game extends Model { use HasFactory; protected $table = "games"; protected $fillable = [ "id", "user_id", "name", "describe", "play_time", "players_minimum", "players_max", "image_path", "updated_at", "created_at", ]; public function user() { return $this->belongsTo(User::class); } }こちらは今回の一覧表示機能にだけ必要というものではないですが。
$fillable
で指定して保存を許可します。
$fillable
についてはこちらの記事が分かりやすかったです。
ありがとうございます。コントローラー
app/Http/Controllers/GameController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Game; use Illuminate\Support\Facades\Auth; use Storage; class GameController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ //下記がindexアクション public function index() { $games = Game::all(); return view('game.index', compact('games')); } }
$games
にGame::all();
でGameモデルから全てのデータを取ってきて代入しています。全てとるので複数形の$games
になってます。プログラミング学び始めのとき、複数形なのか単数形なのか分からなかったんですよね。
allで全てとる=複数のデータ=つまり複数形
なので普通に考えれば簡単ですよね。その後
return view
でindex
のviewを返す動きになってます。
compact('games')
と記述することでview側で$games
という変数が使えます。
逆にcompact書かないとエラーになりますので注意です。compactについてはこちらの記事が分かりやすかったです。
ありがとうございます。ビュー
resources/views/game/index.blade.php<section class="page-section bg-light" id="portfolio"> <div class="container"> <div class="text-center"> <h2 class="section-heading text-uppercase">新着ボードゲーム</h2> <h3 class="section-subheading text-muted">Lorem ipsum dolor sit amet consectetur.</h3> </div> <div class="row"> @foreach($games as $game) @if($game->image_path) <div class="col-lg-4 col-sm-6 mb-4"> <div class="portfolio-item" style="text-align:center"> <a class="portfolio-link" href="{{ route('game.show', $game->id) }}"> <img src="{{ $game->image_path }}" height="200" width="200"> </a> <div class="portfolio-caption" style="margin-top:10px"> <div class="portfolio-caption-heading">{{ $game->name }}</div> <div class="portfolio-caption-subheading text-muted">プレイ時間:{{ $game->play_time }}分</div> <div class="portfolio-caption-subheading text-muted">人数:{{ $game->players_minimum }}~{{ $game->players_max }}人</div> </div> </div> </div> @endif @endforeach </div> </div> </section>resources/views/game/index.blade.php@foreach($games as $game) //この中に処理を書く @endforeach上記のように
foreach
で繰り返し処理をしています。
コントローラーがデータを$games
に入れてviewに渡してくれているのでそれをforeachの中では$game
として一つずつ取り出します。つまり一つずつ呼び出すためには
resources/views/game/index.blade.php{{ $game->name }}上記のように
$game
のname
というように記述します。こちらで一覧表示の実装は完了です。
- 投稿日:2021-02-13T08:02:23+09:00
Laravelでnpm runしたときのメモ
Vueテンプレートを使って、Laravelの認証画面を作ろうとして詰まった。
- Laravelに laravel/uiを導入
- vueテンプレートを指定
- npmインストール
この流れでやると失敗した。
こちらの記事の内容も試してみたが、エラーは解決しなかった。
laravelでnpm run devを実行すると「cross-env: not found」というエラーが出る件対応したった
npm install
まではうまくいくが、npm run dev
でエラーになるnpm ERR! code 1 npm ERR! path /var/www/html/larabel npm ERR! command failed npm ERR! command sh -c cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/2021-02-12T22_41_21_472Z-debug.log npm ERR! code 1 npm ERR! path /var/www/html/laravel npm ERR! command failed npm ERR! command sh -c npm run development npm ERR! A complete log of this run can be found in: npm ERR! /root/.npm/_logs/2021-02-12T22_41_21_507Z-debug.log1. webpack.mix.jsの修正
mix.js('resources/js/app.js', 'public/js') .vue() // → 削除 .sass('resources/sass/app.scss', 'public/css');npm 再インストール
rm -rf node_modules/ rm -rf package-lock.json npm install npm run devこれで解決した。
98% after emitting SizeLimitsPlugin DONE Compiled successfully in 24793ms 10:47:18 PM Asset Size Chunks Chunk Names /css/app.css 179 KiB /js/app [emitted] /js/app /js/app.js 1.41 MiB /js/app [emitted] /js/app
- 投稿日:2021-02-13T07:49:20+09:00
Laravel8.xのプロジェクトをXREAで無料公開する
概要
Laravel8+MySQLで作ったプロジェクトを無料でホスティングしたいなーと思って調べていたら、XREA(エクスリア)というレンタルサーバーを見つけました。無料プランながらシンプルで使いやすく、Laravelアプリの公開もかなり簡単にできたので、こちらに手順をまとめておきます。
Laravel以前にかなり基本的な部分から書いてありますので、わかる部分は適当に読み飛ばして使ってください。前提
- Laravel8系のプロジェクトができている
- githubなどにソースコードが上がっている
- (MacOS)
手順
1. バリュードメインのユーザー登録、XREAのアカウント作成
2. ドメインの購入(特にこだわりがなければ必要ありません)
3. XREAで各種設定
- 3.1 SSH接続の許可
- 3.2 DBの作成
- 3.3 サイト設定の変更 (ドメインを購入していない場合のみ)
- 3.4 ドメイン設定(ドメインを購入した場合のみ)
- 3.5 サイト設定(ドメインを購入した場合のみ)4. SSHログイン
- 4.1 シェルをbashに変更
- 4.2 composerのセットアップ
- 4.3 node,npmのバージョンアップ5. プロジェクトの設定
- 5.1 git cloneで持ってくる
- 5.2 composer、npm周り
- 5.3.env
の設定
- 5.4 マイグレーション等6. シンボリックリンクの設定
変に詰まらなければ20分くらいで終わると思います。
1. バリュードメインのユーザー登録、XREAのアカウント作成
こちらにアクセスして手順通りにバリュードメインとXREAの登録をします。
2021年2月現在、XREAに登録すると1年間無料で
.shop
のドメインがついてきます。次の2.ドメインの購入
を行わない方は、ここで決めたアカウント名がそのままURLになります。
希望のサーバー選択はおそらく無料プランでは選べないようになっているので、そのまま登録してください。2. ドメインの購入
希望のドメインがある方は、バリュードメインの
ドメイン登録
から、希望のドメインの検索をして購入します。https://www.value-domain.com/domain/search/
現在は
.tokyo
ドメインが安く、(取られてなければ)初年度25円で取得できるみたいです。
支払いもクレジットカードからコンビニ決済まで対応しているので結構気軽に買えます。
購入後は登録者情報の入力など手順通りに進めてください。3. XREAでの各種設定
XREA登録時にメールが届いているので確認します。
ログインに必要な情報が記載してあるので、これを使ってXREAにログインします。
https://cp.xrea.com/account/login/XREAのパスワードはバリュードメインに自分で登録したものとは違うので注意してください。
また、XREAでは独自のパスワードが設定できないため、このパスワードはどこかにメモしておくといいと思います。
ログイン後の画面です。
※もし旧コントロールパネルが表示されている場合は、右上の新コンパネ切替
をONにして新コントロールパネルに移行します。
3.1 SSH接続の許可
メニューの
サイト設定
からツール/セキュリティー
を開き、下の方にあるSSH接続IP許可
のボタンをクリックします。
これでSSH接続が可能になります。
3.2 DBの作成
メニューの
データベース
から、データベースの新規作成
をクリックします。
無料プランでは、XREAのユーザー名がそのままDB名になります。
パスワードは後ほど.env
のDB情報に入力するので覚えておいてください。
3.3 サイト設定の変更 (ドメインを購入していない場合のみ)
ついてきた
.shop
のドメインを使う場合は、以下の設定をしてください。メニューの
サイト設定
から、www
のついている方のサイトについての設定を変更します。
PHPのバージョンが7.3以上でないとLaravel8は動かないため、バージョンを7.4にします。
3.4 ドメイン設定 (ドメインを購入した場合のみ)
購入したドメインを使う場合は以下の設定をしてください。
メニューの
ドメイン設定
からドメイン設定の新規設定
をクリックし、先ほど取得したドメインを設定します。
3.5 サイト設定 (ドメインを購入した場合のみ)
次にメニューの
サイト設定
から先ほど設定したドメインについて設定します。
ドメイン名に取得したドメイン、SSLは無料SSL、PHPは7.4を選んでください(Laravel8はPHP7.3以上が必要なため)。
4. SSHログイン
XREAの画面の右上に、ユーザー名とホスト名が表示されています。
コマンドラインで以下のように入力します。$ ssh {user}@{host}例
$ ssh hoge1234@s202.xrea.com
パスワードの入力を要求されるので、XREAのパスワード(先ほど送られてきたメールに記載してあるもの)をコピペで入力します。
[hoge1234@s202 ~]$このように表示されればログイン成功です。
4.1 シェルをbashへ変更
デフォルトのシェルはrbashになっています。このままではcdなどのコマンドが使えないため、bashに変更します。
$ chsh hoge1234 のシェルを変更します。 新しいシェル [/bin/rbash]: /bin/bash パスワード: シェルを変更しました。 $ exit ログアウト Connection to s202.xrea.com closed.パスワードはSSHログイン時と同じです。
bashに変更したあと一度ログアウトして再度入ると変更が反映されており、cdなどのコマンドが使えるようになっています。4.2 composerのセットアップ
Download Composerより、以下のコマンドを実行してください。
ただし、CLI版PHPを使うためコマンドがphp74cli
となっていることに注意してください。また、2行目ではハッシュ値のチェックによりオリジナルファイルかどうかを確認していますが、このハッシュ値はcomposer-setup.phpの変更に伴って変わります。下記のハッシュがそのとき使えるとは限らないので、下記のコピペではなく上記のリンクから公式のコマンド(ハッシュ値)を持ってきて実行してください。
$ php74cli -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" $ php74cli -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" $ php74cli composer-setup.php $ php74cli -r "unlink('composer-setup.php');"コマンドを実行し終えたらcomposerを叩いてみます。
$ php74cli -d register_argc_argv=1 ~/composer.phar --version Composer version 2.0.9 2021-01-27 16:09:27実行コマンドが長いのでエイリアスに登録しておきます。(パスの通し方がイマイチわかりませんでした…)
viで.bash_profile
に以下を記載します。.bash_profilealias composer="php74cli -d register_argc_argv=1 ~/composer.phar"反映します。
$ source ~/.bash_profile$ composer --version Composer version 2.0.9 2021-01-27 16:09:27これでcomposerのセットアップは終わりです。
4.3 node,npmのバージョンアップ
node,npmも入っているもののかなり古いので、バージョンアップします。
$ node -v v6.17.1 $ npm -v 3.10.10現在のLatestは
node: 14.15.5
,npm: 6.14.11
だったので、とりあえずそれを持ってきます。# curlで圧縮ファイルを取ってくる $ curl -sSL -O https://nodejs.org/dist/v14.15.5/node-v14.15.5-linux-x64.tar.xz # 解凍 $ tar xvf ./node-v14.15.5-linux-x64.tar.xz # 圧縮ファイルの削除 $ rm node-v14.15.5-linux-x64.tar.xz #ディレクトリを用意する $ mkdir ~/.local/lib # 移動する $ mv ./node-v14.15.5-linux-x64 ~/.local/lib/パスを通すために
.bash_profile
に以下を追記します。.bash_profileexport PATH="${HOME}/.local/lib/node-v14.15.5-linux-x64/bin:${PATH}"反映します。
$ source ~/.bash_profile$ node -v v14.15.5 $ npm -v 6.14.11nodeとnpmのバージョンアップもできました。
5. プロジェクトの設定
5.1 git cloneで持ってくる
ホームディレクトリの
public_html
内には、XREAのサイト設定にあるサイトごとにディレクトリが用意されています。(ドメイン購入をした場合は、元からついている.shop
のディレクトリに加えて購入したドメインのディレクトリがあると思います。)$ cd ~/public_html/ $ ls log hoge1234.shopXREAではデフォルトでgitが使えます。
使いたいドメインのディレクトリに入り、git cloneします。$ cd hoge1234.shop $ git clone https://github.com/hoge/fuga.git5.2 composer, npm周り
ここはローカルでの作業とあまり変わりません。
cloneしたプロジェクトのディレクトリに入り、下記コマンドを実行します。# composerのライブラリのインストール $ composer install # npmパッケージのインストール $ npm install # LaravelMixでアセットをコンパイル $ npm run dev5.3
.env
の設定
.env
をサーバーに合わせて設定していきます。$ cp .env.example .env $ vi .env以下のように変更します。
.env+ APP_NAME={appname} (自分で決めたappの名前) + APP_ENV=production APP_KEY= + APP_DEBUG=false + APP_URL=https://{domain} (使うドメイン) LOG_CHANNEL=stack + LOG_LEVEL=error DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 + DB_DATABASE=hoge1234 (3.2 DBの作成 で決めたDB名、ユーザー名と同じ) + DB_USERNAME=hoge1234 (ユーザー名) + DB_PASSWORD={password} (3.2 DBの作成 で決めたパスワード)5.4 migration等
こちらもローカルでの作業と変わりません。
ただし、artisanコマンドを使用する際はphp74cli artisan
となることに注意してください。# keyの生成 $ php74cli artisan key:generate # migration $ php74cli artisan migrate # seederがある場合 $ php74cli artisan db:seedローカルで動かす時と同じようにコマンドを叩いてください。
6. シンボリックリンクの設定
Laravelプロジェクトの準備はできたので、参照先の設定をします。
ここもついてくる.shop
を使う方とドメインを購入した方とで少し違うので注意してください。現在のディレクトリ構成は以下のようになっていると思います。
public_html | |-- {domain} | |-- {appname} | |-- app |-- bootstrap |-- config |-- database |-- ... |-- ... |-- public |-- ...
.shop
を使う場合、hoge1234.shop
にアクセスするとwww.hoge1234.shop
にリダイレクトされ、~/public_html/
をルートとしてファイルを参照するようになっています。
~/public_html/
を参照した際に、~/public_html/{domain}/{appname}/public/
のファイルを代わりに参照するようにします。$ ln -s ~/public_html/{domain}/{appname}/public/index.php ~/public_html/index.php $ ln -s ~/public_html/{domain}/{appname}/public/.htaccess ~/public_html/.htaccess $ ln -s ~/public_html/{domain}/{appname}/public/js ~/public_html/js $ ln -s ~/public_html/{domain}/{appname}/public/css ~/public_html/css $ ln -s ~/public_html/{domain}/{appname}/public/img ~/public_html/img $ ln -s ~/public_html/{domain}/{appname}/public/mix-manifest.json ~/public_html/mix-manifest.json $ ln -s ~/public_html/{domain}/{appname}/public/robots.txt ~/public_html/robots.txt $ ln -s ~/public_html/{domain}/{appname}/public/favicon.ico ~/public_html/favicon.ico購入したドメインを使う場合、
fuga1234.com
にアクセスすると~/public_html/fuga1234.com/
をルートとしてファイルを参照するようになっています。
~/public_html/fuga1234.com/
を参照した際に、~/public_html/{domain}/{appname}/public/
のファイルを代わりに参照するようにします。$ ln -s ~/public_html/{domain}/{appname}/public/index.php ~/public_html/{domain}/index.php $ ln -s ~/public_html/{domain}/{appname}/public/.htaccess ~/public_html/{domain}/.htaccess $ ln -s ~/public_html/{domain}/{appname}/public/js ~/public_html/{domain}/js $ ln -s ~/public_html/{domain}/{appname}/public/css ~/public_html/{domain}/css $ ln -s ~/public_html/{domain}/{appname}/public/img ~/public_html/{domain}/img $ ln -s ~/public_html/{domain}/{appname}/public/mix-manifest.json ~/public_html/{domain}/mix-manifest.json $ ln -s ~/public_html/{domain}/{appname}/public/robots.txt ~/public_html/{domain}/robots.txt $ ln -s ~/public_html/{domain}/{appname}/public/favicon.ico ~/public_html/{domain}/favicon.icopublic内の各ファイルについてシンボリックリンクを貼っています。
他にもpublic内にfonts
など別のアセットがある場合はその分のシンボリックリンクも貼ります。これでURLにアクセスしてみて、表示されていたら成功です。
※
.shop
を使う場合、SSL設定ができないのでhttps://
をつけると上手くいきません。最後に
ここまで書きましたがやっぱりherokuの方が楽な気がし
XREAでLaravelプロジェクトを無料公開する手順を最初から最後まで書いている記事が見つからなかったため、いろいろ調べた勢いで書いてみました。
ところどころ知識が甘く曖昧な表現などがあると思いますが、「とりあえずなんでもいいからLaravelで作ったものを公開してみたい!」という方のお役に立てれば幸いです。参考記事