20190730のlaravelに関する記事は11件です。

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 yes

vagrantならすでにリモート側に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最高!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

「ようこそ・・・『テストの世界』へ・・・」

はじめに

本記事では、テストをまだ書いたことのない人向けに

「今日からテストを書いてみようかな」

と思ってもらえるよう、チュートリアル風に簡単なテストの流れを説明します。

題材はLaravelですが、他のフレームワークでも同じようなことはできると思います。

前提

本記事の対象者

  • Laravel初心者で、
    • テストをまだ書いたことの無い人
    • テストで何ができるのか知らない人
    • テストに興味はあるが忙しくてどう書けば良いのかまだ調べられていない人

本記事で取り扱うこと

  • ごく簡単なHTTPリクエストのテストの書き方

本記事で取り扱わないこと

  • テストの全般的な話(利点、注意点など)
  • テストケースの作り方
  • CIツールによるテスト自動化

環境

  • Laravel 5.8.x

簡単な画面(HTTPレスポンス)のテスト

まずは、Laravelを触ったことのある人なら一度は見たことのある?Welcome画面をテストしてみます。

これが正常に表示されることを、目視ではなくテストコードで確認してみましょう。

localhost_8080_.png

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.php
Route::get('/', function () {
    return view('welcome');
});

welcomeというビューは、具体的にはresources/views/welcome.blade.phpというビューのテンプレートです。

このresources/views/welcome.blade.phpこそがあのWelcome画面なので、このテンプレートが使われているかどうかをテストで確認してみます。

tests/Feature/ExampleTest.phpに以下のコードを追加します。

tests/Feature/ExampleTest.php
public 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.php
public 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画面にユーザー登録画面とログイン画面へのリンクが追加されました。

localhost_8080_2.png

以下、テストではなく人力でユーザー登録画面にアクセスし、ユーザー登録を行なっています。

localhost_8080_register.png

ユーザー登録が完了すると、以下のホーム画面へ遷移します。なお、ログイン画面からログインした場合も、このホーム画面へ遷移します。

localhost_8080_home.png

ホーム画面は、ログイン中の時のみ表示されます。

ログインしていない状態で直接/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.php
public 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テーブルからid1であるユーザーを取ってきています。

改めて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にダミーデータが残ることなく、何度でもテストを実行できます。

最後に

以上で、本記事のテスト体験ツアーは終了です。

テストでどのようなことができるか、イメージはつかめたでしょうか。

本記事をきっかけに、テストを書き始めていただければ幸いです。

「納期は守る」「品質も確保する」
「両方」やらなくちゃあならないってのが「エンジニア」のつらいところだな

参考


  1. 正確には\Illuminate\Foundation\Testing\TestResponse 

  2. 正確にはhtml内にその文字列が含まれているかをテストします。htmlのタグなども確認の対象になります。 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerでLaravelを立ち上げた際の学習メモ

DockerでLaravelを立ち上げた際の学習メモ

>>> 編集中

はじめに

アプリケーションを開発していく上で、開発環境のWindowsと本番環境のLinuxで差分が出てしまうのを
解決したかったので、Dockerを実際に使ってみました

それに伴いDockerの概要や使ってみた感想などをまとめてみました

今回使用するリポジトリです

Dockerについて

まず、Dockerとは仮想環境を提供するソフトウェアの事を指します
コンテナは隔離されたOSを持ち、その上でアプリケーションを稼働させることが出来ます
そしてアプリケーションを依存対象と共にカプセル化することが出来ます

またホストOSとリソースを共有出来ることが特徴です

Dockerの大まかな概要は下記を参照してください

公式, Dockerアーキテクチャ, コンテナについて

Dockerのデメリット

Dockerを利用する上での利点についてです

  • フレームワークやミドルウェアを自分で構築する必要がない

例えばLaravelを利用した開発を行う場合に、ホストOSにPHPをインストールしなくても
Bitnamiが提供するLaravelのイメージがDocker Hubと呼ばれるリポジトリに配布されているため
簡単に環境を構築できます

