tag:crieit.net,2005:https://crieit.net/tags/KUSANAGI/feed 「KUSANAGI」の記事 - Crieit Crieitでタグ「KUSANAGI」に投稿された最近の記事 2019-06-12T12:41:37+09:00 https://crieit.net/tags/KUSANAGI/feed tag:crieit.net,2005:PublicArticle/14967 2019-05-06T09:06:29+09:00 2019-06-12T12:41:37+09:00 https://crieit.net/posts/KUSANAGI-wp-cron-cron KUSANAGI wp-cron を cron で動かす <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>ウェブ上に同様のタイトルのソースはいくつかあったが、何故かそのままでは参考にならないものが多いため、改めてまとめ。</p> <h1 id="方法"><a href="#%E6%96%B9%E6%B3%95">方法</a></h1> <p>コンソール画面ログイン後、以下のコマンドを実行。</p> <pre><code>cd /home/ sudo mkdir cronuser sudo chown cronuser:www cronuser sudo chmod 750 cronuser sudo vim /etc/crontab i </code></pre> <p>一番下に以下の内容を記載。</p> <pre><code>*/1 * * * * cronuser php /home/kusanagi/kusanagi_html/DocumentRoot/wp-cron.php > /dev/null 2>&1 </code></pre> <p>※ "kusanagi_html" の部分はプロビジョニングディレクトリを指定<br /> ※ "/1" の数字部分は実行間隔(分)を指定</p> <p>[esc] キー押下。</p> <pre><code>:wq! </code></pre> <p>で完了。</p> <h1 id="動作確認"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">動作確認</a></h1> <p>以下のコマンドで cron 実行結果を確認できる。</p> <pre><code>sudo tail -f /var/log/cron </code></pre> <p>WordPress では予約投稿が公開状態になる事を確認したり「<a target="_blank" rel="nofollow noopener" href="https://ja.wordpress.org/plugins/wp-crontrol/">WP Crontrol</a>」等のプラグインを用いると楽。</p> <h1 id="補足"><a href="#%E8%A3%9C%E8%B6%B3">補足</a></h1> <p>作成するユーザー名は cronuser 以外でも問題ない。<br /> 既存ユーザーをそのまま用いても良いが、権限の問題もあるため、専用ユーザーを用意した方が無難か。</p> <h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://jyo-to.okinawa/20170512/1088/">WordPressのwp-cron.phpをサーバーのcronで実行する - 合同会社ジョートー</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://webtomoblg.net/wordpress/wordpress_future_post/">WordPressの予約投稿 | 新卒IT文系セールスのBLOG</a></li> </ul> sola tag:crieit.net,2005:PublicArticle/14924 2019-04-14T15:37:04+09:00 2019-04-14T15:40:56+09:00 https://crieit.net/posts/KUSANAGI KUSANAGI で環境ごとにページキャッシュを生成する <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>KUSANAGI にはページキャッシュ機能があるが、通常環境ごとにキャッシュが分かれず、PCやスマホで表示が異なる場合問題が生じる。</p> <h1 id="方法"><a href="#%E6%96%B9%E6%B3%95">方法</a></h1> <h2 id="KUSANAGI 設定画面デバイス切替ページにアクセス"><a href="#KUSANAGI+%E8%A8%AD%E5%AE%9A%E7%94%BB%E9%9D%A2%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E5%88%87%E6%9B%BF%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9">KUSANAGI 設定画面デバイス切替ページにアクセス</a></h2> <p><code>https://hogehoge.com/wp-admin/admin.php?page=kusanagi-core/core.php&tab=theme-switcher</code></p> <p>ホスト等は各自の環境に置き換えて下さい。</p> <h2 id="「デバイスによるテーマ切り替えを停止」のチェックマークを外し、[変更を保存] をクリック"><a href="#%E3%80%8C%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%AB%E3%82%88%E3%82%8B%E3%83%86%E3%83%BC%E3%83%9E%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88%E3%82%92%E5%81%9C%E6%AD%A2%E3%80%8D%E3%81%AE%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%83%9E%E3%83%BC%E3%82%AF%E3%82%92%E5%A4%96%E3%81%97%E3%80%81%5B%E5%A4%89%E6%9B%B4%E3%82%92%E4%BF%9D%E5%AD%98%5D+%E3%82%92%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF">「デバイスによるテーマ切り替えを停止」のチェックマークを外し、[変更を保存] をクリック</a></h2> <p><a href="https://crieit.now.sh/upload_images/5920b1ba5aa14ecdac4cb2aa0060871a5cb2d3d66454d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5920b1ba5aa14ecdac4cb2aa0060871a5cb2d3d66454d.png?mw=700" alt="KUSANAGI設定画面.png" /></a></p> <p><a href="https://crieit.now.sh/upload_images/8cd8bfdaa1717f5dd14fd0e40f5d4ab05cb2d3e19eccd.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8cd8bfdaa1717f5dd14fd0e40f5d4ab05cb2d3e19eccd.png?mw=700" alt="チェック解除.png" /></a></p> <h1 id="解説"><a href="#%E8%A7%A3%E8%AA%AC">解説</a></h1> <p>方法はとてもシンプルでした。テーマ切替を行っていない場合でも有効。</p> sola tag:crieit.net,2005:PublicArticle/14923 2019-04-14T15:12:18+09:00 2019-04-22T17:23:17+09:00 https://crieit.net/posts/KUSANAGI-MySQL KUSANAGI で MySQL が頻繁に落ちる際の対処 <h1 id="環境"><a href="#%E7%92%B0%E5%A2%83">環境</a></h1> <div class="table-responsive"><table> <thead> <tr> <th>名前</th> <th>バージョン</th> </tr> </thead> <tbody> <tr> <td>VPS</td> <td>さくらインターネット 4GB</td> </tr> <tr> <td>OS</td> <td>KUSANAGI 8.4.2-2 (CentOS7 ベース)</td> </tr> <tr> <td>ウェブサーバー</td> <td>nginx 1.15.10</td> </tr> <tr> <td>PHP</td> <td>PHP 7.3.4</td> </tr> <tr> <td>MySQL</td> <td>MariaDB 10.1.38</td> </tr> <tr> <td>アプリケーション</td> <td>WordPress</td> </tr> <tr> <td>その他</td> <td><a target="_blank" rel="nofollow noopener" href="https://mackerel.io/">Mackerel</a></td> </tr> </tbody> </table></div> <h1 id="問題発生"><a href="#%E5%95%8F%E9%A1%8C%E7%99%BA%E7%94%9F">問題発生</a></h1> <p><a href="https://crieit.now.sh/upload_images/5920b1ba5aa14ecdac4cb2aa0060871a5cb2cb625acd3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5920b1ba5aa14ecdac4cb2aa0060871a5cb2cb625acd3.png?mw=700" alt="データベース接続確立エラー.png" /></a></p> <p>サイトにブラウザからアクセスすると「データベース接続確立エラー」となる。</p> <h1 id="状況確認"><a href="#%E7%8A%B6%E6%B3%81%E7%A2%BA%E8%AA%8D">状況確認</a></h1> <p>コンソールにて。</p> <pre><code>sudo cat /var/log/messages </code></pre> <p>以下のログを発見。</p> <pre><code>Apr 14 00:31:06 hoge kernel: mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0 </code></pre> <p>MySQL が落ちている。</p> <h1 id="暫定対処"><a href="#%E6%9A%AB%E5%AE%9A%E5%AF%BE%E5%87%A6">暫定対処</a></h1> <p>コンソールにて。</p> <pre><code>sudo systemctl start mysqld </code></pre> <p>「データベース接続確立エラー」は解消される。</p> <h1 id="数時間後に問題再発"><a href="#%E6%95%B0%E6%99%82%E9%96%93%E5%BE%8C%E3%81%AB%E5%95%8F%E9%A1%8C%E5%86%8D%E7%99%BA">数時間後に問題再発</a></h1> <p><a href="https://crieit.now.sh/upload_images/5920b1ba5aa14ecdac4cb2aa0060871a5cb2cb625acd3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5920b1ba5aa14ecdac4cb2aa0060871a5cb2cb625acd3.png?mw=700" alt="データベース接続確立エラー.png" /></a></p> <p>「データベース接続確立エラー」</p> <h1 id="再度状況確認"><a href="#%E5%86%8D%E5%BA%A6%E7%8A%B6%E6%B3%81%E7%A2%BA%E8%AA%8D">再度状況確認</a></h1> <p>コンソールにて。</p> <pre><code>sudo cat /var/log/messages </code></pre> <p>同様のログを確認。</p> <pre><code>Apr 14 07:48:32 hoge kernel: mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0 </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://mackerel.io/">Mackerel</a> でのメモリ状況を確認。</p> <p><a href="https://crieit.now.sh/upload_images/6f5c7f137838dee61bb62935fd733c5e5cb2c0899c6dd.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6f5c7f137838dee61bb62935fd733c5e5cb2c0899c6dd.png?mw=700" alt="スクリーンショット 2019-04-14 14.08.10.png" /></a></p> <p>メモリを食いつぶした後スワップまで喰って無事死亡している。</p> <h1 id="nginx ログの確認"><a href="#nginx+%E3%83%AD%E3%82%B0%E3%81%AE%E7%A2%BA%E8%AA%8D">nginx ログの確認</a></h1> <p>詳細は割愛するが、nginx のログを確認したところ、ブルートフォースアタックでの接続数増、pubsubhubbub での接続数増、行儀の悪い bot からの接続数増など様々な痕跡があった。</p> <p>なお、KUSANAGI による nginx ログは以下の場所に分散している。<br /> (筆者はしばらくの間ログ分散に気付かず、確認に時間がかかった。)</p> <h2 id="WordPress SSL"><a href="#WordPress+SSL">WordPress SSL</a></h2> <p>/home/kusanagi/kusanagi_html/log/nginx/ssl_access.log</p> <p>※ kusanagi_html はプロビジョニングディレクトリ</p> <h2 id="WordPress HTTP"><a href="#WordPress+HTTP">WordPress HTTP</a></h2> <p>/home/kusanagi/kusanagi_html/log/nginx/access.log</p> <p>※ kusanagi_html はプロビジョニングディレクトリ</p> <h2 id="WordPress 外"><a href="#WordPress+%E5%A4%96">WordPress 外</a></h2> <p>/var/log/nginx/access.log</p> <h1 id="恒久対処"><a href="#%E6%81%92%E4%B9%85%E5%AF%BE%E5%87%A6">恒久対処</a></h1> <p>コンソールにて。</p> <pre><code>sudo vim /etc/php-fpm.d/www.conf /pm.max_children = i </code></pre> <p>PHP-FPM の設定を変更する。</p> <pre><code>pm.max_children = 50 </code></pre> <p>を以下に変更。</p> <pre><code>pm.max_children = 17 </code></pre> <p>[esc] キーで編集終了。</p> <p>KUSANAGI (nginx + php-fpm) 再起動</p> <pre><code>sudo kusanagi restart </code></pre> <h1 id="対処後の確認"><a href="#%E5%AF%BE%E5%87%A6%E5%BE%8C%E3%81%AE%E7%A2%BA%E8%AA%8D">対処後の確認</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://mackerel.io/">Mackerel</a> でのメモリ状況</p> <p><a href="https://crieit.now.sh/upload_images/69106066dd8c39df5777475fb4ca26045cb2c0a52e60d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/69106066dd8c39df5777475fb4ca26045cb2c0a52e60d.png?mw=700" alt="スクリーンショット 2019-04-14 14.06.51.png" /></a></p> <p>ピーク時のメモリ消費量が 3.5GB 程度と、上限の 4GB から 0.5GB 程度余裕のある状態で消費しきらずに、スワップアウトも発生しない。</p> <p>結果、「データベース接続確立エラー」とならず接続状況は安定している。</p> <h1 id="解説"><a href="#%E8%A7%A3%E8%AA%AC">解説</a></h1> <p>PHP-FPM の <code>pm.max_children</code> はアプリケーションの最大プロセス数。php.ini ファイルでの <code>memory_limit</code>は <code>128M</code> に設定されているため、<code>pm.max_children</code> を <code>17</code> に設定した場合 PHP-FPM のみで食いつぶすメモリ量を 2GB 程度に抑えることができる。<br /> デフォルトで 1GB 程度消費しているため、計約3GB。さらに MySQL などで 0.5GB 程度消費しているものと思われる。<br /> 詳細は <code>top</code> コマンド等で確認できる。</p> <h1 id="今後"><a href="#%E4%BB%8A%E5%BE%8C">今後</a></h1> <p>万が一落ちた場合に monit で MySQL の自動再起動、fail2ban によるブロッキング設定を行いたいが後ほど。</p> <h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/AknEp/items/42421a4c3a4a3a8d8991">php-fpmとRAMのお勉強メモ。KUSANAGIで試した。 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://gist.github.com/kitak/6349463">コマンドによる「負荷」の原因切り分け</a></li> </ul> sola tag:crieit.net,2005:PublicArticle/14902 2019-04-04T03:18:36+09:00 2019-05-09T21:31:39+09:00 https://crieit.net/posts/MariaDB-InnoDB MariaDB の InnoDB がぶっ壊れて起動できなくなったので復旧した <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>右往左往して復旧に6時間程度かかった。もうこりごりなので内容をざっくりまとめる。</p> <h1 id="手順(概略)"><a href="#%E6%89%8B%E9%A0%86%EF%BC%88%E6%A6%82%E7%95%A5%EF%BC%89">手順(概略)</a></h1> <p>KUSANAGI(CentOS7)での手順。</p> <pre><code>sudo su vi /etc/my.cnf.d/server.cnf i </code></pre> <pre><code>[mysqld] innodb_force_recovery = 3 </code></pre> <p>[esc] キーで vi 終了。</p> <pre><code>systemctl start mysqld mysqldump -u root -p -x --all-databases > alldatabase.dump systemctl stop mysqld rm -rf /var/lib/mysql/* yum remove -y MariaDB-devel MariaDB-client MariaDB-server yum install -y MariaDB-devel MariaDB-client MariaDB-server systemctl start mysqld mysql -u root UPDATE mysql.user SET password=password('password') WHERE user = 'root'; CREATE USER 'username'@'localhost' IDENTIFIED BY 'password'; GRANT ALL ON db_name.* TO 'username'@'localhost'; flush privileges; exit; mysql -u root -p < alldatabase.dump </code></pre> <h1 id="要点"><a href="#%E8%A6%81%E7%82%B9">要点</a></h1> <ul> <li><code>innodb_force_recovery</code> を 3 以下に設定しておくと InnoDB が壊れていても Read only でとりあえず起動出来るようになるっぽい</li> <li>起動したら mysqldump でバックアップ。MariaDB を再インストール後に戻す</li> <li>構成ファイルがいかれていたので <code>/var/lib/mysql/</code> 配下を消しておく。(必要であれば設定ファイルは逃しておく)</li> </ul> <h1 id="原因"><a href="#%E5%8E%9F%E5%9B%A0">原因</a></h1> <p>数日前に単純に MariaDB が落ちたことがあり、何かしら高負荷がかかっている可能性があるが、アクセス数も多くなく、環境である仮想ハードウェアの負荷も目立った様子は無い。できれば関係ログを追って探りたいところだが不明。</p> <h2 id="(2019.4.14 追記) 原因判明したので記事書きました"><a href="#%282019.4.14+%E8%BF%BD%E8%A8%98%29+%E5%8E%9F%E5%9B%A0%E5%88%A4%E6%98%8E%E3%81%97%E3%81%9F%E3%81%AE%E3%81%A7%E8%A8%98%E4%BA%8B%E6%9B%B8%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F">(2019.4.14 追記) 原因判明したので記事書きました</a></h2> <p><a href="https://crieit.net/posts/KUSANAGI-MySQL">KUSANAGI で MySQL が頻繁に落ちる際の対処 - Crieit</a></p> <h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/skouno25/items/71174c959abe435223ab">MySQLでInnoDB破損したときの復旧方法 - Qiita</a></li> </ul> sola tag:crieit.net,2005:PublicArticle/14776 2019-02-02T09:32:29+09:00 2019-02-02T09:34:19+09:00 https://crieit.net/posts/KUSANAGI-PHP7-nginx KUSANAGI で PHP7 + nginx を利用している際のタイムアウト時間設定 <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>デフォルトでファイルが複数あって迷うので、備忘録です。<br /> 以下はタイムアウト時間が1時間(3600秒)の場合の例です。</p> <p>必要な設定箇所は 3 (4) ファイルです。</p> <h1 id="PHP7"><a href="#PHP7">PHP7</a></h1> <h2 id="php.ini"><a href="#php.ini">php.ini</a></h2> <p>/etc/php7.d/php.ini</p> <pre><code>max_execution_time = 3600 </code></pre> <h2 id="PHP-FPM"><a href="#PHP-FPM">PHP-FPM</a></h2> <p>/etc/php7-fpm.d/www.conf</p> <pre><code>request_terminate_timeout = 3600 </code></pre> <h1 id="nginx"><a href="#nginx">nginx</a></h1> <h2 id="SSL"><a href="#SSL">SSL</a></h2> <p>location ディレクティブブロック <code>location ~ [^/]\.php(/|$) {}</code> 内に記載があります。</p> <p>/etc/nginx/conf.d/kusanagi_html_ssl.conf</p> <pre><code>fastcgi_read_timeout 3600s </code></pre> <h2 id="HTTP"><a href="#HTTP">HTTP</a></h2> <p>SSL を用いている場合は不要ですが念の為。</p> <p>/etc/nginx/conf.d/kusanagi_html_http.conf</p> <pre><code>fastcgi_read_timeout 3600s </code></pre> <h1 id="最後に"><a href="#%E6%9C%80%E5%BE%8C%E3%81%AB">最後に</a></h1> <p>PHP (PHP-FPM), nginx の再起動を忘れずに。<br /> KUSNAGAI の場合は、以下のコマンドで PHP (PHP-FPM), nginx の再起動を同時に行ってくれます。</p> <pre><code>sudo kusanagi restart </code></pre> sola tag:crieit.net,2005:PublicArticle/14628 2018-12-06T00:00:50+09:00 2018-12-09T13:50:54+09:00 https://crieit.net/posts/WordPress-Vue-js 初めてのウェブサービスを WordPress + Vue.js で個人開発した話 <h1 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h1> <p>11月25日(日) に「<a target="_blank" rel="nofollow noopener" href="https://nijisanji.net/">にじさんじ配信スケジュール</a>」と呼ばれるウェブサービスをリリースしました。</p> <p><a href="https://crieit.now.sh/upload_images/97a83c7d3562ab645bbaeeacb5f4d9035c0474bf97d50.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/97a83c7d3562ab645bbaeeacb5f4d9035c0474bf97d50.png?mw=700" alt="にじさんじ配信スケジュール" /></a></p> <p>正確には初めてリリースしたサービスでは無いのですが、会員登録機能が用意された本格的なサービスを出した事がこれまでなく、実質的には初めてのサービスと呼んでも良いだろうと考えています。</p> <p>という訳で、<a href="https://crieit.net/">Crieit</a>「<a href="https://crieit.net/advent-calendars/2018/technology">個人開発サービスに用いられている技術 Advent Calendar 2018</a>」6日目は「初めてのウェブサービスを WordPress + Vue.js で個人開発した話」と題して、開発に WordPress や Vue.js を用いたこと、ウェブサービスを作るまでの話や、リリース直後の話をしたいと思います。</p> <p>n番煎じなテーマですし、蛇足に感じられる内容も多々あるかと思いますが、適宜必要な箇所をお読み頂ければ幸いです。</p> <h1 id="この記事の想定読者"><a href="#%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%AE%E6%83%B3%E5%AE%9A%E8%AA%AD%E8%80%85">この記事の想定読者</a></h1> <ul> <li>これからウェブサービスを個人で作りたい方や開発中の方</li> <li>ウェブサービスで実際に用いられている技術やツールを知りたい方</li> <li>開発ノウハウを知りたい方</li> <li>技術面以外の話にも興味がある方</li> </ul> <h1 id="開発経緯"><a href="#%E9%96%8B%E7%99%BA%E7%B5%8C%E7%B7%AF">開発経緯</a></h1> <p>「<a target="_blank" rel="nofollow noopener" href="http://nijisanji.ichikara.co.jp/">にじさんじ</a>」と呼ばれるバーチャルライバー (VTuber) グループが存在しています。</p> <p><a href="https://crieit.now.sh/upload_images/16b8ee5f67d0b16127720c30ee9b6fe65c04737c73b32.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/16b8ee5f67d0b16127720c30ee9b6fe65c04737c73b32.jpg?mw=700" alt="にじさんじ" /></a></p> <p>僕はこちらのグループのファンなのですが、公式がスケジュール情報の発信を行っておらず、スケジュールを把握しにくい問題がありました。<br /> スケジュール情報を発信する非公式サイトやアプリも存在していますが、閲覧がしにくく使い勝手が悪い状態でもありました。<br /> そこで、スマートフォンでも十分に閲覧でき、にじさんじライバーの配信スケジュールに特化したウェブサービスを作れば需要があるのでは考え、開発に着手しました。</p> <h1 id="主な機能"><a href="#%E4%B8%BB%E3%81%AA%E6%A9%9F%E8%83%BD">主な機能</a></h1> <p>元々はシンプルにスケジュールを確認出来るだけのシンプルなサイト開発を考えていましたが、<br /> 自分自身が必要十分に感じるレベル(このサービスユーザーのペルソナの1つは自分自身です!)に加え、サービスとして多くの方々に利用頂く事を前提に機能検討した結果、リリース時は以下の機能を実装しようという結論に至りました。</p> <h2 id="ユーザー向け機能"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E5%90%91%E3%81%91%E6%A9%9F%E8%83%BD">ユーザー向け機能</a></h2> <ul> <li>バーチャルライバー (VTuber) グループ「にじさんじ」メンバーの生配信スケジュールの閲覧</li> <li>実際の生配信(ライブ)、アーカイブ情報の閲覧</li> <li>ライバー情報の閲覧</li> <li>ライバーのフォローを元にしたスケジュール等の情報閲覧(要会員登録)</li> <li>配信時間前のメール通知(要会員登録)</li> <li>Twitter へスケジュール情報まとめツイート</li> <li>端末を問わず利用可能(レスポンシブ)</li> <li>ネイティブアプリっぽいリッチなデザイン</li> </ul> <h2 id="運営者向け機能"><a href="#%E9%81%8B%E5%96%B6%E8%80%85%E5%90%91%E3%81%91%E6%A9%9F%E8%83%BD">運営者向け機能</a></h2> <ul> <li>スケジュール、ライブ、アーカイブ情報の自動取得(API、スクレイピング)</li> <li>情報登録時のメール通知</li> <li>管理画面</li> </ul> <h2 id="機能についての詳細"><a href="#%E6%A9%9F%E8%83%BD%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E8%A9%B3%E7%B4%B0">機能についての詳細</a></h2> <h3 id="ユーザー向け"><a href="#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E5%90%91%E3%81%91">ユーザー向け</a></h3> <p>にじさんじは59名(現在は58名)と多くのライバーを擁します。<br /> ライバー全体の情報を網羅しようとした場合の情報量は馬鹿に出来ません。<br /> ユーザーごとに追っているライバーは異なるため、にじさんじ全体の情報をすべてのユーザーに一律に見せる事はユーザーの負担に繋がります。<br /> また、にじさんじには「1期生・2期生(無印)」「ゲーマーズ」「SEEDs」という3つのグループが存在していますが、それぞれを追っているファン層は異なります。<br /> さらに、グループ問わず人気ライバーを追っている方や、特定のライバーに搾って追っている方など、ユーザーの興味は多種多様です。</p> <p>そこで、以下のフィルタリング機能を備えることにしました。</p> <ul> <li>にじさんじ内のグループごと</li> <li>ユーザーによるライバーのフォロー</li> </ul> <p>フォロー機能を用意する場合、会員機能の実装は欠かせません。</p> <p>また、当サービスを多くの方に継続的に使っていただくことを考えた場合、アプリっぽいデザインで使いやすい UI を提供する事は欠かせないだろうと考え、フロンロエンドを Ajax で提供することに決めました。</p> <h3 id="運営者向け"><a href="#%E9%81%8B%E5%96%B6%E8%80%85%E5%90%91%E3%81%91">運営者向け</a></h3> <p>過去に情報の手動更新で苦労した経験があった為、情報の自動取得は欠かせませんでした。<br /> また、テストデータを作成したり、自動化を行った場合であっても、情報の編集は適宜必要となる事から、GUI の管理画面の存在も必要でした。</p> <h1 id="使用技術・開発ツール"><a href="#%E4%BD%BF%E7%94%A8%E6%8A%80%E8%A1%93%E3%83%BB%E9%96%8B%E7%99%BA%E3%83%84%E3%83%BC%E3%83%AB">使用技術・開発ツール</a></h1> <h2 id="今回用いた技術・開発ツール"><a href="#%E4%BB%8A%E5%9B%9E%E7%94%A8%E3%81%84%E3%81%9F%E6%8A%80%E8%A1%93%E3%83%BB%E9%96%8B%E7%99%BA%E3%83%84%E3%83%BC%E3%83%AB">今回用いた技術・開発ツール</a></h2> <h3 id="WordPress"><a href="#WordPress">WordPress</a></h3> <p>開発フレームワークとして WordPress を用いた理由ですが、</p> <ul> <li>見知った技術であること</li> <li>データの CRUD 、ページ作成、ユーザー認証など、会員機能付きウェブサービス作成に必要十分な機能が揃っていること</li> <li>管理画面が標準で用意されていること</li> <li>「プラグイン」を用いて楽が出来ること</li> <li>枯れた技術であること</li> </ul> <p>上のようなものが挙げられます。</p> <p>特に「管理画面が標準で用意されていること」は重要で、管理画面が必要な状況において、これがあるのと無いのとでは開発工数に雲泥の差が生じます。</p> <p>データモデルの構造上、複数のデータ項目への検索実装が難しい点が弱点ではありますが、検索を主体としたサービスでは無いため、あまり問題にならないと判断しました。</p> <h3 id="Advanced Custom Fields Pro"><a href="#Advanced+Custom+Fields+Pro">Advanced Custom Fields Pro</a></h3> <p>WordPress にてカスタムフィールドを扱う際 <a target="_blank" rel="nofollow noopener" href="https://www.advancedcustomfields.com/pro/">Advanced Custom Fields</a> が欠かせません。<br /> 繰り返しフィールド(配列)を簡単に用いることが可能な有料の <a target="_blank" rel="nofollow noopener" href="https://www.advancedcustomfields.com/pro/">Pro</a> 版を使用しています。</p> <p>GUI でデータ構造や管理画面を作成する事ができ、大変重宝しています。<br /> コードを書かずに済む作業は、書かずに越したことがないです。</p> <h3 id="WP-REST API"><a href="#WP-REST+API">WP-REST API</a></h3> <p>Ajax でのレンダリングを行う場合、情報元となる API が欠かせません。<br /> 以前は <a target="_blank" rel="nofollow noopener" href="https://wpdocs.osdn.jp/%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%81%A7_AJAX_%E3%82%92%E4%BD%BF%E3%81%86">admin-ajax.php</a> を利用して API を1から作る必要がありましたが、<br /> 今では WordPress コアに標準で API の機能が備わっています。<a target="_blank" rel="nofollow noopener" href="https://ja.wp-api.org/">WP-REST API</a> を使わない手はありません。</p> <h3 id="jQuery"><a href="#jQuery">jQuery</a></h3> <p>こちらも WordPress コアに標準で含まれています。<br /> ユーザー画面においてもツールバーの描画に必要で、WordPress を用いる場合欠かせません。<br /> また、後述する Semantic-UI のスクリプトも jQuery で出来ており、jQuery に依存せざる得ない状態です。</p> <p>とはいえ、単一 DOM の表示切り替えといったシンプルな仕事は jQuery 向きであると言えると思います。<br /> また、Ajax 用の仕組みも備わっており、上のような前提が存在する状況においては、別途 axios といったライブラリを用意しなくとも済む点は引き続き評価出来ます。</p> <h3 id="Vue.js"><a href="#Vue.js">Vue.js</a></h3> <p>Ajax にて取得したデータを用いて画面を構成する場合、開発効率やコードの視認性、いずれを考慮してもビューとコントローラーの仕組みは欠かせないだろうと思います。</p> <p>Angular, React, Vue.js あたりが採用候補にあたると思いますが、jQuery との併用可能な(最新バージョンを持つ)フレームワークは後者2つのみです。<br /> 元々 <a target="_blank" rel="nofollow noopener" href="https://riot.js.org/ja/">Riot.js</a> を使っていた身として、またテンプレートエンジンライクな PHP 使いとして、 Vue.js の記法はとても親近感があり書きやすいものでした。<br /> また、Vue CLI, Nuxt.js といった関連技術も充実しており、廃れる心配が少ない技術だろうという点も技術選定の後押しポイントになりました。</p> <h3 id="Semantic-UI"><a href="#Semantic-UI">Semantic-UI</a></h3> <p>UI コンポーネントは Bootstrap が有名で、僕も用いたことがありますが、<br /> あまりにも多くのサイトで用いられている事から見慣れてしまい、飽きを感じ始めていました。<br /> そういった状況で <a target="_blank" rel="nofollow noopener" href="https://semantic-ui.com/">Semantic-UI</a> を見つけた時は感動したのを覚えています。</p> <p>選定理由としてデザインの好みの影響は多分にありますが、UI パターンが Bootstrap 並に備わっており、技術者として実用に耐えうる UI コンポーネントであると感じています。</p> <h3 id="Twitter API"><a href="#Twitter+API">Twitter API</a></h3> <p>会員登録・認証に用いました。</p> <p>利用に審査が必要となり導入敷居が上がりましたが、<br /> Google 翻訳の手助けを得つつ簡単な英文で申請を行ったところ、サクッと審査がおりました。</p> <p>また、<a target="_blank" rel="nofollow noopener" href="https://ja.wordpress.org/plugins/gianism/">Gianism</a> と呼ばれる WordPress プラグインがあった為、認証に係る新規コードはほとんど書かずに利用することが出来ました。</p> <h3 id="YouTube API"><a href="#YouTube+API">YouTube API</a></h3> <p>YouTube のライブ、動画データを取得する為には欠かせませんでした。</p> <p>動画 API は REST 形式でも提供されており、利用の敷居はとても低くなっています。</p> <h3 id="PHPMailer"><a href="#PHPMailer">PHPMailer</a></h3> <p>メール通知の際にメール配信の仕組みが必要でした。</p> <p>今回、サーバーはさくらインターネットさんのものを用いましたが、多くのスパム業者の利用実績の影響からか各プロパイダからの締め付けが強く、標準ポートでのメール配信は厳しいものがありました。</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/PHPMailer/PHPMailer">PHPMailer</a> を用いると、Gmail といった各プロパイダからの受信規制の少ないサーバーを利用できるため、メール配信にあたり安心感があります。</p> <h3 id="さくらインターネットVPS + KUSANAGI"><a href="#%E3%81%95%E3%81%8F%E3%82%89%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%BC%E3%83%8D%E3%83%83%E3%83%88VPS+%2B+KUSANAGI">さくらインターネットVPS + KUSANAGI</a></h3> <p>サーバーはさくらインターネットVPS(標準2GB) + <a target="_blank" rel="nofollow noopener" href="https://kusanagi.tokyo/">KUSANAGI</a> という形を取りました。</p> <p>さくらインターネットVPS は国内サービスのため、契約周りでの安心感がありますし、<a target="_blank" rel="nofollow noopener" href="http://ascii.jp/elem/000/001/738/1738515/">国内サービスの中での信頼性は随一</a>です。<br /> また、ビジネス目的でのサービスでないため運用コストは抑える必要がありますが、従量課金で無く、不意な請求が絶対に起こりえない点もポイントでした。</p> <p>KUSANAGI については WordPress サイトを運営する為に必要な nginx, PHP の設定がデフォルトで最適化されており、SSL 化に欠かせない Let's Encrypt も自動で走るなど、WordPress サイトを運営するために至り尽くせりな機能が OS レベルで備わっています。</p> <p>heroku や Cloud9 といった PaaS に頼る手も検討しましたが、環境セットアップの安易さはそれらのサービスに劣らないことや、さくらインターネットの場合は VPS であってもスケールアップ可能といった特徴を持つことから、最初のウェブサービスはこの構成から始めることにしました。</p> <h3 id="VCCW"><a href="#VCCW">VCCW</a></h3> <p>開発環境は <a target="_blank" rel="nofollow noopener" href="http://vccw.cc/">VCCW</a> を用いました。<br /> VCCW とは Vagrant がベースの WordPress 開発に最適化されたツールです。<br /> macOS での導入は一瞬でした。</p> <p>PaaS ではなく VPS を用いた理由としては VCCW の存在も大きく、同梱された <a target="_blank" rel="nofollow noopener" href="https://github.com/welaika/wordmove">Wordmove</a> で DB 含めたデプロイ(同期)が一瞬で完了するなど、VCCW を用いた際の総合的な体験がとてもスマートで感動しました。</p> <p>実は、これまで Filezilla (FTP) を主なデプロイ手段としていましたが、どうして早く試さなかったのかと反省しています。</p> <h3 id="Visual Studio Code"><a href="#Visual+Studio+Code">Visual Studio Code</a></h3> <p>コードはもっぱら <a target="_blank" rel="nofollow noopener" href="https://code.visualstudio.com/">Visual Studio Code</a> で書いています。<br /> これまで Sublime Text を用いていましたが、稀に落ちたり OS ごとの挙動差分が気になっていました。<br /> Visual Studio Code は開発環境をベースとしており拡張性も高く安心感がありますし、動作が軽快なためストレスフリーにコードが書ける点がとても評価出来ます。</p> <h3 id="Google Chrome"><a href="#Google+Chrome">Google Chrome</a></h3> <p>開発関係のプラグインが豊富である事、検証ツールにてスマートフォンやタブレットの画面エミュレートが安易である点が良いです。</p> <p>もちろん、最終的な動作確認の際は各種ブラウザ(Safari, Firefox, Edge, Opera, それぞれ最新)・OS(macOS, Windows, iOS, Android, それぞれ最新)でのテストも行っています。</p> <h3 id="Git"><a href="#Git">Git</a></h3> <p>純粋にファイルのバージョン管理目的で用いました。</p> <p>ちなみにホスト先は <a target="_blank" rel="nofollow noopener" href="https://bitbucket.org/">Bitbucket</a>、クライアントには <a target="_blank" rel="nofollow noopener" href="https://ja.atlassian.com/software/sourcetree">SourceTree</a> を用いています。</p> <h3 id="Macbook Pro (13inch)"><a href="#Macbook+Pro+%2813inch%29">Macbook Pro (13inch)</a></h3> <p>ハードウェアの好みで用いています。</p> <p>スペックですがメモリ16GB、CPU Corei7 2.5GHz デュアルコア、SSD 512GBになります。</p> <p>VCCW にて仮想環境を走らせる都合上、ある程度のメモリが必要となります。<br /> 8GB では処理が重く感じられる為、7月に new MacBook から移行しました。</p> <h3 id="メモ (Apple)"><a href="#%E3%83%A1%E3%83%A2+%28Apple%29">メモ (Apple)</a></h3> <p>ToDo リスト機能が便利でした。</p> <p><a href="https://crieit.now.sh/upload_images/34a233108cad55c08bf8ba640a9a976f5c0610e0b3e88.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/34a233108cad55c08bf8ba640a9a976f5c0610e0b3e88.png?mw=700" alt="ToDo 抜粋" /></a></p> <h2 id="今回用いなかった技術・開発ツール"><a href="#%E4%BB%8A%E5%9B%9E%E7%94%A8%E3%81%84%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F%E6%8A%80%E8%A1%93%E3%83%BB%E9%96%8B%E7%99%BA%E3%83%84%E3%83%BC%E3%83%AB">今回用いなかった技術・開発ツール</a></h2> <h3 id="Gutenberg"><a href="#Gutenberg">Gutenberg</a></h3> <p>WordPress のエディタにブロックの概念が導入され、レイアウトレベルで見たまま編集が行えるようになりました。その機能名の事を <a target="_blank" rel="nofollow noopener" href="https://ja.wordpress.org/gutenberg/">Gutenberg</a> と呼びます。<br /> WordPress 界隈においては有名な新技術ですが、Gutenberg を無効化する <a target="_blank" rel="nofollow noopener" href="https://ja.wordpress.org/plugins/classic-editor/">Classic Editor</a> を入れ導入を見送りました。<br /> 以下のような理由からです。</p> <ul> <li>今のところ新しい技術であり今後仕様が頻繁に変わるリスクがある</li> <li>画面の表示要素を再利用したり、レイアウトを頻繁に変更したり、デザインを他人に任せたり、ユーザーに編集させたりといった、Gutenberg のメリットを享受可能な状況に置かれていない</li> </ul> <h3 id="Firebase"><a href="#Firebase">Firebase</a></h3> <p>フロントエンド中心の開発の勉強も兼ねて用いることを考えましたが、自動化にあたってスクレイピングが必要で、サーバーサイド中心の開発にせざる得ませんでした。</p> <h3 id="Laravel, CakePHP 等の開発フレームワーク"><a href="#Laravel%2C+CakePHP+%E7%AD%89%E3%81%AE%E9%96%8B%E7%99%BA%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF">Laravel, CakePHP 等の開発フレームワーク</a></h3> <p>複雑なデータモデルが必要であったり、検索が重要となるサービスを開発する場合は WordPress では限界があったと思いますが、そうではありませんでした。</p> <h3 id="Drupal, concrete5, baserCMS, Movable Type 等の CMS"><a href="#Drupal%2C+concrete5%2C+baserCMS%2C+Movable+Type+%E7%AD%89%E3%81%AE+CMS">Drupal, concrete5, baserCMS, Movable Type 等の CMS</a></h3> <p>前者2つについては、掲示板など会員管理周りの機能が充実している事やエディタのリッチさが売りかと思われますが、その点において今回メリットには感じませんでした。</p> <p><a target="_blank" rel="nofollow noopener" href="https://basercms.net/about/index.html">baserCMS</a> については、CakePHP がベースに採用されており、かつ管理画面も備わっている事から、開発者目線ではとても魅力的です。<br /> 今回は採用していないですが、データモデルが複雑で、管理画面もサクッと用意したいという状況においては、選ばざる得ない選択肢だと思われます。</p> <p>Movable Type は WordPress 以上に一般サイト制作に特化しており、会員管理等の標準機能が弱い印象があります。</p> <h3 id="CDN"><a href="#CDN">CDN</a></h3> <p>入れれば速くて良いのですが、コストが気になります。趣味のサービスには向かないでしょう。<br /> 今回は KUSANAGI (nginx + サーバーキャッシュ) に頑張ってもらっています。</p> <h3 id="gulp, babel, webpack 等のフロントツール"><a href="#gulp%2C+babel%2C+webpack+%E7%AD%89%E3%81%AE%E3%83%95%E3%83%AD%E3%83%B3%E3%83%88%E3%83%84%E3%83%BC%E3%83%AB">gulp, babel, webpack 等のフロントツール</a></h3> <p>実はまともに用いたことがありません。(勉強せねば…)<br /> ただ、これらのツールが活用できずともウェブサービスを開発し運用を開始出来る状態になる事が分かります。</p> <ul> <li><a href="https://crieit.net/posts/Webpack">初心者はWebpackの事は一度忘れた方が良い - Crieit</a></li> </ul> <h3 id="AMP"><a href="#AMP">AMP</a></h3> <p>文章や写真ベースの記事がほとんど無く、JavaScript に頼るページも多く導入は見送りました。</p> <p>ただ、Vue.js でのレンダリング結果を Googlebot が拾ってくれない都合で、Vue.js のレンダリングが完了するまでは SSR の結果を表示する仕組みを入れた事で、JavaScript に頼るページがほとんど無くなりました。</p> <p>AMP を導入した場合 SEO 効果も期待できるため、後々導入する可能性があります。</p> <h3 id="PWA"><a href="#PWA">PWA</a></h3> <p>アプリっぽい見た目にした事や Ajax での情報取得は PWA 化を見越しての方法でもありました。<br /> 一旦 apple-touch-icon の設定でお茶を濁しましたが、AMP 同様後々導入する可能性があります。</p> <h3 id="Docker"><a href="#Docker">Docker</a></h3> <p>VCCW のお陰で、動作環境としては Linux ベースで開発が出来ており、本番サーバーに環境も近いはずで、環境を揃える意味ではほとんど不要だろうと考えていたのですが、本番リリース直前に本番でのみ発生する不具合に見合わされました。<br /> 始めから Docker ベースでの開発であればそのような悩みも発生しなかっただろうと思います。<br /> 今後の新規開発の際に導入を検討する可能性がありそうですが、費用を中心に何かとコストが増えやすい為、趣味のサービス開発での導入は難しそうです。</p> <h1 id="開発やリリースで苦労したこと"><a href="#%E9%96%8B%E7%99%BA%E3%82%84%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%A7%E8%8B%A6%E5%8A%B4%E3%81%97%E3%81%9F%E3%81%93%E3%81%A8">開発やリリースで苦労したこと</a></h1> <p>上で記載した以外の点について触れたいと思います。</p> <h2 id="類似サービスの登場"><a href="#%E9%A1%9E%E4%BC%BC%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E7%99%BB%E5%A0%B4">類似サービスの登場</a></h2> <p>開発開始からわずか数日ほど経ったタイミングで、VTuber のスケジュールを扱うサービスが登場しました。</p> <p>一見デザインも綺麗で、にじさんじ以外も含め、様々な VTuber のスケジュールが登録されています。</p> <p>ただ、スケジュールが不十分な部分があったり、にじさんじ好きにとってはノイズとなる情報も多いなど、欠点や方向性の違いによる差がある事も分かってきました。</p> <p>当初の目的を常に意識しながら、なんとかリリースする事が出来ました。</p> <h2 id="Twitter アカウント凍結"><a href="#Twitter+%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E5%87%8D%E7%B5%90">Twitter アカウント凍結</a></h2> <p>現在 <a target="_blank" rel="nofollow noopener" href="https://twitter.com/nijisanji_net">@nijisanji_net</a> というアカウントを用いていますが、元々はドメイン取得時に別のアカウント名で作成し放置していたところ、何故か凍結の事態に…</p> <p>このような事は初めてでしたが、凍結直後に気づくことが出来ず、凍結解除申請も虚しく現在も凍結されたままになっています。</p> <p>惜しかったですが、思い切って別アカウントを作成し事なきを得ました。</p> <h2 id="スクレイピング"><a href="#%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0">スクレイピング</a></h2> <p>スクレイピング対象に想定外のパターンの文字列が混ざった場合、データに不具合が発生します。<br /> 中にはスクレイピング先情報の typo など、どうしようもないものもありますが、<br /> 大きなデータ崩れが発生しないように抑えるべく、多くの分岐処理が必要となりました。<br /> スクレイピングは本サービスのコア機能になりますが、最も実装に時間のかかった部分でもありました。</p> <h2 id="Google Search Console"><a href="#Google+Search+Console">Google Search Console</a></h2> <p>リリース直前に noindex,follow 指定で本番環境でのテストを行っていた影響で、この記事を書いている現在もエラーを吐く状態となっています。<br /> 当初は別に問題があるのではといろいろ試したのですが、不慣れのため、単純な時間の問題だろうと気づくまでにとても時間がかかりました。</p> <h2 id="Googlebot 上で Vue.js が機能しない"><a href="#Googlebot+%E4%B8%8A%E3%81%A7+Vue.js+%E3%81%8C%E6%A9%9F%E8%83%BD%E3%81%97%E3%81%AA%E3%81%84">Googlebot 上で Vue.js が機能しない</a></h2> <p>Search Console 上の問題もあり、時間が経つまでの検索インデックスは DOM に頼るしかない状態となっていましたが、<br /> その問題に追い打ちをかけるように Googlebot 上で Vue.js が機能しない問題にぶち当たりました。</p> <p><a href="https://crieit.now.sh/upload_images/9d6f358801008d7098a080eada7db9425c0629610762a.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d6f358801008d7098a080eada7db9425c0629610762a.png?mw=700" alt="googlebot vue.js" /></a></p> <p>Googlebot で JavaScript を解釈できる事は知っていましたが、Vue.js など一部のスクリプトが正しく認識されない問題についての知識が無く、これには参りました。</p> <p>結局 Vue.js で出力される内容をサーバーサイドレンダリング (SSR) させ、 Vue.js が読み込まれるまでの間の表示をサーバー側に任せる事でなんとか事なきを得ました。</p> <p><a href="https://crieit.now.sh/upload_images/277173c532a3325c1b39552c64edb6705c062acf87c0d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/277173c532a3325c1b39552c64edb6705c062acf87c0d.png?mw=700" alt="Googlebot SSR" /></a></p> <h1 id="開発期間・工数"><a href="#%E9%96%8B%E7%99%BA%E6%9C%9F%E9%96%93%E3%83%BB%E5%B7%A5%E6%95%B0">開発期間・工数</a></h1> <p>9月9日に開発を開始し、11月25日に公開しました。<br /> 開発期間は約3ヶ月、累計作業工数は142時間でした。</p> <h2 id="工数について"><a href="#%E5%B7%A5%E6%95%B0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">工数について</a></h2> <p>当初はせいぜい数十時間で終わるだろうと見込んで開発を開始しましたが、実際はサービス開発を行いながら仕様を詰めており、当初の想定よりも機能が増えたことから、予定よりも工数が嵩んでしまいました。</p> <p>また、作成していたプログラムの不具合の影響で、手動で作成していたライバーデータを全て別データで上書きしてしまったのですが、そのライバーデータの作成に10時間近くかかっており、再度同様の工数が発生しました。</p> <p>さらに、リリース直前に発生した本番環境限定の不具合もあり対処に10時間ほど時間が取られてしまいました。</p> <p>実際にかかった時間と比較し20時間〜30時間ほどは短く出来たのではと思います。次に活かしたいです。</p> <p>余談ですが、改めて2つ歳下のせせりさんのすごさを実感しました。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="http://www.itmedia.co.jp/news/articles/1712/11/news089.html">「1人で6時間で作った」 Twitterで匿名質問「Peing」人気、月間2億PV超えへ - ITmedia NEWS</a></li> </ul> <h1 id="開発以外で取り組んだこと"><a href="#%E9%96%8B%E7%99%BA%E4%BB%A5%E5%A4%96%E3%81%A7%E5%8F%96%E3%82%8A%E7%B5%84%E3%82%93%E3%81%A0%E3%81%93%E3%81%A8">開発以外で取り組んだこと</a></h1> <h2 id="他の趣味活動の制限"><a href="#%E4%BB%96%E3%81%AE%E8%B6%A3%E5%91%B3%E6%B4%BB%E5%8B%95%E3%81%AE%E5%88%B6%E9%99%90">他の趣味活動の制限</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://anitech.fm/">ポッドキャスト</a>や<a target="_blank" rel="nofollow noopener" href="http://solaio.hateblo.jp/">ブログ</a>でのアウトプット、仲間との Discord など、日常的に様々な趣味活動を行っていましたが、業務、他のプライベートでの活動も含め忙しく、削れる活動は制限する事に。</p> <p>もちろん、万人が意識する事でも無いと思いますが、忙しい社会人が開発を継続していく為には、多少他の活動を制限する覚悟が必要だと感じています。</p> <h2 id="息抜きは欠かさない"><a href="#%E6%81%AF%E6%8A%9C%E3%81%8D%E3%81%AF%E6%AC%A0%E3%81%8B%E3%81%95%E3%81%AA%E3%81%84">息抜きは欠かさない</a></h2> <p>とは言いつつも、仕事も開発、プライベートも開発で休み無しという状況では、つらい日々が続きます。</p> <p>趣味のアニメ視聴時間は一切削らず、本サービスで扱っている VTuber 動画の視聴時間もある程度確保した事は、<br /> モチベーションの維持に大きく貢献しただろうと思います。</p> <h2 id="開発者コミュニティへの加入"><a href="#%E9%96%8B%E7%99%BA%E8%80%85%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%83%86%E3%82%A3%E3%81%B8%E3%81%AE%E5%8A%A0%E5%85%A5">開発者コミュニティへの加入</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://scrapbox.io/admin-guild-pr/%E9%81%8B%E5%96%B6%E8%80%85%E3%82%AE%E3%83%AB%E3%83%89">運営者ギルド</a>のメンバーとなりましたが、他のみなさんの発言は「自分も頑張らないと」という刺激になりました。</p> <h1 id="リリースしてからの気付きや変化"><a href="#%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%A6%E3%81%8B%E3%82%89%E3%81%AE%E6%B0%97%E4%BB%98%E3%81%8D%E3%82%84%E5%A4%89%E5%8C%96">リリースしてからの気付きや変化</a></h1> <h2 id="アクセス数が気になって落ち着かない"><a href="#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E6%95%B0%E3%81%8C%E6%B0%97%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E8%90%BD%E3%81%A1%E7%9D%80%E3%81%8B%E3%81%AA%E3%81%84">アクセス数が気になって落ち着かない</a></h2> <p>公開から数日たった現在は多少慣れましたが、公開1日目は気づいたら Analytics の画面を見ている状態で本当に落ち着きませんでした。</p> <h2 id="運用に時間が取られる"><a href="#%E9%81%8B%E7%94%A8%E3%81%AB%E6%99%82%E9%96%93%E3%81%8C%E5%8F%96%E3%82%89%E3%82%8C%E3%82%8B">運用に時間が取られる</a></h2> <p>理論上は自動化出来ているため、運用に時間が取られることも少ないだろうと考えていましたが、実際は更新ツールの不具合を修正したり、データを一部手直ししたり、アクセス数を増やすための SEO や PR を行ったりと、100%の自動化は中々難しく今後の課題であると感じています。</p> <h1 id="WordPress + Vue.js を用いてどうだったか"><a href="#WordPress+%2B+Vue.js+%E3%82%92%E7%94%A8%E3%81%84%E3%81%A6%E3%81%A9%E3%81%86%E3%81%A0%E3%81%A3%E3%81%9F%E3%81%8B">WordPress + Vue.js を用いてどうだったか</a></h1> <h2 id="WordPress"><a href="#WordPress">WordPress</a></h2> <p>サービス開発においても使用感は悪くなかったです。</p> <p>そもそもとして、開発フレームワークではない WordPress を開発に用いる事に対する心配をお持ちの方は多いと思われますが、上に記載した通り</p> <blockquote> <p>データモデルの構造上、複数のデータ項目への検索実装が難しい点が弱点</p> </blockquote> <p>問題はこの程度だと考えています。</p> <p>大規模な開発になった際に、規約が少なくコードの品質が担当者間で不揃いになりやすかったり、<br /> データモデルの都合上パフォーマンスの問題も出てきますが、<br /> 個人開発レベルにおいてはほとんど心配する事ではないだろうと思いますし、<br /> 現実的な対策は十分可能ですので今後業務の開発でも用いると思います。</p> <h2 id="Vue.js"><a href="#Vue.js">Vue.js</a></h2> <p>リリース後に SEO 面の問題が発生した為、フロントエンド技術に頼った開発は難しそうだと実感させられました。<br /> ただ、今回のようなサーバーサイド技術との併用であれば小回りも効くため、十分実用的ではと思います。</p> <h2 id="WordPress と Vue.js の併用"><a href="#WordPress+%E3%81%A8+Vue.js+%E3%81%AE%E4%BD%B5%E7%94%A8">WordPress と Vue.js の併用</a></h2> <p>下記2点があり、併用には全く支障がありませんでした。</p> <ul> <li>WordPress 標準で API が提供されている</li> <li>WordPress コアに含まれている jQuery と Vue.js が併用可能</li> </ul> <h2 id="その他"><a href="#%E3%81%9D%E3%81%AE%E4%BB%96">その他</a></h2> <p>Semantic-UI と Vue.js のかみ合わせがあまりよろしくなく、<br /> Semantic-UI 内の JS ライブラリで作成したフォームの value が Vue.js 側で上手く取得できませんでした。<br /> Semantic-UI に value を直接返す関数が提供されておりどうにかなりましたが、<br /> サードパーティ製ではあるものの <a target="_blank" rel="nofollow noopener" href="https://semantic-ui-vue.github.io/">Semantic UI Vue</a> と呼ばれる UI コンポーネントも存在している事から、今後はそちらを使っていく可能性があります。</p> <h1 id="これから取り組みたいこと"><a href="#%E3%81%93%E3%82%8C%E3%81%8B%E3%82%89%E5%8F%96%E3%82%8A%E7%B5%84%E3%81%BF%E3%81%9F%E3%81%84%E3%81%93%E3%81%A8">これから取り組みたいこと</a></h1> <h2 id="サービスの継続運用、機能拡張"><a href="#%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E7%B6%99%E7%B6%9A%E9%81%8B%E7%94%A8%E3%80%81%E6%A9%9F%E8%83%BD%E6%8B%A1%E5%BC%B5">サービスの継続運用、機能拡張</a></h2> <p>一部不具合も残っているため、それの改善も含めた継続的なサービス運用を目指したいです。<br /> また、ある程度機能を絞ってリリースしており、残りの機能もしっかり開発できればと考えています。</p> <h2 id="数字、結果"><a href="#%E6%95%B0%E5%AD%97%E3%80%81%E7%B5%90%E6%9E%9C">数字、結果</a></h2> <p>現状、Twitter のフォロワーは 50 に満たず、まだ SEO の効果も出ていないことからアクセス数はご察しのとおりです。<br /> 趣味のサービスのため、数字や結果が最優先ではありませんが、折角ですのでにじさんじファンの半数程度(数万人)に利用して頂けるサービスを目指せればと考えています。</p> <h2 id="別サービスの新規開発"><a href="#%E5%88%A5%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E6%96%B0%E8%A6%8F%E9%96%8B%E7%99%BA">別サービスの新規開発</a></h2> <p>上で記載の通り、継続運用の為の対策を打ったり、機能拡張も計画しており、新規着手までは中々骨が折れそうですが、平行開発も踏まえ新しいサービス開発にも取り組めればと考えています。</p> <h1 id="ありそうな質問"><a href="#%E3%81%82%E3%82%8A%E3%81%9D%E3%81%86%E3%81%AA%E8%B3%AA%E5%95%8F">ありそうな質問</a></h1> <h2 id="仕様書や設計書はきちんと書いたの?"><a href="#%E4%BB%95%E6%A7%98%E6%9B%B8%E3%82%84%E8%A8%AD%E8%A8%88%E6%9B%B8%E3%81%AF%E3%81%8D%E3%81%A1%E3%82%93%E3%81%A8%E6%9B%B8%E3%81%84%E3%81%9F%E3%81%AE%EF%BC%9F">仕様書や設計書はきちんと書いたの?</a></h2> <p>ぶっちゃけるとほとんど書いていません。要件を前述のメモ (Apple) に数行書いた程度です。</p> <ul> <li>上記の機能一覧</li> <li>コード上の役割分担 <ul> <li>投稿タイプ、API、情報フィルタリング、テンプレートなどデータ定義・表示制御は「nijisanji」と呼ばれるテーマが担う</li> <li>YouTube API へのアクセス、スクレイピングなどデータ更新は「nijisanji-cron」と呼ばれるプラグインが担う</li> </ul></li> </ul> <p>代わりにコードへのコメントはしっかり入れています。<br /> また、可能な限り WordPress コア標準の仕組みを用いています。<br /> さらに作業中に発生した不要なコードやデータは逐次削除するなど、<br /> 仕様書が無くとも現状の確認で全体像が見えやすい工夫を行いました。</p> <p>趣味の個人開発だから出来ることだと思います。</p> <p>念の為補足ですが、余裕があれば情報は残すに越したことは無いと思います。</p> <h2 id="広告は入れないの?"><a href="#%E5%BA%83%E5%91%8A%E3%81%AF%E5%85%A5%E3%82%8C%E3%81%AA%E3%81%84%E3%81%AE%EF%BC%9F">広告は入れないの?</a></h2> <p>数年前に月間数十万PVのサイトを運営していた事もありますが、 Adsense も大した額にはなっていませんでした。<br /> 本サービスでも同等のアクセス数が稼げれば広告の導入を検討しますが、利便性も下げますので、導入は慎重に判断したいと思います。</p> <h2 id="事業化はしないの?"><a href="#%E4%BA%8B%E6%A5%AD%E5%8C%96%E3%81%AF%E3%81%97%E3%81%AA%E3%81%84%E3%81%AE%EF%BC%9F">事業化はしないの?</a></h2> <p>そもそも趣味のサービスですし、権利問題も絡みますので考えてないですが、公式関係者の方々にも使って頂けるサービスにはしたいと考えています。</p> <h1 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h1> <p>自分のような素人の書いた記事が参考になるのだろうか、と思う節もあり、中々重い腰が上がらなかったのですが、</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">すごいですね~。個人開発はじめたい人とかだとどうやってるか知りたい人多いかもしれないので、もし気が向いて且つ12月もたまたま無茶苦茶暇だったらカレンダーも是非w<a target="_blank" rel="nofollow noopener" href="https://t.co/iGA3PpFL6U">https://t.co/iGA3PpFL6U</a></p>— だら@技術系投稿サービス運営中 (@dala00) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/dala00/status/1067083123005902848?ref_src=twsrc%5Etfw">November 26, 2018</a></blockquote> <p>Crieit の<a href="https://crieit.net/users/dala00">だら</a>さんに直接お誘い頂き執筆するまでに至りました。<br /> 改めてお誘い頂きありがとうございました。</p> <p>何かしらの Advent Calendar への参加は初となりますが、夢でもあったので参加出来たことはとても光栄でした。</p> <p>また、これからウェブサービス開発を考えている方や、ウェブサービス開発中の方の一助になれば幸いです。</p> <p>ご質問、ご指摘、アドバイス大歓迎です。コメントや <a target="_blank" rel="nofollow noopener" href="https://twitter.com/">@sola_io</a> までリプライ、お気軽にお寄せ下さい。</p> <p>ここまで読んで頂いたすべてのみなさま、本当にありがとうございました。</p> <p><a href="https://crieit.net/advent-calendars/2018/technology">個人開発サービスに用いられている技術 Advent Calendar 2018</a>、明日は <a href="https://crieit.net/users/hrz31">Hiroz</a> さんの「Koretteのオモテとウラ」になります。<br /> そもそも「Korette」って何?というところも含め、とても気になりますね。</p> sola