はじめに
まず事前知識として私は社会人でSEしながら趣味で絵を描いている者です。
また、この記事もまた初めてQiitaに投稿するものとなります。読みにくい等あるかもしれませんが、ご容赦ください。
2025年9月から約1ヶ月半をかけて、フルスクラッチで個人ポートフォリオサイトを構築しました。
メインで使用したのは Gemini CLI × Obsidian の開発スタイルで、時々アイデア出しにChatGPTも利用しました。
完成したサイトはこちらです。
https://motimotinotch.com
開発した経緯
サイト制作に踏み切った経緯は、いくつかの要因が重なった結果です。
-
Gemini CLIとObsidianのパワーを持て余していた
- 日々のメモやタスク管理に強力な環境を整えました。いやGemini、お前もっと使えるやろ!!
-
アーティストを取り巻くSNSとAIの事情
- AIによる無断学習やスクレイピングといった問題に対し、個人が対策を講じるのは限界があると感じ、「サービス側がやるべき」という考えから、自分でコントロールできる作品公開の場が欲しくなった
-
技術者としての自己検証
- 業界に入って3年、日々の業務はこなせるものの、「世の中で当たり前とされている開発手法は、本当に自分の現場でも最適なのか?」という疑問が湧きました。検索して知識を得るだけでなく、実際にゼロから構築することで、技術を深く理解し、検証したいと考えました
これらの思いが合わさり、「じゃあサイト作るか!!」という割と軽いノリでプロジェクトがスタート。
余談
もともとNotionで纏めて公開してたけど、やりたいこととちょーーっと管理者とユーザーの切り分けのとこで不安になったので今回り換えた感じ。
サイトのコンセプト
開発を始めるにあたり、ざっくりと以下のようなコンセプトを立てました。
- デザイン: 絵が主体なので、過度な装飾は不要。グレースケールをベースに、無機質で洗練された雰囲気を出す
- 表現: 作品同士の「繋がり」を表現したい。Obsidianのグラフビューのような、インタラクティブなグラフ機能を実装する
- 自己紹介: 単なる文章の羅列ではなく、ObsidianのCanvasのように、思考マップのようなインタラクティブなプロフィールページを作る
開発エコシステム
今回の開発は、以下のツール群を連携させて進めました。
-
計画・設計 (Obsidian × Gemini CLI):
- 全ての仕様書、手順書、課題メモをObsidianで作成・管理。Geminiと対話しながら、思考を整理し、具体的な実装計画に落とし込んでいきました
-
コーディング (VS Code with Dev Containers):
- Dockerコンテナ上に開発環境を構築し、誰が使っても同じ環境を再現できるようにしました
-
インフラ (Cloudflare):
- Pages, Workers, R2, KVといったCloudflareのサービス群を全面的に採用し、サーバーレスな構成を実現しました
-
アイデア出し (ChatGPT):
- 外出時など、コーディングができない場面でのアイデア整理や壁打ち相手として活用しました
開発経緯(タイムライン)
主要な機能実装のマイルストーンは以下の通りです。
- 2025-09-04: プロジェクト開始。AstroとDockerをベースとした開発環境の構築に着手
- 2025-09-07: 基本的なレイアウト、ページコンポーネント、NSFWコンテンツの表示切替機能など、サイトの骨格を実装
- 2025-09-08: Cloudflare WorkersとR2を利用した画像アップロードAPIのバックエンド部分を実装
- 2025-09-14: 閲覧数カウント機能、作品への複数画像登録、コピー禁止機能などを追加
- 2025-09-15: コンテンツ管理の中核となる作品エディタの実装に着手
- 2025-09-17: 管理者認証機能とトップページを実装
- 2025-09-20: 閲覧体験向上のため、作品一覧ページのフィルター・ソート状態がページ遷移後も維持されるように修正
- 2025-09-21: 読んだ本を記録・表示する書籍リスト機能を追加
- 2025-09-23: サムネイル用の画像トリミング機能を追加
- 2025-09-24: 動画コンテンツのアップロードと表示に対応
- 2025-09-25: コンテンツIDをUUIDに統一し、URL構造を堅牢化
- 2025-09-26: タグ管理ページを実装
- 2025-09-27: クレジット(制作者情報)管理ページを実装
- 2025-09-30: 作品間の関連性を可視化するインタラクティブグラフ機能を実装
- 2025-10-01: UIにグラスモーフィズム(すりガラス効果)を導入
- 2025-10-04: お知らせ(What's New)機能を追加
- 2025-10-05: ダークモードを実装
- 2025-10-18: 全機能のテストを完了し、Cloudflare Pagesへデプロイ
技術スタック
本サイトは以下の技術で構成されています。
-
フレームワーク: Astro
- 静的サイト生成とサーバーサイドレンダリングの両方の長所を活かせる点を評価し採用しました。
-
- 管理画面などのインタラクティブなUIはSvelteで構築。インタラクティブグラフのみ、エコシステムの豊富なReactとCytoscape.jsを採用しました
-
バックエンド & ホスティング: Cloudflare Pages, Cloudflare Workers
- Astroとの親和性が高く、デプロイフローが非常にスムーズなため採用。コンテンツ操作APIはすべてWorkersで構築しました
-
ストレージ:
- Cloudflare R2: 画像や動画などのメディアアセット、および作品や書籍のMarkdownコンテンツ本体を保存しています
- Cloudflare KV: 作品ごとの閲覧数を保存するシンプルなキーバリューストアとして利用しています
-
主なライブラリ:
- nanostores: NSFW表示設定やUIのテーマ(ダークモード)など、サイト全体で共有する状態の管理に使用しました
- cropperjs: 管理画面でのサムネイル画像トリミング機能で利用しています
- cytoscape.js: 作品間の関連性を可視化するインタラクティブグラフの描画に使用しました
- marked, sanitize-html: 管理画面から入力されたMarkdownを安全にHTMLとしてレンダリングするために使用しています
-
開発環境:
- Docker / VS Code (Dev Containers): 依存関係をコンテナに閉じ込めることで、クリーンで再現性の高い開発環境を構築しました
実装したページと機能
ページ構成
-
トップページ (
/): サイトの入り口。おすすめ作品や最新情報などを掲載 -
作品一覧ページ (
/works): 全ての完成作品を閲覧・フィルタリングできるページ -
作品詳細ページ (
/works/[id]): 個別の作品の情報、画像、関連クレジットなどを表示 -
書籍一覧ページ (
/books): 読んだ本を一覧で表示・フィルタリングできるページ -
書籍詳細ページ (
/books/[id]): 個別の書籍の情報を表示 -
インタラクティブグラフ (
/graph): 作品、タグ、クレジットの関係性を視覚的に探索できるページ -
進捗ページ (
/progress): 現在制作中の作品の進捗を一覧表示 -
自己紹介ページ (
/about): プロフィールや連絡先などを掲載
主要機能
-
コアアーキテクチャ:
- Astro, Cloudflare Pages/Workers, R2, KVを組み合わせたサーバーレス構成
- コンテンツIDのUUID化による堅牢なデータ管理
-
コンテンツ表示機能:
- レスポンシブデザイン、ダークモード、GlassmorphismによるモダンなUI
- NSFWコンテンツ対応 (表示/非表示トグル)と、それに応じたOGP画像の切り替え
- 作品・タグ・クレジット間の関連性を可視化するインタラクティブグラフ
-
データ操作・フィルタリング機能:
- 階層タグ(親子関係)に対応した高度なAND/OR検索フィルター
- フィルター条件に応じた作品数の動的カウント表示
- フィルターやソート順がページを移動しても維持される状態の永続化
-
管理機能 (Admin Panel):
- パスワード認証で保護された管理画面
- 作品、書籍、タグ、クレジット、お知らせ等のCRUD操作が可能な統合エディタ
- 動画対応、サムネイルトリミング機能を備えた高機能アップローダー
- cronジョブによる、どこからも参照されなくなった孤立ファイルの自動削除機能
まとめ
ObsidianでGeminiに手順書を作成してもらい、それに基づいてVSCodeで実装を進める。
手順書ベースで開発を進めたが再現性もとれるのでまあありなんじゃないかなって思いました。
ただ、使用技術の深堀についてはまあできる訳もなく、あくまでもふんわりこんなものがあるんだなぁ、こんなことができるんだねぇって感じになります。
入口としては全然いい感じかと!(ちょっと重いかもしれない)
初見で、かつ一か月半で行けるんだって今も驚いてます。
評判が良かったら一か月半の紆余曲折も書こうかなと考えてます。