また新しいフレームワークや技術が登場しても、Docker Hubにイメージが配布されていれば、自分で環境構築をする必要はありません

  • 複数の開発環境の統一できる

DockerfileにOSやパッケージのバージョンを指定することが出来るため
開発環境ではUbuntuRHELなどのOSやRubyNodejsPHPGoなどの言語のバージョンを統一できます

またaptpipなどのパッケージマネージャで管理されていないライブラリをmsiをでいちいちインストールする必要もありません

僕の認識ではseleniumは、ChromeDriverを手でインストールする必要がありますが
コンテナの場合、その作業は必要なく、ホストの\\Program Files/opt/varなどの汚染を気にすることもありません

  • 開発環境と本番環境の差分を埋めることが出来る

アプリケーションやミドルウェアはDocker Engine上で稼働するため
開発環境、本番環境のホストOS上でDocker Engineプロセスさえ起動していれば、アプリケーションは差分なく稼働することが出来ます

  • VMと比べて早い

リンクを参照すると早いかもしれません
ゲストOSがない分、コンテナの起動が早くキャッシュを利用したコンテナの再ビルドはとても高速です
vagrant upに比べて体感速度レベルで起動速度が違います

Dockerのデメリット

  • セキュリティが弱い

  • 開発中なので、バグを踏む可能性がある

  • 依然として、VMに依存しているのでオーバヘッドなどで恩恵を100%受けることが出来ない

Dockerを理解する

基本的な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

ターミナルはcmdgit 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をインストールする際に必要なgitunzipをインストールします

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

エントリポイントと呼ばれる起動シェルを指定します
このコンテナはLaravelをインストールするコンテナとして使用するため、値にはcomposerを使用します

ENTRYPOINT ["composer"]

コマンド簡易化のため、ターミナルを切り替えます

> sh

用意が出来たので、Dockerfileの内容をイメージに固めます
イメージを固める際に-tオプションをつけてイメージに名前を付けておくと後で楽なので
composerタグをつけます

$ cd work
$ docker build ./ -t composer

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

コマンドオプションを見てみます
このコマンドでやりたいことは、ホストとコンテナのポートを同期させた状態で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のメリットについて、まだまだかけていない部分がありますので
気になった人は是非調べてみてください

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker + Laravel 学習メモ

はじめに

アプリケーションを開発していく上で、開発環境のWindowsと本番環境のLinuxで差分が出てしまうのを
解決したかったので、Dockerを実際に使ってみました

それに伴いDockerの概要や使ってみた感想などをまとめてみました

今回使用するリポジトリです

Dockerについて

まず、Dockerとは仮想環境を提供するソフトウェアの事を指します
コンテナは隔離されたOSを持ち、その上でアプリケーションを稼働させることが出来ます
そしてアプリケーションを依存対象と共にカプセル化することが出来ます

またホストOSとリソースを共有出来ることが特徴です

Dockerの大まかな概要は下記を参照してください

公式, Dockerアーキテクチャ, コンテナについて

Dockerのメリット

Dockerを利用する上での利点についてです

  • フレームワークやミドルウェアを自分で構築する必要がない

例えばLaravelを利用した開発を行う場合に、ホストOSにPHPをインストールしなくても
Bitnamiが提供するLaravelのイメージがDocker Hubと呼ばれるリポジトリに配布されているため
簡単に環境を構築できます

また新しいフレームワークや技術が登場しても、Docker Hubにイメージが配布されていれば、自分で環境構築をする必要はありません

  • 複数の開発環境の統一できる

DockerfileにOSやパッケージのバージョンを指定することが出来るため
開発環境ではUbuntuRHELなどのOSやRubyNodejsPHPGoなどの言語のバージョンを統一できます

またaptpipなどのパッケージマネージャで管理されていないライブラリをmsiをでいちいちインストールする必要もありません

僕の認識ではseleniumは、ChromeDriverを手でインストールする必要がありますが
コンテナの場合、その作業は必要なく、ホストの\\Program Files/opt/varなどの汚染を気にすることもありません

  • 開発環境と本番環境の差分を埋めることが出来る

