🎨

簡易作図ツール作って公開してみた(Next.js+CloudFront+S3)

に公開

まえがき

シンプルな作図ツールのようなものを作ってみたいとは思っていたんですが、あんまり公開にお金をかけたくないなあと思っていました。
とりあえず作図してpngの保存くらいならフロントエンド一枚で作図できるんじゃないかと思い今回作ってみました。今のところフレームというボタンでpngを保存できるだけです。(gifで保存しても静止画しか保存できないですね...)

とりあえず今回はAWSのインフラ構成の説明や手順について自分なりにまとめたいと思います。

ツールの内容

ツールURL

とりあえず以下がURLです。正直なところwebアプリケーションの知見があまりないので様子見でテスト公開します。(ドメインは買わなかったのでcloudfrontのurlになってます。Googleのタブに表示される名前もCreate Next Appになってますね...)

https://d1erz04a8awa6.cloudfront.net/index.html

ツールの動作

一応動画のようなことができます。四角の部分をクリックすると作業場に図形が表示されます。図形を選択すると右にプロパティ画面が出てきて図形の大きさなどを設定できます。
色には枠線と図形内部の色があり、色を同期するボタンで両方の色を同期させて変更できます。
あとは角丸(図形の角が丸くなる機能)も付けたかったので作りました。
フレームのボタンを押すと静止画は保存できます。
簡易的なアニメーションのようなものも作れるのですが、gif保存機能がまだ未実装です...
まあバクは全然いっぱいあると思います。

フロントエンド

コード

Next.jsのpages.tsx一枚に収めているのでフロントエンドエンジニアの方から見たら酷いもんだと思います。フロントエンドに関しては別途一部だけまたどこかでまとめたいと思います。
https://github.com/nkwork9999/sakuzumotion

フロントエンドのデプロイ

どちらかというと今回はNext.jsで作成したフロントエンドのデプロイやインフラの構成の手順についてまとめたかったのでこの記事を作っています。
なので以下に流れをまとめたいと思います。

ビルドのためのファイル設定

Next.jsでフロントエンドは作成済みなのでビルドするための設定のために以下のファイルを編集します。

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
};

export default nextConfig;

デフォルトだとこのような状態なので、/* config options here */のところに以下の内容を入れます。

output: 'export',
  
  // 画像最適化を無効化(S3では動的な画像処理ができないため)
  images: {
    unoptimized: true,
  },
  
  // URLの末尾に/を追加(S3のフォルダ構造に合わせる)
  trailingSlash: true,

output:'export'を設定することで静的HTMLファイルを生成できます。(サーバーサイドレンダリング(SSR)機能は使用不可)
要はS3上に置いて公開できるページを作成できるということです。(静的ホスティング)

images: {
unoptimized: true,
}
でNext.jsの画像最適化機能を無効化しています。今回は特に画像は使用していないと思うのでいらないかもしれませんね。

trailingSlash: true
でURLの後ろにスラッシュを追加できます。S3上で正しくアクセスできるようにするために必要な設定のようです。

そして以下のコードでoutディレクトリに静的ページがビルドされます。

pnpm build

outフォルダの中身

outフォルダの中身についてもざっくり概要だけ調べてみました。
サーバーなしで動かすためにoutフォルダには色々な、HTML/CSS/JavaScriptファイルが集まっています。

  1. HTMLファイル
    index.html:ここにページの内容が記述されます。
    404.html - エラーページ用のファイルです。

  2. _nextフォルダ
    アプリを動かすために必要なファイルが全部入ってます。
    だいたいがJavaScript(動的な処理)・CSS(デザイン)・他には画像・フォントなどなどが格納されます。

  3. その他
    favicon.ico:ブラウザタブのアイコン
    .svgファイル:ロゴや画像
    などです。

_nextフォルダ内のstaticsフォルダ内にあるファイル名が複雑な文字列になっています。
(xxxxxxx-xxxxxxxxxxx.js xの部分には数字とアルファベットが混ざっている。)

ファイルを更新したらブラウザが新しいファイルだと認識するように一意なファイル名になっているみたいです。
あとchunkというフォルダにファイル分割されています。これは全部まとめると重いので必要になった時だけ読むためにチャンクわけされているということみたいです。

AWS構成をコンソールから作る

S3でドメイン名のバケットを作成する。

まずバケットを作成します。
基本的には特殊なことはしていませんが、cloudfrontでOAC経由で公開するのでパブリックアクセスブロックは有効にします。

次にS3バケットに先ほど作成したoutフォルダの中身をアップロードします。
大事なのはアップロードするのはoutフォルダ自体ではなく、outフォルダ以下にある全ファイルです。
なので前選択して以下のアップロードのところにドラッグ&ドロップします。

ここでoutフォルダ内にあるindex.htmlと404.htmlを指定します。

これで完了です。



# CloudFrontディストリビューションの作成
S3はこのままでもURLを公開できるんですが、CloudFront経由でユーザーに使用してもらいます。

例えば東京リージョンのS3上にあっても、世界中のエッジサーバーにキャッシュすることで海外からのアクセスが高速になったり、あとS3のURLを隠蔽できるので、S3への直接攻撃などを防げます。
あとCloudFrontにキャッシュがあるのでそれにアクセスしてもらうことでS3への直接のアクセスが少なくなり、コスト削減にもなります。

とりあえず手順は以下です。
CloudFrontでディストリビューションを作成ボタンを押します。
![](https://storage.googleapis.com/zenn-user-upload/b2e1da8dbf38-20250615.png)
OriginにはS3 REST APIを選択。
そのあとOAC設定をします。Origin access control settingsをしておくことでS3のアクセスをCloudFrontに限定できます。
以下参考(プライベートの方)

https://dev.classmethod.jp/articles/amazon-cloudfront-origin-access-control/

ビュワープロトコルポリシー
![](https://storage.googleapis.com/zenn-user-upload/3287ce7c7796-20250615.png)

料金は北米と欧州のみにしました。(まあ海外からのアクセスはないと思いますが...)

ログをS3へ 形式はparquetで保存されるようにしています。

これで完了です!あとはディストリビューションドメイン名のところにあるURLからアクセスできます。


# まとめ
久しぶりにWeb公開のツールを作ってみました。いい勉強になりました!
次はバックエンドありのブログのようなものを作りたいと思います!



Discussion