tag:crieit.net,2005:https://crieit.net/tags/Cloudflare/feed 「Cloudflare」の記事 - Crieit Crieitでタグ「Cloudflare」に投稿された最近の記事 2023-07-29T05:35:55+09:00 https://crieit.net/tags/Cloudflare/feed tag:crieit.net,2005:PublicArticle/18544 2023-07-29T05:35:55+09:00 2023-07-29T05:35:55+09:00 https://crieit.net/posts/Nuxt3-Cloudflare-GooglePlay-64c426ab215c8 【個人開発】アイデア出しから公開・プロモーションまでまとめ(Nuxt3、Cloudflare、GooglePlay) <h1 id="1. はじめに"><a href="#1.+%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">1. はじめに</a></h1> <p>個人開発の大体の流れがつかめるように、アイデア出しから公開・プロモーションまでをまとめました。</p> <h2 id="1-1. 作ったアプリ"><a href="#1-1.+%E4%BD%9C%E3%81%A3%E3%81%9F%E3%82%A2%E3%83%97%E3%83%AA">1-1. 作ったアプリ</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://lisble.net/about/"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/2eb38bfc-0efc-d719-9baa-d0967308e507.png" alt="シンプルな買い物リスト-lisble リスブル" width="350"></a></p> <div class="table-responsive"><table> <thead> <tr> <th>About</th> <th>List</th> <th>History</th> </tr> </thead> <tbody> <tr> <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/01ff7a29-9672-8717-161b-807bfd85f014.png" alt="Aboutページのスクリーンショット.png" width="120" height=""></td> <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/1e53b87e-f6d3-8ef8-8646-f66b8c02dbb2.png" alt="リストページのスクリーンショット" width="120" height=""></td> <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/64e97b97-f950-2f48-e346-63a506643401.png" alt="履歴ページのスクリーンショット" width="120" height=""></td> </tr> </tbody> </table></div> <div class="table-responsive"><table> <thead> <tr> <th></th> <th>基本操作</th> </tr> </thead> <tbody> <tr> <td>① <strong>リスト作成</strong> ② <strong>買い物完了でチェック</strong> ③ <strong>チェック済みを削除</strong> ※これらの手順だけで簡単操作</td> <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/33bc7e8d-e258-bdbd-85e4-affb6c585cd9.gif" alt="買い物リスト-lisble リスブルの基本操作" width="160" ></td> </tr> </tbody> </table></div> <p><strong>『<a target="_blank" rel="nofollow noopener" href="https://lisble.net/about/">買い物リスト・メモ - Lisble リスブル</a>』</strong><br /> <div class="table-responsive"><table> <thead> <tr> <th>iOS,PC</th> <th>Android</th> </tr> </thead> <tbody> <tr> <td><a src="https://lisble.net/about/" target="_blank" rel="noopener noreferrer" ><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/992c120a-33bd-48d1-93cd-d97fde42d22c.png" alt="シンプルな買い物リスト-lisble リスブル" width="250"></a></td> <td><a src="https://play.google.com/store/apps/details?id=net.lisble.twa" target="_blank" rel="noopener noreferrer" ><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/f92cdde6-21d1-2d3f-b8bf-9fb72a74abde.png" width=230 alt="googlePlayバッジ" ></a></td> </tr> <tr> <td>iOS,PCの方は、PWAの為、メニューから <strong>「ホーム画面に追加」</strong> をお願いします。</td> <td>このアプリは Google Play で入手できます。</td> </tr> </tbody> </table></div></p> <h1 id="2. 0から公開までの流れ"><a href="#2.+0%E3%81%8B%E3%82%89%E5%85%AC%E9%96%8B%E3%81%BE%E3%81%A7%E3%81%AE%E6%B5%81%E3%82%8C">2. 0から公開までの流れ</a></h1> <h2 id="2-1. アイデア"><a href="#2-1.+%E3%82%A2%E3%82%A4%E3%83%87%E3%82%A2">2-1. アイデア</a></h2> <p>1番大事だけど一番頭を悩ませました。<br /> 新しいものか、既存のサービスでの差別化の二択で、はじめてということで後者にしてしまいました。<br /> これからもアンテナをはって次につなげたいです。</p> <p><strong>アイデアの出し方</strong><br /> * とにかく紙に書く<br /> * 不満・面倒・悩み・困っていること<br /> * 人間観察(周りの人)・他業種の業務課題<br /> * 真似 → シンプル化・別分野へ応用・既存のサービスの不満解消<br /> * 海外のサービス調査<br /> * ニッチ・マニアック(自分の強み・趣味)<br /> * 合体・逆</p> <p>既存のサービスの発展系か、何かの組み合わせか<br /> 思いついたらメモ 📝</p> <p><strong><em>参考サイト</em></strong><br /> <a target="_blank" rel="nofollow noopener" href="https://shuheblog.com/programing-app-idea-creative">アプリ開発でアイデアが浮かばないあなたへ。独創的なアイデアの出し方</a><br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/MasatoraAtarashi/items/eec4642fe1e6ce79304d">ポートフォリオや個人開発で使えそうなアイデア</a></p> <h2 id="2-2. 要件定義"><a href="#2-2.+%E8%A6%81%E4%BB%B6%E5%AE%9A%E7%BE%A9">2-2. 要件定義</a></h2> <p><strong>①要件(こうだったらいいな)</strong><br /> * 出来る、出来ないを考えずあげていく</p> <p><strong>②要件の為の機能</strong><br /> * ここで出来る、出来ないを考える<br /> * 最低限必要な機能を絞る<br /> * 実装方法が思いつかない機能は省略</p> <hr /> <ul> <li>出先で「あれあったかな❓」を解決したい → 買い物履歴を残して最近買ったものをわかるようにする機能</li> <li>在庫の把握・重複購入を減らしたい → 買い物履歴から同じ単語入力時に色の変化で知らせる → 入力中に知らせることにより在庫を思い出すきっかけにもなる<br /> etc...</li> </ul> <p><strong>③出来ればマネタイズも考える</strong><br /> 1. <strong><em>広告</em></strong>:アフィリエイト、AdSense(web)、AdMob(アプリ)<br /> 2. <strong><em>課金</em></strong>:広告削除、追加コンテンツ、アイテム<br /> 3. <strong><em>寄付</em></strong><br /> 4. <strong><em>有料</em></strong>:買い切り<br /> 5. <strong><em>サブスク</em></strong>:月額制</p> <p>とにかく一連の流れを経験したく、マネタイズまでの道のりが見えたのが本アプリ案で、結果Amazonアソシエイト、AdSenseになりました。<br /> AdSenseは受かりませんでした。継続して挑戦します。</p> <p><strong>④利用技術</strong><br /> 🔑 <strong><em>ログイン・ユーザー登録無し</em></strong>、、広告も可でとにかく<strong><em>お金をかけずに</em></strong>を優先して、SPAで制作することにしました。<br /> - GooglePlay Developer 申請・登録25ドル(当時3,352円)<br /> - 独自ドメイン Xserverドメイン 初年度のみ1円<br /> - 更新、移管はCloudflare予定</p> <p><strong><em>アイデア・デザイン</em></strong><br /> Xmind(マインドマッピング)<br /> Figma<br /> <strong><em>コード</em></strong><br /> Nuxt3(Composition API)・TypeScript・Tailwind CSS<br /> <strong><em>インフラ</em></strong><br /> Cloudflare<br /> <strong><em>開発環境</em></strong><br /> VSCode・Git、GitHub</p> <p><strong><em>参考サイト</em></strong><br /> <a target="_blank" rel="nofollow noopener" href="https://tenshoku-miti.com/takahiro/create-original-application/">【5ステップ】初めてのオリジナルアプリの作り方!アイデアの出し方も公開</a></p> <h2 id="2-3. 設計"><a href="#2-3.+%E8%A8%AD%E8%A8%88">2-3. 設計</a></h2> <p><strong>①画面設計</strong><br /> 1. 必要なページ列挙 ➡ 階層・整理<br /> 2. ワイヤーフレーム(紙手書き)下書き<br /> 3. ワイヤーフレーム(figma)清書</p> <p><strong><em>参考サイト</em></strong><br /> <a target="_blank" rel="nofollow noopener" href="https://b-risk.jp/blog/2019/10/wireframe/">ワイヤーフレーム(画面設計)の作り方</a><br /> <a target="_blank" rel="nofollow noopener" href="https://aqcg.jp/web_point/">Web画面設計の手順と重要なポイント</a></p> <p><strong>デザインの4原則</strong><br /> 1. 「<strong><em>近接</em></strong>」:関連する要素を<strong><em>グループ化</em></strong><br /> 2. 「<strong><em>整列</em></strong>」:関連する要素を<strong><em>見えない線</em></strong>で整列<br /> 3. 「<strong><em>反復</em></strong>」:要素の<strong><em>一貫性</em></strong>、デザインの<strong><em>統一</em></strong><br /> 4. 「<strong><em>対比</em></strong>」:要素の優先度を<strong><em>強弱</em></strong>で示す</p> <p><strong><em>参考サイト</em></strong><br /> <a target="_blank" rel="nofollow noopener" href="https://designpartner.jp/principle/#:~:text=%E3%80%8C%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%81%AE4%E5%8E%9F%E5%89%87%E3%80%8D%E3%81%AF,%E3%82%B7%E3%83%BC%E3%83%B3%E3%81%A7%E3%82%82%E5%BD%B9%E7%AB%8B%E3%81%A4%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%80%82">お役立ち知識:デザインの4原則 - デザインパートナー</a></p> <p><strong>②データ設計(構造)</strong><br /> * データの設計図</p> <h2 id="2-4. 開発"><a href="#2-4.+%E9%96%8B%E7%99%BA">2-4. 開発</a></h2> <ul> <li>設計通りに作る</li> <li>最低限の機能</li> <li>制作途中で機能の追加案を我慢して、とにかく完成させることに集中する(追加の機能を制作してしまいました。なのでここに残しておきます。)</li> </ul> <p><strong>①工夫した機能</strong><br /> - <strong>並べ替え(D&D)・スワイプ機能</strong>をライブラリ(Vue.Draggableは、思うような機能にならなかった)を使用せずに作成<br /> - ↳シンプル化のため、<strong>同じ発火点</strong>で、<strong>参考サイト様</strong>(<a target="_blank" rel="nofollow noopener" href="https://reffect.co.jp/vue/trello-drag-drop-clone/">Trello風タスク並び替えドラッグ&ドロップクローン(Vue.js利用)</a>)を参考に、【<strong>マウス、タッチ、処理回数削減、d&dとswipeの融合、グループ間並べ替え、d&d中の上下の画面端scroll</strong>】ロジックを考え自作しました。</p> <div class="table-responsive"><table> <thead> <tr> <th>並び替え機能</th> <th>スワイプ</th> </tr> </thead> <tbody> <tr> <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/30495dd3-fec4-c791-cb39-a1c09f78003d.gif" alt="買い物リスト-lisble リスブルの並べ替え動作" width="150" height=""></td> <td><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/cb611a1f-9124-472b-1a26-b7c4f53f8ecc.gif" alt="買い物リスト-lisble リスブルのスワイプ動作" width="150" height=""></td> </tr> <tr> <td></td> <td>←<strong>色</strong>  →<strong>削除</strong>※タッチデバイスのみ</td> </tr> </tbody> </table></div> <ul> <li>スマホとPCの<strong>挙動の違い</strong>など(ENTER、終了時の処理...)</li> <li>日本、世界の<strong>日時の表示形式</strong>(履歴)</li> <li>Amazonアソシエイトの各国の設定(<strong><em>OneLink</em></strong>)</li> <li>アニメーション(数字のドラムロール、追加削除時...)etc...</li> </ul> <p><strong>②多言語化(i18n)</strong><br /> <strong>@intlify/nuxt3</strong>使用<br /> 日/英で単語の長さの違いによる表示崩れに注意</p> <hr /> <p><strong><em>未解決問題</em></strong><br /> 日本語で検索時、検索結果が英語サイトのtitleとdescriptionになってしまう問題(同じURLで 日/英 にしたい)</p> <p><strong><em>確認</em></strong><br /> meta tagの設定(title、description等)日/英 切替時にきちんと切り替わっている。</p> <p><strong><em>↓ためしたこと↓</em></strong><br /> - <a target="_blank" rel="nofollow noopener" href="https://zenn.dev/koushikagawa/articles/32ef098e0698c7">Nuxt.jsのi18n多言語対応したら、日本語で検索した時の検索結果が英語になってしまった。解決できたので対応方法を記載します。</a><br /> - <strong>@intlify/nuxt3</strong> で <code>detectBrowserLanguage: false,</code>にあたる設定がない??<br /> - sitemapの設定 (hreflang属性)<br /> - Google Search Consoleに日/英を認識させる方法??...<br /> - (2023年7月) Nuxt3での多言語化はまだ開発中らしいので情報待ち🍥 → <a target="_blank" rel="nofollow noopener" href="https://github.com/intlify/nuxt3">intlify/nuxt3: Nuxt 3 Module for vue-i18n-next</a></p> <hr /> <p><strong>③プライバシーポリシー</strong><br /> <strong><em>参考サイト</em></strong><br /> <a target="_blank" rel="nofollow noopener" href="https://biz.moneyforward.com/contract/basic/1237/">プライバシーポリシーとは何か?必要性、記載事項をわかりやすく解説</a></p> <p><strong>④テスト</strong><br /> - 個人情報を扱っているなら、徹底的に安全確認<br /> - 例外処理</p> <h2 id="2-5. 公開"><a href="#2-5.+%E5%85%AC%E9%96%8B">2-5. 公開</a></h2> <p><strong>①(SPA SSG) 静的ファイルホスティングサービス【無料】</strong><br /> 1. GitHub Pages<br /> 2. Firebase Hosting<br /> 3. Netlify<br /> 4. Vercel<br /> 5. <strong><em>Cloudflare Pages</em></strong></p> <p>無料プランの枠・サイトのパフォーマンス・商用利用可で<strong><em>Cloudflare Pages</em></strong></p> <p><strong><em>参考サイト</em></strong><br /> <a target="_blank" rel="nofollow noopener" href="https://zenn.dev/catnose99/scraps/6780379210136f">Cloudflare Pages・Vercel ・Netlify の違いや使い分けをまとめる</a><br /> <a target="_blank" rel="nofollow noopener" href="https://jpsern.com/netlify-to-cloudflare-pages/">NetlifyからCloudflare Pagesに引っ越しました</a></p> <p><strong>②Google Play Store 配信方法</strong><br /> <strong><em>PWA → TWA</em></strong><br /> * TWA変換ツール「<strong><em>Bubblewrap CLI</em></strong>」使用<br /> * Lighthouse で <strong><em>80</em></strong> 以上のパフォーマンス スコアが必要(↓に記述)</p> <p><strong><em>参考サイト</em></strong><br /> <a target="_blank" rel="nofollow noopener" href="https://flaming.codes/ja/posts/trusted-web-activity-create-pwa-android-app">信頼できるWebアクティビティ</a><br /> <a target="_blank" rel="nofollow noopener" href="https://0115765.com/archives/7932#outline__2_2">【TWA】完全開発ガイド=超簡単にPWAをPlay Storeで配信しよう</a><br /> <a target="_blank" rel="nofollow noopener" href="https://sqripts.com/2022/12/14/22480/">PWA対応サイトをAndroid APK(AAB)に変換する</a></p> <p><strong>③Lighthouse のパフォーマンス改善(リファクタリング)</strong><br /> - <strong><em>cssの最適化</em></strong> → 読み込み順、削除、animation(<code>transform</code>,<code>opacity</code>...)etc...<br /> - <strong><em>googleFonts, Analytics</em></strong> → GTM使用、読み込むタイミング、読み込み方、文字の限定etc...<br /> - <a target="_blank" rel="nofollow noopener" href="https://deep-space.blue/web/2090">【2022年3月】Google Fontsのパフォーマンス比較&ハリー・ロバーツ方式の勝手に改良版</a><br /> - <a target="_blank" rel="nofollow noopener" href="https://nullnull.dev/blog/google-fonts-subset/#%F0%9F%8F%A9______________________%F0%9F%91%A8%F0%9F%91%A9">Google Fontsを簡単にサブセット化する方法</a><br /> - <strong><em>Web Worker</em></strong> → 並列処理 <a target="_blank" rel="nofollow noopener" href="https://note.com/npaka/n/nc930b61840ac">Web Workerの使い方</a><br /> - <code>requestAnimationFrame()</code> → 「60fps」 <a target="_blank" rel="nofollow noopener" href="https://www.webdesignleaves.com/pr/jquery/requestAnimationFrame.html">requestAnimationFrame の使い方</a><br /> etc...</p> <p>Mobile :arrow_down:<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/ea2d91d0-76be-ff81-0c8f-ee55669bf1e6.png" alt="Lighthouseモバイルのスコア" width="500" height=""><br /> Desktop :arrow_down:<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/23080b76-e970-9ecb-b92d-3f873b2878e7.png" alt="Lighthouseデスクトップのスコア" width="500" height=""></p> <h2 id="2-6. リリース後"><a href="#2-6.+%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E5%BE%8C">2-6. リリース後</a></h2> <p><strong>①掲載用スクリーンショット、画像作成</strong><br /> * figma制作<br /> * サイトにより、サイズ、比率、枚数、が異なる</p> <p><strong>②登録サイトに投稿/掲載依頼</strong><br /> 当たって砕けろ、チャレンジ精神で色々掲載依頼を出してみた結果です。<br /> <a target="_blank" rel="nofollow noopener" href="https://zenn.dev/yamatake/articles/b93d87ed134f31">個人開発者に告ぐ!「告知=恥ずかしい」を脱却しよう~実例データから重要性を解説</a></p> <p><strong><em>登録or掲載</em></strong> → 🎉<br /> メール・問い合わせ反応待ち → 📧<br /> 更新が止まっているサイトが多い</p> <p><strong>日本</strong><br /> - <a target="_blank" rel="nofollow noopener" href="https://app-liv.jp/5347459/"><strong><em>Appliv</em></strong></a> → 🎉 <strong><em>レビュー</em></strong>、とても丁寧な対応 :thumbsup:<br /> - <a target="_blank" rel="nofollow noopener" href="https://applion.jp/android/app/net.lisble.twa/"><strong><em>APPLION</em></strong></a> → 🎉 ランキング<br /> - <a target="_blank" rel="nofollow noopener" href="http://houkago-no.appspot.com/app_detail/6278466848686080"><strong><em>放課後アプリ部</em></strong></a> →🎉 登録<br /> - <a target="_blank" rel="nofollow noopener" href="https://applishow.com/detail/DsL3Q4b5hxxm/"><strong><em>Applishow</em></strong></a> → 🎉 登録<br /> - <a target="_blank" rel="nofollow noopener" href="https://www.approom.me/app/01H2J1N7SXF5JSH8ZMMDMGBF2V?platform_id=2"><strong><em>AppRoom</em></strong></a> → 🎉 登録 <a target="_blank" rel="nofollow noopener" href="https://www.approom.me/articles/01H2JGWJ3K3J72WVN7EJT5CKYD"><strong><em>アプリ記事掲載</em></strong></a><br /> - <a target="_blank" rel="nofollow noopener" href="https://seekups.seekgeeks.net/views/detail.html?id=712"><strong><em>SeekUps</em></strong></a> → 🎉 登録<br /> - <a target="_blank" rel="nofollow noopener" href="https://rrws.info/archives/3197"><strong><em>ロケットリリース</em></strong></a> → 🎉 登録<br /> - <a target="_blank" rel="nofollow noopener" href="https://appstimes.jp/posts/2991"><strong><em>Appstimes</em></strong></a> → 🎉 登録<br /> - <a target="_blank" rel="nofollow noopener" href="https://anymake.app/products/kAjQm0f6tswHGaKTd0G5"><strong><em>AnyMake</em></strong></a> → 🎉 登録<br /> - <a target="_blank" rel="nofollow noopener" href="https://www.makepost.net/projects/386"><strong><em>makepost</em></strong></a> → 🎉 登録<br /> - <a target="_blank" rel="nofollow noopener" href="https://www.mitsukarusite.jp/2023/06/550/"><strong><em>MITSUKARU!</em></strong></a> → 🎉 登録<br /> - <a target="_blank" rel="nofollow noopener" href="https://devhaunt.com/product/111"><strong><em>DevHaunt!</em></strong></a> →🎉 登録、とても丁寧な対応 👍<br /> - <a target="_blank" rel="nofollow noopener" href="https://kojin.dev/application/41"><strong><em>個人dev</em></strong></a> → 🎉 登録<br /> - <a target="_blank" rel="nofollow noopener" href="https://appget.com/c/developerpage/createdevpost/"><strong><em>アプリゲット</em></strong></a> → ゲームのみ<br /> - <a target="_blank" rel="nofollow noopener" href="https://www.appbank.net/"><strong><em>AppBank</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://applision.com/review/"><strong><em>Applision</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://tsukulog.work/"><strong><em>ツクログ</em></strong></a> → 📧 クリエイター登録済み、まだ作品は掲載されない(2度投稿)<br /> - <a target="_blank" rel="nofollow noopener" href="https://octoba.net/"><strong><em>octoba</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://newlaun-ch.com/"><strong><em>NewLaun-ch</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://appllio.com/"><strong><em>appllio</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://appnavi.info/"><strong><em>appnavi</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://androlion.org/"><strong><em>Androライオン</em></strong></a> → 📧条件:レビュー<br /> - <a target="_blank" rel="nofollow noopener" href="https://androrank.com/?m=send"><strong><em>AndroRank</em></strong></a> → 📧条件:レビュー<br /> - <a target="_blank" rel="nofollow noopener" href="https://android-apps.org/"><strong><em>Androidアップス</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://softcollection.org/android/"><strong><em>Androidコレクション</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://news.mynavi.jp/top/notice/press/"><strong><em>マイナビニュース</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://corp.itmedia.co.jp/pr/"><strong><em>ITmedia</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://corp.itmedia.co.jp/media/pr/"><strong><em>ITmedia ねとらぼ</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://androck.jp/contact/"><strong><em>AndRock</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="http://app-vip.jp/posts/add"><strong><em>AppVIP</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://applink.jp/request"><strong><em>AppLink</em></strong></a> → 📧<br /> - <a target="_blank" rel="nofollow noopener" href="https://www.gapsis.jp/"><strong><em>GAPSIS</em></strong></a> → 📧</p> <hr /> <p><strong>海外</strong></p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.producthunt.com/my/products"><strong><em>Product Hunt</em></strong></a> → 🎉 登録から1週間待つ必要がある</li> <li><a target="_blank" rel="nofollow noopener" href="https://alternativeto.net/software/shopping-list--lisble/about/"><strong><em>AlternativeTo</em></strong></a> → 🎉 登録</li> <li><a target="_blank" rel="nofollow noopener" href="https://appstoreapps.com/submit-your-app/"><strong><em>app store apps</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="https://www.appcraver.com/contact-us/"><strong><em>AppCraver</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="https://arstechnica.com/contact-us/"><strong><em>arttechnica</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="https://www.androidappsreview.com/submit-your-android-app/"><strong><em>Apps Review</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="https://androidcommunity.com/send-tips/"><strong><em>community</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="http://www.androidapplog.com/suggest-app/"><strong><em>App Log</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="https://getandroidstuff.com/submit-app/"><strong><em>Get Android Stuff</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="https://www.androidguys.com/request-app-review/"><strong><em>Android Guys</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="https://www.androlib.com/"><strong><em>androlib</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="https://www.apkmirror.com/"><strong><em>APKMirror</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="http://appscout.pcmag.com/"><strong><em>PCMag</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="https://www.newsreports.com/contact/"><strong><em>NEWSREPORTS</em></strong></a> → 📧</li> <li><a target="_blank" rel="nofollow noopener" href="https://www.ifanzine.com/contact/"><strong><em>iFanzine</em></strong></a> → 📧</li> </ul> <hr /> <p>※上記以外で無料で宣伝できるサイト、方法があれば教えていただけると嬉しいです。</p> <p><strong>③記事を書く</strong><br /> - Qiita<br /> - <a target="_blank" rel="nofollow noopener" href="https://qiita.com/arieight/items/7935afdaf78d31f8b444">【Nuxt3】はじめての個人開発「買い物リストアプリ」開発記録</a><br /> - Zenn<br /> - <a target="_blank" rel="nofollow noopener" href="https://zenn.dev/arieight/articles/55ec7a38edb940">Nuxt3で初めての個人開発記録【買い物リストアプリ】</a><br /> - Crieit<br /> - <a href="https://crieit.net/posts/Lisble-64bfaf0e5e2b7">シンプルな買い物リストアプリ「lisble リスブル 」の紹介</a><br /> - 【個人開発】アイデア出しから公開・プロモーションまでまとめ(Nuxt3、Cloudflare、GooglePlay)<br /> - note<br /> - <a target="_blank" rel="nofollow noopener" href="https://note.com/arieight/n/nc8cace276feb">値上げ対策! 買い物リスト作成で節約</a><br /> - <a target="_blank" rel="nofollow noopener" href="https://note.com/arieight/n/ne70e5e3865f3">シンプルな買い物リストアプリ「Lisble リスブル 」のご紹介</a><br /> - Medium(英語記事)<br /> - <a target="_blank" rel="nofollow noopener" href="https://medium.com/@arieight_8/price-increase-measures-save-money-by-making-a-shopping-list-120cec400b15">Price increase measures! Save money by making a shopping list</a></p> <p><strong>④Twitter(日本語/英語)</strong><br /> - Twitter日本語ver.:<a target="_blank" rel="nofollow noopener" href="https://twitter.com/arieight_8">@arieight_8</a><br /> - Twitter英語ver.:<a target="_blank" rel="nofollow noopener" href="https://twitter.com/Lisble_en">@Lisble_en</a><br /> - 登録or掲載 → つぶやく<br /> - 機能一覧、設定一覧、動画(gif)でツイート<br /> - 開発中からつぶやいた方が良い</p> <p><strong><em>参考サイト</em></strong><br /> <a target="_blank" rel="nofollow noopener" href="https://www.producthunt.com/posts/shopping-list-lisble">個人開発したWebサービスをリリースした後にやったこと / やり続けていること</a></p> <h1 id="3. 気付き・反省点・まとめ"><a href="#3.+%E6%B0%97%E4%BB%98%E3%81%8D%E3%83%BB%E5%8F%8D%E7%9C%81%E7%82%B9%E3%83%BB%E3%81%BE%E3%81%A8%E3%82%81">3. 気付き・反省点・まとめ</a></h1> <ul> <li>開発を0からして、初めてコードをさわって新しい概念にふれた時くらい勉強になり、とても知見が広がり良かったです。</li> <li>プログラミング以外の作業が初だったので「プログラミング:他 = 3:7」くらいの感覚でした。様々なデザインが予想より大変でした。</li> <li>一番面白いと感じた作業は、ロジックを考えて形になった時でした。<br />  </li> <li><strong>アイデア</strong> → 紙やXMindに思いつく限りまとめたのですが、総合的な判断で結局既存のサービスに追加機能の方向になってしまいました。マネタイズまで含めたアイデアが難しいです。どうせやるなら一通りやってみたかったので次回以降にしました。常にアンテナをはって知見を広げていいこうと思いました。</li> <li><strong>要件定義</strong> → 運用費がかからない、個人情報は扱わない、AdSense以外のマネタイズまで考える、などを考慮してアイデアを絞り、考え、すでにあるサービスと見比べ、アイデアと要件定義をぐるぐるしていました。</li> <li>AdSenseは、コンテンツ不足でwebアプリは受かりづらいらしいです。</li> <li><strong>利用技術</strong> → 平凡なアイデアだったので初めて挑戦する技術(Nuxt3、TypeScript、etc...)を使用してしまいました。</li> <li>デプロイ先など、お金をかけずに運用していくための他の効率の良い方法やサービスを引き続き調査していきます。(Firebaseをデータベース等)</li> <li><strong>設計</strong> → 画面デザインは、UI足したら引き算・データ設計は構造整理</li> <li><strong>開発</strong> → 追加の機能を制作してしまいました。最低限の機能でまず完成を目指すべき</li> <li><strong>工夫した機能</strong> → ToDoの変化型アプリで平凡なアプリで非常に多く数があるため、機能にこだわりました。</li> <li>多言語化して作業が増えた。[Amazon設定、時間形式、表示崩れ、metaタグ、etc...]</li> <li><strong>テスト</strong> → 多視点が重要</li> <li><strong>公開</strong> → 運用費をかけないにこだわる</li> <li><strong>パフォーマンス改善</strong> → 良い学習</li> <li><strong>マネタイズ</strong> → Amazonまでの導線が弱い 要検討</li> <li>著作権・プライバシーポリシー・DDoS対策etc...</li> <li><strong>プロモーション</strong> → Twitterは開発中から・アイデア段階でSNSを考慮したサービス・地道にor金をかけるか・個人の場合限られるので勉強段階からブログや記事など書いておけばまた違ったかも</li> <li>「告知=恥ずかしい」があったので、経験せずにはわからないからできることは全部しようと思いました。</li> </ul> <p>作る前に想像していたよりコード以外の作業が多いとうことに改めて気付かされました。<br /> 制作中、何度も宇宙兄弟のセリフが脳内再生してました。ありがとうございました。</p> <hr /> <blockquote> <p>「また積めばいいよ」<br /> 「次はもっと上手く積めるようになってるよ」<br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/54752648-2273-f10c-d125-ea6abc68e562.jpeg" alt="『宇宙兄弟』17巻 小山 宙哉「また積めばいいよ」" width="300"><br /> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/9d577b8b-90ef-2e69-8d2b-2e67ebfb9794.jpeg" alt="『宇宙兄弟』17巻 小山 宙哉「次はもっと上手く積めるようになってるよ」" width="300"><br /> 出典: 『宇宙兄弟』17巻 小山 宙哉(講談社、2012年3月23日第1発行)</p> </blockquote> <hr /> <p>購入履歴が残せるシンプルな買い物リストアプリ <strong><em>『買い物リスト - Lisble リスブル』</em></strong> です。メモ、ToDoアプリとしても機能します。<br /> 購入履歴の保存機能により、無駄な重複購入を防ぎ、在庫の備忘録にもなります。<br /> ログイン・ユーザー登録不要、無料ですぐにご利用いただけます。<br /> もしよかったら、触ってみてください。</p> <p><strong>『<a target="_blank" rel="nofollow noopener" href="https://lisble.net/about/">買い物リスト・メモ - Lisble リスブル</a>』</strong><br /> <div class="table-responsive"><table> <thead> <tr> <th>iOS,PC</th> <th>Android</th> </tr> </thead> <tbody> <tr> <td><a src="https://lisble.net/about/" target="_blank" rel="noopener noreferrer" ><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/992c120a-33bd-48d1-93cd-d97fde42d22c.png" alt="シンプルな買い物リスト-lisble リスブル" width="250"></a></td> <td><a src="https://play.google.com/store/apps/details?id=net.lisble.twa" target="_blank" rel="noopener noreferrer" ><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906025/f92cdde6-21d1-2d3f-b8bf-9fb72a74abde.png" width=230 alt="googlePlayバッジ" ></a></td> </tr> <tr> <td>iOS,PCの方は、PWAの為、メニューから <strong>「ホーム画面に追加」</strong> をお願いします。</td> <td>このアプリは Google Play で入手できます。</td> </tr> </tbody> </table></div></p> <p>Twitter:<a target="_blank" rel="nofollow noopener" href="https://twitter.com/arieight_8">@arieight_8</a></p> <hr /> <p>Google Play および Google Play ロゴは、Google LLC の商標です。</p> Arieight tag:crieit.net,2005:PublicArticle/15775 2020-03-20T13:51:56+09:00 2020-03-22T06:54:01+09:00 https://crieit.net/posts/Nuxt-5-Firebase-GAE-Netlify-Heroku Nuxtアプリを無料で公開するときに試した5つの環境まとめ(Firebase/GAE/Netlify/Heroku) <p>最近Nuxtでいろいろ作っているけど、無料で使える環境をいろいろ試してる。<br /> いろいろメリデメあるけど、SPAならNetlify/SSRならHerokuがよさそう。<br /> いままで試したものをまとめてみた。</p> <h3 id="ほしかったもの"><a href="#%E3%81%BB%E3%81%97%E3%81%8B%E3%81%A3%E3%81%9F%E3%82%82%E3%81%AE">ほしかったもの</a></h3> <p>主に開発してるのが<a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">CGM系のWebサービス</a>なので、</p> <ol> <li>動的なOGP画像などが設定できる(OGP芸)</li> <li>カスタムドメインが使える</li> <li>日次のランキング集計などの定期実行ができる</li> </ol> <p>が、無料でできて、なるべく実装が楽で、そこまで遅くないのがうれしい。</p> <h3 id="試した5つのパターン"><a href="#%E8%A9%A6%E3%81%97%E3%81%9F5%E3%81%A4%E3%81%AE%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3">試した5つのパターン</a></h3> <p>試したのは以下の5パターン。試してみた順で記載。</p> <ol> <li>Nuxt(SSR) + Cloud Function<br /> 起動がかなり遅かった。。実装も大変なのでNG</li> <li>Nuxt(SPA) + Firebase Hosting<br /> 構築はかなり楽。ただ、OGP芸が大変でFunctionsが必要</li> <li>Nuxt(SPA) + Netlify<br /> プレレンダリングでOGP芸が楽。定期実行はFunctionsでできる</li> <li>Nuxt(SSR) + GAE(f1:256M)<br /> メモリの制限きつく、たまに落ちる。。定期実行はcron.yamlでできる</li> <li>Nuxt(SSR) + Heroku(free:512M) + Cloudflare<br /> メモリ多くてよい。SSLはないのでCloudflareを併用。定期実行はHeroku Scheduler</li> </ol> <p>SPAで十分であれば、「3.Nuxt(SPA) + Netlify」が構築も簡単で良かった。<br /> <a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>は、現在この構成。</p> <p>SSRの場合、「5. Nuxt(SSR) + Heroku(free:512M) + CloudFlare」が良い感じ。<br /> <a target="_blank" rel="nofollow noopener" href="https://hen-ai.net/">へんあいマップ</a>がこの構成。</p> <h3 id="各パターンについて"><a href="#%E5%90%84%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">各パターンについて</a></h3> <h4 id="1. Nuxt(SSR) + Cloud Function"><a href="#1.+Nuxt%28SSR%29+%2B+Cloud+Function">1. Nuxt(SSR) + Cloud Function</a></h4> <p>一番はじめに<a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>でやろうとした構成。</p> <p><img width="870" alt="スクリーンショット 2020-03-20 11.43.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/7fa5a956-cec1-9117-1d5d-f769eae53a32.png"></p> <p>細かいやり方は、以下の記事の「Firebase Cloud Functionsの設定してSSRできるようにする」あたりに。<br /> ・<a target="_blank" rel="nofollow noopener" href="https://www.memory-lovers.blog/entry/2019/04/02/115149">Nuxt.jsではじめるときのやることリスト(SSRも国際化も自動デプロイも) - くらげになりたい。</a></p> <p>当時は動的ページのSEO対応するには、この方法が多く検索に出ていたので試したけど、<br /> Cloud Functionのコールドスタートがつらすぎてお蔵入り。。SPAでいくことに。。</p> <h4 id="2. Nuxt(SPA) + Firebase Hosting"><a href="#2.+Nuxt%28SPA%29+%2B+Firebase+Hosting">2. Nuxt(SPA) + Firebase Hosting</a></h4> <p><a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>をリリースしたときの構成。</p> <p><img width="910" alt="スクリーンショット 2020-03-20 11.37.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/37459683-872a-5047-a383-71c33f0c640e.png"></p> <p>課題だった動的ページのSEOは、Cloud Functionsを経由して返す方法で対応。<br /> こちらも当時よく検索に出てたけど、実装が大変そうだったので2番手に。</p> <p>細かいやり方は、以下の記事に。(2020/03/22追記: OGP画像生成系の記事を追加)<br /> ・<a target="_blank" rel="nofollow noopener" href="https://www.memory-lovers.blog/entry/2019/08/07/150000">Nuxt(SPA)+FirebaseでSEO!OGP!: 特定のパスだけheadだけ返すやつ - くらげになりたい。</a><br /> ・<a target="_blank" rel="nofollow noopener" href="https://qiita.com/kira_puka/items/8c1d1240c3aa200cbec0">Nuxt.js(SPA)+Firebaseで積読用の読書管理サービスを作ってみたときにハマったこと - Qiita</a><br /> ・<a target="_blank" rel="nofollow noopener" href="https://www.memory-lovers.blog/entry/2019/06/26/194500">Cloud Functions + ImageMagickでOPG画像の動的生成してCloud Storageにアップロードする - くらげになりたい。</a><br /> ・<a target="_blank" rel="nofollow noopener" href="https://www.memory-lovers.blog/entry/2020/02/19/150000">Cloud FunctionとSVGでOGP画像生成を試行錯誤したまとめ - くらげになりたい。</a></p> <p>カスタムドメインについては、Firebase HostingでSSLと合わせて無料で設定可能。</p> <p>定期実行は、Cloud Functionsでできるのでそれを利用した。<br /> ・<a target="_blank" rel="nofollow noopener" href="https://firebase.google.com/docs/functions/schedule-functions?hl=ja">関数のスケジュール設定  |  Firebase</a><br /> ・<a target="_blank" rel="nofollow noopener" href="https://qiita.com/kira_puka/items/1f164dd8d1a5a281d9c1">Cloud Functions for Firebaseのcronみたいな定期実行を試したら簡単だった - Qiita</a></p> <p>ただ、Cloud Functionsの定期実行は、<br /> 「<strong>Googleアカウントごとに3つのジョブ</strong>を無料で使用できる」<br /> なので、注意が必要。<strong>プロジェクトごとじゃない</strong>。。</p> <h4 id="3. Nuxt(SPA) + Netlify"><a href="#3.+Nuxt%28SPA%29+%2B+Netlify">3. Nuxt(SPA) + Netlify</a></h4> <p><a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>の現在の構成。</p> <p><img width="775" alt="スクリーンショット 2020-03-20 11.47.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/5010c13a-98a9-c9e0-ae3b-767d18cd8006.png"></p> <p><a target="_blank" rel="nofollow noopener" href="https://docs.netlify.com/site-deploys/post-processing/prerendering/#set-up-prerendering">NetlifyのPrerendering</a>が無料化されて使えるようになり、よいという話を聞くように。。</p> <p>実装が複雑で、変更もしにくかったので、この方法に。<br /> Netlify自体がCDNも提供していているので、すこしはやくなった(気がする)</p> <p>カスタムドメインも、NetlifyのDNSを設定して無料で対応できる。</p> <p>定期実行は、2.と同じ感じで、Cloud Functionsのまま。</p> <p>コード量も減って変更もしやすくなったので、OGP画像の改善とかが楽にできるように。。(<em>´ω`</em>)</p> <h4 id="4. Nuxt(SSR) + GAE(f1:256M)"><a href="#4.+Nuxt%28SSR%29+%2B+GAE%28f1%3A256M%29">4. Nuxt(SSR) + GAE(f1:256M)</a></h4> <p>SPAの課題として、初期表示が遅いのでなんとかしたいなと、SSRの環境を模索しはじめ。。<br /> 公開していないけど、1つ作ってみた。</p> <p><img width="798" alt="スクリーンショット 2020-03-20 13.17.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/c24ce0b2-64b3-1ea4-9bd2-e2150ba13d14.png"></p> <p>試してみたところ、起動するだけでメモリ上限すれすれで、複数アクセスがあったりすると、落ちる場合も。。<br /> (ts-nodeで動かしているのも悪い気がしている。。)</p> <p><img width="561" alt="スクリーンショット 2020-03-20 12.22.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/e3940627-4141-4c17-3c82-b2ee13ca1e14.png"></p> <p>ただ、定期実行はcron.yamlを用意すればURLに送信でき、無料範囲も広い。<br /> 料金も「<a target="_blank" rel="nofollow noopener" href="https://cloud.google.com/appengine/pricing?hl=ja#%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AE%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9">その他のリソース</a>」をみるとcronは無料のよう。<br /> ・<a target="_blank" rel="nofollow noopener" href="https://cloud.google.com/appengine/docs/flexible/nodejs/scheduling-jobs-with-cron-yaml?hl=ja">cron.yaml を使用したジョブのスケジューリング</a></p> <p>カスタムドメインやSSLも無料で利用できる感じ。(試してないので未確認)</p> <h4 id="5. Nuxt(SSR) + Heroku(free:512M) + Cloudflare"><a href="#5.+Nuxt%28SSR%29+%2B+Heroku%28free%3A512M%29+%2B+Cloudflare">5. Nuxt(SSR) + Heroku(free:512M) + Cloudflare</a></h4> <p>GAEでうまくいかなかったので、無料でメモリも多いHerokuを利用。<br /> <a target="_blank" rel="nofollow noopener" href="https://hen-ai.net/">へんあいマップ</a>がこの構成で稼働中。</p> <p><img width="885" alt="スクリーンショット 2020-03-20 13.24.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/60f2ab5c-3f4a-9b4b-ac45-341ed99c4667.png"></p> <p>定期実行は無料のアドオン(<a target="_blank" rel="nofollow noopener" href="https://elements.heroku.com/addons/scheduler">Heroku Scheduler</a>)が利用できる。<br /> Nuxt側で<a target="_blank" rel="nofollow noopener" href="https://ja.nuxtjs.org/api/configuration-servermiddleware/">serverMiddleware</a>を用意すればOK。</p> <p>ただ、メモリは多く定期実行もが、Herokuの無料枠だと制限も多い。</p> <ol> <li>SSLは非対応</li> <li>30分アクセスがないとスリープする</li> <li>クレジットカードの登録で1000時間/月xアカウント<br /> (未認証だと550時間/月xアカウント)</li> </ol> <h5 id="1. SSLは非対応"><a href="#1.+SSL%E3%81%AF%E9%9D%9E%E5%AF%BE%E5%BF%9C">1. SSLは非対応</a></h5> <p>単体だけだとSSLに対応していないので、<a target="_blank" rel="nofollow noopener" href="https://www.cloudflare.com/ja-jp/">Cloudflare</a>を併用。<br /> CloudflareがCDNも提供してくれるので良い感じに。</p> <h5 id="2. 30分アクセスがないとスリープする"><a href="#2.+30%E5%88%86%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%8C%E3%81%AA%E3%81%84%E3%81%A8%E3%82%B9%E3%83%AA%E3%83%BC%E3%83%97%E3%81%99%E3%82%8B">2. 30分アクセスがないとスリープする</a></h5> <p>これは、Heroku Schedulerを使えばOK。<br /> 任意のURLを叩けるため、15分毎などスリープしないようにしておく。</p> <h5 id="3. 無料枠は1000時間/月xアカウント"><a href="#3.+%E7%84%A1%E6%96%99%E6%9E%A0%E3%81%AF1000%E6%99%82%E9%96%93%2F%E6%9C%88x%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88">3. 無料枠は1000時間/月xアカウント</a></h5> <p>1000時間あれば、24時間x31日でも744時間なので、大丈夫な感じ。<br /> ただ、アカウント単位での無料枠なので、複数アプリを無料で稼働はできない。。</p> <h5 id="実際のやりかたとかは、"><a href="#%E5%AE%9F%E9%9A%9B%E3%81%AE%E3%82%84%E3%82%8A%E3%81%8B%E3%81%9F%E3%81%A8%E3%81%8B%E3%81%AF%E3%80%81">実際のやりかたとかは、</a></h5> <p>以下の記事に。<br /> ・<a target="_blank" rel="nofollow noopener" href="https://www.memory-lovers.blog/entry/2020/01/25/120000">Heroku+CloudflareなNuxtでSSRしてみる - くらげになりたい。</a></p> <h3 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h3> <p>いろいろ試してみたけど、Nuxt.jsを無料で公開するときは、</p> <ul> <li>SPAならNetlify <ul> <li>prerenderingで動的ページのSEOも対応</li> <li>カスタムドメインやSSLもNetlifyでOK</li> <li>定期実行はCloud Functionsで。</li> <li>ただし、定期実行は1アカウントにつき、3ジョブまで</li> </ul></li> <li>SSRならHeroku <ul> <li>SSRで動的ページのSEOも対応</li> <li>定期実行はHeroku Schedulerで</li> <li>Cloudflareを併用し、SSL対応</li> <li>無料枠は1アカウントにつき、1アプリが限界かも</li> </ul></li> </ul> <p>SSRの方は他に<a target="_blank" rel="nofollow noopener" href="https://cloud.google.com/run?hl=ja">Cloud Run</a>や<a target="_blank" rel="nofollow noopener" href="https://zeit.co/">ZEIT now</a>がある。<br /> Cloud Runは立ち上げがGAEより遅いときので後手だけど、<br /> ZEIT nowは気になってるので試してみたい(<em>´ω`</em>)</p> <p>以上!!</p> <h2 id="こんなのつくってます!!"><a href="#%E3%81%93%E3%82%93%E3%81%AA%E3%81%AE%E3%81%A4%E3%81%8F%E3%81%A3%E3%81%A6%E3%81%BE%E3%81%99%21%21">こんなのつくってます!!</a></h2> <p>積読用の読書管理アプリ 『積読ハウマッチ』をリリースしました!<br /> <a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>は、Nuxt.js+Firebaseで開発してます!</p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="200"/></p> <p>もしよかったら、遊んでみてくださいヽ(=´▽`=)ノ</p> <p>要望・感想・アドバイスなどあれば、<br /> 公式アカウント(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/MemoryLoverz">@MemoryLoverz</a>)や開発者(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/kira_puka">@kira_puka</a>)まで!</p> <h3 id="へんあいマップもリリースしました!"><a href="#%E3%81%B8%E3%82%93%E3%81%82%E3%81%84%E3%83%9E%E3%83%83%E3%83%97%E3%82%82%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%EF%BC%81">へんあいマップもリリースしました!</a></h3> <p>「偏愛マップ」を簡単に作れるWebアプリです!<br /> <a target="_blank" rel="nofollow noopener" href="https://hen-ai.net">へんあいマップ</a>も、Nuxt.js+Firebaseで開発してます!</p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/63686f5c-390b-0b09-3f9a-0ce6676c3cce.png" width="600"/></p> <p>偏愛マップは人見知りや口下手な人にも優しいコミュニケーションツールで、<br /> 勉強会、懇親会、オフ会などの余興・アイスブレイクや自分のプロフィールにも!</p> <p>よかったら遊んでみてください(<em>´ω`</em>)</p> きらぷか@積読ハウマッチ/SSSAPIなど tag:crieit.net,2005:PublicArticle/15520 2019-10-31T08:02:18+09:00 2020-02-06T11:44:52+09:00 https://crieit.net/posts/WEB-Heroku-Laravel-MySQL-SSL 全部無料でWebサービスを公開しよう!(Heroku + Laravel + MySQL + 独自ドメイン + SSL) <p><a href="https://crieit.net/posts/5-5d9c0ecabe849">サービスリリースしました(=゚-゚)ノ 週休5日のプログラマーは快適という話。</a><br /> 上記で紹介した、Webサービス、<a target="_blank" rel="nofollow noopener" href="https://www.myfavrecipe.ml/">My Favorite Recipe</a> の公開の手順を記事にしました。</p> <p>◼️はじめに (。・ω・。)</p> <p>私は初心者です。</p> <p>IT資格はわりと持っていますが、そんなの関係ありません。実務はほぼVBとVB.NETとVBAしかやってません。SQLもちょっとだけ。</p> <p>WEB系は設計書レビューした程度です。テスト設計ならもうイヤという程にはやりました。</p> <p>言い訳はこのくらいにして。</p> <p>◼️作ったサービスを(気軽に)公開できる場所</p> <p>LaravelでWEBサービスを作ってはみたものの、さてどこで公開するか?</p> <p>ということで、試しにHerokuというもの?を使ってみることにしました。</p> <p>私の事前知識は、Herokuって文字見たことあるけどなんて読むんだろう?まさかヘロクじゃないよね?程度です。(そのまさかの、"ヘロク"でした)</p> <p>◼️無料万歳 v(。・ω・。)v</p> <p>以下、すべて無料で揃いました。v(。・ω・。)v</p> <p>・Heroku + Laravel + MySQL</p> <p>・ドメイン取得は、Freenomを利用。</p> <p>・SSL(https)は、Cloudflare を利用。</p> <p>利用規約とか説明のための静的サイトは、Firebaseのhostingを使っています。</p> <p>html/cssテンプレートはf-tpl.comです。これらもすべて無料です。</p> <p>英語が読めなくても意味がわからなくても、無料ならとりあえず使ってみるの精神で挑戦しました。</p> <p>◼️事前に用意するもの</p> <p>・Laravel + MySQL で何か作る</p> <p>ちなみに「SQLite」もHerokuで使えます。</p> <p>◼️手順と参考にしたサイト</p> <p>検索したら、Heroku+Railsの記事が多かったです。<br /> Laravelでも(一部以外は)参考になるので活用しましょう。</p> <p>・Herokuにアカウント登録して、がんばる o(。・ω・。)o</p> <p><a target="_blank" rel="nofollow noopener" href="http://sizukutamago.hatenablog.com/entry/2016/10/21/heroku%E3%81%ABlaravel5%E3%81%A8Mysql%E3%81%AE%E7%92%B0%E5%A2%83%E3%82%92%E6%95%B4%E3%81%88%E3%82%8B">herokuにlaravel5とMysqlの環境を整える</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/tamappe/items/a175596e9aec725e1d2d">Laravelをherokuにデプロイする(データベースはMySQL)</a></p> <p>・独自ドメイン取得して、</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.freenom.com/ja/index.html">Freenom</a></p> <p>「Freenom 使い方」でGoogle検索すると使い方載ってるサイトが見つかると思います!</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/kenjikatooo/items/07c3d911210a4ca96781">初めてHerokuで独自ドメインを公開するあなたへ</a></p> <p>・httpsで接続できるようにがんばる o(。・ω・。)o</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/serinuntius/items/f7f08b2221f5ad068f5d">【完全無料】Herokuで独自ドメイン + HTTPSに対応する【Rails】</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/ai_qiita/items/0e334606709fb9deae87">【無料】Cloudflareを使ってHerokuで独自ドメインで運用する方法</a></p> <p>・MySQLを直で使いたいとき(自分のPCのMySQLの入っている環境でコマンドを実行しましょう)</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/akiko-pusu/items/305e291465d6aac04bf3">HerokuのDBにローカルPCからアクセスしたいんだけど...</a></p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/tocomi/items/0c009d7299584df49378">MySQL Serverに外部から接続する</a></p> <p>・Herokuはアクセスしないと寝てしまうみたいなので対策</p> <p><a target="_blank" rel="nofollow noopener" href="https://casualdevelopers.com/tech-tips/how-to-prevent-idling-of-free-dyno-on-heroku/"> Herokuの無料dynoをスリープさせないで24時間稼働させる4つの方法</a></p> <p>・おまけ (。・ω・。)</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yacchi1123/items/963bdf12c9c4a7a8f67c">Firebaseを使って独自ドメインWebサイトを公開する方法</a></p> <p>◼️メモ書き程度の記録(役に立つかわかりませんが私のブログです)<br /> <a target="_blank" rel="nofollow noopener" href="http://marimoko3.hatenablog.com/">blog</a></p> <p>◼️ちなみに</p> <p>現在私は、MacでVagrant環境(CentOS)で開発しています。<br /> CyberduckでファイルをMacローカルにコピーして、それをGitHubに上げて、それをHerokuの管理画面でポチッとDeployしています。</p> <p>最初はコンソールからHeroku (Heroku Git) に上げていました(どっちでもいいのですが)。</p> <p>◼️よくわからないこと</p> <p>Vagrant環境でLaravelプロジェクトを作って、初回リリースは最初はLaravelプロジェクトを丸ごと載せてしまえばいいので問題ないのですが、<br /> 機能追加で、composer等で何か変更を加えた時に、何が変わったのかわからないと、本番環境に何を適用させたらいいのわからない、ということが起こります。</p> <p>composer、今何してるの?っていう(便利だけど何がどこに入ったのかわからない)。<br /> 新しいパッケージを入れて使うなどの場合も、本番環境への反映のさせ方がわかりません。<br /> プロジェクトフォルダを丸ごと更新するという技(?)で、ひとまず対応できますが・・・。</p> <p>◼️おわりに</p> <p>手順を全部書くと終わらないのでリンクで済ませてしまいましたが、何かあればココのコメントなどで聞いていただければ、だれかが答えてくれるかもしれません!? o(。・ω・。)o 応援してます!気が向いたらやってみてネ o(。・ω・。)o </p> Hata tag:crieit.net,2005:PublicArticle/14854 2019-03-04T07:21:16+09:00 2020-10-11T09:37:18+09:00 https://crieit.net/posts/Crieit-5c7c535c6fca2 Crieitの記事詳細ページが日本の技術系投稿サービスで最速になった <p>Crieitの記事詳細ページのレスポンスがdev.toのような速さになりました。実際にはdev.toよりも速いです。技術記事系サービスとしてはQiita等を含めて日本一となります。</p> <p>この画像は各サービスの記事ページのレスポンスにかかった時間を比較したものになります。タイミングによってばらつきもあるため速いものをメモしてみましたが、国内のQiitaやQrunchは170ミリ秒ほど、爆速で話題になったdev.toも意外にも30ミリ秒ほどで、平均だともうちょっと遅い感じがします。そしてCrieitは15ミリ秒くらいなのでダントツで最速です。</p> <p><a href="https://crieit.now.sh/upload_images/01b220b58fd2f913ea6f07542d8741565c7bfe868fd02.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/01b220b58fd2f913ea6f07542d8741565c7bfe868fd02.png?mw=700" alt="" /></a></p> <p>確認方法としては、トップページから記事ページのリンクをクリックするか、記事ページでリロードするかが分かりやすいと思います。</p> <p>追記)<br /> 現在はZennがZennページ同じ速さになったので恐らく総合的に最速だと思います。Next.jsのキャッシュコントロールにまだ不足点がありますので、そちらがコントロールできるような実装がされると完璧になるでしょう。</p> <h2 id="なぜ速いのか"><a href="#%E3%81%AA%E3%81%9C%E9%80%9F%E3%81%84%E3%81%AE%E3%81%8B">なぜ速いのか</a></h2> <p>理由としては、Laravel側で動的にレンダリングしたHTMLをCloudflareというCDNでキャッシュしてもらっているため、サイトを閲覧している人のブラウザではそれが表示されているだけだからです。つまり、プログラム無しの単なるhtmlファイルを読み込んでいるのと同じレベルということです。実際に阿部 寛のホームページも大体17ミリ秒という感じで同じくらいの速さです。</p> <p>最近Gatsbyという静的サイトジェネレータが流行っています。これもコンテンツを事前にビルドし、サイト上では静的なファイルを表示するだけのため最速でコンテンツを届けることができるのですが、つまりはこれと全く同じレベルということです。しかもCloudflareのようなCDNは閲覧者の近くのサーバーから配信を行うため、ネットワークのレイテンシも非常に少なくあっという間にブラウザに表示されます。なので、速いのは何もすごくはなく、当たり前といえば当たり前のことです。</p> <p>mizchiさんもブログで仰っていました。</p> <blockquote> <p>フロントエンドの最適化の行き着く先の解の一つ、それは「CDN Edge で HTML をキャッシュして返却する」というものです。</p> </blockquote> <p><a target="_blank" rel="nofollow noopener" href="https://mizchi.hatenablog.com/entry/2019/02/21/235403">Edge Worker PaaS の fly.io が面白い - mizchi's blog</a></p> <h2 id="完璧なのか"><a href="#%E5%AE%8C%E7%92%A7%E3%81%AA%E3%81%AE%E3%81%8B">完璧なのか</a></h2> <p>全然完璧ではありません。そもそも現在記事ページしか対応していないので、他のページは今までどおりです。</p> <p>さらには、各ページには一度誰かがアクセスしなければならないので、投稿後や編集後に限っては今までどおりですし、普段誰もアクセスしない記事などはキャッシュされていないので最初に誰かがアクセスした時に重さを味わってもらわなければなりません。具体的にはChromeのDev Tools等で見ると下記のようにHITというレスポンスになっていればキャッシュが効いている状態です。(MISSになっている場合はリロードするとその後はHITになります)</p> <p><a href="https://crieit.now.sh/upload_images/baf891a4cf72ecfd1374559401f2af6b5c794c55ab21b.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/baf891a4cf72ecfd1374559401f2af6b5c794c55ab21b.png?mw=700" alt="" /></a></p> <p>あと僕自身の理解も完璧とは言えないので、何かしら勘違いしている可能性もあります。一度でもbotがアクセスされればキャッシュされるという認識ですが、適当な記事にアクセスしてみると意外にキャッシュされていないことが多いです。まだリリースして間もない時期ということもあり不明点や十分な確認ができていない部分も多いため、このあたりは引き続き要確認です。</p> <p>ということで記事タイトルも文字数を気にしなければ「Crieitの記事詳細ページのHTML取得レスポンスはCDNのキャッシュが効いているページに限っては日本の技術系投稿サービスで最速になったが効いてなければすごく遅い」が正確です。</p> <h2 id="GatsbyやHugoとの違い"><a href="#Gatsby%E3%82%84Hugo%E3%81%A8%E3%81%AE%E9%81%95%E3%81%84">GatsbyやHugoとの違い</a></h2> <p>最近流行っているGatsbyやHugoを使えばよいのでは、と思うかもしれませんが、これらは事前にビルドが必要なため、Crieitのようなユーザー投稿型のサービスで利用することはできません。(何か方法があるのかもしれませんが、どちらにしろリアルタイムで反映していくのは難しそうな気がします)</p> <p>そのためサーバーサイドでレンダリングしたものをそのままキャッシュしてもらうのが現実的な気がします。ビルドも不要です。</p> <h2 id="どんなメリットがあるのか"><a href="#%E3%81%A9%E3%82%93%E3%81%AA%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88%E3%81%8C%E3%81%82%E3%82%8B%E3%81%AE%E3%81%8B">どんなメリットがあるのか</a></h2> <h3 id="速い事自体が良い"><a href="#%E9%80%9F%E3%81%84%E4%BA%8B%E8%87%AA%E4%BD%93%E3%81%8C%E8%89%AF%E3%81%84">速い事自体が良い</a></h3> <p>とにかく速い事自体がメリットです。遅いとやはりイライラしますし、検索エンジン的にも速ければ速いほど良いと思います。そしてアクセスした時の気持ちよさも大きいです。</p> <h3 id="サーバーの負荷もない"><a href="#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%B2%A0%E8%8D%B7%E3%82%82%E3%81%AA%E3%81%84">サーバーの負荷もない</a></h3> <p>CDN側で配信してくれるため、サーバーへのアクセスが来ません。そのためサーバーの負荷を抑えることができるようになります。実際にこのサーバーはGoogle Compute Engineの一番しょぼいサーバーで無料運用しているレベルのため、パフォーマンスも悪いしアメリカのリージョンのためレイテンシも大きいです。大体普通にアクセスすると1秒くらいかかってしまいます。(なので、dev.toは当然として、QiitaやQrunchも非常に高速という印象です)</p> <p>まあそれはそれほどの問題にはならないのですが、記事や投稿が増えてそれに伴ってページが増えていくと、サイトを勝手に巡回するよくわからないbotのアクセスもどんどん増えていってしまいます。普通に閲覧してくれるユーザーさんのアクセスだけだと全く問題にはならないのですが、そういうbotのアクセスまで含めてしまうと結構限界が来るのも早くなってしまうのではないかと思います。</p> <p>ですのでbotは全部もううちのサーバーに一切来なくなってほしいという思いからも対応を決意しました。</p> <h2 id="具体的にどうやったのか"><a href="#%E5%85%B7%E4%BD%93%E7%9A%84%E3%81%AB%E3%81%A9%E3%81%86%E3%82%84%E3%81%A3%E3%81%9F%E3%81%AE%E3%81%8B">具体的にどうやったのか</a></h2> <h3 id="そもそもCloudflareとは"><a href="#%E3%81%9D%E3%82%82%E3%81%9D%E3%82%82Cloudflare%E3%81%A8%E3%81%AF">そもそもCloudflareとは</a></h3> <p>CDNというのは各サービスの静的コンテンツをキャッシュし、それを世界中に張り巡らされた配信ネットワークを利用して、最も近い拠点から配信してくれる、というものすごい仕組みです。</p> <p>例えばCloudflareではデフォルトではjs, css, 画像を配信してくれます。jsファイルやcssファイルは最近はビルドされていて数MBになっていることもあるため、サーバー上から配信するとかなり遅かったりします。うちでも初期はダウンロードに数秒かかっていました。CDNを通して配信すると一瞬で配信できるため、そもそもCloudflareがないと成り立たないレベルになっています。</p> <p>デフォルトでは上記のファイルしか配信されないのですが、Page rulesを設定すると他のパターンでも配信できるようになります。それを用いて記事のURLのパターンを設定し、配信されるようにしました。</p> <h3 id="ヘッダーの調整が必要"><a href="#%E3%83%98%E3%83%83%E3%83%80%E3%83%BC%E3%81%AE%E8%AA%BF%E6%95%B4%E3%81%8C%E5%BF%85%E8%A6%81">ヘッダーの調整が必要</a></h3> <p>しかし、ただPage rulesを設定してもキャッシュされません。というのもCloudflareはページのレスポンスヘッダの内容を見てキャッシュするかどうかを判断してくれます。キャッシュ期間を定めていればその期間でキャッシュを破棄して再度更新されるようにすることができますし、そもそも個人情報などを含んでいてキャッシュしてはならないページなどはキャッシュしないようになっています。</p> <p>例えばLaravelとかであればデフォルトで全てキャッシュを無効化するレスポンスヘッダが含まれていますので、一切キャッシュされません。そのため、Middlewareやルーティングを設定してキャッシュを許可するためのレスポンスヘッダを返す必要があります。</p> <p>具体的にはCache-Controlヘッダで下記を返すようにします。CDN用のMiddlewareグループを作成し、それ用のルーティングファイルにルーティングを記述するようにしています。ヘッダだけでなく、安全のためセッションも無効にしています。</p> <h4 id="public"><a href="#public">public</a></h4> <p>好き勝手にキャッシュしていいよ、というやつです。</p> <h4 id="s-maxage"><a href="#s-maxage">s-maxage</a></h4> <p>CDN向けのキャッシュ時間です。とにかく大きくして永久にキャッシュしてもらうようにしました。(実際にされているかどうかは検証できていませんが)</p> <h4 id="max-age"><a href="#max-age">max-age</a></h4> <p>ブラウザ向けのキャッシュ時間です。s-maxageを指定していない場合はCDNのキャッシュ時間にも用いられます。これは長くしすぎるとCDN側のキャッシュが切れたことに気づくことができませんので、短めにしています。ブラウザキャッシュが切れてもCDNのキャッシュを取ってくるだけなので、問題はありません。</p> <h4 id="Set-Cookieヘッダを送信しない"><a href="#Set-Cookie%E3%83%98%E3%83%83%E3%83%80%E3%82%92%E9%80%81%E4%BF%A1%E3%81%97%E3%81%AA%E3%81%84">Set-Cookieヘッダを送信しない</a></h4> <p>Set-Cookieをレスポンスで返すと個人情報が含まれている可能性があると判断されるようでキャッシュが行われませんので送信しないようにします。</p> <p>Laravelであればこのヘッダを無効にするためのミドルウェアを追加します。ただ、webのルーティングでこのミドルウェアだけ追加しても動作しないようなので、別途CDN用のミドルウェアグループを作ると良いと思います。</p> <h3 id="キャッシュのpurgeが必要"><a href="#%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%81%AEpurge%E3%81%8C%E5%BF%85%E8%A6%81">キャッシュのpurgeが必要</a></h3> <p>このままだと永久にキャッシュされてしまい、記事を更新しても反映されなくなってしまいます。そのため、キャッシュを破棄する必要があります。</p> <p>Cloudflareの管理画面で可能ですが、APIも用意されているためそれを用います。</p> <p><a href="https://crieit.net/posts/PHP-Cloudflare-API">PHPでCloudflareのAPI経由でキャッシュを削除する</a></p> <p>これで記事が更新された時にキャッシュをpurgeするようにしました。今のところは上手くいっている気がします。</p> <h3 id="ログイン状態をどう管理するか"><a href="#%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E7%8A%B6%E6%85%8B%E3%82%92%E3%81%A9%E3%81%86%E7%AE%A1%E7%90%86%E3%81%99%E3%82%8B%E3%81%8B">ログイン状態をどう管理するか</a></h3> <p>静的にキャッシュしてしまっているため、サーバーサイドのテンプレート上でログインしている場合だけこれを表示、みたいなことはできなくなります。そのため、VuexのStoreにログインしている状態を保持しておき、ページが表示されたあとに必要なところだけ置き換えるようにしました。</p> <p>置き換えると言っても単にVueコンポーネント化しておき、Storeの情報によって表示を切り替えているだけです。</p> <h3 id="リアルタイムのデータをどうするか"><a href="#%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%BF%E3%82%A4%E3%83%A0%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E3%81%A9%E3%81%86%E3%81%99%E3%82%8B%E3%81%8B">リアルタイムのデータをどうするか</a></h3> <p>リアルタイムのデータというのは、例えばキャッシュはできないけど表示が必要なコメントやアクセス数などです。これらはページが表示されたあと、ajaxで取って来ています。つまりキャッシュされていればまだ良いのですが、キャッシュされていない場合はページの描画を含めると2回通信していることになります。</p> <p>ただ、これは独自でアクセス数をカウントするため元々通信していたので変わらないのと、あとあくまでもやろうと思ったきっかけはbot対策のため、そのアクセスを軽減できれば問題ないかなと思っています。よくアクセスがあるページはだいたいキャッシュされた状態になると思いますし、そうでないページはさほどアクセスも来ないと思うので誤差かなと思います。とにかくbotを無視して、実際に見に来てくれる方の負荷だけを気にすれば良くなると考えると大きなメリットだと思っています。</p> <h2 id="問題点等の考察"><a href="#%E5%95%8F%E9%A1%8C%E7%82%B9%E7%AD%89%E3%81%AE%E8%80%83%E5%AF%9F">問題点等の考察</a></h2> <p>まだ謎や問題点があるので考察していきます。単なる知識不足の勘違いの可能性もあるのでわかる方は是非アドバイスをお願いします。また、この考察はあくまでもCloudflareの話ですので、他のCDNサービスの場合は全然関係ない可能性もあります。</p> <h3 id="キャッシュされていない?"><a href="#%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%EF%BC%9F">キャッシュされていない?</a></h3> <p>Google Analyticsでアクセスされたことが確認できたページや、サーバーのログでbotが来たらしきページにアクセスしてみるのですが、キャッシュが効いていない事が多いです。(前述のヘッダがHITではなくMISSになる)</p> <p>そのため上手く期限が設定できていなかったり、そもそもCDN自体の仕様を勘違いしているのではないか、と心配になりました。ただ、もしかするとネットワークのエリア毎にキャッシュをしているようであれば、そのようになる可能性もあるのかな、と思いました。</p> <p>前述のように近いエリアからコンテンツが配信されるので、必ずしも全てのCDNサーバーがキャッシュを持っているとは限りません。確かにそのあたり細かく連携するとレスポンスの速さが失われる要因になるような気もするので、エリアごとの管理で十分なのかなという気はします。purgeは多分全て連動で行ってくれるのかな、と思います。(どこかで瞬時に削除する、というような記述を見たような)</p> <p>もしくはbotっぽいアクセスはキャッシュを使わず素通りさせるようにしているとか?</p> <h3 id="アップデート時にpurgeが必要"><a href="#%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E6%99%82%E3%81%ABpurge%E3%81%8C%E5%BF%85%E8%A6%81">アップデート時にpurgeが必要</a></h3> <p>あとで気づいたのですが、よくよく考えると何かしら機能を更新してリリースしても、HTMLが変わらないのでリリースしたことが反映されません。ビルド済みのJavaScriptファイルはバージョニングされているのですが、それも新しいバージョンのものを見てくれないので、結局何かアップデートした際にはpurgeが必要で、また全てのページが一度重い状態になります。頻繁にアップデートすればするほどキャッシュが効かない状態が多くなります。(とはいえ対応前と変わらない状況ではありますが)</p> <p>そのためとりあえず手動全purgeするか、しんどくなってきたら今手動でやっているデプロイを自動デプロイできるようにしてその中に組み込むか、あとはCDN芸をやめて最速の座から降りるか、というところになりそうです。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>とりあえずCloudflareを使った無料でのCDN芸をやってみたかった、というところもあったので試してみました。有料にはなりますが、他のCDNサービスであればもうちょっと楽な運用ができるのではないかと思います。もしログイン情報をあまり使っていないサービス等であればすぐにでも導入できたりするかもしれません。</p> <p>Crieit上でもボードのデータ数が増えてきているため、こちらもCDN化を試しているところです。プライベート機能があるのでそのあたりでちょっとコツが必要だったりします。また、サーバー側のアクセスログもどういう風にアクセス数が推移しているかも解析してみたいなと思っています。また面白い情報が出たら記事にしてみます。(詳しく設定を確認していないのでもう消えているかもしれませんが…)</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14839 2019-02-27T10:09:15+09:00 2019-02-27T23:24:18+09:00 https://crieit.net/posts/PHP-Cloudflare-API PHPでCloudflareのAPI経由でキャッシュを削除する <p>Cloudflareの管理画面でできる機能の多くにはAPIが用意されており、キャッシュの削除もAPI経由で行うことができます。これにより投稿に応じて指定したページのキャッシュをpurgeするといった事が可能です。</p> <p>自分で処理を作っても良いのですが、どうもCloudflareの公式がPHP用のSDKを作成しているようなのでそちらを使ってみました。</p> <h2 id="インストール"><a href="#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">インストール</a></h2> <pre><code class="sh">composer require cloudflare/sdk </code></pre> <h2 id="Adapterの作成"><a href="#Adapter%E3%81%AE%E4%BD%9C%E6%88%90">Adapterの作成</a></h2> <p>API接続用のAdapterを初期化します。下記の情報が必要になりますので、Cloudflareのダッシュボードの分かりやすいところに書かれていますのでそちらで確認し、アプリケーションの.env等に設定しておくと良いと思います。</p> <ul> <li>アカウントのメールアドレス</li> <li>API Key</li> <li>ZONE ID</li> </ul> <p>色々なAPIがありますが、共通の初期化です。</p> <pre><code class="php">use Cloudflare\API\Auth\APIKey; use Cloudflare\API\Adapter\Guzzle; use Cloudflare\API\Endpoints\Zones; $key = new APIKey(config('services.cloudflare.email'), config('services.cloudflare.key')); $adapter = new Guzzle($key); </code></pre> <h2 id="キャッシュのpurge"><a href="#%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E3%81%AEpurge">キャッシュのpurge</a></h2> <p>キャッシュを削除するにはzonesというエンドポイントの機能を使います。先程のadapterを利用して実行します。</p> <pre><code class="php">$zones = new Zones($this->adapter); try { $zones->cachePurge(config('services.cloudflare.zone_id'), [$url]); } catch (\GuzzleHttp\Exception\RequestException $e) { \Log::error($e->getMessage()); } </code></pre> <p>URLのホスト名がおかしかったりすると例外が発生するので適宜エラー処理を行ってください。cachePurgeの戻り値はboolのためレスポンスの詳細は分かりませんが、<code>$zones</code>自体にレスポンスが保存されているのでダンプすれば確認可能です。(成功しているとたいした情報は無いのであまり意味はないです)</p> <p>僕はなぜかpurgeされずおかしいな、と思っていたらURL指定が間違っていたりしたのですが、Cloudflare的には正常のため特にエラーなども出ないので、そのあたりはしっかりログを残して確認しておいてください。</p> だら@Crieit開発者 tag:crieit.net,2005:PublicArticle/14593 2018-11-06T09:29:58+09:00 2018-11-07T01:20:27+09:00 https://crieit.net/posts/Cloudflare-DDoS CloudflareのDDoS攻撃対策を調べてみた <p>CloudflareはCDNだけでなくDDoS対策も行っているというのは知っていたのですが、具体的にどういう機能があるのかよく分かっていなかったので調べてみました。</p> <p>というのも先日からQrunchが攻撃を受けて非常に辛い状態が続いていたようです。個人開発のサービスに攻撃が来ると正直対処のしようがないというのが現実です。サーバーを使っていたりするともう止まるしかありませんし、サーバーレスにしていたら今度はクラウド破産の危険性があります。こういう時はこういったファイアウォールサービスに頼るしかなさそうです。</p> <p>正直こういうことはどのサービスにも起こりうることで、考えれば考える程恐ろしいのでざっとCloudflareのDDoS対策について調べてみました。</p> <h2 id="Firewallの設定"><a href="#Firewall%E3%81%AE%E8%A8%AD%E5%AE%9A">Firewallの設定</a></h2> <p>Firewallの設定画面を開くとSecurity Levelの設定があります。恐らくここが一番シンプルなベースとなるセキュリティ設定項目になりそうです。</p> <p><a href="https://crieit.now.sh/upload_images/e8a79a122784f28ffc9aff2003ba8b425be0dac2f2eb1.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/e8a79a122784f28ffc9aff2003ba8b425be0dac2f2eb1.png?mw=700" alt="Firewall crieit net Alphabrend gmail com s Account Cloudflare Web Performance Security.png" /></a></p> <p>初期設定はMediumとなっています。 Essentially Off から I'm Under Attack! までのレベル設定があり、上から順番に低いレベルのようです。</p> <h3 id="Essentially off"><a href="#Essentially+off">Essentially off</a></h3> <p>最も脅威となる攻撃にのみ対処します。</p> <h3 id="Low"><a href="#Low">Low</a></h3> <p>そこそこ脅威となるアクセスを防御します。</p> <h3 id="Medium"><a href="#Medium">Medium</a></h3> <p>最も脅威となる攻撃とそこそこ脅威となるアクセスを防御します。</p> <h3 id="High"><a href="#High">High</a></h3> <p>14日間に脅威を与えた全ての閲覧者に対して防御を行います。ここからその場限りでなく過去の行動も見ての防御となるようです。</p> <h3 id="I'm Under Attack!"><a href="#I%27m+Under+Attack%21">I'm Under Attack!</a></h3> <p>現在攻撃を受けている場合の防御のようです。全ての閲覧者はサービスにアクセスする前に間に1ページ確認用の画面が表示され、問題ないと判断された場合のみにサービスにアクセスできるというもののようです。</p> <p>Qrunchも現時点の最もひどい状況で利用していたものと思われます。確かにこれであれば連続アクセスが不可能のため、確実に防御はできそうです。そのかわりOGP等も表示できなくなっているようですし、他にも色々と影響がありそうですのでなかなか辛いところではありそうです。</p> <h2 id="その他"><a href="#%E3%81%9D%E3%81%AE%E4%BB%96">その他</a></h2> <p>上記のようなベースの設定以外にもいくつかの機能があります。</p> <h3 id="Firewall Rules"><a href="#Firewall+Rules">Firewall Rules</a></h3> <p>こちらは独自にルールを設けて攻撃を遮断できます。ただ、IP、国等、攻撃者の情報がある程度分かる場合のみに限られそうです。</p> <h3 id="Rate Limiting"><a href="#Rate+Limiting">Rate Limiting</a></h3> <p>おかしな頻度でアクセスしてくるユーザーを遮断できます。軽い設定にしすぎると普通のユーザーも排除してしまいそうですので使う場合はきっちり考えたほうが良さそうです。</p> <p>あとは強力な設定を使いたい場合は有料になるようです。</p> <p>ただこちらもIPを大量に持っている攻撃者の場合は対策が難しいかもしれません。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>その他もいくつか設定がありそうですが、汎用的な設定は他にはなさそうですので、攻撃者の特性を把握しつつ設定を行っていく必要があるのかもしれません。</p> <p>あとは並行してサーバーを強化したり、攻撃しにくい構成にしたりする必要があるのかもしれませんが、個人開発ではなかなか厳しそうです…。個人開発だけでなく、最近は質問箱も攻撃を受けて止まっていたりするようですので、ユーザーや関係者が穏やかな心で見守ってあげるというところが一番重要なのかもしれません。</p> <p>あとは攻撃を受けて止まってしまっても、情報が閲覧できるようにTwitterの公式アカウントや、ステータスだけ確認できるページなどを用意してあげるのが良さそうです。</p> だら@Crieit開発者