アプリケーションやミドルウェアはDocker Engine上で稼働するため
開発環境、本番環境のホストOS上でDocker Engineプロセスさえ起動していれば、アプリケーションは差分なく稼働することが出来ます

  • VMと比べて早い

リンクを参照すると早いかもしれません
ゲストOSがない分、コンテナの起動が早くキャッシュを利用したコンテナの再ビルドはとても高速です
vagrant upに比べて体感速度レベルで起動速度が違います

Dockerのデメリット

Dockerのデメリットとして

  • セキュリティが弱い
  • 開発中なので、バグを踏む可能性がある
  • 依然として、VMに依存しているのでオーバヘッドなどで恩恵を100%受けることが出来ない

が挙げられます、これについては現在調査中です

Dockerを理解する

基本的な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

ターミナルはcmdgit 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をインストールする際に必要なgitunzipをインストールします

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

エントリポイントと呼ばれる起動シェルを指定します
このコンテナはLaravelをインストールするコンテナとして使用するため、値にはcomposerを使用します

ENTRYPOINT ["composer"]

コマンド簡易化のため、ターミナルを切り替えます

> sh

用意が出来たので、Dockerfileの内容をイメージに固めます
イメージを固める際に-tオプションをつけてイメージに名前を付けておくと後で楽なのでcomposerタグをつけます

$ cd work
$ docker build ./ -t composer

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

コマンドオプションを見てみます
このコマンドでやりたいことは、ホストとコンテナのポートを同期させた状態で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のメリットについて、まだまだかけていない部分がありますので
気になった人は是非調べてみてください

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker学習メモ

DockerでLaravelを立ち上げた際の学習メモ

>>> 編集中

はじめに

アプリケーションを開発していく上で、開発環境のWindowsと本番環境のLinuxで差分が出てしまうのを
解決したかったので、Dockerを実際に使ってみました

それに伴いDockerの概要や使ってみた感想などをまとめてみました

今回使用するリポジトリはここです

Dockerについて

まず、Dockerとは仮想環境を提供するソフトウェアの事を指します
コンテナは隔離されたOSを持ち、その上でアプリケーションを稼働させることが出来ます
そしてアプリケーションを依存対象と共にカプセル化することが出来ます

またホストOSとリソースを共有出来ることが特徴です

Dockerの大まかな概要は下記を参照してください

公式, Dockerアーキテクチャ, コンテナについて

Dockerのデメリット

Dockerを利用する上での利点についてです

  • フレームワークやミドルウェアを自分で構築する必要がない

例えばLaravelを利用した開発を行う場合に、ホストOSにPHPをインストールしなくても
Bitnamiが提供するLaravelのイメージがDocker Hubと呼ばれるリポジトリに配布されているため
簡単に環境を構築できます

また新しいフレームワークや技術が登場しても、Docker Hubにイメージが配布されていれば、自分で環境構築をする必要はありません

  • 複数の開発環境の統一できる

DockerfileにOSやパッケージのバージョンを指定することが出来るため
開発環境ではUbuntuRHELなどのOSやRubyNodejsPHPGoなどの言語のバージョンを統一できます

またaptpipなどのパッケージマネージャで管理されていないライブラリをmsiをでいちいちインストールする必要もありません

僕の認識ではseleniumは、ChromeDriverを手でインストールする必要がありますが
コンテナの場合、その作業は必要なく、ホストの\\Program Files/opt/varなどの汚染を気にすることもありません

  • 開発環境と本番環境の差分を埋めることが出来る

アプリケーションやミドルウェアはDocker Engine上で稼働するため
開発環境、本番環境のホストOS上でDocker Engineプロセスさえ起動していれば、アプリケーションは差分なく稼働することが出来ます

  • VMと比べて早い

リンクを参照すると早いかもしれません
ゲストOSがない分、コンテナの起動が早くキャッシュを利用したコンテナの再ビルドはとても高速です
vagrant upに比べて体感速度レベルで起動速度が違います

Dockerのデメリット

  • セキュリティが弱い

  • 開発中なので、バグを踏む可能性がある

  • 依然として、VMに依存しているのでオーバヘッドなどで恩恵を100%受けることが出来ない

