- 投稿日:2019-07-30T21:31:01+09:00
VagrantでVScodeのRemote Developmentを使おう!
はじめに
最近LaravelのでVagrantを用いたHomestead環境で作業をしており,remoteの作業環境としてVScode拡張機能のSSH FSを使用していました(この記事).
上記記事を投稿したところ,VScodeではもうremote developmentが使えるよ!と教えていただいたので,使ってみたいと思います.
実行環境
- macOS Mojave v10.14.5
- VScode v1.36.1クソ簡単
とりあえずVagrantを動かすディレクトリに移動します.
その後,vagrantでssh接続する際の設定をみてみます.cd Homestead vagrant ssh-config上記コマンドのように,vagrantが動くところに行って
vagrant ssh-config
,というイメージで大丈夫です.すると以下のようにvagrantでssh接続する際の設定が吐き出されます.
Host homestead HostName 127.0.0.1 User vagrant Port [port.No] UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/[username]/Homestead/.vagrant/machines/homestead/virtualbox/private_key IdentitiesOnly yes LogLevel FATAL ForwardAgent yesvagrantならすでにリモート側にssh接続をする準備が整っているので,ホストのssh接続に関するconfigに設定を書き込んでおきます.
以下のコマンドを実行してください.
vagrant ssh-config
で出力される結果を~/.ssh/config
に書き込みます.vagrant ssh-config >> ~/.ssh/config設定は以上だけで終わりです!
あとはVScode(アップデートはしておいてください)で拡張機能の"Remote Development"を検索してください.
Remote Developmentをインストールしたら,画面左下に表示される
><
のようなマークをクリック,"Remote-SSH: Connect to Host"を選択して先ほど設定したリモートサーバの名前を選択します.以上で接続終了です!
ローカルに入っている拡張機能はリモート側では導入されていないことがありますので,必要な拡張機能をインストールしてカスタマイズしていきましょう.
まとめ
設定ファイルの記述がコマンド一発なのは楽ですね...
各種intellisenseやemmet, git lensなどの拡張機能も使えてかなり開発が捗りそうです,VScode最高!!
- 投稿日:2019-07-30T19:58:50+09:00
「ようこそ・・・『テストの世界』へ・・・」
はじめに
本記事では、テストをまだ書いたことのない人向けに
「今日からテストを書いてみようかな」
と思ってもらえるよう、チュートリアル風に簡単なテストの流れを説明します。
題材はLaravelですが、他のフレームワークでも同じようなことはできると思います。
前提
本記事の対象者
- Laravel初心者で、
- テストをまだ書いたことの無い人
- テストで何ができるのか知らない人
- テストに興味はあるが忙しくてどう書けば良いのかまだ調べられていない人
本記事で取り扱うこと
- ごく簡単なHTTPリクエストのテストの書き方
本記事で取り扱わないこと
- テストの全般的な話(利点、注意点など)
- テストケースの作り方
- CIツールによるテスト自動化
環境
- Laravel 5.8.x
簡単な画面(HTTPレスポンス)のテスト
まずは、Laravelを触ったことのある人なら一度は見たことのある?Welcome画面をテストしてみます。
これが正常に表示されることを、目視ではなくテストコードで確認してみましょう。
Laravelをインストールすると、既に
tests/Feature/ExampleTest.php
という、テストコードのサンプルが存在します。tests/Feature/ExampleTest.php<?php namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; class ExampleTest extends TestCase { /** * A basic test example. * * @return void */ public function testBasicTest() { $response = $this->get('/'); $response->assertStatus(200); } }この
ExampleTest
は、Tests\TestCase
を継承しており、テストに関する様々なメソッドが使えます。
$response = $this->get('/')
で、'/'
にアクセスした(GETリクエストした)結果のレスポンス1が$response
に代入されます。
そして、$response->assertStatus(200)
で、そのレスポンスが正常であること(ステータスコードが200 OK
であること)をチェックしています。ステータスコードについては以下を参考にしてください。
この
ExampleTest
を実行するには、Laravelのルートフォルダで以下コマンドを実行してください。$ ./vendor/bin/phpunit ./tests/Feature/ExampleTest.phpすると、以下の結果が表示されました。
PHPUnit 7.5.12 by Sebastian Bergmann and contributors. . 1 / 1 (100%) Time: 448 ms, Memory: 14.00 MB OK (1 test, 1 assertion)OK、と表示されています。
つまり、
'/'
へアクセスした(GETリクエストした)結果、正常にレスポンスが返ってきた(HTTPレスポンスステータスコードが200 OK
だった)ということです。これをテストコードで確認することができました。
ビューのテスト
ただ、このテストでわかったのは、正常にレスポンスが返ってきた、ということまでです。
Welcome画面が表示されたのかどうかまでテストできていません。
現状のルーティングを見ると、
'/'
へアクセスすると、'welcome'
というビューが表示されることがわかります。routes/web.phpRoute::get('/', function () { return view('welcome'); });
welcome
というビューは、具体的にはresources/views/welcome.blade.php
というビューのテンプレートです。この
resources/views/welcome.blade.php
こそがあのWelcome画面なので、このテンプレートが使われているかどうかをテストで確認してみます。
tests/Feature/ExampleTest.php
に以下のコードを追加します。tests/Feature/ExampleTest.phppublic function testBasicTest() { $response = $this->get('/'); $response->assertStatus(200) ->assertViewIs('welcome'); // 追加 }このように
assertViewIs
メソッドで、どんなビューが使われたのかをテストすることができます。修正後の
ExampleTest
を実行してみます。$ ./vendor/bin/phpunit ./tests/Feature/ExampleTest.php // 略 OK (1 test, 2 assertions)こちらも結果はOKとなりました。
あのWelcome画面が表示されていることを、テストコードで確認することができました。
さらに
assertSee
メソッドを使うと、表示されている2文字列もテストできます。
Welcome画面にLaravel
の文字が表示されていることを、テストコードで確認してみましょう。
tests/Feature/ExampleTest.php
に以下のコードを追加します。tests/Feature/ExampleTest.phppublic function testBasicTest() { $response = $this->get('/'); $response->assertStatus(200) ->assertViewIs('welcome') ->assertSee('Laravel'); // 追加 }修正後の
ExampleTest
を実行してみます。$ ./vendor/bin/phpunit ./tests/Feature/ExampleTest.php // 略 OK (1 test, 3 assertions)こちらも結果はOKとなりました!
ログイン中かどうかを絡めたテスト
ここから先は、ユーザーがログイン中かそうでないかによって結果が異なる画面をテストしていきます。
Laravelでは以下コマンドでユーザー登録画面やログイン画面等を作成できるので、これを実行します。
$ php artisan make:authこのコマンドの詳細については、以下の記事を参考にしてください。
Welcome画面にユーザー登録画面とログイン画面へのリンクが追加されました。
以下、テストではなく人力でユーザー登録画面にアクセスし、ユーザー登録を行なっています。
ユーザー登録が完了すると、以下のホーム画面へ遷移します。なお、ログイン画面からログインした場合も、このホーム画面へ遷移します。
ホーム画面は、ログイン中の時のみ表示されます。
ログインしていない状態で直接
/home
へアクセスすると、ホーム画面は表示されず、ログイン画面へリダイレクトされます。この「ホーム画面は、ログイン中の時のみ表示される」ということをテストコードで確認してみましょう。
ホーム画面の表示は、
php artisan make:auth
コマンドによって作成された、app\Http\Controlles\HomeController
で行われています。この
HomeController
をテストするためのHomeControllerTest
を作成します。以下コマンドを実行すると、テストの雛形を作成できます。
$ php artisan make:test HomeControllerTest作成されたテストの雛形の内容は、以下になります。
tests/Feature/HomeControllerTest.php<?php namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Foundation\Testing\RefreshDatabase; class HomeControllerTest extends TestCase { /** * A basic feature test example. * * @return void */ public function testExample() { $response = $this->get('/'); $response->assertStatus(200); } }この
tests/Feature/HomeControllerTest.php
を以下の通り編集します。tests/Feature/HomeControllerTest.phppublic function testExample() { $response = $this->get('/home'); // 変更(ホーム画面のパスに変更) $response->assertStatus(200) ->assertViewIs('home') // 追加(ここでの'home'は、ホーム画面で使われているビュー名) ->assertSee('You are logged in!'); // 追加(ホーム画面で表示されているメッセージ) }この
HomeControllerTest
を、以下コマンドで実行します。$ ./vendor/bin/phpunit ./tests/Feature/HomeControllerTest.phpすると、以下の通り、OKではなくFAILURES!となりました。
PHPUnit 7.5.12 by Sebastian Bergmann and contributors. F 1 / 1 (100%) Time: 442 ms, Memory: 14.00 MB There was 1 failure: 1) Tests\Feature\HomeControllerTest::testExample Expected status code 200 but received 302. Failed asserting that false is true. /var/www/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:133 /var/www/tests/Feature/HomeControllerTest.php:20 FAILURES! Tests: 1, Assertions: 1, Failures: 1.
Expected status code 200 but received 302.
と出力されています。ログイン中でない状態でアクセスしたので、リダイレクトを示す
302
のステータスコードが返ってきた、ということです。そこで、ログインした状態を作り出してテストしてみます。
DBには、先ほど人力でユーザー登録画面にアクセスして登録したユーザーデータが存在するので、テストではこのユーザーを使うことにします。
# select id, name from users; id | name ----+-------------------- 1 | shonansurvivors (1 rows)
tests/Feature/HomeControllerTest.php
を以下の通り編集します。tests/Feature/HomeControllerTest.php<?php namespace Tests\Feature; use App\User; // 追加 use Tests\TestCase; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Foundation\Testing\RefreshDatabase; class HomeControllerTest extends TestCase { public function testExample() { $response = $this ->actingAs(User::find(1)) // 追加 ->get(route('home')); $response->assertStatus(200) ->assertViewIs('home') ->assertSee('You are logged in!'); } }
actingAs
メソッドで、そのユーザーとしてログイン済の状態になります。また、
User::find(1)
で、DBのusersテーブルからid
が1
であるユーザーを取ってきています。改めて
HomeControllerTest
を、以下コマンドで実行します。$ ./vendor/bin/phpunit ./tests/Feature/ExampleTest.phpすると、OKとなりました。
OK (1 test, 3 assertions)ログイン中の状態で
/home
へアクセスすると、
- ステータスコードが
200
となることhome
というビューが使われていることYou are logged in!
が、html中に存在することが確認できました。
このようにログイン中かどうかが絡む機能も、テストコードで確認できます。
テストに必要なDBのデータを自動で準備する
今回はたまたま開発環境のDBにユーザーのデータが存在し、テストではこれを利用してログインを行いましたが、 テストに必要なDBのデータ準備もコードで自動化してみます。
Laravelではテスト用のDBのデータを作るのに、ファクトリというものを使う方法があります。
database/factories/UserFactory.php
が、ユーザーデータを作るためのファクトリです。database/factories/UserFactory.php<?php use App\User; use Illuminate\Support\Str; use Faker\Generator as Faker; $factory->define(User::class, function (Faker $faker) { return [ 'name' => $faker->name, 'email' => $faker->unique()->safeEmail, 'email_verified_at' => now(), 'password' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', // password 'remember_token' => Str::random(10), ]; });このファクトリの詳細については本記事では触れませんが、これを使うといい感じにダミーのデータを作ってくれます。
ファクトリについてもっと知りたい方は、以下記事を参考にしてください。
このファクトリを使うよう、
tests/Feature/HomeControllerTest.php
を以下の通り変更します。tests/Feature/HomeControllerTest.php<?php namespace Tests\Feature; use App\User; // 追加 use Tests\TestCase; use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Foundation\Testing\RefreshDatabase; class HomeControllerTest extends TestCase { public function testExample() { $user = factory(User::class)->create(); // 変更(ファクトリでユーザーデータを作成) $response = $this ->actingAs($user) // 変更(ファクトリで作ったユーザーデータでログイン中状態を作る) ->get(route('home')); $response->assertStatus(200) ->assertViewIs('home') ->assertSee('You are logged in!'); } }ファクトリで作成されたユーザーにて、ログイン中の状態を作っています。
以下コマンドで
HomeControllerTest
を実行すると、結果はOKとなりました。$ ./vendor/bin/phpunit ./tests/Feature/HomeControllerTest.php // 略 OK (1 test, 3 assertions)ただ、これだと
HomeControllerTest
実行のたびにDBにダミーのユーザーデータが1件また1件...と作られてしまいます。sample=# select id, name from users; id | name ----+-------------------- 1 | shonansurvivors 2 | Dr. Jayce Wiegand 3 | Miss Shayna Deckow (3 rows)2件目と3件目がファクトリで作られたダミーのユーザーデータです。
これに対しては、ひとつのやり方として、テスト用の
DatabaseTransactions
を使うという方法があります。これを使うと、テストの実行後にDBをロールバックし、テスト実行中にDBに作ったデータが残らなくなります。
tests/Feature/HomeControllerTest.php
で、DatabaseTransactions
を使うようにします。tests/Feature/HomeControllerTest.php<?php namespace Tests\Feature; use App\User; use Tests\TestCase; use Illuminate\Foundation\Testing\DatabaseTransactions; // 追加 use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Foundation\Testing\RefreshDatabase; class HomeControllerTest extends TestCase { use DatabaseTransactions; // 追加 public function testExample() { // 以下変更点なしにつき省略以下コマンドで
HomeControllerTest
を実行すると、結果は引き続きOKとなりますが・・・$ ./vendor/bin/phpunit ./tests/Feature/HomeControllerTest.php // 略 OK (1 test, 3 assertions)テスト終了後のDBを見ると、ユーザーデータはテスト開始前時点から増えてはいません(3件のまま)でした。
sample=# select id, name from users; id | name ----+-------------------- 1 | shonansurvivors 2 | Dr. Jayce Wiegand 3 | Miss Shayna Deckow (3 rows)これでDBにダミーデータが残ることなく、何度でもテストを実行できます。
最後に
以上で、本記事のテスト体験ツアーは終了です。
テストでどのようなことができるか、イメージはつかめたでしょうか。
本記事をきっかけに、テストを書き始めていただければ幸いです。
「納期は守る」「品質も確保する」
「両方」やらなくちゃあならないってのが「エンジニア」のつらいところだな参考
- 投稿日:2019-07-30T19:00:49+09:00
DockerでLaravelを立ち上げた際の学習メモ
DockerでLaravelを立ち上げた際の学習メモ
>>> 編集中
はじめに
アプリケーションを開発していく上で、開発環境のWindowsと本番環境のLinuxで差分が出てしまうのを
解決したかったので、Dockerを実際に使ってみましたそれに伴いDockerの概要や使ってみた感想などをまとめてみました
今回使用するリポジトリです
Dockerについて
まず、Dockerとは仮想環境を提供するソフトウェアの事を指します
コンテナは隔離されたOSを持ち、その上でアプリケーションを稼働させることが出来ます
そしてアプリケーションを依存対象と共にカプセル化することが出来ますまたホストOSとリソースを共有出来ることが特徴です
Dockerの大まかな概要は下記を参照してください
Dockerのデメリット
Dockerを利用する上での利点についてです
- フレームワークやミドルウェアを自分で構築する必要がない
例えばLaravelを利用した開発を行う場合に、ホストOSにPHPをインストールしなくても
Bitnamiが提供するLaravelのイメージがDocker Hubと呼ばれるリポジトリに配布されているため
簡単に環境を構築できますまた新しいフレームワークや技術が登場しても、Docker Hubにイメージが配布されていれば、自分で環境構築をする必要はありません
- 複数の開発環境の統一できる
DockerfileにOSやパッケージのバージョンを指定することが出来るため
開発環境ではUbuntu
、RHEL
などのOSやRuby
、Nodejs
、PHP
、Go
などの言語のバージョンを統一できますまた
apt
、pip
などのパッケージマネージャで管理されていないライブラリをmsiをでいちいちインストールする必要もありません僕の認識ではseleniumは、ChromeDriverを手でインストールする必要がありますが
コンテナの場合、その作業は必要なく、ホストの\\Program Files
や/opt
、/var
などの汚染を気にすることもありません
- 開発環境と本番環境の差分を埋めることが出来る
アプリケーションやミドルウェアはDocker Engine上で稼働するため
開発環境、本番環境のホストOS上でDocker Engineプロセスさえ起動していれば、アプリケーションは差分なく稼働することが出来ます
- VMと比べて早い
リンクを参照すると早いかもしれません
ゲストOSがない分、コンテナの起動が早くキャッシュを利用したコンテナの再ビルドはとても高速です
vagrant up
に比べて体感速度レベルで起動速度が違いますDockerのデメリット
セキュリティが弱い
開発中なので、バグを踏む可能性がある
依然として、VMに依存しているのでオーバヘッドなどで恩恵を100%受けることが出来ない
Dockerを理解する
基本的なDockerの操作についてです
まずDockerをホストにインストールする必要があります
Dockerのインストールについては、下記のリンクを参照してくださいインストールが終わったところで、簡単にコンテナでコマンドを実行する流れを紹介します
例えばCent OSコンテナでcat /etc/system-release
コマンドを実行する場合は下記の手順を踏むことで処理を行えます
docker pull centos
コマンドで、コンテナのひな形となるイメージファイルを取得するdocker run --name mycontainer centos
コマンドで、イメージからコンテナを生成、起動する- コンテナログイン後、
cat /etc/system-release
コマンドで実行するexit
コマンドでコンテナから抜ける
CentOS Linux release 7.6.1810 (Core)
が表示されれば処理成功です、バージョンは読み替えて下さい補足ですが、docker runの引数に指定されたイメージがローカル環境に存在しない場合、Docker Hubから取得できるため、上記の作業はワンライナーで行えます
docker run -it --rm centos cat /etc/system-release
基本的な操作を理解したうえで、サブコマンドやDockerアーキテクチャについて確認してください
Docker + Laravel
ここではDockerを使ってLaravelをインストールし、起動してみます
まずは環境情報についてです
PC
: Windows 10 Pro
Docker
: Docker version 19.03.1
シェル
: cmd、git bashターミナルは
cmd
とgit bash
を使用しています、>
プロンプトはcmdで$
プロンプトはgit bashですここで下記の内容を行います
- composerコンテナを作成する
- Laravelをcomposerでインストールする
- Laravelを起動し、ホストOSからLaravelのTOPページが見えることを確認する
- 開発環境でソースを編集し、変更が反映されることを確認する
まずは作業に使うディレクトリとLaravelを配置するディレクトリを作成します
> sh -c "mkdir -p work/app"ディレクトリ階層
> tree /F /A | sh -c "egrep '^\s*[\||\\\\|+]'"\---work --- 親ディレクトリ \---app --- Laravel配置ディレクトリ次にDockerfileを作成します
> sh -c "touch work/Dockerfile"Dockerfileの詳細です、このDockerfileはcomposerコンテナとして使用します
FROM php ENV COMPOSER_ALLOW_SUPERUSER 1 RUN apt update && apt install -y wget git unzip RUN EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)" && \ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \ ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" && \ [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] && { \ >&2 echo 'ERROR: Invalid installer signature' && \ rm composer-setup.php && \ exit 1;\ }; \ php composer-setup.php --quiet && \ mv ./composer.phar /usr/local/bin/composer ENTRYPOINT ["composer"]各パラメータについて説明します
Laravelのインストールのため、phpコンテナを使用します
FROM phpコンテナの操作する際のユーザはrootを使用していますが、Laravelをrootで起動すると
警告が出るため、一旦ここではroot起動を許可する設定を入れていますENV COMPOSER_ALLOW_SUPERUSER 1インストーラ取得時の
wget
、Laravelをインストールする際に必要なgit
、unzip
をインストールしますRUN apt update && apt install -y wget git unzipRUN EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)" && \ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \ ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" && \ [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] && { \ >&2 echo 'ERROR: Invalid installer signature' && \ rm composer-setup.php && \ exit 1;\ }; \ php composer-setup.php --quiet && \ mv ./composer.phar /usr/local/bin/composerエントリポイントと呼ばれる起動シェルを指定します
このコンテナはLaravelをインストールするコンテナとして使用するため、値にはcomposer
を使用しますENTRYPOINT ["composer"]コマンド簡易化のため、ターミナルを切り替えます
> sh用意が出来たので、Dockerfileの内容をイメージに固めます
イメージを固める際に-t
オプションをつけてイメージに名前を付けておくと後で楽なので
composerタグをつけます$ cd work $ docker build ./ -t composercomposerイメージを使用して、Laravelのインストールを行います、下記コマンドを実行し
Application key set successfully.
が標準出力に表示され、ホストのディレクトリにLaravel一式が作成された場合は、処理成功です$ docker run -it --rm -v /`pwd`/app://app -w //app composer create-project --prefer-dist "laravel/laravel=5.8.*" .コマンドオプションを見てみます
このコマンドでやりたいことは、ホストの./app
ディレクトリとコンテナの/app
ディレクトリをマウントさせた状態でLaravelを/app
にインストールすることです
-i
ホストの入力をコンテナの標準入力に繋げます
-t
コンテナの標準出力をホストの標準出力に繋げます
--rm
コンテナが処理を終了した場合、自動的に停止したコンテナを削除します
-v
マウントオプションです、[ホストのパス]:[コンテナのパス]によって
ホストのファイルとコンテナのファイルの同期を行います
-w
作業ディレクトリの指定です
composer
イメージの指定です
create-project --prefer-dist "laravel/laravel=5.8.*" .
コンテナで実行するコマンドですコマンドが成功したら、Laravelを起動してみます、下記コマンドを実行し
ブラウザからlocalhost:8000
にアクセスし、LaravelのTOPページが表示されたら成功です$ docker run -t --rm --name laravel -v /`pwd`/app://app -w //app -p 8000:8000 php php artisan serve --host=0.0.0.0コマンドオプションを見てみます
このコマンドでやりたいことは、ホストとコンテナのポートを同期させた状態でLaravelを起動することです
-t、--rm、-v、-w
省略
-p
ポートフォワードの指定です、コンテナのポートとホストのポートを同期できます
--name
コンテナ名の指定です
php
イメージの指定です
php artisan serve --host=0.0.0.0
コンテナで実行するコマンドですLaravelを立ちあげることが出来たら、Ctrl + Cでコンテナを停止させ、ソースの編集します
コンテナを停止した場合でもコンテナは動き続け、マウントとポートフォワードは有効なままです
Controller作成
$ docker run -it --rm -v /`pwd`/app://app -w //app php php artisan make:controller TmpControllerルーティングを定義します
work/app/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('/tmp','TmpController@index');Controllerを編集します
work/app/app/Http/Controllers/TmpController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class TmpController extends Controller { public function index() { return "Hello World"; } }ブラウザから
localhost:8000/tmp
にアクセスし、Hello World
が表示されれば成功です掃除
コンテナが残ったままなので、コンテナの削除を行います
docker ps -aq | xargs docker stop | xargs docker rm
docker ps -aq
すべてコンテナのIDを表示します、--allと--quietの合わせ技ですね
docker stop
標準入力、または引数に指定されたコンテナを停止します
docker rm
標準入力、または引数に指定されたコンテナを削除しますイメージの削除を行います
docker rmi composer最後に
開発環境でのみDockerを使用し、複数の環境を整えた上でSCMを利用した開発を行うなど
Dockerの使い方はいろいろとあると思いますまたDockerのメリットについて、まだまだかけていない部分がありますので
気になった人は是非調べてみてください
- 投稿日:2019-07-30T19:00:49+09:00
Docker + Laravel 学習メモ
はじめに
アプリケーションを開発していく上で、開発環境のWindowsと本番環境のLinuxで差分が出てしまうのを
解決したかったので、Dockerを実際に使ってみましたそれに伴いDockerの概要や使ってみた感想などをまとめてみました
今回使用するリポジトリです
Dockerについて
まず、Dockerとは仮想環境を提供するソフトウェアの事を指します
コンテナは隔離されたOSを持ち、その上でアプリケーションを稼働させることが出来ます
そしてアプリケーションを依存対象と共にカプセル化することが出来ますまたホストOSとリソースを共有出来ることが特徴です
Dockerの大まかな概要は下記を参照してください
Dockerのメリット
Dockerを利用する上での利点についてです
- フレームワークやミドルウェアを自分で構築する必要がない
例えばLaravelを利用した開発を行う場合に、ホストOSにPHPをインストールしなくても
Bitnamiが提供するLaravelのイメージがDocker Hubと呼ばれるリポジトリに配布されているため
簡単に環境を構築できますまた新しいフレームワークや技術が登場しても、Docker Hubにイメージが配布されていれば、自分で環境構築をする必要はありません
- 複数の開発環境の統一できる
DockerfileにOSやパッケージのバージョンを指定することが出来るため
開発環境ではUbuntu
、RHEL
などのOSやRuby
、Nodejs
、PHP
、Go
などの言語のバージョンを統一できますまた
apt
、pip
などのパッケージマネージャで管理されていないライブラリをmsiをでいちいちインストールする必要もありません僕の認識ではseleniumは、ChromeDriverを手でインストールする必要がありますが
コンテナの場合、その作業は必要なく、ホストの\\Program Files
や/opt
、/var
などの汚染を気にすることもありません
- 開発環境と本番環境の差分を埋めることが出来る
アプリケーションやミドルウェアはDocker Engine上で稼働するため
開発環境、本番環境のホストOS上でDocker Engineプロセスさえ起動していれば、アプリケーションは差分なく稼働することが出来ます
- VMと比べて早い
リンクを参照すると早いかもしれません
ゲストOSがない分、コンテナの起動が早くキャッシュを利用したコンテナの再ビルドはとても高速です
vagrant up
に比べて体感速度レベルで起動速度が違いますDockerのデメリット
Dockerのデメリットとして
- セキュリティが弱い
- 開発中なので、バグを踏む可能性がある
- 依然として、VMに依存しているのでオーバヘッドなどで恩恵を100%受けることが出来ない
が挙げられます、これについては現在調査中です
Dockerを理解する
基本的なDockerの操作についてです
まずDockerをホストにインストールする必要があります
Dockerのインストールについては、下記のリンクを参照してくださいインストールが終わったところで、簡単にコンテナでコマンドを実行する流れを紹介します
例えばCent OSコンテナでcat /etc/system-release
コマンドを実行する場合は下記の手順を踏むことで処理を行えます
docker pull centos
コマンドで、コンテナのひな形となるイメージファイルを取得するdocker run --name mycontainer centos
コマンドで、イメージからコンテナを生成、起動する- コンテナ起動後、
cat /etc/system-release
コマンドで実行するexit
コマンドでコンテナから抜ける
CentOS Linux release 7.6.1810 (Core)
が表示されれば処理成功です、バージョンは読み替えて下さい補足ですが、docker runの引数に指定されたイメージがローカル環境に存在しない場合、Docker Hubから取得できるため、上記の作業はワンライナーで行えます
docker run -it --rm centos cat /etc/system-release
基本的な操作を理解したうえで、サブコマンドやDockerアーキテクチャについて確認してください
Docker + Laravel
ここではDockerを使ってLaravelをインストールし、起動してみます
まずは環境情報についてです
PC: Windows 10 Pro
Docker: Docker version 19.03.1
シェル: cmd、git bash
ターミナルは
cmd
とgit bash
を使用しています、>
プロンプトはcmdで$
プロンプトはgit bashですここでは下記の内容を行います
- composerコンテナを作成する
- Laravelをcomposerでインストールする
- Laravelを起動し、ホストOSからLaravelのTOPページが見えることを確認する
- 開発環境でソースを編集し、変更が反映されることを確認する
まずは作業に使うディレクトリとLaravelを配置するディレクトリを作成します
> sh -c "mkdir -p work/app"ディレクトリ階層
> tree /F /A | sh -c "egrep -e '^\s*[\||\\\\|]' -e '^\s+.*'"\---work --- 親ディレクトリ \---app --- Laravel配置ディレクトリ次にDockerfileを作成します
> sh -c "touch work/Dockerfile"Dockerfileの詳細です、composerコンテナとして使用します
FROM php ENV COMPOSER_ALLOW_SUPERUSER 1 RUN apt update && apt install -y wget git unzip RUN EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)" && \ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \ ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" && \ [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] && { \ >&2 echo 'ERROR: Invalid installer signature' && \ rm composer-setup.php && \ exit 1;\ }; \ php composer-setup.php --quiet && \ mv ./composer.phar /usr/local/bin/composer ENTRYPOINT ["composer"]各パラメータについて説明します
Laravelのインストールのため、phpコンテナを使用します
FROM phpコンテナの操作する際のユーザはrootを使用していますが、Laravelをrootで起動すると
警告が出るため、一旦ここではroot起動を許可する設定を入れていますENV COMPOSER_ALLOW_SUPERUSER 1インストーラ取得時の
wget
、Laravelをインストールする際に必要なgit
、unzip
をインストールしますRUN apt update && apt install -y wget git unzipRUN EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)" && \ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \ ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" && \ [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] && { \ >&2 echo 'ERROR: Invalid installer signature' && \ rm composer-setup.php && \ exit 1;\ }; \ php composer-setup.php --quiet && \ mv ./composer.phar /usr/local/bin/composerエントリポイントと呼ばれる起動シェルを指定します
このコンテナはLaravelをインストールするコンテナとして使用するため、値にはcomposer
を使用しますENTRYPOINT ["composer"]コマンド簡易化のため、ターミナルを切り替えます
> sh用意が出来たので、Dockerfileの内容をイメージに固めます
イメージを固める際に-t
オプションをつけてイメージに名前を付けておくと後で楽なのでcomposerタグをつけます$ cd work $ docker build ./ -t composercomposerイメージを使用して、Laravelのインストールを行います、下記コマンドを実行し
Application key set successfully.
が標準出力に表示され、ホストのディレクトリにLaravel一式が作成された場合は、処理成功です$ docker run -it --rm -v /`pwd`/app://app -w //app composer create-project --prefer-dist "laravel/laravel=5.8.*" .コマンドオプションを見てみます
このコマンドでやりたいことは、ホストの./app
ディレクトリとコンテナの/app
ディレクトリをマウントさせた状態でLaravelを/app
にインストールすることです
-i
ホストの入力をコンテナの標準入力に繋げます
-t
コンテナの標準出力をホストの標準出力に繋げます
--rm
コンテナが処理を終了した場合、自動的に停止したコンテナを削除します
-v
マウントオプションです、[ホストのパス]:[コンテナのパス]によって
ホストのファイルとコンテナのファイルの同期を行います
-w
作業ディレクトリの指定です
composer
イメージの指定です
create-project --prefer-dist "laravel/laravel=5.8.*" .
コンテナで実行するコマンドですコマンドが成功したら、Laravelを起動してみます、下記コマンドを実行し
ブラウザからlocalhost:8000
にアクセスし、LaravelのTOPページが表示されたら成功です$ docker run -t --rm --name laravel -v /`pwd`/app://app -w //app -p 8000:8000 php php artisan serve --host=0.0.0.0コマンドオプションを見てみます
このコマンドでやりたいことは、ホストとコンテナのポートを同期させた状態でLaravelを起動することです
-t、--rm、-v、-w
省略
-p
ポートフォワードの指定です、コンテナのポートとホストのポートを同期できます
--name
コンテナ名の指定です
php
イメージの指定です
php artisan serve --host=0.0.0.0
コンテナで実行するコマンドですLaravelを立ちあげることが出来たら、Ctrl + Cでコンテナを停止させ、ソースの編集します
コンテナを停止した場合でもコンテナは動き続け、マウントとポートフォワードは有効なままです
Controller作成
$ docker run -it --rm -v /`pwd`/app://app -w //app php php artisan make:controller TmpControllerルーティングを定義します
work/app/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('/tmp','TmpController@index');Controllerを編集します
work/app/app/Http/Controllers/TmpController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class TmpController extends Controller { public function index() { return "Hello World"; } }ブラウザから
localhost:8000/tmp
にアクセスし、Hello World
が表示されれば成功です掃除
コンテナが残ったままなので、コンテナの削除を行います
$ docker ps -aq | xargs docker stop | xargs docker rm
docker ps -aq
すべてコンテナのIDのみを表示します、--allと--quietの合わせ技ですね
docker stop
標準入力、または引数に指定されたコンテナを停止します
docker rm
標準入力、または引数に指定されたコンテナを削除しますイメージの削除を行います
$ docker rmi composer
最後に
今回はDBも使用しないシンプルなLaravelを構築しました
実際に開発を行うとなるとこれだけではダメなので、それぞれのプロジェクトに合わせたDockerfileやdocker-composer.ymlを作成しましょう
下記Laravelについてのエントリです
Laravelの開発環境をDockerを使って構築する、Dockerを使ってLaravel開発環境構築
開発環境でのみDockerを使用し、複数の環境を整えた上でSCMを利用した開発を行うなど
Dockerの使い方はいろいろとあると思いますまたDockerのメリットについて、まだまだかけていない部分がありますので
気になった人は是非調べてみてください
- 投稿日:2019-07-30T19:00:49+09:00
Docker学習メモ
DockerでLaravelを立ち上げた際の学習メモ
>>> 編集中
はじめに
アプリケーションを開発していく上で、開発環境のWindowsと本番環境のLinuxで差分が出てしまうのを
解決したかったので、Dockerを実際に使ってみましたそれに伴いDockerの概要や使ってみた感想などをまとめてみました
今回使用するリポジトリはここです
Dockerについて
まず、Dockerとは仮想環境を提供するソフトウェアの事を指します
コンテナは隔離されたOSを持ち、その上でアプリケーションを稼働させることが出来ます
そしてアプリケーションを依存対象と共にカプセル化することが出来ますまたホストOSとリソースを共有出来ることが特徴です
Dockerの大まかな概要は下記を参照してください
Dockerのデメリット
Dockerを利用する上での利点についてです
- フレームワークやミドルウェアを自分で構築する必要がない
例えばLaravelを利用した開発を行う場合に、ホストOSにPHPをインストールしなくても
Bitnamiが提供するLaravelのイメージがDocker Hubと呼ばれるリポジトリに配布されているため
簡単に環境を構築できますまた新しいフレームワークや技術が登場しても、Docker Hubにイメージが配布されていれば、自分で環境構築をする必要はありません
- 複数の開発環境の統一できる
DockerfileにOSやパッケージのバージョンを指定することが出来るため
開発環境ではUbuntu
、RHEL
などのOSやRuby
、Nodejs
、PHP
、Go
などの言語のバージョンを統一できますまた
apt
、pip
などのパッケージマネージャで管理されていないライブラリをmsiをでいちいちインストールする必要もありません僕の認識ではseleniumは、ChromeDriverを手でインストールする必要がありますが
コンテナの場合、その作業は必要なく、ホストの\\Program Files
や/opt
、/var
などの汚染を気にすることもありません
- 開発環境と本番環境の差分を埋めることが出来る
アプリケーションやミドルウェアはDocker Engine上で稼働するため
開発環境、本番環境のホストOS上でDocker Engineプロセスさえ起動していれば、アプリケーションは差分なく稼働することが出来ます
- VMと比べて早い
リンクを参照すると早いかもしれません
ゲストOSがない分、コンテナの起動が早くキャッシュを利用したコンテナの再ビルドはとても高速です
vagrant up
に比べて体感速度レベルで起動速度が違いますDockerのデメリット
セキュリティが弱い
開発中なので、バグを踏む可能性がある
依然として、VMに依存しているのでオーバヘッドなどで恩恵を100%受けることが出来ない
Dockerを理解する
基本的なDockerの操作についてです
まずDockerをホストにインストールする必要があります
Dockerのインストールについては、下記のリンクを参照してくださいインストールが終わったところで、簡単にコンテナでコマンドを実行する流れを紹介します
例えばCent OSコンテナでcat /etc/system-release
コマンドを実行する場合は下記の手順を踏むことで処理を行えます
docker pull centos
コマンドで、コンテナのひな形となるイメージファイルを取得するdocker run --name mycontainer centos
コマンドで、イメージからコンテナを生成、起動する- コンテナログイン後、
cat /etc/system-release
コマンドで実行するexit
コマンドでコンテナから抜ける
CentOS Linux release 7.6.1810 (Core)
が表示されれば処理成功です、バージョンは読み替えて下さい補足ですが、docker runの引数に指定されたイメージがローカル環境に存在しない場合、Docker Hubから取得できるため、上記の作業はワンライナーで行えます
docker run -it --rm centos cat /etc/system-release
基本的な操作を理解したうえで、サブコマンドやDockerアーキテクチャについて確認してください
Docker + Laravel
ここではDockerを使ってLaravelをインストールし、起動してみます
ここで掲載されている環境情報についてですが、PCは
Windows 10 Pro
で
ターミナルはcmd
とgit bash
を使用しています、>
プロンプトはcmdで$
プロンプトはgit bashですここでやりたいことは下記です
- composerコンテナを作成する
- Laravelをcomposerでインストールする
- ホストOSからLaravelのTOPページが見えることを確認する
- 開発環境でソースを編集し、変更が反映されることを確認する
まずは作業に使うディレクトリとLaravelを配置するディレクトリを作成します
> sh -c "mkdir -p work/app"ディレクトリ階層
> tree /F /A | sh -c "egrep '^\s*[\||\\\\|+]'"\---work --- 親ディレクトリ \---app --- Laravel配置ディレクトリ次にDockerfileを作成します
> sh -c "touch work/Dockerfile"Dockerfileの詳細です、このDockerfileはcomposerコンテナとして使用します
FROM php ENV COMPOSER_ALLOW_SUPERUSER 1 RUN apt update && apt install -y wget git unzip RUN EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)" && \ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \ ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" && \ [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] && { \ >&2 echo 'ERROR: Invalid installer signature' && \ rm composer-setup.php && \ exit 1;\ }; \ php composer-setup.php --quiet && \ mv ./composer.phar /usr/local/bin/composer ENTRYPOINT ["composer"]各パラメータについて説明します
Laravelのインストールのため、phpコンテナを使用します
FROM phpコンテナの操作する際のユーザはrootを使用していますが、Laravelをrootで起動すると
警告が出るため、一旦ここではroot起動を許可する設定を入れていますENV COMPOSER_ALLOW_SUPERUSER 1インストーラ取得時の
wget
、Laravelをインストールする際に必要なgit
、unzip
をインストールしますRUN apt update && apt install -y wget git unzipRUN EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)" && \ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \ ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")" && \ [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] && { \ >&2 echo 'ERROR: Invalid installer signature' && \ rm composer-setup.php && \ exit 1;\ }; \ php composer-setup.php --quiet && \ mv ./composer.phar /usr/local/bin/composerエントリポイントと呼ばれる起動シェルを指定します
このコンテナはLaravelをインストールするコンテナとして使用するため、値にはcomposer
を使用しますENTRYPOINT ["composer"]コマンド簡易化のため、ターミナルを切り替えます
> sh用意が出来たので、Dockerfileの内容をイメージに固めます
イメージを固める際に-t
オプションをつけてイメージに名前を付けておくと後で楽なので
composerタグをつけます$ cd work $ docker build ./ -t composer先ほどビルドしたイメージを使用して、Laravelのインストールを行います、下記コマンドを実行し
Application key set successfully.
が標準出力に表示され、ホストのディレクトリにLaravel一式が作成された場合は、処理成功です$ docker run -it --rm -v /`pwd`/app://app -w //app composer create-project --prefer-dist "laravel/laravel=5.8.*" .コマンドオプションを見てみます
このコマンドでやりたいことは、ホストの./appディレクトリとコンテナの/appディレクトリをマウントさせた状態でLaravelを/appにインストールすることです
-i
ホストの入力をコンテナの標準入力に繋げます
-t
コンテナの標準出力をホストの標準出力に繋げます
--rm
コンテナが処理を終了した場合、自動的に停止したコンテナを削除します
-v
マウントオプションです、[ホストのパス]:[コンテナのパス]によって
ホストのファイルとコンテナのファイルの同期を行います
-w
作業ディレクトリの指定です
composer
イメージの指定です
create-project --prefer-dist "laravel/laravel=5.8.*" .
コンテナで実行するコマンドですコマンドが成功したら、Laravelを起動してみます、下記コマンドを実行し
ブラウザからlocalhost:8000
にアクセスし、LaravelのTOPページが表示されたら成功です$ docker run -t --rm --name laravel -v /`pwd`/app://app -w //app -p 8000:8000 php php artisan serve --host=0.0.0.0コマンドオプションを見てみます
このコマンドでやりたいことは、ホストの8000ポートとコンテナの8000を同期させた状態で
Laravelを起動することです
-t、--rm、-v、-w
省略
-p
ポートフォワードの指定です、コンテナのポートとホストのポートを同期できます
--name
コンテナ名の指定です
php
イメージの指定です
php artisan serve --host=0.0.0.0
コンテナで実行するコマンドですLaravelを立ちあげることが出来たら、Ctrl + Cでコンテナを停止させ、ソースの編集します
Controller作成
$ docker run -it --rm -v /`pwd`/app://app -w //app php php artisan make:controller TmpControllerルーティングを定義します
work/app/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('/tmp','TmpController@index');Controllerを編集します
work/app/app/Http/Controllers/TmpController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class TmpController extends Controller { public function index() { return "Hello World"; } }ブラウザから
localhost:8000/tmp
にアクセスし、Hello World
が表示されれば成功ですDockerを本番環境で稼働させ、kubernetesと併用してオートスケーリングなどが可能ですが
開発環境でのみDockerを使用し、Gitでソースを管理し、本番環境とDockerの環境を揃えるなど
使い方はいろいろとあると思いますまたDockerのメリットについて、まだまだかけていない部分がありますので
気になった人は是非調べてみてください
- 投稿日:2019-07-30T17:13:44+09:00
[Laravel 5.8] report()にコンテキストを渡せるようにする
report()? コンテキスト?
Laravelが用意しているreportヘルパは、例外をロギングしてくれます。
report(new \Exception('sample exception'));ログファイル[2019-07-30 16:15:55] local.ERROR: sample exception {"exception":"[object] (Exception(code: 0): sample exception at /var/www/routes/web.php:29) [stacktrace] ...ログファイルにある
{"exception":"[object] ...
がコンテキストで、ロギングする情報のことです。デフォルトでは例外情報とログインしていればそのユーザーIDになります。以下はデフォルトLaravelの実装です。vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php/** * Report or log an exception. * * @param \Exception $e * @return mixed * * @throws \Exception */ public function report(Exception $e) { //略 $logger->error( $e->getMessage(), array_merge($this->context(), ['exception' => $e] // ここでコンテキストをロギング )); } /** * Get the default context variables for logging. * * @return array */ protected function context() { try { return array_filter([ 'userId' => Auth::id(), // 'email' => optional(Auth::user())->email, ]); } catch (Throwable $e) { return []; } }上記のcontextメソッドをオーバーライドすればコンテキストを自由に編集できますが、全てのreportヘルパに影響するので、reportするときにコンテキストを渡せるようにしました。
ただ、本当は以下のようにしたかったのですが
こうしたいreport($e); // デフォルトのコンテキストでロギング report($e, ['hoge' => 'fuga']); // コンテキストに追加してロギング後述の理由で難しそうだったので以下で妥協しました。
こうなったuse Illuminate\Contracts\Debug\ExceptionHandler; report($e); // デフォルトのコンテキストでロギング app(ExceptionHandler::class)->report($e, ['hoge' => 'fuga']); // コンテキストに追加してロギング実装
app/Exceptions/Handler.php
でreportメソッドをオーバーライドします。app/Exceptions/Handler.php/** * Report or log an exception. * * @param \Exception $e * @return mixed * * @throws \Exception */ public function report(Exception $e, array $context = []) // $contextを引数に追加 { if ($this->shouldntReport($e)) { return; } if (is_callable($reportCallable = [$e, 'report'])) { return $this->container->call($reportCallable); } try { $logger = $this->container->make(LoggerInterface::class); } catch (Exception $ex) { throw $e; } $logger->error( $e->getMessage(), array_merge($this->context(), $context, ['exception' => $e] // $contextをマージするようにする )); }使用するときは、サービスコンテナからExceptionHandlerを受け取りreportしてください。
use Illuminate\Contracts\Debug\ExceptionHandler; app(ExceptionHandler::class)->report(new \Exception('sample exception'), ['hoge' => 'fuga']);ログファイル[2019-07-30 16:34:17] local.ERROR: sample exception {"hoge":"fuga","exception":"[object] (Exception(code: 0): sample exception at /var/www/routes/web.php:25) [stacktrace] ...reportヘルパにコンテキストを渡せるようにできないか?
上記はreportヘルパを通さず、直接ExceptionHandlerのreportメソッドを呼んでいます。reportヘルパを使って
report($e, $context)
とするには、reportヘルパをオーバーライドする必要があります。
reportヘルパの実装は以下になっています。vendor/laravel/framework/src/Illuminate/Foundation/helpers.phpif (! function_exists('report')) { /** * Report an exception. * * @param \Throwable $exception * @return void */ function report($exception) { if ($exception instanceof Throwable && ! $exception instanceof Exception) { $exception = new FatalThrowableError($exception); } app(ExceptionHandler::class)->report($exception); } }ヘルパのオーバーライドは、
https://qiita.com/kd9951/items/46ef3559009ee575ea7d
の記事が詳しいです。ただヘルパの引数を追加したいので、この記事のベストな方法(サービスコンテナで入れ替える)は使えません。以下のような
app/helpers.php
を作り、vendor/laravel/framework/src/Illuminate/Foundation/helpers.php
よりも早くapp/helpers.php
を読み込むようにすればオーバーライドできるようですが、良さそうな方法がないので辞めました。app/helpers.php<?php if (! function_exists('report')) { /** * Report an exception. * * @param \Throwable $exception * @param array $context * @return void */ function report($exception, $context = []) // 引数に$context追加 { if ($exception instanceof Throwable && ! $exception instanceof Exception) { $exception = new FatalThrowableError($exception); } app(ExceptionHandler::class)->report($exception, $context); // $contextを渡す } }
- 投稿日:2019-07-30T13:17:47+09:00
Docker前提のLaravelログ設定
概要
Laravelでのログ設定についてまとめした。
- この記事のゴール
- 任意のログを stdout で書き出す
最終的にDockerコンテナのログを書き出すことを前提にしてるため、
stdout
のみに焦点を当てています。Laravelには上記のゴール以外にも、ログをファイルに書き出したり、Slackに通知するよう設定できます。
詳しく知りたい方は以下のリンクをご覧ください。
※監視ド素人が書いたものですので、間違い等ありましたらご指摘いただけると幸いです!
目次
- ログ設定
- ログレベル
- なにをログとして書き出すか
1. ログ設定
設定ファイル
Laraveのログシステム設定には、
config/logging.php
を使用します(デフォルトで存在します)。
基本的にこのファイルしか触りません。ファイルにはチャンネルという単位で設定が記述されており、
デフォルトではstack
チャンネルが使用されます。以下は設定例です。
// logging.php <?php use Monolog\\Handler\\StreamHandler; return [ // デフォルトでstackチャンネルを使用 'default' => env('LOG_CHANNEL', 'stack'), 'channels' => [ 'stack' => [ 'driver' => 'stack', 'channels' => ['stdout'], // stdoutチャンネルを使用 ], 'stdout' => [ 'driver' => 'monolog', 'handler' => StreamHandler::class, 'with' => [ 'stream' => 'php://stdout', ], 'level' => 'debug', ], 'single' => [ 'driver' => 'single', 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', ], 'daily' => [ 'driver' => 'daily', 'path' => storage_path('logs/laravel.log'), 'level' => 'debug', 'days' => 7, ], 'slack' => [ 'driver' => 'slack', 'url' => env('LOG_SLACK_WEBHOOK_URL'), 'username' => 'Laravel Log', 'emoji' => ':boom:', 'level' => 'critical', ], 'stderr' => [ 'driver' => 'monolog', 'handler' => StreamHandler::class, 'with' => [ 'stream' => 'php://stderr', ], ], 'syslog' => [ 'driver' => 'syslog', 'level' => 'debug', ], 'errorlog' => [ 'driver' => 'errorlog', 'level' => 'debug', ], ]用途に合わせてチャンネルを使っていくのですが、
今回はstdout
のみなので、設定は上記のままでOKです。2. ログレベル
ログには重要度などで分類されたレベルがあります。
- emergency
- alert
- critical
- error
- warning
- notice
- info
- debug
上から高→低レベルです。
各チャンネルでは、
level
オプションで指定されたレベル以上のログが書き出されます。'stdout' => [ 'driver' => 'monolog', 'handler' => StreamHandler::class, 'with' => [ 'stream' => 'php://stdout', ], // debugは最低レベルなので全レベルのログを書き出す 'level' => 'debug', ],
logging.php
での設定は以上です。あとは各処理にログを仕込んでいきます。
// 本家HPより引用 <?php namespace App\Http\Controllers; use App\User; use Illuminate\Support\Facades\Log; use App\Http\Controllers\Controller; class UserController extends Controller { /** * 指定したユーザーのプロファイルを表示 * * @param int $id * @return Response */ public function showProfile($id) { Log::info('Showing user profile for user: '.$id); return view('user.profile', ['user' => User::findOrFail($id)]); } }// 各レベルの書き出し方 Log::emergency($message); Log::alert($message); Log::critical($message); Log::error($message); Log::warning($message); Log::notice($message); Log::info($message); Log::debug($message);※引用元:ログ 5.7 Laravel
3. なにをログとして書き出すか
ログを残す目的は大きく分けて2つ。
- 障害発生時、原因究明の手がかりとする
- 改善に役立てる
主にひとつ目の目的が大きいです。
どこで問題が起きたか、なにが問題となったか等を知るため、各処理にたいしてログを残すことが必要です。ただし、すべての処理に対してログを差し込むのは大変ですし、すんごい小さな処理にまでログを残してると、本当に必要なログが埋もれてしまいます。
まずはリクエストごと、コントローラの各処理を1単位として、
あとは必要に応じてログを残すようにします。どんなログを残すか
ここはログ設計指針 - Qiitaから引用させていただきます。
- INFOリクエスト開始時 - 処理概要、実行クラス名、メソッド名
- INFO途中経過 - 実行条件、処理対象オブジェクトのキーとなる値等(customer_id, order_id 等)
- INFO処理終了時 - 実行結果(OK/NG 等)、リダイレクト先
- WARNイベント発生時 - 画面に表示したエラーメッセージ等
- ERROR例外発生時 - 例外クラス、例外メッセージ
- INFOその他、必要に応じて
おわりに
Laravelのログ設定は
logging.php
のみで完結してて取っつきやすく、デフォルトでslack通知にも対応してたり(使わないけど)パワフルで良いですね。次はDockerでのログの扱いについてまとめます。
参考
- 投稿日:2019-07-30T11:16:24+09:00
Laravel+MySQL5.7+nginxをDockerで構築(laravel.mix、docker-syncで速度改善)
未経験エンジニアのsongxunといいます。
初めての投稿です。間違い等あればご指摘いただけると幸いです。備忘録として、DockerでLaravelを環境構築、brouser-sync、docker-syncの導入手順をまとめます。
環境はDocker for Mac。
速度がめちゃくちゃ遅い。さらにbrowser-sync
を使うと、体感5s~10sくらいはページリロードにかかってるかもしれません。結果的に
docker-sync
を導入して、以下のように改善しました。
- ページのリロードがbrowser-sync込みでも体感1s以内
- コンテナ環境内でのコマンドも爆速に
まずはLaravelをDockerで構築する手順からまとめていきます。
Laravel+MySQL5.7+nginxをDockerで構築
ディレクトリ構成、
docker-compose.yml
、Dockerfile
はこちらを参考にさせていただきました。作成し終わったら、以下のコマンドを実行します。# コンテナをバックグラウンドで起動 $ docker-compose up -d # 環境内に入る docker-compose exec app bash # composerコマンドでLaravelプロジェクトを作成 composer create-project --prefer-dist laravel/laravel [プロジェクト名]プロジェクト内の
.env
ファイルを以下のように編集します。.envDB_CONNECTION=mysql DB_HOST=mysql DB_PORT=3306 DB_DATABASE=sample DB_USERNAME=user DB_PASSWORD=password# コンテナを再起動 $ docker-compose restart # appコンテナ内に入る $ docker-compose exec app bash # ここでartisanコマンドを実行する $ php artisan migrate# mysqlコンテナ内に入る場合は $ docker-compose exec mysql bash # DBに接続 mysql -u root -p # DBを選択 > use sample;ブラウザにアクセス
http://localhost:8000/個人的に
docker-compose
と入力するのが面倒なのでエイリアスを設定しています。~/.bashrcalias dkcp='docker-compose'# sourceコマンドで設定を反映 $ source ~/.bashrc # 以下のように入力できるようになります $ dkcp up -dlaravel mix
browser-sync
を使うために、package.json
を以下のようにします。package.json"devDependencies": { "axios": "^0.18", "bootstrap": "^4.1.0", "browser-sync": "^2.26.3", "browser-sync-webpack-plugin": "2.0.1", "cross-env": "^5.1", "jquery": "^3.2", "laravel-mix": "^4.0.7", "lodash": "^4.17.5", "popper.js": "^1.12", "resolve-url-loader": "^2.3.1", "sass": "^1.15.2", "sass-loader": "^7.1.0", "vue": "^2.5.17", "vue-template-compiler": "^2.6.10" }$ cd [package.jsonがあるディレクトリ] ############## # npmを使う場合 ############## $ npm install ############## # yarnを使う場合 ############## $ yarn
webpack.mix.js
を編集する。webpack.mix.jsconst mix = require('laravel-mix') mix.browserSync('localhost:8000') .js('resources/js/app.js', 'public/js') .sass('resources/sass/app.scss', 'public/css') .version()############## # npmを使う場合 ############## # ビルド $ npm run dev # 監視する $ npm run watch # 以下のエラーが出た場合は参考にあるURLを見てください # The Mix manifest does not exist when it does exist ############## # yarnを使う場合 ############## # ビルド $ yarn run dev # 監視する $ yarn run watchdocker-syncを使って、docker for Macの速度を改善する
事前準備
$ gem install docker-sync $ brew install fswatch $ brew install unison
docker-compose-dev.yml
,docker-sync.yml
を追加。コチラを参考にさせていただきました。ymlのバージョンを変更する必要があるかもしれません。# docker-syncで同期開始 $ docker-sync start # コンテナを起動 $ docker-compose -f docker-compose.yml -f docker-compose-dev.yml up -dPermission denidがブラウザに表示される場合
ブラウザを確認しながら、適宜
storage
内のパーミッションを変更する。$ chmod 777 hogehogefile not foundとブラウザに表示される場合
ドキュメントルートを変更すると直るかもしれません。
nginxの設定ファイルのdefault.conf
内にあるrootを変更する。参考
- 投稿日:2019-07-30T11:16:24+09:00
Laravel+MySQL5.7+nginxをDockerで構築(laravel.mix、docker-sync)
未経験エンジニアのsongxunといいます。
初めての投稿です。間違い等あればご指摘いただけると幸いです。備忘録として、DockerでLaravelを環境構築、brouser-sync、docker-syncの導入手順をまとめます。
環境はDocker for Mac。
速度がめちゃくちゃ遅い。さらにbrowser-sync
を使うと、体感5s~10sくらいはページリロードにかかってるかもしれません。結果的に
docker-sync
を導入して、以下のように改善しました。
- ページのリロードがbrowser-sync込みでも体感1s以内
- コンテナ環境内でのコマンドも爆速に
まずはLaravelをDockerで構築する手順からまとめていきます。
Laravel+MySQL5.7+nginxをDockerで構築
ディレクトリ構成、
docker-compose.yml
、Dockerfile
はこちらを参考にさせていただきました。作成し終わったら、以下のコマンドを実行します。# コンテナをバックグラウンドで起動 $ docker-compose up -d # 環境内に入る docker-compose exec app bash # composerコマンドでLaravelプロジェクトを作成 composer create-project --prefer-dist laravel/laravel [プロジェクト名]プロジェクト内の
.env
ファイルを以下のように編集します。.envDB_CONNECTION=mysql DB_HOST=mysql DB_PORT=3306 DB_DATABASE=sample DB_USERNAME=user DB_PASSWORD=password# コンテナを再起動 $ docker-compose restart # appコンテナ内に入る $ docker-compose exec app bash # ここでartisanコマンドを実行する $ php artisan migrate# mysqlコンテナ内に入る場合は $ docker-compose exec mysql bash # DBに接続 mysql -u root -p # DBを選択 > use sample;ブラウザにアクセス
http://localhost:8000/個人的に
docker-compose
と入力するのが面倒なのでエイリアスを設定しています。~/.bashrcalias dkcp='docker-compose'# sourceコマンドで設定を反映 $ source ~/.bashrc # 以下のように入力できるようになります $ dkcp up -dlaravel mix
browser-sync
を使うために、package.json
を以下のようにします。package.json"devDependencies": { "axios": "^0.18", "bootstrap": "^4.1.0", "browser-sync": "^2.26.3", "browser-sync-webpack-plugin": "2.0.1", "cross-env": "^5.1", "jquery": "^3.2", "laravel-mix": "^4.0.7", "lodash": "^4.17.5", "popper.js": "^1.12", "resolve-url-loader": "^2.3.1", "sass": "^1.15.2", "sass-loader": "^7.1.0", "vue": "^2.5.17", "vue-template-compiler": "^2.6.10" }$ cd [package.jsonがあるディレクトリ] ############## # npmを使う場合 ############## $ npm install ############## # yarnを使う場合 ############## $ yarn
webpack.mix.js
を編集する。webpack.mix.jsconst mix = require('laravel-mix') mix.browserSync('localhost:8000') .js('resources/js/app.js', 'public/js') .sass('resources/sass/app.scss', 'public/css') .version()############## # npmを使う場合 ############## # ビルド $ npm run dev # 監視する $ npm run watch # 以下のエラーが出た場合は参考にあるURLを見てください # The Mix manifest does not exist when it does exist ############## # yarnを使う場合 ############## # ビルド $ yarn run dev # 監視する $ yarn run watchdocker-syncを使って、docker for Macの速度を改善する
事前準備
$ gem install docker-sync $ brew install fswatch $ brew install unison
docker-compose-dev.yml
,docker-sync.yml
を追加。コチラを参考にさせていただきました。ymlのバージョンを変更する必要があるかもしれません。# docker-syncで同期開始 $ docker-sync start # コンテナを起動 $ docker-compose -f docker-compose.yml -f docker-compose-dev.yml up -dPermission denidがブラウザに表示される場合
ブラウザを確認しながら、適宜
storage
内のパーミッションを変更する。$ chmod 777 hogehogefile not foundとブラウザに表示される場合
ドキュメントルートを変更すると直るかもしれません。
nginxの設定ファイルのdefault.conf
内にあるrootを変更する。参考
- 投稿日:2019-07-30T11:16:24+09:00
Laravel+MySQL5.7+nginxをDockerで構築(browser-sync、docker-sync)
未経験エンジニアのsongxunといいます。
初めての投稿です。間違い等あればご指摘いただけると幸いです。備忘録として、DockerでLaravelを環境構築、brouser-sync、docker-syncの導入手順をまとめます。
- Docker for Macは速度が遅い。
browser-sync
を使うと、体感5s~10sくらいはページリロードにかかる。結果的に
docker-sync
を導入して、以下のように改善しました。
- ページのリロードがbrowser-sync込みでも体感1s以内
- コンテナ環境内でのコマンドも爆速に
まずはLaravelをDockerで構築する手順からまとめていきます。
Laravel+MySQL5.7+nginxをDockerで構築
ディレクトリ構成、
docker-compose.yml
、Dockerfile
は以下を参考にしました。
Laravelの環境をDockerで構築するチュートリアルディレクトリの構成
$ tree -L 3 . ├── docker │ ├── php │ │ └── Dockerfile │ └── web │ └── default.conf ├── docker-compose.ymlDockerfileFROM php:7.2-fpm # install composer RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer RUN apt-get update \ && apt-get install -y \ git \ zip \ unzip \ vim RUN apt-get update \ && apt-get install -y libpq-dev \ && docker-php-ext-install pdo_mysql pdo_pgsql WORKDIR /var/www/htmldocker-compose.ymlversion: '3' services: web: image: nginx:1.15.6 ports: - "8000:80" depends_on: - app volumes: - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf - .:/var/www/html app: build: ./docker/php depends_on: - mysql mysql: image: mysql:5.7 environment: MYSQL_DATABASE: sample MYSQL_USER: user MYSQL_PASSWORD: password MYSQL_ROOT_PASSWORD: password ports: - "3306:3306" volumes: - mysql-data:/var/lib/mysql volumes: mysql-data:次に、以下のコマンドを実行します。
# コンテナをバックグラウンドで起動 $ docker-compose up -d # 環境内に入る docker-compose exec app bash # composerコマンドでLaravelプロジェクトを作成 composer create-project --prefer-dist laravel/laravel [プロジェクト名]nginxの設定ファイルを編集します。
default.confserver { listen 80; root /var/www/html/[プロジェクト名]/public; index index.php index.html index.htm; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass app:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; } }プロジェクト内にある
.env
を編集します。.envDB_CONNECTION=mysql DB_HOST=mysql DB_PORT=3306 DB_DATABASE=sample DB_USERNAME=user DB_PASSWORD=password# コンテナを再起動 $ docker-compose restart # appコンテナ内に入る $ docker-compose exec app bash # ここでartisanコマンドを実行する $ php artisan migrate# mysqlコンテナ内に入る場合は $ docker-compose exec mysql bash # DBに接続 mysql -u root -p # DBを選択 > use sample;以下のURLからアプリをブラウザに確認できる
http://localhost:8000/個人的に
docker-compose
と入力するのが面倒なのでエイリアスを設定しています。~/.bashrcalias dkcp='docker-compose'# sourceコマンドで設定を反映 $ source ~/.bashrc # 以下のように入力できるようになります $ dkcp up -dlaravel mix
browser-sync
を使うために、package.json
を以下のようにします。package.json"devDependencies": { "axios": "^0.18", "bootstrap": "^4.1.0", "browser-sync": "^2.26.3", # 追記(コメントは削除する) "browser-sync-webpack-plugin": "2.0.1", # 追記(コメントは削除する) "cross-env": "^5.1", "jquery": "^3.2", "laravel-mix": "^4.0.7", "lodash": "^4.17.5", "popper.js": "^1.12", "resolve-url-loader": "^2.3.1", "sass": "^1.15.2", "sass-loader": "^7.1.0", "vue": "^2.5.17", "vue-template-compiler": "^2.6.10" }$ cd [package.jsonがあるディレクトリ] ############## # npmを使う場合 ############## $ npm install ############## # yarnを使う場合 ############## $ yarn
webpack.mix.js
を編集。webpack.mix.jsconst mix = require('laravel-mix') mix.browserSync('localhost:8000') .js('resources/js/app.js', 'public/js') .sass('resources/sass/app.scss', 'public/css') .version()############## # npmを使う場合 ############## # ビルド $ npm run dev # 監視する $ npm run watch # 以下のエラーが出た場合は参考にあるURLを見てください # The Mix manifest does not exist when it does exist ############## # yarnを使う場合 ############## # ビルド $ yarn run dev # 監視する $ yarn run watchdocker-syncを使って、docker for Macの速度を改善する
事前準備
$ gem install docker-sync $ brew install fswatch $ brew install unison
docker-compose-dev.yml
,docker-sync.yml
を新規に作成する。
docker-sync ドキュメントディレクトリの構成
$ tree -L 3 . ├── docker │ ├── php │ │ └── Dockerfile │ └── web │ └── default.conf ├── docker-compose-dev.yml ├── docker-compose.yml ├── docker-sync.ymldocker-compose-dem.ymlversion: "3" services: app: volumes: - sync-volume:/var/www/html:nocopy # nocopy is important volumes: sync-volume: external: truedocker-sync.ymlversion: '2' syncs: sync-volume: src: '.'# docker-syncで同期開始 $ docker-sync start # コンテナを起動 $ docker-compose -f docker-compose.yml -f docker-compose-dev.yml up -dブラウザで確認
http://localhost:8000/
Permission denidがブラウザに表示される場合
ブラウザを確認しながら、適宜
storage
内のパーミッションを変更する。$ chmod 777 hogehoge
file not foundとブラウザに表示される場合
ドキュメントルートを変更すると直るかもしれません。
nginxの設定ファイルのdefault.conf
内にあるrootを変更する。参考
- 投稿日:2019-07-30T08:05:56+09:00
自分の勉強記録を分析しよう!~新米エンジニアの個人開発~
自分の勉強記録を分析しよう!~新米エンジニアの個人開発~
プログラマー歴1年目のじょーだいです。
プログラマーになって一年、そろそろ新しいことを学んでみたかったので、使ったことのない技術を使用して簡単なwebアプリケーションを開発してみました。
どんなアプリ?
僕は勉強したことをTwitterでつぶやいています。
他にも多くの方々が自分の勉強したことをつぶやいているのをよく見かけます。
せっかく勉強しているならその記録をしっかり残したい。。。
そこで今回は自分の勉強を記録しておくことのできる「Stacker」というアプリを開発しました。
使用している技術は?
- Laravel
- Vue.js
- Chart.js
- MySQL
- Docker
- XSERVER
- Git
各画面の説明
ダッシュボード
この画面の作成が一番時間をとられました。
上部に1週間のグラフ、下部に日毎の入力したデータが表示されます。
また右上のボタンによって、1週間のグラフを総合計のグラフに切り替えることでカテゴリーごとの合計時間を知ることができます。
勉強している日、してない日がすぐわかるので結構気に入ってます。
カテゴリ―毎の詳細
ダッシュボードの左側のカテゴリー一覧からカテゴリ―を選択すると画像のような画面が開きます。
今まで入力したコメントが一覧表示されるので、どんなことを勉強してきたのか一目瞭然です。
カテゴリ―詳細ページは他のユーザーが覗くこともできます。
知らない語句や勉強の順序、気になるエンジニアがどんなことを学んでいるのかを知ることができます。
ホーム
各ユーザーの投稿が一覧表示されています。
とても簡易的なSNSのような感じです。
フォロー機能等は実装していませんが、他のユーザーの勉強量を知ることで、モチベーションを上げることができます。
現在会社の後輩とこのアプリを使用しているのですが、とても会話が盛り上がります。
特に相手が何を勉強しているのかがわかるので、気になったことをすぐに聞けるし、話のきっかけづくりにもなります。
感想
一応完成はしたものの、まだまだ実装したい機能が盛りだくさんです。
例えば
フォロー機能
、円グラフでの分析
、カテゴリ―毎の表示順序、色の切り替え
など、他にも細かいところでまだまだたくさんあります。他にもリファクタリングやテストコードの作成などすることは盛りだくさん。
これからも勉強を記録していくためにこのアプリを使用し、改善を続けていきます。
自分自身が毎日使用していくので、改善、メンテナンスを無理なく続けていくことができると思います。
個人開発でも作りっぱなしではなく、しっかりと運用していくので、よければ皆様も使ってみてください。
一言
コードが汚すぎる。リーダブルコード読んだはずなんだけどな~