ゴマちゃんフロンティア

アザラシが大好きなエンジニアの開発日記です

【開発日記】2019年GW中に「アザラシの写真集」のwebアプリを作ったお話

time 2019/05/08

AWSの無料試用期間が切れてしまったため、現在写真集のサーバを停止しています。
気になる方はTwitterや質問箱で管理者にお問い合わせください。

2019年のゴールデンウィークは10日も休みがありましたね。(お仕事だった方ごめんなさい)
私は3月からフリーランスSEとしてお仕事をしていますが、仕事内容のほとんどがgoogleスプレッドシートを使ったドキュメント作成であり、正直望んでいた内容とは異なるものです。
そんな経緯もあってか、連休前に元会社の方から「GWに自由研究やってみないか?」とお誘いを受けたので、勉強も兼ねてAWS上にwebアプリを立ててみました。

以下のURLから見れますので、気になる方はどうぞ~。
http://azarashiphoto.gomafrontier.com

せっかくなので、構成や仕様についてざっくりと書いておきます!

基本的な構成と仕様

WebサーバとDBサーバに「EC2」、写真のストレージに「S3」、S3のCDNとして「CloudFront」を使いました。シンプルなアプリ故、構成も至って普通ですね。

勉強も兼ねていたので、VPCやイントラネット、セキュリティグループやインターネットゲートウェイ等も新規に作成しました。
参考にしたのは以下の本で、Wordpressのインストールを今回作成したアプリの展開に差し替え、S3やCloudFrontを足した感じですね。
本自体、構成や操作手順が画像で載っていたり、「オンプレのこれはAWSで言うとこれ」のような比較があったりして分かりやすかったです。

Webアプリの方はフレームワークとしてアザラシ検定と同じくLaravelを使用しました。
加えてフロントエンドのフレームワークにはreact.jsを使いました。仕事で使うことになりそうなので、vue.jsで味をしめている今のうちに慣れておきたかったためです。
スマホからも見たいため、レスポンシブデザイン用にBootstrap4のグリッドシステムを使用しました。

Webアプリ公開側

アップロードされている写真を並べて表示します。セレクトボックスでロケーションを選択すると、表示する写真を絞り込みます。

内部的にはreactからAPIをコールし、ロケーションに応じた写真のファイルパスの一覧を取得、それをぐるぐる回してimgタグのsrc属性に設定して表示しています。

写真はクリックするとモーダルで大きく表示されます。
このモーダルは「react-modal」ライブラリを使用して表示しています。

ちなみにスマホの場合はタップしてもモーダルを表示しません。
スマホの縦画面ではモーダルの表示が難しいこと、実装しても画面サイズ的に大きく表示できないことが理由です。

Webアプリ管理側

管理者ユーザーでログインすることで、写真のアップロードやロケーションの追加・削除が行えます。

写真はS3に保存するため、Laravelで推奨されているライブラリ「league/flysystem-aws-s3-v3」を追加・使用しました。
使う度にStorage::disk(‘s3’)と書くのは面倒なので、1個専用のサービスを作成。

<?php

namespace App\Service;

use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\File\File;

/**
* 「Amazon S3」関連のサービス
*/
class AmazonS3Service
{
    /**
     * ファイルをS3へアップロード
     */
    public function upload(File $file, $target_dir = '/photos')
    {
        return Storage::disk('s3')->putFile($target_dir, $file, 'public');
    }

    /**
     * ファイルをS3から削除
     */
    public function delete($filepath)
    {
        Storage::disk('s3')->delete($filepath);
    }

    /**
     * S3上にファイルが存在するか確認
     */
    public function isExists($filepath)
    {
        return Storage::disk('s3')->exists($filepath);
    }

    /**
     * S3のベースURLを取得
     */
    public function getBaseUrl()
    {
        $url = Storage::disk('s3')->url('/');
        
        // 末尾のスラッシュを削除
        $url = rtrim($url, '/');

        return $url;
    }
}

これを各コントローラのコンストラクタで注入してS3関連の処理を行いました。
アップロードの際は返り値のファイルパスをDBに保存し、各画面での写真表示に使用します。

今後やりたいこと

GW開けの成果発表でレビューいただいた結果、以下の点をやりたくなりました。

  • DBをEC2からRDSに移行
  • CircleCIを使った自動デプロイ
  • ロードバランサの導入

優先すべきはCircleCIですかね…。
今はGitにプッシュ後に手動でpullしている状態なので、シャレオツとは言い難い運用です。
先に作ったアザラシ検定も同様なので、自動デプロイのやり方を確立しておきたいです。

あとがき

そんなわけで、GW中にアザラシの写真集アプリを作りました!
単純なアプリですが、AWSの入門として手頃であり、LaravelやReact.jsの慣らし運転にもなったので、実りは大きいです。
今後も定期的にアザラシなサービス作成に挑戦しますので、お楽しみに~!

down

コメントする