Dockerを理解する

基本的な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
ターミナルはcmdgit 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をインストールする際に必要なgitunzipをインストールします

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

エントリポイントと呼ばれる起動シェルを指定します
このコンテナは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のメリットについて、まだまだかけていない部分がありますので
気になった人は是非調べてみてください

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[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.php
if (! 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を渡す
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker前提のLaravelログ設定

概要

Laravelでのログ設定についてまとめした。

  • この記事のゴール
    • 任意のログを stdout で書き出す

最終的にDockerコンテナのログを書き出すことを前提にしてるため、stdoutのみに焦点を当てています。

Laravelには上記のゴール以外にも、ログをファイルに書き出したり、Slackに通知するよう設定できます。

詳しく知りたい方は以下のリンクをご覧ください。

※監視ド素人が書いたものですので、間違い等ありましたらご指摘いただけると幸いです!

目次

  1. ログ設定
  2. ログレベル
  3. なにをログとして書き出すか

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. 障害発生時、原因究明の手がかりとする
  2. 改善に役立てる

主にひとつ目の目的が大きいです。
どこで問題が起きたか、なにが問題となったか等を知るため、各処理にたいしてログを残すことが必要です。

ただし、すべての処理に対してログを差し込むのは大変ですし、すんごい小さな処理にまでログを残してると、本当に必要なログが埋もれてしまいます。

まずはリクエストごと、コントローラの各処理を1単位として、
あとは必要に応じてログを残すようにします。

どんなログを残すか

ここはログ設計指針 - Qiitaから引用させていただきます。

  • INFOリクエスト開始時 - 処理概要、実行クラス名、メソッド名
  • INFO途中経過 - 実行条件、処理対象オブジェクトのキーとなる値等(customer_id, order_id 等)
  • INFO処理終了時 - 実行結果(OK/NG 等)、リダイレクト先
  • WARNイベント発生時 - 画面に表示したエラーメッセージ等
  • ERROR例外発生時 - 例外クラス、例外メッセージ
  • INFOその他、必要に応じて

おわりに

Laravelのログ設定はlogging.phpのみで完結してて取っつきやすく、デフォルトでslack通知にも対応してたり(使わないけど)パワフルで良いですね。

次はDockerでのログの扱いについてまとめます。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.ymlDockerfileこちらを参考にさせていただきました。作成し終わったら、以下のコマンドを実行します。

# コンテナをバックグラウンドで起動
$ docker-compose up -d

# 環境内に入る
docker-compose exec app bash

# composerコマンドでLaravelプロジェクトを作成
composer create-project --prefer-dist laravel/laravel [プロジェクト名] 

プロジェクト内の.envファイルを以下のように編集します。

.env
DB_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と入力するのが面倒なのでエイリアスを設定しています。

~/.bashrc
alias dkcp='docker-compose'
# sourceコマンドで設定を反映
$ source ~/.bashrc

# 以下のように入力できるようになります
$ dkcp up -d

laravel 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.js
const 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 watch

docker-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 -d

Permission denidがブラウザに表示される場合

ブラウザを確認しながら、適宜storage内のパーミッションを変更する。

$ chmod 777 hogehoge

file not foundとブラウザに表示される場合

ドキュメントルートを変更すると直るかもしれません。
nginxの設定ファイルのdefault.conf内にあるrootを変更する。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.ymlDockerfileこちらを参考にさせていただきました。作成し終わったら、以下のコマンドを実行します。

# コンテナをバックグラウンドで起動
$ docker-compose up -d

# 環境内に入る
docker-compose exec app bash

# composerコマンドでLaravelプロジェクトを作成
composer create-project --prefer-dist laravel/laravel [プロジェクト名] 

プロジェクト内の.envファイルを以下のように編集します。

.env
DB_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と入力するのが面倒なのでエイリアスを設定しています。

~/.bashrc
alias dkcp='docker-compose'
# sourceコマンドで設定を反映
$ source ~/.bashrc

# 以下のように入力できるようになります
$ dkcp up -d

laravel 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.js
const 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 watch

docker-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 -d

Permission denidがブラウザに表示される場合

ブラウザを確認しながら、適宜storage内のパーミッションを変更する。

$ chmod 777 hogehoge

file not foundとブラウザに表示される場合

ドキュメントルートを変更すると直るかもしれません。
nginxの設定ファイルのdefault.conf内にあるrootを変更する。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.ymlDockerfileは以下を参考にしました。
Laravelの環境をDockerで構築するチュートリアル

ディレクトリの構成

$ tree -L 3
.
├── docker
│   ├── php
│   │   └── Dockerfile
│   └── web
│       └── default.conf
├── docker-compose.yml
Dockerfile
FROM 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/html
docker-compose.yml
version: '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.conf
server {
    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を編集します。

.env
DB_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と入力するのが面倒なのでエイリアスを設定しています。

~/.bashrc
alias dkcp='docker-compose'
# sourceコマンドで設定を反映
$ source ~/.bashrc

# 以下のように入力できるようになります
$ dkcp up -d

laravel 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.js
const 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 watch

docker-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.yml
docker-compose-dem.yml
version: "3"
services:
  app:
    volumes:
      - sync-volume:/var/www/html:nocopy # nocopy is important

volumes:
  sync-volume:
    external: true
docker-sync.yml
version: '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を変更する。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

自分の勉強記録を分析しよう!~新米エンジニアの個人開発~

自分の勉強記録を分析しよう!~新米エンジニアの個人開発~

プログラマー歴1年目のじょーだいです。

プログラマーになって一年、そろそろ新しいことを学んでみたかったので、使ったことのない技術を使用して簡単なwebアプリケーションを開発してみました。

どんなアプリ?

僕は勉強したことをTwitterでつぶやいています。

他にも多くの方々が自分の勉強したことをつぶやいているのをよく見かけます。

せっかく勉強しているならその記録をしっかり残したい。。。

そこで今回は自分の勉強を記録しておくことのできる「Stacker」というアプリを開発しました。

使用している技術は?

  • Laravel
  • Vue.js
  • Chart.js
  • MySQL
  • Docker
  • XSERVER
  • Git

各画面の説明

ダッシュボード

01.png

この画面の作成が一番時間をとられました。

上部に1週間のグラフ、下部に日毎の入力したデータが表示されます。

また右上のボタンによって、1週間のグラフを総合計のグラフに切り替えることでカテゴリーごとの合計時間を知ることができます。

勉強している日、してない日がすぐわかるので結構気に入ってます。

カテゴリ―毎の詳細

02.png

ダッシュボードの左側のカテゴリー一覧からカテゴリ―を選択すると画像のような画面が開きます。

今まで入力したコメントが一覧表示されるので、どんなことを勉強してきたのか一目瞭然です。

カテゴリ―詳細ページは他のユーザーが覗くこともできます。

知らない語句や勉強の順序、気になるエンジニアがどんなことを学んでいるのかを知ることができます。

ホーム

02.png

各ユーザーの投稿が一覧表示されています。

とても簡易的なSNSのような感じです。

フォロー機能等は実装していませんが、他のユーザーの勉強量を知ることで、モチベーションを上げることができます。

現在会社の後輩とこのアプリを使用しているのですが、とても会話が盛り上がります。

特に相手が何を勉強しているのかがわかるので、気になったことをすぐに聞けるし、話のきっかけづくりにもなります。

感想

一応完成はしたものの、まだまだ実装したい機能が盛りだくさんです。
例えば
 フォロー機能
 、円グラフでの分析
 、カテゴリ―毎の表示順序、色の切り替え
など、他にも細かいところでまだまだたくさんあります。

他にもリファクタリングやテストコードの作成などすることは盛りだくさん。

これからも勉強を記録していくためにこのアプリを使用し、改善を続けていきます。

自分自身が毎日使用していくので、改善、メンテナンスを無理なく続けていくことができると思います。

個人開発でも作りっぱなしではなく、しっかりと運用していくので、よければ皆様も使ってみてください。

一言

コードが汚すぎる。リーダブルコード読んだはずなんだけどな~

➡Stackerはこちら

➡Twitterはこちら

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む