<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Matsubo Tech Blog</title><description>Engineering, AI Agents, Cloud Native</description><link>https://blog.teraren.com/</link><language>ja</language><item><title>Raspberry Pi 4 + Debian 13 (Trixie) で RTL-SDR を使った ADS-B 受信局を構築して Flightradar24 にフィードした記録</title><link>https://blog.teraren.com/posts/2026-04-01-airband/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2026-04-01-airband/</guid><pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;航空機のリアルタイム追跡サービス「Flightradar24」に自作の受信機からデータをフィードすると、Contributor プランが無料で提供されます（Business Plan と同等の機能が使えます）。今回は、最新の Debian 13 (Trixie) 環境で RTL-SDR ドングルを使い、基地局（RJTT2257）を立ち上げた際の技術ログをまとめます。公式スクリプトが Cloudflare に弾かれ、最新の署名ポリシーがレガシーを拒絶するケースへの対処が必要でした。&lt;/p&gt;
&lt;h3&gt;1. 動作環境と構成&lt;/h3&gt;
&lt;p&gt;今回のスタックは以下の通りです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SBC:&lt;/strong&gt; Raspberry Pi 4 Model B (4GB)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OS:&lt;/strong&gt; Debian GNU/Linux 13 (trixie) aarch64&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SDR:&lt;/strong&gt; RTL2832U + R820T2&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Software:&lt;/strong&gt; readsb (Decoder) + fr24feed (Feeder)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RTL-SDR ドングルは AliExpress で数百円から購入できます。今回使用した RTL2832U + R820T2 チップセットのものが 1090MHz の ADS-B 受信に適しています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/04/aliexpress-rtlsdr.webp&quot; alt=&quot;AliExpress で購入できる RTL-SDR ドングル&quot; /&gt;&lt;/p&gt;
&lt;p&gt;公式のオールインワン・インストーラーに頼らず、デコーダーとフィーダーを疎結合にする構成を採用しました。これにより、SDRから上がってくる Raw データを 30005 ポート（Beast形式）で一旦受け、そこから各サービスに分配する拡張性を持たせています。&lt;/p&gt;
&lt;h3&gt;2. 最初の壁：Cloudflare の 403 Forbidden&lt;/h3&gt;
&lt;p&gt;構築を開始して早々、&lt;code&gt;get.flightradar24.com&lt;/code&gt; からのスクリプト取得が WAF（恐らく Cloudflare）に弾かれ、403 Forbidden が返される事態に遭遇しました。多くのエンジニアがここで躓きますが、これは &lt;code&gt;wget&lt;/code&gt; や &lt;code&gt;curl&lt;/code&gt; のデフォルト User-Agent が Bot と判定されているためです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解決策：User-Agent の偽装&lt;/strong&gt; ブラウザ（Chrome等）の文字列を模倣することで、セキュリティフィルタをパスします。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;curl -L -A &quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36&quot; [URL]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;このワンクッションを入れることで、リポジトリ署名キー（.pub）の取得に成功しました。&lt;/p&gt;
&lt;h3&gt;3. 次の壁：Debian 13 (Trixie) の厳格なセキュリティポリシー&lt;/h3&gt;
&lt;p&gt;Debian 13 (Trixie) では、2026年以降のポリシーとして SHA1 署名を用いたリポジトリが &lt;code&gt;apt update&lt;/code&gt; で拒絶されます。FR24 の公式リポジトリは依然として古い署名形式を使用しているため、そのままではインストールが不可能です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解決策：[trusted=yes] による強制バイパス&lt;/strong&gt; &lt;code&gt;/etc/apt/sources.list.d/fr24feed.list&lt;/code&gt; の定義に &lt;code&gt;[trusted=yes]&lt;/code&gt; を追記し、パッケージの署名検証を明示的にスキップさせることで解決しました。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;deb [trusted=yes] https://repo-feed.flightradar24.com flightradar24 raspberrypi-stable&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;4. 最後の壁：libssl1.1 の依存関係崩壊&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;fr24feed&lt;/code&gt; バイナリは古い &lt;code&gt;libssl1.1&lt;/code&gt; を要求しますが、Trixie 環境では &lt;code&gt;libssl3&lt;/code&gt; が標準であり、旧版ライブラリがリポジトリから削除されています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解決策：旧版 deb パッケージの直接導入&lt;/strong&gt; Ubuntu 20.04 等のアーカイブから &lt;code&gt;libssl1.1&lt;/code&gt; の aarch64 用 deb パッケージを取得し、&lt;code&gt;dpkg -i&lt;/code&gt; で無理やり流し込むことでバイナリのリンクエラーを解消しました。&lt;/p&gt;
&lt;h3&gt;5. フィーダー設定と運用ステータス&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/fr24feed.ini&lt;/code&gt; では、&lt;code&gt;readsb&lt;/code&gt; が開放している 127.0.0.1:30005 に接続するよう &lt;code&gt;beast-tcp&lt;/code&gt; 形式で指定します。&lt;/p&gt;
&lt;p&gt;港区・浜松町付近（RJTT周辺）に設置した結果、&lt;code&gt;btop&lt;/code&gt; での観測では CPU 使用率 3% 前後、温度 42°C という超低負荷で安定稼働。深夜帯でも羽田のアプローチ機を確実にトラッキングし、サーバーとの同期結果を示す &lt;code&gt;syncing stream result: 1&lt;/code&gt; を吐き出し続けています。&lt;/p&gt;
&lt;p&gt;tar1090 のローカル画面では、受信した航空機の位置がリアルタイムに描画されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/04/tar1090-screenshot.webp&quot; alt=&quot;tar1090 のリアルタイム受信画面&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Flightradar24 の統計ページでは、受信機ごとの受信機数・距離・機数などの実績が確認できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/04/flightradar24-stats.webp&quot; alt=&quot;Flightradar24 の統計ページ&quot; /&gt;&lt;/p&gt;
&lt;p&gt;データのフィードを継続することで Contributor として認定され、Business Plan 相当の機能が利用できるようになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/04/flightradar24-contributor.webp&quot; alt=&quot;Flightradar24 の Contributor 表示&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;まとめ&lt;/h3&gt;
&lt;p&gt;最新 OS での構築は依存関係の問題が連続しましたが、一つずつ解きほぐすことで稼働にこぎつけました。現在は &lt;strong&gt;RJTT2257&lt;/strong&gt; という局 ID で世界中の航空ファンにデータを提供しています。&lt;/p&gt;
&lt;p&gt;次は JE1WFV（アマチュア無線）としての知見を活かし、1090MHz 専用のバンドパスフィルタを自作して S/N 比を追い込み、受信距離の限界に挑戦する予定です。&lt;/p&gt;
</content:encoded></item><item><title>Claude Opus 4.6 + ブラウザ自動操作で2025年確定申告：CSV解析・仕訳生成・MoneyForward入力・e-Tax送信</title><link>https://blog.teraren.com/posts/tax-return-with-ai-agent-2025/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tax-return-with-ai-agent-2025/</guid><description>確定申告（青色・不動産所得+雑所得+株式分離課税）をAIエージェント主導で完走。去年の「あと少し」から1年で主従が逆転した記録。</description><pubDate>Tue, 17 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;TL;DR&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;確定申告（青色・不動産所得+雑所得+株式分離課税）を &lt;strong&gt;AIエージェント主導&lt;/strong&gt; で完走&lt;/li&gt;
&lt;li&gt;人間（自分）の実作業は &lt;strong&gt;約3.5時間&lt;/strong&gt;（e-Taxバグ対応除く）&lt;/li&gt;
&lt;li&gt;AIが経費の申告漏れや控除の見落としを的確に指摘してくれた&lt;/li&gt;
&lt;li&gt;使ったもの：&lt;strong&gt;Claude Opus 4.6 + AIエージェント基盤 + ブラウザ自動操作 + MoneyForward確定申告 + e-Tax&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;かかったコスト：MF月額 ¥380 + AI API 数千円程度&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;去年の記事：「あと少しのところまでできた」&lt;/h2&gt;
&lt;p&gt;去年（2025年3月）、同じく確定申告のAI化を試みた記事を書いた。&lt;/p&gt;
&lt;p&gt;https://note.com/matsubokkuri/n/nc976d5258e37&lt;/p&gt;
&lt;p&gt;去年のアプローチは &lt;strong&gt;Browser Use WebUI + OpenHands&lt;/strong&gt; で、確定申告書等作成コーナーのUIをブラウザ自動操作で埋めようとした。結果は：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ダミーデータで所得入力ページまでは自動遷移できた&lt;/li&gt;
&lt;li&gt;しかし &lt;strong&gt;入力値が間違っている箇所が多い&lt;/strong&gt;（指示した値と無関係な数字が入る）&lt;/li&gt;
&lt;li&gt;5回トライしても所得入力ページで&lt;strong&gt;停止してしまう&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;結局、&lt;strong&gt;MFで帳簿を手動で作り、e-Taxのサイトでひとつずつ手入力&lt;/strong&gt;した&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;去年の結論は「LLMが確定申告を行ってくれる未来はすぐそこに来ている」「来年にはできるようになっていそう」だった。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1年後の今年、本当にできた。&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;何が変わったのか：去年 → 今年&lt;/h2&gt;
&lt;p&gt;去年（2025年3月）と今年（2026年3月）で何が違うのか。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;LLM&lt;/strong&gt;: GPT-4 / Claude 3 → Claude Opus 4.6&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ブラウザ操作&lt;/strong&gt;: Browser Use WebUI（Playwright）→ AIエージェント基盤のブラウザ自動操作（CDP直接操作）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;データ入力&lt;/strong&gt;: 国税庁サイトのUIを直接操作（失敗）→ MFにCSVインポート + ブラウザ操作で補完&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;帳簿作成&lt;/strong&gt;: 手動 → AIが約50件の複式簿記仕訳を自動生成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;税務判断&lt;/strong&gt;: LLMに個別質問 → エージェントが文脈を保持して通しで判断&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ファイル解析&lt;/strong&gt;: なし → PDF OCR、CSV解析、XML解析&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;結果&lt;/strong&gt;: 所得入力で停止・手動完了 → &lt;strong&gt;e-Tax送信・納税まで完走&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;最大の違いは3つある。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;1. マルチモーダル対応&lt;/h3&gt;
&lt;p&gt;領収書の写真、ローン明細書の画像、過去の確定申告書PDFをそのまま渡せる。去年は全部人間がテキストに起こす必要があった。&lt;/p&gt;
&lt;h3&gt;2. ローカルファイルアクセス&lt;/h3&gt;
&lt;p&gt;Google Driveにマウントした確定申告フォルダを直接読める。クレカCSV（Shift_JIS）も銀行CSVも、AIが自分で開いて解析する。去年はコピペでLLMに渡していた。&lt;/p&gt;
&lt;h3&gt;3. 常駐エージェント&lt;/h3&gt;
&lt;p&gt;セッションを跨いで文脈が維持される。「あの物件の取得年は？」「さっき計算した利息は？」が全部記憶されている。去年は毎回ゼロから説明し直していた。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;エンジニア歴20年超。給与所得だけなら会社の年末調整で完結するが、不動産所得があるため確定申告が必要になる。副業収入（広告・アフィリエイト等）も微々たるものながらあり、所得の種類が多いせいで申告だけは毎年それなりに面倒。&lt;/p&gt;
&lt;p&gt;数年前までは税理士に依頼していたが、副業の収入に対して税理士報酬が10万円以上というのは本末転倒だし、結局こちら側の作業も多い。ある程度のノウハウを吸収したので自分でやるようになった。税理士に依頼していた時代の申告内容が過去データとして残っているので、最後にそれとの差分を確認すれば検証も楽。&lt;/p&gt;
&lt;p&gt;数ヶ月前からAIエージェントを常駐させて日常的に使い始めていたので、今年はそのまま確定申告にも投入してみた。人間はほぼ意思決定と認証操作だけ、という体制で挑んだ。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;申告の規模感&lt;/h2&gt;
&lt;p&gt;今回の確定申告の複雑さを伝えるために、項目だけ列挙する（金額は省略）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;所得の種類（6種類）：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;給与所得（本業）&lt;/li&gt;
&lt;li&gt;不動産所得（青色申告）&lt;/li&gt;
&lt;li&gt;雑所得-業務（広告収入、アフィリエイト、OSS）&lt;/li&gt;
&lt;li&gt;雑所得-その他（暗号資産・トークン取引）&lt;/li&gt;
&lt;li&gt;株式譲渡所得（損益通算）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;経費の種類：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不動産経費 9科目（利息、保険、減価償却、固定資産税、修繕費、外注費、車両費 等）&lt;/li&gt;
&lt;li&gt;雑所得経費 多数（通信費、クラウドサービス、AI利用料、消耗品 等）&lt;/li&gt;
&lt;li&gt;事業按分（項目ごとに異なる）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;控除：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;社会保険料、iDeCo、生命保険料、医療費、ふるさと納税（複数自治体）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;添付帳票：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;申告書（第一表〜第四表）、付表、青色申告決算書（一般用+不動産所得用）、計14枚&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;なぜ確定申告がこんなに面倒なのか&lt;/h2&gt;
&lt;p&gt;所得が給与だけなら年末調整で終わる。しかし不動産所得、副業収入、株式譲渡、暗号資産が加わると、マイナポータル連携だけでは全然足りない。&lt;/p&gt;
&lt;p&gt;今回の申告で扱ったデータソースを列挙する：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;源泉徴収票（PDF）&lt;/li&gt;
&lt;li&gt;クレカ年間利用明細（CSV・Shift_JIS）&lt;/li&gt;
&lt;li&gt;銀行ローン返済明細（CSV・Shift_JIS）&lt;/li&gt;
&lt;li&gt;固定資産税の領収書（写真）&lt;/li&gt;
&lt;li&gt;ローン残高証明書（画像）&lt;/li&gt;
&lt;li&gt;火災保険証券（XML）&lt;/li&gt;
&lt;li&gt;ふるさと納税証明（XML）&lt;/li&gt;
&lt;li&gt;特定口座年間取引報告書（XML）&lt;/li&gt;
&lt;li&gt;生命保険料控除証明書（XML）&lt;/li&gt;
&lt;li&gt;過去の確定申告書（PDF × 2年分）&lt;/li&gt;
&lt;li&gt;暗号資産の取引履歴（取引所の画面）&lt;/li&gt;
&lt;li&gt;アフィリエイト報酬画面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらを突合して、複式簿記の仕訳帳を作り、青色申告決算書を作り、申告書の各欄に正しい数字を入れていく。手作業でやると丸1日〜2日かかる。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;今年のブレイクスルー：控除関連のデータがXMLで一通りダウンロードできるようになった&lt;/strong&gt;こと。ふるさと納税、特定口座、生命保険料——これらがXMLだとLLMが構造的に読めるので、手入力が大幅に減った。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;人間が事前に用意したデータ&lt;/h2&gt;
&lt;p&gt;AIが勝手にデータを集めてくるわけではない。&lt;strong&gt;人間が各サービスからダウンロード・撮影して、Google Driveのフォルダに放り込む&lt;/strong&gt;という下準備が必要。ここが実は一番時間がかかる。&lt;/p&gt;
&lt;p&gt;Google Drive上に以下のフォルダ構成でデータを用意した：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tax/personal/2025 (R7)/
├── gensen/          ← 源泉徴収票（PDF）
├── credit_card/     ← クレカ年間明細（CSV + 月別PDF）
│   ├── 2025.csv         （Shift_JIS、全取引。事業按分の元データ）
│   └── pdf/             （月別利用明細PDF）
├── bank/            ← 銀行明細（ローン返済CSV、入金確認CSV 等）
├── stock/           ← 株式（特定口座XML + PDF + 売買CSV + 暗号資産取引CSV）
├── token/           ← トークン取引（CSV + スクショ）
├── furusato/        ← ふるさと納税（XML）
├── Insurance/       ← 保険（生命保険料控除証明書の写真、火災保険XML）
├── Loan/            ← ローン残高証明書（写真）
├── Tax/             ← 固定資産税の領収書（写真）
├── iryouhi/         ← 医療費の領収書（写真 + Googleスプレッドシート）
├── ad_revenue/      ← 広告収入の支払い画面（スクショ）
├── affiliate/       ← アフィリエイト報酬（CSV）
└── zz submit/       ← 最終提出物（xtx, PDF, 証明書XML）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;合計80ファイル超。&lt;/strong&gt; これを集めるのに人間が使った時間は約1時間（各サービスにログインしてダウンロード・撮影）。&lt;/p&gt;
&lt;p&gt;ポイントは以下の4つ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;XMLで取れるものはXMLで取る&lt;/strong&gt;（ふるさと納税、特定口座、保険）。LLMが構造的に読めるし、MFにそのままインポートもできる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CSVで取れるものはCSVで取る&lt;/strong&gt;（クレカ明細、銀行明細、アフィリエイト報酬）。LLMがパースして集計できる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;紙の書類は撮影してHEICのまま放り込む&lt;/strong&gt;（固定資産税、医療費、ローン証明書）。マルチモーダルLLMがそのまま読める&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スクショで済むものはスクショ&lt;/strong&gt;（広告収入の管理画面等）。PDF出力がない画面はこれで十分&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;去年との最大の違いは、&lt;strong&gt;写真やスクショをそのまま渡せるようになった&lt;/strong&gt;こと。去年はこれを全部人間がテキストに起こしていた。クレカCSVも銀行CSVもShift_JISだが、AIが自分で文字コードを判定して読んでくれる。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;構成&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    A[&quot;👤 人間（自分）&amp;lt;br/&amp;gt;意思決定・認証・物理作業&quot;] --&amp;gt;|チャット（Telegram / TUI）| B[&quot;🤖 AIエージェント&amp;lt;br/&amp;gt;Claude Opus 4.6 on AIエージェント基盤&quot;]
    B --&amp;gt;|ツール呼び出し| C[&quot;📁 ファイル読み書き&quot;]
    B --&amp;gt;|ツール呼び出し| D[&quot;🌐 ブラウザ操作(CDP)&quot;]
    B --&amp;gt;|ツール呼び出し| E[&quot;📄 PDF解析(OCR)&quot;]
    B --&amp;gt;|ツール呼び出し| F[&quot;🔍 Web検索&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ユースケース図&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    subgraph Actors
        Person[&quot;👤 人間&quot;]
        AI[&quot;🤖 AIエージェント&quot;]
    end

    subgraph &quot;データソース&quot;
        Receipt[&quot;📸 領収書・証明書&amp;lt;br/&amp;gt;（写真・PDF・XML）&quot;]
        Transaction[&quot;📊 取引記録&amp;lt;br/&amp;gt;（CSV・明細）&quot;]
        PrevTax[&quot;📄 過去の確定申告書&amp;lt;br/&amp;gt;（PDF）&quot;]
    end

    subgraph &quot;外部システム&quot;
        MF[&quot;MoneyForward&amp;lt;br/&amp;gt;確定申告&quot;]
        ETax[&quot;e-Tax&amp;lt;br/&amp;gt;Web版（Safari）&quot;]
        Browser[&quot;🌐 Chrome&amp;lt;br/&amp;gt;（CDP操作）&quot;]
    end

    Person --&amp;gt;|&quot;データ収集・撮影&quot;| Receipt
    Person --&amp;gt;|&quot;ダウンロード&quot;| Transaction
    Person --&amp;gt;|&quot;意思決定・承認&quot;| AI
    Person --&amp;gt;|&quot;XMLアップロード&quot;| MF
    Person --&amp;gt;|&quot;xtxダウンロード&quot;| MF
    Person --&amp;gt;|&quot;xtxアップロード・認証・送信&quot;| ETax

    AI --&amp;gt;|&quot;OCR・解析&quot;| Receipt
    AI --&amp;gt;|&quot;パース・集計&quot;| Transaction
    AI --&amp;gt;|&quot;スコープ把握&quot;| PrevTax
    AI --&amp;gt;|&quot;仕訳CSV生成&quot;| MF
    AI --&amp;gt;|&quot;CDP経由で操作&quot;| Browser
    Browser --&amp;gt;|&quot;UI操作&quot;| MF

    MF --&amp;gt;|&quot;xtx生成&quot;| Person
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用ツール&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AIエージェント基盤&lt;/strong&gt;: ツール実行、メモリ、セッション管理（ローカルマシン上で常駐）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Opus 4.6&lt;/strong&gt;: メインの頭脳（税務判断、計算、CSV解析、帳簿作成）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MoneyForward 確定申告&lt;/strong&gt;: 複式簿記・決算書・申告書・xtx生成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;e-Tax Web版&lt;/strong&gt;: 電子申告の送信&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ブラウザ自動操作（Chrome拡張）&lt;/strong&gt;: MoneyForwardのブラウザUI操作（CDP経由。e-TaxはSafari必須のため対象外）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pdfminer&lt;/strong&gt;: 過去の確定申告書PDFからのデータ抽出&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Drive&lt;/strong&gt;: 源泉徴収票、ローン明細、保険証券等の原本保管&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;タイムライン：3日間の流れ&lt;/h2&gt;
&lt;h3&gt;Day 1（金曜夜）— データ収集・方針決定&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;人間の作業：30分&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人間がやったこと：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google Driveの確定申告フォルダのパスを伝えた&lt;/li&gt;
&lt;li&gt;「2025年の確定申告やって」と指示&lt;/li&gt;
&lt;li&gt;いくつかの質問に答えた（物件の取得年、法人との関係 等）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;AIがやったこと：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google Drive上の全資料を読み込み・分類&lt;/li&gt;
&lt;li&gt;源泉徴収票PDFの解析&lt;/li&gt;
&lt;li&gt;クレカ年間CSV（Shift_JIS）の全明細読み込み・事業経費の候補抽出&lt;/li&gt;
&lt;li&gt;銀行CSVからローン利息の集計&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;過去の確定申告書PDF（直近2年分）をOCRで読み取り、過去の申告内容を把握&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;収入源の一覧化と分類（給与/不動産/雑所得/株式/非課税の仕分け）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ここでのポイント：過去の確定申告書PDFを渡すこと。&lt;/strong&gt; これが最も重要な一手だった。AIは過去の申告書から所得の種類・経費科目・控除項目のスコープを自動的に把握し、「何を聞けばいいか」を理解する。これがないとAIはひとつずつ「不動産所得はありますか？」「株式は？」と質問してくる。過去の申告書があれば、AIが勝手に全体像を掴んでプランを立ててくれる。&lt;/p&gt;
&lt;h3&gt;Day 2（土曜）— 調査・計算・申告漏れの洗い出し&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;人間の作業：30分&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人間がやったこと：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;固定資産税の領収書を撮影してチャットに送った&lt;/li&gt;
&lt;li&gt;「このサブスクは個人利用」「通信費の按分率はこれで」等の判断&lt;/li&gt;
&lt;li&gt;経費項目の最終承認&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;AIがやったこと：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;減価償却計算（耐用年数・取得価額・償却済み年数の調査）&lt;/li&gt;
&lt;li&gt;過去10年分の申告データと照合して未計上経費の発見（固定資産税が2年間未計上だった）&lt;/li&gt;
&lt;li&gt;領収書画像のOCR → 固定資産税を全期確定&lt;/li&gt;
&lt;li&gt;ローンの金利変動を反映した利息再計算&lt;/li&gt;
&lt;li&gt;事業按分率の提案と計算&lt;/li&gt;
&lt;li&gt;法人→個人の請求書をPDF生成（管理委託料、車両使用料、修繕費）&lt;/li&gt;
&lt;li&gt;税額の段階的試算（経費を追加するたびに再計算）&lt;/li&gt;
&lt;li&gt;「外国税額控除は数千円の効果しかないのでスキップ」等の費用対効果判断&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Day 3（日曜）— 帳簿作成・入力・提出&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;人間の作業：2時間&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;人間がやったこと：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MoneyForwardのアカウント契約（¥380/月）&lt;/li&gt;
&lt;li&gt;ふるさと納税XMLのアップロード（CDPの制約でAIからはファイルアップロード不可）&lt;/li&gt;
&lt;li&gt;マイナンバーの入力&lt;/li&gt;
&lt;li&gt;マイナンバーカード認証（QRコード読み取り）&lt;/li&gt;
&lt;li&gt;e-Tax送信（Safari必須のためブラウザ自動操作不可）&lt;/li&gt;
&lt;li&gt;クレジットカード納付&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;AIがやったこと：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MoneyForward用の仕訳CSV（約50件・複式簿記）を自動生成&lt;/li&gt;
&lt;li&gt;CSVインポート後の補助科目10件をブラウザ操作で一括登録&lt;/li&gt;
&lt;li&gt;固定資産台帳の設定修正（不動産割合、事業供用開始日）&lt;/li&gt;
&lt;li&gt;重複仕訳の検出・削除（React fiber経由でのDOM操作）&lt;/li&gt;
&lt;li&gt;青色申告決算書の不動産収入内訳をブラウザ操作で入力&lt;/li&gt;
&lt;li&gt;給与、雑所得、暗号資産、控除（6種類）をブラウザ操作で入力&lt;/li&gt;
&lt;li&gt;株式（分離課税）のXMLインポート確認&lt;/li&gt;
&lt;li&gt;配偶者情報の入力&lt;/li&gt;
&lt;li&gt;最終チェック（PDFをOCR → 全項目を期待値と突合）&lt;/li&gt;
&lt;li&gt;xtxダウンロード&lt;/li&gt;
&lt;li&gt;xtxの最終チェック&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;AIがブラウザを操作する&lt;/h2&gt;
&lt;p&gt;今回の肝は、AIがMoneyForwardのWebUIを &lt;strong&gt;CDP（Chrome DevTools Protocol）経由で直接操作&lt;/strong&gt; した点。&lt;/p&gt;
&lt;p&gt;MFのUIはReact製のSPAで、普通のセレクタではうまく動かない箇所が多い。AIは以下のようなテクニックを自力で編み出して対処していた：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MUI Selectコンポーネント&lt;/strong&gt;：&lt;code&gt;.MuiSelect-select&lt;/code&gt; に &lt;code&gt;mousedown&lt;/code&gt; イベントを発火 → ドロップダウンが開く → &lt;code&gt;.MuiMenuItem-root&lt;/code&gt; をクリック&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;React制御のinput&lt;/strong&gt;：&lt;code&gt;HTMLInputElement.prototype.value&lt;/code&gt; の setter で値を設定 → &lt;code&gt;input&lt;/code&gt; + &lt;code&gt;change&lt;/code&gt; イベントを発火&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;仕訳の削除&lt;/strong&gt;：React fiber を辿って &lt;code&gt;processing.dropdownMenu.onClickDeleteButton()&lt;/code&gt; を直接呼び出し&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;人間が手動でやれば30分の入力作業を、AIが試行錯誤しながら1〜2時間かけて自動化した。時間だけ見ると効率が悪いが、&lt;strong&gt;人間の手が空く&lt;/strong&gt;のが重要。AIが入力している間、自分は別のことをしていた。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;e-Tax Web版が動かない問題&lt;/h2&gt;
&lt;p&gt;提出段階で最大のトラブルが発生。e-Tax Web版（&lt;code&gt;clientweb.e-tax.nta.go.jp&lt;/code&gt;）にログインしても、メインコンテンツが&lt;strong&gt;完全に空白&lt;/strong&gt;で何も操作できない。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/etax-safari-blank.jpg&quot; alt=&quot;e-Tax Web版がSafariで空白表示になった画面&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Safari → ダメ。Chrome → ダメ。ポップアップ許可 → ダメ。&lt;/p&gt;
&lt;p&gt;開発者ツールのコンソールを確認したところ、原因が判明した：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Failed to load resource: 404 (Not Found)
  → /nls/etaxweb_dlparts_en-us.js

Error: Could not load &apos;dojo.nls.etaxweb_dlparts_en-us&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;e-Tax Web版はDojo Toolkit（JavaScriptフレームワーク）を使っていて、ブラウザの &lt;code&gt;Accept-Language&lt;/code&gt; ヘッダーから言語を判定し、対応するNLS（National Language Support）ファイルを読み込む。しかし &lt;code&gt;en-us&lt;/code&gt; 用のファイルが存在しない。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;自分のMacは &lt;code&gt;en-JP&lt;/code&gt;（英語UIで日本リージョン）に設定していたため、Dojoが英語リソースを探して404になり、画面描画が停止していた。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;修正：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;defaults write com.apple.Safari AppleLanguages &apos;(&quot;ja-JP&quot;, &quot;ja&quot;, &quot;en-JP&quot;, &quot;en&quot;)&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Safari再起動で即解決。&lt;strong&gt;確定申告期限前日に国税庁のUIバグで提出できない&lt;/strong&gt;というのは洒落にならない。英語環境のMacユーザーは要注意。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;AIによる申告漏れ・計上漏れの発見&lt;/h2&gt;
&lt;p&gt;今回最も価値があったのは、AIが経費や控除の&lt;strong&gt;漏れを自発的に指摘してくれた&lt;/strong&gt;こと。人間が「これ経費にできる？」と聞くのではなく、AIがデータを分析して「これ計上してないけど、経費にできるのでは？」と提案してくる。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AIが発見した主な申告漏れ・計上漏れ：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;過去に計上漏れしていた経費の発見&lt;/strong&gt;：過去の確定申告書PDFと今年の経費を突合して、計上すべきだった経費の漏れを指摘。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;減価償却の状態整理&lt;/strong&gt;：取得年・構造・耐用年数を調べ、償却完了済みかまだ残っているかを正確に仕分け。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事業按分の提案&lt;/strong&gt;：クレカCSVの全明細から事業関連の支出を抽出し、項目ごとに按分率を提案。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;経費の追加候補&lt;/strong&gt;：「AI利用料（Claude/ChatGPT）は雑所得の経費にできる」「実験用機材の購入も消耗品費として計上可能」等、人間が見落としていた項目を提案。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;費用対効果の判断&lt;/strong&gt;：「外国税額控除は数千円の効果しかないのでスキップ」「この控除証明書は自宅用で事業関係なし」等、やらなくていいことも明確にしてくれた。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これは税理士に頼んでも同じようなアドバイスをもらえるが、&lt;strong&gt;AIは全データを読んだ上で網羅的に指摘する&lt;/strong&gt;ので、見落としが少ない。しかもコストはAPI利用料数千円。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;人間 vs AI の分担まとめ&lt;/h2&gt;
&lt;p&gt;大きな流れはこうだ：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;序盤（データ収集）→ 人間&lt;/strong&gt;：各サービスにログインしてCSV・PDF・XMLをダウンロード、領収書を撮影してGoogle Driveに放り込む&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中盤（帳簿作成・申告書入力）→ AI&lt;/strong&gt;：仕訳の自動生成、MFへのブラウザ操作での入力、控除・経費の計算&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;終盤（提出・納税）→ 人間&lt;/strong&gt;：e-Tax送信（Safari必須）、マイナンバーカード認証、納税&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;加えて、途中で「納税額の概算はいくら？」と聞けば即座に試算してくれるし、「この経費は計上してないけど入れたほうがいいのでは？」と申告漏れの候補を自発的に提案してくれる。これが税理士不要で数千円のAPI利用料で得られるのは非常に大きい。&lt;/p&gt;
&lt;p&gt;具体的な分担は以下の通り。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;資料の収集・整理&lt;/strong&gt; → &lt;strong&gt;AI&lt;/strong&gt;（ファイルシステム+PDF解析で自動化）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;経費の分類・按分率決定&lt;/strong&gt; → &lt;strong&gt;AI提案→人間承認&lt;/strong&gt;（税務判断はAIが提案、最終判断は人間）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;帳簿（複式簿記）の作成&lt;/strong&gt; → &lt;strong&gt;AI&lt;/strong&gt;（CSV自動生成 → MFインポート）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MFへの入力&lt;/strong&gt; → &lt;strong&gt;AI（ブラウザ操作）&lt;/strong&gt;（CDP経由でReact UIを操作）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;XMLデータのアップロード&lt;/strong&gt; → &lt;strong&gt;人間&lt;/strong&gt;（CDPのセキュリティ制約でファイルアップロード不可）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;マイナンバー入力&lt;/strong&gt; → &lt;strong&gt;人間&lt;/strong&gt;（機密情報の直接入力）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最終レビュー&lt;/strong&gt; → &lt;strong&gt;AI&lt;/strong&gt;（PDF OCRで全項目を期待値と突合）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;e-Tax認証・送信&lt;/strong&gt; → &lt;strong&gt;人間&lt;/strong&gt;（マイナンバーカード認証にSafariが必須のため、ブラウザ自動操作の対象外）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/etax-send.png&quot; alt=&quot;e-Taxへの送信直前。帳票14枚がすべて揃った状態&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;納税&lt;/strong&gt; → &lt;strong&gt;人間&lt;/strong&gt;（クレジットカード決済）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;人間の実作業時間の内訳：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;作業&lt;/th&gt;
&lt;th&gt;時間&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;データ準備（撮影・ダウンロード・Google Driveに保存）&lt;/td&gt;
&lt;td&gt;約1.5時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AIとの対話（方針決定・承認・質問回答）&lt;/td&gt;
&lt;td&gt;約1時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MoneyForward操作（契約・アップロード等）&lt;/td&gt;
&lt;td&gt;約0.5時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;e-Taxのデバッグ（言語設定問題の解決）&lt;/td&gt;
&lt;td&gt;約3時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;e-Tax送信・納税&lt;/td&gt;
&lt;td&gt;約0.5時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;合計&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;約6.5時間&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;e-Taxのバグに3時間取られなければ&lt;strong&gt;約3.5時間&lt;/strong&gt;で完了していた。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;来年への改善メモ&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;MFの契約を忘れず解約する&lt;/strong&gt;（毎年1ヶ月だけ契約）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;納税方法の比較&lt;/strong&gt;：クレカ納付の手数料 vs ポイント還元率を確認して選択（高還元率カードならクレカ有利）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;e-Tax Web版はSafariの言語設定を &lt;code&gt;ja-JP&lt;/code&gt; にしてから使う&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ふるさと納税XMLのアップロード&lt;/strong&gt;を自動化できるとさらに省力化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;固定資産税の領収書&lt;/strong&gt;は届いた時点で撮影・Drive保存を習慣化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開業届を検討&lt;/strong&gt;：雑所得→事業所得への移行で損益通算が可能に&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;今回の確定申告の内容をスキル化しておく&lt;/strong&gt;：AIエージェントに「今回の申告内容を来年用にスキルとして保存して」と依頼しておけば、知識が圧縮されて来年はゼロからの質問がなくなる。変わった部分の差分だけ補完すればよい&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;まとめ：去年の予言は当たった&lt;/h2&gt;
&lt;p&gt;去年の記事の結論はこうだった：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;LLMが確定申告を行ってくれる未来はすぐそこに来ている気がします。来年(2026年)にはできるようになっていそうな気がします。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;1年でここまで変わった：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;帳簿作成&lt;/strong&gt;: 手動 → AI自動生成（約50仕訳）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;申告書入力&lt;/strong&gt;: 手動 → AI（ブラウザ操作）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人間の作業時間&lt;/strong&gt;: &lt;strong&gt;2日&lt;/strong&gt; → &lt;strong&gt;3時間&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI活用度&lt;/strong&gt;: &lt;strong&gt;5%&lt;/strong&gt;（仕訳の相談程度）→ &lt;strong&gt;85%&lt;/strong&gt;（データ収集→計算→入力→チェック→提出補助）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/tax-ai-ratio.png&quot; alt=&quot;作業負担の割合：主従が逆転&quot; /&gt;&lt;/p&gt;
&lt;p&gt;去年は「AIに聞きながら人間が作業」。今年は「AIが作業して人間が承認」。主従が完全に逆転した。&lt;/p&gt;
&lt;p&gt;AIエージェントを使った確定申告は、「AIに丸投げ」ではなく「&lt;strong&gt;AIが下準備・入力・チェックを担当し、人間は意思決定と認証だけ&lt;/strong&gt;」という分業モデルだ。&lt;/p&gt;
&lt;p&gt;一番面倒な「散在するデータを集めて、正しい科目に分類して、正しい金額を計算して、正しい欄に入力する」という作業がほぼ自動化できた。人間がやるのはマイナンバーカードをかざすことと、「これは経費？」「按分率は？」という判断だけ。&lt;/p&gt;
&lt;p&gt;今年の実績：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;🕐 人間の作業時間：&lt;strong&gt;約3.5時間&lt;/strong&gt;（e-Taxバグ除く）&lt;/li&gt;
&lt;li&gt;🤖 AIの稼働：&lt;strong&gt;データ収集→計算→入力→チェックを自動化&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;💡 AIが発見した申告漏れ・計上漏れ：&lt;strong&gt;多数&lt;/strong&gt;（経費計上漏れ、減価償却整理、経費追加候補 等）&lt;/li&gt;
&lt;li&gt;💸 コスト：&lt;strong&gt;MF ¥380のみ&lt;/strong&gt;（AI APIは既存契約内で追加費用なし）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;確定申告は「毎年同じような作業を、微妙に変わるルールで、締め切りに追われながらやる」典型的なタスク。AIエージェントとの相性は非常に良い。&lt;/p&gt;
&lt;p&gt;来年はもっと楽になるはず。（去年も同じこと言ってたけど、今年は本当にそう思う。）&lt;/p&gt;
&lt;p&gt;去年までは確定「深刻」だったが、今年からは深刻ではなくなった。&lt;/p&gt;
</content:encoded></item><item><title>Coolify環境のバックアップ戦略：6つのDBを自動ダンプ+復旧手順</title><link>https://blog.teraren.com/posts/coolify-backup-strategy/</link><guid isPermaLink="true">https://blog.teraren.com/posts/coolify-backup-strategy/</guid><description>Coolifyで運用中の6データベース・100+ボリュームを自動バックアップする設計と実装。復旧手順まで含めたDR戦略。</description><pubDate>Sun, 15 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;6つのデータベース&lt;/strong&gt;（PostgreSQL×2、MySQL×1、MariaDB×3）のダンプを毎日自動実行&lt;/li&gt;
&lt;li&gt;バックアップ先は &lt;strong&gt;mergerfs + snapraid&lt;/strong&gt; で冗長化されたストレージプール（7.2TB、3ドライブ構成）&lt;/li&gt;
&lt;li&gt;Coolifyの設定データ（&lt;code&gt;/data/coolify&lt;/code&gt;）もバージョニング付きで保存&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;復旧手順&lt;/strong&gt;を文書化して、災害時に「何をすればいいか」を明確にしました&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring&quot;&gt;第6回&lt;/a&gt;でZabbixによるリソース監視を構築しました。コンテナが「今どうなっているか」は見えるようになりました。次に必要なのは、&lt;strong&gt;「壊れたときにどう戻すか」&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;バックアップ対象の棚卸し&lt;/h2&gt;
&lt;p&gt;まず、何をバックアップすべきかを整理しました。&lt;/p&gt;
&lt;h3&gt;データベース一覧&lt;/h3&gt;
&lt;p&gt;現在のCoolify環境で稼働中のデータベースコンテナ。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;コンテナ&lt;/th&gt;
&lt;th&gt;エンジン&lt;/th&gt;
&lt;th&gt;サイズ&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;coolify-db&lt;/td&gt;
&lt;td&gt;PostgreSQL 15&lt;/td&gt;
&lt;td&gt;42 MB&lt;/td&gt;
&lt;td&gt;Coolify設定データ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;immich-database&lt;/td&gt;
&lt;td&gt;PostgreSQL 14 + pgvector&lt;/td&gt;
&lt;td&gt;1.2 GB&lt;/td&gt;
&lt;td&gt;写真管理（Immich）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zabbix MySQL&lt;/td&gt;
&lt;td&gt;MySQL LTS&lt;/td&gt;
&lt;td&gt;6.6 GB&lt;/td&gt;
&lt;td&gt;監視データ（Zabbix）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WordPress共有DB&lt;/td&gt;
&lt;td&gt;MariaDB 11.7&lt;/td&gt;
&lt;td&gt;678 MB&lt;/td&gt;
&lt;td&gt;WordPress 2サイト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI Moderator DB&lt;/td&gt;
&lt;td&gt;MariaDB 11&lt;/td&gt;
&lt;td&gt;3.1 GB&lt;/td&gt;
&lt;td&gt;AI Moderator + LipSync&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WordPress個別DB&lt;/td&gt;
&lt;td&gt;MariaDB 11&lt;/td&gt;
&lt;td&gt;162 MB&lt;/td&gt;
&lt;td&gt;WordPress（teraren.com）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;合計約12GBです。毎日のフルダンプでも十分に現実的なサイズです。&lt;/p&gt;
&lt;h3&gt;その他のバックアップ対象&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;対象&lt;/th&gt;
&lt;th&gt;場所&lt;/th&gt;
&lt;th&gt;重要度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Coolify設定&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/data/coolify&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;最重要&lt;/strong&gt; — アプリ定義、環境変数、秘密鍵すべて&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker volumes&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/var/lib/docker/volumes/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;100+ボリューム。DBは個別ダンプするので、それ以外&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zabbix agent設定&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/etc/zabbix/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;設定ファイル。手動で再現可能だが保存しておく&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cloudflared設定&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/etc/cloudflared/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tunnel設定。トークンが入っている&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;crontab&lt;/td&gt;
&lt;td&gt;&lt;code&gt;crontab -l&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;定期実行ジョブの定義&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;バックアップ先のストレージ構成&lt;/h2&gt;
&lt;h3&gt;mergerfs + snapraid&lt;/h3&gt;
&lt;p&gt;バックアップ先として、すでに構築済みの mergerfs + snapraid ストレージプールを使います。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/mnt/data1 (3.6TB HDD) ─┐
/mnt/data2 (1.8TB HDD) ─┼─ mergerfs ─→ /mnt/storage (7.2TB pool)
/mnt/data3 (1.8TB HDD) ─┘
/mnt/parity (parity disk) ─→ snapraid parity
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;値&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;総容量&lt;/td&gt;
&lt;td&gt;7.2 TB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;使用済み&lt;/td&gt;
&lt;td&gt;1.6 TB（22%）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;空き容量&lt;/td&gt;
&lt;td&gt;5.5 TB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;パリティ&lt;/td&gt;
&lt;td&gt;1ドライブ（1台故障まで復元可能）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;作成ポリシー&lt;/td&gt;
&lt;td&gt;epmfs（最も空き容量の多いドライブに配置）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;mergerfsの利点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;複数ドライブを1つのマウントポイントに統合。アプリからは単一パスに見えます&lt;/li&gt;
&lt;li&gt;JBODなので、1台が壊れても他のドライブのデータは無事&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;snapraidの利点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;パリティドライブで1台分の冗長性を確保&lt;/li&gt;
&lt;li&gt;常時同期ではなく定期実行。省電力&lt;/li&gt;
&lt;li&gt;既存データの保護に特化（追記メインのバックアップに最適）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;バックアップスクリプト&lt;/h2&gt;
&lt;h3&gt;設計方針&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;データベースはロジカルダンプ&lt;/strong&gt;（&lt;code&gt;pg_dump&lt;/code&gt;、&lt;code&gt;mysqldump&lt;/code&gt;）。バイナリコピーは復元が面倒&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;世代管理は7日分&lt;/strong&gt;。古いダンプは自動削除&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coolify設定は rsync&lt;/strong&gt;。差分コピーで高速&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ログを残す&lt;/strong&gt;。成功・失敗がわかるように&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;スクリプト全体&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/home/matsu/bin/coolify-backup.sh&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
set -euo pipefail

# === 設定 ===
BACKUP_BASE=&quot;/mnt/storage/coolify-backups&quot;
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=7
LOG_FILE=&quot;${BACKUP_BASE}/backup.log&quot;

mkdir -p &quot;${BACKUP_BASE}/db&quot; &quot;${BACKUP_BASE}/coolify-config&quot; &quot;${BACKUP_BASE}/system-config&quot;

log() {
    echo &quot;[$(date &apos;+%Y-%m-%d %H:%M:%S&apos;)] $1&quot; | tee -a &quot;$LOG_FILE&quot;
}

log &quot;=== バックアップ開始 ===&quot;

# === 1. PostgreSQL ダンプ ===
log &quot;PostgreSQL: coolify-db&quot;
docker exec coolify-db pg_dumpall -U coolify \
    | gzip &amp;gt; &quot;${BACKUP_BASE}/db/coolify-db_${DATE}.sql.gz&quot;

log &quot;PostgreSQL: immich-database&quot;
IMMICH_DB=$(docker ps --format &apos;{{.Names}}&apos; | grep immich-database)
docker exec &quot;$IMMICH_DB&quot; pg_dumpall -U postgres \
    | gzip &amp;gt; &quot;${BACKUP_BASE}/db/immich-db_${DATE}.sql.gz&quot;

# === 2. MySQL / MariaDB ダンプ ===
# Zabbix MySQL
ZABBIX_MYSQL=$(docker ps --format &apos;{{.Names}}&apos; | grep -E &apos;^fswk&apos;)
log &quot;MySQL: Zabbix ($ZABBIX_MYSQL)&quot;
docker exec &quot;$ZABBIX_MYSQL&quot; mysqldump -u root --all-databases --single-transaction \
    | gzip &amp;gt; &quot;${BACKUP_BASE}/db/zabbix-mysql_${DATE}.sql.gz&quot;

# WordPress 共有 MariaDB
WP_SHARED_DB=$(docker ps --format &apos;{{.Names}}&apos; | grep -E &apos;^fqff&apos;)
log &quot;MariaDB: WordPress共有 ($WP_SHARED_DB)&quot;
docker exec &quot;$WP_SHARED_DB&quot; mariadb-dump -u root --all-databases --single-transaction \
    | gzip &amp;gt; &quot;${BACKUP_BASE}/db/wp-shared-db_${DATE}.sql.gz&quot;

# AI Moderator MariaDB
log &quot;MariaDB: AI Moderator&quot;
docker exec ai-moderator-lipsync-db-1 mariadb-dump -u root --all-databases --single-transaction \
    | gzip &amp;gt; &quot;${BACKUP_BASE}/db/ai-moderator-db_${DATE}.sql.gz&quot;

# WordPress 個別 MariaDB
WP_TERA_DB=$(docker ps --format &apos;{{.Names}}&apos; | grep -E &apos;^p8sg&apos;)
log &quot;MariaDB: WordPress teraren ($WP_TERA_DB)&quot;
docker exec &quot;$WP_TERA_DB&quot; mariadb-dump -u root --all-databases --single-transaction \
    | gzip &amp;gt; &quot;${BACKUP_BASE}/db/wp-teraren-db_${DATE}.sql.gz&quot;

# === 3. Coolify 設定ディレクトリ ===
log &quot;Coolify設定: /data/coolify&quot;
sudo rsync -a --delete /data/coolify/ &quot;${BACKUP_BASE}/coolify-config/&quot;

# === 4. システム設定 ===
log &quot;システム設定のバックアップ&quot;
sudo cp -r /etc/zabbix/ &quot;${BACKUP_BASE}/system-config/zabbix/&quot; 2&amp;gt;/dev/null || true
sudo cp -r /etc/cloudflared/ &quot;${BACKUP_BASE}/system-config/cloudflared/&quot; 2&amp;gt;/dev/null || true
crontab -l &amp;gt; &quot;${BACKUP_BASE}/system-config/crontab.txt&quot; 2&amp;gt;/dev/null || true

# === 5. 古いバックアップの削除 ===
log &quot;古いバックアップの削除 (${RETENTION_DAYS}日以上)&quot;
find &quot;${BACKUP_BASE}/db&quot; -name &quot;*.sql.gz&quot; -mtime +${RETENTION_DAYS} -delete

# === 6. サイズ確認 ===
TOTAL_SIZE=$(du -sh &quot;${BACKUP_BASE}&quot; | cut -f1)
log &quot;バックアップ完了。合計サイズ: ${TOTAL_SIZE}&quot;
log &quot;=== バックアップ終了 ===&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;crontab への登録&lt;/h3&gt;
&lt;p&gt;毎日 AM 4:00 に実行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Coolify環境の全DBバックアップ + 設定バックアップ
0 4 * * * /home/matsu/bin/coolify-backup.sh &amp;gt;&amp;gt; /tmp/coolify-backup.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;復旧手順&lt;/h2&gt;
&lt;p&gt;バックアップは取るだけでは意味がありません。&lt;strong&gt;「壊れたときに何をするか」&lt;/strong&gt; が明確でないと、パニック時に役に立ちません。&lt;/p&gt;
&lt;h3&gt;ケース1: データベースの破損&lt;/h3&gt;
&lt;p&gt;特定のデータベースだけが壊れた場合。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 最新のダンプを確認
ls -lt /mnt/storage/coolify-backups/db/ | head -10

# PostgreSQL の復元（例: coolify-db）
gunzip -c /mnt/storage/coolify-backups/db/coolify-db_YYYYMMDD_HHMMSS.sql.gz \
    | docker exec -i coolify-db psql -U coolify

# MariaDB の復元（例: WordPress）
gunzip -c /mnt/storage/coolify-backups/db/wp-shared-db_YYYYMMDD_HHMMSS.sql.gz \
    | docker exec -i &amp;lt;container_name&amp;gt; mariadb -u root
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ケース2: Coolifyの再インストール&lt;/h3&gt;
&lt;p&gt;サーバは生きているが、Coolify自体が壊れた場合。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 1. Coolify を再インストール
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash

# 2. 設定を復元
sudo systemctl stop coolify
sudo rsync -a /mnt/storage/coolify-backups/coolify-config/ /data/coolify/
sudo systemctl start coolify

# 3. データベースの復元は不要（設定に含まれている）
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ケース3: サーバの全損&lt;/h3&gt;
&lt;p&gt;ハードウェア故障でOSごと失った場合。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 1. 新しいサーバにOSをインストール（Debian/Ubuntu）
# 2. mergerfsストレージをマウント（HDDが無事であれば）
# 3. Coolify をインストール
curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash

# 4. 設定を復元
sudo rsync -a /mnt/storage/coolify-backups/coolify-config/ /data/coolify/

# 5. 各データベースを順番に復元
for dump in /mnt/storage/coolify-backups/db/*_latest.sql.gz; do
    echo &quot;Restoring: $dump&quot;
    # DB種類に応じて pg_restore or mysql で復元
done

# 6. cloudflared を再設定
sudo cp -r /mnt/storage/coolify-backups/system-config/cloudflared/ /etc/cloudflared/
sudo systemctl restart cloudflared

# 7. Zabbix agent を再設定
sudo cp -r /mnt/storage/coolify-backups/system-config/zabbix/ /etc/zabbix/
sudo systemctl restart zabbix-agent2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ケース4: snapraid ドライブ障害&lt;/h3&gt;
&lt;p&gt;mergerfsプール内の1台が故障した場合。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 1. 故障したドライブを特定
sudo smartctl -a /dev/sdX

# 2. 新しいドライブを同じマウントポイントにマウント
# 3. snapraid fix で復元
sudo snapraid fix -d dN

# 4. パリティを再構築
sudo snapraid sync
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;バックアップの検証&lt;/h2&gt;
&lt;p&gt;バックアップは「取っている」だけでは不十分です。&lt;strong&gt;定期的に復元テスト&lt;/strong&gt;をすべきです。&lt;/p&gt;
&lt;h3&gt;簡易チェック（毎日）&lt;/h3&gt;
&lt;p&gt;バックアップスクリプトのログで、ファイルサイズがゼロでないことを確認。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ダンプファイルが空でないか確認
find /mnt/storage/coolify-backups/db/ -name &quot;*.sql.gz&quot; -size 0 -print
# 出力がなければOK
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;復元テスト（月1回推奨）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# テスト用コンテナでダンプを読み込んでみる
docker run --rm -i postgres:15-alpine psql -U postgres &amp;lt; test_dump.sql
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;オフサイトバックアップ（将来の拡張）&lt;/h2&gt;
&lt;p&gt;現在のバックアップは同一サーバ内の別ドライブです。火事や盗難には対応できません。将来的には：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方式&lt;/th&gt;
&lt;th&gt;コスト&lt;/th&gt;
&lt;th&gt;特徴&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Backblaze B2&lt;/td&gt;
&lt;td&gt;~$0.5/月（12GB）&lt;/td&gt;
&lt;td&gt;安い。S3互換API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rclone + Google Drive&lt;/td&gt;
&lt;td&gt;$0（15GBまで）&lt;/td&gt;
&lt;td&gt;無料枠で収まる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;物理メディア（USB HDD）&lt;/td&gt;
&lt;td&gt;初期費用のみ&lt;/td&gt;
&lt;td&gt;最もシンプル。月1回持ち出し&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;12GBのDBダンプなら、Backblaze B2で月$0.5以下です。導入するなら rclone でスクリプトに1行追加するだけです。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;対象&lt;/th&gt;
&lt;th&gt;方式&lt;/th&gt;
&lt;th&gt;頻度&lt;/th&gt;
&lt;th&gt;保持期間&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;データベース（6つ）&lt;/td&gt;
&lt;td&gt;ロジカルダンプ + gzip&lt;/td&gt;
&lt;td&gt;毎日 AM 4:00&lt;/td&gt;
&lt;td&gt;7日分&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coolify設定&lt;/td&gt;
&lt;td&gt;rsync&lt;/td&gt;
&lt;td&gt;毎日 AM 4:00&lt;/td&gt;
&lt;td&gt;最新のみ（差分）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;システム設定&lt;/td&gt;
&lt;td&gt;ファイルコピー&lt;/td&gt;
&lt;td&gt;毎日 AM 4:00&lt;/td&gt;
&lt;td&gt;最新のみ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ストレージ冗長化&lt;/td&gt;
&lt;td&gt;snapraid parity&lt;/td&gt;
&lt;td&gt;定期sync&lt;/td&gt;
&lt;td&gt;パリティ1台分&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;バックアップは「やらなきゃ」と思いつつ後回しにしがちです。でも、&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring&quot;&gt;第6回&lt;/a&gt;でsentinelが5.2GBメモリを食っていたことを発見したように、&lt;strong&gt;見えていないリスクは常にあります&lt;/strong&gt;。バックアップスクリプト1本と、復旧手順の文書化。これだけで「壊れても戻せる」安心感が手に入ります。&lt;/p&gt;
&lt;h3&gt;シリーズ記事&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas/&quot;&gt;Vercel月額$42→自宅サーバ月額$0。Coolifyで個人サービス基盤を作った話&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-claude-code-mcp/&quot;&gt;Coolifyインストールから「プロンプトでデプロイ」まで：Claude Code MCP実践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-hands-on-deploy/&quot;&gt;Coolifyハンズオン：Hono・Go・Railsを実際にデプロイしてみる&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-cloudflare-tunnel/&quot;&gt;Cloudflare Tunnel×Coolify：自宅サーバを安全に外部公開する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-llm-era-self-hosting/&quot;&gt;API-firstなインフラが生き残る：LLM時代のセルフホスト戦略&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring/&quot;&gt;ZabbixでDockerコンテナをリソース監視する：Coolify環境の可視化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coolify環境のバックアップ戦略：6つのDBを自動ダンプ+復旧手順&lt;/strong&gt;（この記事）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-log-management-incident-response/&quot;&gt;Coolify環境のログ管理と障害対応：Docker + Zabbix + Discordで運用を回す&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Coolify環境のログ管理と障害対応：Docker + Zabbix + Discordで運用を回す</title><link>https://blog.teraren.com/posts/coolify-log-management-incident-response/</link><guid isPermaLink="true">https://blog.teraren.com/posts/coolify-log-management-incident-response/</guid><description>30+コンテナのログ管理、Docker log rotation設定、ZabbixアラートのDiscord通知、実際に発生した障害の対応事例。セルフホストの運用ルーティンを確立する。</description><pubDate>Sun, 15 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Docker json-file ドライバ&lt;/strong&gt;のログローテーション設定で、ディスク溢れを防止&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zabbix → Discord Webhook&lt;/strong&gt;で障害をリアルタイム通知&lt;/li&gt;
&lt;li&gt;実際に発生した障害（MySQL停止、swap圧迫、SSL証明書エラー）の対応事例&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;journald + docker logs + Zabbix&lt;/strong&gt;の3層で「何が起きているか」を把握する運用フロー&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring&quot;&gt;第6回&lt;/a&gt;でリソース監視、&lt;a href=&quot;/posts/coolify-backup-strategy&quot;&gt;第7回&lt;/a&gt;でバックアップ戦略を構築しました。最後のピースは &lt;strong&gt;「何か起きたとき、どう気づいて、どう対応するか」&lt;/strong&gt; です。&lt;/p&gt;
&lt;h2&gt;ログの全体像&lt;/h2&gt;
&lt;p&gt;Coolify環境には3つのログソースがあります。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;レイヤー&lt;/th&gt;
&lt;th&gt;ソース&lt;/th&gt;
&lt;th&gt;確認方法&lt;/th&gt;
&lt;th&gt;主な用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;systemd journald&lt;/td&gt;
&lt;td&gt;&lt;code&gt;journalctl -u &amp;lt;service&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;cloudflared、zabbix-agent2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;コンテナ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Docker json-file&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker logs &amp;lt;container&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;アプリログ、DBログ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;監視&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Zabbix&lt;/td&gt;
&lt;td&gt;Web UI / API&lt;/td&gt;
&lt;td&gt;トリガー、アラート履歴&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;この3つを組み合わせて「何が起きているか」を把握します。&lt;/p&gt;
&lt;h2&gt;Docker ログローテーション&lt;/h2&gt;
&lt;h3&gt;デフォルトの罠&lt;/h3&gt;
&lt;p&gt;Dockerのデフォルトログドライバは &lt;code&gt;json-file&lt;/code&gt; で、&lt;strong&gt;ローテーションなし&lt;/strong&gt;です。放置するとログファイルが際限なく膨らんでディスクを食い潰します。30+コンテナが動いている環境では致命的です。&lt;/p&gt;
&lt;h3&gt;設定&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/docker/daemon.json&lt;/code&gt; でグローバルに設定済みです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;log-driver&quot;: &quot;json-file&quot;,
  &quot;log-opts&quot;: {
    &quot;max-size&quot;: &quot;10m&quot;,
    &quot;max-file&quot;: &quot;3&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;設定&lt;/th&gt;
&lt;th&gt;値&lt;/th&gt;
&lt;th&gt;意味&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max-size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10m&lt;/td&gt;
&lt;td&gt;1ファイル最大10MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max-file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;最大3ファイル保持&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;コンテナあたり上限&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;30MB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10MB × 3ファイル&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;全体上限（30コンテナ）&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;約900MB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;十分に制御可能&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;この設定がないと、ログが活発なコンテナ（Railsアプリ、Traefik）で数GBに膨らむことがあります。&lt;/p&gt;
&lt;h3&gt;確認方法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 各コンテナのログサイズ確認
sudo du -sh /var/lib/docker/containers/*/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;アラート通知：Zabbix → Discord&lt;/h2&gt;
&lt;h3&gt;なぜDiscordなのか&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;通知先&lt;/th&gt;
&lt;th&gt;コスト&lt;/th&gt;
&lt;th&gt;セットアップ&lt;/th&gt;
&lt;th&gt;モバイル通知&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Email&lt;/td&gt;
&lt;td&gt;無料&lt;/td&gt;
&lt;td&gt;SMTPサーバ必要&lt;/td&gt;
&lt;td&gt;△&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Slack&lt;/td&gt;
&lt;td&gt;無料枠あり&lt;/td&gt;
&lt;td&gt;Webhook簡単&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Discord&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;無料&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Webhook簡単&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Telegram&lt;/td&gt;
&lt;td&gt;無料&lt;/td&gt;
&lt;td&gt;Bot作成必要&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PagerDuty&lt;/td&gt;
&lt;td&gt;有料&lt;/td&gt;
&lt;td&gt;エンタープライズ向け&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;個人開発者にとって、Discordが最適解です。無料、Webhook作成が30秒、スマホ通知あり、メッセージの色分け（Severity）にも対応しています。&lt;/p&gt;
&lt;h3&gt;Discord Webhook の設定&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Discordサーバーで「サーバー設定 → 連携サービス → ウェブフック」&lt;/li&gt;
&lt;li&gt;「新しいウェブフック」を作成。チャンネルは &lt;code&gt;#alerts&lt;/code&gt; 等&lt;/li&gt;
&lt;li&gt;Webhook URLをコピー&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Zabbix側の設定&lt;/h3&gt;
&lt;p&gt;Zabbixには&lt;strong&gt;Discordメディアタイプが標準搭載&lt;/strong&gt;されています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Alerts → Media types → Discord&lt;/strong&gt; を開く（status: Enabled）&lt;/li&gt;
&lt;li&gt;Trigger actionsを作成：
&lt;ul&gt;
&lt;li&gt;Alerts → Actions → Trigger actions → Create action&lt;/li&gt;
&lt;li&gt;Conditions: Trigger severity &amp;gt;= Warning&lt;/li&gt;
&lt;li&gt;Operations: Send to Discord（Admin userのMedia設定にDiscord Webhook URLを追加）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;通知の内容&lt;/h3&gt;
&lt;p&gt;Zabbixの標準Discord Webhookは、Severity に応じた色分け付きで通知されます。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Severity&lt;/th&gt;
&lt;th&gt;色&lt;/th&gt;
&lt;th&gt;例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Information&lt;/td&gt;
&lt;td&gt;青&lt;/td&gt;
&lt;td&gt;コンテナ再起動検知&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Warning&lt;/td&gt;
&lt;td&gt;黄&lt;/td&gt;
&lt;td&gt;swap使用率 &amp;gt; 50%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Average&lt;/td&gt;
&lt;td&gt;オレンジ&lt;/td&gt;
&lt;td&gt;コンテナ停止&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;赤&lt;/td&gt;
&lt;td&gt;MySQLダウン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Disaster&lt;/td&gt;
&lt;td&gt;濃赤&lt;/td&gt;
&lt;td&gt;サーバー到達不能&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;実際に発生した障害事例&lt;/h2&gt;
&lt;p&gt;監視を入れたことで、実際にいくつかの問題を検知・対応できました。&lt;/p&gt;
&lt;h3&gt;事例1: MySQL停止（High）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;問題: MySQL: Service is down
ホスト: gmk
継続時間: 6日以上
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WordPressの旧MySQL（移行前のレガシーDB）が停止していました。Coolifyのリソース画面でも &lt;code&gt;Exited&lt;/code&gt; 表示です。現在は使っていないDBなので、意図的に停止したまま放置していますが、&lt;strong&gt;監視がなければ「本番DBが落ちていた」場合に気づけませんでした&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;対応: Zabbixでこのトリガーをacknowledgeし、不要ならコンテナを削除します。&lt;/p&gt;
&lt;h3&gt;事例2: swap圧迫（Warning）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;問題: Linux: High swap space usage (less than 50% free)
ホスト: gmk
継続時間: 2日以上
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;32GB RAMの環境でswapが圧迫されています。&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring&quot;&gt;第6回&lt;/a&gt;で発見した&lt;strong&gt;coolify-sentinelの5.2GBメモリ使用&lt;/strong&gt;が主因です。30+コンテナの合計メモリ使用量がRAMを超え始めています。&lt;/p&gt;
&lt;p&gt;対応: sentinel以外のメモリ消費を確認し、不要なコンテナを停止しました。長期的にはRAM増設（64GB）を検討しています。&lt;/p&gt;
&lt;h3&gt;事例3: SSL証明書エラー（Traefik）&lt;/h3&gt;
&lt;p&gt;Traefik（coolify-proxy）のログに繰り返しエラーが出ていました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ERR Unable to obtain ACME certificate for domains
    domains=[&quot;coolify.teraren.com&quot;]
    error=&quot;too many failed authorizations&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;原因: Cloudflare Access（Zero Trust）でcoolify.teraren.comを保護しているため、Let&apos;s EncryptのHTTP-01チャレンジがCloudflare Accessのログインページにリダイレクトされて認証に失敗します。&lt;/p&gt;
&lt;p&gt;対応: Cloudflare Tunnel経由のサービスはCloudflare側でSSL終端するため、&lt;strong&gt;Traefik側のLet&apos;s Encrypt証明書は不要&lt;/strong&gt;です。&lt;a href=&quot;/posts/coolify-cloudflare-tunnel&quot;&gt;第4回&lt;/a&gt;で説明した通り、CoolifyのドメインはHTTPで設定します。このエラーは無視して問題ありません。&lt;/p&gt;
&lt;h3&gt;事例4: コンテナの異常再起動&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;問題: Docker: Container /immich: Container has restarted 11 times
ホスト: gmk
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Immich（写真管理）のコンテナが11回再起動していました。Coolifyのリソース画面でも &lt;code&gt;(11x restarts)&lt;/code&gt; と表示されています。&lt;/p&gt;
&lt;p&gt;対応: &lt;code&gt;docker logs&lt;/code&gt; でImmichのログを確認しました。メモリ不足でOOM Killerに殺されていました。Immichのメモリ制限を調整しました。&lt;/p&gt;
&lt;h2&gt;障害対応フロー&lt;/h2&gt;
&lt;p&gt;障害が発生したときの対応手順を標準化しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;1. Discord通知を受信
   ↓
2. Zabbix Web UIで詳細確認
   - どのホスト？どのトリガー？いつから？
   ↓
3. ログ確認
   - OS系: journalctl -u &amp;lt;service&amp;gt; --since &quot;1 hour ago&quot;
   - コンテナ系: docker logs --tail 100 &amp;lt;container&amp;gt;
   - Traefik: docker logs coolify-proxy --tail 50
   ↓
4. 対応
   - コンテナ再起動: docker restart &amp;lt;container&amp;gt;
   - Coolify経由: Coolify UI → アプリ → Restart
   - 設定変更: Coolify UI or MCP経由
   ↓
5. 確認
   - Zabbixでトリガーが解消されたか確認
   - アプリにアクセスして正常動作を確認
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;よく使うログコマンド&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# === OS サービス ===
# cloudflaredのログ（Tunnel障害時）
journalctl -u cloudflared --since &quot;1 hour ago&quot; --no-pager

# zabbix-agentのログ
journalctl -u zabbix-agent2 --since &quot;1 hour ago&quot; --no-pager

# === Docker コンテナ ===
# 特定コンテナの最新ログ
docker logs --tail 100 &amp;lt;container_name&amp;gt;

# リアルタイムログ（Ctrl+Cで終了）
docker logs -f &amp;lt;container_name&amp;gt;

# タイムスタンプ付き
docker logs --tail 50 -t &amp;lt;container_name&amp;gt;

# === 横断的な確認 ===
# 全コンテナの状態一覧
docker ps --format &quot;table {{.Names}}\t{{.Status}}\t{{.RunningFor}}&quot;

# 異常終了したコンテナ
docker ps -a --filter &quot;status=exited&quot; --format &quot;table {{.Names}}\t{{.Status}}&quot;

# ディスク使用量
docker system df
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Coolify UIのログ機能&lt;/h2&gt;
&lt;p&gt;CoolifyのWeb UIにもログ表示機能があります。各アプリの詳細画面 → Logsタブで、コンテナログをブラウザから確認できます。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Coolify UI → Logs&lt;/td&gt;
&lt;td&gt;ブラウザから手軽に確認。外出先でも&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker logs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;詳細な検索。grep等でフィルタ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zabbix&lt;/td&gt;
&lt;td&gt;異常検知・アラート。過去のイベント履歴&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;普段はZabbixのアラートで異常に気づき、Coolify UIかdocker logsで詳細を確認する流れです。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;要素&lt;/th&gt;
&lt;th&gt;構成&lt;/th&gt;
&lt;th&gt;目的&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ログローテーション&lt;/td&gt;
&lt;td&gt;Docker json-file 10MB×3&lt;/td&gt;
&lt;td&gt;ディスク溢れ防止&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;アラート通知&lt;/td&gt;
&lt;td&gt;Zabbix → Discord Webhook&lt;/td&gt;
&lt;td&gt;リアルタイムで障害検知&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ログ確認&lt;/td&gt;
&lt;td&gt;journald + docker logs + Coolify UI&lt;/td&gt;
&lt;td&gt;原因調査&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;障害対応&lt;/td&gt;
&lt;td&gt;標準化されたフロー&lt;/td&gt;
&lt;td&gt;パニックせずに対応&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;セルフホストの運用は「監視 → アラート → ログ確認 → 対応」のサイクルを回すことが大切です。Zabbix（&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring&quot;&gt;第6回&lt;/a&gt;）で監視し、Discordで通知を受け、docker logsで原因を調べ、Coolify UIかMCPで対応します。バックアップ（&lt;a href=&quot;/posts/coolify-backup-strategy&quot;&gt;第7回&lt;/a&gt;）があれば、最悪の場合でも復旧できます。&lt;/p&gt;
&lt;p&gt;このシリーズで構築した環境の全体像：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;GitHub Push → Coolify（自動ビルド&amp;amp;デプロイ）
                ↕
         Cloudflare Tunnel（外部公開）
                ↕
         Zabbix（監視） → Discord（通知）
                ↕
         mergerfs + snapraid（バックアップ）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Vercel月額$42から始まった話が、&lt;strong&gt;月額$0で監視・バックアップ・アラート通知まで揃った自宅PaaS環境&lt;/strong&gt;になりました。&lt;/p&gt;
&lt;h3&gt;シリーズ記事&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas/&quot;&gt;Vercel月額$42→自宅サーバ月額$0。Coolifyで個人サービス基盤を作った話&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-claude-code-mcp/&quot;&gt;Coolifyインストールから「プロンプトでデプロイ」まで：Claude Code MCP実践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-hands-on-deploy/&quot;&gt;Coolifyハンズオン：Hono・Go・Railsを実際にデプロイしてみる&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-cloudflare-tunnel/&quot;&gt;Cloudflare Tunnel×Coolify：自宅サーバを安全に外部公開する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-llm-era-self-hosting/&quot;&gt;API-firstなインフラが生き残る：LLM時代のセルフホスト戦略&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring/&quot;&gt;ZabbixでDockerコンテナをリソース監視する：Coolify環境の可視化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-backup-strategy/&quot;&gt;Coolify環境のバックアップ戦略：6つのDBを自動ダンプ+復旧手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coolify環境のログ管理と障害対応：Docker + Zabbix + Discordで運用を回す&lt;/strong&gt;（この記事）&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>ZabbixでDockerコンテナをリソース監視する：Coolify環境の可視化</title><link>https://blog.teraren.com/posts/coolify-zabbix-container-monitoring/</link><guid isPermaLink="true">https://blog.teraren.com/posts/coolify-zabbix-container-monitoring/</guid><description>Coolifyで運用中の30+コンテナをZabbixで監視する方法。Docker by Zabbix agent 2テンプレートでCPU・メモリ・ネットワークを自動検出し、ダッシュボードで可視化。</description><pubDate>Sun, 15 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Zabbix agent 2 + Docker テンプレート&lt;/strong&gt;で、コンテナ単位のCPU・メモリ・ネットワークを自動検出・監視&lt;/li&gt;
&lt;li&gt;Coolify環境の30+コンテナの&lt;strong&gt;リソース使用量を可視化&lt;/strong&gt;するダッシュボードを構築&lt;/li&gt;
&lt;li&gt;「メモリ食いすぎコンテナ」や「CPU使用率の異常スパイク」を検知できるようになりました&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;/posts/coolify-llm-era-self-hosting&quot;&gt;第5回&lt;/a&gt;までで、Coolify + Cloudflare Tunnelの基盤は完成しました。でも、&lt;strong&gt;監視がなければ運用とは呼べません。&lt;/strong&gt; 30個以上のコンテナが動いていて、どれがどれだけリソースを使っているか見えないのは怖いです。&lt;/p&gt;
&lt;h2&gt;なぜZabbixなのか&lt;/h2&gt;
&lt;p&gt;監視ツールの選択肢はいくつかあります。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ツール&lt;/th&gt;
&lt;th&gt;特徴&lt;/th&gt;
&lt;th&gt;セルフホスト&lt;/th&gt;
&lt;th&gt;API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Zabbix&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;エンタープライズ級。テンプレート豊富&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅ REST API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prometheus + Grafana&lt;/td&gt;
&lt;td&gt;メトリクス特化。Kubernetes向き&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Datadog&lt;/td&gt;
&lt;td&gt;SaaS。簡単だが高い&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uptime Kuma&lt;/td&gt;
&lt;td&gt;死活監視特化。軽量&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;△&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Zabbixを選んだ理由：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Dockerコンテナの自動検出（LLD）&lt;/strong&gt; が標準テンプレートでできます&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SNMP対応&lt;/strong&gt; でルーター（RTX1200）やNAS（QNAP）も同じ画面で監視できます&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;REST APIがある&lt;/strong&gt; から&lt;a href=&quot;/posts/coolify-llm-era-self-hosting&quot;&gt;第5回&lt;/a&gt;で書いた「API-first」の基準を満たします&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coolifyでデプロイできます&lt;/strong&gt;。Dockerイメージが公式で提供されています&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Zabbixの構成&lt;/h2&gt;
&lt;p&gt;Coolifyでデプロイ済みのZabbix構成。Docker Composeで3コンテナ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  zabbix-server:
    image: zabbix/zabbix-server-mysql:alpine-7.4-latest
    ports:
      - &quot;10051:10051&quot;
    environment:
      - DB_SERVER_HOST=mysql
      - MYSQL_DATABASE=zabbix

  zabbix-web:
    image: zabbix/zabbix-web-nginx-mysql:alpine-7.4-latest
    environment:
      - ZBX_SERVER_HOST=zabbix-server
      - PHP_TZ=Asia/Tokyo

  mysql:
    image: mysql:8.0
    volumes:
      - mysql-data:/var/lib/mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ポイントは、Zabbix Server自体はCoolifyのDockerネットワーク内で動いていること。&lt;strong&gt;監視対象のコンテナと同じホスト上にいる&lt;/strong&gt;から、Zabbix agentで直接Dockerソケットにアクセスできます。&lt;/p&gt;
&lt;h2&gt;Dockerコンテナ監視の設定&lt;/h2&gt;
&lt;h3&gt;1. Zabbix agent 2のインストール&lt;/h3&gt;
&lt;p&gt;Zabbix agent 2は&lt;strong&gt;ホストOS側にインストール&lt;/strong&gt;する必要があります。コンテナ内からDockerソケットにアクセスするのは設定が面倒なので、ホストに直接入れた方がシンプルです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Debian/Ubuntu
wget https://repo.zabbix.com/zabbix/7.4/release/ubuntu/pool/main/z/zabbix-release/zabbix-release_latest_7.4+ubuntu24.04_all.deb
sudo dpkg -i zabbix-release_latest_7.4+ubuntu24.04_all.deb
sudo apt update
sudo apt install zabbix-agent2 zabbix-agent2-plugin-*
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. Dockerソケットへのアクセス権設定&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# zabbix ユーザーを docker グループに追加
sudo usermod -aG docker zabbix

# agent2 を再起動
sudo systemctl restart zabbix-agent2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. Zabbix agent 2 の設定&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;/etc/zabbix/zabbix_agent2.conf&lt;/code&gt; の主要設定：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Server=172.16.238.1        # Zabbix ServerのIPアドレス
ServerActive=172.16.238.1
Hostname=gmk               # ホスト名
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;172.16.238.1&lt;/code&gt; はCoolifyのDockerネットワーク（&lt;code&gt;coolify&lt;/code&gt; bridge）のゲートウェイIP。Zabbix ServerコンテナからホストのAgent 2に接続するため、このアドレスを使います。&lt;/p&gt;
&lt;h3&gt;4. 「Docker by Zabbix agent 2」テンプレートの適用&lt;/h3&gt;
&lt;p&gt;Zabbix Web UI → Data Collection → Hosts → 対象ホスト → Templates で &lt;strong&gt;「Docker by Zabbix agent 2」&lt;/strong&gt; を追加。&lt;/p&gt;
&lt;p&gt;これだけで、ホスト上のすべてのDockerコンテナが&lt;strong&gt;自動検出（LLD: Low-Level Discovery）&lt;/strong&gt; されます。&lt;/p&gt;
&lt;h3&gt;自動検出されるメトリクス&lt;/h3&gt;
&lt;p&gt;1コンテナあたり約100個のメトリクスが自動で収集されます。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;カテゴリ&lt;/th&gt;
&lt;th&gt;主なメトリクス&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CPU&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;CPU使用率（%）、ユーザーモード/カーネルモード使用時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;メモリ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;使用量、最大使用量、制限値、キャッシュ、RSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ネットワーク&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;受信/送信バイト数、パケット数、ドロップ数、エラー数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ブロックI/O&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;読み取り/書き込みバイト数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;状態&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;起動時刻、ステータス（running/stopped/paused）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;30コンテナ × 100メトリクス = &lt;strong&gt;約3,000データポイント&lt;/strong&gt; が自動で監視されます。手動で設定する必要はありません。&lt;/p&gt;
&lt;h2&gt;ダッシュボードの構築&lt;/h2&gt;
&lt;h3&gt;Zabbix APIでダッシュボード作成&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;/posts/coolify-llm-era-self-hosting&quot;&gt;第5回&lt;/a&gt;で「API-firstが重要」と書きましたが、まさにここでその恩恵を受けます。ダッシュボードをGUIでポチポチ作るのではなく、&lt;strong&gt;APIで一発で作成&lt;/strong&gt;しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -s -X POST https://zabbix.teraren.com/api_jsonrpc.php \
  -H &apos;Content-Type: application/json&apos; \
  -H &apos;Authorization: Bearer &amp;lt;TOKEN&amp;gt;&apos; \
  -d &apos;{
    &quot;jsonrpc&quot;: &quot;2.0&quot;,
    &quot;method&quot;: &quot;dashboard.create&quot;,
    &quot;params&quot;: {
      &quot;name&quot;: &quot;Docker Containers&quot;,
      &quot;pages&quot;: [{
        &quot;widgets&quot;: [
          {&quot;type&quot;:&quot;graph&quot;,&quot;name&quot;:&quot;Coolify: CPU&quot;,
           &quot;x&quot;:0,&quot;y&quot;:0,&quot;width&quot;:36,&quot;height&quot;:5,
           &quot;fields&quot;:[{&quot;type&quot;:6,&quot;name&quot;:&quot;graphid&quot;,&quot;value&quot;:&quot;5862&quot;}]},
          {&quot;type&quot;:&quot;graph&quot;,&quot;name&quot;:&quot;Coolify: Memory&quot;,
           &quot;x&quot;:36,&quot;y&quot;:0,&quot;width&quot;:36,&quot;height&quot;:5,
           &quot;fields&quot;:[{&quot;type&quot;:6,&quot;name&quot;:&quot;graphid&quot;,&quot;value&quot;:&quot;5867&quot;}]}
        ]
      }]
    },
    &quot;id&quot;: 1
  }&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;作成したダッシュボードには、Coolify本体・Traefik Proxy・PostgreSQL・Sentinelのコンテナのリソースグラフを配置しました。&lt;/p&gt;
&lt;h3&gt;可視化で見えてきたこと&lt;/h3&gt;
&lt;p&gt;ダッシュボードを見て気づいたことがいくつかあります。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;コンテナ&lt;/th&gt;
&lt;th&gt;メモリ使用量&lt;/th&gt;
&lt;th&gt;気づき&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;coolify-sentinel&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5.2 GB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Coolifyの全コンテナヘルスチェックを担当。メモリ食いすぎ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;coolify&lt;/td&gt;
&lt;td&gt;178 MB&lt;/td&gt;
&lt;td&gt;Laravel アプリ本体。妥当&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;coolify-proxy (Traefik)&lt;/td&gt;
&lt;td&gt;84 MB&lt;/td&gt;
&lt;td&gt;リバースプロキシ。軽量&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;coolify-redis&lt;/td&gt;
&lt;td&gt;81 MB&lt;/td&gt;
&lt;td&gt;セッション・キャッシュ。妥当&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;coolify-realtime&lt;/td&gt;
&lt;td&gt;55 MB&lt;/td&gt;
&lt;td&gt;WebSocket。妥当&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;coolify-db (PostgreSQL)&lt;/td&gt;
&lt;td&gt;44 MB&lt;/td&gt;
&lt;td&gt;設定データのみ。軽量&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;coolify-sentinelが5.2GBも使っている&lt;/strong&gt;のは監視なしでは絶対に気づけませんでした。30+コンテナのヘルスチェックを常時回しているからでしょうけど、32GBのRAMのうち16%を1つのヘルスチェッカーが使っているのは気になります。&lt;/p&gt;
&lt;h2&gt;アラート設定&lt;/h2&gt;
&lt;p&gt;コンテナ監視のアラートは「Docker by Zabbix agent 2」テンプレートに最初から含まれています。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;トリガー&lt;/th&gt;
&lt;th&gt;条件&lt;/th&gt;
&lt;th&gt;重要度&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Container stopped&lt;/td&gt;
&lt;td&gt;コンテナが停止&lt;/td&gt;
&lt;td&gt;Average&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High memory usage&lt;/td&gt;
&lt;td&gt;メモリ使用率 &amp;gt; 90%&lt;/td&gt;
&lt;td&gt;Warning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container restart detected&lt;/td&gt;
&lt;td&gt;再起動を検知&lt;/td&gt;
&lt;td&gt;Information&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;追加でカスタムトリガーを設定する場合は、Zabbix APIでも可能です。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Zabbix + Docker by Zabbix agent 2 テンプレートで、&lt;strong&gt;設定ほぼゼロでコンテナ単位のリソース監視&lt;/strong&gt;ができます。3,000以上のメトリクスが自動収集されて、ダッシュボードで可視化できます。sentinelの5.2GBメモリ問題のように、監視しないと絶対に気づけない問題が見つかります。&lt;/p&gt;
&lt;p&gt;Coolifyの「API-first」思想は、監視との組み合わせでさらに威力を発揮します。「プロンプトでデプロイして、ダッシュボードで監視する」。これがセルフホストの運用ルーティンです。&lt;/p&gt;
&lt;h3&gt;シリーズ記事&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas/&quot;&gt;Vercel月額$42→自宅サーバ月額$0。Coolifyで個人サービス基盤を作った話&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-claude-code-mcp/&quot;&gt;Coolifyインストールから「プロンプトでデプロイ」まで：Claude Code MCP実践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-hands-on-deploy/&quot;&gt;Coolifyハンズオン：Hono・Go・Railsを実際にデプロイしてみる&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-cloudflare-tunnel/&quot;&gt;Cloudflare Tunnel×Coolify：自宅サーバを安全に外部公開する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-llm-era-self-hosting/&quot;&gt;API-firstなインフラが生き残る：LLM時代のセルフホスト戦略&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ZabbixでDockerコンテナをリソース監視する：Coolify環境の可視化&lt;/strong&gt;（この記事）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-backup-strategy/&quot;&gt;Coolify環境のバックアップ戦略：6つのDBを自動ダンプ+復旧手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-log-management-incident-response/&quot;&gt;Coolify環境のログ管理と障害対応：Docker + Zabbix + Discordで運用を回す&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Coolifyインストールから「プロンプトでデプロイ」まで：Claude Code MCP実践</title><link>https://blog.teraren.com/posts/coolify-claude-code-mcp/</link><guid isPermaLink="true">https://blog.teraren.com/posts/coolify-claude-code-mcp/</guid><description>Coolifyのインストール・初期設定からClaude Code MCPで「プロンプトだけでデプロイ」する体験までを一気に紹介。手動のGUIポチポチ→MCP一発の対比が強烈。</description><pubDate>Sat, 14 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://coolify.io/&quot;&gt;Coolify&lt;/a&gt;のインストールはコマンド1発、初期設定も数分で完了&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://modelcontextprotocol.io/&quot;&gt;MCP（Model Context Protocol）&lt;/a&gt;を使えば、&lt;strong&gt;Claude Codeからプロンプトだけでインフラ操作&lt;/strong&gt;が可能&lt;/li&gt;
&lt;li&gt;GUIで10分かかるデプロイ作業が、プロンプト一発で4分に&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Coolifyのインストール&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas&quot;&gt;第1回&lt;/a&gt;でCoolifyの選定理由を書きました。ここからは実際にインストールして使い始めます。&lt;/p&gt;
&lt;h3&gt;必要な環境&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;要件&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OS&lt;/td&gt;
&lt;td&gt;Ubuntu 22.04/24.04（推奨）、Debian、CentOS等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CPU&lt;/td&gt;
&lt;td&gt;2コア以上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RAM&lt;/td&gt;
&lt;td&gt;4GB以上（実用的には8GB推奨）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ストレージ&lt;/td&gt;
&lt;td&gt;20GB以上の空き容量&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Dockerが入っていなくても、インストールスクリプトが自動で入れてくれます。&lt;/p&gt;
&lt;h3&gt;インストール手順&lt;/h3&gt;
&lt;p&gt;公式のインストールスクリプトを実行するだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ステップ&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;th&gt;所要時間&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Docker自動インストール（未導入の場合）&lt;/td&gt;
&lt;td&gt;1〜2分&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;CoolifyのコンテナイメージをPull&lt;/td&gt;
&lt;td&gt;2〜3分&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;管理UI（ポート8000）を起動&lt;/td&gt;
&lt;td&gt;30秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Traefik（リバースプロキシ）を起動&lt;/td&gt;
&lt;td&gt;30秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;合計&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;約5分&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;初回セットアップ&lt;/h3&gt;
&lt;p&gt;ブラウザで &lt;code&gt;http://サーバIP:8000&lt;/code&gt; にアクセス。初期登録画面でメールアドレスとパスワードを設定したら、もう使えます。サーバのリソース（CPU/RAM/ディスク）は自動検出されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-dashboard.png&quot; alt=&quot;Coolifyのダッシュボード。プロジェクト一覧とサーバー情報が表示されている&quot; /&gt;&lt;/p&gt;
&lt;p&gt;自宅サーバで外部公開する場合は&lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/&quot;&gt;Cloudflare Tunnel&lt;/a&gt;を使うのが一番簡単で安全です。詳細は&lt;a href=&quot;/posts/coolify-cloudflare-tunnel&quot;&gt;第4回&lt;/a&gt;で書きます。&lt;/p&gt;
&lt;h3&gt;ワイルドカードDNSの設定&lt;/h3&gt;
&lt;p&gt;Coolifyでは &lt;code&gt;myapp.teraren.com&lt;/code&gt;、&lt;code&gt;api.teraren.com&lt;/code&gt; のように&lt;strong&gt;サービスごとにサブドメインを割り当てる&lt;/strong&gt;運用になります。サービスを追加するたびにDNSレコードを手動で追加するのは面倒なので、ワイルドカードDNSを設定しておきます。&lt;/p&gt;
&lt;p&gt;CloudflareのDNS設定画面で、以下のレコードを追加。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Content&lt;/th&gt;
&lt;th&gt;Proxy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CNAME&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cloudflare TunnelのターゲットまたはサーバIP&lt;/td&gt;
&lt;td&gt;ON&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;{/* TODO: Cloudflare管理画面のスクリーンショットを追加 */}&lt;/p&gt;
&lt;p&gt;これで &lt;code&gt;*.teraren.com&lt;/code&gt; 宛のリクエストがすべてCoolifyサーバに届くようになります。Coolify側のTraefikが、Hostヘッダを見て適切なコンテナにルーティングしてくれます。新しいサービスを追加するときにDNSをいじる必要がなくなるので、MCPでのプロンプト一発デプロイがさらに手軽になります。&lt;/p&gt;
&lt;h3&gt;GitHub App連携&lt;/h3&gt;
&lt;p&gt;CoolifyでPush to Deployを使うには、GitHub Appの連携が必要です。管理UIの Settings &amp;gt; GitHub から「Create GitHub App」をクリックすると、GitHubのOAuth認証フローが始まります。数クリックで完了。&lt;/p&gt;
&lt;p&gt;これで特定のリポジトリへのPushをWebhookで受け取って、自動ビルド&amp;amp;デプロイが動くようになります。&lt;/p&gt;
&lt;h2&gt;まずは手動でデプロイしてみる&lt;/h2&gt;
&lt;p&gt;MCPの話に行く前に、GUIでの手動デプロイを体験しておきます。&lt;strong&gt;この面倒さを知っておくと、後でMCPの威力がよくわかる&lt;/strong&gt;ので。&lt;/p&gt;
&lt;h3&gt;GUIでのデプロイ手順&lt;/h3&gt;
&lt;p&gt;管理UIでの操作はざっくりこんな流れです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;プロジェクトを作成（名前を入力）&lt;/li&gt;
&lt;li&gt;「New Resource」→「Application」を選択&lt;/li&gt;
&lt;li&gt;GitHub Appを選んでリポジトリを検索&lt;/li&gt;
&lt;li&gt;リポジトリとブランチを指定&lt;/li&gt;
&lt;li&gt;ビルド方式を選択（Nixpacks / Dockerfile / Docker Compose）&lt;/li&gt;
&lt;li&gt;ドメインを入力（例: &lt;code&gt;myapp.teraren.com&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;環境変数を1つずつ入力。。。&lt;/li&gt;
&lt;li&gt;「Deploy」ボタンを押す&lt;/li&gt;
&lt;li&gt;ビルドログを眺めて待つ&lt;/li&gt;
&lt;li&gt;SSL証明書が自動発行されてアクセス可能に&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-app-configuration.png&quot; alt=&quot;Coolifyのアプリケーション設定画面。Name、Build Pack、Domains、Docker Registry、Build設定などをGUIで1つずつ入力していく&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1アプリなら問題ありません。&lt;/strong&gt; でも、これを20個のサービスで繰り返すのは正直しんどいです。特に環境変数を1つずつGUIに入力するのが面倒です。DB接続文字列、APIキー、シークレット。。。コピペミスも怖いです。&lt;/p&gt;
&lt;p&gt;ここで「もうちょっと楽にならないかな」と思ったところで、MCPの出番です。&lt;/p&gt;
&lt;h2&gt;MCPとは&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://modelcontextprotocol.io/&quot;&gt;MCP（Model Context Protocol）&lt;/a&gt;は&lt;a href=&quot;https://www.anthropic.com/&quot;&gt;Anthropic&lt;/a&gt;が2024年末に発表した標準プロトコルです。AIモデルが外部のツールやサービスを直接操作するための共通規格です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;従来: 人間がAIに質問 → AIが回答 → 人間が手動でコマンド実行
MCP: 人間がAIに指示 → AIがMCP経由でツールを自動実行 → 結果を報告
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MCPは「サーバー」と「クライアント」の2層構造です。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;コンポーネント&lt;/th&gt;
&lt;th&gt;役割&lt;/th&gt;
&lt;th&gt;例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCPサーバー&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;特定のサービスを操作するためのAPI&lt;/td&gt;
&lt;td&gt;Coolify MCP、GitHub MCP、Slack MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MCPクライアント&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;MCPサーバーを呼び出すAI側&lt;/td&gt;
&lt;td&gt;Claude Code、Claude Desktop、Cursor&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Claude Codeは複数のMCPサーバーに同時接続できるので、「GitHubでリポジトリ作成 → Coolifyでデプロイ → Slackで通知」みたいな連携もプロンプト一発で可能です。MCPサーバーは&lt;a href=&quot;https://github.com/StuMason/coolify-mcp&quot;&gt;Coolify&lt;/a&gt;以外にも&lt;a href=&quot;https://github.com/awslabs/mcp&quot;&gt;AWS&lt;/a&gt;、&lt;a href=&quot;https://github.com/cloudflare/mcp-server-cloudflare&quot;&gt;Cloudflare&lt;/a&gt;、&lt;a href=&quot;https://github.com/modelcontextprotocol/servers&quot;&gt;GitHub&lt;/a&gt;など増え続けています。&lt;/p&gt;
&lt;h2&gt;Coolify MCPサーバーの導入&lt;/h2&gt;
&lt;h3&gt;必要なもの&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Coolify&lt;/td&gt;
&lt;td&gt;インストール済み&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code&lt;/td&gt;
&lt;td&gt;最新版&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Token&lt;/td&gt;
&lt;td&gt;Coolifyの Settings &amp;gt; API Keys から生成&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;設定手順&lt;/h3&gt;
&lt;p&gt;Claude Codeの &lt;code&gt;claude mcp add&lt;/code&gt; コマンド一発で追加できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;claude mcp add coolify \
  -e COOLIFY_URL=https://coolify.your-domain.com \
  -e COOLIFY_TOKEN=your-api-token-here \
  -- npx -y @coolify-community/coolify-mcp@latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これで &lt;code&gt;~/.claude/settings.json&lt;/code&gt; に自動で追加されます。設定ファイルを手動で編集する必要はありません。Claude Codeを再起動すれば、もうCoolifyのAPIが使えます。&lt;/p&gt;
&lt;h3&gt;動作確認&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Coolifyに接続して、現在のサーバーとプロジェクト一覧を教えて。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これだけで &lt;code&gt;list_servers&lt;/code&gt; と &lt;code&gt;list_projects&lt;/code&gt; が自動的に呼ばれて、結果を表形式で返してくれます。curlを打つ必要はありません。&lt;/p&gt;
&lt;h2&gt;実践例1：プロンプトだけでWordPressを立ち上げる&lt;/h2&gt;
&lt;p&gt;まずはシンプルな例からです。&lt;strong&gt;WordPressをプロンプトだけで構築して公開します&lt;/strong&gt;。DB作成からドメイン設定、テーマ導入まで全部MCPでやります。&lt;/p&gt;
&lt;h3&gt;会話ログ（要約）&lt;/h3&gt;
&lt;p&gt;実際にClaude Codeとやり取りした流れです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;私: CoolifyでWordPressを立ち上げて。
    プロジェクト名は wordpress-demo、
    ドメインは wordpress-demo.teraren.com で。

Claude Code: まずプロジェクトを作成します。
  → [MCP] create_project &quot;wordpress-demo&quot;

Claude Code: MySQLデータベースを作成します。
  → [MCP] create_database（MySQL、wordpressユーザー/DB）
  → 内部接続URL: mysql://wordpress:***@コンテナID:3306/wordpress

Claude Code: WordPressアプリケーションを作成します。
  → [MCP] create_application（Dockerイメージ: wordpress:latest）
  → [MCP] update_application（ドメイン設定）

Claude Code: DB接続用の環境変数を設定します。
  → [MCP] env_vars × 4
    WORDPRESS_DB_HOST, WORDPRESS_DB_USER,
    WORDPRESS_DB_PASSWORD, WORDPRESS_DB_NAME

Claude Code: デプロイを開始します。
  → [MCP] deploy
  → ✓ WordPress初期画面が表示されました。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ここまでで&lt;strong&gt;プロジェクト作成→DB作成→アプリ作成→環境変数設定→デプロイ&lt;/strong&gt;が完了しました。所要時間は約4分です。さっきGUIで10ステップかけてやった作業が、プロンプト1回で終わりました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-wordpress-default.png&quot; alt=&quot;デフォルトテーマ（Twenty Twenty-Five）のWordPress。Hello world!の記事だけが表示されている&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;テーマ設定や初期構成もAIに丸投げ&lt;/h3&gt;
&lt;p&gt;WordPressが立ち上がりましたが、デフォルトテーマだと味気ないです。車メディアサイトを作りたいので、ここからさらにプロンプトで指示します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;私: 車メディアサイトにしたい。派手な車のテーマを入れて、
    日本語設定にして、車関連の記事を5本入れておいて。
    サイト名は「Car Media Demo」で。

Claude Code: WordPressコンテナ内でWP-CLIを実行します。
  $ docker exec ... wp core install \
      --url=wordpress-demo.teraren.com \
      --title=&quot;Car Media Demo&quot; --locale=ja
  $ docker exec ... wp theme install automobile-car-shop --activate
  $ docker exec ... wp option update blogdescription \
      &quot;最新の車ニュースとレビュー&quot;
  $ docker exec ... wp post create \
      --post_title=&quot;2026年版 国産スポーツカー比較ガイド&quot; \
      --post_status=publish
  $ docker exec ... wp post create \
      --post_title=&quot;電気自動車の充電インフラ最前線&quot; \
      --post_status=publish
  $ docker exec ... wp post create \
      --post_title=&quot;ポルシェ 911 GT3 RS 試乗レビュー&quot; \
      --post_status=publish
  $ docker exec ... wp post create \
      --post_title=&quot;ヘッドライトの黄ばみをDIYで復活させる方法&quot; \
      --post_status=publish
  $ docker exec ... wp post create \
      --post_title=&quot;新型アルファード vs ヴェルファイア 2026年モデル&quot; \
      --post_status=publish
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-wordpress-themed.png&quot; alt=&quot;Automobile Car Shopテーマを適用した車メディアサイト。ダークなヘッダーに車の画像、「Designed For Driving Pleasure」のヒーローセクション、スペック表示が映える&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;wordpress-demo.teraren.com&lt;/code&gt; を開いたら、車ディーラー風のダークテーマが適用されたサイトが動いています。&lt;strong&gt;DB作成からテーマ導入・記事5本投入まで、ターミナルから一歩も出ていません。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-wordpress-demo-project.png&quot; alt=&quot;Coolifyのプロジェクト一覧にwordpress-demoが追加されている&quot; /&gt;&lt;/p&gt;
&lt;p&gt;この例のポイントは、MCPだけでなくDocker execコマンドも組み合わせているところです。Claude Codeは「MCPでインフラ操作 → シェルでアプリ内操作」を自然に切り替えてくれます。人間が「次はWP-CLIで…」と考える必要すらありません。&lt;/p&gt;
&lt;h3&gt;v0→Vercel との対比&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://v0.dev/&quot;&gt;v0&lt;/a&gt;→Vercelが「バイブコーディング→即デプロイ」の神ワークフローとして知られていますが、Claude Code→Coolifyでも同じことができます。しかもリソース無制限、月額$0です。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;観点&lt;/th&gt;
&lt;th&gt;v0 → Vercel&lt;/th&gt;
&lt;th&gt;Claude Code → Coolify&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;コード生成&lt;/td&gt;
&lt;td&gt;v0独自のUI生成&lt;/td&gt;
&lt;td&gt;既存コードベースに統合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;デプロイ先&lt;/td&gt;
&lt;td&gt;Vercel（クラウド）&lt;/td&gt;
&lt;td&gt;Coolify（セルフホスト）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コスト&lt;/td&gt;
&lt;td&gt;従量課金&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;複雑な機能&lt;/td&gt;
&lt;td&gt;制限あり&lt;/td&gt;
&lt;td&gt;制限なし&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;v0は「ゼロから作る」に特化しています。Claude Codeは「既存のものを理解して拡張する」に特化しています。まぁ両方使えばいいと思います。&lt;/p&gt;
&lt;h2&gt;実践例2：develop環境をプロンプト一発で複製&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ai-triathlon-result.teraren.com/&quot;&gt;トライアスロン大会結果の分析サービス&lt;/a&gt;のdevelop環境を作った例です。本番環境の構成をそのままコピーして、ブランチだけ変えてデプロイします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;私: ai-triリポジトリの develop ブランチをCoolifyにデプロイして。
    ドメインは develop.ai-triathlon-result.teraren.com で。
    環境変数は本番環境からコピーして。

Claude Code:
  → [MCP] list_projects → ai-triプロジェクトを発見
  → [MCP] create_application（developブランチ指定）
  → [MCP] get_env_vars（本番から取得）
  → [MCP] bulk_env_update（developに設定）
  → [MCP] update_application（ドメイン設定）
  → [MCP] deploy
  → ✓ develop.ai-triathlon-result.teraren.com でアクセス可能
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-deployments.png&quot; alt=&quot;Coolifyのデプロイ履歴。ai-tri-productionの4回のデプロイが全てSuccessで表示されている。Webhook経由やAPI経由のデプロイが混在している&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本番の環境変数を自動でコピーしてくれるのが地味に便利です。手動だと環境変数のコピペミスが一番怖いところです。&lt;/p&gt;
&lt;h2&gt;実践例3：Zabbix環境を丸投げ構築&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.zabbix.com/&quot;&gt;Zabbix&lt;/a&gt;（監視システム）をCoolifyに載せた例です。Server + Web + DB の複合構成で、手動だとコンテナ間の接続設定が面倒なやつです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;私: ZabbixをCoolifyに構築して。
    ドメインは zabbix.teraren.com で。

Claude Code:
  → [MCP] create_project &quot;zabbix&quot;
  → [MCP] create_database（MariaDB）
  → [MCP] create_application × 2（Server, Web）
  → 環境変数にDB接続情報を自動設定（10個以上）
  → [MCP] update_application でドメイン設定
  → [MCP] deploy × 2
  → ✓ zabbix.teraren.com でアクセス可能
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;すごいのは、&lt;strong&gt;コンテナ間の接続設定を全部自動でやってくれる&lt;/strong&gt;ところです。Zabbix ServerのDB接続文字列、Zabbix WebからServerへの接続先、ポート設定。。。手動だと環境変数を10個以上、コピペミスなく設定する必要があります。AIに任せれば一瞬で終わりますし、ミスもありません。&lt;/p&gt;
&lt;p&gt;手動でやったら1時間以上かかりそうな作業が、&lt;strong&gt;約10分で完了&lt;/strong&gt;しました。&lt;/p&gt;
&lt;h2&gt;実践例4：MariaDBチューニング&lt;/h2&gt;
&lt;p&gt;この件は &lt;a href=&quot;/posts/mariadb-memory-tuning-with-claude-code&quot;&gt;「Claude Codeでプロンプト1発、MariaDBのメモリ使用量を400MB→150MBに削減した話」&lt;/a&gt; に詳しく書いています。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;メモリ使用量&lt;/td&gt;
&lt;td&gt;403.5 MiB&lt;/td&gt;
&lt;td&gt;~150 MiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;削減率&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;63%削減&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;作業時間&lt;/td&gt;
&lt;td&gt;数時間（手動調査）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5分&lt;/strong&gt;（プロンプト3回）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;MCP経由で &lt;code&gt;SHOW VARIABLES&lt;/code&gt; / &lt;code&gt;SHOW GLOBAL STATUS&lt;/code&gt; を取得→分析→チューニングプラン作成→設定適用→再起動まで一気通貫です。Plan Modeで計画を見せてもらってから実行に移したので安心感がありました。&lt;/p&gt;
&lt;h2&gt;プロンプト設計のコツ&lt;/h2&gt;
&lt;p&gt;MCPでインフラ操作するとき、いくつかコツがあります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;文脈を具体的に伝える。&lt;/strong&gt; 「新しい環境を作って」ではなく「ai-triプロジェクトの本番と同じ構成でdevelop環境を作って」。プロジェクト名、リポジトリ名、ブランチ名を明示します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Plan Modeを使う。&lt;/strong&gt; インフラ操作は影響範囲が大きいので、Claude CodeのPlan Modeで計画を立てさせてから実行します。DB再起動みたいな影響のある操作を勝手にやられると怖いので。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;段階的に進める。&lt;/strong&gt; 「全部まとめてやって」より「まず現在の構成を確認して」→「新しいアプリを作成して（まだデプロイしない）」→「環境変数を設定して」と段階的に指示した方が、トラブルシューティングが楽です。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;タスク&lt;/th&gt;
&lt;th&gt;GUIで手動&lt;/th&gt;
&lt;th&gt;Claude Code + MCP&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;WordPress構築（DB+テーマ込み）&lt;/td&gt;
&lt;td&gt;15分&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4分&lt;/strong&gt;（プロンプト2回）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;develop環境の複製&lt;/td&gt;
&lt;td&gt;10分（ポチポチ）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4分&lt;/strong&gt;（プロンプト一発）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Zabbix移行（複合構成）&lt;/td&gt;
&lt;td&gt;1時間以上&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;約10分&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MariaDBチューニング&lt;/td&gt;
&lt;td&gt;数時間&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;5分&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;GUIでポチポチやっていた作業がプロンプト一発で終わります。やらない理由はありません。&lt;/p&gt;
&lt;h2&gt;余談：TerraformでもAnsibleでもなくMCPだった理由&lt;/h2&gt;
&lt;p&gt;「インフラ自動化ならTerraformやAnsibleがあるじゃん」と思うかもしれません。実際、Coolifyに移行する前にTerraformを検討しました。&lt;/p&gt;
&lt;p&gt;でも、個人で10〜30個のサービスを運用する規模に、Terraformの &lt;code&gt;.tf&lt;/code&gt; ファイルを書いて &lt;code&gt;plan&lt;/code&gt; して &lt;code&gt;apply&lt;/code&gt; するワークフローはオーバーキルです。状態管理のバックエンド（S3とか）も用意しないといけませんし、HCL（Terraformの設定言語）の学習コストもあります。Ansibleも同様で、playbookを書いてメンテナンスする手間が本末転倒です。&lt;/p&gt;
&lt;p&gt;MCPが良いのは、&lt;strong&gt;自動化のためのコードを書かなくていい&lt;/strong&gt;ところです。Terraformは「インフラをコードで管理する」思想ですが、MCPは「インフラをAIに口頭で頼む」思想です。コードの管理コストがゼロです。&lt;/p&gt;
&lt;p&gt;もちろん、大規模なチームでGitOps的にインフラを管理するならTerraformの方が向いています。でも個人開発者が自宅サーバで20個のサービスを回すなら、MCPの方が圧倒的に手軽です。&lt;/p&gt;
&lt;p&gt;面白いのは、MCPサーバーの実装が思ったよりシンプルなことです。&lt;a href=&quot;https://github.com/StuMason/coolify-mcp&quot;&gt;Coolify MCPサーバーのソースコード&lt;/a&gt;を見ると、やっていることはCoolifyのREST APIをラップしているだけです。MCPの仕様に沿ってツール定義を書いて、APIを叩いて結果を返します。つまり&lt;strong&gt;MCPはAPI設定の簡略化レイヤー&lt;/strong&gt;であって、本質はREST APIの存在そのものです。&lt;/p&gt;
&lt;p&gt;MCPがなくても、REST APIがあればAIエージェントは直接APIを叩けます。MCPはセットアップを楽にしてくれますが、コンテキストウィンドウを圧迫するデメリットもあります（接続したツール定義がすべてトークンを消費します）。&lt;strong&gt;大事なのはAPI-firstであること&lt;/strong&gt;で、MCPはあくまでおまけです。この話は&lt;a href=&quot;/posts/coolify-llm-era-self-hosting&quot;&gt;第5回&lt;/a&gt;で詳しく書きます。&lt;/p&gt;
&lt;h3&gt;シリーズ記事&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas/&quot;&gt;Vercel月額$42→自宅サーバ月額$0。Coolifyで個人サービス基盤を作った話&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coolifyインストールから「プロンプトでデプロイ」まで：Claude Code MCP実践&lt;/strong&gt;（この記事）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-hands-on-deploy/&quot;&gt;Coolifyハンズオン：Hono・Go・Railsを実際にデプロイしてみる&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-cloudflare-tunnel/&quot;&gt;Cloudflare Tunnel×Coolify：自宅サーバを安全に外部公開する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-llm-era-self-hosting/&quot;&gt;API-firstなインフラが生き残る：LLM時代のセルフホスト戦略&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring/&quot;&gt;ZabbixでDockerコンテナをリソース監視する：Coolify環境の可視化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-backup-strategy/&quot;&gt;Coolify環境のバックアップ戦略：6つのDBを自動ダンプ+復旧手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-log-management-incident-response/&quot;&gt;Coolify環境のログ管理と障害対応：Docker + Zabbix + Discordで運用を回す&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Cloudflare Tunnel×Coolify：自宅サーバを安全に外部公開する</title><link>https://blog.teraren.com/posts/coolify-cloudflare-tunnel/</link><guid isPermaLink="true">https://blog.teraren.com/posts/coolify-cloudflare-tunnel/</guid><description>自宅サーバをポート開放なしで安全に外部公開する方法。Cloudflare TunnelとCoolifyの組み合わせで、CDN・WAF・SSL・PRプレビュー環境が全部タダ。</description><pubDate>Sat, 14 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宅サーバを外部公開するのに&lt;strong&gt;ポート開放は不要&lt;/strong&gt;。&lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/&quot;&gt;Cloudflare Tunnel&lt;/a&gt;でOutbound接続だけで公開できます&lt;/li&gt;
&lt;li&gt;CDN・WAF・DDoS対策・SSL証明書が&lt;strong&gt;全部無料&lt;/strong&gt;でついてきます&lt;/li&gt;
&lt;li&gt;CoolifyのPRプレビュー環境と組み合わせると、&lt;strong&gt;PRごとに一時的なURLが自動生成&lt;/strong&gt;されます&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas&quot;&gt;第1回&lt;/a&gt;でCoolifyの選定理由、&lt;a href=&quot;/posts/coolify-claude-code-mcp&quot;&gt;第2回&lt;/a&gt;でインストールとMCP、&lt;a href=&quot;/posts/coolify-hands-on-deploy&quot;&gt;第3回&lt;/a&gt;で実際のデプロイを紹介しました。今回は「自宅サーバをどうやって安全に外部公開するか」の話です。&lt;/p&gt;
&lt;h2&gt;自宅サーバ公開の課題&lt;/h2&gt;
&lt;p&gt;自宅サーバでサービスを公開するには、いくつかハードルがあります。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;課題&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ポート開放&lt;/td&gt;
&lt;td&gt;ルーターのNAT設定が必要。セキュリティリスクが増える&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;固定IPなし&lt;/td&gt;
&lt;td&gt;多くの家庭回線はIPが変わる。DDNSが必要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DDoS&lt;/td&gt;
&lt;td&gt;自宅IPが攻撃対象になると回線ごと死ぬ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL証明書&lt;/td&gt;
&lt;td&gt;Let&apos;s Encryptで取れるが、80/443ポートの開放が前提&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ポート開放は本当にやりたくありません。自宅のIPアドレスがバレたら、サーバだけでなく家庭のネットワーク全体がリスクにさらされます。&lt;/p&gt;
&lt;h2&gt;Cloudflare Tunnelとは&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/&quot;&gt;Cloudflare Tunnel&lt;/a&gt;（旧称Argo Tunnel）は、サーバからCloudflareへ&lt;strong&gt;Outbound接続だけ&lt;/strong&gt;でトンネルを張るサービス。ポート開放不要、固定IP不要、DDNS不要。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    participant User as ユーザー
    participant CF as Cloudflare Edge
    participant Tunnel as cloudflared&amp;lt;br/&amp;gt;(自宅サーバ)
    participant Coolify as Coolify / Traefik

    User-&amp;gt;&amp;gt;CF: https://app.teraren.com
    Note over CF: CDN / WAF / DDoS保護
    CF-&amp;gt;&amp;gt;Tunnel: Tunnelで転送
    Tunnel-&amp;gt;&amp;gt;Coolify: localhost:80
    Coolify--&amp;gt;&amp;gt;Tunnel: レスポンス
    Tunnel--&amp;gt;&amp;gt;CF: レスポンス
    CF--&amp;gt;&amp;gt;User: レスポンス（キャッシュ済み）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;ポイント:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自宅サーバ側の &lt;code&gt;cloudflared&lt;/code&gt; がCloudflareに&lt;strong&gt;Outbound接続&lt;/strong&gt;します。Inbound接続は一切ありません&lt;/li&gt;
&lt;li&gt;自宅のIPアドレスは外部に公開されません。Cloudflareが全部受けてくれます&lt;/li&gt;
&lt;li&gt;CDN・WAF・DDoS対策が&lt;strong&gt;自動的に&lt;/strong&gt;適用されます。設定不要&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;cloudflaredのインストール&lt;/h2&gt;
&lt;h3&gt;Cloudflare側の設定&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://one.dash.cloudflare.com/&quot;&gt;Cloudflare Zero Trust&lt;/a&gt; にログイン&lt;/li&gt;
&lt;li&gt;Networks → Tunnels → Create a Tunnel&lt;/li&gt;
&lt;li&gt;Tunnel名を入力（例: &lt;code&gt;home-server&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;インストール用のトークンが発行される&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;サーバ側のインストール&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# Debianの場合
curl -L https://pkg.cloudflare.com/cloudflare-main.gpg \
  | sudo tee /usr/share/keyrings/cloudflare-archive-keyring.gpg
echo &quot;deb [signed-by=/usr/share/keyrings/cloudflare-archive-keyring.gpg] \
  https://pkg.cloudflare.com/cloudflared $(lsb_release -cs) main&quot; \
  | sudo tee /etc/apt/sources.list.d/cloudflared.list
sudo apt update &amp;amp;&amp;amp; sudo apt install cloudflared

# サービスとして登録
sudo cloudflared service install &amp;lt;TOKEN&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;systemctl status cloudflared&lt;/code&gt; で &lt;code&gt;active (running)&lt;/code&gt; なら成功。&lt;/p&gt;
&lt;h3&gt;Public Hostnameの設定&lt;/h3&gt;
&lt;p&gt;Cloudflare Zero Trust Dashboard → Tunnels → 作成したTunnel → Public Hostname で、ルーティングを設定します。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Subdomain&lt;/th&gt;
&lt;th&gt;Domain&lt;/th&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;teraren.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://localhost:80&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;ワイルドカード（&lt;code&gt;*&lt;/code&gt;）を設定するのがポイント。&lt;/strong&gt; これで &lt;code&gt;*.teraren.com&lt;/code&gt; 宛のリクエストがすべてトンネル経由でCoolifyサーバに届きます。Coolify側のTraefikがHostヘッダを見て、適切なコンテナにルーティングしてくれます。&lt;/p&gt;
&lt;p&gt;個別のサービスごとにDNSレコードを追加する必要がありません。Coolifyで新しいアプリを作ってドメインを設定するだけで、即座にアクセス可能になります。&lt;/p&gt;
&lt;h2&gt;CoolifyとCloudflare Tunnelの連携&lt;/h2&gt;
&lt;h3&gt;SSL/TLSの設定（重要）&lt;/h3&gt;
&lt;p&gt;ここでハマりポイントがあります。&lt;strong&gt;CoolifyのドメインはHTTP（&lt;code&gt;http://&lt;/code&gt;）で設定する必要があります。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;なぜかというと、Cloudflare → cloudflared → Coolify の経路で、SSL終端はCloudflareが担当するからです。Coolify側でもHTTPSにすると、Cloudflare→Coolify間で&lt;strong&gt;二重暗号化&lt;/strong&gt;になって接続できません。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❌ ダメな設定: Coolifyのドメインに https://app.teraren.com
   → Cloudflare(SSL) → Tunnel → Coolify(SSL) = 二重暗号化でエラー

✅ 正しい設定: Coolifyのドメインに http://app.teraren.com
   → Cloudflare(SSL) → Tunnel → Coolify(HTTP) = 正常動作
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;エンドユーザーは &lt;code&gt;https://app.teraren.com&lt;/code&gt; でアクセスします。SSLはCloudflareが処理するので、通信は暗号化されています。Coolify↔Cloudflare間はトンネル内なので、HTTPでも安全です。&lt;/p&gt;
&lt;h3&gt;Cloudflare側のSSL設定&lt;/h3&gt;
&lt;p&gt;Cloudflare Dashboard → SSL/TLS で、暗号化モードを確認します。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;モード&lt;/th&gt;
&lt;th&gt;動作&lt;/th&gt;
&lt;th&gt;推奨&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Off&lt;/td&gt;
&lt;td&gt;暗号化なし&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexible&lt;/td&gt;
&lt;td&gt;ブラウザ→Cloudflareのみ暗号化&lt;/td&gt;
&lt;td&gt;△&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Full&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ブラウザ→Cloudflare→オリジン&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full (Strict)&lt;/td&gt;
&lt;td&gt;上記＋オリジン証明書検証&lt;/td&gt;
&lt;td&gt;△（自宅サーバでは不要）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Full&lt;/strong&gt;が推奨です。自宅サーバ側にLet&apos;s Encrypt証明書がなくても、Tunnel経由なので問題ありません。&lt;/p&gt;
&lt;h3&gt;ネットワーク構成の全体像&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;graph TB
    subgraph Internet
        User[&quot;ユーザー&quot;]
        GitHub[GitHub]
    end

    subgraph Cloudflare
        CDN[CDN / WAF]
        DNS[&quot;DNS&amp;lt;br/&amp;gt;*.teraren.com&quot;]
    end

    subgraph &quot;自宅サーバ&quot;
        CFD[&quot;cloudflared&amp;lt;br/&amp;gt;(Tunnel Agent)&quot;]

        subgraph Coolify
            Traefik[&quot;Traefik&amp;lt;br/&amp;gt;(リバースプロキシ)&quot;]
            UI[&quot;管理UI :8000&quot;]
        end

        subgraph Docker
            App1[&quot;Next.js&amp;lt;br/&amp;gt;app.teraren.com&quot;]
            App2[&quot;Rails&amp;lt;br/&amp;gt;train.teraren.com&quot;]
            App3[&quot;WordPress&amp;lt;br/&amp;gt;blog.teraren.com&quot;]
            DB[&quot;MariaDB / Redis&quot;]
        end
    end

    User --&amp;gt;|HTTPS| CDN
    CDN --&amp;gt; DNS
    DNS --&amp;gt;|Tunnel| CFD
    CFD --&amp;gt;|HTTP| Traefik
    Traefik --&amp;gt;|Host: app| App1
    Traefik --&amp;gt;|Host: train| App2
    Traefik --&amp;gt;|Host: blog| App3
    App1 --&amp;gt; DB
    App3 --&amp;gt; DB

    GitHub --&amp;gt;|Webhook| UI
    UI --&amp;gt;|Deploy| App1
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;PRプレビュー環境&lt;/h2&gt;
&lt;p&gt;CoolifyにはPRプレビュー環境の機能があります。PRを作るたびに一時的なURLが自動生成されて、レビュワーがデプロイ済みの状態で確認できます。Vercelのプレビュー機能と同じです。&lt;/p&gt;
&lt;h3&gt;設定方法&lt;/h3&gt;
&lt;p&gt;Coolifyのアプリ設定 → Preview Deployments で有効化。URLテンプレートはデフォルトで &lt;code&gt;{{pr_id}}.{{domain}}&lt;/code&gt;。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;設定&lt;/th&gt;
&lt;th&gt;例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;本番ドメイン&lt;/td&gt;
&lt;td&gt;&lt;code&gt;app.teraren.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PR #42 のプレビュー&lt;/td&gt;
&lt;td&gt;&lt;code&gt;42.app.teraren.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ワイルドカードDNSを設定済みなら、追加のDNS設定は不要です。PRがマージされたらプレビュー環境は自動で削除されます。&lt;/p&gt;
&lt;h3&gt;MCPでの活用&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;PR #42 のプレビュー環境を確認して。動いてる？
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MCP経由でプレビューデプロイの状態確認も可能です。外部の人にURLを共有してフィードバックをもらうフローが、Coolify + Cloudflare Tunnelだけで完結します。&lt;/p&gt;
&lt;h2&gt;VPSとの比較&lt;/h2&gt;
&lt;p&gt;「自宅サーバじゃなくてVPSでいいのでは？」という疑問への回答です。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;観点&lt;/th&gt;
&lt;th&gt;自宅サーバ + Cloudflare Tunnel&lt;/th&gt;
&lt;th&gt;VPS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;月額コスト&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$0&lt;/strong&gt;（電気代のみ）&lt;/td&gt;
&lt;td&gt;$5〜$50/月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CDN&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;自動付与&lt;/strong&gt;（Cloudflare）&lt;/td&gt;
&lt;td&gt;別途設定が必要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WAF / DDoS&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;自動付与&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;別途設定が必要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Cloudflareが自動管理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Let&apos;s Encrypt等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;リソース&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;物理マシンの全リソース&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;プランに依存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;回線速度&lt;/td&gt;
&lt;td&gt;家庭回線に依存（上り制限あり）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;安定&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;冗長性&lt;/td&gt;
&lt;td&gt;なし（停電で止まる）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;データセンター品質&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;物理管理&lt;/td&gt;
&lt;td&gt;自分でやる（電源、冷却、故障）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不要&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;個人サービスで「いつでも絶対に落ちない」ことが求められないなら、自宅サーバの方がコスパは圧倒的に良いです。CDNとWAFが無料でついてくるのは、Cloudflare Tunnelを通す自宅サーバだけのメリットです。VPSでCloudflareを使うのは追加設定が必要ですが、自宅Tunnelなら&lt;strong&gt;構造上必ずCloudflareを経由する&lt;/strong&gt;ので、設定忘れもありません。&lt;/p&gt;
&lt;p&gt;回線速度だけは弱点です。うちは100Mbps回線なので、大量のトラフィックには向きません。でも、Cloudflare CDNがキャッシュしてくれるので、静的アセットはCDNから配信されます。オリジンへのリクエストは思ったより少ないです。&lt;/p&gt;
&lt;h2&gt;運用上の注意点&lt;/h2&gt;
&lt;h3&gt;cloudflaredの監視&lt;/h3&gt;
&lt;p&gt;cloudflaredが落ちると全サービスが外部からアクセスできなくなります。systemdのサービスとして動いているので、基本的には自動再起動されますが、&lt;a href=&quot;https://www.zabbix.com/&quot;&gt;Zabbix&lt;/a&gt;等で死活監視しておくと安心です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ステータス確認
systemctl status cloudflared

# ログ確認
journalctl -u cloudflared -f
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Cloudflareの無料プランの制限&lt;/h3&gt;
&lt;p&gt;無料プランでも十分使えます。主な制限は以下の通りです。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;無料プラン&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;リクエスト数&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;無制限&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;帯域幅&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;無制限&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tunnel数&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;無制限&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workers&lt;/td&gt;
&lt;td&gt;100,000リクエスト/日&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cacheルール&lt;/td&gt;
&lt;td&gt;10個&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page Rules&lt;/td&gt;
&lt;td&gt;3個&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;リクエスト数も帯域幅も無制限です。個人サービスの規模なら、有料プランにアップグレードする必要はまずありません。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;自宅サーバ + Cloudflare Tunnel + Coolify の組み合わせは、個人開発者にとってかなり強力です。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;得られるもの&lt;/th&gt;
&lt;th&gt;コスト&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ポート開放なしの外部公開&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CDN + キャッシュ&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WAF + DDoS対策&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL証明書&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PRプレビュー環境&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;無制限のサービスデプロイ&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;全部タダ。やらない理由はありません。&lt;/p&gt;
&lt;p&gt;次回の&lt;a href=&quot;/posts/coolify-llm-era-self-hosting&quot;&gt;第5回&lt;/a&gt;では、API-firstがインフラ選定にどう影響するか、LLM時代のセルフホスト戦略について書きます。&lt;/p&gt;
&lt;h3&gt;シリーズ記事&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas/&quot;&gt;Vercel月額$42→自宅サーバ月額$0。Coolifyで個人サービス基盤を作った話&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-claude-code-mcp/&quot;&gt;Coolifyインストールから「プロンプトでデプロイ」まで：Claude Code MCP実践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-hands-on-deploy/&quot;&gt;Coolifyハンズオン：Hono・Go・Railsを実際にデプロイしてみる&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Tunnel×Coolify：自宅サーバを安全に外部公開する&lt;/strong&gt;（この記事）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-llm-era-self-hosting/&quot;&gt;API-firstなインフラが生き残る：LLM時代のセルフホスト戦略&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring/&quot;&gt;ZabbixでDockerコンテナをリソース監視する：Coolify環境の可視化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-backup-strategy/&quot;&gt;Coolify環境のバックアップ戦略：6つのDBを自動ダンプ+復旧手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-log-management-incident-response/&quot;&gt;Coolify環境のログ管理と障害対応：Docker + Zabbix + Discordで運用を回す&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Coolifyハンズオン：Hono・Go・Railsを実際にデプロイしてみる</title><link>https://blog.teraren.com/posts/coolify-hands-on-deploy/</link><guid isPermaLink="true">https://blog.teraren.com/posts/coolify-hands-on-deploy/</guid><description>Coolifyの3つのビルドパック（Nixpacks・Dockerfile・Docker Compose）を、実際にアプリを作ってデプロイしながら体験するハンズオン記事。ゼロからデプロイ完了まで。</description><pubDate>Sat, 14 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Coolifyには3つのビルドパック（&lt;strong&gt;Nixpacks&lt;/strong&gt;・&lt;strong&gt;Dockerfile&lt;/strong&gt;・&lt;strong&gt;Docker Compose&lt;/strong&gt;）があります&lt;/li&gt;
&lt;li&gt;それぞれの特徴を、&lt;strong&gt;実際にアプリを作ってデプロイしながら&lt;/strong&gt;体験します&lt;/li&gt;
&lt;li&gt;簡単な順に進みます：Hono（Nixpacks）→ Go（Dockerfile）→ Rails + Ollama（Docker Compose）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas&quot;&gt;第1回&lt;/a&gt;でCoolifyの選定理由、&lt;a href=&quot;/posts/coolify-claude-code-mcp&quot;&gt;第2回&lt;/a&gt;でインストールとMCPを紹介しました。今回は「実際にゼロからアプリを載せる」ハンズオンです。読みながら手を動かせるようにしています。&lt;/p&gt;
&lt;h2&gt;前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Coolifyがインストール済み（&lt;a href=&quot;/posts/coolify-claude-code-mcp&quot;&gt;第2回&lt;/a&gt;参照）&lt;/li&gt;
&lt;li&gt;GitHubアカウントがある&lt;/li&gt;
&lt;li&gt;ワイルドカードDNS（&lt;code&gt;*.yourdomain.com&lt;/code&gt;）が設定済み&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3つのビルドパック&lt;/h2&gt;
&lt;p&gt;Coolifyには、アプリをどうやってコンテナにするかを決める「ビルドパック」が3種類あります。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ビルドパック&lt;/th&gt;
&lt;th&gt;何をするか&lt;/th&gt;
&lt;th&gt;向いているケース&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Nixpacks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ソースコードから自動でDockerイメージを生成&lt;/td&gt;
&lt;td&gt;プロトタイプ、小〜中規模アプリ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;リポジトリのDockerfileでビルド&lt;/td&gt;
&lt;td&gt;本番運用、細かい制御が必要な場合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker Compose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;複数コンテナをまとめてデプロイ&lt;/td&gt;
&lt;td&gt;DB・キャッシュ込みのフルスタック構成&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;順番にやっていきます。&lt;/p&gt;
&lt;h2&gt;1. Hono × Nixpacks：Dockerfileを書かずにデプロイ&lt;/h2&gt;
&lt;h3&gt;Nixpacksとは&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://nixpacks.com/&quot;&gt;Nixpacks&lt;/a&gt;はRailwayが開発したビルドツールです。ソースコードを読んで、言語やフレームワークを自動検出し、Dockerイメージを勝手に作ってくれます。&lt;strong&gt;Dockerfileを書く必要がありません。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Herokuの&lt;a href=&quot;https://devcenter.heroku.com/articles/buildpacks&quot;&gt;Buildpacks&lt;/a&gt;と似た思想ですが、Nixpacksは最終的にDockerイメージを生成するので、どこでも動きます。&lt;/p&gt;
&lt;h3&gt;アプリを作る&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://hono.dev/&quot;&gt;Hono&lt;/a&gt;はCloudflare Workers向けに作られた軽量Webフレームワークです。Node.jsでも動くので、ここではNode.jsランタイムで使います。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mkdir coolify-demo-hono &amp;amp;&amp;amp; cd coolify-demo-hono
npm init -y
npm install hono @hono/node-server
npm install -D typescript @types/node tsx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;src/index.ts&lt;/code&gt; を作成します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Hono } from &apos;hono&apos;
import { serve } from &apos;@hono/node-server&apos;

const app = new Hono()

app.get(&apos;/&apos;, (c) =&amp;gt; {
  const now = new Date().toISOString()
  return c.html(`
    &amp;lt;h1&amp;gt;Hello from Hono on Coolify!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Current time: ${now}&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;Node.js ${process.version}&amp;lt;/p&amp;gt;
  `)
})

app.get(&apos;/health&apos;, (c) =&amp;gt; {
  return c.json({ status: &apos;ok&apos; })
})

const port = Number(process.env.PORT) || 3000
console.log(`Server running on port ${port}`)
serve({ fetch: app.fetch, port })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt; の &lt;code&gt;scripts&lt;/code&gt; にビルドとスタートを追加します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;type&quot;: &quot;module&quot;,
  &quot;scripts&quot;: {
    &quot;build&quot;: &quot;tsc&quot;,
    &quot;start&quot;: &quot;node dist/index.js&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;これだけです。&lt;/strong&gt; Dockerfile不要。&lt;code&gt;package.json&lt;/code&gt;に&lt;code&gt;build&lt;/code&gt;と&lt;code&gt;start&lt;/code&gt;があれば、Nixpacksが勝手にやってくれます。&lt;/p&gt;
&lt;h3&gt;GitHubにpushしてCoolifyでデプロイ&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;git init &amp;amp;&amp;amp; git add -A &amp;amp;&amp;amp; git commit -m &quot;initial commit&quot;
gh repo create coolify-demo-hono --public --source=. --push
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;管理画面（GUI）の場合：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;New Resource → Application → GitHubリポジトリを選択 → ビルドパックで&lt;strong&gt;Nixpacks&lt;/strong&gt;を選択 → ドメインを入力 → Deploy。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Claude Code MCP（プロンプト）の場合：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;coolify-demo-honoリポジトリをNixpacksでデプロイして。
ドメインはdemo-hono.teraren.comで。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MCPが &lt;code&gt;create application&lt;/code&gt; → &lt;code&gt;deploy&lt;/code&gt; まで自動で実行してくれます。GUIで3〜4画面分の操作が、プロンプト1つで完了します。&lt;/p&gt;
&lt;h3&gt;動作確認&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ curl https://demo-hono.teraren.com/
&amp;lt;h1&amp;gt;Hello from Hono on Coolify!&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;Current time: 2026-03-14T21:41:05.634Z&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Node.js v22.11.0&amp;lt;/p&amp;gt;

$ curl https://demo-hono.teraren.com/health
{&quot;status&quot;:&quot;ok&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nixpacksが自動検出したビルドプラン：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;╔══════════════ Nixpacks v1.41.0 ═══════════════╗
║ setup      │ nodejs_22, npm-9_x, curl, wget   ║
║────────────────────────────────────────────────║
║ install    │ npm ci                            ║
║────────────────────────────────────────────────║
║ build      │ npm run build                     ║
║────────────────────────────────────────────────║
║ start      │ npm run start                     ║
╚════════════════════════════════════════════════╝
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt;を見てNode.jsアプリだと判定し、&lt;code&gt;npm ci&lt;/code&gt; → &lt;code&gt;npm run build&lt;/code&gt; → &lt;code&gt;npm run start&lt;/code&gt;のフローを自動構成してくれました。&lt;strong&gt;設定ファイルゼロでデプロイ完了です。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;Nixpacksの限界&lt;/h3&gt;
&lt;p&gt;便利ですが限界もあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;マルチステージビルドができない&lt;/strong&gt;（イメージサイズが大きくなりがち）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;キャッシュ制御が粗い&lt;/strong&gt;（ビルド時間の最適化が難しい）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alpine以外のベースイメージを選べない&lt;/strong&gt;場面がある&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ネイティブ拡張の依存関係&lt;/strong&gt;で詰まることがある&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;プロトタイプや小規模アプリには最高です。ただし本番運用で細かい制御が必要になったら、Dockerfileに移行するタイミングです。&lt;/p&gt;
&lt;h2&gt;2. Go × Dockerfile：バイナリ1つのミニマルデプロイ&lt;/h2&gt;
&lt;h3&gt;なぜDockerfileを書くのか&lt;/h3&gt;
&lt;p&gt;Nixpacksで自動生成されるDockerfileは汎用的です。しかしGoのようにシングルバイナリにコンパイルできる言語では、&lt;strong&gt;マルチステージビルドで本番イメージを極小にできます&lt;/strong&gt;。これはNixpacksではできません。&lt;/p&gt;
&lt;h3&gt;アプリを作る&lt;/h3&gt;
&lt;p&gt;標準ライブラリだけで書きます。外部依存ゼロです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;package main

import (
	&quot;encoding/json&quot;
	&quot;fmt&quot;
	&quot;net/http&quot;
	&quot;os&quot;
	&quot;runtime&quot;
	&quot;time&quot;
)

func main() {
	port := os.Getenv(&quot;PORT&quot;)
	if port == &quot;&quot; {
		port = &quot;8080&quot;
	}

	hostname, _ := os.Hostname()

	http.HandleFunc(&quot;/&quot;, func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set(&quot;Content-Type&quot;, &quot;text/plain; charset=utf-8&quot;)
		fmt.Fprintf(w, &quot;Hello from Go on Coolify!\n\nGo version: %s\nHostname:   %s\nTime:       %s\n&quot;,
			runtime.Version(), hostname, time.Now().Format(time.RFC3339))
	})

	http.HandleFunc(&quot;/health&quot;, func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set(&quot;Content-Type&quot;, &quot;application/json&quot;)
		json.NewEncoder(w).Encode(map[string]string{&quot;status&quot;: &quot;ok&quot;})
	})

	fmt.Printf(&quot;Listening on :%s\n&quot;, port)
	http.ListenAndServe(&quot;:&quot;+port, nil)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Dockerfile：マルチステージビルド&lt;/h3&gt;
&lt;p&gt;ここがDockerfileの真価です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Build stage
FROM golang:1.24-alpine AS builder
WORKDIR /app
COPY go.mod .
COPY main.go .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags=&quot;-s -w&quot; -o server .

# Production stage — tiny image with just the binary
FROM scratch
COPY --from=builder /app/server /server
EXPOSE 8080
ENTRYPOINT [&quot;/server&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;ポイント:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ビルドステージ（&lt;code&gt;golang:1.24-alpine&lt;/code&gt;、約300MB）でコンパイル&lt;/li&gt;
&lt;li&gt;本番ステージは&lt;code&gt;scratch&lt;/code&gt;（0バイト）にバイナリだけコピー&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最終イメージはバイナリのサイズだけ&lt;/strong&gt;（数MB）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CGO_ENABLED=0&lt;/code&gt;で静的リンク、&lt;code&gt;-ldflags=&quot;-s -w&quot;&lt;/code&gt;でデバッグ情報を除去&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;デプロイと動作確認&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;gh repo create coolify-demo-go --public --source=. --push
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;管理画面（GUI）の場合：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;New Resource → Application → GitHubリポジトリを選択 → ビルドパックで&lt;strong&gt;Dockerfile&lt;/strong&gt;を選択 → ドメインを入力 → Deploy。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Claude Code MCP（プロンプト）の場合：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;coolify-demo-goリポジトリをDockerfileでデプロイして。
ドメインはdemo-go.teraren.comで。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ビルド時間は約40秒です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ curl https://demo-go.teraren.com/
Hello from Go on Coolify!

Go version: go1.24.13
Hostname:   ed06252fb474
Time:       2026-03-14T21:41:04Z

$ curl https://demo-go.teraren.com/health
{&quot;status&quot;:&quot;ok&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Goのマルチステージビルドのイメージサイズ比較です。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ステージ&lt;/th&gt;
&lt;th&gt;ベースイメージ&lt;/th&gt;
&lt;th&gt;サイズ&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ビルド&lt;/td&gt;
&lt;td&gt;&lt;code&gt;golang:1.24-alpine&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~300MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;本番&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;scratch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~6MB&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;これがDockerfileを自分で書く理由です。Nixpacksだとこの最適化はできません。&lt;/p&gt;
&lt;h2&gt;3. Rails × Docker Compose：ローカルLLMチャットアプリ&lt;/h2&gt;
&lt;h3&gt;Docker Composeとは&lt;/h3&gt;
&lt;p&gt;複数のコンテナをまとめて定義・管理する仕組みです。Webアプリ + DB + キャッシュ + α を&lt;code&gt;docker-compose.yaml&lt;/code&gt;一つで定義できます。&lt;/p&gt;
&lt;p&gt;Coolifyは「アプリとDBを個別に作って環境変数で繋ぐ」思想ですが、Docker Compose方式にも対応しています。コンテナ間の依存関係が複雑な場合はこちらの方が楽です。&lt;/p&gt;
&lt;h3&gt;何を作るか&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://ollama.com/&quot;&gt;Ollama&lt;/a&gt;を使ったローカルLLMチャットアプリです。構成は以下のとおりです。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;サービス&lt;/th&gt;
&lt;th&gt;イメージ&lt;/th&gt;
&lt;th&gt;役割&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;app&lt;/td&gt;
&lt;td&gt;Ruby on Rails&lt;/td&gt;
&lt;td&gt;Webアプリ + チャットUI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;db&lt;/td&gt;
&lt;td&gt;PostgreSQL 17&lt;/td&gt;
&lt;td&gt;チャット履歴の保存&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;redis&lt;/td&gt;
&lt;td&gt;Redis 7&lt;/td&gt;
&lt;td&gt;セッション・キャッシュ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ollama&lt;/td&gt;
&lt;td&gt;Ollama&lt;/td&gt;
&lt;td&gt;ローカルLLM推論&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;4つのコンテナが連携して動く、フルスタック構成です。&lt;/p&gt;
&lt;h3&gt;docker-compose.yaml&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;services:
  app:
    build: .
    ports:
      - &quot;3000:3000&quot;
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    environment:
      - RAILS_ENV=production
      - DATABASE_HOST=db
      - DATABASE_USER=postgres
      - DATABASE_PASSWORD=password
      - REDIS_URL=redis://redis:6379/0
      - OLLAMA_URL=http://ollama:11434
      - SECRET_KEY_BASE=dummy-secret-key-for-demo-only
      - RAILS_LOG_TO_STDOUT=true
      - RAILS_SERVE_STATIC_FILES=true
    healthcheck:
      test: [&quot;CMD&quot;, &quot;curl&quot;, &quot;-f&quot;, &quot;http://localhost:3000/up&quot;]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 30s

  db:
    image: postgres:17-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=app_production
    healthcheck:
      test: [&quot;CMD-SHELL&quot;, &quot;pg_isready -U postgres&quot;]
      interval: 5s
      timeout: 3s
      retries: 5

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    healthcheck:
      test: [&quot;CMD&quot;, &quot;redis-cli&quot;, &quot;ping&quot;]
      interval: 5s
      timeout: 3s
      retries: 5

  ollama:
    image: ollama/ollama:latest
    volumes:
      - ollama_data:/root/.ollama
    healthcheck:
      test: [&quot;CMD&quot;, &quot;curl&quot;, &quot;-f&quot;, &quot;http://localhost:11434/api/tags&quot;]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

volumes:
  postgres_data:
  redis_data:
  ollama_data:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;ポイント:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;depends_on&lt;/code&gt; + &lt;code&gt;condition: service_healthy&lt;/code&gt; でDBとRedisの起動を待ってからアプリを起動します&lt;/li&gt;
&lt;li&gt;各サービスに&lt;code&gt;healthcheck&lt;/code&gt;を定義しています。Coolifyがコンテナの状態を監視できます&lt;/li&gt;
&lt;li&gt;&lt;code&gt;volumes&lt;/code&gt;でデータを永続化しています。デプロイしてもDB・Redis・Ollamaのモデルデータは保持されます&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Railsアプリのコード&lt;/h3&gt;
&lt;p&gt;Ollamaとの通信は&lt;code&gt;Net::HTTP&lt;/code&gt;で直接行います。gem追加は不要です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class HomeController &amp;lt; ApplicationController
  def index
    @db_adapter = ActiveRecord::Base.connection.adapter_name
    @redis_status = check_redis
    @ollama_status, @ollama_models = check_ollama
    @messages = Message.order(created_at: :desc).limit(20).reverse
  end

  def chat
    prompt = params[:prompt].to_s.strip
    return redirect_to root_path if prompt.empty?

    Message.create!(role: &quot;user&quot;, content: prompt)
    response = chat_with_ollama(prompt)
    Message.create!(role: &quot;assistant&quot;, content: response)
    redirect_to root_path
  end

  private

  def chat_with_ollama(prompt)
    uri = URI(&quot;#{ENV[&apos;OLLAMA_URL&apos;]}/api/generate&quot;)
    body = { model: &quot;tinyllama&quot;, prompt: prompt, stream: false }.to_json
    response = Net::HTTP.post(uri, body, &quot;Content-Type&quot; =&amp;gt; &quot;application/json&quot;)
    JSON.parse(response.body)[&quot;response&quot;]
  rescue =&amp;gt; e
    &quot;Error: #{e.message}&quot;
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ollamaの&lt;code&gt;/api/generate&lt;/code&gt;エンドポイントにPOSTするだけです。&lt;code&gt;stream: false&lt;/code&gt;で一括レスポンスを受け取っています。&lt;/p&gt;
&lt;h3&gt;Dockerfile&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;FROM ruby:3.4-alpine AS base
WORKDIR /app
ENV RAILS_ENV=production BUNDLE_WITHOUT=&quot;development:test&quot; BUNDLE_DEPLOYMENT=1

FROM base AS build
RUN apk add --no-cache build-base postgresql-dev curl yaml-dev
COPY Gemfile ./
RUN bundle lock &amp;amp;&amp;amp; bundle install --jobs 4

COPY . .
RUN SECRET_KEY_BASE_DUMMY=1 bin/rails assets:precompile 2&amp;gt;/dev/null || true

FROM base AS runtime
RUN apk add --no-cache libpq curl tzdata yaml &amp;amp;&amp;amp; adduser -D -h /app rails
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /app /app
RUN mkdir -p db storage log tmp/pids &amp;amp;&amp;amp; chown -R rails:rails db storage log tmp
USER rails
EXPOSE 3000

CMD [&quot;sh&quot;, &quot;-c&quot;, &quot;bin/rails db:prepare &amp;amp;&amp;amp; bin/rails server -b 0.0.0.0 -p 3000&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Coolifyでのデプロイ&lt;/h3&gt;
&lt;p&gt;Docker Composeアプリの場合、Coolifyの設定が少し違います。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;管理画面（GUI）の場合：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ビルドパックで&lt;strong&gt;Docker Compose&lt;/strong&gt;を選択&lt;/li&gt;
&lt;li&gt;ファイル名は&lt;code&gt;docker-compose.yaml&lt;/code&gt;（&lt;code&gt;.yml&lt;/code&gt;だとCoolifyが見つけられません。。。ここでハマりました）&lt;/li&gt;
&lt;li&gt;ドメインは「Domains for app」欄に入力（サービス名ごとに設定欄があります）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Claude Code MCP（プロンプト）の場合：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;coolify-demo-railsリポジトリをDocker Composeでデプロイして。
appサービスのドメインはdemo-rails.teraren.comで。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Docker Composeの場合、MCPの恩恵が特に大きいです。GUIだと&lt;code&gt;docker_compose_domains&lt;/code&gt;の設定がわかりにくいですが、MCPなら「appサービスにこのドメイン」と言えば裏でAPIを叩いて設定してくれます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-demo-project.png&quot; alt=&quot;Coolifyのプロジェクト一覧 — 3つのデモアプリがすべてrunning&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;動作確認&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-rails-chat-app.png&quot; alt=&quot;Rails + Ollama チャットアプリ — PostgreSQL・Redis・Ollamaすべて接続済み&quot; /&gt;&lt;/p&gt;
&lt;p&gt;4つのコンテナが連携して動いています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-rails-containers.png&quot; alt=&quot;Coolifyのログ画面 — app・db・redis・ollamaの4コンテナが稼働中&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Docker Composeの注意点&lt;/h3&gt;
&lt;p&gt;Coolifyは本来「アプリとDBを個別管理」の思想です。Docker Composeを使う場合の注意点があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DB・Redisのバックアップ&lt;/strong&gt;はCoolifyの管理外になります（Compose内のボリュームは自分で管理）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;個別サービスのスケーリング&lt;/strong&gt;ができません&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;環境変数の管理&lt;/strong&gt;がCompose内に閉じます（CoolifyのUI経由で変更しにくい）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;逆に向いているケース：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ollama + App のように&lt;strong&gt;サービス間の結合度が高い&lt;/strong&gt;場合&lt;/li&gt;
&lt;li&gt;&lt;code&gt;depends_on&lt;/code&gt;で&lt;strong&gt;起動順序の制御が必要&lt;/strong&gt;な場合&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ローカルとCoolifyで同じcompose&lt;/strong&gt;を使い回したい場合&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ビルドパック比較まとめ&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;観点&lt;/th&gt;
&lt;th&gt;Nixpacks&lt;/th&gt;
&lt;th&gt;Dockerfile&lt;/th&gt;
&lt;th&gt;Docker Compose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;設定ファイル&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;不要&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dockerfile&lt;/td&gt;
&lt;td&gt;docker-compose.yaml + Dockerfile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;難易度&lt;/td&gt;
&lt;td&gt;簡単&lt;/td&gt;
&lt;td&gt;中&lt;/td&gt;
&lt;td&gt;複雑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;イメージ最適化&lt;/td&gt;
&lt;td&gt;自動（大きめ）&lt;/td&gt;
&lt;td&gt;自由自在&lt;/td&gt;
&lt;td&gt;自由自在&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;マルチコンテナ&lt;/td&gt;
&lt;td&gt;不可&lt;/td&gt;
&lt;td&gt;不可&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;可能&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ビルド時間&lt;/td&gt;
&lt;td&gt;長め&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;制御可能&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;長め&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;本番向き&lt;/td&gt;
&lt;td&gt;△&lt;/td&gt;
&lt;td&gt;◎&lt;/td&gt;
&lt;td&gt;○&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;迷ったら：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;とりあえず動かしたい → &lt;strong&gt;Nixpacks&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;本番で使う → &lt;strong&gt;Dockerfile&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;DB込みで丸ごと載せたい → &lt;strong&gt;Docker Compose&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;MCPでやる場合の比較&lt;/h3&gt;
&lt;p&gt;今回の3つのアプリは、GUIだと各アプリで3〜5画面の操作が必要でした。MCPなら以下のとおりです。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;th&gt;GUI&lt;/th&gt;
&lt;th&gt;MCP（プロンプト）&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hono（Nixpacks）&lt;/td&gt;
&lt;td&gt;画面操作4ステップ&lt;/td&gt;
&lt;td&gt;プロンプト1つ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go（Dockerfile）&lt;/td&gt;
&lt;td&gt;画面操作4ステップ&lt;/td&gt;
&lt;td&gt;プロンプト1つ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rails（Docker Compose）&lt;/td&gt;
&lt;td&gt;画面操作6ステップ + API&lt;/td&gt;
&lt;td&gt;プロンプト1つ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3つまとめてデプロイ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;約15分&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;約4分&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;特にDocker Composeのドメイン設定は、GUIだと&lt;code&gt;docker_compose_domains&lt;/code&gt;のJSON構造を理解する必要があります。MCPなら「appサービスにこのドメイン」と言うだけです。詳しくは&lt;a href=&quot;/posts/coolify-claude-code-mcp&quot;&gt;第2回&lt;/a&gt;を参照してください。&lt;/p&gt;
&lt;p&gt;次回の&lt;a href=&quot;/posts/coolify-cloudflare-tunnel&quot;&gt;第4回&lt;/a&gt;ではCloudflare Tunnelとの連携を詳しく書きます。自宅サーバを安全に外部公開する方法と、PRプレビュー環境の構築など。&lt;/p&gt;
&lt;h3&gt;シリーズ記事&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas/&quot;&gt;Vercel月額$42→自宅サーバ月額$0。Coolifyで個人サービス基盤を作った話&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-claude-code-mcp/&quot;&gt;Coolifyインストールから「プロンプトでデプロイ」まで：Claude Code MCP実践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coolifyハンズオン：Hono・Go・Railsを実際にデプロイしてみる&lt;/strong&gt;（この記事）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-cloudflare-tunnel/&quot;&gt;Cloudflare Tunnel×Coolify：自宅サーバを安全に外部公開する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-llm-era-self-hosting/&quot;&gt;API-firstなインフラが生き残る：LLM時代のセルフホスト戦略&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring/&quot;&gt;ZabbixでDockerコンテナをリソース監視する：Coolify環境の可視化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-backup-strategy/&quot;&gt;Coolify環境のバックアップ戦略：6つのDBを自動ダンプ+復旧手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-log-management-incident-response/&quot;&gt;Coolify環境のログ管理と障害対応：Docker + Zabbix + Discordで運用を回す&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>API-firstなインフラが生き残る：LLM時代のセルフホスト戦略</title><link>https://blog.teraren.com/posts/coolify-llm-era-self-hosting/</link><guid isPermaLink="true">https://blog.teraren.com/posts/coolify-llm-era-self-hosting/</guid><description>REST APIがあればAIエージェントと連携できる。MCPはAPI設定の簡略化レイヤーに過ぎない。API-firstなOSSがLLM時代に生き残る理由。</description><pubDate>Sat, 14 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;REST APIがあるかどうか&lt;/strong&gt;が、インフラツールの選定基準として重要度を増した&lt;/li&gt;
&lt;li&gt;AIエージェントから操作できないインフラは、手動オペレーションのコストが相対的に上がる&lt;/li&gt;
&lt;li&gt;セルフホストの世界では、&lt;strong&gt;API-firstなOSSが生き残る&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このシリーズの最終回。&lt;a href=&quot;/posts/coolify-why-self-hosted-paas&quot;&gt;第1回&lt;/a&gt;から&lt;a href=&quot;/posts/coolify-cloudflare-tunnel&quot;&gt;第4回&lt;/a&gt;まで、Coolify + Cloudflare Tunnelで自宅サーバにPaaS環境を構築してきました。ここでは「なぜ今セルフホストなのか」を、LLMとAPIの文脈から考えます。&lt;/p&gt;
&lt;h2&gt;Coolifyシリーズの振り返り&lt;/h2&gt;
&lt;p&gt;5回にわたって書いてきたことの全体像。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;回&lt;/th&gt;
&lt;th&gt;テーマ&lt;/th&gt;
&lt;th&gt;要点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas&quot;&gt;第1回&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;選定理由&lt;/td&gt;
&lt;td&gt;Vercel月額$42→$0。Coolify一択だった&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/posts/coolify-claude-code-mcp&quot;&gt;第2回&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;インストール &amp;amp; MCP&lt;/td&gt;
&lt;td&gt;GUIで10分→プロンプト4分&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/posts/coolify-hands-on-deploy&quot;&gt;第3回&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;ハンズオン&lt;/td&gt;
&lt;td&gt;3つのビルドパックを実際に体験&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;/posts/coolify-cloudflare-tunnel&quot;&gt;第4回&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;ネットワーク&lt;/td&gt;
&lt;td&gt;Cloudflare Tunnelでポート開放なし公開&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;第5回&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;戦略&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;API-firstがインフラ選定を変える&lt;/strong&gt;（この記事）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;個別のHowToは前の4回で書きました。ここでは「なぜ」と「これから」の話をします。&lt;/p&gt;
&lt;h2&gt;APIがインフラ選定の基準を変える&lt;/h2&gt;
&lt;h3&gt;従来の選定基準&lt;/h3&gt;
&lt;p&gt;インフラツールを選ぶとき、これまでの判断基準はこんな感じでした。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;機能が要件を満たすか&lt;/li&gt;
&lt;li&gt;コスト（ライセンス、運用コスト）&lt;/li&gt;
&lt;li&gt;学習コスト&lt;/li&gt;
&lt;li&gt;コミュニティの活発さ&lt;/li&gt;
&lt;li&gt;ベンダーロックイン&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;新しい基準：AI操作可能性&lt;/h3&gt;
&lt;p&gt;2025年以降、ここに &lt;strong&gt;「AIエージェントから操作できるか」&lt;/strong&gt; が加わりました。具体的には：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;REST APIがあるか？&lt;/strong&gt; → AIエージェントがツールを操作する大前提&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;操作の粒度は十分か？&lt;/strong&gt; → 作成・更新・削除・デプロイが一通りAPIでできるか&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APIドキュメントが整備されているか？&lt;/strong&gt; → LLMが使い方を理解できるか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;REST APIさえあれば、AIエージェントは直接APIを叩けますし、MCPのようなラッパーを介した操作も可能です。&lt;strong&gt;本質はAPIの有無&lt;/strong&gt;であって、特定のプロトコルへの対応ではありません。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/coolify-claude-code-mcp&quot;&gt;第2回&lt;/a&gt;で実際にやりましたが、WordPressの構築（DB作成→アプリ作成→環境変数→デプロイ→テーマ設定→記事投入）が&lt;strong&gt;プロンプト2回で完了&lt;/strong&gt;しました。GUIだと15分、Terraformで書くなら30分はかかる作業です。&lt;/p&gt;
&lt;p&gt;この差は、サービスが1個なら大したことありません。でも20個、30個のサービスを運用していると、&lt;strong&gt;積算の差が巨大になります。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;API対応状況の現在地&lt;/h2&gt;
&lt;p&gt;2026年3月時点で、主要なインフラツールのAPI対応状況。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ツール&lt;/th&gt;
&lt;th&gt;REST API&lt;/th&gt;
&lt;th&gt;AI連携&lt;/th&gt;
&lt;th&gt;備考&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Coolify&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;REST API完備&lt;/td&gt;
&lt;td&gt;MCP、直接API呼び出し&lt;/td&gt;
&lt;td&gt;コミュニティMCPあり&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cloudflare&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;公式API&lt;/td&gt;
&lt;td&gt;MCP、Wrangler CLI&lt;/td&gt;
&lt;td&gt;Workers, KV, D1等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;公式API&lt;/td&gt;
&lt;td&gt;MCP、AWS CLI、SDK&lt;/td&gt;
&lt;td&gt;CDK, CloudWatch等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Terraform&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HCL + CLI&lt;/td&gt;
&lt;td&gt;MCP、直接CLI&lt;/td&gt;
&lt;td&gt;plan/apply連携&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;REST / GraphQL&lt;/td&gt;
&lt;td&gt;MCP、gh CLI&lt;/td&gt;
&lt;td&gt;Issue, PR, Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vercel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;REST API あり&lt;/td&gt;
&lt;td&gt;直接API呼び出し&lt;/td&gt;
&lt;td&gt;MCPなしでもAPI経由で操作可能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Kubernetes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;kubectl / API&lt;/td&gt;
&lt;td&gt;直接API、CLI&lt;/td&gt;
&lt;td&gt;豊富なエコシステム&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;注目すべきは、&lt;strong&gt;REST APIがあればAIエージェントとの連携方法は複数ある&lt;/strong&gt;ことです。MCPはその一つに過ぎません。&lt;a href=&quot;/posts/coolify-claude-code-mcp&quot;&gt;第2回&lt;/a&gt;の余談で書きましたが、MCPサーバーのソースコードを見ると、やっていることはAPIのラッパーに過ぎません。MCPはAPI設定を簡略化するレイヤーであって、本質はREST APIの存在そのものです。&lt;/p&gt;
&lt;p&gt;逆に言えば、&lt;strong&gt;REST APIがないツールはAIエージェントとの連携が構造的にできません&lt;/strong&gt;。GUIオンリーのツールは、AIエージェント時代に取り残されます。&lt;/p&gt;
&lt;h3&gt;MCPの立ち位置と限界&lt;/h3&gt;
&lt;p&gt;MCPは便利ですが、過度に持ち上げるべきではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MCPの利点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API接続のセットアップが簡単（&lt;code&gt;claude mcp add&lt;/code&gt; 一発）&lt;/li&gt;
&lt;li&gt;ツール定義がAIに自動で渡される&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;MCPの限界：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;コンテキストウィンドウを圧迫します。&lt;/strong&gt; MCPで接続したツール定義はすべてコンテキストに載ります。MCPサーバーを5個、10個と追加すると、それだけでトークンを消費してしまいます&lt;/li&gt;
&lt;li&gt;REST APIを直接叩けるAIエージェントなら、MCPなしでも同等のことができます&lt;/li&gt;
&lt;li&gt;MCPサーバーの品質はまちまちです。APIドキュメントを直接読んだ方が確実なケースもあります&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;結論：MCPはAPI-firstの恩恵を受けやすくする便利なレイヤーですが、本質はREST APIの有無です。&lt;/strong&gt; APIがあればMCPがなくても困りません。&lt;/p&gt;
&lt;h2&gt;「手動オペレーション税」の概念&lt;/h2&gt;
&lt;p&gt;AIエージェントが使えないインフラを運用し続けることは、&lt;strong&gt;毎回「手動オペレーション税」を払い続ける&lt;/strong&gt;ことになります。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;操作&lt;/th&gt;
&lt;th&gt;API対応ツール（AI活用）&lt;/th&gt;
&lt;th&gt;APIなしツール&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;新サービスのデプロイ&lt;/td&gt;
&lt;td&gt;プロンプト1つ（2分）&lt;/td&gt;
&lt;td&gt;GUIで10分&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;環境変数の一括設定&lt;/td&gt;
&lt;td&gt;プロンプト1つ（1分）&lt;/td&gt;
&lt;td&gt;1つずつ手入力（5分）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;develop環境の複製&lt;/td&gt;
&lt;td&gt;プロンプト1つ（4分）&lt;/td&gt;
&lt;td&gt;手順書を見て再現（20分）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DB接続設定&lt;/td&gt;
&lt;td&gt;AIが自動判定（0分）&lt;/td&gt;
&lt;td&gt;接続文字列をコピペ（3分）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;監視ツール構築&lt;/td&gt;
&lt;td&gt;プロンプト1つ（10分）&lt;/td&gt;
&lt;td&gt;ドキュメント読んで設定（1時間）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;1回1回の差は小さくても、20サービス×月に数回のオペレーション×12ヶ月で考えると、&lt;strong&gt;年間で数十時間の差&lt;/strong&gt;になります。個人開発者にとって、この時間は新しいサービスを作る時間に充てられます。&lt;/p&gt;
&lt;h2&gt;セルフホストとLLMの相性&lt;/h2&gt;
&lt;h3&gt;なぜセルフホストが有利なのか&lt;/h3&gt;
&lt;p&gt;LLMを活用したサービスを作る場合、セルフホストには構造的な優位性があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. リソースの制約がない&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;クラウドPaaSでは、LLM推論に必要なメモリやCPUがプランの上限に引っかかります。&lt;a href=&quot;/posts/coolify-hands-on-deploy&quot;&gt;第3回&lt;/a&gt;でOllama + Rails + PostgreSQL + Redisの4コンテナをDocker Composeでデプロイしましたが、これをVercelやfly.ioでやると従量課金が跳ねます。自宅サーバなら、32GBのRAMを好きなだけ使えます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. プロトタイプの公開が即座にできる&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;LLMを使った新しいアイデアを思いついたら、Claude Codeに「このアプリをCoolifyにデプロイして」と言うだけで外部公開できます。&lt;a href=&quot;/posts/coolify-cloudflare-tunnel&quot;&gt;Cloudflare Tunnel&lt;/a&gt;でSSLもCDNも自動です。友人やチームメンバーにURLを共有してフィードバックをもらえます。&lt;/p&gt;
&lt;p&gt;クラウドPaaSだと「まず料金を確認して」「プランを選んで」「クレカ情報を入れて」。。。プロトタイプの段階でこの摩擦は致命的です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. データが手元にある&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;LLMアプリは大量のユーザーデータを扱うことが多いです。トレーニングデータ、会話履歴、生成結果。これを外部のクラウドに置くと、プライバシーの問題が出てきます。セルフホストなら全部自分のSSDの中です。&lt;/p&gt;
&lt;h3&gt;AIエージェントが加速するセルフホスト&lt;/h3&gt;
&lt;p&gt;AIエージェント（Claude Code等）の登場で、セルフホストの最大の弱点だった &lt;strong&gt;「運用の面倒さ」が大幅に軽減&lt;/strong&gt; されました。&lt;/p&gt;
&lt;p&gt;従来のセルフホストは「自分で全部やる」が前提で、DevOpsの知識が必要でした。でも今は「AIに頼む」でほとんどの運用タスクが完結します。REST APIがあるツールなら、AIが直接APIを叩いて操作してくれます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;従来: ドキュメントを読む → 設定ファイルを書く → テスト → 本番適用 → 監視
AI:  「〜を設定して」→ AIがAPIで全部やる → 結果を確認
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;/posts/coolify-claude-code-mcp&quot;&gt;第2回&lt;/a&gt;でZabbixの構築に10分、MariaDBのチューニングに5分かかった程度です。手動だったら各1時間以上かかる作業です。この効率化が、セルフホストのハードルを劇的に下げています。&lt;/p&gt;
&lt;h2&gt;「GUIの良さ」は残る&lt;/h2&gt;
&lt;p&gt;ここまでMCPとCLIの話をしてきましたが、GUIが不要になるわけではありません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GUIが向いている場面：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;現在の状態を&lt;strong&gt;俯瞰的に把握&lt;/strong&gt;する（ダッシュボード、メトリクス）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;視覚的な確認&lt;/strong&gt;が必要な操作（ログのスクロール、グラフの確認）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;初めて触るツール&lt;/strong&gt;の学習（何ができるかを探索する）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;AIエージェント（API経由）が向いている場面：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;繰り返しの操作&lt;/strong&gt;（デプロイ、環境変数設定、DB作成）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;複数ステップの自動化&lt;/strong&gt;（プロジェクト作成→DB→アプリ→環境変数→デプロイ）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;既知のタスクの実行&lt;/strong&gt;（やりたいことが明確で、手順がわかっている）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CoolifyにはGUIもREST APIもあります。状況に応じて使い分けられるのが理想で、「API対応だからGUIは不要」ではありません。&lt;strong&gt;両方あるツールが強いです。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;これからのインフラ選定&lt;/h2&gt;
&lt;p&gt;個人開発者として、今後インフラツールを選ぶときの基準をまとめておきます。&lt;/p&gt;
&lt;h3&gt;必須条件&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;REST APIが充実している&lt;/strong&gt;（AI連携の土台）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セルフホスト可能&lt;/strong&gt;（コスト制御とデータ主権）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dockerベース&lt;/strong&gt;（ポータビリティ、ベンダーロックインなし）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OSSである&lt;/strong&gt;（透明性、コミュニティ、将来性）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;強い加点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;APIドキュメントが充実している&lt;/strong&gt;（AIが使い方を理解しやすい）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub App連携&lt;/strong&gt;（Push to Deploy）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CDN/Tunnel対応の容易さ&lt;/strong&gt;（Cloudflare Tunnel等）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;これから淘汰されるもの&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;GUIオンリーでAPIがないツール&lt;/li&gt;
&lt;li&gt;SaaS専用でセルフホストできないツール&lt;/li&gt;
&lt;li&gt;独自プロトコルでDockerと相性が悪いツール&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;厳しい言い方ですが、REST APIがないインフラツールは今後AIエージェントと連携できません。APIを後付けするのはアーキテクチャレベルの改修になります。&lt;strong&gt;API-firstで設計されていないツールは、構造的にAIエージェント時代に適応できません。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;5回にわたって、Coolify + Cloudflare Tunnel + Claude Codeの組み合わせで自宅サーバにPaaS環境を構築する話を書きました。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;シリーズで得たもの&lt;/th&gt;
&lt;th&gt;コスト&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Vercel相当のデプロイ体験&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CDN + WAF + DDoS対策&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AIエージェントによるインフラ操作&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;無制限のサービスデプロイ&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PRプレビュー環境&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLMプロトタイプの即時公開基盤&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;全部タダです。必要なのは、Dockerが動くサーバ1台と、Cloudflareの無料アカウントと、Claude Codeだけです。&lt;/p&gt;
&lt;p&gt;LLMの時代に「インフラをどう管理するか」の答えは、 &lt;strong&gt;「AIに頼む」&lt;/strong&gt; だと思っています。そのためには、AIが操作できるインフラを選ぶ必要があります。Coolifyはその条件を満たしている数少ないOSSの一つです。&lt;/p&gt;
&lt;p&gt;自宅にサーバがあるなら、Coolifyを入れない理由がありません。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;シリーズ記事&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-why-self-hosted-paas/&quot;&gt;Vercel月額$42→自宅サーバ月額$0。Coolifyで個人サービス基盤を作った話&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-claude-code-mcp/&quot;&gt;Coolifyインストールから「プロンプトでデプロイ」まで：Claude Code MCP実践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-hands-on-deploy/&quot;&gt;Coolifyハンズオン：Hono・Go・Railsを実際にデプロイしてみる&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-cloudflare-tunnel/&quot;&gt;Cloudflare Tunnel×Coolify：自宅サーバを安全に外部公開する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API-firstなインフラが生き残る：LLM時代のセルフホスト戦略&lt;/strong&gt;（この記事）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring/&quot;&gt;ZabbixでDockerコンテナをリソース監視する：Coolify環境の可視化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-backup-strategy/&quot;&gt;Coolify環境のバックアップ戦略：6つのDBを自動ダンプ+復旧手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-log-management-incident-response/&quot;&gt;Coolify環境のログ管理と障害対応：Docker + Zabbix + Discordで運用を回す&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Vercel月額$42→自宅サーバ月額$0。Coolifyで個人サービス基盤を作った話</title><link>https://blog.teraren.com/posts/coolify-why-self-hosted-paas/</link><guid isPermaLink="true">https://blog.teraren.com/posts/coolify-why-self-hosted-paas/</guid><description>Vercelに年間$300以上払っていた個人サービス群を、自宅サーバ+Coolifyに移行してコストゼロにした選定理由と実践記録。23アプリ・7DBを1台で運用中。</description><pubDate>Fri, 13 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://vercel.com/&quot;&gt;Vercel&lt;/a&gt; Pro に月額$20〜$42払っていた個人サービスを、自宅サーバ + &lt;a href=&quot;https://coolify.io/&quot;&gt;Coolify&lt;/a&gt; に移行した&lt;/li&gt;
&lt;li&gt;現在、&lt;strong&gt;5プロジェクト・23アプリケーション・7データベース&lt;/strong&gt;を1台のサーバで運用中。月額$0&lt;/li&gt;
&lt;li&gt;Coolifyは「自宅の&lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt;をVercel化する」OSS PaaS。GitHubにPushしたら自動ビルド&amp;amp;デプロイ&amp;amp;SSL化してくれる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;きっかけ：Vercelの請求書&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ai-triathlon-result.teraren.com/&quot;&gt;トライアスロン大会結果の分析サービス&lt;/a&gt;を&lt;a href=&quot;https://vercel.com/&quot;&gt;Vercel&lt;/a&gt;で運用していました。構成は&lt;a href=&quot;https://nextjs.org/&quot;&gt;Next.js&lt;/a&gt; + &lt;a href=&quot;https://auth0.com/&quot;&gt;Auth0&lt;/a&gt; + &lt;a href=&quot;https://stripe.com/&quot;&gt;Stripe&lt;/a&gt; + &lt;a href=&quot;https://redis.io/&quot;&gt;Redis&lt;/a&gt;（ioredis） + &lt;a href=&quot;https://sdk.vercel.ai/&quot;&gt;AI SDK&lt;/a&gt;（Google AI / xAI / Groq） + &lt;a href=&quot;https://next-intl-docs.vercel.app/&quot;&gt;next-intl&lt;/a&gt;（多言語対応）。フルスタックのNext.jsアプリで、Server ActionsでバックエンドもTypeScriptです。&lt;/p&gt;
&lt;p&gt;Vercel ProのBaseが月$20。トラフィックが多い月は従量課金で$42まで跳ねました。12ヶ月で31M edge requests、1TB fast data transfer。年間$300〜$500。個人サービスとしてはかなりの出費です。&lt;/p&gt;
&lt;p&gt;他にも個人で運用しているサービスが20個ほどあり、今後もLLMを使ったプロトタイプをどんどん作りたいと考えています。サービスが増えるたびにVercelの課金が増えるのは厳しいです。&lt;/p&gt;
&lt;h2&gt;これまで：自宅Docker直運用&lt;/h2&gt;
&lt;p&gt;自宅サーバにDockerは既に入っています。サーバといっても&lt;a href=&quot;/posts/gmktec-nucbox-m2/&quot;&gt;GMKtec NucBox M2&lt;/a&gt;という&lt;strong&gt;53,000円の激安ミニPC&lt;/strong&gt;（Intel Core i7-11390H / 32GB RAM / 1TB SSD）。手のひらサイズ。20個のサービスをそれぞれポート直叩きで動かして、&lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/&quot;&gt;Cloudflare Tunnel&lt;/a&gt;でDNSとポートのマッピングをGUIでポチポチ設定していました。&lt;/p&gt;
&lt;p&gt;これの問題は、サービスが増えるたびに以下の作業が必要なことです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dockerコンテナの起動設定を書く&lt;/li&gt;
&lt;li&gt;Cloudflare Zero Trust Dashboardでホスト名→ポートの設定を追加&lt;/li&gt;
&lt;li&gt;SSL証明書の管理（Cloudflare任せとはいえ）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;20個まではなんとかなりましたが、30個、40個と増えていくと管理コストが線形に増加します。もうちょっとなんとかしたいところです。&lt;/p&gt;
&lt;h2&gt;いくつか選択肢を考えた&lt;/h2&gt;
&lt;h3&gt;選択肢1: exe.dev&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/exe-dev-top.png&quot; alt=&quot;exe.devのトップページ。「A VM for every idea」がキャッチコピー&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://exe.dev/&quot;&gt;exe.dev&lt;/a&gt;はAIネイティブなインスタントVMホスティング。永続ディスク付きのUbuntuが即座に立ち上がって、HTTPS付きで公開されます。認証もヘッダー情報だけで完結するので手軽です。月$20で2CPU/8GB RAM/25GB disk、最大25VMまで。&lt;/p&gt;
&lt;p&gt;ただ、ベンダーロックインが気になります。10〜30個のサービスを載せるとなるとリソースが足りません。&lt;/p&gt;
&lt;h3&gt;選択肢2: fly.io&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/fly-io-top.png&quot; alt=&quot;fly.ioのトップページ。「Build fast. Run any code fearlessly.」&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://fly.io/&quot;&gt;fly.io&lt;/a&gt;は良いサービスですが、リソース制限があります。無料枠を超えるとすぐに課金が発生します。個人で大量のサービスを運用する基盤としてはコストが読みにくいです。&lt;/p&gt;
&lt;h3&gt;選択肢3: Kubernetes (k8s)&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://kubernetes.io/&quot;&gt;Kubernetes&lt;/a&gt;は言わずと知れたコンテナオーケストレーションツール。本格的に運用するなら最有力候補ですが、個人サービス10〜30個の規模にはオーバーキルです。Control Planeだけで数GBのRAMを消費します。32GBのミニPCでは、管理基盤にリソースを取られてアプリに回せません。学習コストも高いです。&lt;/p&gt;
&lt;h3&gt;選択肢4: Proxmox&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.proxmox.com/en/proxmox-virtual-environment/overview&quot;&gt;Proxmox VE&lt;/a&gt;は仮想化基盤。VMを切ってその上にDockerを載せる。。。みたいな構成もできますが、やりだすと沼にハマります。個人サービスの基盤としては大げさすぎます。やりたいのはアプリのデプロイであって、仮想マシンの管理ではありません。&lt;/p&gt;
&lt;h3&gt;選択肢5: Coolify&lt;/h3&gt;
&lt;p&gt;そこで見つけたのが&lt;a href=&quot;https://coolify.io/&quot;&gt;Coolify&lt;/a&gt;です。一言でいうと、&lt;strong&gt;セルフホスト版のVercel/Heroku/Netlify&lt;/strong&gt;です。自分のサーバにインストールするだけで、PaaSと同じデプロイ体験が手に入るOSSです。&lt;/p&gt;
&lt;h3&gt;比較まとめ&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;exe.dev&lt;/th&gt;
&lt;th&gt;fly.io&lt;/th&gt;
&lt;th&gt;Kubernetes&lt;/th&gt;
&lt;th&gt;Proxmox&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Coolify&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;月額コスト&lt;/td&gt;
&lt;td&gt;$20〜&lt;/td&gt;
&lt;td&gt;従量課金&lt;/td&gt;
&lt;td&gt;✅ $0（セルフホスト）&lt;/td&gt;
&lt;td&gt;✅ $0（セルフホスト）&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;$0（セルフホスト）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;初期構築&lt;/td&gt;
&lt;td&gt;✅ 即座&lt;/td&gt;
&lt;td&gt;✅ 数分&lt;/td&gt;
&lt;td&gt;数時間〜&lt;/td&gt;
&lt;td&gt;数時間〜&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;数分（コマンド1発）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;学習コスト&lt;/td&gt;
&lt;td&gt;✅ 低い&lt;/td&gt;
&lt;td&gt;中程度&lt;/td&gt;
&lt;td&gt;高い（YAML地獄）&lt;/td&gt;
&lt;td&gt;高い（仮想化の知識必要）&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;低い（GUIでポチポチ）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;サービス数上限&lt;/td&gt;
&lt;td&gt;25VM&lt;/td&gt;
&lt;td&gt;従量課金で増加&lt;/td&gt;
&lt;td&gt;✅ 実質無制限&lt;/td&gt;
&lt;td&gt;✅ 実質無制限&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;実質無制限&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DB管理&lt;/td&gt;
&lt;td&gt;自前&lt;/td&gt;
&lt;td&gt;有料アドオン&lt;/td&gt;
&lt;td&gt;自前&lt;/td&gt;
&lt;td&gt;自前&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;GUI標準装備&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Push to Deploy&lt;/td&gt;
&lt;td&gt;なし&lt;/td&gt;
&lt;td&gt;✅ あり&lt;/td&gt;
&lt;td&gt;要CI/CD構築&lt;/td&gt;
&lt;td&gt;なし&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;あり（GitHub連携）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL自動化&lt;/td&gt;
&lt;td&gt;✅ あり&lt;/td&gt;
&lt;td&gt;✅ あり&lt;/td&gt;
&lt;td&gt;要設定&lt;/td&gt;
&lt;td&gt;なし&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;あり（Let&apos;s Encrypt）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ベンダーロックイン&lt;/td&gt;
&lt;td&gt;あり&lt;/td&gt;
&lt;td&gt;あり&lt;/td&gt;
&lt;td&gt;✅ なし&lt;/td&gt;
&lt;td&gt;✅ なし&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;なし（素のDocker）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;管理リソース消費&lt;/td&gt;
&lt;td&gt;−&lt;/td&gt;
&lt;td&gt;−&lt;/td&gt;
&lt;td&gt;数GB（Control Plane）&lt;/td&gt;
&lt;td&gt;数GB（Hypervisor）&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;数百MB（UI+Traefik）&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;向いている用途&lt;/td&gt;
&lt;td&gt;プロトタイプ&lt;/td&gt;
&lt;td&gt;小〜中規模&lt;/td&gt;
&lt;td&gt;大規模運用&lt;/td&gt;
&lt;td&gt;VM管理&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;個人〜中規模のサービス運用&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;個人で10〜30個のサービスを運用する前提だと、&lt;strong&gt;Coolify一択&lt;/strong&gt;でした。コストゼロ、学習コストが低い、Docker資産がそのまま使える、管理リソースも軽いという点が決め手でした。&lt;/p&gt;
&lt;h2&gt;Coolifyとは&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-top.png&quot; alt=&quot;Coolifyのトップページ。「Self-hosting with superpowers.」429,991以上のセルフホストインスタンスが稼働中&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;プロジェクト概要&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/coollabsio/coolify&quot;&gt;Coolify&lt;/a&gt;は、ハンガリーの開発者 Andras Bacsai が2021年に立ち上げたOSSプロジェクトです。coolLabs Solutions Kft. が開発・運営しています。ライセンスは Apache 2.0です。&lt;/p&gt;
&lt;p&gt;GitHubスターは&lt;strong&gt;51,600以上&lt;/strong&gt;（2026年3月時点）。Discordコミュニティは20,000人超。クラウド版の有料ユーザーも3,200人以上いて、個人のサイドプロジェクトではなく、ちゃんとした事業として回っています。日本ではまだあまり知られていませんが、海外のセルフホスト界隈ではかなりメジャーな存在です。&lt;/p&gt;
&lt;p&gt;現在のバージョンは &lt;strong&gt;v4.0.0-beta&lt;/strong&gt;です。v3からアーキテクチャを刷新して、安定性重視の設計になっています。&lt;/p&gt;
&lt;h3&gt;アーキテクチャ&lt;/h3&gt;
&lt;p&gt;Coolifyの構成はシンプルです。自分のサーバにインストールすると、管理UI + Traefik（リバースプロキシ）+ Docker Engineの3層構造で動きます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TB
    subgraph Internet
        EndUser[&quot;サービス利用者&quot;]
        Admin[&quot;Coolify管理者&quot;]
        GitHub[GitHub]
        CF[Cloudflare CDN / WAF]
    end

    subgraph &quot;自宅サーバ（GMKtec NucBox M2）&quot;
        Tunnel[cloudflared&amp;lt;br/&amp;gt;Cloudflare Tunnel]

        subgraph Coolify
            UI[管理UI :8000]
            API[REST API]
            Traefik[Traefik リバースプロキシ]
        end

        subgraph &quot;Docker Engine&quot;
            App1[Next.js アプリ]
            App2[Rails アプリ]
            App3[WordPress]
            DB1[(MariaDB)]
            DB2[(Redis)]
            More[&quot;他のコンテナ...&quot;]
        end
    end

    EndUser --&amp;gt;|HTTPS| CF
    CF --&amp;gt;|Tunnel| Tunnel
    Tunnel --&amp;gt; Traefik
    Traefik --&amp;gt; App1
    Traefik --&amp;gt; App2
    Traefik --&amp;gt; App3
    App1 --&amp;gt; DB2
    App3 --&amp;gt; DB1

    Admin --&amp;gt;|HTTPS| UI
    GitHub --&amp;gt;|Webhook| API
    API --&amp;gt;|Build &amp;amp; Deploy| App1
    API --&amp;gt;|Build &amp;amp; Deploy| App2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ポイントは、&lt;strong&gt;CoolifyはDockerの上に乗る管理レイヤーに過ぎない&lt;/strong&gt;ということです。中で動いているのは普通のDockerコンテナです。Coolifyを外しても、コンテナはそのまま動き続けます。&lt;/p&gt;
&lt;h3&gt;ネットワーク構成：自宅サーバ vs VPS&lt;/h3&gt;
&lt;p&gt;Coolifyはどこで動かすかによってネットワーク構成が変わります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自宅サーバの場合&lt;/strong&gt;、インターネットに直接公開するにはポート開放が必要ですが、それはセキュリティ的にやりたくありません。&lt;a href=&quot;https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/&quot;&gt;Cloudflare Tunnel&lt;/a&gt;を使えば、自宅からOutbound接続だけで外部公開できます。ポート開放不要、固定IP不要、DDNS不要。さらにCloudflareのCDNとWAFが必然的にフロントに立つので、DDoS対策もキャッシュも無料でついてきます。&lt;strong&gt;自宅サーバで運用するなら、Cloudflareの裏で動かすのが一番安全&lt;/strong&gt;だと感じています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;VPSの場合&lt;/strong&gt;、インターネットに直接出せばよいです。CoolifyのTraefikがSSL終端してくれるので、そのまま公開できます。ただ、CDNやWAFが欲しければ別途Cloudflare等を設定する必要があるので、そこは若干面倒です。&lt;/p&gt;
&lt;p&gt;結局、自宅サーバ + Cloudflare Tunnelの構成が、セキュリティ・コスト・手軽さのバランスが一番良い気がします。CDNが勝手についてくるのは自宅サーバならではのメリットです。ネットワーク構成の詳細は&lt;a href=&quot;/posts/coolify-cloudflare-tunnel&quot;&gt;第4回&lt;/a&gt;で書きます。&lt;/p&gt;
&lt;h3&gt;k8sとの違い&lt;/h3&gt;
&lt;p&gt;「Dockerでサービスを管理するなら&lt;a href=&quot;https://kubernetes.io/&quot;&gt;Kubernetes&lt;/a&gt;じゃないの？」と思うかもしれません。比較するとこんな感じです。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Coolify&lt;/th&gt;
&lt;th&gt;Kubernetes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;学習コスト&lt;/td&gt;
&lt;td&gt;低い。GUIでポチポチ&lt;/td&gt;
&lt;td&gt;高い。YAML地獄&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;インストール&lt;/td&gt;
&lt;td&gt;コマンド1発（5分）&lt;/td&gt;
&lt;td&gt;クラスター構築が必要（数時間〜）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;最小構成&lt;/td&gt;
&lt;td&gt;サーバ1台&lt;/td&gt;
&lt;td&gt;Control Plane + Worker Node（最低2〜3台推奨）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;リソース消費&lt;/td&gt;
&lt;td&gt;管理UI + Traefik（軽量）&lt;/td&gt;
&lt;td&gt;Control Planeだけで数GBのRAM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;スケーリング&lt;/td&gt;
&lt;td&gt;Docker Swarmで対応可&lt;/td&gt;
&lt;td&gt;ネイティブ対応。大規模向き&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;向いている規模&lt;/td&gt;
&lt;td&gt;1〜50サービス程度&lt;/td&gt;
&lt;td&gt;50〜数千サービス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ベンダーロックイン&lt;/td&gt;
&lt;td&gt;なし（素のDocker）&lt;/td&gt;
&lt;td&gt;なし（OSSだが依存は複雑）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;個人サービス10〜30個の規模なら、k8sは明らかにオーバーキルです。Control Planeのリソース消費だけで、私のミニPCのRAMがかなり持っていかれます。Coolifyなら管理UI + Traefikで数百MB程度です。残りの30GBをアプリに使えます。&lt;/p&gt;
&lt;h3&gt;デプロイフロー&lt;/h3&gt;
&lt;p&gt;開発からデプロイまでの流れです。Vercelと同じ体験がセルフホストで手に入ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    participant Dev as 開発者
    participant GH as GitHub
    participant Cool as Coolify
    participant Docker as Docker Engine
    participant CF as Cloudflare

    Dev-&amp;gt;&amp;gt;GH: git push
    GH-&amp;gt;&amp;gt;Cool: Webhook通知
    Cool-&amp;gt;&amp;gt;Cool: ソースをPull
    Cool-&amp;gt;&amp;gt;Cool: Nixpacks or Dockerfileでビルド
    Cool-&amp;gt;&amp;gt;Docker: コンテナをデプロイ
    Cool-&amp;gt;&amp;gt;Cool: Traefikルーティング設定
    Cool-&amp;gt;&amp;gt;CF: SSL証明書（自動）
    CF--&amp;gt;&amp;gt;Dev: https://app.example.com で公開完了
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;初期構築フロー&lt;/h3&gt;
&lt;p&gt;Coolifyの導入から最初のサービス公開まで、やることは少ないです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flowchart LR
    A[サーバを用意] --&amp;gt; B[Coolifyインストール&amp;lt;br/&amp;gt;コマンド1発]
    B --&amp;gt; C[管理UIにアクセス&amp;lt;br/&amp;gt;:8000]
    C --&amp;gt; D[GitHubアプリ連携]
    D --&amp;gt; E[プロジェクト作成]
    E --&amp;gt; F[アプリ追加&amp;lt;br/&amp;gt;リポジトリを選択]
    F --&amp;gt; G[ドメイン設定]
    G --&amp;gt; H[デプロイ！]

    style A fill:#f9f,stroke:#333
    style H fill:#9f9,stroke:#333
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;何ができるのか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Push to Deploy&lt;/strong&gt;: GitHub / GitLab / Bitbucket / Giteaと連携。Pushしたら自動でビルド&amp;amp;デプロイ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リバースプロキシ自動設定&lt;/strong&gt;: &lt;a href=&quot;https://traefik.io/&quot;&gt;Traefik&lt;/a&gt;が裏で動いていて、ドメインを割り当てれば即SSL化（&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let&apos;s Encrypt&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;データベース管理&lt;/strong&gt;: MariaDB、PostgreSQL、MySQL、MongoDB、Redisなどをボタンひとつで立ち上げ。自動バックアップもある&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;280+のワンクリックサービス&lt;/strong&gt;: &lt;a href=&quot;https://plausible.io/&quot;&gt;Plausible&lt;/a&gt;、&lt;a href=&quot;https://gitea.io/&quot;&gt;Gitea&lt;/a&gt;、&lt;a href=&quot;https://uptime.kuma.pet/&quot;&gt;Uptime Kuma&lt;/a&gt;、&lt;a href=&quot;https://n8n.io/&quot;&gt;n8n&lt;/a&gt;など、OSSのセルフホストツールを一発でデプロイできる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PRプレビュー環境&lt;/strong&gt;: PRごとに一時的なURLを自動生成。Vercelのプレビューと同じ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker Compose対応&lt;/strong&gt;: 既存の&lt;code&gt;docker-compose.yml&lt;/code&gt;がそのまま使える&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;複数サーバ管理&lt;/strong&gt;: SSH接続できるサーバならリモートでも管理可能。VPSやRaspberry Piでも&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API &amp;amp; MCP&lt;/strong&gt;: REST APIが充実していて、&lt;a href=&quot;https://github.com/StuMason/coolify-mcp&quot;&gt;MCP（Model Context Protocol）サーバー&lt;/a&gt;も用意されている。つまり&lt;strong&gt;Claude CodeなどのAIエージェントからプロンプトで操作できる&lt;/strong&gt;（これについては&lt;a href=&quot;/posts/coolify-claude-code-mcp&quot;&gt;第2回&lt;/a&gt;で詳しく書きます）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;誰が使うのか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;個人開発者&lt;/strong&gt;: 月額$0で無制限にサービスをデプロイ。Vercel/Herokuの代替&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スタートアップ&lt;/strong&gt;: LLMを使ったプロトタイプを即座に外部公開してフィードバックを得る&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;社内ツール運用&lt;/strong&gt;: 社内向けサービスをVPSや自社サーバに集約。SaaSの課金を減らしたいチーム&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;完全にセルフホストなので、データは全部自分の手元です。ベンダーロックインもありません。Coolifyをやめても、中で動いているDockerコンテナはそのまま動き続けます。&lt;/p&gt;
&lt;h2&gt;選定の決め手&lt;/h2&gt;
&lt;h3&gt;ベンダーロックインなし&lt;/h3&gt;
&lt;p&gt;上のアーキテクチャ図の通り、CoolifyはDockerの管理レイヤーでしかありません。&lt;code&gt;docker-compose.yml&lt;/code&gt;がそのまま資産になるので、Coolifyをやめても何も失いません。&lt;/p&gt;
&lt;h3&gt;既存サービスの移行が段階的に可能&lt;/h3&gt;
&lt;p&gt;既存の20サービスは各サブドメイン（&lt;code&gt;xxx.teraren.com&lt;/code&gt;）で運用中。Cloudflare Tunnelの設定を活かしたまま、こうやって移行できます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Coolifyをインストール（既存サービスに影響なし）&lt;/li&gt;
&lt;li&gt;Cloudflare Tunnelにワイルドカード設定（&lt;code&gt;*.teraren.com&lt;/code&gt; → Coolify）を追加&lt;/li&gt;
&lt;li&gt;既存の個別設定（&lt;code&gt;xxx.teraren.com&lt;/code&gt; → &lt;code&gt;localhost:3000&lt;/code&gt;）は&lt;strong&gt;そのまま優先される&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;新サービスはCoolifyにデプロイ。ワイルドカードでキャッチされる&lt;/li&gt;
&lt;li&gt;既存サービスもCoolifyに載せ替えたら、個別設定を削除するだけ&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;旧環境を残したまま新環境を構築し、DNS切り替えで移行します。Blue/Green的な安心感があります。&lt;/p&gt;
&lt;h2&gt;現在の構成&lt;/h2&gt;
&lt;p&gt;移行完了後の構成がこちらです。1台のサーバで全部動いています。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;サーバ&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;/posts/gmktec-nucbox-m2/&quot;&gt;GMKtec NucBox M2&lt;/a&gt;（Core i7-11390H / 32GB RAM / 1TB SSD、53,000円）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PaaS&lt;/td&gt;
&lt;td&gt;Coolify&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;プロジェクト数&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;アプリケーション数&lt;/td&gt;
&lt;td&gt;23&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;データベース数&lt;/td&gt;
&lt;td&gt;7（MariaDB×2, MySQL×2, Redis×3）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;月額コスト&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Coolifyのダッシュボードで見ると、5プロジェクトが並んでいます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-dashboard.png&quot; alt=&quot;Coolifyのダッシュボード。5つのプロジェクト（ai-moderator、ai-tri、teraren、wordpress、zabbix）と1台のlocalhostサーバが表示されている&quot; /&gt;&lt;/p&gt;
&lt;p&gt;terarenプロジェクトだけで20個近いアプリケーションが全部runningで稼働中。bank-code、corporation、postcode、train、schoolなどの各種APIサーバ、blog-redirect等のリダイレクト用コンテナ、Immich（写真管理）など。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/coolify-teraren-resources.png&quot; alt=&quot;terarenプロジェクトのリソース一覧。20個近いアプリケーションが全てrunning状態で表示されている&quot; /&gt;&lt;/p&gt;
&lt;p&gt;内訳としては、Next.jsのWebアプリ、Railsアプリ、WordPress、各種APIサーバ、リダイレクト用コンテナ、Zabbix（監視）、Immich（写真管理）など。開発用と本番用で環境を分けているサービスもあるので、コンテナ数はそれなりに多いです。&lt;/p&gt;
&lt;p&gt;これが全部、53,000円のミニPC1台で、月額$0で動いています。Vercel時代は1サービスだけで$42/月だったことを考えると、もっと早く移行すべきでした。&lt;/p&gt;
&lt;h2&gt;Before / After&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指標&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After (Coolify)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;月額コスト&lt;/td&gt;
&lt;td&gt;$20〜$42（Vercelだけで）&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;年間コスト&lt;/td&gt;
&lt;td&gt;$300〜$500&lt;/td&gt;
&lt;td&gt;$0（電気代のみ）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;サービス数制限&lt;/td&gt;
&lt;td&gt;従量課金で増加&lt;/td&gt;
&lt;td&gt;無制限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DB&lt;/td&gt;
&lt;td&gt;外部サービス必要&lt;/td&gt;
&lt;td&gt;Coolify内で管理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CD&lt;/td&gt;
&lt;td&gt;サービスごとに個別管理&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Coolifyで統一&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL&lt;/td&gt;
&lt;td&gt;自動&lt;/td&gt;
&lt;td&gt;自動&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Beforeでは、Vercelに載っているもの、Docker直で動かしているもの、それぞれでCD（継続的デプロイ）の仕組みがバラバラでした。Next.js、Rails、WordPress、静的サイト。。。多種多様なアプリのデプロイ方法を個別に管理するのは本当に面倒でした。&lt;/p&gt;
&lt;p&gt;Coolifyに統一したことで、&lt;strong&gt;全サービスが「GitHub Push→自動ビルド&amp;amp;デプロイ」の同じフロー&lt;/strong&gt;になりました。これはコスト削減以上に大きなメリットかもしれません。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;自宅にDockerが動くサーバがあるなら、Coolifyを入れない理由がありません。インストールはコマンド一発。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この記事ではCoolifyの選定理由を書きました。次回以降で、実際の運用に踏み込んでいきます。&lt;/p&gt;
&lt;h3&gt;シリーズ記事&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Vercel月額$42→自宅サーバ月額$0。Coolifyで個人サービス基盤を作った話&lt;/strong&gt;（この記事）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-claude-code-mcp/&quot;&gt;Coolifyインストールから「プロンプトでデプロイ」まで：Claude Code MCP実践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-hands-on-deploy/&quot;&gt;Coolifyハンズオン：Hono・Go・Railsを実際にデプロイしてみる&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-cloudflare-tunnel/&quot;&gt;Cloudflare Tunnel×Coolify：自宅サーバを安全に外部公開する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-llm-era-self-hosting/&quot;&gt;API-firstなインフラが生き残る：LLM時代のセルフホスト戦略&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-zabbix-container-monitoring/&quot;&gt;ZabbixでDockerコンテナをリソース監視する：Coolify環境の可視化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-backup-strategy/&quot;&gt;Coolify環境のバックアップ戦略：6つのDBを自動ダンプ+復旧手順&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/coolify-log-management-incident-response/&quot;&gt;Coolify環境のログ管理と障害対応：Docker + Zabbix + Discordで運用を回す&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Claude Codeでプロンプト1発、MariaDBのメモリ使用量を400MB→150MBに削減した話</title><link>https://blog.teraren.com/posts/mariadb-memory-tuning-with-claude-code/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mariadb-memory-tuning-with-claude-code/</guid><description>Coolify上のMariaDB 11.7がデフォルト設定でメモリを400MB使用していたのを、Claude CodeのAIエージェントに丸投げして具体的な数値分析とチューニングを実施し、150MBまで削減した実践記録</description><pubDate>Thu, 12 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;きっかけ&lt;/h2&gt;
&lt;p&gt;自宅サーバで&lt;a href=&quot;https://wordpress.org/&quot;&gt;WordPress&lt;/a&gt;を2サイト運用している。PaaS基盤には&lt;a href=&quot;https://coolify.io/&quot;&gt;Coolify&lt;/a&gt;を使っていて、データベースには&lt;a href=&quot;https://mariadb.org/&quot;&gt;MariaDB&lt;/a&gt; 11.7を採用している。&lt;/p&gt;
&lt;p&gt;ある日、コンテナのメモリ使用量を確認したところ、MariaDBが&lt;strong&gt;約400MB&lt;/strong&gt;も消費していることに気づいた。格納しているデータは合計わずか&lt;strong&gt;5.1MB&lt;/strong&gt;。WordPressのブログ2つだけで、アクセス数もそこまで多くない。データに対してメモリが80倍近い。明らかにもったいない。&lt;/p&gt;
&lt;p&gt;でも、MariaDBのチューニングパラメータは数が多く、どれをどこまで下げれば安全なのか判断するのが面倒。そこで&lt;a href=&quot;https://docs.anthropic.com/en/docs/claude-code/overview&quot;&gt;Claude Code&lt;/a&gt;に丸投げしてみました。&lt;/p&gt;
&lt;h2&gt;環境&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;DB&lt;/td&gt;
&lt;td&gt;MariaDB 11.7 (&lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PaaS&lt;/td&gt;
&lt;td&gt;Coolify&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;用途&lt;/td&gt;
&lt;td&gt;WordPress 2サイト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;実データ量&lt;/td&gt;
&lt;td&gt;5.1MB（3データベース合計）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;サーバメモリ&lt;/td&gt;
&lt;td&gt;32GB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;チューニング前メモリ&lt;/td&gt;
&lt;td&gt;約400MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;問題の発見：デフォルト設定の罠&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;docker stats&lt;/code&gt; でコンテナのメモリ使用量を確認すると、MariaDBが &lt;strong&gt;403.5MiB&lt;/strong&gt; 使用していた。&lt;/p&gt;
&lt;p&gt;MariaDBのコンテナに入って &lt;code&gt;SHOW VARIABLES&lt;/code&gt; と &lt;code&gt;SHOW GLOBAL STATUS&lt;/code&gt; を確認すると、メモリを大量消費しているバッファが3つ見つかった。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SHOW VARIABLES LIKE &apos;innodb_buffer_pool_size&apos;;
-- 134,217,728 (128MB)

SHOW VARIABLES LIKE &apos;aria_pagecache_buffer_size&apos;;
-- 134,217,728 (128MB)

SHOW VARIABLES LIKE &apos;key_buffer_size&apos;;
-- 134,217,728 (128MB)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この3つだけで &lt;strong&gt;384MB&lt;/strong&gt;。これがデフォルト設定です。&lt;/p&gt;
&lt;h2&gt;分析：バッファの現在値と実使用量&lt;/h2&gt;
&lt;p&gt;Claude Codeに現在のステータスを取得・分析させた結果がこちら。&lt;/p&gt;
&lt;h3&gt;主要バッファの使用状況&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;パラメータ&lt;/th&gt;
&lt;th&gt;割当量&lt;/th&gt;
&lt;th&gt;実使用/必要量&lt;/th&gt;
&lt;th&gt;乖離率&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;innodb_buffer_pool_size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;128MB&lt;/td&gt;
&lt;td&gt;データ5.1MB（hit rate 98.28%）&lt;/td&gt;
&lt;td&gt;25倍&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;aria_pagecache_buffer_size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;128MB&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mariadb.com/kb/en/aria-storage-engine/&quot;&gt;Aria&lt;/a&gt;テーブル未使用&lt;/td&gt;
&lt;td&gt;∞&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;key_buffer_size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;128MB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Key_blocks_used = 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;∞&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;innodb_log_buffer_size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;16MB&lt;/td&gt;
&lt;td&gt;書込み頻度低い&lt;/td&gt;
&lt;td&gt;8倍&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;接続まわりの設定&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;パラメータ&lt;/th&gt;
&lt;th&gt;設定値&lt;/th&gt;
&lt;th&gt;実績&lt;/th&gt;
&lt;th&gt;乖離率&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_connections&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;151&lt;/td&gt;
&lt;td&gt;最大同時接続 5&lt;/td&gt;
&lt;td&gt;30倍&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;thread_cache_size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;151&lt;/td&gt;
&lt;td&gt;作成スレッド 5&lt;/td&gt;
&lt;td&gt;30倍&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;table_open_cache&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;2000&lt;/td&gt;
&lt;td&gt;Open tables 157&lt;/td&gt;
&lt;td&gt;12倍&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;key_buffer_size&lt;/code&gt; に至っては使用量がゼロ。&lt;a href=&quot;https://mariadb.com/kb/en/myisam-storage-engine/&quot;&gt;MyISAM&lt;/a&gt;テーブルを一切使っていないのに128MBが確保されていた。&lt;/p&gt;
&lt;h2&gt;Claude Codeに投げたプロンプト&lt;/h2&gt;
&lt;p&gt;Claude Codeの&lt;a href=&quot;https://docs.anthropic.com/en/docs/claude-code/tutorials#use-plan-mode-for-complex-tasks&quot;&gt;Plan Mode&lt;/a&gt;を使い、以下の流れで作業しました。&lt;/p&gt;
&lt;h3&gt;Step 1: 現状分析のプロンプト&lt;/h3&gt;
&lt;p&gt;まずCoolify管理下のMariaDBコンテナに対して、現在のメモリ使用状況を分析させました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MariaDB (Coolify, UUID: xxx) のメモリ使用量を分析して。
docker stats でメモリ使用量を確認し、SHOW VARIABLES / SHOW GLOBAL STATUS
から主要パラメータの設定値と実使用量を比較して。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Claude Codeは自動的にCoolifyの&lt;a href=&quot;https://modelcontextprotocol.io/&quot;&gt;MCP&lt;/a&gt;ツール経由でコンテナ内のMariaDBに接続し、&lt;code&gt;SHOW VARIABLES&lt;/code&gt; と &lt;code&gt;SHOW GLOBAL STATUS&lt;/code&gt; を取得して分析結果を表形式でまとめてくれた。&lt;/p&gt;
&lt;h3&gt;Step 2: チューニングプランの作成&lt;/h3&gt;
&lt;p&gt;分析結果を踏まえ、Plan Modeでチューニング計画を立てさせました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;この分析結果をもとに、メモリ使用量を100-150MBに削減するチューニングプランを作って。
安全マージンを考慮して、各パラメータの推奨値と根拠を示して。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Step 3: 実行&lt;/h3&gt;
&lt;p&gt;プランを承認し、そのまま適用まで実行させました。&lt;/p&gt;
&lt;h2&gt;チューニング設定&lt;/h2&gt;
&lt;p&gt;Claude Codeが作成した設定ファイルがこちら。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[mysqld]
# === InnoDB ===
innodb_buffer_pool_size = 32M      # 128M→32M (データ5MBに対して6倍の余裕)
innodb_log_buffer_size = 2M        # 16M→2M (書込み少ない)
innodb_log_file_size = 16M         # 96M→16M

# === Aria (未使用だが最小値に) ===
aria_pagecache_buffer_size = 8M    # 128M→8M

# === MyISAM (完全未使用) ===
key_buffer_size = 1M               # 128M→1M (Key_blocks_used=0)

# === 接続 ===
max_connections = 20               # 151→20 (最大5接続に対して4倍マージン)
thread_cache_size = 10             # 151→10

# === テーブルキャッシュ ===
table_open_cache = 256             # 2000→256 (Open=157)
table_definition_cache = 256       # 400→256

# === 一時テーブル ===
tmp_table_size = 8M                # 16M→8M
max_heap_table_size = 8M           # 16M→8M

# === ソート・バッファ (per-connection) ===
sort_buffer_size = 512K            # 2M→512K
join_buffer_size = 512K            # 256K→512K
read_buffer_size = 256K            # 128K→256K (少し増加)
read_rnd_buffer_size = 512K        # 256K→512K
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;設定のポイント&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;innodb_buffer_pool_size = 32M&lt;/code&gt;&lt;/strong&gt;: データ5.1MBに対して6倍の余裕。全データがバッファプールに載るのでhit rateは維持される&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;key_buffer_size = 1M&lt;/code&gt;&lt;/strong&gt;: 使用量ゼロなので最小値に。0にはできない（MariaDBの制約）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;aria_pagecache_buffer_size = 8M&lt;/code&gt;&lt;/strong&gt;: Ariaテーブルは使っていないが、内部的に一時テーブルで使われる可能性があるため8MBは残す&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;max_connections = 20&lt;/code&gt;&lt;/strong&gt;: ピーク5接続に対して4倍マージン。WordPress + cronジョブを考慮しても十分&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Coolifyでの適用手順&lt;/h2&gt;
&lt;p&gt;CoolifyではMariaDBの設定ファイルをCustom Docker Configuration経由で注入する。Claude CodeはCoolifyのAPIを使って以下の手順を自動実行した。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 1. 設定ファイルをbase64エンコード
CONFIG=$(cat my.cnf | base64 -w 0)

# 2. Coolify API で設定を更新
curl -X PATCH &quot;https://coolify.example.com/api/v1/databases/{uuid}&quot; \
  -H &quot;Authorization: Bearer $TOKEN&quot; \
  -H &quot;Content-Type: application/json&quot; \
  -d &quot;{\&quot;custom_docker_run_options\&quot;: \&quot;--volume ...\&quot;}&quot;

# 3. データベースを再起動
curl -X POST &quot;https://coolify.example.com/api/v1/databases/{uuid}/restart&quot; \
  -H &quot;Authorization: Bearer $TOKEN&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;実際にはClaude CodeがCoolifyの&lt;a href=&quot;https://github.com/StuMason/coolify-mcp&quot;&gt;MCPサーバー&lt;/a&gt;経由でこれらのAPIを叩いてくれるので、手動でcurlを打つ必要はなかった。&lt;/p&gt;
&lt;h2&gt;Before / After&lt;/h2&gt;
&lt;h3&gt;メモリ使用量&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指標&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;削減率&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;コンテナメモリ&lt;/td&gt;
&lt;td&gt;403.5 MiB&lt;/td&gt;
&lt;td&gt;~150 MiB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;63%削減&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/mariadb-memory-before-after.png&quot; alt=&quot;CoolifyのMetrics画面。Memory Usageグラフで14時頃に約400MBから150MB付近に急落しているのが確認できる&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;主要バッファの比較&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;パラメータ&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;削減量&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;innodb_buffer_pool_size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;128MB&lt;/td&gt;
&lt;td&gt;32MB&lt;/td&gt;
&lt;td&gt;-96MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;aria_pagecache_buffer_size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;128MB&lt;/td&gt;
&lt;td&gt;8MB&lt;/td&gt;
&lt;td&gt;-120MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;key_buffer_size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;128MB&lt;/td&gt;
&lt;td&gt;1MB&lt;/td&gt;
&lt;td&gt;-127MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;innodb_log_buffer_size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;16MB&lt;/td&gt;
&lt;td&gt;2MB&lt;/td&gt;
&lt;td&gt;-14MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max_connections&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;151&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;バッファ合計&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;400MB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;43MB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;-357MB&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;パフォーマンスへの影響&lt;/h3&gt;
&lt;p&gt;チューニング後もWordPressの応答に体感上の変化はなく、&lt;a href=&quot;https://mariadb.com/kb/en/innodb/&quot;&gt;InnoDB&lt;/a&gt; buffer pool hit rateも高い水準を維持している。データ量が5.1MBで32MBのバッファプールに完全に収まっているため、性能劣化は発生しない。&lt;/p&gt;
&lt;h2&gt;検証ポイント&lt;/h2&gt;
&lt;p&gt;チューニング後に確認すべき項目をまとめる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- Buffer pool hit rate（95%以上ならOK）
SHOW GLOBAL STATUS LIKE &apos;Innodb_buffer_pool_read%&apos;;

-- 一時テーブルのディスク書き出し率
SHOW GLOBAL STATUS LIKE &apos;Created_tmp%&apos;;

-- 接続数が上限に近づいていないか
SHOW GLOBAL STATUS LIKE &apos;Max_used_connections&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;もしhit rateが著しく低下したり、&lt;code&gt;Max_used_connections&lt;/code&gt; が &lt;code&gt;max_connections&lt;/code&gt; に近づいた場合は、該当パラメータを引き上げれば対処できる。&lt;/p&gt;
&lt;h2&gt;所感：Claude Codeでのインフラ運用&lt;/h2&gt;
&lt;p&gt;今回の作業、全体で&lt;strong&gt;プロンプト3回、所要時間約5分&lt;/strong&gt;で完了した。&lt;/p&gt;
&lt;p&gt;従来なら以下のステップが必要だったはずです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;MariaDBのドキュメントを読む&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SHOW VARIABLES&lt;/code&gt; / &lt;code&gt;SHOW GLOBAL STATUS&lt;/code&gt; の出力を読み解く&lt;/li&gt;
&lt;li&gt;各パラメータの意味と推奨値を調べる&lt;/li&gt;
&lt;li&gt;安全な値を計算する&lt;/li&gt;
&lt;li&gt;設定ファイルを書く&lt;/li&gt;
&lt;li&gt;CoolifyのAPIで適用する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これらすべてをClaude Codeが一気通貫で実行してくれた。特に良かった点は以下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;数値分析が正確&lt;/strong&gt;: &lt;code&gt;Key_blocks_used = 0&lt;/code&gt; のようなステータスから「MyISAMは完全未使用」と即座に判断&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安全マージンが適切&lt;/strong&gt;: データ5.1MBに対して32MBのバッファプールを推奨（6倍マージン）するなど、攻めすぎない設定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coolify APIの操作も自動化&lt;/strong&gt;: MCP（Model Context Protocol）経由でCoolifyのAPIを直接操作し、設定変更から再起動まで完了&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MariaDBのチューニングに限らず、「現状を分析して→計画を立てて→実行する」というインフラ運用タスクはClaude Codeと相性が良いと感じた。特にPlan Modeで計画を人間がレビューしてから実行に移せるのが安心感がある。&lt;/p&gt;
&lt;p&gt;データベースのメモリ設定はデフォルトのまま放置されがちですが、5分の投資で250MBのメモリを回収できるなら、やらない理由はありません。&lt;/p&gt;
&lt;h2&gt;余談：MySQLはいつから重くなったのか&lt;/h2&gt;
&lt;p&gt;昔のMySQL（5.x系あたり）には &lt;code&gt;my-micro.cnf&lt;/code&gt; や &lt;code&gt;my-small.cnf&lt;/code&gt; といった設定テンプレートが同梱されていて、メモリ64MB程度のマシンでも動かせるような超省メモリ設定が用意されていました。当時のデフォルト設定も控えめで、カジュアルにDBを立ち上げて開発やちょっとしたWebサイトに使うのが当たり前でした。&lt;/p&gt;
&lt;p&gt;ところが、MySQL 8.0やMariaDB 10.x以降はそうした軽量設定テンプレートが廃止され、デフォルトの &lt;code&gt;innodb_buffer_pool_size&lt;/code&gt; が128MBに設定されるなど、「そこそこのメモリが載っている前提」の設定に変わりました。今回のように何も考えずに立ち上げるだけで数百MBを占有する、かつての軽量高速なMySQLとは別物です。&lt;/p&gt;
&lt;p&gt;カジュアルにDBを使いたいなら、今なら&lt;a href=&quot;https://www.sqlite.org/&quot;&gt;SQLite&lt;/a&gt;が現実的な選択肢でしょう。サーバープロセスが不要で、ファイル1つで完結する。&lt;a href=&quot;https://litestream.io/&quot;&gt;Litestream&lt;/a&gt;を組み合わせればレプリケーションもできます。&lt;/p&gt;
&lt;p&gt;ただ、&lt;a href=&quot;https://wordpress.org/&quot;&gt;WordPress&lt;/a&gt;はSQLiteに公式対応していないという矛盾があります。&lt;a href=&quot;https://github.com/aaemnnosttv/wp-sqlite-db&quot;&gt;WP-SQLite-DB&lt;/a&gt;のようなコミュニティプラグインはあるものの、公式サポートではありません。結局、WordPressを使い続ける限りMySQL/MariaDBからは逃れられない。&lt;/p&gt;
&lt;p&gt;もっとも、この記事で扱っている2つのWordPressサイトも、&lt;a href=&quot;/posts/wordpress-to-astro-migration/&quot;&gt;このブログと同様に&lt;/a&gt;Astroへの移行を予定しています。移行が完了すればDBコンテナごと消えるので、メモリチューニングの話自体が不要になります。最終的には静的サイトジェネレータが正義、ということかもしれません。&lt;/p&gt;
</content:encoded></item><item><title>19年運用したWordPress 661記事をAstro + Cloudflare Pagesへ移行した手順と技術的ポイント</title><link>https://blog.teraren.com/posts/wordpress-to-astro-migration/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-to-astro-migration/</guid><description>661記事・2,515画像のWordPressブログをAstro + Cloudflare Pagesに移行した技術的な記録</description><pubDate>Tue, 10 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;19年運用してきたWordPressブログ（661記事、2,515画像）をAstroに移行して、Cloudflare Pagesで配信するようにしました。ホスティング費用はゼロになり、デプロイは &lt;code&gt;git push&lt;/code&gt; だけで完了するようになりました。&lt;/p&gt;
&lt;p&gt;この記事では移行の背景、技術スタック、実際の作業手順、苦労した点をまとめます。&lt;/p&gt;
&lt;h2&gt;WordPressの何が問題だったのか&lt;/h2&gt;
&lt;h3&gt;静的コンテンツなのにDBが必要&lt;/h3&gt;
&lt;p&gt;ブログの記事は基本的に静的コンテンツです。それなのにMySQLが必要で、DBのバックアップやメンテナンスが発生します。&lt;/p&gt;
&lt;h3&gt;スナップショットが面倒&lt;/h3&gt;
&lt;p&gt;WordPressのデータは3箇所に分散しています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;MySQL&lt;/strong&gt; - 記事本文、メタデータ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;wp-content/uploads/&lt;/strong&gt; - 画像ファイル&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テーマ・プラグイン&lt;/strong&gt; - PHP設定&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;バックアップするには &lt;code&gt;mysqldump&lt;/code&gt; + &lt;code&gt;rsync&lt;/code&gt; が必要で、復元するにも両方を揃えないとサイトが壊れます。Gitで丸ごと管理できない。&lt;/p&gt;
&lt;h3&gt;画像のサムネイル地獄&lt;/h3&gt;
&lt;p&gt;WordPressは画像を1枚アップロードすると、自動的にサムネイルを大量生成します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IMG_1234.jpg          ← オリジナル
IMG_1234-150x150.jpg  ← thumbnail
IMG_1234-300x200.jpg  ← medium
IMG_1234-768x512.jpg  ← medium_large
IMG_1234-1024x683.jpg ← large
IMG_1234-1536x1024.jpg
IMG_1234-2048x1365.jpg
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2,515枚のアップロードに対して、サムネイルまで含めると数万ファイルになります。実際にこのブログでは参照されていない画像ファイルが3,250個（数 GB）も蓄積していました。&lt;/p&gt;
&lt;h3&gt;LLMとの相性が悪い&lt;/h3&gt;
&lt;p&gt;LLMで記事を書いたり校正したりすることが増えてきましたが、WordPressだとDBの中にあるコンテンツを取り出してLLMに渡す必要があります。Markdownファイルならエディタやターミナルからそのまま渡せます。Claude Codeにディレクトリを渡すだけで記事を書いてもらえるのは圧倒的に楽です。&lt;/p&gt;
&lt;h3&gt;フロントエンドのアセットパイプラインがない&lt;/h3&gt;
&lt;p&gt;WordPressにはビルドパイプラインがないので、画像の最適化（WebP変換、リサイズ）をビルド時に自動実行する仕組みがありません。プラグインで対応できますが、PHPベースの処理なので遅いし制約が多い。&lt;/p&gt;
&lt;h3&gt;リンク切れ・ゴミファイルが検出しづらい&lt;/h3&gt;
&lt;p&gt;19年運用していると、記事から参照されなくなった画像やファイルがどんどん溜まっていきます。WordPressのメディアライブラリは「どの記事からも参照されていないファイル」を検出する機能がありません。&lt;/p&gt;
&lt;p&gt;実際にこのブログを調査したところ、参照されていないファイルが &lt;strong&gt;3,250個（数 GB）&lt;/strong&gt; も蓄積していました。WordPressのDB内のHTMLと &lt;code&gt;wp-content/uploads/&lt;/code&gt; のファイルを突き合わせないと検出できないので非常に面倒です。&lt;/p&gt;
&lt;p&gt;Astroに移行した後は、Markdownファイルからの参照をgrepで簡単に調べられるので、不要ファイルの検出がシンプルになりました。&lt;/p&gt;
&lt;h2&gt;移行先の検討&lt;/h2&gt;
&lt;h3&gt;MicroCMS + Next.js&lt;/h3&gt;
&lt;p&gt;最初はHeadless CMSの &lt;a href=&quot;https://microcms.io/&quot;&gt;MicroCMS&lt;/a&gt; と &lt;a href=&quot;https://nextjs.org/&quot;&gt;Next.js&lt;/a&gt; の組み合わせを検討した。しかし、&lt;a href=&quot;https://vercel.com/&quot;&gt;Vercel&lt;/a&gt;のホスティング費用がかかる。個人ブログにそこまでコストをかけたくない。&lt;/p&gt;
&lt;h3&gt;Astro + Cloudflare Pages&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;を試してみたところ、これがドンピシャでした。&lt;/p&gt;
&lt;p&gt;まず小さめのWordPressサイトを5つほどAstroに移行してみて、問題がないことを確認してからメインブログの移行に取り掛かりました。トータルで10サイト近くAstroに移行しましたが、最後に残ったのが3サイトで、このメインブログはそのうちの1つです。&lt;/p&gt;
&lt;p&gt;今回の移行では &lt;a href=&quot;https://docs.anthropic.com/en/docs/claude-code&quot;&gt;Claude Code&lt;/a&gt;（Opus 4.5）を全面的に活用した。Opus 4.5は賢くて、移行作業の8割方は半自動で進められた。コンテンツ変換、frontmatter生成、リダイレクトルール作成、プラグイン実装といった定型作業は指示を出すだけでほぼ自動で完了し、半日で一通り動く状態になりました。ただし、残りの2割（UIの微調整、デザインの仕上げ、コンテンツの整理）にはもう半日かかりました。LLMが苦手なのは「見た目の良し悪し」や「コンテンツとして何を残すか」の判断で、そこは人間の目が必要です。&lt;/p&gt;
&lt;h2&gt;技術スタック&lt;/h2&gt;
&lt;p&gt;最終的に採用した構成です。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;レイヤー&lt;/th&gt;
&lt;th&gt;技術&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SSG&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt; 5.18&lt;/td&gt;
&lt;td&gt;静的サイト生成&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;テーマ&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;Fuwari&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;ブログテンプレート&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSS&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind CSS&lt;/a&gt; 4&lt;/td&gt;
&lt;td&gt;スタイリング&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://svelte.dev/&quot;&gt;Svelte&lt;/a&gt; 5&lt;/td&gt;
&lt;td&gt;インタラクティブコンポーネント&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Markdown拡張&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://mdxjs.com/&quot;&gt;MDX&lt;/a&gt;, &lt;a href=&quot;https://github.com/remarkjs/remark&quot;&gt;remark&lt;/a&gt;, &lt;a href=&quot;https://github.com/rehypejs/rehype&quot;&gt;rehype&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;カスタムコンポーネント&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;画像最適化&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://sharp.pixelplumbing.com/&quot;&gt;sharp&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;ビルド時にWebP変換・リサイズ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;全文検索&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://pagefind.app/&quot;&gt;Pagefind&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;クライアントサイド検索&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コードハイライト&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://expressive-code.com/&quot;&gt;Expressive Code&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;シンタックスハイライト&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;数式&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://katex.org/&quot;&gt;KaTeX&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;LaTeX数式レンダリング&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コメント&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://giscus.app/&quot;&gt;Giscus&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;GitHub Discussions連携&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ホスティング&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://pages.cloudflare.com/&quot;&gt;Cloudflare Pages&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;CDN配信（無料枠）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/features/actions&quot;&gt;GitHub Actions&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;自動ビルド・デプロイ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linter&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://biomejs.dev/&quot;&gt;Biome&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;フォーマット・lint&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Remark/Rehypeプラグイン構成&lt;/h3&gt;
&lt;p&gt;Markdownの拡張にはremark/rehypeのプラグインを多数使っています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// astro.config.mjs
markdown: {
  remarkPlugins: [
    remarkMath,           // LaTeX数式
    remarkReadingTime,    // 読了時間計算
    remarkExcerpt,        // 記事の抜粋生成
    remarkDirective,      // カスタムディレクティブ
    remarkSectionize,     // セクション分割
    remarkMdxGlobalComponents,
  ],
  rehypePlugins: [
    rehypeKatex,          // KaTeX数式レンダリング
    rehypeSlug,           // 見出しにID付与
    rehypeUnwrapImages,   // 画像のリンクラッピング解除
    rehypeImageSize,      // 画像サイズ自動取得
    [rehypeComponents, {  // カスタムコンポーネント
      components: {
        github: GithubCardComponent,
        amazon: AmazonCardComponent,
        note: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;note&quot;),
        tip: (x, y) =&amp;gt; AdmonitionComponent(x, y, &quot;tip&quot;),
      },
    }],
    [rehypeAutolinkHeadings, { behavior: &quot;append&quot; }],
  ],
},
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;コンテンツスキーマ&lt;/h3&gt;
&lt;p&gt;Astroの &lt;a href=&quot;https://docs.astro.build/en/guides/content-collections/&quot;&gt;Content Collections&lt;/a&gt; でfrontmatterのスキーマを定義しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// src/content/config.ts
const postsCollection = defineCollection({
  schema: z.object({
    title: z.string(),
    published: z.date(),
    updated: z.date().optional(),
    draft: z.boolean().optional().default(false),
    description: z.string().optional().default(&quot;&quot;),
    image: z.string().optional().default(&quot;&quot;),
    tags: z.array(z.string()).optional().default([]),
    category: z.string().optional().nullable().default(&quot;&quot;),
  }),
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WordPressの &lt;code&gt;wp_posts&lt;/code&gt; テーブルにバラバラに格納されていたメタデータが、frontmatterとして1ファイルにまとまりました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: ブログのCMSをWordPressからAstroに移行した
published: 2026-03-10
category: &quot;Programming&quot;
tags: [&quot;WordPress&quot;, &quot;Astro&quot;, &quot;Cloudflare&quot;]
image: &quot;../../assets/uploads/2026/03/cover.png&quot;
---

本文はMarkdownで書く。これが全て。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;移行作業の実際&lt;/h2&gt;
&lt;p&gt;移行は74コミットで完了しました。Gitのログから主要な作業フェーズを振り返ります。&lt;/p&gt;
&lt;h3&gt;Phase 1: 初期移行&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;43a2057 feat: switch to Fuwari blog template with migrated content
be433be feat: add blog uploads (images) via Git LFS
f2f02b0 feat: set featured images from WordPress thumbnail metadata
13c2cfd fix: correct featured image URLs using wp_get_attachment_url
797fe8f fix: convert WordPress/Cocoon shortcodes to standard Markdown/HTML
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.anthropic.com/en/docs/claude-code&quot;&gt;Claude Code&lt;/a&gt;に「WordPressのディレクトリをAstro Fuwariテーマで動くように移行して」と指示しました。WordPressのHTMLをMarkdownに変換して、frontmatterを生成する作業を自動でやってくれます。&lt;/p&gt;
&lt;p&gt;ただし、一発でうまくいくわけではないです。WordPress/Cocoonテーマ固有のショートコードやブロックパターンの変換が必要でした。&lt;/p&gt;
&lt;h3&gt;Phase 2: 機能追加&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;ad849b0 feat: add Amazon MDX component, OGP, GTM, redirects, 404 page
a064cc3 feat: generate OG images for 39 posts without featured images
6046ae5 feat: add Giscus comment system powered by GitHub Discussions
88fea73 feat: add related posts, Japanese nav, remove GitHub link from header
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WordPressで使っていた機能をAstroで再実装しました。&lt;/p&gt;
&lt;h4&gt;Amazonアフィリエイトコンポーネント&lt;/h4&gt;
&lt;p&gt;WordPressではAmazonリンクをプレーンなHTMLやプラグインで書いていましたが、Astroでは自作のrehypeプラグインでカスタムコンポーネントとして処理しています。Markdownで &lt;code&gt;::amazon{asin=&quot;...&quot;}&lt;/code&gt; と書くだけで商品カードがレンダリングされます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;::amazon{asin=&quot;B0CKWS1VWR&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;商品データ（タイトル、価格、画像URL、レビュー数）はAmazon PA-APIから事前にフェッチして &lt;code&gt;amazon-products.json&lt;/code&gt; に保存しておき、ビルド時に読み込みます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// src/plugins/rehype-component-amazon.mjs（抜粋）
let amazonProducts = {};
try {
  const dataPath = join(process.cwd(), &quot;src&quot;, &quot;data&quot;, &quot;amazon-products.json&quot;);
  amazonProducts = JSON.parse(readFileSync(dataPath, &quot;utf-8&quot;));
} catch (error) {
  console.warn(&quot;[AMAZON] Failed to load amazon-products.json:&quot;, error.message);
}

export function AmazonCardComponent(properties, children) {
  const asin = properties.asin;
  const productData = amazonProducts[asin];
  const affiliateUrl = productData?.detailPageUrl
    || `https://www.amazon.co.jp/dp/${asin}?tag=${AFFILIATE_TAG}`;
  const title = productData?.title || &quot;&quot;;
  const imageUrl = productData?.imageUrl || &quot;&quot;;
  // ... hastscriptでカード要素を構築
  return h(&quot;a&quot;, { class: &quot;card-amazon&quot;, href: affiliateUrl, target: &quot;_blank&quot; }, [
    nImage, h(&quot;div&quot;, { class: &quot;az-info&quot; }, [nTitle, ...priceElements, nButton]),
  ]);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MDXファイルでは &lt;code&gt;::amazon{asin=&quot;...&quot;}&lt;/code&gt; というJSXコンポーネントも使えるように、remarkプラグインで自動importを挿入しています。&lt;/p&gt;
&lt;p&gt;実際のレンダリング結果はこんな感じです。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;4297150085&quot;}&lt;/p&gt;
&lt;h4&gt;URLの自動埋め込み（astro-embed）&lt;/h4&gt;
&lt;p&gt;YouTubeやX(Twitter)のURLをMarkdownにそのまま貼るだけで、自動的にembedカードに変換されます。&lt;a href=&quot;https://www.npmjs.com/package/astro-embed&quot;&gt;astro-embed&lt;/a&gt;を使っています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- こう書くだけでYouTubeが埋め込まれる --&amp;gt;
https://www.youtube.com/watch?v=9TVkrzxjNRo

&amp;lt;!-- Xのポストも同様 --&amp;gt;
https://x.com/matsubokkuri/status/1893168256317563150
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WordPressのoEmbedと同じ体験がMarkdownで実現できます。&lt;/p&gt;
&lt;h3&gt;Phase 3: 画像最適化&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;7bf0764 feat: move images to src/assets for build-time optimization
7214b99 refactor: move OG images from public/og to src/assets/og
318eb07 chore: remove 3250 unreferenced upload files (566 MB)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これが一番大変でした。WordPressの &lt;code&gt;wp-content/uploads/&lt;/code&gt; にあった画像を &lt;code&gt;src/assets/uploads/&lt;/code&gt; に移動することで、Astroのビルドパイプライン（sharp）による最適化対象にしました。&lt;/p&gt;
&lt;p&gt;画像をpublicディレクトリからsrc/assetsに移すことで、ビルド時に自動的にWebP変換とリサイズが行われます。&lt;/p&gt;
&lt;p&gt;参照されていない画像ファイルが3,250個（数 GB）もあったので、全て削除しました。さらにGit履歴からも &lt;a href=&quot;https://github.com/newren/git-filter-repo&quot;&gt;&lt;code&gt;git-filter-repo&lt;/code&gt;&lt;/a&gt; で完全に消して、リポジトリサイズを3.7GBから2.4GBに縮小しました。&lt;/p&gt;
&lt;h3&gt;Phase 4: URL互換性&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;1e74d38 refactor: rename multibyte post filenames to ASCII
9a54209 fix: update redirects for renamed Japanese slug posts
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WordPressは &lt;code&gt;/YYYY/MM/DD/slug/&lt;/code&gt; というURL構造でしたが、Astroでは &lt;code&gt;/posts/slug/&lt;/code&gt; になります。SEO上の影響を最小化するため、973件の301リダイレクトルールを生成しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# public/_redirects
/2003/06/05/php/ /posts/php/ 301
/2024/08/02/stop-using-url-shortener-services/ /posts/stop-using-url-shortener-services/ 301
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;canonical URLも旧WordPress形式で出力するようにして、Googleの検索インデックスを引き継ぎました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// src/pages/posts/[...slug].astro
const pubDate = entry.data.published;
const yyyy = pubDate.getFullYear().toString();
const mm = (pubDate.getMonth() + 1).toString().padStart(2, &quot;0&quot;);
const dd = pubDate.getDate().toString().padStart(2, &quot;0&quot;);
const canonicalUrl = new URL(
  `/${yyyy}/${mm}/${dd}/${entry.slug}/`, Astro.site
).href;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Phase 5: Tailwind CSS v3 → v4&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;36bfa03 feat: migrate Tailwind CSS v3 to v4
d3f9e66 fix: move text-* utilities from @layer components to @utility for TW4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/saicaca/fuwari&quot;&gt;Fuwari&lt;/a&gt;テーマ自体が&lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind CSS&lt;/a&gt; v3ベースだったので、v4への移行が必要でした。&lt;/p&gt;
&lt;p&gt;Tailwind 4では &lt;code&gt;@layer components&lt;/code&gt; の中に書いたスタイルの優先度が大きく変わりました。&lt;code&gt;@layer&lt;/code&gt; 内のスタイルは &lt;code&gt;@layer&lt;/code&gt; 外のスタイルより&lt;strong&gt;常に優先度が低い&lt;/strong&gt;ため、開発サーバーでは動くのに本番ビルドでスタイルが崩れるという厄介なバグにハマりました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* BAD: @layer内のスタイルは優先度が低い */
@layer components {
  .meta-icon {
    @apply mr-1.5;  /* 本番ビルドで効かない！ */
  }
}

/* GOOD: @layer外に書く */
.meta-icon {
  margin-right: 0.375rem;
  background-color: var(--btn-regular-bg);
  color: var(--btn-content);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Phase 6: 仕上げ&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;d49c8a2 feat: add social sharing, sponsor button, and improve Amazon cards
1d10317 feat: add PA-API product data fetcher for Amazon affiliate cards
20a7448 refactor: update 121 internal links from old WordPress URLs to new paths
16ca3bf feat: add internal blog post link card component
9185ee9 refactor: remove dead rehypeImageSize plugin, fix tweet script duplication
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最後の仕上げとして、以下の作業をしました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SNSシェアボタン&lt;/strong&gt;: X（Twitter）シェアとはてなブックマークボタンを記事ページに追加&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazonアフィリエイト強化&lt;/strong&gt;: &lt;a href=&quot;https://webservices.amazon.co.jp/paapi5/documentation/&quot;&gt;Amazon PA-API&lt;/a&gt;から商品データ（タイトル、価格、画像、レビュー数）を自動取得するスクリプトを作成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内部リンクカード&lt;/strong&gt;: 自サイトへのURLを自動的にブログカード形式で表示するremarkプラグインを実装。OGPフェッチ不要で、ビルド時にfrontmatterから直接データを取得&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;旧URLの一括更新&lt;/strong&gt;: 記事中の121箇所の旧WordPress URL（&lt;code&gt;/YYYY/MM/DD/slug/&lt;/code&gt;形式）を新しいパス（&lt;code&gt;/posts/slug/&lt;/code&gt;形式）に書き換え&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;画像のフルサイズ配信&lt;/strong&gt;: ライトボックス（&lt;a href=&quot;https://photoswipe.com/&quot;&gt;PhotoSwipe&lt;/a&gt;）でオリジナル解像度の画像を表示できるように、画像幅の800px制限を撤廃&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OGP画像の正常化&lt;/strong&gt;: 記事のfeature imageを &lt;code&gt;og:image&lt;/code&gt; に使用するように修正。フォールバック用のデフォルト画像も配置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;X（Twitter）埋め込み&lt;/strong&gt;: &lt;code&gt;widgets.js&lt;/code&gt; を動的ロードして、ツイートの画像・メディアが正しく表示されるように対応&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;デプロイパイプライン&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/features/actions&quot;&gt;GitHub Actions&lt;/a&gt;でビルドして、&lt;a href=&quot;https://pages.cloudflare.com/&quot;&gt;Cloudflare Pages&lt;/a&gt;にデプロイしています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# .github/workflows/deploy.yml
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 22 }
      - uses: pnpm/action-setup@v4
      - run: pnpm install --frozen-lockfile
      - run: pnpm build  # astro build &amp;amp;&amp;amp; pagefind --site dist
      - uses: cloudflare/wrangler-action@v3
        with:
          command: pages deploy dist --project-name=blog
      # CDNキャッシュも自動パージ
      - run: |
          curl -X POST &quot;https://api.cloudflare.com/client/v4/zones/$ZONE/purge_cache&quot; \
            -H &quot;Authorization: Bearer $TOKEN&quot; \
            --data &apos;{&quot;hosts&quot;:[&quot;blog.teraren.com&quot;]}&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;git push&lt;/code&gt; するだけで、ビルド → デプロイ → CDNキャッシュパージまで自動で走ります。&lt;/p&gt;
&lt;p&gt;実際のGitHub Actionsワークフローの実行画面です。Biome、textlint、Build、Deployの4ジョブが並列・直列で実行されています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/github-actions-workflow.png&quot; alt=&quot;GitHub Actions Workflow&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;WordPress機能の代替&lt;/h2&gt;
&lt;p&gt;「静的サイトだとWordPressの○○ができないのでは？」という懸念があると思います。主要な機能の代替方法をまとめます。&lt;/p&gt;
&lt;h3&gt;全文検索 → Pagefind&lt;/h3&gt;
&lt;p&gt;WordPressの検索はMySQL上で &lt;code&gt;LIKE&lt;/code&gt; クエリを実行していましたが、静的サイトでも全文検索はできます。&lt;a href=&quot;https://pagefind.app/&quot;&gt;Pagefind&lt;/a&gt;はビルド時に静的なインデックスファイルを生成し、クライアントサイドでFTS（Full Text Search）を実行します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// package.json
{
  &quot;scripts&quot;: {
    &quot;build&quot;: &quot;astro build &amp;amp;&amp;amp; pagefind --site dist&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ビルドの最後に &lt;code&gt;pagefind&lt;/code&gt; を実行するだけで、日本語対応の検索インデックスが自動生成されます。検索UIはSvelteで実装して、インクリメンタルサーチに対応しています。DBを使わない検索がこんなに手軽にできるとは思っていませんでした。&lt;/p&gt;
&lt;h3&gt;コメント → Giscus&lt;/h3&gt;
&lt;p&gt;WordPressの組み込みコメント機能の代わりに&lt;a href=&quot;https://giscus.app/&quot;&gt;Giscus&lt;/a&gt;を使っています。GitHub Discussionsをバックエンドにしたコメントシステムで、記事のパス名にマッピングされます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- src/components/Giscus.astro --&amp;gt;
&amp;lt;script
  src=&quot;https://giscus.app/client.js&quot;
  data-repo=&quot;matsubo/blog-giscus&quot;
  data-mapping=&quot;pathname&quot;
  data-theme=&quot;preferred_color_scheme&quot;
  data-lang=&quot;ja&quot;
  data-loading=&quot;lazy&quot;
  async
&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;コメントデータはGitHubに保存されるので、自前でDBを管理する必要がありません。ダークモードの切り替えにも &lt;code&gt;postMessage&lt;/code&gt; で連動させています。&lt;/p&gt;
&lt;h2&gt;Before / After&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;WordPress&lt;/th&gt;
&lt;th&gt;Astro&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;記事数&lt;/td&gt;
&lt;td&gt;661（MySQL内）&lt;/td&gt;
&lt;td&gt;664（.md/.mdx）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;画像&lt;/td&gt;
&lt;td&gt;2,515 + サムネイル数万&lt;/td&gt;
&lt;td&gt;1,632（最適化済み）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ホスティング&lt;/td&gt;
&lt;td&gt;VPS (Docker)&lt;/td&gt;
&lt;td&gt;Cloudflare Pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;デプロイ&lt;/td&gt;
&lt;td&gt;手動 or プラグイン&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;バックアップ&lt;/td&gt;
&lt;td&gt;mysqldump + rsync&lt;/td&gt;
&lt;td&gt;&lt;code&gt;git clone&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コスト&lt;/td&gt;
&lt;td&gt;~$10/月&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;全文検索&lt;/td&gt;
&lt;td&gt;MySQL LIKE&lt;/td&gt;
&lt;td&gt;Pagefind（クライアントサイド）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;コメント&lt;/td&gt;
&lt;td&gt;WordPress組み込み&lt;/td&gt;
&lt;td&gt;Giscus（GitHub Discussions）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ビルド出力&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;349 MB（静的HTML）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;苦労した点&lt;/h2&gt;
&lt;h3&gt;304記事のMarkdownフォーマット修正&lt;/h3&gt;
&lt;p&gt;WordPressからの変換で壊れたMarkdownを手作業で修正しました。インデントのずれ、HTMLタグの残骸、Cocoonショートコードの変換漏れなど。&lt;/p&gt;
&lt;p&gt;単純置換、正規表現で処理できるところは機械的に行いましたが、それだけでは取り切れないフォーマット変換時のゴミや誤変換が多くて、結局は全記事をOpus 4.5にparseさせることで正常化しました。&lt;/p&gt;
&lt;p&gt;特に、code blockのアノテーションにおいてソースコードなのかシェルの出力なのかを今までは区別しないでpreタグで囲っていましたが、今回はその部分もアノテーションで区別するようにすることで読みやすくなりました。&lt;/p&gt;
&lt;h3&gt;画像パスの移行&lt;/h3&gt;
&lt;p&gt;WordPressは画像を &lt;code&gt;wp-content/uploads/YYYY/MM/&lt;/code&gt; に格納しますが、Astroで画像最適化を有効にするには &lt;code&gt;src/assets/&lt;/code&gt; 配下に移す必要があります。一旦画像はすべてコピーしてpathを機械的に置換したうえで、未参照の画像やサムネ画像を正規表現で置換しました。&lt;/p&gt;
&lt;p&gt;WordPressでのマークアップは画像を表示しつつ、Aタグで拡大画像にリンクを貼るというフォーマットに統一していましたが、Markdownに統一することで1つのオリジナル画像を指定しておくだけで済むようにし、build時に拡大用のマークアップをするようにしてます。&lt;/p&gt;
&lt;h3&gt;日本語スラッグの扱い&lt;/h3&gt;
&lt;p&gt;WordPressは日本語スラッグを許容しますが、ファイル名に日本語が入っているとビルドやデプロイで問題が起きる可能性があります。マルチバイトのスラッグを全てASCIIにリネームして、リダイレクトルールを追加しました。&lt;/p&gt;
&lt;h2&gt;良い点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;コストゼロ&lt;/strong&gt;: &lt;a href=&quot;https://pages.cloudflare.com/&quot;&gt;Cloudflare Pages&lt;/a&gt;の無料枠で十分。月10ドルの節約&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;速い&lt;/strong&gt;: 静的サイトでCDN配信。体感で明らかに速い&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gitで管理&lt;/strong&gt;: &lt;code&gt;git log&lt;/code&gt; で記事の変更履歴が全て追える&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLMフレンドリー&lt;/strong&gt;: ディレクトリごと&lt;a href=&quot;https://docs.anthropic.com/en/docs/claude-code&quot;&gt;Claude Code&lt;/a&gt;に渡すだけで記事を書いてもらえる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アセット最適化&lt;/strong&gt;: &lt;a href=&quot;https://sharp.pixelplumbing.com/&quot;&gt;sharp&lt;/a&gt;によるビルド時WebP変換・リサイズ&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;悪い点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;WYSIWYGエディタがない&lt;/strong&gt;: WordPressのJetpackアプリのように、スマホからサクッと記事を書けない。Markdownエディタが必要。ちょうど&lt;a href=&quot;https://zenn.dev/jishii/articles/5b9d2eb8f9ec9a&quot;&gt;VS Codeならこのようなプラグイン&lt;/a&gt;が出てました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ビルド時間&lt;/strong&gt;: 664記事のビルドはそれなりに時間がかかる。GitHub Actionsのランナーで数分&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Lighthouseスコア&lt;/h2&gt;
&lt;p&gt;移行後のLighthouseスコアです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/lighthouse-scores.png&quot; alt=&quot;Lighthouse Scores&quot; /&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;メトリクス&lt;/th&gt;
&lt;th&gt;スコア&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;85&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accessibility&lt;/td&gt;
&lt;td&gt;93&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best Practices&lt;/td&gt;
&lt;td&gt;81&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;100&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First Contentful Paint&lt;/td&gt;
&lt;td&gt;2.6s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Largest Contentful Paint&lt;/td&gt;
&lt;td&gt;3.4s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total Blocking Time&lt;/td&gt;
&lt;td&gt;200ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cumulative Layout Shift&lt;/td&gt;
&lt;td&gt;0.001&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;SEOは満点。静的HTMLをCDNから配信しているので、CLSはほぼゼロです。Performanceは&lt;a href=&quot;https://swup.js.org/&quot;&gt;Swup&lt;/a&gt;のページ遷移アニメーションやWebフォントの読み込みがあるので85ですが、体感は十分速いです。&lt;/p&gt;
&lt;h2&gt;個人ブログとZennの棲み分け&lt;/h2&gt;
&lt;p&gt;Astroで自前ブログを構築したものの、技術記事の発信先として&lt;a href=&quot;https://zenn.dev/&quot;&gt;Zenn&lt;/a&gt;も併用しており、棲み分けは悩みどころです。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;個人ブログ&lt;/th&gt;
&lt;th&gt;Zenn&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;読者層&lt;/td&gt;
&lt;td&gt;検索流入、既存読者&lt;/td&gt;
&lt;td&gt;Zennコミュニティ、エンジニア&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO&lt;/td&gt;
&lt;td&gt;自分でコントロール可能&lt;/td&gt;
&lt;td&gt;Zennドメインの強さに乗れる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;デザイン&lt;/td&gt;
&lt;td&gt;完全に自由&lt;/td&gt;
&lt;td&gt;Zennのフォーマット固定&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;収益化&lt;/td&gt;
&lt;td&gt;アフィリエイト自由&lt;/td&gt;
&lt;td&gt;バッジ（投げ銭）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;所有権&lt;/td&gt;
&lt;td&gt;自分のドメイン・リポジトリ&lt;/td&gt;
&lt;td&gt;プラットフォーム依存&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;現時点の方針としては、技術的にニッチな記事やガジェットレビュー、生活系の記事は個人ブログへ、汎用的な技術Tipsや他のエンジニアに届けたい記事はZennへ書くようにしています。ただ、明確な基準があるわけではなく、書きながら判断しているのが正直なところです。&lt;/p&gt;
&lt;h2&gt;textlintで日本語の品質を底上げ&lt;/h2&gt;
&lt;p&gt;移行後の仕上げとして、日本語文章のlinterである&lt;a href=&quot;https://textlint.github.io/&quot;&gt;textlint&lt;/a&gt;を導入しました。コードにESLintがあるように、日本語の文章にもlinterを入れることで、タイポや読みにくい表現を機械的に検出できます。&lt;/p&gt;
&lt;h3&gt;導入したプラグイン&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;パッケージ&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/textlint-ja/textlint-rule-preset-ja-technical-writing&quot;&gt;textlint-rule-preset-ja-technical-writing&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;技術文書向けの日本語ルール集&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/textlint/textlint-plugin-mdx&quot;&gt;textlint-plugin-mdx&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;MDXファイルの解析対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/textlint/textlint-filter-rule-comments&quot;&gt;textlint-filter-rule-comments&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;HTMLコメントによるルール無効化&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;設定方針&lt;/h3&gt;
&lt;p&gt;テックブログは書籍のような堅い文体を求められないため、ガチガチのフォーマットルールは無効にし、&lt;strong&gt;読みやすさとタイポ検出&lt;/strong&gt;に絞りました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;有効にしたルール（読みやすさ・タイポ）:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;{/* textlint-disable */}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ja-no-successive-word&lt;/code&gt; — 同じ単語の連続（「にに」「をを」等のタイポ）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ja-no-redundant-expression&lt;/code&gt; — 冗長表現（「○○を行う」→「○○する」）
{/* textlint-enable */}&lt;/li&gt;
&lt;li&gt;&lt;code&gt;no-unmatched-pair&lt;/code&gt; — 括弧の閉じ忘れ&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sentence-length&lt;/code&gt; — 長すぎる文（200文字超）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;no-dropping-the-ra&lt;/code&gt; — ら抜き言葉&lt;/li&gt;
&lt;li&gt;&lt;code&gt;no-invalid-control-character&lt;/code&gt; — 不正な制御文字&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;無効にしたルール（ブログには不要）:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;no-mix-dearu-desumasu&lt;/code&gt; — ですます/である調の混在（ブログでは自然）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;preset-jtf-style&lt;/code&gt; — JTF日本語標準スタイルガイド全般（半角/全角かっこ、箇条書き句点統一など）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max-ten&lt;/code&gt; / &lt;code&gt;max-comma&lt;/code&gt; — 読点・カンマの数制限&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;効果&lt;/h3&gt;
&lt;p&gt;661記事に対して実行したところ、初回で約300件のエラーが検出されました。内訳は冗長表現、タイポ（助詞の重複や文字の二重入力）、括弧の閉じ忘れが大半です。WordPress時代には気づけなかった問題が一括で洗い出せたのは、Markdownファイルとしてファイルシステム上にコンテンツがあるからこそです。&lt;/p&gt;
&lt;p&gt;CIにもBiomeと並列でtextlintを実行するジョブを追加しているため、今後の記事でも品質が自動的に担保されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// .textlintrc.json（抜粋）
{
  &quot;rules&quot;: {
    &quot;preset-ja-technical-writing&quot;: {
      &quot;sentence-length&quot;: { &quot;max&quot;: 200 },
      &quot;no-mix-dearu-desumasu&quot;: false,
      &quot;ja-no-successive-word&quot;: { &quot;allow&quot;: [&quot;。&quot;, &quot;！&quot;, &quot;？&quot;, &quot;…&quot;, &quot;・&quot;, &quot;○&quot;] },
      &quot;ja-no-redundant-expression&quot;: true,
      &quot;no-unmatched-pair&quot;: true,
      &quot;no-dropping-the-ra&quot;: true
    },
    &quot;preset-jtf-style&quot;: false
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;WordPressからAstroへ移行しました。初期構築に半日、仕上げに2日間ぐらいかかりました。&lt;/p&gt;
&lt;p&gt;19年分のコンテンツをMarkdownファイルとしてGitリポジトリに格納し、Cloudflare CDNから配信する。DBもVPSも不要。&lt;a href=&quot;https://docs.anthropic.com/en/docs/claude-code&quot;&gt;Claude Code&lt;/a&gt;に移行作業を手伝ってもらったおかげで、661記事の移行も現実的な工数で完了しました。&lt;/p&gt;
&lt;p&gt;LLMの活用が進む中で、コンテンツがMarkdownファイルとしてファイルシステム上にあることの価値はますます大きくなると思います。残りの2サイトも同じようにすすめます。&lt;/p&gt;
</content:encoded></item><item><title>Claude Code (Max plan) の使用率を tmux / Starship に表示する</title><link>https://blog.teraren.com/posts/claude-code-tmux-usage/</link><guid isPermaLink="true">https://blog.teraren.com/posts/claude-code-tmux-usage/</guid><description>ステータスバーの右側に、Claude Code の使用率がカラーバーで表示されています。左のバーが5時間セッション使用率、右が週間使用率です。使用率に応じて**緑→黄→赤**と色が変わるので、パッと見で残りの枠が分かります。</description><pubDate>Mon, 02 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/tmux-status-bar.png&quot; alt=&quot;tmux ステータスバーに Claude Code 使用率を表示&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Claude Code Max プランの&lt;strong&gt;5時間セッション使用率&lt;/strong&gt;と&lt;strong&gt;週間使用率&lt;/strong&gt;をカラーバーで表示&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tmux TPM プラグイン&lt;/strong&gt;と &lt;strong&gt;Starship カスタムモジュール&lt;/strong&gt;の両方に対応&lt;/li&gt;
&lt;li&gt;OAuth トークンで使用率 API を叩き、キャッシュ付きで負荷を最小限に抑える設計&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Claude Code の Max プランを使っていて、残りの使用枠を常に把握したい方&lt;/li&gt;
&lt;li&gt;tmux や Starship でターミナル環境をカスタマイズしている方&lt;/li&gt;
&lt;li&gt;CLI 環境を自分好みにいじるのが好きな方&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ステータスバーの右側に、Claude Code の使用率がカラーバーで表示されています。左のバーが5時間セッション使用率、右が週間使用率です。使用率に応じて&lt;strong&gt;緑→黄→赤&lt;/strong&gt;と色が変わるので、パッと見で残りの枠が分かります。&lt;/p&gt;
&lt;h2&gt;背景：なぜ tmux に表示したいのか&lt;/h2&gt;
&lt;p&gt;Claude Code を Max プランで使っていると、「今どれくらい使ったかな？」って気になりますよね。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/usage&lt;/code&gt; コマンドで確認できるけど、作業中にわざわざコマンドを打つのは面倒です。tmux のステータスバーに常時表示しておけば、コーディングしながらチラッと目をやるだけで使用状況が分かります。&lt;/p&gt;
&lt;h2&gt;仕組み&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    A[tmux status-interval&amp;lt;br/&amp;gt;5秒ごと] --&amp;gt;|#実行| B[tmux-claude.sh]
    B --&amp;gt; C{キャッシュ&amp;lt;br/&amp;gt;有効?}
    C --&amp;gt;|有効| D[キャッシュ値を表示]
    C --&amp;gt;|期限切れ| E[古い値を表示]
    E --&amp;gt;|バックグラウンド| F[API から取得]
    F --&amp;gt; G[キャッシュ更新]
    C --&amp;gt;|キャッシュなし| H[API から取得して表示]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ポイントは以下の3つです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;OAuth トークンで使用率 API を呼び出し&lt;/strong&gt;: Claude Code が保持している OAuth トークンを使って、Anthropic の使用率 API からセッション/週間の利用率を取得&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5分間キャッシュ&lt;/strong&gt;: API を毎回叩くのは無駄なので、取得結果を &lt;code&gt;/tmp&lt;/code&gt; にキャッシュ。期限切れ時も古い値を即表示しつつバックグラウンドで更新&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tmux カラーコード出力&lt;/strong&gt;: スクリプトの stdout に &lt;code&gt;#[fg=色]&lt;/code&gt; 形式の tmux フォーマットコードを含めることで、カラフルなバー表示を実現&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;p&gt;この仕組みを &lt;strong&gt;tmux TPM プラグイン&lt;/strong&gt;と &lt;strong&gt;Starship カスタムモジュール&lt;/strong&gt;として公開しました。&lt;/p&gt;
&lt;p&gt;https://github.com/matsubo/claude-code-max-usage&lt;/p&gt;
&lt;h3&gt;tmux (TPM プラグイン)&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/tmux-plugins/tpm&quot;&gt;TPM (Tmux Plugin Manager)&lt;/a&gt; を使っている方は、&lt;code&gt;~/.tmux.conf&lt;/code&gt; に2行追加するだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# プラグイン追加
set -g @plugin &apos;matsubo/claude-code-max-usage&apos;

# status-right に組み込む
set -g status-right &quot;#{claude_usage}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;prefix&lt;/code&gt; + &lt;code&gt;I&lt;/code&gt; でインストールしたら完了です。&lt;/p&gt;
&lt;p&gt;コンパクト表示（バーなし、パーセントのみ）もあります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# コンパクト表示: 22%/14%
set -g status-right &quot;#{claude_usage_compact}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Starship カスタムモジュール&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/03/starship-prompt.png&quot; alt=&quot;Starship でのコンパクト表示&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Starship を使っている方は &lt;code&gt;~/.config/starship.toml&lt;/code&gt; に追加します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[custom.claude]
command = &quot;/path/to/claude-code-max-usage/scripts/claude_usage_starship.sh&quot;
when = &quot;test -f ~/.claude/.credentials.json&quot;
format = &quot;[$output]($style) &quot;
style = &quot;&quot;
shell = [&quot;bash&quot;, &quot;--noprofile&quot;, &quot;--norc&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;tmux と Starship で&lt;strong&gt;キャッシュを共有&lt;/strong&gt;しているので、両方使っても API コールは5分に1回だけです。&lt;/p&gt;
&lt;h3&gt;カスタマイズ&lt;/h3&gt;
&lt;p&gt;色やしきい値は tmux オプションまたは環境変数で変更できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set -g @claude_usage_cache_ttl 600        # キャッシュ 10分
set -g @claude_usage_threshold_warn 40    # 黄色のしきい値
set -g @claude_usage_threshold_crit 70    # 赤のしきい値
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;詳細は &lt;a href=&quot;https://github.com/matsubo/claude-code-max-usage#configuration&quot;&gt;README&lt;/a&gt; を参照してください。&lt;/p&gt;
&lt;h2&gt;技術的なポイント&lt;/h2&gt;
&lt;h3&gt;OAuth トークンの取得&lt;/h3&gt;
&lt;p&gt;Claude Code は OAuth 認証情報を &lt;code&gt;~/.claude/.credentials.json&lt;/code&gt; に保存しています。ここから &lt;code&gt;claudeAiOauth.accessToken&lt;/code&gt; を取得して API リクエストに使います。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;jq -r &apos;.claudeAiOauth.accessToken&apos; ~/.claude/.credentials.json
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用率 API&lt;/h3&gt;
&lt;p&gt;Anthropic の使用率 API は以下のエンドポイントです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -s \
    -H &quot;Authorization: Bearer $TOKEN&quot; \
    -H &quot;anthropic-beta: oauth-2025-04-20&quot; \
    &quot;https://api.anthropic.com/api/oauth/usage&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;レスポンスはこんな形で返ってきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;five_hour&quot;: {
    &quot;utilization&quot;: 22,
    &quot;resets_at&quot;: &quot;2026-03-02T15:00:00Z&quot;
  },
  &quot;seven_day&quot;: {
    &quot;utilization&quot;: 14,
    &quot;resets_at&quot;: &quot;2026-03-08T00:00:00Z&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;five_hour.utilization&lt;/code&gt; が5時間枠の使用率（%）、&lt;code&gt;seven_day.utilization&lt;/code&gt; が週間の使用率（%）です。&lt;code&gt;/usage&lt;/code&gt; コマンドで表示される値と完全に一致します。&lt;/p&gt;
&lt;h3&gt;tmux のカラー出力&lt;/h3&gt;
&lt;p&gt;tmux の &lt;code&gt;#()&lt;/code&gt; コマンド置換では、出力に tmux フォーマットコード（&lt;code&gt;#[fg=色]&lt;/code&gt;）を含めることができます。これを利用して、スクリプトの stdout にカラーコードを埋め込んでいます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 使用率 50% 未満は緑、80% 未満は黄、それ以上は赤
printf &quot;#[fg=#a6da95]██#[fg=#7a839e]░░░#[fg=#a6da95]22%%&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;printf&lt;/code&gt; で &lt;code&gt;%&lt;/code&gt; を出力するには &lt;code&gt;%%&lt;/code&gt; と書きます。tmux の &lt;code&gt;#()&lt;/code&gt; 出力では strftime 処理が走らないため、&lt;code&gt;%%&lt;/code&gt; がそのまま &lt;code&gt;%&lt;/code&gt; として表示されます。&lt;code&gt;%%%%&lt;/code&gt; にすると &lt;code&gt;%%&lt;/code&gt; が表示されてしまうので注意です。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h3&gt;キャッシュ戦略&lt;/h3&gt;
&lt;p&gt;API を毎回叩くとレートリミットに引っかかる可能性があるので、5分間のキャッシュを設けています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    A[スクリプト実行] --&amp;gt; B{キャッシュファイル&amp;lt;br/&amp;gt;存在する?}
    B --&amp;gt;|No| C[同期的に API 取得]
    C --&amp;gt; D[キャッシュに保存]
    D --&amp;gt; E[結果を出力]
    B --&amp;gt;|Yes| F{5分以内?}
    F --&amp;gt;|Yes| G[キャッシュ値を出力]
    F --&amp;gt;|No| H[古いキャッシュ値を出力]
    H --&amp;gt; I{ロック取得&amp;lt;br/&amp;gt;できる?}
    I --&amp;gt;|Yes| J[バックグラウンドで&amp;lt;br/&amp;gt;API 取得 &amp;amp; 更新]
    I --&amp;gt;|No| K[別プロセスが&amp;lt;br/&amp;gt;更新中なのでスキップ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ポイントは、キャッシュ期限切れでも&lt;strong&gt;古い値を即座に返す&lt;/strong&gt;こと。バックグラウンドで更新するので、ユーザーは待たされません。&lt;code&gt;mkdir&lt;/code&gt; によるロックで二重実行も防止しています。&lt;/p&gt;
&lt;h3&gt;iOS 端末での対策&lt;/h3&gt;
&lt;p&gt;Termius などの iOS ターミナルから接続すると、Nerd Font アイコンやブロック文字（█、░）が倍幅レンダリングされてステータスバーが崩れることがあります。&lt;/p&gt;
&lt;p&gt;tmux の &lt;code&gt;#{client_width}&lt;/code&gt; を使った条件分岐で、狭い端末ではコンパクト表示に切り替えています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set -g status-right &quot;#{?#{e|&amp;gt;=:#{client_width},120},&amp;lt;フル表示&amp;gt;,&amp;lt;コンパクト表示&amp;gt;}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;依存ツール&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;jq&lt;/strong&gt;: JSON パース&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;cURL&lt;/strong&gt;: API リクエスト&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nerd Font&lt;/strong&gt;: アイコン表示（オプション）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Claude Code の使用率を tmux や Starship に表示することで、コーディング中でも残りの枠を意識できるようになりました。特に Max プランでは5時間ウィンドウの制限があるので、「あとどれくらい使えるか」がチラ見で分かるのはめちゃくちゃ便利です。&lt;/p&gt;
&lt;p&gt;TPM プラグインとして公開したので、&lt;code&gt;set -g @plugin&lt;/code&gt; の1行で導入できます。Starship ユーザーもカスタムモジュールとしてすぐに使えます。カラーパレットやしきい値も変更できるので、好みに合わせていじってみてください。&lt;/p&gt;
&lt;p&gt;https://github.com/matsubo/claude-code-max-usage&lt;/p&gt;
&lt;h2&gt;おまけ&lt;/h2&gt;
&lt;p&gt;https://x.com/matsubokkuri/status/2028549242973983206&lt;/p&gt;
</content:encoded></item><item><title>17万9千座の山頂データをサブ10msで検索するPWAをClaude Codeで開発した</title><link>https://blog.teraren.com/posts/sota-peak-finder/</link><guid isPermaLink="true">https://blog.teraren.com/posts/sota-peak-finder/</guid><description>SOTA対象の17万9千座をサブ10msで検索できるPWAをClaude Codeだけで開発。SQLite Wasm+R*Treeで完全オフライン動作。</description><pubDate>Thu, 26 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SOTA（Summits On The Air）&lt;/strong&gt; という山岳アマチュア無線のプログラム用の山頂検索PWAを作った&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SQLite Wasm + R*Tree空間インデックス&lt;/strong&gt; で17万9千座の山をサブ10msで検索できる超高速アプリ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自分ではコードを1行も書いていない。&lt;/strong&gt; Claude Codeとfrontend-designスキルだけで開発した&lt;/li&gt;
&lt;li&gt;PWA対応で &lt;strong&gt;完全オフライン動作&lt;/strong&gt;。山の上で電波がなくても使える&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インフラ費用は完全無料。&lt;/strong&gt; GitHub Pages + GitHub Actionsだけで運用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PWAやSQLite Wasmなど、ブラウザの最新技術に興味がある人&lt;/li&gt;
&lt;li&gt;Claude Codeでアプリ開発をしてみたい人&lt;/li&gt;
&lt;li&gt;位置ゲー好きな人（Ingress勢、ポケGO勢）&lt;/li&gt;
&lt;li&gt;個人開発でインフラ費用ゼロを目指したい人&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;完成したアプリ&lt;/h2&gt;
&lt;p&gt;https://matsubo.github.io/sota-peak-finder/&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;まず完成品をお見せします。「SOTA Peak Finder」は、世界中の &lt;strong&gt;17万9,527座&lt;/strong&gt; のSOTA対象山頂を検索できるPWAです。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/02/dashboard.png&quot; alt=&quot;SOTA Peak Finderのダッシュボード画面。世界のSOTA統計情報が一覧できる&quot; /&gt;
&lt;em&gt;ダッシュボード画面。世界中のSOTA統計情報が一目でわかる&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;そもそもSOTAってなに？&lt;/h2&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SOTA（Summits On The Air）&lt;/strong&gt; は、登山とアマチュア無線を組み合わせた世界的なプログラムです。2002年にイギリスで始まりました。&lt;/p&gt;
&lt;p&gt;ざっくり言うと、&lt;strong&gt;山に登って、山頂から無線で4局以上と交信すると、ポイントがもらえる&lt;/strong&gt; というプログラムです。山が高いほど、冬季はさらにポイントが多くもらえます。たとえば &lt;strong&gt;富士山（JA/SO-001）は10ポイント&lt;/strong&gt;（最高値）、&lt;strong&gt;高尾山（JA/TK-034）は2ポイント&lt;/strong&gt;。1,000ポイント貯めると「Mountain Goat（山のヤギ）」というトロフィーがもらえる。富士山でも100回登らないと届かない計算です。こういうの燃えません？&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    A[山頂に登る 🏔️] --&amp;gt; B[無線機をセットアップ 📻]
    B --&amp;gt; C[4局以上と交信 📡]
    C --&amp;gt; D[ポイントゲット！ 🎯]
    D --&amp;gt; E{1000pt到達？}
    E --&amp;gt;|Yes| F[Mountain Goat 🐐]
    E --&amp;gt;|No| A
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;参加者には2種類います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;アクティベーター&lt;/strong&gt;: 自分で山に登って山頂からQRV（無線で電波を出す）する人&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;チェイサー&lt;/strong&gt;: 自宅や別の場所からアクティベーターと交信する人&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;私のコールサインは &lt;strong&gt;JE1WFV&lt;/strong&gt; です。アクティベーターとして山に登って無線運用しています。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;h2&gt;作った背景 ― 位置ゲーマーの血が騒ぐ&lt;/h2&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;{/* textlint-disable spellcheck-tech-word */}&lt;/p&gt;
&lt;p&gt;私は &lt;strong&gt;位置ゲーが大好き&lt;/strong&gt; です。Ingressを長いことやっていました。ポータルを巡って街を歩き回る、あの感覚がたまらないんですよね。&lt;/p&gt;
&lt;p&gt;で、アマチュア無線を始めて SOTA を知ったとき、「&lt;strong&gt;これ、位置ゲーじゃん！&lt;/strong&gt;」って思ったんですよ。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable spellcheck-tech-word */}&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;特定の場所（山頂）に行く → Ingressのポータル巡りと同じ&lt;/li&gt;
&lt;li&gt;ポイントを貯める → ゲーミフィケーション&lt;/li&gt;
&lt;li&gt;世界中にスポットがある → グローバルな位置ゲー&lt;/li&gt;
&lt;li&gt;レアなスポット（未踏峰）がある → コンプ欲を刺激&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;しかも私は &lt;strong&gt;トレイルランニング&lt;/strong&gt; もやっています。トレランで山を走れば、1日で複数の高ポイント山頂を回れる。SOTAのポイントを効率よく稼ぐのにトレランとの相性が抜群なんです。逆に言えば、SOTAが &lt;strong&gt;トレランで山を走る目的&lt;/strong&gt; にもなる。「次はあの山頂をアクティベートしよう」と思えば、トレーニングのモチベーションも上がります。&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;ただ、SOTAには1つ大きな課題がありました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;近くのSOTA対象の山を探すのがめちゃくちゃ面倒。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;公式サイトのデータベースは検索しにくいし、一覧性がないし、オフラインで使えない。しかも登山中はキャリアの電波が届かないことが多い。山の中腹から山頂にかけて圏外になるのは日常茶飯事です。つまり、&lt;strong&gt;山頂に着いてから「この山SOTAの対象だっけ？」と調べようとしても、そもそもネットにつながらない&lt;/strong&gt;。だからデータをローカルに持つPWAが必要なんです。&lt;/p&gt;
&lt;p&gt;ないなら作ろう。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;h2&gt;技術スタック&lt;/h2&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;今回の開発で使った技術スタックはこちらです。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;カテゴリ&lt;/th&gt;
&lt;th&gt;技術&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;フロントエンド&lt;/td&gt;
&lt;td&gt;React 19 + TypeScript 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ビルドツール&lt;/td&gt;
&lt;td&gt;Vite 5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;データベース&lt;/td&gt;
&lt;td&gt;SQLite Wasm（@sqlite.org/sqlite-wasm v3.52.0）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;空間インデックス&lt;/td&gt;
&lt;td&gt;R*Tree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PWA&lt;/td&gt;
&lt;td&gt;vite-plugin-pwa + Service Worker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;スタイリング&lt;/td&gt;
&lt;td&gt;Tailwind CSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;デプロイ&lt;/td&gt;
&lt;td&gt;GitHub Pages + GitHub Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;データ更新&lt;/td&gt;
&lt;td&gt;GitHub Actions（毎週日曜自動更新）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    subgraph Browser
        React[React 19] --&amp;gt; SQLite[SQLite Wasm]
        SW[Service Worker] --&amp;gt; React
    end

    subgraph GitHub
        Actions[GitHub Actions] --&amp;gt; Pages[GitHub Pages]
    end

    SOTA[SOTA CSV Data] --&amp;gt; Actions
    Pages --&amp;gt; SW
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;主な機能&lt;/h2&gt;
&lt;h3&gt;ダッシュボード&lt;/h3&gt;
&lt;p&gt;ホーム画面では世界中のSOTA統計情報を俯瞰できます。最高峰・最低峰、高ポイント山頂、人気の山頂、まだ誰もアクティベートしていない未踏峰など。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/02/stats.png&quot; alt=&quot;ダッシュボードの統計カード。世界のSOTA情報が一目でわかる&quot; /&gt;
&lt;em&gt;統計情報セクション。山頂の数だけ見ても世界規模のプログラムだとわかる&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;GPS検索 ― 近くの山を瞬時に発見&lt;/h3&gt;
&lt;p&gt;GPSボタンをタップすると、&lt;strong&gt;現在位置から50km以内のSOTA山頂を最大20座&lt;/strong&gt; 表示します。距離、方位、標高、ポイント、アクティベーションゾーン内かどうかまでわかります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/02/nearby.png&quot; alt=&quot;GPS検索画面。現在位置からの近傍山頂が一覧表示される&quot; /&gt;
&lt;em&gt;GPS検索結果。距離・方位・標高・ポイントが一覧で見える&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Summit一覧 &amp;amp; フィルタリング&lt;/h3&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;17万9千座を自由にフィルタリングできます。アソシエーション（国/地域）、リージョン、標高範囲、ポイント値など、細かい条件で絞り込める。「日本のまだ誰もアクティベートしていない10ポイント峰」みたいな検索がサクサクできます。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/02/browse.png&quot; alt=&quot;Summit一覧画面。フィルタ条件で絞り込みができる&quot; /&gt;
&lt;em&gt;Browse画面。多彩なフィルタで目的の山を探せる&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Summit詳細ページ&lt;/h3&gt;
&lt;p&gt;各山頂の詳細ページでは、座標、Maidenheadグリッドロケーター、標高、ポイント、直近のアクティベーション履歴、さらには &lt;strong&gt;7日間の天気予報&lt;/strong&gt; まで表示します。天気予報は標高補正済みのデータで、風速30km/h超の場合は警告も出します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/02/detail.png&quot; alt=&quot;Summit詳細画面。天気予報やアクティベーション履歴が見られる&quot; /&gt;
&lt;em&gt;Summit詳細。天気予報まで見られるのは登山計画に便利&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;ブックマーク機能&lt;/h3&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;各山頂ページのブックマークボタンをクリックするだけで、&lt;strong&gt;「Want to Go（行きたい）」→「Activated（アクティベート済み）」→ 解除&lt;/strong&gt; と3段階でステータスが切り替わります。登山計画と実績管理がワンタップで完結する。localStorageに保存されるのでサーバー不要、オフラインでも使えます。まさに位置ゲーの「お気に入りスポット」感覚です。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/02/bookmarks.png&quot; alt=&quot;ブックマーク画面。Want to GoとActivatedの2カテゴリで管理できる&quot; /&gt;
&lt;em&gt;ブックマーク画面。「行きたい」と「アクティベート済み」をワンタップで切り替え&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;完全オフライン動作 ― 圏外の山頂でこそ真価を発揮&lt;/h3&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;登山をやっている人ならわかると思いますが、山の中はキャリアの電波が届かないことがほんとうに多い。標高が高くなるほど、谷間に入るほど圏外になります。だからこそ、&lt;strong&gt;データをローカルに持つPWAという設計が必須&lt;/strong&gt; でした。&lt;/p&gt;
&lt;p&gt;初回アクセス時にService Workerが全データ（約44MB）をキャッシュします。2回目以降は &lt;strong&gt;完全オフライン&lt;/strong&gt; で動作します。CacheFirst戦略で90日間キャッシュを保持するので、自宅でアプリを開いておけば、あとは山の上で圏外でも問題なく使えます。&lt;/p&gt;
&lt;p&gt;正直、初回ダウンロードの約50MBは軽くはないです。リージョンごとにデータを分割して必要な地域だけダウンロードさせる設計も考えました。でも、「いま日本のデータしか入ってないから海外の山は検索できない」みたいな &lt;strong&gt;機能制限を意識しながら使うストレスのほうがよっぽど大きい&lt;/strong&gt;。初回だけ我慢すれば、あとは世界中の17万9千座がまるごと手元にある。このシンプルさを優先しました。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;h2&gt;技術的なこだわり&lt;/h2&gt;
&lt;h3&gt;SQLite Wasm + R*Tree空間インデックス ― サブ10msの秘密&lt;/h3&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;今回のアプリで一番こだわったのは &lt;strong&gt;検索速度&lt;/strong&gt; です。&lt;/p&gt;
&lt;p&gt;17万9千座の山頂データをブラウザ内で高速に検索するために、SQLite Wasmを採用しました。しかもただのSQLiteではなく、&lt;strong&gt;R*Tree空間インデックス&lt;/strong&gt; を使って緯度経度のバウンディングボックスクエリを高速化しています。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    participant User as ユーザー
    participant App as React App
    participant SQLite as SQLite Wasm
    participant RTree as R*Tree Index

    User-&amp;gt;&amp;gt;App: GPS位置取得
    App-&amp;gt;&amp;gt;SQLite: 近傍検索クエリ
    SQLite-&amp;gt;&amp;gt;RTree: バウンディングボックス検索
    RTree--&amp;gt;&amp;gt;SQLite: 候補の山頂群
    SQLite--&amp;gt;&amp;gt;App: 結果（&amp;lt; 10ms）
    App-&amp;gt;&amp;gt;App: Haversine距離計算
    App--&amp;gt;&amp;gt;User: 近い順にソートして表示
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;処理の流れは、R*Treeで大まかな矩形範囲を絞り込み、その後JavaScriptでHaversine公式を使って正確な距離を計算してソートします。この2段階フィルタリングのおかげで、&lt;strong&gt;17万9千座の中から近傍の山をサブ10msで検索&lt;/strong&gt; できます。&lt;/p&gt;
&lt;p&gt;JSONで同じデータを扱うと60%以上サイズが大きくなる上に、空間インデックスも使えないので検索が遅くなります。SQLite Wasmは正解でした。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意点&lt;/strong&gt;: SQLite Wasmでは &lt;code&gt;PRAGMA journal_mode = DELETE&lt;/code&gt; を使う必要があります。WALモードだと &lt;code&gt;sqlite3_deserialize&lt;/code&gt; と互換性がないためです。ここはちょっとハマりました。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h3&gt;PWA ― ネイティブアプリのような体験&lt;/h3&gt;
&lt;p&gt;vite-plugin-pwaを使って、Service Workerの自動生成とキャッシュ戦略を実装しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    A[初回アクセス] --&amp;gt; B[Service Worker登録]
    B --&amp;gt; C[SQLite DB キャッシュ&amp;lt;br/&amp;gt;CacheFirst / 90日]
    B --&amp;gt; D[地図タイル キャッシュ&amp;lt;br/&amp;gt;CacheFirst / 500枚 / 30日]
    B --&amp;gt; E[天気API キャッシュ&amp;lt;br/&amp;gt;CacheFirst / 12時間]
    B --&amp;gt; F[標高データ キャッシュ&amp;lt;br/&amp;gt;CacheFirst / 30日]
    C --&amp;gt; G[完全オフライン動作 ✅]
    D --&amp;gt; G
    E --&amp;gt; G
    F --&amp;gt; G
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;リソース&lt;/th&gt;
&lt;th&gt;キャッシュ戦略&lt;/th&gt;
&lt;th&gt;有効期限&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SQLiteデータベース（44MB）&lt;/td&gt;
&lt;td&gt;CacheFirst&lt;/td&gt;
&lt;td&gt;90日&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenStreetMap タイル&lt;/td&gt;
&lt;td&gt;CacheFirst&lt;/td&gt;
&lt;td&gt;30日（最大500枚）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;天気API（Open-Meteo）&lt;/td&gt;
&lt;td&gt;CacheFirst&lt;/td&gt;
&lt;td&gt;12時間&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;標高データ（国土地理院）&lt;/td&gt;
&lt;td&gt;CacheFirst&lt;/td&gt;
&lt;td&gt;30日&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SOTA API&lt;/td&gt;
&lt;td&gt;CacheFirst&lt;/td&gt;
&lt;td&gt;12時間&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;デザインシステム ― Technical Cartography&lt;/h3&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;UIデザインは &lt;strong&gt;「Technical Cartography」&lt;/strong&gt; というコンセプトで、ヴィンテージの無線機と地形図からインスピレーションを得ています。ダークベースに琥珀色のアクセント、等高線パターン、CRTスキャンライン効果など、無線の世界観を表現しています。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/02/design.png&quot; alt=&quot;アプリのUI。ヴィンテージ無線機風のダークテーマデザイン&quot; /&gt;
&lt;em&gt;Technical Cartographyデザイン。等高線パターンとネオングロウがかっこいい&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;背景&lt;/strong&gt;: &lt;code&gt;rgb(12, 16, 24)&lt;/code&gt; のダークベース&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プライマリアクセント&lt;/strong&gt;: &lt;code&gt;rgb(255, 169, 51)&lt;/code&gt; 琥珀色（ボタン、重要データ）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セカンダリ&lt;/strong&gt;: &lt;code&gt;rgb(51, 204, 204)&lt;/code&gt; ティール（グリッド、ラベル）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPS/ステータス&lt;/strong&gt;: &lt;code&gt;rgb(102, 255, 153)&lt;/code&gt; グリーン&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;フォントも3種類使い分けています。ヘッダーにRajdhani、座標データにJetBrains Mono、本文にDM Sans。技術的な雰囲気を出しつつ、読みやすさも確保しました。&lt;/p&gt;
&lt;h2&gt;Claude Codeだけで開発した話&lt;/h2&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;ここが今回一番伝えたいことかもしれません。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;このアプリ、自分ではコードを1行も書いていません。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;全部 &lt;strong&gt;Claude Code&lt;/strong&gt; で開発しました。要件を日本語で伝えて、Claude Codeがコードを生成して、テストして、コミットして、リリースまでやってくれる。v3.1.0からv3.6.0まで、機能追加もバグ修正も全部Claude Codeです。&lt;/p&gt;
&lt;p&gt;UIデザインに関しては、Claude Codeの &lt;strong&gt;frontend-designスキル&lt;/strong&gt;（Anthropic公式）を使いました。このスキルは「AIっぽいダサいUI」を避けて、プロダクションクオリティの独創的なデザインを生成してくれます。フォント選定、カラーパレット、アニメーション、背景パターンまで、全部スキルが決めてくれました。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    A[私] --&amp;gt;|要件を日本語で伝える| B[Claude Code]
    B --&amp;gt;|コード生成| C[React + TypeScript]
    B --&amp;gt;|デザイン| D[frontend-design Skill]
    B --&amp;gt;|テスト| E[Playwright E2E]
    B --&amp;gt;|デプロイ| F[GitHub Actions]
    D --&amp;gt; C
    C --&amp;gt; G[SOTA Peak Finder 🏔️]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;開発の流れ&lt;/h3&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;要件定義&lt;/strong&gt;: 「SOTAの山頂を近くの位置から検索できるPWAを作りたい。オフラインで動くようにしたい」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;技術選定&lt;/strong&gt;: SQLite Wasmを使った高速検索、R*Tree空間インデックスの提案もClaude Codeから&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実装&lt;/strong&gt;: ページごとに「ダッシュボードページを作って」「GPS検索機能を追加して」と指示&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デザイン&lt;/strong&gt;: &lt;code&gt;/frontend-design&lt;/code&gt;スキルでUIを洗練&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テスト&lt;/strong&gt;: Playwright E2Eテストの作成と実行もClaude Codeが担当&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リリース&lt;/strong&gt;: コミット、タグ付け、リリースノート作成まで自動化&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;GitHubのコミット履歴を見ると、Claude Codeのセッションリンクが含まれているコミットがあります。開発プロセスが完全にトレーサブルです。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;h3&gt;リリース履歴&lt;/h3&gt;
&lt;p&gt;OSSとしてGitHubで公開しているので、開発の全履歴が見られます。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;バージョン&lt;/th&gt;
&lt;th&gt;主な機能追加&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;v3.1.0&lt;/td&gt;
&lt;td&gt;ホームページをダッシュボードに変身。統計カード、ヒーローバナー追加&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v3.2.0&lt;/td&gt;
&lt;td&gt;国別フィルタ、色分けインジケーター&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v3.3.0&lt;/td&gt;
&lt;td&gt;全ドキュメント英語翻訳、バイリンガルUI対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v3.4.0&lt;/td&gt;
&lt;td&gt;山頂ページに7日間天気予報を追加&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v3.5.0&lt;/td&gt;
&lt;td&gt;直近のアクティベーション履歴、アクティベーターページ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;v3.6.0&lt;/td&gt;
&lt;td&gt;ブックマーク機能、GPSライブポジショニング、ダウンロード進捗バー&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;インフラ費用：完全無料&lt;/h2&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;このアプリの運用にかかるインフラ費用は &lt;strong&gt;完全にゼロ&lt;/strong&gt; です。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;サービス&lt;/th&gt;
&lt;th&gt;用途&lt;/th&gt;
&lt;th&gt;費用&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Pages&lt;/td&gt;
&lt;td&gt;ホスティング&lt;/td&gt;
&lt;td&gt;無料&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;td&gt;ビルド・デプロイ・データ更新&lt;/td&gt;
&lt;td&gt;無料&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SOTA公式CSV&lt;/td&gt;
&lt;td&gt;山頂データソース&lt;/td&gt;
&lt;td&gt;無料&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open-Meteo&lt;/td&gt;
&lt;td&gt;天気予報API&lt;/td&gt;
&lt;td&gt;無料&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenStreetMap&lt;/td&gt;
&lt;td&gt;地図タイル&lt;/td&gt;
&lt;td&gt;無料&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;国土地理院&lt;/td&gt;
&lt;td&gt;標高データ&lt;/td&gt;
&lt;td&gt;無料&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;サーバーレス。データベースサーバーなし。APIサーバーなし。全部ブラウザ内で完結します。SQLite Wasmのおかげで、サーバーサイドのデータベースが不要になりました。&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;毎週日曜日にGitHub Actionsが自動でSOTA公式CSVを取得してデータベースを再構築し、GitHub Pagesにデプロイします。完全自動運用です。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    A[毎週日曜 00:00 UTC] --&amp;gt; B[GitHub Actions起動]
    B --&amp;gt; C[SOTA公式CSVダウンロード&amp;lt;br/&amp;gt;24MB / 179,527座]
    C --&amp;gt; D[SQLiteデータベース構築&amp;lt;br/&amp;gt;R*Tree空間インデックス付き]
    D --&amp;gt; E[サイトマップ生成&amp;lt;br/&amp;gt;プログラマティックSEO]
    E --&amp;gt; F[GitHub Pagesへデプロイ]
    F --&amp;gt; G[ユーザーのService Worker&amp;lt;br/&amp;gt;が次回アクセス時に更新]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;SOTA Peak Finderは「位置ゲー好き×アマチュア無線家」の自分にとって、最高に楽しいプロジェクトでした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SQLite Wasm + R*Tree&lt;/strong&gt; は、ブラウザ内で大量の地理データを扱うベストな選択肢。サブ10msの検索速度は体感で「一瞬」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PWA&lt;/strong&gt; でオフライン動作させることで、電波のない山の上でも使える実用的なアプリに&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; を使えば、コードを1行も書かずにプロダクションレベルのアプリが作れる時代&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Pages + GitHub Actions&lt;/strong&gt; で、インフラ費用完全無料の自動運用が実現&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SOTAをやっている人はぜひ使ってみてください。そしてSOTAを知らなかった人は、これを機にアマチュア無線の世界に足を踏み入れてみませんか？　山に登って、無線で交信して、ポイントを貯める。&lt;strong&gt;究極の位置ゲー&lt;/strong&gt; がそこにあります。&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;https://matsubo.github.io/sota-peak-finder/&lt;/p&gt;
&lt;p&gt;https://github.com/matsubo/sota-peak-finder&lt;/p&gt;
&lt;h2&gt;おまけ&lt;/h2&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;私のコールサインは &lt;strong&gt;JE1WFV&lt;/strong&gt; です。SOTAでアクティベーションしているときに聞こえたら、ぜひ呼んでください！&lt;/p&gt;
&lt;p&gt;Ingressは今でもたまにやっています。位置ゲーの血は抜けないものですね。SOTAはIngressの「ユニークポータル数を稼ぐ」感覚に近い楽しさがあって、ハマっています。&lt;/p&gt;
&lt;p&gt;アプリに関するフィードバックやバグ報告は、&lt;a href=&quot;https://github.com/matsubo/sota-peak-finder/issues&quot;&gt;GitHubのIssue&lt;/a&gt;や&lt;a href=&quot;https://discord.gg/Fztt8jwr6A&quot;&gt;Discord&lt;/a&gt;で受け付けています。プルリクエストも大歓迎です！&lt;/p&gt;
&lt;p&gt;{/* textlint-enable ja-technical-writing/ja-no-weak-phrase */}&lt;/p&gt;
&lt;p&gt;73 &amp;amp; Happy Trails! 🏔️📻&lt;/p&gt;
</content:encoded></item><item><title>QNAP NAS を卒業して mergerfs + SnapRAID で「壊れても理解できる」ストレージを作った</title><link>https://blog.teraren.com/posts/nas-diy-mergerfs-snapraid/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nas-diy-mergerfs-snapraid/</guid><description>QNAP NASの不満を解消するため、mergerfs + SnapRAIDでDIY NASを構築した記録。異なる容量のHDDを無駄なく活用できる構成を紹介。</description><pubDate>Wed, 25 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;QNAP TS-431P に不満が溜まり&lt;/strong&gt;、mergerfs + SnapRAID で DIY NAS を構築した&lt;/li&gt;
&lt;li&gt;異なる容量の HDD（4TB×1 + 2TB×2）を無駄なくプールしつつ、パリティで冗長性を確保&lt;/li&gt;
&lt;li&gt;3-2-1 バックアップの考え方に基づいて、クラウドへの定期バックアップも組み合わせた&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;NAS アプライアンス（QNAP、Synology）に不満を感じている人&lt;/li&gt;
&lt;li&gt;RAID の仕組みに不安があり、もっとシンプルなストレージ構成を探している人&lt;/li&gt;
&lt;li&gt;異なる容量の HDD を無駄なく活用したい人&lt;/li&gt;
&lt;li&gt;自宅サーバーで写真やメディアファイルを長期保管したい人&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;@matsubokkuri です。&lt;/p&gt;
&lt;p&gt;自宅のストレージ環境を &lt;strong&gt;QNAP NAS から mergerfs + SnapRAID&lt;/strong&gt; に移行しました。この記事では、移行の背景から実際の設定ファイルまでをまとめます。&lt;/p&gt;
&lt;p&gt;「NAS アプライアンス、なんか微妙だな…」と感じている方の参考になれば嬉しいです。&lt;/p&gt;
&lt;p&gt;色々な AI に聞いても、mergerfs + SnapRAID の組み合わせをおすすめされたので、この構成にしました。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;背景：これまでのストレージ遍歴&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    A[&quot;🖥️ 第1世代&amp;lt;br/&amp;gt;Dell PowerEdge T320&amp;lt;br/&amp;gt;ハードウェア RAID&quot;] --&amp;gt;|RAIDカード障害で&amp;lt;br/&amp;gt;データロスト危機| B[&quot;📦 第2世代&amp;lt;br/&amp;gt;QNAP TS-431P&amp;lt;br/&amp;gt;ソフトウェア RAID5&quot;]
    B --&amp;gt;|ベンダーロックイン&amp;lt;br/&amp;gt;HDD スタンバイ問題&amp;lt;br/&amp;gt;アプリ品質| C[&quot;🛠️ 第3世代&amp;lt;br/&amp;gt;mergerfs + SnapRAID&amp;lt;br/&amp;gt;DIY NAS&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第1世代：Dell PowerEdge T320 + ハードウェア RAID&lt;/h3&gt;
&lt;p&gt;最初の自宅ストレージは &lt;strong&gt;Dell PowerEdge T320&lt;/strong&gt; に 2TB HDD を 6 本載せて、ハードウェア RAID で運用していました。サーバーらしいサーバーで、それなりに満足していたのですが、ある日 &lt;strong&gt;RAID カードが壊れかけて&lt;/strong&gt; 危うくデータをロストしかける事件が発生しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/02/poweredge-t320.jpg&quot; alt=&quot;Dell PowerEdge T320&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ハードウェア RAID の怖いところは、&lt;strong&gt;コントローラが死ぬとデータにアクセスできなくなる&lt;/strong&gt; ということです。同じ型番の RAID カードを調達して差し替えればいける——理論上は。でも実際に障害が起きたときにそれを冷静にやれるかというと、かなり厳しい。&lt;/p&gt;
&lt;p&gt;この経験から「ハードウェア RAID は信用できない」という教訓を得ました。&lt;/p&gt;
&lt;h3&gt;第2世代：QNAP TS-431P（RAID5）&lt;/h3&gt;
&lt;p&gt;PowerEdge の反省を踏まえて、次は手軽さを重視して &lt;strong&gt;&lt;a href=&quot;https://blog.teraren.com/2024/06/15/qnap-ts-431p/&quot;&gt;QNAP TS-431P&lt;/a&gt;&lt;/strong&gt; を導入しました。4 ベイの ARM ベース NAS で、2TB HDD × 4 を RAID5 で構成。利用可能容量は約 6TB です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/02/qnap-ts-431p.jpg&quot; alt=&quot;QNAP TS-431P&quot; /&gt;&lt;/p&gt;
&lt;p&gt;「アプライアンスなら管理が楽だろう」と思って導入したのですが、使い続けるうちに不満が溜まっていきました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;iOS からの写真バックアップがつらい。&lt;/strong&gt; QNAP 公式の Qfile アプリで iPhone の写真を自動バックアップしていたのですが、バックアップが途中で止まる、重複ファイルが量産される、HEIF の扱いが怪しい——控えめに言ってひどい。一眼レフの写真も含めて 1 万枚以上あるので、ここのバックアップ体験が悪いのは致命的です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HDD がスタンバイにならない。&lt;/strong&gt; 何もしていないのに &lt;strong&gt;HDD のアクセスランプが頻繁に点滅&lt;/strong&gt; しています。QTS のバックグラウンドプロセスが何かしら動いているようで、HDD がスタンバイに移行しません。日本の電気代は ¥25〜35/kWh と安くないので、使っていない時間帯にはちゃんと止まってほしい。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ベンダーロックイン。&lt;/strong&gt; QNAP の RAID 構成は独自フォーマットに依存しています。本体が壊れたら HDD を取り出して別のマシンでマウントすることが容易ではありません。PowerEdge の RAID カード障害と本質的に同じリスクを抱えています。さらに QNAP は過去に &lt;strong&gt;Deadbolt ランサムウェア&lt;/strong&gt; の標的になった実績もあり、セキュリティ面でも不安がありました。&lt;/p&gt;
&lt;h3&gt;RAID の根本的な問題&lt;/h3&gt;
&lt;p&gt;振り返ると、PowerEdge のハードウェア RAID も QNAP のソフトウェア RAID も、共通の問題を抱えていました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;管理が複雑で、壊れたときに詰む。&lt;/strong&gt; ハードウェア RAID はコントローラ依存。ZFS のようなソフトウェア RAID はプール管理が複雑で、異なるサイズのドライブを混在させにくい。QNAP の QTS RAID は GUI こそ綺麗だけど、中身はブラックボックスで、障害時に何が起きているのか分からない。&lt;/p&gt;
&lt;p&gt;そして最大の問題：&lt;strong&gt;RAID アレイが崩壊したら、全データが道連れになる。&lt;/strong&gt; RAID5 で 2 台同時に壊れたらおしまい。QNAP の場合、ストレージプール内に複数の RAID グループがあって 1 つが壊れると、&lt;strong&gt;プール全体のデータが失われる&lt;/strong&gt; という仕様もあります。&lt;/p&gt;
&lt;p&gt;もっとシンプルで、壊れても理解できて、壊れても被害が限定的なストレージが欲しい。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;目的：こんなストレージが欲しかった&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;異なる容量の HDD を無駄なくプール&lt;/strong&gt; できる（手持ちの 4TB×1、2TB×2 を活かしたい）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1台の HDD が故障しても復旧&lt;/strong&gt; できる冗長性&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ドライブ故障時に生き残ったデータは即座にアクセス可能&lt;/strong&gt; であること&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HDD が使われていない時はスタンバイ&lt;/strong&gt; に入る省電力設計&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;壊れたときに何が起きているか理解できる&lt;/strong&gt; シンプルな仕組み&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker で自由にアプリを動かせる&lt;/strong&gt; 汎用 Linux 環境&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;アプローチ：mergerfs + SnapRAID&lt;/h2&gt;
&lt;h3&gt;mergerfs：異なるサイズの HDD を 1 つに束ねる&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/trapexit/mergerfs&quot;&gt;mergerfs&lt;/a&gt; は &lt;strong&gt;FUSE ベースのユニオンファイルシステム&lt;/strong&gt; です。複数のディスクのマウントポイントを、1 つの仮想的なディレクトリとして統合します。&lt;/p&gt;
&lt;p&gt;最大のポイントは &lt;strong&gt;ファイル単位&lt;/strong&gt; で動作すること。RAID のようにブロックレベルでストライピングするのではなく、各ファイルは物理的にどれか 1 台の HDD にそのまま保存されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/mnt/data1 (4TB)  ─┐
/mnt/data2 (2TB)  ─┼─→ /mnt/storage (8TB)
/mnt/data3 (2TB)  ─┘
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これの何が嬉しいかというと：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;異なる容量の HDD を混在可能。&lt;/strong&gt; 4TB + 2TB + 2TB = 8TB がそのまま使える。RAID5 だと最小ドライブに合わせて 2TB × 3 = 6TB になってしまう&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ドライブを 1 台追加するだけで容量拡張。&lt;/strong&gt; RAID の再構築は不要&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;各 HDD は普通の ext4 なので単体でマウントして読める。&lt;/strong&gt; mergerfs が消えてもデータは無事&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;1 台が故障しても、他の HDD 上のファイルは無傷。&lt;/strong&gt; 被害は壊れたドライブに載っていたファイルだけ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RAID5 だとアレイが崩壊したら全データ喪失のリスクがありますが、mergerfs なら &lt;strong&gt;被害が限定的&lt;/strong&gt; です。PowerEdge で RAID カードが壊れかけた経験がある身としては、これがめちゃくちゃ大きい。&lt;/p&gt;
&lt;h3&gt;SnapRAID：あとからパリティを計算する&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.snapraid.it/&quot;&gt;SnapRAID&lt;/a&gt; は &lt;strong&gt;スナップショットベースのパリティシステム&lt;/strong&gt; です。リアルタイム RAID と違い、&lt;code&gt;snapraid sync&lt;/code&gt; コマンドを実行したタイミングでパリティを計算します。&lt;/p&gt;
&lt;p&gt;重要なルール：&lt;strong&gt;パリティドライブは最大のデータドライブ以上の容量が必要&lt;/strong&gt; です。今回は最大データドライブが 4TB、パリティドライブが 6TB なので余裕があります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;データ:    data1(4TB) + data2(2TB) + data3(2TB) = 8TB 利用可能
パリティ:  parity(6TB) → シングルパリティ保護
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SnapRAID は &lt;strong&gt;「書き込んだらほとんど変更しない」データ&lt;/strong&gt; に最適化されています。一眼レフの RAW 写真やメディアファイルの保管にはぴったり。逆にデータベースのように頻繁に書き換わるデータには向きません（sync 間隔の間に書き込まれたデータはパリティで保護されない）。&lt;/p&gt;
&lt;p&gt;SnapRAID のもう一つの強みは &lt;strong&gt;ビットロット検出&lt;/strong&gt; です。128bit ハッシュで全ファイルのチェックサムを管理しているので、定期的に &lt;code&gt;scrub&lt;/code&gt; を実行することでサイレントデータ破損を検出できます。長期間の写真アーカイブには地味に重要な機能です。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;サイレントデータ破損（ビットロット）とは？&lt;/strong&gt;
HDD や SSD の記録媒体は、経年劣化や宇宙線の影響で保存されたビットが勝手に反転することがあります。これが &lt;strong&gt;サイレントデータ破損（bit rot）&lt;/strong&gt; です。「サイレント」と呼ばれる理由は、OS やファイルシステムがエラーを報告しないまま、ファイルの中身が静かに壊れていくからです。たとえば 3 年前に撮った写真を開いたら画像の一部が変色していた——というケースがこれにあたります。通常のファイルシステム（ext4 など）はデータの整合性を自動チェックしない（メタデータのチェックサムはあるがデータ本体にはない）ため、ビットロットは検出されずに放置されがちです。SnapRAID は全ファイルのハッシュを記録しているので、&lt;code&gt;scrub&lt;/code&gt; コマンドで定期的にチェックすれば破損を早期発見し、パリティから修復できます。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h3&gt;従来の構成との比較&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;特徴&lt;/th&gt;
&lt;th&gt;mergerfs + SnapRAID&lt;/th&gt;
&lt;th&gt;RAID5/6&lt;/th&gt;
&lt;th&gt;QNAP QTS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;異なるサイズの HDD&lt;/td&gt;
&lt;td&gt;✅ 完全対応&lt;/td&gt;
&lt;td&gt;❌ 最小ドライブに制限&lt;/td&gt;
&lt;td&gt;❌ 最小ドライブに制限&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;パリティ計算&lt;/td&gt;
&lt;td&gt;スナップショット（定期実行）&lt;/td&gt;
&lt;td&gt;リアルタイム&lt;/td&gt;
&lt;td&gt;リアルタイム&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;書き込み性能&lt;/td&gt;
&lt;td&gt;ディスクネイティブ速度&lt;/td&gt;
&lt;td&gt;パリティオーバーヘッド&lt;/td&gt;
&lt;td&gt;パリティオーバーヘッド&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;アレイ崩壊時&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;生存ディスクのデータは保持&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;全データ喪失&lt;/td&gt;
&lt;td&gt;全データ喪失&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ドライブ追加&lt;/td&gt;
&lt;td&gt;いつでも追加可能&lt;/td&gt;
&lt;td&gt;アレイ再構築が必要&lt;/td&gt;
&lt;td&gt;RAID グループ単位&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;個別ドライブの可読性&lt;/td&gt;
&lt;td&gt;✅ 標準 FS（ext4）&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ビットロット検出&lt;/td&gt;
&lt;td&gt;✅ 128bit ハッシュ&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;限定的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HDD スタンバイ&lt;/td&gt;
&lt;td&gt;✅ 未使用ドライブは停止&lt;/td&gt;
&lt;td&gt;❌ 全 HDD 常時回転&lt;/td&gt;
&lt;td&gt;❌ 全 HDD 常時回転&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;管理&lt;/td&gt;
&lt;td&gt;CLI&lt;/td&gt;
&lt;td&gt;コントローラ依存&lt;/td&gt;
&lt;td&gt;Web GUI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;ハードウェア選定と予算&lt;/h2&gt;
&lt;h3&gt;方針：ミニ PC + USB DAS&lt;/h3&gt;
&lt;p&gt;最初は &lt;strong&gt;Raspberry Pi&lt;/strong&gt; で組みたかったんですが、写真管理に使っている Immich の機械学習機能（顔認識・セマンティック検索）は ARM では荷が重い。仕方なく、もともと自宅サーバーとして使っていた &lt;strong&gt;&lt;a href=&quot;https://amzn.to/4kZRuPQ&quot;&gt;Beelink SER5 MAX&lt;/a&gt;&lt;/strong&gt; を NAS 兼用にすることにしました。&lt;/p&gt;
&lt;h3&gt;Beelink SER5 MAX&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;CPU:    AMD Ryzen 7 5800H（8C/16T、最大 4.4GHz）
RAM:    16GB DDR4
SSD:    1TB NVMe（OS + Docker用）
USB:    3 × USB 3.2 Gen2（10Gbps）
LAN:    1GbE
TDP:    45W（実測アイドル ~15W）
サイズ:  126 × 113 × 42mm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Passmark スコアは約 21,000。QNAP TS-431P の ARM CPU とは比較にならない処理能力です。Docker で複数のサービス（写真管理、監視、ファイル共有など）を同時に動かしても余裕があります。&lt;/p&gt;
&lt;p&gt;日本のマンションだとサイズも重要で、126 × 113mm の手のひらサイズは PowerEdge のタワー型と比べると天と地の差です。&lt;/p&gt;
&lt;h3&gt;USB DAS の選び方&lt;/h3&gt;
&lt;p&gt;mergerfs では各ドライブが OS から &lt;strong&gt;独立したブロックデバイス&lt;/strong&gt; として認識される必要があります。RAID 機能のない JBOD モデルなら何も設定せず、HDD を入れるだけで &lt;code&gt;/dev/sda&lt;/code&gt;, &lt;code&gt;/dev/sdb&lt;/code&gt;… として認識されます。&lt;/p&gt;
&lt;p&gt;今回は &lt;strong&gt;&lt;a href=&quot;https://amzn.to/4aBJvVy&quot;&gt;ORICO 4 ベイ HDD ケース（USB 3.0、RAID なし）&lt;/a&gt;&lt;/strong&gt; を選びました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/02/das.png&quot; alt=&quot;ORICO HDD ケース&quot; /&gt;&lt;/p&gt;
&lt;p&gt;選定基準は &lt;strong&gt;「安い」「壊れなさそう」&lt;/strong&gt; の 2 点だけ。正直なところ、USB DAS（特に RAID なしの JBOD モデル）は選択肢が少なく、Amazon のレビューを見ても評価の高い製品がなかなか見つかりません。QNAP や Synology のような NAS アプライアンスと違って、「ただの箱」にあたる DAS はメーカーもユーザーも少なく、品質の当たり外れも大きい印象です。&lt;/p&gt;
&lt;p&gt;その中で ORICO を選んだ理由：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RAID 機能なしの JBOD モード&lt;/strong&gt; がある（RAID コントローラ付きのモデルは mergerfs と相性が悪い）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;4 ベイ&lt;/strong&gt; でデータ 3 台 + パリティ 1 台を収容可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;¥10,000 前後&lt;/strong&gt; と比較的安価&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ファン付き&lt;/strong&gt; で HDD の冷却ができる&lt;/li&gt;
&lt;li&gt;ORICO は USB ストレージ周辺機器メーカーとしてはそこそこ実績がある&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;「消去法で選んだ」感は否めませんが、数ヶ月使ってみて今のところ問題は出ていません。&lt;/p&gt;
&lt;p&gt;USB 3.0（5Gbps）で理論上 ~400MB/s。HDD 自体が 150〜200MB/s なのでボトルネックにはなりません。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;USB DAS は SATA 直結と比べると接続の信頼性は劣ります。ケーブルの抜けや電源トラブルには注意が必要です。&lt;code&gt;dmesg&lt;/code&gt; を定期的にチェックする運用が求められます。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h3&gt;コスト&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;パーツ&lt;/th&gt;
&lt;th&gt;モデル&lt;/th&gt;
&lt;th&gt;価格&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ミニ PC&lt;/td&gt;
&lt;td&gt;Beelink SER5 MAX（Ryzen 7 5800H / 16GB / 1TB）&lt;/td&gt;
&lt;td&gt;¥50,000（自宅サーバーを流用）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DAS&lt;/td&gt;
&lt;td&gt;ORICO 4ベイ HDD ケース（USB 3.0、RAID なし）&lt;/td&gt;
&lt;td&gt;¥10,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HDD（データ）&lt;/td&gt;
&lt;td&gt;4TB × 1 + 2TB × 2（手持ち）&lt;/td&gt;
&lt;td&gt;¥0（既存在庫）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HDD（パリティ）&lt;/td&gt;
&lt;td&gt;6TB × 1（新規購入）&lt;/td&gt;
&lt;td&gt;¥25,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;合計&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;¥85,000&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ミニ PC は自宅サーバーの流用なので、NAS 構築のための &lt;strong&gt;実質追加コストは約 35,000 円&lt;/strong&gt;（DAS + パリティ用 HDD）です。&lt;/p&gt;
&lt;p&gt;参考までに、QNAP TS-464（現行 4ベイモデル）を新品で買うと本体だけで ¥70,000〜90,000。HDD 4 本を足すと &lt;strong&gt;¥150,000 超え&lt;/strong&gt; になります。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;構成&lt;/th&gt;
&lt;th&gt;概算コスト&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;QNAP TS-464 + NAS用 HDD × 4&lt;/td&gt;
&lt;td&gt;~¥150,000〜170,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DIY（SER5 + ORICO + HDD）&lt;/td&gt;
&lt;td&gt;~¥85,000（うち流用 ¥50,000）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DIY 追加分のみ&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~¥35,000&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;データ量と HDD 構成&lt;/h2&gt;
&lt;h3&gt;保管しているデータ&lt;/h3&gt;
&lt;p&gt;主に一眼レフ（RAW）と iPhone の写真・動画です。現時点で約 2TB。&lt;/p&gt;
&lt;p&gt;24MP の一眼で RAW 1 枚あたり 25〜40MB、動画ファイルも含めるとそれなりの容量になります。8TB の利用可能容量があれば当面は余裕です。&lt;/p&gt;
&lt;h3&gt;ドライブ構成&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;/dev/sdb → /mnt/data1    (4TB)  [データ]
/dev/sdc → /mnt/data2    (2TB)  [データ]
/dev/sdd → /mnt/data3    (2TB)  [データ]
/dev/sda → /mnt/parity   (6TB)  [パリティ] ← 新規購入
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mergerfs で 4TB + 2TB + 2TB = &lt;strong&gt;8TB の利用可能容量&lt;/strong&gt;。SnapRAID のシングルパリティでどれか 1 台が壊れても復旧可能。&lt;/p&gt;
&lt;p&gt;RAID5 だと 2TB × 3（最小ドライブに合わせる）= 6TB にしかならないので、mergerfs のほうが &lt;strong&gt;2TB 多く&lt;/strong&gt; 使えます。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3-2-1 バックアップ戦略&lt;/h2&gt;
&lt;p&gt;ここで超重要なことを書きます。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;warning&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SnapRAID のパリティはバックアップではありません。&lt;/strong&gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;SnapRAID はドライブ故障からの &lt;strong&gt;冗長性&lt;/strong&gt; を提供しますが、以下のケースからは守ってくれません：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;誤削除&lt;/strong&gt; → sync が走ると削除がパリティに反映され、復旧不可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ランサムウェア&lt;/strong&gt; → 暗号化されたファイルが sync で記録される&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;火災・盗難&lt;/strong&gt; → 物理的にすべてのドライブが失われる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;sync 間の書き込み&lt;/strong&gt; → まだパリティに反映されていないデータ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;冗長性（= ドライブが壊れてもシステムが動き続ける）と、バックアップ（= どんな障害からもデータを復旧できる）は &lt;strong&gt;別物&lt;/strong&gt; です。両方必要です。&lt;/p&gt;
&lt;h3&gt;3-2-1 ルールとは&lt;/h3&gt;
&lt;p&gt;データ保護の基本原則として広く知られているルールです。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;意味&lt;/th&gt;
&lt;th&gt;今回の実装&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;3&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;データのコピーを &lt;strong&gt;3 つ&lt;/strong&gt; 持つ&lt;/td&gt;
&lt;td&gt;原本 + ローカルバックアップ + クラウド&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2 種類&lt;/strong&gt; 以上の異なるメディアに保存&lt;/td&gt;
&lt;td&gt;HDD アレイ + クラウドストレージ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1 つ&lt;/strong&gt; はオフサイト（物理的に離れた場所）&lt;/td&gt;
&lt;td&gt;AWS S3 Glacier&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;今回のバックアップ構成&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    subgraph &quot;自宅&quot;
        A[&quot;💾 原本&amp;lt;br/&amp;gt;mergerfs + SnapRAID アレイ&quot;] --&amp;gt;|rsync| B[&quot;🔌 ローカルバックアップ&amp;lt;br/&amp;gt;外付け USB HDD&amp;lt;br/&amp;gt;（普段は電源 OFF）&quot;]
    end
    A --&amp;gt;|&quot;rclone copy&amp;lt;br/&amp;gt;Glacier Deep Archive&quot;| C[&quot;☁️ オフサイト&amp;lt;br/&amp;gt;AWS S3 Glacier Deep Archive&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;なぜ &lt;code&gt;rclone copy&lt;/code&gt; なのか&lt;/h3&gt;
&lt;p&gt;クラウドバックアップのツールとして &lt;strong&gt;&lt;a href=&quot;https://rclone.org/&quot;&gt;rclone&lt;/a&gt;&lt;/strong&gt; を採用しています。rclone は &lt;strong&gt;クラウドストレージ向けの rsync&lt;/strong&gt; とも呼ばれるオープンソースの CLI ツールで、AWS S3、Google Cloud Storage、Backblaze B2 など 70 以上のクラウドストレージに対応しています。&lt;/p&gt;
&lt;p&gt;rclone には &lt;code&gt;copy&lt;/code&gt; と &lt;code&gt;sync&lt;/code&gt; の 2 つのモードがあります。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;コマンド&lt;/th&gt;
&lt;th&gt;動作&lt;/th&gt;
&lt;th&gt;リモートの削除&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rclone copy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ローカルにあるファイルをリモートにコピー&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;しない&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rclone sync&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ローカルとリモートを完全に同期（ミラーリング）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;する&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;今回は &lt;strong&gt;&lt;code&gt;copy&lt;/code&gt; を選択&lt;/strong&gt; しました。理由は明確で：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;誤削除からの保護。&lt;/strong&gt; &lt;code&gt;sync&lt;/code&gt; だとローカルで誤ってファイルを消した瞬間、次の同期でクラウドからも消えます。バックアップの意味がなくなる。&lt;code&gt;copy&lt;/code&gt; なら&lt;strong&gt;ローカルで削除してもクラウド側は残る&lt;/strong&gt;ので、「あの写真消しちゃった！」というときにクラウドから復旧できます&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ランサムウェア対策。&lt;/strong&gt; ランサムウェアにやられてローカルが暗号化されても、&lt;code&gt;copy&lt;/code&gt; なら暗号化前のファイルがクラウドに残っています。&lt;code&gt;sync&lt;/code&gt; だと暗号化されたファイルでクラウドが上書きされるリスクがあります&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;なぜ Glacier Deep Archive なのか&lt;/h3&gt;
&lt;p&gt;ストレージクラスは &lt;strong&gt;Glacier Deep Archive&lt;/strong&gt; を選択。理由：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;写真・動画は write-once データ。&lt;/strong&gt; 一度保存したらほぼ変更しない。頻繁にアクセスする必要もない。この特性は Glacier Deep Archive の「低頻度アクセス・長期保存」にぴったり合致します&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;圧倒的に安い。&lt;/strong&gt; S3 Standard の約 1/23 のコスト（~$1/TB/月 vs ~$23/TB/月）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;rclone から直接 PUT できる。&lt;/strong&gt; &lt;code&gt;--s3-storage-class DEEP_ARCHIVE&lt;/code&gt; を指定するだけ。ライフサイクルポリシーの設定は不要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;取り出しに 12〜48 時間かかりますが、これは「火災・盗難で物理ドライブが全滅したときの最終手段」なので問題ありません。&lt;/p&gt;
&lt;h3&gt;なぜサムネイルとドットファイルを除外するのか&lt;/h3&gt;
&lt;p&gt;バックアップ対象を &lt;strong&gt;写真・動画の本体データだけ&lt;/strong&gt; に絞っています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;thumbs/&lt;/code&gt;&lt;/strong&gt; — Immich などの写真管理ツールが生成するサムネイルキャッシュ。元データから再生成できるのでバックアップ不要&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;.*&lt;/code&gt;（ドットファイル）&lt;/strong&gt; — &lt;code&gt;.DS_Store&lt;/code&gt;、&lt;code&gt;.Thumbs.db&lt;/code&gt; などの OS やアプリが生成するメタデータ。これもバックアップ不要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これにより、バックアップ対象が約 2TB → &lt;strong&gt;約 1.5TB&lt;/strong&gt; に減少。年間のストレージコストが ¥900 程度削減されます。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;warning&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;初回バックアップ前にディレクトリ構造を整理してください。&lt;/strong&gt; rclone はファイルパスでリモートのファイルを管理しています。バックアップ開始後にディレクトリを &lt;code&gt;mv&lt;/code&gt; で移動すると、rclone は「旧パスのファイルが消えて、新パスに別のファイルが現れた」と認識します。結果として、同じファイルが新パスで再アップロードされ、旧パスのファイルは年次クリーンアップまでクラウドに残り続けます。つまり &lt;strong&gt;転送量と保管料が二重にかかります。&lt;/strong&gt; ディレクトリ構成の変更は初回バックアップの前に済ませておきましょう。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h3&gt;実際のコマンド&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;❯ rclone copy /mnt/storage s3-remote:nas-backup/ \
    --s3-storage-class DEEP_ARCHIVE \
    --exclude &quot;thumbs/**&quot; \
    --exclude &quot;.*&quot; \
    --transfers 4 --checkers 8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;rclone はファイルサイズとタイムスタンプで差分を検知するため、変更のないファイルは再転送されません。毎月実行しても、転送されるのは新しく追加された写真・動画だけです。&lt;/p&gt;
&lt;h3&gt;年 1 回のクリーンアップ&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;rclone copy&lt;/code&gt; はリモートのファイルを削除しないので、ローカルで整理・削除したファイルがクラウドに溜まり続けます。これを放置するとストレージコストが増え続けるので、年 1 回のクリーンアップを行います。&lt;/p&gt;
&lt;p&gt;ただし Glacier Deep Archive は &lt;strong&gt;最低保存期間が 180 日&lt;/strong&gt; で、180 日未満で削除すると残り期間分の料金が発生します。そこで、&lt;strong&gt;ローカルに存在せず、かつアップロードから 180 日以上経過したファイル&lt;/strong&gt; だけを削除対象にします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 1. S3 にあるがローカルに存在しないファイルを検出
❯ rclone lsf s3-remote:nas-backup/ -R &amp;gt; /tmp/remote.txt
❯ rclone lsf /mnt/storage/ -R --exclude &quot;thumbs/**&quot; --exclude &quot;.*&quot; &amp;gt; /tmp/local.txt
❯ comm -23 &amp;lt;(sort /tmp/remote.txt) &amp;lt;(sort /tmp/local.txt) &amp;gt; /tmp/orphaned.txt

# 2. 180 日以上経過したファイルだけ削除
❯ rclone delete s3-remote:nas-backup/ \
    --files-from /tmp/orphaned.txt \
    --min-age 180d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この運用なら：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;普段の &lt;code&gt;rclone copy&lt;/code&gt;&lt;/strong&gt; — 追加のみ。誤削除・ランサムウェアから保護&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;年 1 回のクリーンアップ&lt;/strong&gt; — 本当に不要になったファイルだけ削除。180 日ルールに抵触しない&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;結果&lt;/strong&gt; — クラウド上には「ローカルに存在するファイル + 削除後 180 日未満のファイル」だけが残り、コストが膨らみ続けることはない&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;クラウドバックアップのコスト見積もり&lt;/h3&gt;
&lt;p&gt;サムネイルやドットファイルを除外すると、実際のバックアップ対象は写真・動画データの約 1.5TB 程度になります。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;サービス&lt;/th&gt;
&lt;th&gt;ストレージ単価&lt;/th&gt;
&lt;th&gt;月額（1.5TB）&lt;/th&gt;
&lt;th&gt;年額&lt;/th&gt;
&lt;th&gt;取り出し&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS S3 Glacier Deep Archive&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~$1/TB/月&lt;/td&gt;
&lt;td&gt;~$1.5（≒ ¥225）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;≒ ¥2,700&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;取り出しに 12〜48 時間、別途料金&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backblaze B2&lt;/td&gt;
&lt;td&gt;$6/TB/月&lt;/td&gt;
&lt;td&gt;~$9（≒ ¥1,350）&lt;/td&gt;
&lt;td&gt;≒ ¥16,200&lt;/td&gt;
&lt;td&gt;即時アクセス、3× ストレージまで egress 無料&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS S3 Standard&lt;/td&gt;
&lt;td&gt;$23/TB/月&lt;/td&gt;
&lt;td&gt;~$34.5（≒ ¥5,175）&lt;/td&gt;
&lt;td&gt;≒ ¥62,100&lt;/td&gt;
&lt;td&gt;即時アクセス&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;rclone copy&lt;/code&gt; で月 1 回の差分転送なら、PUT リクエストは毎月の新規ファイル分だけ（月数百〜数千件程度）。API コストはほぼ無視できます。&lt;/p&gt;
&lt;p&gt;アーカイブ用途で「普段は取り出さない、災害時の最終手段」と割り切るなら &lt;strong&gt;Glacier Deep Archive が圧倒的に安い&lt;/strong&gt; です。年額 ¥3,000 以下で 3-2-1 ルールのオフサイトコピーを実現できます。&lt;/p&gt;
&lt;h3&gt;ランニングコストの全体像&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;月額&lt;/th&gt;
&lt;th&gt;年額&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;電気代（ミニ PC + DAS、~30W 平均）&lt;/td&gt;
&lt;td&gt;≒ ¥650&lt;/td&gt;
&lt;td&gt;≒ ¥7,800&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;クラウドバックアップ（Glacier Deep Archive）&lt;/td&gt;
&lt;td&gt;≒ ¥225&lt;/td&gt;
&lt;td&gt;≒ ¥2,700&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;合計&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;≒ ¥875&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;≒ ¥10,500&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;比較として、QNAP TS-431P は公称消費電力 36W（HDD 4 台搭載時）ですが、HDD がスタンバイに入らない問題があったので実質もう少し高いはず。加えて QNAP のクラウドバックアップ機能を使うにしても別途クラウドストレージ費用がかかります。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;実際の設定&lt;/h2&gt;
&lt;p&gt;ここからは実際に構築した設定ファイルを掲載します。OS は &lt;strong&gt;Ubuntu 24.04 LTS&lt;/strong&gt; です。&lt;/p&gt;
&lt;h3&gt;ディスクのマウント&lt;/h3&gt;
&lt;p&gt;各 HDD を UUID で個別にマウントします。USB DAS は接続順でデバイス名が変わることがあるため、UUID 指定が必須です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ lsblk -o NAME,SIZE,FSTYPE,UUID,MOUNTPOINT
NAME   SIZE FSTYPE UUID                                 MOUNTPOINT
sda    5.4T ext4   xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /mnt/parity
sdb    3.6T ext4   yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy /mnt/data1
sdc    1.8T ext4   zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz /mnt/data2
sdd    1.8T ext4   wwwwwwww-wwww-wwww-wwww-wwwwwwwwwwww /mnt/data3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;/etc/fstab&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# --- データドライブ ---
UUID=yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy /mnt/data1    ext4 defaults,nofail 0 2
UUID=zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz /mnt/data2    ext4 defaults,nofail 0 2
UUID=wwwwwwww-wwww-wwww-wwww-wwwwwwwwwwww /mnt/data3    ext4 defaults,nofail 0 2

# --- パリティドライブ ---
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /mnt/parity  ext4 defaults,nofail 0 2

# --- mergerfs プール ---
/mnt/data1:/mnt/data2:/mnt/data3 /mnt/storage fuse.mergerfs defaults,allow_other,use_ino,cache.files=off,moveonenospc=true,dropcacheonclose=true,minfreespace=20G,category.create=mfs,fsname=mergerfs 0 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;nofail&lt;/code&gt; は USB DAS の起動が OS のブートより遅れても起動が止まらないようにするためのオプションです。USB 接続では必須。&lt;/p&gt;
&lt;h3&gt;mergerfs のポリシー&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;category.create=mfs&lt;/code&gt;（most free space）は mergerfs の &lt;strong&gt;デフォルトポリシー&lt;/strong&gt; で、空き容量が最も大きいドライブに新規ファイルを書き込みます。特にこだわりがないので、まずはデフォルトのままで運用してみることにしました。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ポリシー&lt;/th&gt;
&lt;th&gt;動作&lt;/th&gt;
&lt;th&gt;ユースケース&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mfs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;空き容量が最大のドライブに書き込み&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;今回採用。&lt;/strong&gt; ドライブ間で均等に分散&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;epmfs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;既存パスがあるドライブ優先、なければ mfs&lt;/td&gt;
&lt;td&gt;ディレクトリ構造を維持したい場合&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lfs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;空きが最小のドライブに書き込み&lt;/td&gt;
&lt;td&gt;1 台ずつ順番に埋めたい場合&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;moveonenospc=true&lt;/code&gt; は書き込み先が満杯の場合に自動で別ドライブにリトライする設定。&lt;code&gt;minfreespace=20G&lt;/code&gt; で各ドライブを使い切らないようにガードします。&lt;/p&gt;
&lt;h3&gt;SnapRAID の設定&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;❯ sudo apt install snapraid
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;/etc/snapraid.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# パリティファイルの場所
parity /mnt/parity/snapraid.parity

# コンテンツファイル（複数ドライブに分散配置を推奨）
content /var/snapraid/snapraid.content
content /mnt/data1/.snapraid.content
content /mnt/data2/.snapraid.content
content /mnt/data3/.snapraid.content

# データドライブ
data d1 /mnt/data1/
data d2 /mnt/data2/
data d3 /mnt/data3/

# 除外パターン
exclude *.unrecoverable
exclude /tmp/
exclude /lost+found/
exclude .DS_Store
exclude .Thumbs.db
exclude .snapraid.content

# 250GB ごとに中間セーブ（初回 sync 中に中断しても途中から再開可能）
autosave 250
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;コンテンツファイルは SnapRAID のメタデータで、&lt;strong&gt;最低 2 箇所&lt;/strong&gt; に配置する必要があります。パリティドライブ以外のデータドライブに分散させるのがベストプラクティスです。&lt;/p&gt;
&lt;p&gt;初回の sync:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ sudo snapraid sync
Self test...
Loading state from /var/snapraid/snapraid.content...
Scanning disk d1...
Scanning disk d2...
Scanning disk d3...
...
Syncing...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初回は全データのハッシュ計算が走るのでそれなりに時間がかかります。&lt;code&gt;autosave 250&lt;/code&gt; のおかげで 250GB ごとに中間保存されるので、途中で中断しても最初からやり直しにはなりません。&lt;/p&gt;
&lt;h3&gt;SnapRAID の自動化&lt;/h3&gt;
&lt;p&gt;毎日深夜に sync + scrub を自動実行します。安全のため、&lt;strong&gt;大量削除を検知したら sync を中止する&lt;/strong&gt; しきい値を設けます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/usr/local/bin/snapraid-sync.sh&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
set -euo pipefail

THRESHOLD=250
LOG=&quot;/var/log/snapraid-sync.log&quot;

echo &quot;=== SnapRAID sync started at $(date) ===&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;

# diff で変更量を確認
DIFF_OUTPUT=$(snapraid diff 2&amp;gt;&amp;amp;1)
REMOVED=$(echo &quot;$DIFF_OUTPUT&quot; | grep -E &apos;removed&apos; | awk &apos;{print $1}&apos; || echo &quot;0&quot;)

if [ &quot;$REMOVED&quot; -gt &quot;$THRESHOLD&quot; ]; then
    echo &quot;WARNING: $REMOVED files removed (threshold: $THRESHOLD). Sync aborted.&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;
    # ここに通知処理を追加（メール、Discord webhook など）
    exit 1
fi

snapraid sync &amp;gt;&amp;gt; &quot;$LOG&quot; 2&amp;gt;&amp;amp;1

# 30日以上前にチェックしたデータの 8% をスクラブ
snapraid scrub -p 8 -o 30 &amp;gt;&amp;gt; &quot;$LOG&quot; 2&amp;gt;&amp;amp;1

echo &quot;=== SnapRAID sync completed at $(date) ===&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;❯ sudo chmod +x /usr/local/bin/snapraid-sync.sh
❯ sudo crontab -e
# 毎日 AM 3:00 に実行
0 3 * * * /usr/local/bin/snapraid-sync.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;削除しきい値（&lt;code&gt;THRESHOLD=250&lt;/code&gt;）がポイントです。ランサムウェアに感染してファイルが大量に暗号化・削除されたケースでは、&lt;code&gt;snapraid diff&lt;/code&gt; が異常な削除数を検出して sync を止めてくれます。パリティが上書きされる前に対処できるわけです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;scrub -p 8 -o 30&lt;/code&gt; は「30 日以上前にチェックしたデータのうち 8% をスクラブ」。毎日実行すれば約 2 週間でアレイ全体を 1 巡し、ビットロットを早期発見できます。&lt;/p&gt;
&lt;h3&gt;Samba によるネットワーク共有&lt;/h3&gt;
&lt;p&gt;LAN 内の他のマシンから mergerfs プールにアクセスするための設定です。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/samba/smb.conf&lt;/code&gt;（抜粋）:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[pool]
   comment = mergerfs pool
   path = /mnt/storage
   browseable = yes
   read only = no
   valid users = @smbusers
   create mask = 0664
   directory mask = 0775
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;❯ sudo useradd -M -s /usr/sbin/nologin smbuser
❯ sudo smbpasswd -a smbuser
❯ sudo usermod -aG smbusers smbuser
❯ sudo systemctl restart smbd
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;rclone によるクラウドバックアップの設定&lt;/h3&gt;
&lt;h4&gt;rclone のインストールとリモート設定&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;❯ sudo apt install rclone
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;S3 リモートを設定します。&lt;code&gt;rclone config&lt;/code&gt; は対話式で進みます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ rclone config

# 以下の順で入力:
# n) New remote
# name&amp;gt; s3-remote
# Storage&amp;gt; s3
# provider&amp;gt; AWS
# env_auth&amp;gt; false
# access_key_id&amp;gt; （IAM ユーザーの Access Key ID）
# secret_access_key&amp;gt; （IAM ユーザーの Secret Access Key）
# region&amp;gt; ap-northeast-1
# endpoint&amp;gt; （空欄のまま Enter）
# location_constraint&amp;gt; ap-northeast-1
# acl&amp;gt; private
# storage_class&amp;gt; DEEP_ARCHIVE
# （残りはデフォルトのまま Enter）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IAM ユーザーには以下のポリシーを付与しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [{
    &quot;Effect&quot;: &quot;Allow&quot;,
    &quot;Action&quot;: [&quot;s3:PutObject&quot;, &quot;s3:GetObject&quot;, &quot;s3:ListBucket&quot;, &quot;s3:DeleteObject&quot;],
    &quot;Resource&quot;: [
      &quot;arn:aws:s3:::nas-backup&quot;,
      &quot;arn:aws:s3:::nas-backup/*&quot;
    ]
  }]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;設定が完了したら動作確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# リモートへの接続テスト
❯ rclone lsd s3-remote:

# バケットがなければ作成
❯ rclone mkdir s3-remote:nas-backup

# dry-run でバックアップ対象を確認（実際には転送しない）
❯ rclone copy /mnt/storage s3-remote:nas-backup/ \
    --s3-storage-class DEEP_ARCHIVE \
    --exclude &quot;thumbs/**&quot; \
    --exclude &quot;.*&quot; \
    --dry-run -v
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;バックアップスクリプト&lt;/h4&gt;
&lt;p&gt;月次バックアップスクリプト（&lt;code&gt;/usr/local/bin/backup-cloud.sh&lt;/code&gt;）:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
set -euo pipefail

LOG=&quot;/var/log/backup-cloud.log&quot;
REMOTE=&quot;s3-remote:nas-backup&quot;
LOCK=&quot;/var/run/backup-cloud.lock&quot;

# 多重起動の防止
if [ -f &quot;$LOCK&quot; ]; then
    echo &quot;ERROR: Backup already running (lockfile exists)&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;
    exit 1
fi
trap &apos;rm -f &quot;$LOCK&quot;&apos; EXIT
touch &quot;$LOCK&quot;

echo &quot;=== Cloud backup started at $(date) ===&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;

# rclone copy: 新規・変更ファイルだけアップロード、リモートのファイルは削除しない
rclone copy /mnt/storage &quot;$REMOTE&quot; \
    --s3-storage-class DEEP_ARCHIVE \
    --exclude &quot;thumbs/**&quot; \
    --exclude &quot;.*&quot; \
    --transfers 4 \
    --checkers 8 \
    --bwlimit 50M \
    --log-file &quot;$LOG&quot; \
    --log-level INFO \
    --stats 1h \
    --stats-log-level INFO \
    &amp;amp;&amp;amp; echo &quot;=== Cloud backup completed successfully at $(date) ===&quot; &amp;gt;&amp;gt; &quot;$LOG&quot; \
    || { echo &quot;=== Cloud backup FAILED at $(date) ===&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;; exit 1; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;スクリプトのポイント：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--bwlimit 50M&lt;/code&gt;&lt;/strong&gt; — 帯域を 50MB/s に制限。バックアップ中に他のネットワーク通信が遅くならないようにします。回線速度に応じて調整してください&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ロックファイル&lt;/strong&gt; — &lt;code&gt;backup-cloud.lock&lt;/code&gt; で多重起動を防止。初回の 1.5TB アップロードは数時間以上かかるため、cron の次の実行と重複しないようにします&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--stats 1h&lt;/code&gt;&lt;/strong&gt; — 1 時間ごとに転送状況をログに出力。長時間実行の進捗がわかります&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;❯ sudo chmod +x /usr/local/bin/backup-cloud.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;クリーンアップスクリプト&lt;/h4&gt;
&lt;p&gt;年次クリーンアップスクリプト（&lt;code&gt;/usr/local/bin/backup-cleanup.sh&lt;/code&gt;）:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
set -euo pipefail

LOG=&quot;/var/log/backup-cloud.log&quot;
REMOTE=&quot;s3-remote:nas-backup&quot;

echo &quot;=== Cleanup started at $(date) ===&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;

# S3 上のファイル一覧を取得
rclone lsf &quot;$REMOTE&quot; -R &amp;gt; /tmp/remote-files.txt

# ローカルのファイル一覧を取得（バックアップと同じ exclude ルールを適用）
rclone lsf /mnt/storage/ -R \
    --exclude &quot;thumbs/**&quot; \
    --exclude &quot;.*&quot; &amp;gt; /tmp/local-files.txt

# S3 にあるがローカルに存在しないファイルを抽出
comm -23 &amp;lt;(sort /tmp/remote-files.txt) &amp;lt;(sort /tmp/local-files.txt) &amp;gt; /tmp/orphaned-files.txt

ORPHAN_COUNT=$(wc -l &amp;lt; /tmp/orphaned-files.txt)
echo &quot;Found $ORPHAN_COUNT orphaned files&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;

if [ &quot;$ORPHAN_COUNT&quot; -gt 0 ]; then
    # 180 日以上経過したファイルだけ削除（Glacier の最低保存期間を回避）
    rclone delete &quot;$REMOTE&quot; \
        --files-from /tmp/orphaned-files.txt \
        --min-age 180d \
        --log-file &quot;$LOG&quot; \
        --log-level INFO
fi

# 一時ファイルの削除
rm -f /tmp/remote-files.txt /tmp/local-files.txt /tmp/orphaned-files.txt

echo &quot;=== Cleanup completed at $(date) ===&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;❯ sudo chmod +x /usr/local/bin/backup-cleanup.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;cron 設定&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;❯ sudo crontab -e
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# --- SnapRAID ---
# 毎日 AM 3:00 に sync + scrub
0 3 * * * /usr/local/bin/snapraid-sync.sh

# --- クラウドバックアップ ---
# 毎月 1 日 AM 4:00 に rclone copy（SnapRAID sync の後に実行）
0 4 1 * * /usr/local/bin/backup-cloud.sh

# 毎年 1 月 15 日 AM 4:00 にクリーンアップ（1 日のバックアップ完了後に実行）
0 4 15 1 * /usr/local/bin/backup-cleanup.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SnapRAID sync（AM 3:00）→ rclone copy（AM 4:00）の順番にしています。sync が完了してパリティが最新になった状態でクラウドバックアップを実行するためです。&lt;/p&gt;
&lt;h3&gt;ドライブの監視&lt;/h3&gt;
&lt;p&gt;SMART データの監視を設定しています。Reallocated Sector Count や Current Pending Sector が増加傾向にあるドライブは早めに交換する判断材料になります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ sudo apt install smartmontools

# 各ドライブの SMART 情報を確認
❯ sudo smartctl -a /dev/sda
❯ sudo smartctl -a /dev/sdb
❯ sudo smartctl -a /dev/sdc
❯ sudo smartctl -a /dev/sdd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Zabbix などの監視ツールでカスタム UserParameter を設定し、温度やセクタエラーの推移を記録しておくと、障害の予兆を捉えやすくなります。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;運用してみての所感&lt;/h2&gt;
&lt;h3&gt;良かったこと&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;HDD がちゃんとスタンバイに入る。&lt;/strong&gt; QNAP の謎のアクセスランプ点滅から解放されました。使っていない時間帯は静かで、電気代も下がった実感があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;異なる容量のドライブを無駄なく使い切れる。&lt;/strong&gt; RAID5 だと 2TB に揃えなきゃいけなかったところ、手持ちの 4TB + 2TB + 2TB がそのまま 8TB として活きています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;壊れても理解できる。&lt;/strong&gt; mergerfs + SnapRAID の仕組みはシンプルなので、何か問題が起きても &lt;code&gt;dmesg&lt;/code&gt; と &lt;code&gt;snapraid status&lt;/code&gt; を見れば状況が分かります。QNAP の QTS や PowerEdge の RAID コントローラではこうはいかなかった。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1 台壊れても慌てない安心感。&lt;/strong&gt; 仮に disk2 が死んでも、disk1 と disk3 のファイルはそのまま ext4 として読めます。PowerEdge で RAID カード障害を経験した身としては、この安心感は本当に大きい。&lt;/p&gt;
&lt;h3&gt;注意点・トレードオフ&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;mergerfs の CPU 使用率がそこそこある。&lt;/strong&gt; これは運用してみて気づいたことですが、mergerfs は FUSE（ユーザー空間ファイルシステム）で動作するため、ファイルアクセスのたびにカーネル空間とユーザー空間を往復するオーバーヘッドがあります。&lt;code&gt;btop&lt;/code&gt; で見ると、特に大量のファイルを読み書きしている時に mergerfs プロセスが CPU をそれなりに食っているのが分かります。Ryzen 7 5800H なら実用上問題にはなりませんが、Raspberry Pi のような低スペック環境だとボトルネックになる可能性があります。mergerfs の開発者も「CPU を使っているように見えるが、実際にはリクエストのディスパッチがほとんど」と説明しており、実 I/O に比べれば軽微とのこと。とはいえ、カーネルモジュールとして実装された場合と比べるとオーバーヘッドがあるのは事実です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;USB DAS の信頼性。&lt;/strong&gt; SATA 直結と比べると USB 接続はどうしても一段劣ります。ケーブルの抜けや DAS の電源トラブルには注意が必要で、&lt;code&gt;dmesg&lt;/code&gt; を定期的にチェックする運用が求められます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SnapRAID はリアルタイム保護ではない。&lt;/strong&gt; sync の間隔（今回は 1 日 1 回）の分だけデータ損失リスクがあります。重要な写真を大量に取り込んだ直後は手動で &lt;code&gt;snapraid sync&lt;/code&gt; を走らせるのが安心です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GUI がない。&lt;/strong&gt; QNAP の QTS のような Web UI はありません。すべて CLI です。Linux に慣れていない人にはハードルが高いですが、逆に言えばすべてテキストファイルで設定が完結するので、バージョン管理やドキュメント化がしやすいです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;初期セットアップの手間。&lt;/strong&gt; QNAP は箱から出して 30 分で使い始められますが、この構成は数時間〜数日かかります。そのぶん自由度と「何が起きているか理解できる」度は桁違いです。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;mergerfs FAQ&lt;/h2&gt;
&lt;p&gt;mergerfs + SnapRAID の運用事例はあまり記事になっていなかったので、運用していく中で自分が気になったことをチェックリストとしてまとめておきます。&lt;/p&gt;
&lt;h3&gt;Q. ドライブが 1 台壊れたらどうなる？&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;mergerfs プール自体は動き続けます。&lt;/strong&gt; 壊れたドライブに載っていたファイルにアクセスするとエラーになりますが、他のドライブのファイルは何事もなく読み書きできます。RAID5 のように「アレイが degraded になって全体のパフォーマンスが落ちる」ということはありません。&lt;/p&gt;
&lt;p&gt;復旧手順としては、壊れたドライブを新しいドライブに交換し、SnapRAID の &lt;code&gt;fix&lt;/code&gt; コマンドでパリティからデータを復元します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 新しいドライブをフォーマットしてマウント
❯ sudo mkfs.ext4 /dev/sdX
❯ sudo mount /dev/sdX /mnt/data2

# SnapRAID でデータを復元
❯ sudo snapraid fix -d d2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Q. 新しいドライブを追加するには？&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;fstab を 1 行書き換えるだけ&lt;/strong&gt; です。mergerfs のソースパスに新しいドライブを追加して &lt;code&gt;mount -a&lt;/code&gt; するか、再マウントすれば即座に反映されます。RAID のような再構築は一切不要。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 例: /mnt/data4 を追加
❯ sudo mkfs.ext4 /dev/sdX
❯ sudo mkdir /mnt/data4
❯ sudo mount /dev/sdX /mnt/data4

# fstab の mergerfs 行を編集
/mnt/data1:/mnt/data2:/mnt/data3:/mnt/data4 /mnt/storage fuse.mergerfs ...

# 再マウント
❯ sudo umount /mnt/storage &amp;amp;&amp;amp; sudo mount -a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SnapRAID 側も &lt;code&gt;/etc/snapraid.conf&lt;/code&gt; に &lt;code&gt;data d4 /mnt/data4/&lt;/code&gt; を追加して &lt;code&gt;snapraid sync&lt;/code&gt; を実行すればOK。&lt;/p&gt;
&lt;p&gt;ライブで追加したい場合は &lt;code&gt;mergerfs.ctl&lt;/code&gt; や &lt;code&gt;xattr&lt;/code&gt; 経由で再マウントなしに追加できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ sudo xattr -w user.mergerfs.srcmounts +/mnt/data4 /mnt/storage/.mergerfs
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Q. ドライブを取り外すには？&lt;/h3&gt;
&lt;p&gt;mergerfs は &lt;strong&gt;ドライブ取り外し時にデータを自動移動しません。&lt;/strong&gt; 手動でデータを退避する必要があります。&lt;/p&gt;
&lt;p&gt;ポイントは &lt;strong&gt;先にプールから除外してから rsync する&lt;/strong&gt; ことです。除外前に rsync すると、コピー先の &lt;code&gt;/mnt/storage/&lt;/code&gt; に取り外し対象ドライブ自身が含まれているため、ファイルが「既に存在する」と判定されてコピーがスキップされてしまいます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 1. mergerfs からドライブを除外（プール上でこのドライブのファイルが見えなくなる）
❯ sudo xattr -w user.mergerfs.srcmounts -/mnt/data3 /mnt/storage/.mergerfs

# 2. 除外したドライブのデータをプールにコピー（他のドライブに書き込まれる）
❯ sudo rsync -avxHAXWE --numeric-ids --info=progress2 /mnt/data3/ /mnt/storage/

# 3. コピー漏れがないか dry-run で確認（出力がなければ OK）
❯ sudo rsync -avxHAXWE --numeric-ids --dry-run /mnt/data3/ /mnt/storage/

# 4. ドライブをアンマウント
❯ sudo umount /mnt/data3

# 5. fstab から該当行を削除し、SnapRAID の設定から d3 を削除して再 sync
❯ sudo snapraid sync
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;プール全体に十分な空き容量がある前提です（取り外すドライブの使用量 &amp;lt; 残りドライブの空き容量）。ドライブの容量アップグレード（2TB → 4TB に交換など）もこの手順で対応できます。&lt;/p&gt;
&lt;h3&gt;Q. あるファイルがどのドライブに保存されているか確認できる？&lt;/h3&gt;
&lt;p&gt;できます。mergerfs はファイル単位で保存先が分かれるので、物理的にどこにあるか確認したい場合は個別のマウントポイントを &lt;code&gt;find&lt;/code&gt; で探します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /mnt/storage/photos/2024/IMG_001.RAF がどのドライブにあるか
❯ find /mnt/data1 /mnt/data2 /mnt/data3 -path &quot;*/photos/2024/IMG_001.RAF&quot;
/mnt/data1/photos/2024/IMG_001.RAF
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Q. ext4 と xfs など異なるファイルシステムを混在できる？&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;できます。&lt;/strong&gt; mergerfs はファイルシステムの種類に依存しません。ext4 と xfs を混在させても問題なく動作します。ただし、運用のシンプルさを考えると統一しておくのが無難です。NTFS や FAT のような非 POSIX ファイルシステムはパーミッションの問題が出る可能性があるので非推奨。&lt;/p&gt;
&lt;h3&gt;Q. mergerfs 自体がクラッシュしたらデータは消える？&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;消えません。&lt;/strong&gt; mergerfs はデータを変換・加工しているわけではなく、既存のファイルシステムの上にマウントポイントを仮想的に統合しているだけです。mergerfs が落ちたら &lt;code&gt;/mnt/storage&lt;/code&gt; にアクセスできなくなりますが、各ドライブ（&lt;code&gt;/mnt/data1&lt;/code&gt;, &lt;code&gt;/mnt/data2&lt;/code&gt;, &lt;code&gt;/mnt/data3&lt;/code&gt;）は普通の ext4 なので、そのままマウントしてファイルにアクセスできます。&lt;/p&gt;
&lt;p&gt;最悪の場合、mergerfs を一切使わなくても全データにアクセスできるというのが、RAID に対する最大のメリットの 1 つです。&lt;/p&gt;
&lt;h3&gt;Q. Docker のボリュームとして mergerfs プールを使える？&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;使えます。&lt;/strong&gt; Docker の &lt;code&gt;volumes&lt;/code&gt; に &lt;code&gt;/mnt/storage&lt;/code&gt; のパスをそのまま指定すれば OK です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;volumes:
  - /mnt/storage/data:/app/data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ただし、データベース（PostgreSQL、MySQL など）のデータディレクトリを mergerfs 上に置くのは &lt;strong&gt;非推奨&lt;/strong&gt; です。データベースは小さなファイルを頻繁に読み書きするワークロードで、FUSE のオーバーヘッドがパフォーマンスに影響します。データベースのデータは SSD（OS ドライブ）に置いて、mergerfs プールには写真やメディアなどの大きなファイルを保存する、という使い分けがおすすめです。&lt;/p&gt;
&lt;h3&gt;Q. パフォーマンスはどのくらい出る？&lt;/h3&gt;
&lt;p&gt;シーケンシャルな Read/Write であれば、&lt;strong&gt;ほぼディスクネイティブの速度&lt;/strong&gt; が出ます。USB 3.0 接続の HDD で 150〜200MB/s 程度。mergerfs のオーバーヘッドよりも HDD や USB の帯域がボトルネックになるので、実質的な速度低下は体感しにくいです。&lt;/p&gt;
&lt;p&gt;ただし、&lt;strong&gt;大量の小さなファイルを扱うメタデータ操作&lt;/strong&gt;（&lt;code&gt;find&lt;/code&gt;、&lt;code&gt;ls -R&lt;/code&gt;、&lt;code&gt;du&lt;/code&gt; など）は FUSE のオーバーヘッドが効いてきます。ファイルアクセスのたびにカーネル↔ユーザー空間を往復するので、ファイル数が多いディレクトリでは遅延を感じることがあります。写真やメディアファイルのような「数は多いが個々のファイルは大きい」ワークロードなら問題になることは少ないです。&lt;/p&gt;
&lt;h3&gt;Q. 1 台が壊れたとき、他のディスクに新しい書き込みがあってもパリティから復元できる？&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;最後に &lt;code&gt;snapraid sync&lt;/code&gt; が成功した時点のデータは復元できます。&lt;/strong&gt; ただし、いくつか注意点があります。&lt;/p&gt;
&lt;p&gt;SnapRAID のパリティはリアルタイムではなく &lt;strong&gt;スナップショットベース&lt;/strong&gt; です。パリティが保護しているのは「最後の sync 時点でのデータ」なので、sync 後に他のディスクへ書き込みがあっても、壊れたディスクの復元には影響しません。パリティ計算のベースラインが変わっていないからです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    A[&quot;最後の sync 完了&amp;lt;br/&amp;gt;（パリティ計算済み）&quot;] --&amp;gt; B[&quot;他のディスクに&amp;lt;br/&amp;gt;新規ファイル追加&quot;]
    B --&amp;gt; C[&quot;disk2 が故障 💥&quot;]
    C --&amp;gt; D[&quot;snapraid fix -d d2&amp;lt;br/&amp;gt;✅ 最後の sync 時点の&amp;lt;br/&amp;gt;データは復元可能&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;絶対にやってはいけないこと：故障したディスクがある状態で &lt;code&gt;snapraid sync&lt;/code&gt; を実行すること。&lt;/strong&gt; sync を実行すると、壊れたディスクの欠損を「正しい状態」としてパリティが再計算されてしまい、復元できなくなります。&lt;strong&gt;必ず &lt;code&gt;fix&lt;/code&gt; → ディスク交換 → &lt;code&gt;sync&lt;/code&gt; の順番&lt;/strong&gt; を守ってください。&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-mixed-period */}
まとめると：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;状況&lt;/th&gt;
&lt;th&gt;復元&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;sync 後、他ディスクへの書き込みなし&lt;/td&gt;
&lt;td&gt;✅ 完全復元&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sync 後、他ディスクへの新規ファイル追加あり&lt;/td&gt;
&lt;td&gt;✅ 壊れたディスクは sync 時点で復元可能。新規ファイルはパリティ未保護&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sync 後、他ディスクの既存ファイルを変更&lt;/td&gt;
&lt;td&gt;⚠️ 壊れたディスクの復元精度が下がる可能性あり（変更されたファイルとパリティの整合性がずれるため）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;故障後に sync を実行してしまった&lt;/td&gt;
&lt;td&gt;❌ 復元不可能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;{/* textlint-enable ja-technical-writing/ja-no-mixed-period */}&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;運用のコツとしては、ディスク故障に気づいたら &lt;strong&gt;すぐに自動 sync の cron を止めて、&lt;code&gt;snapraid fix&lt;/code&gt; を実行する&lt;/strong&gt; ことです。自動化スクリプトで &lt;code&gt;snapraid diff&lt;/code&gt; の結果をチェックしてディスク異常を検知→ sync を中止する仕組みを入れておくと安心です（本記事の自動化スクリプトでは削除しきい値でこれに近い保護をしています）。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Dell PowerEdge T320（ハードウェア RAID）→ QNAP TS-431P（ソフトウェア RAID）→ &lt;strong&gt;mergerfs + SnapRAID on Ubuntu 24.04&lt;/strong&gt; と渡り歩いてきて、ようやく「壊れても理解できる」ストレージ構成にたどり着きました。&lt;/p&gt;
&lt;p&gt;3 世代の経験から言えるのは：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ハードウェア RAID はコントローラが SPOF。&lt;/strong&gt; 壊れたら詰む&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NAS アプライアンスは便利だが、ベンダーロックインと品質のばらつきがある。&lt;/strong&gt; 特に周辺アプリの完成度は過信できない&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;mergerfs + SnapRAID は「理解できるシンプルさ」が最大の価値。&lt;/strong&gt; 各ドライブが普通の ext4 で読めるという安心感は他に替えがたい&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SnapRAID はバックアップではない。&lt;/strong&gt; 3-2-1 ルールに基づくオフサイトバックアップは別途必須。Glacier Deep Archive なら年額 ¥3,000 以下で実現可能&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CLI 運用と USB DAS の割り切りが必要なので万人向けとは言えませんが、NAS のブラックボックスに不安を感じている人、過去に RAID で痛い目に遭った人には自信を持っておすすめできます。&lt;/p&gt;
&lt;p&gt;次回の記事では、この NAS 上に構築した &lt;strong&gt;写真管理環境&lt;/strong&gt;（Immich）について書く予定です。&lt;/p&gt;
</content:encoded></item><item><title>DAIKINエアコン3回目の修理 | 基盤交換で無償対応</title><link>https://blog.teraren.com/posts/2026-01-23-daikin-air-conditioner-repair-3rd/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2026-01-23-daikin-air-conditioner-repair-3rd/</guid><description>DAIKINエアコンの暖房が停止する問題が発生し、3回目の修理依頼。エラーコードから基盤故障が判明し、保証期間外だが無償で基盤交換してもらえた記録。</description><pubDate>Fri, 23 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;稼働し始めて数年が経過したDAIKINのエアコンで、暖房がすぐに停止してしまう問題が発生しました。&lt;/p&gt;
&lt;p&gt;これで修理依頼は3回目です。&lt;/p&gt;
&lt;h2&gt;前回の修理&lt;/h2&gt;
&lt;p&gt;半年ほど前にクーラーが途中で止まってしまう問題があったので、修理の調査に来てもらいました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/2025-07-31-daikin-air-conditioner/&quot;&gt;ダイキンエアコンAN71VRP-W修理 | 原因不明で5,000円&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;しかし、原因不明なまま症状が直ってしまい、結局何も対処せず終わりました。&lt;/p&gt;
&lt;h2&gt;今回の問題&lt;/h2&gt;
&lt;p&gt;今度は、暖房がすぐに停止する問題が発生。&lt;/p&gt;
&lt;p&gt;冬なので暖房が使えないのは困るため、すぐに修理を依頼しました。&lt;/p&gt;
&lt;h2&gt;修理の流れ&lt;/h2&gt;
&lt;p&gt;前回と同じようにオンラインで修理依頼をしました。&lt;/p&gt;
&lt;p&gt;2日後に修理の人が訪問。&lt;/p&gt;
&lt;h3&gt;エラーコード確認&lt;/h3&gt;
&lt;p&gt;今回はエラーコードが出力されていたので、基盤が問題ということが特定できたとのことでした。&lt;/p&gt;
&lt;p&gt;前回はエラーコードが出ていなかったので原因特定が難しかったようですが、今回は明確にエラーが記録されていたため、すぐに問題箇所が判明しました。&lt;/p&gt;
&lt;h3&gt;作業内容&lt;/h3&gt;
&lt;p&gt;作業内容は&lt;strong&gt;基盤交換&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;保証期限ははるか昔に切れていましたが、なぜか&lt;strong&gt;無料で対応&lt;/strong&gt;してもらえました。&lt;/p&gt;
&lt;p&gt;半年前の修理のときには、「基盤が怪しいけど交換するとなると数万円は自費修理になる」という話でしたが、今回は無償でやってもらえてよかったです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2026/01/repair-receipt.png&quot; alt=&quot;修理完了の記録&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;このエアコンで修理に来てもらうのは3回目。&lt;/p&gt;
&lt;p&gt;夏はほとんど入れっぱなし。冬は電気オイルヒーターを使っているのでたまにしか使わないぐらいなのに、修理頻度が高すぎます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;無駄に高機能なエアコンは買わないほうが良いですね&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;とはいえ、部屋の割には巨大なエアコンを導入したので、すぐに部屋が暖かくなります。&lt;/p&gt;
&lt;p&gt;帰宅する前に部屋を温めるようなことをしなくてもよいです。マンションのエントランスで暖房をONにするくらいのタイミングで大丈夫です。&lt;/p&gt;
&lt;h3&gt;ポイント&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;修理回数&lt;/strong&gt;: 3回目（購入から数年で）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;修理費用&lt;/strong&gt;: 無償（保証期間外だが無償対応）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;作業内容&lt;/strong&gt;: 基盤交換&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;所要時間&lt;/strong&gt;: 約1時間&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原因特定&lt;/strong&gt;: エラーコードが記録されていたため特定が容易&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;教訓&lt;/strong&gt;: 高機能なエアコンは故障リスクも高い&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;エアコンの能力自体は申し分ないのですが、故障頻度が高いのは気になるところです。次に買い替えるときは、シンプルな機種を選んだほうが良いかもしれません。&lt;/p&gt;
</content:encoded></item><item><title>実家のネットワークインフラを整備 | 3階建RC造にWiFi AP3台配置</title><link>https://blog.teraren.com/posts/home-network-infrastructure-setup/</link><guid isPermaLink="true">https://blog.teraren.com/posts/home-network-infrastructure-setup/</guid><description>3階建鉄筋コンクリート造の実家にWiFiアクセスポイント3台を設置。Cat6Aケーブル100mを使った有線LAN配線と情報ボックスの構築。YAMAHA RTX 1200とL2スイッチで全フロアに安定したネットワーク環境を実現。</description><pubDate>Fri, 09 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;この記事について&lt;/h2&gt;
&lt;h3&gt;学べること&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;鉄筋コンクリート造建物でのWiFi環境構築のポイント&lt;/li&gt;
&lt;li&gt;LANケーブル自作と配線モール施工の実践方法&lt;/li&gt;
&lt;li&gt;YAMAHA RTX 1200を使ったネットワーク構成&lt;/li&gt;
&lt;li&gt;情報ボックスを使った配線管理のベストプラクティス&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;想定読者&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;RC造住宅でWiFi環境に悩んでいる方&lt;/li&gt;
&lt;li&gt;鉄筋コンクリート造の建物でネットワークを構築したい方&lt;/li&gt;
&lt;li&gt;有線LAN配線を自分で施工してコストを抑えたい方&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;前提条件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;LANケーブル圧着工具とテスターが必要&lt;/li&gt;
&lt;li&gt;配線モールの施工スキル&lt;/li&gt;
&lt;li&gt;推定所要時間: 1-2日（配線距離による）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;実家のネットワーク・インフラを整備しました。&lt;/p&gt;
&lt;p&gt;3階建で、鉄筋コンクリート建てなのでWiFiの電波が飛びづらいので各階の踊り場にWiFi APを設置しました。&lt;/p&gt;
&lt;h2&gt;予備知識：鉄筋コンクリートとWiFiの関係&lt;/h2&gt;
&lt;p&gt;鉄筋コンクリートの壁だとほとんどWiFiの電波が透過しません。&lt;/p&gt;
&lt;p&gt;透過しないどころか、結構吸収している感じがします。2GHzも5GHzも。&lt;/p&gt;
&lt;p&gt;階段もコンクリートで作られているので階をまたいで、ドアを通過して各部屋に電波を届かせるのは1台のアクセスポイントでは無理でした。&lt;/p&gt;
&lt;h2&gt;ネットワーク機器&lt;/h2&gt;
&lt;p&gt;今回使用した機器は以下の通りです。&lt;/p&gt;
&lt;h3&gt;ルーター&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;YAMAHA RTX 1200&lt;/strong&gt; - 業務用ルーター、安定性と拡張性が高い&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;WiFi アクセスポイント&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;既存の3台を活用
&lt;ul&gt;
&lt;li&gt;NEC製 1台&lt;/li&gt;
&lt;li&gt;TP-Link 2台&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ネットワークケーブル&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cat6A LANケーブル 100m&lt;/strong&gt; を購入&lt;/li&gt;
&lt;li&gt;必要な長さに自分でカット&lt;/li&gt;
&lt;li&gt;コネクタを圧着工具で取り付け&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;物理ネットワーク構成&lt;/h2&gt;
&lt;p&gt;ネットワークの配線構成は以下の通りです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;2F寝室&lt;/strong&gt;: 光コンバーター → 電話分配器 → YAMAHA RTX 1200&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2F踊り場&lt;/strong&gt;: 情報ボックスを設置 → 1000MBaseT対応のL2スイッチ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;各階への分配&lt;/strong&gt;: L2スイッチから1Fと3Fへ有線LANで分配&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WiFi AP接続&lt;/strong&gt;: 各階の踊り場にWiFi APを配置&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;この構成により、各階で安定したWiFi環境を実現しました。&lt;/p&gt;
&lt;h2&gt;完成写真&lt;/h2&gt;
&lt;p&gt;完成したところの写真です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/01/network-box-completed.jpg&quot; alt=&quot;完成した情報ボックス&quot; /&gt;&lt;/p&gt;
&lt;p&gt;配線モールで綺麗に配線を整理しています。&lt;/p&gt;
&lt;p&gt;中身はこんな感じです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/01/network-box-inside.jpg&quot; alt=&quot;情報ボックス内部&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中身をもう少しズームで。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/01/network-box-inside-zoom.jpg&quot; alt=&quot;情報ボックス内部のズーム&quot; /&gt;&lt;/p&gt;
&lt;p&gt;L2スイッチとケーブルが整然と配置されています。&lt;/p&gt;
&lt;h2&gt;使用した資材&lt;/h2&gt;
&lt;p&gt;今回の工事で使用した資材をまとめます。&lt;/p&gt;
&lt;h3&gt;配線モール&lt;/h3&gt;
&lt;p&gt;::amazon{asin=&quot;B0FJQDJG3J&quot;}&lt;/p&gt;
&lt;p&gt;壁面に這わせるケーブルを保護・整理するために使用。&lt;/p&gt;
&lt;h3&gt;配線モールカッター&lt;/h3&gt;
&lt;p&gt;::amazon{asin=&quot;B0BZSKMMHW&quot;}&lt;/p&gt;
&lt;p&gt;配線モールを綺麗にカットするための専用工具。&lt;/p&gt;
&lt;h3&gt;ラベルテープ&lt;/h3&gt;
&lt;p&gt;::amazon{asin=&quot;B0BCXR95VZ&quot;}&lt;/p&gt;
&lt;p&gt;各ケーブルに用途を記載して管理を容易に。&lt;/p&gt;
&lt;h3&gt;LANケーブル圧着工具とテスター&lt;/h3&gt;
&lt;p&gt;::amazon{asin=&quot;B0CQ2DR8VS&quot;}&lt;/p&gt;
&lt;p&gt;Cat6A対応のコネクタを圧着するための工具とケーブルテスター。&lt;/p&gt;
&lt;h3&gt;Cat6A LANケーブル 100m&lt;/h3&gt;
&lt;p&gt;::amazon{asin=&quot;B0CLJM94PP&quot;}&lt;/p&gt;
&lt;p&gt;10Gbps対応のCat6Aケーブル。将来的な速度向上にも対応可能。&lt;/p&gt;
&lt;h3&gt;スイッチングハブ&lt;/h3&gt;
&lt;p&gt;::amazon{asin=&quot;GS305-300JPS&quot;}&lt;/p&gt;
&lt;p&gt;適当に安いL2 Switchを選びました。
理論値に近い950Mbpsは出るので十分です。&lt;/p&gt;
&lt;h2&gt;ベンチマーク結果&lt;/h2&gt;
&lt;p&gt;実際に速度を測定しました。&lt;/p&gt;
&lt;p&gt;木製のドアを隔てた場所では&lt;strong&gt;700Mbps近く&lt;/strong&gt;出ます。&lt;/p&gt;
&lt;p&gt;ちょっと離れたりすると&lt;strong&gt;400Mbps&lt;/strong&gt;でした。&lt;/p&gt;
&lt;p&gt;普段使いには十分な速度かなと思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/01/speed-test.png&quot; alt=&quot;速度測定結果&quot; /&gt;&lt;/p&gt;
&lt;p&gt;スマートフォンでの測定結果。下り速度が600Mbps以上出ています。&lt;/p&gt;
&lt;h2&gt;施工のポイント&lt;/h2&gt;
&lt;h3&gt;LANケーブルの自作&lt;/h3&gt;
&lt;p&gt;Cat6Aケーブルは100m購入して、必要な長さにカットしました。&lt;/p&gt;
&lt;p&gt;圧着工具を使ってRJ45コネクタを取り付けます。&lt;/p&gt;
&lt;p&gt;テスターで導通確認を行い、8本の芯線がすべて正しく接続されていることを確認するのが重要です。&lt;/p&gt;
&lt;h3&gt;配線モールの施工&lt;/h3&gt;
&lt;p&gt;壁面に這わせるケーブルは、配線モールで保護します。&lt;/p&gt;
&lt;p&gt;専用カッターを使うと、綺麗に切断できて仕上がりが良くなります。&lt;/p&gt;
&lt;p&gt;曲がり部分は専用の継手を使うと見た目も良く、ケーブルの保護もしっかりできます。&lt;/p&gt;
&lt;h3&gt;情報ボックスの設置&lt;/h3&gt;
&lt;p&gt;2Fの踊り場に情報ボックスを設置して、L2スイッチを収納しました。&lt;/p&gt;
&lt;p&gt;ここから各階へケーブルを分配することで、配線がスッキリして管理しやすくなります。&lt;/p&gt;
&lt;p&gt;ラベルテープで各ケーブルに「1F AP」「3F AP」といったラベルを貼っておくと、後々のメンテナンスが楽です。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;実家の3階建RC造にネットワークインフラを構築した記録です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;WiFi環境&lt;/strong&gt;: 各階にAP配置で全フロア快適に利用可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;速度&lt;/strong&gt;: 700Mbps（木製ドア越え）、400Mbps（距離あり）で実用十分&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;配線&lt;/strong&gt;: Cat6Aケーブル100mを自作で配線、将来の10Gbps対応も可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コスト削減&lt;/strong&gt;: ケーブル自作と配線モール施工で業者依頼より大幅削減&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;管理性&lt;/strong&gt;: 情報ボックスとラベルテープで配線管理が容易&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;鉄筋コンクリート造の建物でWiFi環境に悩んでいる方は、各階にAPを配置する方式がおすすめです。&lt;/p&gt;
&lt;p&gt;有線LAN配線は少し手間ですが、Cat6Aケーブルを自作することでコストを抑えつつ、将来的な速度向上にも対応できる構成になりました。&lt;/p&gt;
&lt;p&gt;YAMAHA RTX 1200は業務用ルーターなので安定性が高く、設定の自由度も高いので、本格的なホームネットワークを構築したい方におすすめです。&lt;/p&gt;
</content:encoded></item><item><title>QNAP NASにTailscaleをインストールして外出先からアクセスできるようにする</title><link>https://blog.teraren.com/posts/2025-12-19-tailscale-on-qnap-ts431p/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2025-12-19-tailscale-on-qnap-ts431p/</guid><description>QNAP TS-431PにTailscaleをインストールして外出先からNASへアクセスする方法。ARM用パッケージの選択からSSH経由での起動、認証までの手順を解説。</description><pubDate>Fri, 19 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;QNAP TS-431PというNASをRAID 1構成で運用しており、2TBのディスクを4台使用しています。今回、Tailscaleを導入することで、外出先のスマートフォンやPCから安全にNASへアクセスできる環境を構築しました。&lt;/p&gt;
&lt;h2&gt;QNAP TS-431Pについて&lt;/h2&gt;
&lt;p&gt;使用しているNASは以下のモデルです。&lt;/p&gt;
&lt;p&gt;https://www.qnap.com/ja-jp/product/ts-431p&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-19-10-07-55.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ARM CPUを搭載した4ベイNASで、自宅のファイルサーバーとして活用しています。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B08F7QYJLS&quot; kw=&quot;QNAP TS-431P 4ベイ NAS&quot;}&lt;/p&gt;
&lt;h2&gt;Tailscaleとは&lt;/h2&gt;
&lt;p&gt;Tailscaleは、WireGuardをベースとしたVPNソリューションで、複雑なネットワーク設定なしに、異なるネットワーク上のデバイス同士を安全に接続できるサービスです。従来のVPNと比べて設定が簡単で、NAT越えも自動で処理してくれるため、自宅のNASへのリモートアクセスに最適です。&lt;/p&gt;
&lt;h2&gt;パッケージのダウンロード&lt;/h2&gt;
&lt;p&gt;まず、QNAP用のTailscaleパッケージをダウンロードします。&lt;/p&gt;
&lt;p&gt;GitHubのリリースページから、使用しているNASのアーキテクチャに合ったパッケージを選択します。&lt;/p&gt;
&lt;p&gt;https://github.com/tailscale/tailscale-qpkg/releases/tag/v1.58.2&lt;/p&gt;
&lt;h3&gt;アーキテクチャの確認&lt;/h3&gt;
&lt;p&gt;TS-431PのCPUはARM Cortex-A15なので、ARM用パッケージを選択します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[matsu@ts431p Tailscale]$ cat /proc/cpuinfo
processor       : 0
model name      : Annapurna Labs Alpine AL212 Dual-core ARM Cortex-A15 CPU @ 1.70GHz
Speed           : 1.7GHz
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x2
CPU part        : 0xc0f
CPU revision    : 4

processor       : 1
model name      : Annapurna Labs Alpine AL212 Dual-core ARM Cortex-A15 CPU @ 1.70GHz
Speed           : 1.7GHz
Features        : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x2
CPU part        : 0xc0f
CPU revision    : 4

Hardware        : Annapurna Labs Alpine
Revision        : 0000
Serial          : 0000000000000000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記の情報から、以下のパッケージをダウンロードします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tailscale_1.58.2-1_arm-x41.qpkg
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;インストール手順&lt;/h2&gt;
&lt;h3&gt;1. パッケージのアップロード&lt;/h3&gt;
&lt;p&gt;ダウンロードしたパッケージを、QNAP管理画面（QTS）の「App Center」からアップロードしてインストールします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-19-09-42-57.png&quot; alt=&quot;Tailscaleパッケージのインストール画面&quot; /&gt;&lt;/p&gt;
&lt;p&gt;「手動インストール」を選択し、ダウンロードしたqpkgファイルを指定してインストールを実行します。&lt;/p&gt;
&lt;h2&gt;Tailscaleの起動&lt;/h2&gt;
&lt;h3&gt;問題: 管理画面から起動できない&lt;/h3&gt;
&lt;p&gt;インストール後、QNAP管理画面上にTailscaleアプリが表示されますが、起動しようとすると「Internal Server Error」が発生して起動できない問題に遭遇しました。&lt;/p&gt;
&lt;h3&gt;解決方法: SSH経由での起動&lt;/h3&gt;
&lt;p&gt;この問題は、&lt;code&gt;tailscaled&lt;/code&gt;デーモンが起動していないことが原因です。SSH経由でNASにログインし、手動で起動する必要があります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[matsu@ts431p Tailscale]$ cd /share/CACHEDEV1_DATA/.qpkg/Tailscale
[matsu@ts431p Tailscale]$ ls
Tailscale.sh* state/        tailscale*    tailscaled*   ui/

[matsu@ts431p Tailscale]$ ./Tailscale.sh start
ln: /home/httpd/cgi-bin/qpkg/Tailscale/ui: Permission denied

[matsu@ts431p Tailscale]$ sudo ./Tailscale.sh start

[matsu@ts431p Tailscale]$ ps | grep tailscaled
30731 admin     28156 S   /share/CACHEDEV1_DATA/.qpkg/Tailscale/tailscaled --port 41641 --statedir=/share/CACHEDEV1_DATA/.qpkg/Tailscale/state --socket=/tmp/tailscale/tailscaled.sock
30975 matsu       388 S   grep tailscaled
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;sudo&lt;/code&gt;権限で起動スクリプトを実行すると、&lt;code&gt;tailscaled&lt;/code&gt;が正常に起動します。&lt;/p&gt;
&lt;h2&gt;Tailscaleへの認証&lt;/h2&gt;
&lt;h3&gt;認証手続き&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;tailscaled&lt;/code&gt;が起動すると、QNAP管理画面のTailscaleアプリに「Reauthenticate」ボタンが表示されるようになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-19-09-45-11.png&quot; alt=&quot;Reauthenticateボタンが表示された画面&quot; /&gt;&lt;/p&gt;
&lt;p&gt;このボタンをクリックすると、Tailscaleの認証ページにリダイレクトされます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-19-09-45-35.png&quot; alt=&quot;Tailscale認証画面&quot; /&gt;&lt;/p&gt;
&lt;p&gt;TailscaleアカウントでログインしてNASを承認すると、Tailscaleネットワークに参加できます。&lt;/p&gt;
&lt;h3&gt;設定完了&lt;/h3&gt;
&lt;p&gt;認証が完了すると、QNAPアプリ上で以下のような画面が表示されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-19-09-46-39.png&quot; alt=&quot;Tailscale接続完了画面&quot; /&gt;&lt;/p&gt;
&lt;p&gt;これで設定は完了です。TailscaleがインストールされているスマートフォンやPCから、NASに割り当てられたTailscale IPアドレス（100.x.x.x形式）でアクセスできるようになります。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;QNAP NASへのTailscaleインストールは、管理画面からの起動に問題があるものの、SSH経由で手動起動することで解決できました。一度設定してしまえば、外出先からも安全にNASへアクセスできる環境が整います。&lt;/p&gt;
&lt;h3&gt;ポイント&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;QNAP用のTailscaleパッケージは、NASのアーキテクチャに合ったものを選択&lt;/li&gt;
&lt;li&gt;初回起動時はSSH経由で&lt;code&gt;sudo ./Tailscale.sh start&lt;/code&gt;を実行する必要がある&lt;/li&gt;
&lt;li&gt;認証後はTailscaleネットワーク経由で外部から安全にアクセス可能&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tailscaleを使うことで、ポート転送やDDNSの設定なしに、セキュアなリモートアクセス環境を簡単に構築できるため、自宅NASの利便性が大きく向上しました。&lt;/p&gt;
</content:encoded></item><item><title>APC UPSのバッテリーを交換。3,000円で再生品ではない新品電池！（BR-550S-JP E)</title><link>https://blog.teraren.com/posts/2025-12-13-apc-ups-battery-replacement/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2025-12-13-apc-ups-battery-replacement/</guid><description>APC BR-550S-JP Eのバッテリーを約3,000円の汎用12V 7.2Ah鉛蓄電池で交換した手順。サルフェーション除去による再生も試みたが効果なく、互換品で解決。</description><pubDate>Sat, 13 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;2021年4月12日に自宅サーバー、ネットワーク機器の電源を保護するためにAPCのUPSを購入しました。&lt;/p&gt;
&lt;p&gt;型番は BR-550S-JP E です。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B06XHZ3K5T&quot;}&lt;/p&gt;
&lt;h2&gt;UPSバッテリーの一般的な寿命について&lt;/h2&gt;
&lt;p&gt;家庭用・SOHO向けUPSに使われている鉛蓄電池（シールド型鉛蓄電池 / VRLA）は、
&lt;strong&gt;使用環境にもよりますが、一般的に3〜5年程度が寿命&lt;/strong&gt;と言われています。&lt;/p&gt;
&lt;p&gt;特に以下の条件では劣化が早まります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;常時通電（フロート充電）されている&lt;/li&gt;
&lt;li&gt;室温が高い（25℃超）&lt;/li&gt;
&lt;li&gt;停電が少なく、放電・充電のサイクルがほぼ無い&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今回のUPSは約4年半使用しており、寿命としては妥当なタイミングでした。&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;稼働し始めて4年半が経過しましたが、2025年12月に入ってからUPSのバッテリーが劣化している旨のアラートが頻発するようになりました。&lt;/p&gt;
&lt;p&gt;詳細は以下の記事にまとめてあります。&lt;/p&gt;
&lt;p&gt;https://diary.teraren.com/posts/2025-11-27-apc-ups/&lt;/p&gt;
&lt;h2&gt;対処1：バッテリー再生の試み&lt;/h2&gt;
&lt;p&gt;ちょうど、車のバッテリーは鉛蓄電池で、サルフェーションを除去して充電すれば、バッテリー自体を交換しなくても復活できるという話を聞きました。&lt;/p&gt;
&lt;p&gt;色々調べていくとUPSのバッテリーも鉛蓄電池であることがわかりました。&lt;/p&gt;
&lt;p&gt;APCのバッテリーには、ボルト数やバッテリーの種別が細かく書いていないので、色々調べていくと12V 7.2Ahの鉛蓄電池であることがわかりました。&lt;/p&gt;
&lt;p&gt;APCのバッテリーの電圧を計測してみたら、
10.84V
しかありませんでした。この電圧降下がバッテリー劣化の原因と思われます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-22-55-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;鉛蓄電池の場合はこの電圧降下はサルフェーションによるものと思われるので、サルフェーション除去充電をすることにしました。&lt;/p&gt;
&lt;p&gt;あまりモノを増やしたくないので、小型で安価な充電器を探したところ、以下の製品が見つかりました。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0D54NF9KG&quot;}&lt;/p&gt;
&lt;p&gt;シンプルな充電器なので色々と手動で行う必要がありそうです。本体には「Repair」というボタンがあるだけです。このRepairボタンを押すとサルフェーション除去充電が開始されるようです。
&lt;a href=&quot;https://minkara.carview.co.jp/search/?q=anhtczyx+pulse+repair+battery+charger&quot;&gt;みんからのレビュー&lt;/a&gt;でも鉛蓄電池のサルフェーション除去に効果があると書かれていました。&lt;/p&gt;
&lt;p&gt;でもちょっと怖いですね。&lt;/p&gt;
&lt;p&gt;一応、Gemini 3 Proにもどのくらいパルス充電すべきかを聞いてみました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-02-01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一旦、24時間〜48時間という回答が返ってきたので、電池本体の温度を計測しながら充電することにしました。
また、膨張がないかも定期的に目視しながら充電することにしました。&lt;/p&gt;
&lt;p&gt;充電器のクリップが端子に固定できなかったので、プラス側は平型端子を自作して端子を露出して掴めるようにして充電を開始しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-35-01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;パルス充電を開始して、20時間程度経過したら「Full」という表示が充電器に出ました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-03-41.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;電圧を計測してみると、11.42Vまで回復していました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-04-38.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;UPSに戻してみましたが、相変わらずエラーが出てしまいます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-05-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Geminiに再度聞いてみたら以下のような回答でした。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;充電を中止する: これ以上の長時間充電は、バッテリーに不要な熱をかけるリスクが高く、安全上の懸念があります。
廃棄を検討する: このバッテリーは、UPSという重要な用途のバックアップ電源として使用するには、信頼性が完全に失われています。CSBのバッテリーはリサイクルが可能ですので、お住まいの自治体や専門の回収業者に相談し、廃棄処分を強くお勧めします。
新品への交換: APC RS 550Sを今後も利用されるのであれば、新しい純正RBC（Replacement Battery Cartridge）または互換品（7.2Ah）の購入が必要です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;なので、このバッテリーの再生は諦めました。&lt;/p&gt;
&lt;h3&gt;なぜ電圧が回復してもUPSでは使えなかったのか&lt;/h3&gt;
&lt;p&gt;鉛蓄電池は、開放電圧がある程度回復しても、以下の特性が劣化している場合があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内部抵抗の増加&lt;/li&gt;
&lt;li&gt;瞬間的な大電流供給能力の低下&lt;/li&gt;
&lt;li&gt;容量（Ah）の実質的な低下&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;UPSは停電時に&lt;strong&gt;瞬時に大電流を供給できること&lt;/strong&gt;が重要なため、
単純に電圧が11〜12Vに戻っただけでは「正常」とは判断されません。&lt;/p&gt;
&lt;p&gt;今回、UPSに戻してもエラーが解消されなかったのは、
内部抵抗や容量劣化をUPS側のセルフテストで検知された可能性が高いと考えられます。&lt;/p&gt;
&lt;h3&gt;安全面の補足（重要）&lt;/h3&gt;
&lt;p&gt;※ 注意
UPS用バッテリーの再生（サルフェーション除去）は、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;発熱&lt;/li&gt;
&lt;li&gt;ガス発生&lt;/li&gt;
&lt;li&gt;膨張・破裂&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;といったリスクを伴います。
特に室内で行う場合は、&lt;strong&gt;換気・温度監視・目視確認を必ず行う&lt;/strong&gt;必要があります。&lt;/p&gt;
&lt;p&gt;業務用途や重要機器のバックアップ用途では、
再生バッテリーの使用は推奨されません。&lt;/p&gt;
&lt;h2&gt;対処2：互換バッテリーの購入&lt;/h2&gt;
&lt;p&gt;UPSのバッテリーの上部にQRコードがあって、それをスキャンしてみると電池の詳細が判明しました。
CSBというメーカーの「GPL1272F2FR」になります。12V/7.2Ahの鉛蓄電池です。&lt;/p&gt;
&lt;p&gt;APCはこのバッテリーにラベルを付けて販売しているようです。&lt;/p&gt;
&lt;p&gt;ちなみに純正品はかなり高くて、新品のUPS（18,000円程度）を1台買えるのと同じくらいの値段（14,000円程度）になります。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B004OOY914&quot;}&lt;/p&gt;
&lt;p&gt;Amazonでこの純正品に対する &lt;strong&gt;再生品&lt;/strong&gt; の互換バッテリーが売っていることがわかりました。しかし、金額はさほど安くはありません。（7,000円程度）&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B01NAH8YHO&quot;}&lt;/p&gt;
&lt;p&gt;さらに調査を進めると、この12V 7.2Ahの鉛蓄電池は色々なメーカーから販売されていることがわかりました。サイズも規格品なので、以下のようなもっと安価なバッテリーも見つかりました。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B06XXD7KC8&quot;}&lt;/p&gt;
&lt;p&gt;もっと安価なものもありますが、信頼性を考慮してこのあたりのものを購入しました。
Amazonなので配送も早く、注文してから2日で到着しました。&lt;/p&gt;
&lt;p&gt;手前が古いバッテリー、奥が新しいバッテリーです。
&lt;strong&gt;よく見るとAPCの電池は傷だらけでした。これ自体が再生バッテリーのように見えます！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-14-34.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;右が新しいバッテリー、左が古いバッテリーです。
大きさが全く同じです。端子の形状が少し違いますが、問題なく接続できました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-16-02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;新しいバッテリーの電圧を測定してみたら、13.07Vありました。新品なので当然ですね。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-16-34.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下のようにしてインストールします。ぴったりです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-17-20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;APCのUPSの電源を入れてみたら、正常に認識しました。アラートもでません。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-18-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;商用電源を投入してから数秒経つと、バッテリーのセルフテストが走って残り時間などが表示されました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-23-18-32.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;これで無事にバッテリー交換が完了しました。UPS自体はまだまだ使えるので、バッテリー交換だけで延命できてよかったです。&lt;/p&gt;
&lt;h2&gt;UPS用互換バッテリー選定時のチェックポイント&lt;/h2&gt;
&lt;p&gt;汎用の12V 7.2Ah鉛蓄電池を選ぶ際は、以下の点を確認しました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;電圧・容量&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;12V / 7.2Ah（±0.5Ah程度は許容）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;サイズ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;約151 × 65 × 94 mm（一般的な7.2Ah規格）&lt;/li&gt;
&lt;li&gt;ケースに収まることが重要&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;端子形状&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;F2端子（平型 6.3mm）&lt;/li&gt;
&lt;li&gt;形状が違っても接続できる場合が多いが要確認&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;用途&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UPS用途対応（ディープサイクル想定）&lt;/li&gt;
&lt;li&gt;「非常用電源」「UPS」「非常灯」用途と明記されているものが望ましい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;新品であること&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;再生品・長期在庫品は避ける&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;UPS用途で汎用バッテリーを使う際の注意点&lt;/h2&gt;
&lt;p&gt;車用バッテリーと異なり、UPSでは以下が重要です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;瞬時の放電性能（停電時）&lt;/li&gt;
&lt;li&gt;常時フロート充電への耐性&lt;/li&gt;
&lt;li&gt;長期間「満充電状態」で劣化しにくいこと&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そのため、安価すぎるノーブランド品や、
用途が不明確なバッテリーは避けた方が無難です。&lt;/p&gt;
&lt;p&gt;今回は価格と信頼性のバランスを考え、
国内流通実績のある製品を選びました。&lt;/p&gt;
&lt;h3&gt;参考情報&lt;/h3&gt;
&lt;p&gt;https://pepeprism.hatenablog.com/entry/2023/12/03/202852
https://bbs.kakaku.com/bbs/K0000934956/#25813114&lt;/p&gt;
&lt;h2&gt;まとめ（結論）&lt;/h2&gt;
&lt;h3&gt;コストまとめ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;純正バッテリー&lt;/strong&gt;: 約14,000円&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APC互換バッテリー&lt;/strong&gt;: 約7,000円&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;汎用12V 7.2Ah鉛蓄電池&lt;/strong&gt;: 約3,000〜5,000円&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今回は汎用バッテリーを購入し、純正品と比べて約10,000円のコスト削減に成功しました。&lt;/p&gt;
&lt;h3&gt;重要ポイント&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;APC BR-550S-JP E のバッテリーは &lt;strong&gt;12V 7.2Ahの規格品&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;純正RBCは高価だが、&lt;strong&gt;新品の汎用バッテリーで問題なく代替可能&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;サルフェーション除去による再生は、UPS用途では現実的ではない&lt;/li&gt;
&lt;li&gt;バッテリー交換だけでUPS本体を長く使える&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;安価な互換バッテリーでも問題なく動作し、交換作業も比較的簡単でした。
同様の症状でお悩みの方は、自己責任でバッテリー交換を試してみてください。&lt;/p&gt;
</content:encoded></item><item><title>povoからの請求に不当な請求があったので調査した話</title><link>https://blog.teraren.com/posts/2025-12-12-povo-unauthorized-billing/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2025-12-12-povo-unauthorized-billing/</guid><description>povoから身に覚えのない海外ローミングSMS料金200円が請求された件を調査。サポートに問い合わせた結果、システム側の不具合で多数のユーザに影響があったことが判明。</description><pubDate>Fri, 12 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;KDDIの&lt;a href=&quot;https://povo.jp/&quot;&gt;povo&lt;/a&gt;を不定期に使っているのではあるが、直近は使っていないのに200円の請求が上がってきた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-13-04-33-54.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;名目は、「海外ローミングSMS」という項目。金額が小さから放置してもよいのだが、今後も同様のことが発生すると困るので、調査した。&lt;/p&gt;
&lt;h2&gt;調査&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Xや検索したりGeminiに聞いてみたが、特に海外に行っていないのにSMSが来ることはない、とのこと。&lt;/li&gt;
&lt;li&gt;povoのFAQを見てみたが、特に該当するような記述は見当たらない。&lt;/li&gt;
&lt;li&gt;海外からの着信を受け取っただけで受け取り側で課金されるかもしれないので、一応電話の履歴とSMSの履歴を確認したが、特に海外からの着信はない。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ぐぐってみると、PovoのFAQをには&lt;a href=&quot;https://kdlsupport.zendesk.com/hc/ja/articles/4405850369551-%E8%AB%8B%E6%B1%82%E6%9B%B8%E3%81%AB%E8%BA%AB%E3%81%AB%E8%A6%9A%E3%81%88%E3%81%AE%E3%81%AA%E3%81%84%E6%96%99%E9%87%91%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99-%E3%81%A9%E3%81%86%E3%81%97%E3%81%9F%E3%82%89%E3%81%84%E3%81%84%E3%81%A7%E3%81%99%E3%81%8B&quot;&gt;身に覚えのない施灸があったらお問い合わせをしろ&lt;/a&gt;と書いてあった。&lt;/p&gt;
&lt;p&gt;そこで、povoのサポートに問い合わせた。povoのアプリ上のチャットで問い合わせる形。状況説明などを15分程度行った後、povo側の持ち帰り案件となった。&lt;/p&gt;
&lt;p&gt;1日後、以下のような回答が来た。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-12-17-46-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;海外へ渡航されていないにもかかわらず料金が発生している状況とお伺いしております。&lt;/p&gt;
&lt;p&gt;社内で協議させていただいた結果、今回の海外ローミングSMSの料金につきましては、
返金対応をさせていただくこととなりました。&lt;/p&gt;
&lt;p&gt;返金のお手続きにはお日にちをいただく見込みでございます。
完了いたしましたら、改めてメールにてご連絡させていただきますので、お待ちいただけますと幸いです。&lt;/p&gt;
&lt;p&gt;この度はご不安な思いをさせてしまい、大変申し訳ございませんでした。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;全く納得できない。原因がわからないのに、返金対応をされても困るし、再発防止が示されていない。&lt;/p&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;2025/12/24&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/12/2025-12-24-10-27-57.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;povoのシステム側の問題だったようで、影響が出ているユーザは自分だけではなく、多数いた模様。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;平素よりpovo2.0をご利用いただき、誠にありがとうございます。&lt;/p&gt;
&lt;p&gt;本メールは12月ご請求の(11月利用分)料金において、海外ローミングSMS送信料*が発生している一部のお客様へお送りしております。
*ご利用料金の明細確認方法はこちらをご覧ください。(https://povo.jp/support/invoice/)&lt;/p&gt;
&lt;p&gt;2025年11月ご利用分に、実際には海外ローミングSMSのご利用がないお客様にも海外ローミングSMS送信料をご請求している場合があることが判明いたしました。現在はシステム側の対処により、すでに同様の事象は発生しない状況となっておりますので、ご安心ください。&lt;/p&gt;
&lt;p&gt;そのため、12月のご請求において、海外ローミングSMS送信料金の返金手続きを実施いたしました。&lt;/p&gt;
&lt;p&gt;なお、ご利用の決済会社への返金データの連携に2週間程度要する場合がございますので、反映までお待ちくださいますようお願い申し上げます。
具体的な返金日は決済方法によって異なりますため、お手数おかけしますが、クレジットカード会社またはあと払い(ペイディ)窓口へお問い合わせをお願いいたします。&lt;/p&gt;
&lt;p&gt;このたび、お客様にご迷惑、ご心配をおかけいたしましたことを深くお詫び申し上げます。&lt;/p&gt;
&lt;p&gt;今後このようなことがないよう再発防止に努めてまいります。
引き続きpovo2.0をご愛顧賜りますようお願い申し上げます。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Palantir AIPの正体：なぜ「Chat」ではなく「OS」なのか？そのアーキテクチャを解剖する</title><link>https://blog.teraren.com/posts/palantir-aip-architecture/</link><guid isPermaLink="true">https://blog.teraren.com/posts/palantir-aip-architecture/</guid><description>現在、多くのエンジニアが生成AIの業務適用（RAG等）に取り組んでいますが、多くのプロジェクトが「社内ドキュメントを検索して要約する」という **Read-Onlyなチャットボット** の域を出ずに停滞しています。</description><pubDate>Wed, 03 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに：AIを「おしゃべり」で終わらせないために&lt;/h2&gt;
&lt;p&gt;現在、多くのエンジニアが生成AIの業務適用（RAG等）に取り組んでいますが、多くのプロジェクトが「社内ドキュメントを検索して要約する」という &lt;strong&gt;Read-Onlyなチャットボット&lt;/strong&gt; の域を出ずに停滞しています。&lt;/p&gt;
&lt;p&gt;一方で、Palantir AIP (Artificial Intelligence Platform) は、チャットUIを通じて「発注する」「生産計画を変更する」といった &lt;strong&gt;Write/Action&lt;/strong&gt; まで完結させる「OS（オペレーティングシステム）」として機能しています。&lt;/p&gt;
&lt;p&gt;なぜPalantirにはそれが可能なのか？単にプロンプトエンジニアリングが優れているからではありません。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;わかりやすく乱暴に言えば…&lt;/strong&gt;
Palantir AIPは「エンプラ用のDify」です。ただし、Difyの100倍くらい高機能。最大の違いは、Difyが都度データソースを読みに行くのに対し、Palantirはデータをコピー（レプリケート）して専用のストレージに保持しているため、スケーラビリティが圧倒的に高いという点です。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;本記事では、マーケティング的な用語を排し、その裏側にある &lt;strong&gt;「Ontology（オントロジー）」という独自のデータミドルウェアと、分散KVS + 検索エンジンを組み合わせたハイブリッド・アーキテクチャ&lt;/strong&gt; を技術的に解剖します。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;1. 全体アーキテクチャ：3層構造の解剖&lt;/h2&gt;
&lt;p&gt;Palantir AIPは、単なるLLMラッパーではありません。その本質は、LLMに「現実世界の地図（Context）」と「手足（Tool）」を与えるための強固なバックエンドシステムにあります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    %% 全体アーキテクチャ
    subgraph &quot;1. Data Sources (物理層)&quot;
        ERP[(ERP)]
        CRM[(CRM)]
        IoT[(&quot;IoT Sensors&quot;)]
        SaaS[(&quot;SaaS API&quot;)]
        Files[(&quot;CSV/PDF&quot;)]
    end

    subgraph &quot;2. Palantir AIP Platform&quot;
        subgraph &quot;Data Integration Layer&quot;
            Connectors[&quot;200+ Connectors&quot;] -- &quot;Ingest (Batch/Stream)&quot; --&amp;gt; RawData[&quot;Raw Data Storage&quot;]
            RawData -- &quot;Transform (Pipeline Builder)&quot; --&amp;gt; CleanData[&quot;Cleaned Tables&quot;]
        end

        subgraph &quot;Ontology Layer (The Context)&quot;
            CleanData --&amp;gt;|Map &amp;amp; Link| Ontology[&quot;Ontology Core&quot;]
            Ontology --&amp;gt;|Define Objects, Properties, Links| ObjectModel[&quot;Object Model&quot;]
            Ontology --&amp;gt;|Define Actions &amp;amp; Functions| ActionDefinitions[&quot;Action Definitions&quot;]
        end

        subgraph &quot;AIP LLM Mesh (The Brain)&quot;
            Ontology --&amp;gt;|RAG / Grounding| Router{&quot;LLM Router&quot;}
            Router --&amp;gt;|Select Model| LLMs[&quot;LLM Pool&amp;lt;br/&amp;gt;(GPT-4, Claude, Llama, etc.)&quot;]
        end
        
        subgraph &quot;Action &amp;amp; Logic (The Tool)&quot;
            LLMs --&amp;gt;|Reasoning Result| Logic{&quot;AIP Logic / Guardrails&quot;}
            Logic --&amp;gt;|Authorize &amp;amp; Execute| ActionExec[&quot;Action Executor&quot;]
        end
    end

    subgraph &quot;3. User Interface &amp;amp; External Systems&quot;
        ActionExec --&amp;gt;|Write-back| ERP
        ActionExec --&amp;gt;|Write-back| CRM
        Logic --&amp;gt;|Response &amp;amp; Suggestion| UserUI[&quot;AIP Terminal / Workshop UI&quot;]
        UserUI --&amp;gt;|Human Feedback / Approval| Logic
    end

    ERP -.-&amp;gt; Connectors
    CRM -.-&amp;gt; Connectors
    IoT -.-&amp;gt; Connectors
    SaaS -.-&amp;gt; Connectors
    Files -.-&amp;gt; Connectors

    style Ontology fill:#f9f,stroke:#333,stroke-width:2px,color:black
    style LLMs fill:#ccf,stroke:#333,stroke-width:2px,color:black
    style Logic fill:#ff9,stroke:#333,stroke-width:2px,color:black
    style ActionExec fill:#f99,stroke:#333,stroke-width:2px,color:black
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;アーキテクチャは大きく3つのレイヤーで構成されています。&lt;/p&gt;
&lt;h3&gt;1. Ontology (The Context Layer)&lt;/h3&gt;
&lt;p&gt;物理的なデータ（SQLテーブル、SaaS、IoT等）を「意味のあるオブジェクト」に変換するレイヤー。ここが本記事のメインテーマです。&lt;/p&gt;
&lt;h3&gt;2. AIP LLM Mesh (The Brain)&lt;/h3&gt;
&lt;p&gt;特定のモデルに依存しない（Model Agnostic）推論レイヤー。GPT-4、Claude、Llamaなどをタスクに応じて動的に切り替えるルーティング機能などを持ちます。&lt;/p&gt;
&lt;h3&gt;3. Action &amp;amp; Logic (The Tool)&lt;/h3&gt;
&lt;p&gt;LLMが推論した結果に基づき、安全に基幹システムへの書き込み（Write-back）を行うためのAPIゲートウェイおよび権限管理機構。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;2. Deep Dive：オントロジーの物理アーキテクチャ&lt;/h2&gt;
&lt;p&gt;エンジニアとして最も興味深いのは、「ERPやIoTセンサーなどの数億〜数十億レコードのデータを、どうやってLLMに即座に供給しているのか？」という点でしょう。&lt;/p&gt;
&lt;p&gt;公式ドキュメントでは、このデータ基盤は &lt;strong&gt;「Object Storage V2」&lt;/strong&gt; と呼称されていますが、その内部実装の詳細は非公開です。しかし、Palantirが開発・公開しているOSS（AtlasDB等）のアーキテクチャから推測すると、 &lt;strong&gt;一般的なRDB（PostgreSQLやOracle）をメインストアとして使用していない可能性が高いです。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TB
    %% Ontology ストレージ層の詳細
    subgraph &quot;Ontology Backend (Hybrid Storage)&quot;
        
        subgraph &quot;Logical Layer (AtlasDB)&quot;
            TransactionMgr[&quot;AtlasDB (Transaction Manager)&quot;]
            NoteAtlas[&quot;NoSQL上で&amp;lt;br/&amp;gt;ACIDトランザクションを実現&quot;]
            TransactionMgr --- NoteAtlas
        end

        subgraph &quot;Physical Storage Layer (Compute-Storage Separation)&quot;
            subgraph &quot;Search &amp;amp; Light Aggregation (Find)&quot;
                ES[(&quot;Elasticsearch / OpenSearch&quot;)]
                NoteES[&quot;高速検索&amp;lt;br/&amp;gt;ID特定&amp;lt;br/&amp;gt;軽量集計(Memory)&quot;]
                ES --- NoteES
            end
            
            subgraph &quot;Data Fetch &amp;amp; Storage (Fetch)&quot;
                KVS[(&quot;Apache Cassandra / HBase&quot;)]
                NoteKVS[&quot;Wide-Column Store&amp;lt;br/&amp;gt;スケーラブル&amp;lt;br/&amp;gt;必要な列のみ取得&quot;]
                KVS --- NoteKVS
            end
        end

        TransactionMgr -- &quot;Index Write (Async)&quot; --&amp;gt; ES
        TransactionMgr -- &quot;Data Write (Sync)&quot; --&amp;gt; KVS
    end

    subgraph &quot;Application / LLM Query Flow&quot;
        AppQuery[&quot;Client Query&quot;] -- &quot;1. Find IDs (検索)&quot; --&amp;gt; ES
        ES --&amp;gt;|2. Return Object IDs| AppQuery
        AppQuery -- &quot;3. Fetch Data by ID (取得)&quot; --&amp;gt; KVS
        KVS --&amp;gt;|4. Return Hydrated Objects| AppQuery
    end
    
    style ES fill:#d4e157,stroke:#333,color:black
    style KVS fill:#4fc3f7,stroke:#333,color:black
    style TransactionMgr fill:#ffb74d,stroke:#333,color:black
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;「ER（実体関連）モデル」を扱うためRDBが最適に見えますが、RDBでは大規模な結合（JOIN）とスキーマ変更の柔軟性において限界が来るためです。代わりに、 &lt;strong&gt;「分散KVS」と「検索エンジン」のハイブリッド構成&lt;/strong&gt; を採用していると考えられます。&lt;/p&gt;
&lt;h3&gt;2.1 ストレージ層：Cassandra (Wide-Column Store)&lt;/h3&gt;
&lt;p&gt;実データの保存には、Apache Cassandra（またはHBase等）のような &lt;strong&gt;Wide-Column Store&lt;/strong&gt; が採用されていると推察されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;なぜBlob Storageではないのか？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;単純なKVS（Key=ID、Value=JSON Blob）だと、一部のプロパティ（例：&lt;code&gt;status&lt;/code&gt;のみ）を取得したい場合でも、巨大なオブジェクト全体をメモリにロードする「Over-fetching」が発生します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Wide-Columnの利点&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;データは「行（Row）」の中に「列（Column）」の集合として保存されます。クライアントが必要なプロパティを指定すると、ストレージエンジンは &lt;strong&gt;該当するカラムのディスクブロックのみ&lt;/strong&gt; を読みに行きます。これにより、巨大なオブジェクトでも軽量にアクセス可能です。&lt;/p&gt;
&lt;h3&gt;2.2 検索・集計層：Elasticsearch (Search Engine)&lt;/h3&gt;
&lt;p&gt;「IDを指定して取得」以外の操作、つまり「検索」や「集計」にはElasticsearch（またはOpenSearch）を使用していると推測されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;役割分担 (Compute-Storage Separation)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Find (検索):&lt;/strong&gt; 「ステータスが『Error』の設備を探す」→ Elasticsearchのインデックスを叩き、対象の&lt;code&gt;ObjectID&lt;/code&gt;リストを高速に特定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fetch (取得):&lt;/strong&gt; 特定されたIDを使って、Cassandraから実データをHydrate（水分補給/実体化）する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;軽量集計のオフロード&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;「地域ごとの売上合計」のような集計クエリに対し、実データをスキャンするのは非効率です。Elasticsearchの&lt;code&gt;Aggregation&lt;/code&gt;機能（メモリ上の処理）を使うことで、DB負荷をかけずに高速に数値を返します。&lt;/p&gt;
&lt;h3&gt;2.3 トランザクション制御：AtlasDB&lt;/h3&gt;
&lt;p&gt;NoSQL（Cassandra）の弱点はACIDトランザクションの欠如ですが、Palantirは &lt;strong&gt;「AtlasDB」&lt;/strong&gt; という独自のミドルウェア層を被せることでこれを解決しているようです。これにより、 &lt;strong&gt;「NoSQLのスケーラビリティ」と「RDBの整合性」&lt;/strong&gt; を両立させています。&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;3. データ構造と「リンク」の正体&lt;/h2&gt;
&lt;p&gt;物理層の上にある論理層（オントロジー）では、データはどう定義されているのでしょうか？&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph LR
    %% データ構造の比較
    subgraph &quot;RDB Model (Table &amp;amp; JOIN)&quot;
        T_Machines[&quot;t_machines Table&quot;] -- JOIN --&amp;gt; T_Factories[&quot;t_factories Table&quot;]
        T_Machines -- JOIN --&amp;gt; T_Parts[&quot;t_parts Table&quot;]
        T_Parts -- JOIN --&amp;gt; T_Sensors[&quot;t_sensors Table&quot;]
        NoteRDB[&quot;巨大なJOIN計算が必要&amp;lt;br/&amp;gt;スキーマ変更が困難&quot;]
        T_Sensors --- NoteRDB
    end

    subgraph &quot;Ontology Model (Object &amp;amp; Link)&quot;
        O_Machine((&quot;Object: Machine&quot;)) -- Link: installed_at --&amp;gt; O_Factory((&quot;Object: Factory&quot;))
        O_Machine -- Link: uses_part --&amp;gt; O_Part((&quot;Object: Part&quot;))
        O_Part -- Link: monitored_by --&amp;gt; O_Sensor((&quot;Object: Sensor&quot;))
        NoteOntology[&quot;グラフ探索で辿る(高速)&amp;lt;br/&amp;gt;プロパティ追加が容易&quot;]
        O_Sensor --- NoteOntology
    end

    style O_Machine fill:#f9f,stroke:#333,color:black
    style O_Factory fill:#f9f,stroke:#333,color:black
    style O_Part fill:#f9f,stroke:#333,color:black
    style O_Sensor fill:#f9f,stroke:#333,color:black
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.1 オブジェクトのマッピング&lt;/h3&gt;
&lt;p&gt;SQLのテーブルをそのまま使うのではなく、 &lt;strong&gt;「オブジェクト」&lt;/strong&gt; として再定義します。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SQLの世界 (Raw Data)&lt;/th&gt;
&lt;th&gt;Ontologyの世界 (Semantic Layer)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SELECT * FROM t_machines&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Object: Machine (設備)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Column: &lt;code&gt;m_id&lt;/code&gt; (VARCHAR)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Primary Key&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Column: &lt;code&gt;temp_val&lt;/code&gt; (FLOAT)&lt;/td&gt;
&lt;td&gt;Property: &lt;code&gt;Temperature&lt;/code&gt; (時系列データとして扱える)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Column: &lt;code&gt;stat_code&lt;/code&gt; (INT)&lt;/td&gt;
&lt;td&gt;Property: &lt;code&gt;Status&lt;/code&gt; (Enum: &quot;Running&quot;, &quot;Stop&quot;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;このマッピングにより、LLMは「&lt;code&gt;t_machines&lt;/code&gt;テーブルの&lt;code&gt;temp_val&lt;/code&gt;」ではなく、 &lt;strong&gt;「設備の温度」&lt;/strong&gt; という自然言語に近い概念でデータにアクセスできます。&lt;/p&gt;
&lt;h3&gt;3.2 リンク（Link）≠ JOIN&lt;/h3&gt;
&lt;p&gt;ここが最大のポイントです。RDBのJOINは実行時に計算コストがかかりますが、オントロジーの「リンク」は &lt;strong&gt;グラフのエッジ（辺）&lt;/strong&gt; として事前定義されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;構造:&lt;/strong&gt; &lt;code&gt;[Machine: A] --(installed_at)--&amp;gt; [Factory: B]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;探索:&lt;/strong&gt; RDBのような直積（Cartesian Product）を作るのではなく、グラフ探索（トラバーサル）を行います。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;メリット:&lt;/strong&gt; 「この工場にある設備で作られた製品の、納品先顧客は？」といった4〜5段階のホップが必要なクエリでも、インデックスを辿るだけなので計算量が爆発しません。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;4. 動的ユースケース：Actionへの繋がり&lt;/h2&gt;
&lt;p&gt;この静的なアーキテクチャが、実際にどう動くのか。3つのユースケースでデータの流れを追います。&lt;/p&gt;
&lt;h3&gt;Case 1: 製造業 - サプライチェーンの断絶を繋ぐ（Write-back）&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;シナリオ:&lt;/strong&gt; 原材料の納入遅延が発生し、生産計画の見直しが必要。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flow:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Alert:&lt;/strong&gt; オントロジー上の「納入予定日」プロパティが更新され、閾値を超えたためAIPがアラート発報。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reasoning (LLM):&lt;/strong&gt; LLMがグラフを辿り、「代替サプライヤーB社」の在庫と単価を取得。「B社への発注」を推奨。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Human Loop:&lt;/strong&gt; 担当者が画面上で「承認」ボタンを押下。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Action (Write):&lt;/strong&gt; AIPがERP（SAP等）のAPIを叩き、発注データを書き込む。同時にオントロジー上のステータスも「発注済」に更新される。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Case 2: 病院運営 - リアルタイムリソース配分&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;シナリオ:&lt;/strong&gt; 急患搬送。ICUの空きがない。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flow:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ingest:&lt;/strong&gt; 電子カルテとベッドセンサーからリアルタイムデータをCassandraに吸い上げ。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Search:&lt;/strong&gt; Elasticsearchが「容態が安定（バイタル正常）かつ、一般病棟へ移動可能な患者」を数ミリ秒でリストアップ。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Action:&lt;/strong&gt; 看護師長のタブレットに「患者移動プラン」を提示し、ワンタップで病床管理システムへ反映。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Case 3: インフラ保守 - 非構造化データの統合&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;シナリオ:&lt;/strong&gt; 現場作業員がポンプの異音を検知。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flow:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Vector Search:&lt;/strong&gt; 作業員が音声で状況入力。AIPはベクトルDB（検索インデックスの一部）を使い、過去の「類似トラブル報告書（PDF）」を検索。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hybrid Retrieval:&lt;/strong&gt; 同時に、対象ポンプの「直近1週間の振動データ（構造化データ）」をKVSから取得。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Synthesis:&lt;/strong&gt; LLMが「3年前の事例に酷似しています。バルブBの摩耗を確認してください」と回答。&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;5. 💡 思考実験：自社ならどうなる？&lt;/h2&gt;
&lt;p&gt;最後に、Palantir AIPのコンセプトを自社に適用した場合のイメージを掴むためのプロンプトを用意しました。以下のプロンプトをChatGPTやClaudeに入力して、思考実験をしてみてください。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;## 役割
あなたはPalantir AIPのアーキテクトです。
私の会社/サービスである【ここに自社サービス名や業種を入れる】において、
バラバラに散らばっているデータソース（DB、SaaS、Excel等）を統合し、 「オントロジー（デジタルツイン）」を構築してください。

## 以下の形式で出力してください

1. 定義すべき主要な「オブジェクト」と「プロパティ」（3つ以上）
2. オブジェクト間の「リンク（関係性）」
3. AIが実行可能な「アクション（書き込み処理）」の具体例

## 参考資料
Palantir AIPのアーキテクチャのブレイクダウンはこの記事にまとまっています。
https://zenn.dev/matsubokkuri/articles/palantir-aip-architecture
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;おわりに&lt;/h2&gt;
&lt;p&gt;Palantir AIPの事例から学べることは、 &lt;strong&gt;「強力なAIアプリケーションを作るためには、強力なデータ基盤（データエンジニアリング）が不可欠である」&lt;/strong&gt; という事実です。&lt;/p&gt;
&lt;p&gt;LLM単体では、企業の複雑なコンテキストを理解できません。バラバラなデータを「オントロジー」として統合し、高速な検索と取得が可能なアーキテクチャ（Search + KVS）の上に載せることで初めて、AIは「おしゃべり」を超えて「仕事」ができるようになります。&lt;/p&gt;
&lt;p&gt;我々エンジニアが次に目指すべきは、単にプロンプトを工夫することではなく、AIが現実世界を正しく認識し、触れることができる &lt;strong&gt;「データのインターフェース」&lt;/strong&gt; を設計することなのです。&lt;/p&gt;
</content:encoded></item><item><title>APC BR550S バッテリー劣化でサーバーダウン | ログ解析</title><link>https://blog.teraren.com/posts/2025-11-27-apc-ups/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2025-11-27-apc-ups/</guid><description>APC BR550Sのバッテリー劣化により、セルフテスト時にサーバーがダウン。apcupsdログから読み取れる予兆と、高頻度セルフテストによるロシアンルーレット状態を解析。UPS交換までの対策を共有。</description><pubDate>Thu, 27 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;この記事について&lt;/h2&gt;
&lt;h3&gt;学べること&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;UPSバッテリー劣化時の危険な挙動（セルフテストによる自爆）&lt;/li&gt;
&lt;li&gt;apcupsdログから読み取る「死の予兆」の見つけ方&lt;/li&gt;
&lt;li&gt;バッテリー警告後の高頻度セルフテストのリスク&lt;/li&gt;
&lt;li&gt;安全マージンを取ったシャットダウン設定&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;想定読者&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;自宅サーバーやNASでUPSを運用している方&lt;/li&gt;
&lt;li&gt;UPSのバッテリー交換警告が出ているが「まだ動くから」と放置している方&lt;/li&gt;
&lt;li&gt;apcupsdのログ解析に興味がある方&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;前提条件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Linux環境でのapcupsd運用経験&lt;/li&gt;
&lt;li&gt;基本的なログ解析の知識&lt;/li&gt;
&lt;li&gt;推定所要時間: 読了10分&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;自宅サーバー運用において、最後の砦となるのがUPS（無停電電源装置）です。&lt;/p&gt;
&lt;p&gt;しかし、メンテを怠ると&lt;strong&gt;UPS自体がSPOF（単一障害点）となり、逆にサーバーをクラッシュさせる原因になる&lt;/strong&gt;という教科書通りの事象を経験しました。&lt;/p&gt;
&lt;p&gt;今回は、APC BR550Sのバッテリー寿命末期における挙動と、apcupsd（UPS監視・管理デーモン）のログから読み取れる「死の予兆」について共有します。&lt;/p&gt;
&lt;h2&gt;環境とハードウェア&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UPS&lt;/strong&gt;: APC BR550S (BR550S-JP)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OS&lt;/strong&gt;: Linux (Debian)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;管理ツール&lt;/strong&gt;: apcupsd 3.14.14&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;購入日&lt;/strong&gt;: 2021年4月12日&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;障害発生日&lt;/strong&gt;: 2025年11月27日（稼働期間：約4年7ヶ月）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;予兆&lt;/strong&gt;: 障害の約1ヶ月前からバッテリー交換警告（赤ランプ＆アラート）が発生&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B06XHZ3K5T&quot; kw=&quot;APC UPS BR550S&quot;}&lt;/p&gt;
&lt;h2&gt;何が起きたか&lt;/h2&gt;
&lt;p&gt;結論から言うと、&lt;strong&gt;「劣化したバッテリーを積んだUPSがセルフテスト（自己診断）を行い、その瞬間に電圧を維持できずサーバーごと落ちた」&lt;/strong&gt; という事象です。&lt;/p&gt;
&lt;p&gt;商用電源（コンセント）からは電気が来ているにも関わらず、UPSの挙動によって電源が断たれました。&lt;/p&gt;
&lt;h2&gt;ログによる解析&lt;/h2&gt;
&lt;h3&gt;1. 頻発する「死のロシアンルーレット」&lt;/h3&gt;
&lt;p&gt;通常、APCのUPSはデフォルトで &lt;strong&gt;14日（2週間）に1回&lt;/strong&gt; のセルフテストを行います。しかし、バッテリー交換警告が出ている末期状態では、挙動が異なりました。&lt;/p&gt;
&lt;p&gt;以下は &lt;code&gt;syslog&lt;/code&gt; の抜粋です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;864489:2025-11-24T12:46:04.978346+00:00 gmk apcupsd[1630084]: UPS Self Test switch to battery.
864490:2025-11-24T12:46:05.257428+00:00 gmk apcupsd[1630084]: UPS battery must be replaced.
864501:2025-11-24T12:46:07.025059+00:00 gmk apcupsd[1630084]: UPS Self Test completed: Warning

1166439:2025-11-25T01:30:53.985560+00:00 gmk apcupsd[1630084]: UPS Self Test switch to battery.
1166610:2025-11-25T01:30:54.989559+00:00 gmk apcupsd[1630084]: UPS Self Test completed: Warning

1579590:2025-11-25T14:15:40.478205+00:00 gmk apcupsd[1630084]: UPS Self Test switch to battery.
1579650:2025-11-25T14:15:50.698265+00:00 gmk apcupsd[1630084]: UPS Self Test completed: Warning

1911424:2025-11-26T03:00:33.260875+00:00 gmk apcupsd[1630084]: UPS Self Test switch to battery.
1911434:2025-11-26T03:00:35.334053+00:00 gmk apcupsd[1630084]: UPS Self Test completed: Warning
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ご覧の通り、&lt;strong&gt;約12時間〜13時間おき&lt;/strong&gt;に &lt;code&gt;UPS Self Test switch to battery&lt;/code&gt;（バッテリーへの切り替えテスト）が走っています。&lt;/p&gt;
&lt;p&gt;バッテリーが完全に死んでいる状態で、半日に1回、強制的にバッテリー駆動テストが行われる—つまり、&lt;strong&gt;1日に2回「運が悪ければ落ちる」ロシアンルーレットが自動実行されている状態&lt;/strong&gt;でした。&lt;/p&gt;
&lt;h3&gt;2. ログを残さず「即死」する瞬間&lt;/h3&gt;
&lt;p&gt;そして迎えた11月26日の夜。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2423952:2025-11-26T18:46:48.927315+00:00 gmk apcupsd[1630084]: UPS battery must be replaced.
（ここでログが途絶える）
2530548:2025-11-26T22:48:09.951429+00:00 gmk systemd[1]: Starting apcupsd.service - UPS power management daemon...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;18:46の定期ログを最後に、次は22:48の起動ログまで飛んでいます。&lt;/p&gt;
&lt;p&gt;通常、apcupsdがシャットダウンをトリガーした場合は &lt;code&gt;apcupsd exiting, signal 15&lt;/code&gt; といったログが残りますが、今回はそれすらありません。&lt;/p&gt;
&lt;p&gt;これは以下のプロセスで落ちたと推測されます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;何らかの理由（セルフテスト、あるいは瞬断）でUPSがバッテリー駆動に切り替わろうとする。&lt;/li&gt;
&lt;li&gt;バッテリーの内部抵抗が高すぎて、負荷（サーバー）を支えきれず電圧が瞬時にゼロになる。&lt;/li&gt;
&lt;li&gt;OSはログをディスクに書き込む暇もなく、物理的に電源が落ちる（Dirty Shutdown）。&lt;/li&gt;
&lt;li&gt;その後、商用電源が安定しているため、BIOSの「AC Power Recovery」設定により自動再起動。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;まさに**「UPSがついているからこそ落ちた（スルー出力なら耐えたかもしれない）」**という本末転倒な事態です。&lt;/p&gt;
&lt;h2&gt;教訓と対策&lt;/h2&gt;
&lt;h3&gt;1. アラートが出たら即交換、あるいはバイパスする&lt;/h3&gt;
&lt;p&gt;「まだ動いてるし、来週交換しよう」は危険です。&lt;/p&gt;
&lt;p&gt;アラートが出ているUPSは、保護装置ではなく&lt;strong&gt;時限爆弾&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;交換用バッテリーが手元にない場合は、サーバーのコンセントをUPSから抜き、&lt;strong&gt;壁のコンセント（商用電源）に直結する&lt;/strong&gt;方が、テストによる自爆リスクがない分だけ安全です。&lt;/p&gt;
&lt;h3&gt;2. apcupsdの設定見直し&lt;/h3&gt;
&lt;p&gt;今回の設定（&lt;code&gt;/etc/apcupsd/apcupsd.conf&lt;/code&gt;）を確認したところ、以下のようになっていました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BATTERYLEVEL 5
MINUTES 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;「残り5%」または「残り3分」まで粘る設定です。&lt;/p&gt;
&lt;p&gt;新品バッテリーならこれで良いですが、劣化したバッテリーでは「残り3分」と表示されていても、負荷がかかった瞬間に電圧降下で落ちる可能性があります。&lt;/p&gt;
&lt;p&gt;安全マージンを取り、以下のように早めに倒す設定へ変更することをおすすめします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BATTERYLEVEL 15  # 15%を切ったらシャットダウン
MINUTES 10       # 残り10分を切ったらシャットダウン
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;寿命&lt;/strong&gt;: APC BR550Sは約4年7ヶ月（2021年4月〜2025年11月）で交換となりました&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;危険な挙動&lt;/strong&gt;: バッテリー警告が出ると、高頻度（半日ごと）でセルフテストが走り、リスクが跳ね上がります&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;重要な対策&lt;/strong&gt;: アラートが出たら即座に交換、あるいは商用電源に直結してバイパスする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;apcupsd設定&lt;/strong&gt;: &lt;code&gt;BATTERYLEVEL&lt;/code&gt; と &lt;code&gt;MINUTES&lt;/code&gt; を余裕を持った値に設定（15%、10分を推奨）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;予兆の見つけ方&lt;/strong&gt;: ログに &lt;code&gt;Power failure&lt;/code&gt; や &lt;code&gt;Switch to battery&lt;/code&gt; が頻発し始めたら要注意&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2025年11月27日、新しいUPSへのリプレイスが完了し、平穏なログが戻ってきました。&lt;/p&gt;
&lt;p&gt;皆さんの家のUPSも、バッテリーランプが赤く光っていないか今すぐ確認を。&lt;/p&gt;
</content:encoded></item><item><title>Amexカード不正利用未遂 | 3Dセキュアで阻止</title><link>https://blog.teraren.com/posts/2025-11-26-amex-fraud/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2025-11-26-amex-fraud/</guid><description>メルカリでAmexカードの不正利用を検知。3Dセキュア認証で決済を阻止し、カード再発行を依頼。実害なし、3日で新カード受領。Mercari_browserの加盟店名と対応手順を記録。</description><pubDate>Tue, 25 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;ことの発端&lt;/h2&gt;
&lt;p&gt;SNSと電子メール宛に3Dセキュア（本人認証サービス）の認証コードが届きました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/11/2025-11-26-12-47-01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;手元で調査&lt;/h2&gt;
&lt;p&gt;まず、この送信元がクレジットカードの発行元からの正規のメールかどうかを確認するため、メールアドレスをググってみた。過去にも同じメールアドレスが使われていることが確認でき、怪しい情報も出てこなかったため、フィッシングメールではないと判断した。&lt;/p&gt;
&lt;p&gt;通知内容を見ると、&lt;code&gt;Mercari_browser&lt;/code&gt; という加盟店からの請求となっている。しかし、最近メルカリで買い物をした覚えはまったくない。&lt;/p&gt;
&lt;p&gt;さらに、決済金額が9,700円と、絶妙に10,000円を下回る少額であることも不自然に感じた。これらのことから、メルカリでの不正利用である可能性が高いと判断した。&lt;/p&gt;
&lt;h2&gt;クレカ会社に問い合わせ&lt;/h2&gt;
&lt;p&gt;クレジットカード会社に電話で問い合わせたところ、この3Dセキュア認証の通知は本物であることが確認できた。ただし、私自身は決済を試みていないため、第三者による不正利用の試みであることが判明した。&lt;/p&gt;
&lt;p&gt;クレジットカード番号とセキュリティコードが何らかの経路で流出し、不正に使用されようとしている可能性が高いとのこと。&lt;/p&gt;
&lt;p&gt;不正利用を防止するため、カード番号の再発行を依頼した。新しいカードが届くまでには約1週間かかるとのことだった。&lt;/p&gt;
&lt;p&gt;なお、&lt;code&gt;Mercari_browser&lt;/code&gt; という加盟店名は一見怪しく見えるが、これがメルカリの正式な加盟店名であることも確認できた。&lt;/p&gt;
&lt;h2&gt;その後&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;すでに登録済みの前提で、Amazonでは利用が継続できると電話口で行っていたが、できなかった。（家族カードを自分で使って回避できた）&lt;/li&gt;
&lt;li&gt;3日後に速達郵便で再発行された新しいクレジットカードを受け取れた。&lt;/li&gt;
&lt;li&gt;Apple Payに登録してあったカードは新しい番号に勝手に置き換わっていたので再登録の必要は無い。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>WordPressサイトをAstroへ移行：4700記事のビルドが10秒で完了する構成</title><link>https://blog.teraren.com/posts/moving-covid-19-to-astro-from-wordpress/</link><guid isPermaLink="true">https://blog.teraren.com/posts/moving-covid-19-to-astro-from-wordpress/</guid><description>前回、WordPress で作られた写真ポートフォリオサイトを Astroに移管してみたときにメリットしかなかったので、引き続きWordPressサイトをAstroに移管していきます。</description><pubDate>Thu, 30 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;約4700記事&lt;/strong&gt;の WordPress サイトを Astro へ移行し、&lt;strong&gt;ビルド時間はわずか10秒&lt;/strong&gt;を実現&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;wordpress-export-to-markdown&lt;/strong&gt;を使ってコンテンツを自動変換、Claude Code で効率的にデータ処理&lt;/li&gt;
&lt;li&gt;Cloudflare Pages で&lt;strong&gt;無料ホスティング&lt;/strong&gt;、Lighthouse スコア 100 点達成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全文検索機能&lt;/strong&gt;も pagefind で実装、トータルの移行作業は&lt;strong&gt;数時間&lt;/strong&gt;で完了&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WordPress サイトを静的サイトジェネレーターへ移行したい方&lt;/li&gt;
&lt;li&gt;大量のコンテンツを効率的に移行する方法を知りたい方&lt;/li&gt;
&lt;li&gt;Astro を使った実践的な移行事例を参考にしたい方&lt;/li&gt;
&lt;li&gt;サーバー運用コストを削減したい方&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;前回、WordPress で作られた写真ポートフォリオサイトを &lt;a href=&quot;https://zenn.dev/matsubokkuri/articles/moving-to-astro-from-wordpress&quot;&gt;Astroに移管&lt;/a&gt;してみたときにメリットしかなかったので、引き続きWordPressサイトをAstroに移管していきます。&lt;/p&gt;
&lt;p&gt;移管が簡単なサイトから順番に置き換えていく方針です。&lt;/p&gt;
&lt;p&gt;今回移行したサイトはこちら:
https://covid19.teraren.com/&lt;/p&gt;
&lt;h2&gt;UIの変化&lt;/h2&gt;
&lt;p&gt;まずは見た目の変化を確認しましょう。&lt;/p&gt;
&lt;h3&gt;Before&lt;/h3&gt;
&lt;p&gt;トップページ
&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-31-03-34-29.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;個別ページ
&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-31-03-35-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;After&lt;/h3&gt;
&lt;p&gt;トップページ
&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-31-03-03-56.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;個別ページ
&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-31-03-04-08.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;移行手順の概要&lt;/h2&gt;
&lt;p&gt;WordPress から Astro への移行手順を以下にまとめます。各ステップの詳細はこの後に説明します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;移行前サイトの特性理解&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Astroのテンプレート探し&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Astroプロジェクトの初期化&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WordPressからのフルバックアップ取得&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バックアップデータのAstroへの復元&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Astro上での各種調整&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Pagesへのデプロイ&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;0. 移行前サイトの特性理解&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;記事数は約4700記事&lt;/strong&gt;。毎日 × 10 都道府県 × 2 年間のデータ（期間や都道府県に歯抜けが多い）で構成されています。
各記事の文章は短く、&lt;strong&gt;画像のグラフが重要なコンテンツ&lt;/strong&gt;となっています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;URL構造を維持する必要があります&lt;/strong&gt;。記事数が膨大なため、リダイレクトではなく同じ URL フォーマットを保持します。&lt;/p&gt;
&lt;p&gt;URL フォーマット:
&lt;code&gt;https://covid19.teraren.com/&amp;lt;year&amp;gt;/&amp;lt;month&amp;gt;/&amp;lt;day&amp;gt;/&amp;lt;slug&amp;gt;/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;URL 例:
&lt;code&gt;https://covid19.teraren.com/2022/09/25/ishikawa-560/&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;PV はほとんど無いサイトなので、サクッとデータを移行してサーバー運用を楽にしたいというのが今回の狙いです。&lt;/p&gt;
&lt;h2&gt;1. Astroのテンプレート探し&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://astro.build/themes/&quot;&gt;Astro公式サイトのテーマライブラリ&lt;/a&gt;から、Freeのフラグをオンにしてサクッと探しました。&lt;/p&gt;
&lt;p&gt;今回見つけたのがこちらの &lt;a href=&quot;https://github.com/Mrahmani71/astro-news&quot;&gt;Astro News&lt;/a&gt;。シンプルなUIでニュースサイト用のUXを提供するテーマです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-31-04-27-01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2. Astroプロジェクトの初期化&lt;/h2&gt;
&lt;p&gt;今回は公式提供のテーマではないため、GitHub リポジトリを直接 clone して使います。MIT ライセンスなので安心して利用できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone git@github.com:Mrahmani71/astro-news.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完成品をcloneしているので、あとは自分好みにパパっと変更していくだけです。&lt;/p&gt;
&lt;p&gt;リポジトリをcloneしただけだとパッケージが古い可能性があるため、最新版にアップデートしておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm update
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. WordPressからのデータエクスポート&lt;/h2&gt;
&lt;p&gt;WordPressの管理画面から「ツール」→「エクスポート」を選択してデータをエクスポートします。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;warning&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;ここで取得できるのはテキストデータ（投稿内容、メタデータなど）のみです。アップロードされている画像などのアセットはURL形式のリンクとして記録されます。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;でも大丈夫！　次のステップで使用するツールが、XMLファイル内のアセットURLを検知して&lt;strong&gt;自動的にローカルにダウンロード&lt;/strong&gt;してくれます。優秀！&lt;/p&gt;
&lt;p&gt;エクスポートファイルは &lt;code&gt;covid19.WordPress.2025-10-23.xml&lt;/code&gt; のようなファイル名で保存されます。&lt;/p&gt;
&lt;h2&gt;4. データのMarkdown変換&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/lonekorean/wordpress-export-to-markdown&quot;&gt;wordpress-export-to-markdown&lt;/a&gt;を使ってWordPressのデータをMarkdownに変換します。&lt;/p&gt;
&lt;p&gt;このツールを実行すると、エクスポートファイルの場所や展開方法について対話形式で質問されるため、順番に答えていきます。&lt;/p&gt;
&lt;p&gt;今回は投稿のタイトルやカテゴリ、画像ファイルが整理された状態で取得できれば十分だったため、シンプルな構成を選択しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; npx wordpress-export-to-markdown

Starting wizard...
✓ Path to WordPress export file? covid-yukimatsukura.WordPress.2025-10-24.xml
✓ Put each post into its own folder? No
✓ Add date prefix to posts? No
✓ Organize posts into date folders? No
✓ Save images? All Images

Parsing...
54 normal posts found.
1 pages found.
81 attached images found.
55 images scraped from post body content.

Saving posts...
55 posts to save.
✓ [post] shou-ren-in
✓ [post] umbrella
✓ [post] maple-on-the-moss
✓ [post] tanuki-ko
✓ [post] skytree
✓ [post] skytree-2
✓ [post] tokyo-tower
✓ [post] summer-morning
✓ [post] relais-la-suvera
✓ [post] ginza
✓ [post] relais-la-suvera
✓ [post] colosseo
✓ [post] grotta-azzurra
✓ [post] venetia
✓ [post] positano
✓ [post] eiffel-tower
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;すべての画像データが自動的にダウンロードされます。
&lt;strong&gt;容量は約800MB&lt;/strong&gt;ありました。Cloudflare Pagesの無料プランでホスティングする予定だったため、上限に引っかかる可能性を心配していましたが、&lt;strong&gt;問題なく無料枠でデプロイ&lt;/strong&gt;できました。&lt;/p&gt;
&lt;h2&gt;5. Astroへのデータインポート&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;約4700記事&lt;/strong&gt;あるため、CLIで効率的にデータをコンバートする必要がありました。shellとの相性が良いClaude Codeを使用してコンバート処理を実装しました。&lt;/p&gt;
&lt;p&gt;プロンプトは以下のように簡潔に書きましたが、これで&lt;strong&gt;すべての記事を自動変換&lt;/strong&gt;できました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;こちらのサイト(https://covid19.teraren.com/) をAstroで再構築します。このレポジトリを基本として進めます。 covid19.teraren.com の全部の記事はexportして covid19-WordPress.2025-10-29.xml に保管してあります。
このXMLファイルを処理して、markdownでコンバートして、画像ファイルを保管したディレクトリが、 `output/`
以下になります。

このコンテンツをカレントディレクトリのAstroのレポジトリでインポートしてください。XMLファイルは巨大なので一気に読み込まないでください。covid19.teraren.com をチェックしてもらえればわかると思いますが、コンテンツとしては4000ページあります。整理の方法は、日本の都道府県ごとに、1日1つの記事が生成されます。記事の内容は短いです。

記事には1つの画像があり、その画像が重要な画像となります。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Claude Codeは、データのコンバートと同時に各ページを表示するAstroファイルも生成してくれました。処理の後半で細かな実装方法について質問されたため、いくつか回答するだけで完了しました。&lt;/p&gt;
&lt;h3&gt;画像ファイルの配置方法&lt;/h3&gt;
&lt;p&gt;大きな論点として、画像ファイルをどう管理するかという点がありました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;選択肢:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;src/&lt;/code&gt; 以下に配置してAstroの画像最適化を利用する&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public/&lt;/code&gt; 以下に置いて単純に読み込む&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;前者が理想的ですが、&lt;strong&gt;ビルド時間が長くなる&lt;/strong&gt;こと、そしてサイトへのアクセスがほとんど無いため最適化の優先度が低いという理由で、&lt;strong&gt;&lt;code&gt;public/&lt;/code&gt; に配置する方針&lt;/strong&gt;を選択しました。&lt;/p&gt;
&lt;p&gt;この方法により、&lt;strong&gt;コンテキストの消費を抑えつつ、高速にインポート&lt;/strong&gt;できました。データをGit add, git commitする際は、ファイル数が多いため約1分かかりました。&lt;/p&gt;
&lt;p&gt;作られたファイルは以下のような構造です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ fd mdx src/|head -n 50
src/content/views/error404.mdx
src/content/views/authors.mdx
src/content/views/articles.mdx
src/content/views/categories.mdx
src/content/views/author.mdx
src/content/views/home.mdx
src/content/views/search.mdx
src/content/views/contact.mdx
src/content/covid19/2021/12/ishikawa-295.mdx
src/content/covid19/2021/12/kanagawa-384.mdx
src/content/covid19/2021/12/kanagawa-390.mdx
src/content/covid19/2021/12/kanagawa-385.mdx
src/content/covid19/2021/12/ishikawa-294.mdx
src/content/covid19/2021/12/gifu-269.mdx
src/content/covid19/2021/12/ishikawa-296.mdx
src/content/covid19/2021/12/kanagawa-378.mdx
src/content/covid19/2021/12/kanagawa-387.mdx
src/content/covid19/2021/12/kanagawa-386.mdx
src/content/covid19/2021/12/kanagawa-379.mdx
src/content/covid19/2021/12/ishikawa-297.mdx
src/content/covid19/2021/12/ishikawa-287.mdx
src/content/covid19/2021/12/ishikawa-293.mdx
src/content/covid19/2021/12/kanagawa-369.mdx
src/content/covid19/2021/12/kanagawa-382.mdx
src/content/covid19/2021/12/kanagawa-383.mdx
src/content/covid19/2021/12/kanagawa-368.mdx
src/content/covid19/2021/12/ishikawa-292.mdx
src/content/covid19/2021/12/ishikawa-290.mdx
src/content/covid19/2021/12/kanagawa-381.mdx
src/content/covid19/2021/12/kanagawa-380.mdx
src/content/covid19/2021/12/ishikawa-291.mdx
src/content/covid19/2021/12/tokyo-383.mdx
src/content/covid19/2021/12/tokyo-354.mdx
src/content/covid19/2021/12/tokyo-368.mdx
src/content/covid19/2021/12/mie-187.mdx
src/content/covid19/2021/12/mie-186.mdx
src/content/covid19/2021/12/tokyo-369.mdx
src/content/covid19/2021/12/tokyo-355.mdx
src/content/covid19/2021/12/tokyo-382.mdx
src/content/covid19/2021/12/tokyo-380.mdx
src/content/covid19/2021/12/tokyo-357.mdx
src/content/covid19/2021/12/mie-184.mdx
src/content/covid19/2021/12/kochi-2.mdx
src/content/covid19/2021/12/mie-185.mdx
src/content/covid19/2021/12/tokyo-356.mdx
src/content/covid19/2021/12/tokyo-381.mdx
src/content/covid19/2021/12/fukui-189.mdx
src/content/covid19/2021/12/fukui-172.mdx
src/content/covid19/2021/12/tokyo-352.mdx
src/content/covid19/2021/12/mie-181.mdx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;画像ファイルは以下のような構造になります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ fd &apos;gruff.*png&apos; public/ | head -n 20
public/images/hero/gruff20220926-1-r4c6mc-cut.png
public/images/2022/06/gruff20220624-1-okz7x0.png
public/images/2022/06/gruff20220607-1-h6ieww.png
public/images/2022/06/gruff20220629-1-dv16k9.png
public/images/2022/06/gruff20220625-1-7l432r.png
public/images/2022/06/gruff20220605-1-n4hq4x.png
public/images/2022/06/gruff20220623-1-tumiku.png
public/images/2022/06/gruff20220618-1-6cb8hw.png
public/images/2022/06/gruff20220625-1-708n0u.png
public/images/2022/06/gruff20220626-1-pqm5nt.png
public/images/2022/06/gruff20220624-1-udulbu.png
public/images/2022/06/gruff20220605-1-ramra9.png
public/images/2022/06/gruff20220622-1-qpzcon.png
public/images/2022/06/gruff20220618-1-bb9fyw.png
public/images/2022/06/gruff20220604-1-gupi4z.png
public/images/2022/06/gruff20220602-1-90m8te.png
public/images/2022/06/gruff20220602-1-jybrnb.png
public/images/2022/06/gruff20220605-1-b613w6.png
public/images/2022/06/gruff20220601-1-r4d1em.png
public/images/2022/06/gruff20220606-1-pw5yvo.png
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;全文検索機能の実装&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://pagefind.app/&quot;&gt;pagefind&lt;/a&gt;を使って、静的サイトでも全文検索できるようにします。&lt;/p&gt;
&lt;p&gt;Astroとのインテグレーションキットがあるため導入は簡単です。インクリメンタルに全文検索が動作します:
https://covid19.teraren.com/search/?q=%E6%9D%B1%E4%BA%AC&lt;/p&gt;
&lt;p&gt;全文検索用のインデックスはビルド時に作成されます。&lt;strong&gt;今回は約3分（206秒）かかりました&lt;/strong&gt;。
結構時間がかかるため導入はトレードオフですね。今回のサイトでは全文検索のユースケースはほとんど無いと思いますが、将来的な拡張性を考慮して実装しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;02:28:45.462	17:28:45 [@astrojs/sitemap] `sitemap-index.xml` created at `dist`
02:28:48.462	17:28:48 [build] Waiting for integration &quot;pagefind&quot;, hook &quot;astro:build:done&quot;...
02:29:03.469	17:29:03 [pagefind] Pagefind indexed 5222 pages
02:29:03.476	17:29:03 [pagefind] Pagefind wrote index to /opt/buildhome/repo/dist/pagefind
02:29:03.477	17:29:03 [build] 5222 page(s) built in 206.27s
02:29:03.477	17:29:03 [build] Complete!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ビルドされたインデックスファイルは静的ファイルとしてデプロイされ、ブラウザからダウンロードされます。検索はブラウザ上のJavaScriptランタイムで実行される仕組みです。
&lt;strong&gt;ダウンロードされたインデックスサイズは約70KB&lt;/strong&gt;と軽量でした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-31-09-40-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;サーバサイドに保存されているindexはファイルごとに分割されいて、19MBでした。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ du -hs dist/pagefind/
 19M    dist/pagefind/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;6. Cloudflare Pagesへのデプロイ&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pages.cloudflare.com/&quot;&gt;Cloudflare Pages&lt;/a&gt;でGitHubと連携して、今回作成したリポジトリを指定します。リポジトリのタイプを&lt;code&gt;Astro&lt;/code&gt;と選んでデプロイボタンをポチッと押したら、&lt;strong&gt;約6分後にデプロイ完了&lt;/strong&gt;しました。&lt;/p&gt;
&lt;p&gt;データ容量が約 1GB、pnpm build で出力されたファイル数は&lt;strong&gt;1万以上&lt;/strong&gt;あるため、ネットワーク転送とディスク I/O に時間がかかっています。&lt;/p&gt;
&lt;p&gt;今回もほとんど更新が無い静的コンテンツのため、&lt;strong&gt;CloudflareのCDNを有効化&lt;/strong&gt;して配信しています。&lt;/p&gt;
&lt;h2&gt;パフォーマンスベンチマーク&lt;/h2&gt;
&lt;p&gt;今回は大きな写真データは無いですし、UI もこだわっていないのでパフォーマンスが良いです。&lt;/p&gt;
&lt;h3&gt;トップページのLighthouseスコア&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-31-03-56-33.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;個別ページのLighthouseスコア&lt;/h3&gt;
&lt;p&gt;画像関連の最適化を入れていないのでスコアは少し低めに出ています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-31-03-57-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ビルド時間の内訳&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;約4700ページ&lt;/strong&gt;分のデプロイ時間は&lt;strong&gt;約7分&lt;/strong&gt;でした。
内訳は以下のとおりです:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;データのダウンロード＋ビルド環境の構築：&lt;strong&gt;1分&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;ページの生成: &lt;strong&gt;10秒&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;全文検索インデックスの作成：&lt;strong&gt;3分&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;ファイルのデプロイ: &lt;strong&gt;2分&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;意外にも、&lt;strong&gt;全文検索機能のインデックス作成が一番時間がかかる&lt;/strong&gt;処理になっています。ページの生成自体は驚異的な速さです。&lt;/p&gt;
&lt;h2&gt;実際に使ってみた感想&lt;/h2&gt;
&lt;h3&gt;良かった点&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;圧倒的なビルド速度&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;4700ページのビルドがわずか10秒&lt;/strong&gt;で完了&lt;/li&gt;
&lt;li&gt;開発サーバーの起動も速く、ファイル変更時のホットリロードもサクサク動作&lt;/li&gt;
&lt;li&gt;プロダクション環境では静的 HTML を配信するため、サーバーサイドの処理が不要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;自動最適化が優秀&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;画像の遅延読み込み、CSS の最小化など、Web パフォーマンスに必要な最適化を自動で実施&lt;/li&gt;
&lt;li&gt;特別な設定なしで Lighthouse スコア 100 点を達成&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;モダンな開発体験&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生の HTML に近い形でレンダリングを高速化しつつ、開発体験は React ライク&lt;/li&gt;
&lt;li&gt;必要な部分だけ JavaScript を使う「アイランドアーキテクチャ」により、パフォーマンスと開発効率を両立&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;運用コストゼロ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cloudflareの無料プランで運用可能&lt;/strong&gt;、月額費用ゼロを実現&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;課題と改善点&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;全文検索のビルド時間&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pagefind のインデックス作成に&lt;strong&gt;約3分&lt;/strong&gt;かかる。手動でビルドして Git に入れるような運用でも良いが、pagefind がそのようなワークフローに対応していなさそうなので面倒そう。&lt;/li&gt;
&lt;li&gt;全文検索が不要なサイトでは、このステップを省略することでビルド時間を大幅に短縮できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;約4700記事&lt;/strong&gt;の WordPress サイトを Astro へ移行し、想像以上にスムーズに完了しました。&lt;/p&gt;
&lt;p&gt;wordpress-export-to-markdown などの専用ツールが充実しているため、技術的なハードルは低く、&lt;strong&gt;数時間程度の作業で移行が完了&lt;/strong&gt;しました。&lt;/p&gt;
&lt;h3&gt;得られた成果&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;圧倒的なパフォーマンス向上&lt;/strong&gt; - Lighthouse スコア 100 点達成&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ビルド時間の劇的な短縮&lt;/strong&gt; - 4700 ページが 10 秒でビルド完了&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保守性の向上&lt;/strong&gt; - Git 管理で変更履歴を追跡可能に&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用コストゼロ&lt;/strong&gt; - Cloudflare Pages で無料ホスティング&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開発体験の向上&lt;/strong&gt; - 開発サーバーもビルドも爆速&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ディスク容量の節約&lt;/strong&gt; - 3.3GB =&amp;gt; 800MB。1/4 になりました。画像に対して複数のサイズのサムネイルを保持しないようにしたので削減できました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>WordPressからAstroへ移行してサイト表示速度を改善した記録</title><link>https://blog.teraren.com/posts/moving-to-astro-from-wordpress/</link><guid isPermaLink="true">https://blog.teraren.com/posts/moving-to-astro-from-wordpress/</guid><description>業務で Astro を調査していたら、Astro で作ったウェブサイトの表示速度がめちゃくちゃ速くて驚愕しました。開発サーバの起動やビルドも爆速です。</description><pubDate>Mon, 27 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WordPress で運用していた写真ポートフォリオサイトを Astro に移行した&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;移行作業は数時間で完了&lt;/strong&gt;し、専用ツールでサクッと移行できた&lt;/li&gt;
&lt;li&gt;Lighthouse スコアが大幅改善し、&lt;strong&gt;めちゃくちゃ速いサイト&lt;/strong&gt;になった&lt;/li&gt;
&lt;li&gt;開発サーバの起動やビルドも高速で、開発体験も良好&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WordPress から静的サイトへの移行を検討している方&lt;/li&gt;
&lt;li&gt;Astro に興味があり、実際の移行事例を知りたい方&lt;/li&gt;
&lt;li&gt;写真やポートフォリオサイトを高速化したい方&lt;/li&gt;
&lt;li&gt;静的サイトジェネレーターの導入を考えている方&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;業務で Astro を調査していたら、Astro で作ったウェブサイトの表示速度がめちゃくちゃ速くて驚愕しました。開発サーバの起動やビルドも爆速です。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Astroって何？&lt;/strong&gt;
Astro は、コンテンツ重視の高速なウェブサイトを構築するための静的サイトジェネレーター（SSG）です。デフォルトで JavaScript をクライアントに送信せず、必要な部分だけをハイドレーション（動的に機能を追加）する「アイランドアーキテクチャ」を採用しています。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;WordPress からの移行ツールも充実しているので、重い腰を上げて WordPress で運用していた写真ポートフォリオサイトを Astro に移行してみました。&lt;/p&gt;
&lt;p&gt;そもそも、なぜ自分でサイトを構築したのかというと、
Flickr や 500px といった写真共有サービスだと 1 ファイルあたりの最大容量制限があって、高画質なファイルをフル解像度でアップロードできる場所がなかったんです。だから自分でホスティングする方針にしました。&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;まずは見た目の変化&lt;/p&gt;
&lt;h3&gt;Before&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-27-19-26-51.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;After&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-27-19-28-29.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;https://portfolio.teraren.com/&lt;/p&gt;
&lt;h2&gt;移行手順の概要&lt;/h2&gt;
&lt;p&gt;WordPress から Astro への移行手順を以下にまとめます。各ステップの詳細はこの後に説明します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Astroのテンプレート探し&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Astroプロジェクトの初期化&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WordPressからのフルバックアップ取得&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バックアップデータのAstroへの復元&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Astro上での各種調整&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Pagesへのデプロイ&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;1. Astroのテンプレート探し&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://astro.build/themes/&quot;&gt;Astro公式サイトのテーマライブラリ&lt;/a&gt;から、Freeのフラグをオンにしてサクッと探します。&lt;/p&gt;
&lt;p&gt;今回見つけたのがこちらの &lt;a href=&quot;https://astro.build/themes/details/photography-portfolio-template/&quot;&gt;Photography Portfolio Template&lt;/a&gt;。トップページと一覧ページだけのシンプルな構成です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-28-07-49-08.png&quot; alt=&quot;&quot; /&gt;
もともと写真を掲載しているだけのサイトだし、Astro 初心者だったのでシンプルな方が良いと思ってこれを選びました。&lt;/p&gt;
&lt;h2&gt;2. Astroプロジェクトの初期化&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/withastro/astro/tree/main/examples&quot;&gt;Astro公式のテンプレート&lt;/a&gt;であれば、コマンド1発で初期化できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm create astro@latest -- --template blog
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;でも今回は公式提供のテーマじゃないので、GitHubリポジトリをcloneして使います。MITライセンスなので安心。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone git@github.com:rockem/astro-photography-portfolio.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完成品をcloneしてるので、あとは自分好みにパパっと変更していくだけ。デモ用の写真データがそのまま入ってるので、それをサンプルとして参照しながら置き換えていく感じです。元データがサンプルとして使えるので学習が捗りました。&lt;/p&gt;
&lt;p&gt;リポジトリをcloneしただけだとパッケージが古い可能性があるので、最新版にアップデートしておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm update
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. WordPressからのフルバックアップ取得&lt;/h2&gt;
&lt;p&gt;まず、WordPressの管理画面から「ツール」→「エクスポート」を選択してフルバックアップを取得します。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;warning&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;ここで取得できるのはテキストデータ（投稿内容、メタデータなど）だけです。アップロードされている画像などのアセットはURL形式のリンクとして記録されてます。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;でも大丈夫！　後述するAstroインポートツールが、XMLファイル内のアセットURLを検知して自動的にローカルにダウンロードしてくれます。優秀！&lt;/p&gt;
&lt;p&gt;エクスポートファイルは &lt;code&gt;portfolio.WordPress.2025-10-23.xml&lt;/code&gt; みたいなファイル名で保存されます。&lt;/p&gt;
&lt;h2&gt;4. バックアップデータのAstroへの復元&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/lonekorean/wordpress-export-to-markdown&quot;&gt;wordpress-export-to-markdown&lt;/a&gt;というツールを使います。&lt;/p&gt;
&lt;p&gt;このツールを実行すると、エクスポートファイルの場所や展開方法について対話形式で質問されるので、サクッと答えていきます。&lt;/p&gt;
&lt;p&gt;今回は投稿のタイトルやカテゴリ、画像ファイルが整理された状態で取得できれば十分だったので、そのように選択しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npx wordpress-export-to-markdown

Starting wizard...
✓ Path to WordPress export file? photoportfolio-yukimatsukura.WordPress.2025-10-24.xml
✓ Put each post into its own folder? No
✓ Add date prefix to posts? No
✓ Organize posts into date folders? No
✓ Save images? All Images

Parsing...
54 normal posts found.
1 pages found.
81 attached images found.
55 images scraped from post body content.

Saving posts...
55 posts to save.
✓ [post] shou-ren-in
✓ [post] umbrella
✓ [post] maple-on-the-moss
✓ [post] tanuki-ko
✓ [post] skytree
✓ [post] skytree-2
✓ [post] tokyo-tower
✓ [post] summer-morning
✓ [post] relais-la-suvera
✓ [post] ginza
✓ [post] relais-la-suvera
✓ [post] colosseo
✓ [post] grotta-azzurra
✓ [post] venetia
✓ [post] positano
✓ [post] eiffel-tower
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;5. Astro上での各種調整&lt;/h2&gt;
&lt;p&gt;今回選択したテンプレートでは、&lt;code&gt;src/gallery/gallery.yml&lt;/code&gt;ファイルで画像とそのメタ情報を管理してます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;collections:
  - id: kyoto
    name: Kyoto
  - id: japan
    name: Japan
images:
  - path: japan/dsc_7137.jpg
    meta:
      title: calm moss and water
      description: Calm pound and stone with moss.
      collections:
        - japan
      tags:
        - Koishikawa Korakuen Garden
        - Japan
        - Tokyo
    exif:
      captureDate: 2015-11-28T10:40:21.000Z
      fNumber: 8
      focalLength: 70
      iso: 125
      model: NIKON D800
      shutterSpeed: 15
      lensModel: 24.0-70.0 mm f/2.8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;先ほど展開したWordPressのデータを、このYAML形式にコンバートします。ファイルの変換はCline（AIコーディングアシスタント）経由でClaude 3.5 Sonnetに実行させました。めちゃくちゃ便利。&lt;/p&gt;
&lt;p&gt;その他、以下のようなカスタマイズを実施：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UIの調整&lt;/li&gt;
&lt;li&gt;写真1枚ごとにパーマリンクを持つ個別ページの追加&lt;/li&gt;
&lt;li&gt;Sitemap XMLの追加&lt;/li&gt;
&lt;li&gt;トップページにHeroセクションの追加&lt;/li&gt;
&lt;li&gt;レスポンシブ対応のためのサムネイル画像を複数サイズで生成&lt;/li&gt;
&lt;li&gt;dark mode対応&lt;/li&gt;
&lt;li&gt;footerの追加&lt;/li&gt;
&lt;li&gt;prefetchの追加&lt;/li&gt;
&lt;li&gt;robots.txtの追加&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;6. Cloudflare Pagesへのデプロイ&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pages.cloudflare.com/&quot;&gt;Cloudflare Pages&lt;/a&gt;でGitHubと連携して、今回作ったリポジトリを指定。リポジトリのタイプを&lt;code&gt;Astro&lt;/code&gt;と選んでデプロイボタンをポチッと押したら、&lt;strong&gt;約2分後にデプロイ完了&lt;/strong&gt;しました。速い！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-27-23-46-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;使ってるドメインは&lt;a href=&quot;https://zenn.dev/matsubokkuri/articles/cloudflare-service&quot;&gt;Cloudflareで管理&lt;/a&gt;してるので、ProxyモードをオンにするだけでCDN経由での高速配信が実現できてます。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h2&gt;パフォーマンスベンチマーク&lt;/h2&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lighthouseって何？&lt;/strong&gt;
Googleが提供するWebサイトの品質測定ツールです。パフォーマンス、アクセシビリティ、SEOなどを100点満点で評価してくれます。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;カスタムフォントの読み込みと、画像拡大表示用のLightBoxライブラリのJavaScriptロードがあるので、スコアはやや抑えめです。でも、&lt;strong&gt;特別な最適化を施さずにこれだけリッチな見た目と機能があるのに、このスコアは優秀！&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;トップページのLighthouseスコア&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-27-23-49-09.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;写真個別ページのLighthouseスコア&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-27-23-58-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Coverage Treemap&lt;/h3&gt;
&lt;p&gt;JavaScript/CSSの使用状況を可視化したTreemapも超シンプル。無駄なコードがほぼないですね。下の方のチャンクはGoogle Tag Managerです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-27-23-54-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;比較用にNext.jsのTreemapも貼っておきます。
&lt;a href=&quot;https://ai-triathlon-result.teraren.com/&quot;&gt;こちらのサイト&lt;/a&gt;です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/10/2025-10-28-11-24-58.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;アセットのサイズは、Next.jsでは162KiB、では24.5KiBなのでAstroは約15％のサイズです（さいとが違うのでなんとも言えませんが、概算だけ掴んでもらえればと思います）&lt;/p&gt;
&lt;h2&gt;実際に使ってみた感想&lt;/h2&gt;
&lt;h3&gt;良かった点&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;めちゃくちゃ速い！&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;プロダクション環境でのレンダリングが爆速。静的HTMLを生成するからサーバーサイドの処理が不要&lt;/li&gt;
&lt;li&gt;開発サーバの起動も速いし、ファイル変更時のホットリロードもサクサク&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;自動最適化が優秀&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;画像の遅延読み込み、CSSの最小化など、Webパフォーマンスに必要な最適化を勝手にやってくれる&lt;/li&gt;
&lt;li&gt;何も考えずにデプロイしてもそこそこ速いサイトになる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;モダンな開発体験&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React/Next.jsなどのUI構築が主流の昨今、Astroは生のHTMLに近い形でレンダリングを高速化しつつ、開発体験はReactっぽい&lt;/li&gt;
&lt;li&gt;必要な部分だけJavaScriptを使う「アイランドアーキテクチャ」で、パフォーマンスと開発効率を両立してる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ホスティングコストが安い&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflareの無料プランで運用できるので、コストゼロ！&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;正直なところ、ここは微妙&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Astro専用の構文を覚える必要がある&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.astro&lt;/code&gt; ファイルの書き方を新しく学ぶ必要があります&lt;/li&gt;
&lt;li&gt;とはいえ、HTML と JavaScript の知識があれば割とすぐ慣れました&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;WordPress から Astro への移行、想像以上にスムーズでした。&lt;/p&gt;
&lt;p&gt;専用の移行ツールが充実してるので、技術的なハードルは低いです。&lt;strong&gt;数時間程度の作業で移行完了&lt;/strong&gt;しました。&lt;/p&gt;
&lt;p&gt;結果として得られた成果：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;圧倒的なパフォーマンス向上&lt;/strong&gt; - Lighthouse スコアが大幅改善&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;保守性の向上&lt;/strong&gt; - Git 管理で変更履歴を追跡できるように&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;運用コストの削減&lt;/strong&gt; - サーバーレスで無料ホスティング（Cloudflare Pages 最高）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開発体験の向上&lt;/strong&gt; - 開発サーバもビルドも爆速&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;WordPress みたいな動的 CMS から静的サイトジェネレーターへの移行を検討してる方、Astro はかなり有力な選択肢だと思います。&lt;/p&gt;
&lt;p&gt;次のステップとしては、さらなるパフォーマンス最適化（画像の最適化、フォントのサブセット化など）にも挑戦してみたいですね。&lt;/p&gt;
&lt;p&gt;https://portfolio.teraren.com/&lt;/p&gt;
&lt;h2&gt;参考リンク&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://astro.build/&quot;&gt;Astro公式サイト&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.astro.build/ja/getting-started/&quot;&gt;Astroドキュメント（日本語）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/lonekorean/wordpress-export-to-markdown&quot;&gt;wordpress-export-to-markdown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pages.cloudflare.com/&quot;&gt;Cloudflare Pages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://portfolio.teraren.com/&quot;&gt;完成したポートフォリオサイト&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>ダイキンエアコンAN71VRP-W修理 | 原因不明で5,000円</title><link>https://blog.teraren.com/posts/2025-07-31-daikin-air-conditioner/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2025-07-31-daikin-air-conditioner/</guid><description>6年使用のダイキンエアコン（AN71VRP-W）が突然冷えなくなる症状が発生。メーカー修理を依頼するも原因不明。自動清掃機能をオフにして症状が大幅に改善。基盤交換は見送り、部品交換なしで修理費5,000円で応急対応完了。</description><pubDate>Thu, 31 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;この記事について&lt;/h2&gt;
&lt;h3&gt;学べること&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ダイキンエアコンで冷えなくなる症状の具体的な事例&lt;/li&gt;
&lt;li&gt;自動清掃機能が原因となる可能性&lt;/li&gt;
&lt;li&gt;原因不明のトラブルへの対処法と修理費用の相場&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;想定読者&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ダイキンエアコンで冷房が効かなくなった方&lt;/li&gt;
&lt;li&gt;自動清掃機能付きエアコンのトラブルでお悩みの方&lt;/li&gt;
&lt;li&gt;エアコン修理の費用感を知りたい方&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;前提条件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;メーカー修理依頼が必要&lt;/li&gt;
&lt;li&gt;推定所要時間: 初回訪問30分 + 様子見期間2-3週間&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題の発生&lt;/h2&gt;
&lt;p&gt;ダイキンのエアコン(&lt;a href=&quot;https://kakaku.com/item/K0001005213/&quot;&gt;AN71VRP-W&lt;/a&gt;)を使っています。設置してから6年近くは経過しています。冬は別の暖房器具を使っているので、主に夏にほぼ24時間つけっぱなしにしているような運用です。&lt;/p&gt;
&lt;p&gt;最近、クーラーをつけていると、いきなり冷えなくなって送風だけになるような状態が発生します。そうなるとエアコンの電源切って入れても復活しなくて、ブレーカーというかコンセントを抜いてしばらく放置してまたコンセントを挿すと治るような現象です。&lt;/p&gt;
&lt;p&gt;このコンセントの抜く時間も、数分で良い場合もあれば、数時間おかないと復活しないようなケースがあります。&lt;/p&gt;
&lt;p&gt;関連する症状としては、アプリからエアコン操作するとこの状態に陥りやすくなります。&lt;/p&gt;
&lt;h2&gt;修理依頼と対応&lt;/h2&gt;
&lt;p&gt;さすがに真夏の昼にこの状態になることが何回かあったので、修理依頼をかけました。&lt;/p&gt;
&lt;p&gt;初回の訪問の時に、エアコンを分解して、作業員の人が乾電池などを使ってテストをしてもらいましたが、特に異常は見当たらず様子見ということになりました。&lt;/p&gt;
&lt;p&gt;その時に&lt;strong&gt;自動清掃機能をすべてオフ&lt;/strong&gt;にしました。例えば24時間で自動でお掃除する機能やエアコンの動作が終わった後に1-2時間運転を続ける機能です。&lt;/p&gt;
&lt;p&gt;何が影響したか分かりませんが、状況はかなり改善されました。ただし、2週間のうちに何回か発生しました。その後も1週間に1回発生したりしてましたが、頻度はかなり減ったので、もうこれ以上トラブルシュートしようがないとなって修理を完了としました。&lt;/p&gt;
&lt;h2&gt;修理費用&lt;/h2&gt;
&lt;p&gt;もし根本解決をするためには、基盤を交換しないとできないので、30,000円程度かかると言われました。今回はとりあえず発生頻度がかなり下がったので交換しないで終わりました。&lt;/p&gt;
&lt;p&gt;最終的には部品交換なしだったので、請求としては&lt;strong&gt;5,000円&lt;/strong&gt;で終わりました。原因不明のまま症状だけ改善したので、少し釈然としない感じはありますが、実用上は問題なくなりました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/07/img_3835-1.jpg&quot; alt=&quot;修理費用の請求書&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;考察とまとめ&lt;/h2&gt;
&lt;p&gt;このエアコンを設置した後に、Xでエアコン業者のつぶやきをいろいろ見ていたのですが、やっぱりエアコンはたくさん数が出ている低機能のシンプルなエアコンが1番良いと思いました。&lt;/p&gt;
&lt;p&gt;今回のエアコンには「ウルルとさらら」（ダイキンの加湿・除湿機能）が入っていますが、体感できるほどの違いはないので、個人的には不要な機能だと感じています。&lt;/p&gt;
&lt;p&gt;あと無駄に大きいので、風の力が強すぎて、エアコン自体が風の音でうるさいです。なんていうかリビングに置いてますが、業務用エアコンという感じです。テレビの音が聞こえづらいです。普通の大きさの家庭用エアコンが良いと思います。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;今回の修理まとめ&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;機種&lt;/strong&gt;: ダイキン AN71VRP-W（使用期間: 約6年）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;症状&lt;/strong&gt;: 冷房運転中に突然送風のみになる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;原因&lt;/strong&gt;: 不明（基盤の不具合の可能性）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対応&lt;/strong&gt;: 自動清掃機能をすべてオフに設定&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;効果&lt;/strong&gt;: 症状の発生頻度が大幅に減少（週1回以下）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;費用&lt;/strong&gt;: 5,000円（診断料のみ、部品交換なし）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;根本解決の場合&lt;/strong&gt;: 基盤交換で約30,000円&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;教訓&lt;/strong&gt;: 高機能エアコンより、シンプルな機種の方が故障リスクが低い&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Tapoを天井に設置して部屋ごと監視</title><link>https://blog.teraren.com/posts/tapo-on-the-ceiling/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tapo-on-the-ceiling/</guid><description>行動範囲が広がった赤ちゃんを見守るため、TP-Link Tapoカメラを天井に設置。石膏ボード加工と電源配線の施工方法、死角への対処法を解説。</description><pubDate>Wed, 16 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前回の記事&lt;/h2&gt;
&lt;p&gt;ベビーベッドにtapoを設置して監視しやすくしていましたが、ベビーベッドは2ヶ月ぐらいで卒業しました。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/tapo-baby-check/&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;行動範囲が広くなったので部屋ごと監視する必要が出てきました。&lt;/p&gt;
&lt;p&gt;三脚や棚においたりしておくと画角が変わってしまったりして不便です。また、邪魔です。また、カメラの近くに赤ちゃんが来たらカメラで捉えることができません。&lt;/p&gt;
&lt;h2&gt;解決方法&lt;/h2&gt;
&lt;p&gt;天井に設置しました。&lt;/p&gt;
&lt;p&gt;石膏ボードに穴を開けて、電源はエアコン用に来ていたので電圧を確認したら100Vだったので天井裏で分岐して、コンセントを作って、tapoのACアダプタをぶち込みました。これで死角ができなくなります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/07/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/07/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0CKWS1VWR&quot;}&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;部屋中が見えて快適です！しかしながら影も存在するので、死角をカバーするように2台設置するか部屋の中央に設置するのが良いと思いました。&lt;/p&gt;
&lt;p&gt;部屋の中央に設置すると対象オブジェクトを自動トラッキングにしておかないと監視するのが面倒です。カメラを動かすときにモーターの動作音がするので部屋の環境騒音の度合いにも気をつける必要があります。&lt;/p&gt;
</content:encoded></item><item><title>DELL POWEREDGE T320資料写真</title><link>https://blog.teraren.com/posts/dell-poweredge-t320/</link><guid isPermaLink="true">https://blog.teraren.com/posts/dell-poweredge-t320/</guid><description>DELL POWEREDGE T320資料写真</description><pubDate>Thu, 26 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;家のファイルサーバ、アプリケーションサーバとして4年ほど稼働してくれました。&lt;/p&gt;
&lt;p&gt;運用途中、RAIDカードが壊れてリプレイスしました。ちょっと古めなので消費電力が多くて売却しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/IMG_1254.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/IMG_1255.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/IMG_1256.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/IMG_1257.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/IMG_1258.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/IMG_1259.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/IMG_1260.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/IMG_1261.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/IMG_1262.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/IMG_1263.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Context engineeringの実践例 - システムプロンプトと人間向けドキュメントを共存して管理</title><link>https://blog.teraren.com/posts/instructions-for-llms/</link><guid isPermaLink="true">https://blog.teraren.com/posts/instructions-for-llms/</guid><description>本記事では、**Context Engineering**（コンテキスト・エンジニアリング）の実践例として、人間と AI の両方が効率的に情報にアクセスできるドキュメント管理手法を解説します。</description><pubDate>Thu, 26 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;課題&lt;/strong&gt;: 複数の LLM（Claude、Gemini、GitHub Copilot）ごとに個別の指示書を管理するのは非効率&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解決策&lt;/strong&gt;: Diátaxis (ディアタクシス)フレームワークで情報を体系化し、シンボリックリンクでエントリーポイントを統一&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;効果&lt;/strong&gt;: Context Engineering の実践により、人間と AI 両方が効率的にアクセスできる、メンテナンス性の高いドキュメント管理を実現&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;本記事では、&lt;strong&gt;Context Engineering&lt;/strong&gt;（コンテキスト・エンジニアリング）の実践例として、人間と AI の両方が効率的に情報にアクセスできるドキュメント管理手法を解説します。&lt;/p&gt;
&lt;p&gt;Context Engineering とは、LLM に対して適切な文脈情報（コンテキスト）を構造化して提供することで、より精度の高い出力を得るための技術体系です。本記事で紹介する手法は、Diátaxis (ディアタクシス)フレームワークを活用した Context Engineering の具体的な実装例となります。&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;現在、Claude、Gemini、GitHub Copilot など多数の LLM サービスが利用されており、それぞれが参照するドキュメントのエントリーポイントが異なります。開発チームは複数の LLM を使い分けることが一般的になっており、統一的なドキュメント管理の必要性が高まっています。&lt;/p&gt;
&lt;p&gt;昨日発表された Gemini CLI は &lt;code&gt;GEMINI.md&lt;/code&gt; をエントリーポイントとして要求しています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Context Engineeringの観点から見ると&lt;/strong&gt;、LLM の出力品質は提供されるコンテキストの質と構造に大きく依存します。適切に構造化されたコンテキストを提供することで、LLM はより正確で有用な支援ができます。&lt;/p&gt;
&lt;h2&gt;課題&lt;/h2&gt;
&lt;p&gt;現状のドキュメント管理には、Context Engineering の視点から以下のような問題があります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;コンテキストの断片化&lt;/strong&gt;: 各 LLM ごとに個別の指示書を用意することで、コンテキスト情報が断片化し、一貫性のある文脈提供が困難&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;情報の重複と不整合&lt;/strong&gt;: LLM 向けの指示と人間向けのドキュメントで同じ内容が重複し、Context Engineering の基本原則である「Single Source of Truth」が守られていない&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;構造化の欠如&lt;/strong&gt;: 情報が体系的に整理されておらず、LLM が効率的にコンテキストを理解・活用できない&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;メンテナンス性の低下&lt;/strong&gt;: Context Engineering の実践において重要な、コンテキスト情報の継続的な改善が困難&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;解決アプローチ&lt;/h2&gt;
&lt;p&gt;上記の課題を解決するため、&lt;strong&gt;Context Engineeringのベストプラクティス&lt;/strong&gt;として、以下の 3 つの原則に基づいたアプローチを採用します：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;構造化されたコンテキスト提供&lt;/strong&gt;: 人間と LLM で共通利用できる部分と、それぞれに特化した部分を明確に分離し、Context Engineering の原則に従って情報を構造化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;階層的なコンテキスト管理&lt;/strong&gt;: ドキュメントの階層と参照関係を明確にし、LLM が段階的にコンテキストを理解できるよう設計&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;標準フレームワークの採用&lt;/strong&gt;: &lt;a href=&quot;https://inside.dmm.com/articles/systematicness-documentation-diataxis/&quot;&gt;Diátaxis&lt;/a&gt;フレームワークを活用し、Context Engineering に適した体系的な情報分類を実現&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;設計思想&lt;/h2&gt;
&lt;p&gt;本手法は、Context Engineering の実践において重要な、以下の確立されたドキュメント管理のベストプラクティスを組み合わせています：&lt;/p&gt;
&lt;h3&gt;1. Diátaxis フレームワーク&lt;/h3&gt;
&lt;p&gt;技術文書をその目的に応じて 4 つのタイプに分類するフレームワークです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;チュートリアル (Tutorials)&lt;/strong&gt;: 学習者を手引きするレッスン&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ハウツーガイド (How-to guides)&lt;/strong&gt;: 特定の目標達成のための具体的手順&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;解説 (Explanation)&lt;/strong&gt;: 背景や設計思想の理解のための説明&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リファレンス (Reference)&lt;/strong&gt;: 技術的に正確で網羅的な情報&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-26-19-31-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2. Docs as Code&lt;/h3&gt;
&lt;p&gt;すべてのドキュメントを Git でコードと共に管理し、Markdown で記述、Pull Request でレビューするアプローチです。これにより、ドキュメントとコードの同期を保ち、品質を担保します。&lt;/p&gt;
&lt;h3&gt;3. アーキテクチャ・デシジョン・レコード (ADR)&lt;/h3&gt;
&lt;p&gt;ソフトウェアアーキテクチャに関する重要な意思決定とその理由、選択肢、背景、結果などを時系列で記録するドキュメント手法です。これにより、設計や技術選定の経緯を後から追跡でき、プロジェクトの知識共有や意思決定の透明性が向上します。&lt;/p&gt;
&lt;h2&gt;提案するドキュメント構成&lt;/h2&gt;
&lt;p&gt;Context Engineering の実践として、現在の LLM サービスが要求する固有のエントリーポイントファイルを効率的に管理する構成を提案します。&lt;/p&gt;
&lt;p&gt;これらの LLM ごとのファイルの内容は本質的に大きく異なるものではなく、&lt;strong&gt;適切なContext Engineeringによって統一的に管理&lt;/strong&gt;できます。&lt;/p&gt;
&lt;p&gt;人間の開発者にとってのエントリーポイントは従来通り &lt;code&gt;README.md&lt;/code&gt; ですが、これも Context Engineering の観点から最適化されています。&lt;/p&gt;
&lt;p&gt;これらの要件を満たしつつ、Context Engineering の原則に基づいてドキュメントの重複を最小限に抑え、保守性を高める構成モデルを設計しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
title: ドキュメント構成図
---
graph TD
    subgraph &quot;アクター&quot;
        direction LR
        A[&quot;開発者 (人間)&quot;]
        B[&quot;Claude&quot;]
        C[&quot;Gemini&quot;]
        D[&quot;GitHub Copilot&quot;]
    end

    subgraph &quot;入口となるドキュメント&quot;
        direction LR
        README(&quot;README.md [人間向け入口]&quot;)
        CLAUDE_MD(&quot;CLAUDE.md [LLM向けマスター文書]&quot;)
        GEMINI_MD(&quot;GEMINI.md&quot;)
        COPILOT_MD(&quot;.github/copilot-instructions.md&quot;)
    end

    subgraph &quot;知識ベース (.claude/)&quot;
        direction TB
        KNOWLEDGE(&quot;knowledge.md [なぜ (Why)]&quot;)
        COOKBOOK(&quot;cookbook.md [やり方 (How-to)]&quot;)
        HISTORY(&quot;history.md [変遷 (Evolution)]&quot;)
    end

    A -- &quot;参照&quot; --&amp;gt; README
    README -- &quot;詳細はこちら&quot; --&amp;gt; CLAUDE_MD
    B -- &quot;参照&quot; --&amp;gt; CLAUDE_MD
    C -- &quot;参照&quot; --&amp;gt; GEMINI_MD
    D -- &quot;参照&quot; --&amp;gt; COPILOT_MD

    GEMINI_MD -.-&amp;gt; |シンボリックリンク| CLAUDE_MD
    COPILOT_MD -.-&amp;gt; |シンボリックリンク| CLAUDE_MD

    CLAUDE_MD -- &quot;参照&quot; --&amp;gt; KNOWLEDGE
    CLAUDE_MD -- &quot;参照&quot; --&amp;gt; COOKBOOK
    CLAUDE_MD -- &quot;参照&quot; --&amp;gt; HISTORY

    style README fill:#cde4ff,stroke:#333,stroke-width:2px
    style CLAUDE_MD fill:#e1f7d5,stroke:#333,stroke-width:2px
    style GEMINI_MD fill:#e1f7d5,stroke:#333,stroke-width:1px,stroke-dasharray: 5 5
    style COPILOT_MD fill:#e1f7d5,stroke:#333,stroke-width:1px,stroke-dasharray: 5 5
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;構成の概要（Context Engineeringの実装）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;開発者 (人間)&lt;/strong&gt;: &lt;code&gt;README.md&lt;/code&gt; から読み始め、プロジェクトの概要やセットアップ手順を把握します。詳細なコマンドやコードのレシピについては、&lt;code&gt;.claude/cookbook.md&lt;/code&gt; を参照します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM (Claude, Gemini, Copilot)&lt;/strong&gt;: それぞれの入口となるファイル (&lt;code&gt;CLAUDE.md&lt;/code&gt;, &lt;code&gt;GEMINI.md&lt;/code&gt;, &lt;code&gt;.github/copilot-instructions.md&lt;/code&gt;) を使用します。これらのファイルはすべて、Context Engineeringの中核となる &lt;code&gt;CLAUDE.md&lt;/code&gt; に繋がっています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;&lt;/strong&gt;: Context Engineeringのマスタファイルとして機能し、LLMに対して構造化されたプロジェクトコンテキストを提供しつつ、&lt;code&gt;.claude/&lt;/code&gt; ディレクトリ内の詳細な知識ベースへリンクします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;知識ベース (&lt;code&gt;.claude/&lt;/code&gt;)&lt;/strong&gt;: Context Engineeringの原則に基づき、特定のトピックに関する信頼できる唯一の情報源（Single Source of Truth）として機能し、情報の重複を防ぎます。
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;knowledge.md&lt;/code&gt;: アーキテクチャの決定や技術的な背景（なぜ）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cookbook.md&lt;/code&gt;: コマンドやコードパターンを網羅したレシピ集（やり方）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;history.md&lt;/code&gt;: プロジェクトの改善履歴や背景（変遷）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;この構成により、情報は論理的に整理され、保守が容易になり、人間とAIの両方が明確な入口から情報にアクセスできます。&lt;/p&gt;
&lt;h2&gt;実装方法&lt;/h2&gt;
&lt;p&gt;この構成を実際のプロジェクトに導入するための具体的な手順を示します。以下のプロンプトをLLMに提供することで、自動的に構成を構築できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 標準ドキュメント構成 構築プロンプト (Diátaxis準拠 最終版)

## 目的
プロジェクトのドキュメントを、人間とAIの両方にとって分かりやすく、メンテナンス性の高い標準構成に再構築します。特に、[Diátaxisフレームワーク](https://diataxis.fr/)の考え方を全面的に採用し、ドキュメントをその目的に応じて明確に分類します。

## 指示
以下の手順に従って、プロジェクトのドキュメントを **日本語で** 再構築してください。

---

### フェーズ1: 現状分析と情報整理

1.  **既存ドキュメントの分析**:
    現在の `README.md` や、その他存在するすべてのドキュメントを読み込み、内容を完全に把握してください。

2.  **情報の分類 (Diátaxis)**:
    分析した内容を、Diátaxisフレームワークの4つのカテゴリに分類・整理してください。
    -   **チュートリアル (Tutorials)**: プロジェクトのセットアップ手順など、学習者を手引きするレッスン。
    -   **ハウツーガイド (How-to guides)**: コマンド実行、デバッグ、リリース手順など、特定の目標を達成するための具体的な手順。
    -   **解説 (Explanation)**: アーキテクチャ、設計思想、技術選定の理由、過去の経緯など、背景や文脈を理解するための説明。
    -   **リファレンス (Reference)**: API仕様、重要なログ、技術的に正確で網羅的な情報。

---

### フェーズ2: 新しいドキュメント構造の構築

1.  **知識ベース用ディレクトリの作成**:
    プロジェクトのルートに `.claude` という名前のディレクトリを作成し、その中にDiátaxisのカテゴリに対応するサブディレクトリを作成します。
    ```bash
    mkdir -p .claude/tutorials .claude/how-to-guides .claude/explanation .claude/reference
    ```

2.  **知識ベースの作成**:
    分類した情報を基に、対応するディレクトリ内にファイルを日本語で作成・記述してください。
    -   `.claude/how-to-guides/cookbook.md`: **ハウツーガイド**を集約します。
    -   `.claude/explanation/knowledge.md`: **解説**（アーキテクチャや設計思想）を集約します。
    -   `.claude/explanation/history.md`: **解説**（プロジェクトの歴史と変遷）を集約します。
    -   `.claude/reference/debug-log.md`: **リファレンス**（重要なデバッグログなど）を集約します。

3.  **マスタードキュメントの作成 (`CLAUDE.md`)**:
    -   プロジェクトのルートに `CLAUDE.md` というファイル名で、日本語で作成します。
    -   このファイルには、プロジェクト概要と、Diátaxisフレームワークに基づいた新しいナレッジベースへの案内を記述します。以下のテンプレートを参考にしてください。
        ```markdown
        ## ナレッジベース (Diátaxisフレームワーク準拠)

        このプロジェクトの知識は、Diátaxisフレームワークに基づき、`.claude/` ディレクトリ内で目的別に分類・管理されています。

        - **[解説 (Explanation)](./.claude/explanation/)**: なぜそうなっているのか、背景や設計思想を理解するためのドキュメントです。
        - **[ハウツーガイド (How-to guides)](./.claude/how-to-guides/)**: 特定のタスクを達成するための具体的な手順を示します。
        - **[リファレンス (Reference)](./.claude/reference/)**: 技術的に正確で網羅的な情報です。
        - **チュートリアル (Tutorials)**: この役割は主に `README.md` が担っています。
        ```
    -   プロジェクトのコンテキストやアーキテクチャの概要もここに含めます。

4.  **人間向け `README.md` の再構築**:
    -   `README.md` を、Diátaxisにおける**チュートリアル**として再定義します。
    -   内容は、プロジェクトのセットアップと基本的な操作に限定し、シンプルに保ちます。
    -   冒頭に、より詳細な情報への入口として `CLAUDE.md` へのリンクを目立つように配置します。

5.  **各種AI向けシンボリックリンクの作成**:
    -   `CLAUDE.md` へのシンボリックリンクを作成します。
        ```bash
        ln -sf CLAUDE.md GEMINI.md
        mkdir -p .github
        ln -sf ../CLAUDE.md .github/copilot-instructions.md
        ```

---

### フェーズ3: 仕上げ

1.  **ドキュメント構成図の作成と追記**:
    -   以下のDiátaxisベースのMermaid図を、「ドキュメント構成」セクションとして `README.md` と `CLAUDE.md` の両方の末尾に追記します。
        ```mermaid
        ---
        title: ドキュメント構成図 (Diátaxis準拠)
        ---
        graph TD
            subgraph &quot;アクター&quot;
                direction LR
                A[&quot;開発者 (人間)&quot;]
                B[&quot;Claude&quot;]
                C[&quot;Gemini&quot;]
                D[&quot;GitHub Copilot&quot;]
            end

            subgraph &quot;入口となるドキュメント&quot;
                direction LR
                README(&quot;README.md&amp;lt;br&amp;gt;[チュートリアル]&quot;)
                CLAUDE_MD(&quot;CLAUDE.md&amp;lt;br&amp;gt;[マスター文書]&quot;)
                GEMINI_MD(&quot;GEMINI.md&quot;)
                COPILOT_MD(&quot;.github/copilot-instructions.md&quot;)
            end

            subgraph &quot;知識ベース (.claude/)&quot;
                direction TB
                subgraph &quot;解説 (Explanation)&quot;
                    KNOWLEDGE(&quot;knowledge.md&quot;)
                    HISTORY(&quot;history.md&quot;)
                end
                subgraph &quot;ハウツー (How-to)&quot;
                    COOKBOOK(&quot;cookbook.md&quot;)
                end
                subgraph &quot;リファレンス (Reference)&quot;
                    DEBUG(&quot;debug-log.md&quot;)
                end
            end

            A -- &quot;参照&quot; --&amp;gt; README
            README -- &quot;詳細はこちら&quot; --&amp;gt; CLAUDE_MD
            B -- &quot;参照&quot; --&amp;gt; CLAUDE_MD
            C -- &quot;参照&quot; --&amp;gt; GEMINI_MD
            D -- &quot;参照&quot; --&amp;gt; COPILOT_MD

            GEMINI_MD -.-&amp;gt; |シンボリックリンク| CLAUDE_MD
            COPILOT_MD -.-&amp;gt; |シンボリックリンク| CLAUDE_MD

            CLAUDE_MD -- &quot;参照&quot; --&amp;gt; KNOWLEDGE &amp;amp; HISTORY &amp;amp; COOKBOOK &amp;amp; DEBUG

            style README fill:#cde4ff,stroke:#333,stroke-width:2px
            style CLAUDE_MD fill:#e1f7d5,stroke:#333,stroke-width:2px
        ```

2.  **最終確認**:
    -   作成した新しいファイル構造と、更新された `README.md` および `CLAUDE.md` の内容を提示し、最終的な承認を求めてください。
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;期待される効果&lt;/h2&gt;
&lt;p&gt;この Context Engineering 手法を導入することで、以下のような効果が期待できます：&lt;/p&gt;
&lt;h3&gt;開発効率の向上&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Context Engineeringによる情報検索の最適化&lt;/strong&gt;: 構造化されたコンテキストにより、LLM と人間の両方が必要な情報に素早くアクセス可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLMの出力品質向上&lt;/strong&gt;: Context Engineering の原則に基づいた適切なコンテキスト提供により、より精度の高い AI 支援を実現&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オンボーディングの効率化&lt;/strong&gt;: 体系的に整理されたコンテキスト情報により、新しいチームメンバーが迅速にプロジェクトを理解できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Context Engineeringによるメンテナンス性の向上&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;コンテキスト情報の一元管理&lt;/strong&gt;: Context Engineering の Single Source of Truth 原則により、情報の重複と不整合を防止&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;更新作業の簡素化&lt;/strong&gt;: 一箇所の更新で複数の LLM エントリーポイントに反映される効率的な Context Engineering&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;品質の向上&lt;/strong&gt;: Docs as Code によるレビュープロセスで、Context Engineering の品質を継続的に改善&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;本記事では、&lt;strong&gt;Context Engineeringの実践例&lt;/strong&gt;として、LLM 時代に対応したドキュメント管理手法を提案しました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Context Engineeringの主要な実装ポイント：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Diátaxis フレームワークを活用した、Context Engineering に適した体系的な情報分類&lt;/li&gt;
&lt;li&gt;人間と AI の両方に最適化されたコンテキスト提供のためのエントリーポイント設計&lt;/li&gt;
&lt;li&gt;Context Engineering の Single Source of Truth 原則による情報の一元管理&lt;/li&gt;
&lt;li&gt;シンボリックリンクを活用した効率的な Context Engineering 構成&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この Context Engineering 手法により、開発チームは複数の LLM を効果的に活用しながら、メンテナンス性の高いドキュメント管理を実現できます。特に、Context Engineering の原則に基づいて情報の重複を排除し、一貫性のあるコンテキストを維持しながら、人間と AI の両方が効率的に情報にアクセスできる環境を構築できる点が大きな利点です。&lt;/p&gt;
&lt;p&gt;今後の LLM 技術の発展に伴い、このような Context Engineering の手法はますます重要になると考えられます。本記事で紹介した Context Engineering の実践例を、ぜひ皆さんのプロジェクトでも試してみてください。&lt;/p&gt;
</content:encoded></item><item><title>OpenHands CLIで抽象的な指示から動くコードを生成する：Claude Codeとの比較</title><link>https://blog.teraren.com/posts/openhands-cli/</link><guid isPermaLink="true">https://blog.teraren.com/posts/openhands-cli/</guid><description>2025 年 6 月 17 日に OpenHands の CLI 版がリリースされました。</description><pubDate>Fri, 20 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;2025 年 6 月 17 日に OpenHands の CLI 版がリリースされました。&lt;/p&gt;
&lt;p&gt;https://www.all-hands.dev/blog/the-openhands-cli-ai-powered-development-in-your-terminal&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;OpenHands とは？&lt;/p&gt;
&lt;p&gt;https://zenn.dev/tatsuyasusukida/articles/try-openhands-for-5-dollars
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;OpenHands CLI を使うことによって、Claude Code と同じことが LLM の制限なしにできるようになります。しかも OpenHands なのでより抽象度の高いエージェントっぽい動きをしてくれます。&lt;/p&gt;
&lt;h2&gt;セットアップ&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Python 3.13 on macOS&lt;/code&gt; と &lt;code&gt;Docker&lt;/code&gt; で動かそうとしましたがエラーが出て動きませんでした。&lt;/p&gt;
&lt;p&gt;uvx 経由だと動いたので今回は uvx 経由で起動します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; uvx --python 3.12 --from openhands-ai openhands
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初回起動は数分待ちます。&lt;/p&gt;
&lt;p&gt;初期設定をします。
今回は、Claude sonnet 4で実行してみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ cat   ~/.openhands/settings.json | json_pp | grep llm_model
   &quot;llm_model&quot; : &quot;anthropic/claude-sonnet-4-20250514&quot;,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;起動するとプロンプトが表示されます。
&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-13-58-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;実装テスト&lt;/h2&gt;
&lt;p&gt;今回実装してもらう機能の内容をGitHub issueに記載して、それを実装してもらうことにします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-14-06-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;サンプルで使うサービスはこちらの個人開発しているサービスです。
https://ai-triathlon-result.teraren.com/&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-14-09-39.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;issueを作成してあるので、プロンプトでそのIDを使って指示します。指示した内容は以下です&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; GitHub issueの#22を実装してください。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最初に、issueの取得方法と実装してよいかの確認が聞かれます。その後はどんどん自律的に処理が進んでいきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-14-06-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;どんどん標準出力に実行内容が出力されていって処理が進んでいきます。&lt;/p&gt;
&lt;p&gt;出力が多いし、速いので目で追いつけないです。。。(何をしているか把握したかったのですが諦めて、OpenHandsを放置してご飯を食べに行きました)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-14-07-46.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;(おそらく15分ほど)いろいろ出力して、最終的に以下の内容が出力されました。&lt;/p&gt;
&lt;p&gt;細かいステップを指示しなくても勝手にステップにブレークダウンして実装してくれています。&lt;strong&gt;優秀！&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Agent running... (Press Ctrl-P to pause)
/Users/username/.cache/uv/archive-v0/8UNE-QZmsj_fwI7VgPxJz/lib/python3.12/site-packages/pydantic/main.py:463: UserWarning: Pydantic serializer warnings:
  PydanticSerializationUnexpectedValue(Expected 9 fields but got 5: Expected `Message` - serialized value may not be as expected [input_value=Message(content=&apos;Excellen...thinking_blocks&apos;: None}), input_type=Message])
  PydanticSerializationUnexpectedValue(Expected `StreamingChoices` - serialized value may not be as expected [input_value=Choices(finish_reason=&apos;to...hinking_blocks&apos;: None})), input_type=Choices])
  return self.__pydantic_serializer__.to_python(

Excellent! The build completed successfully. I can see that all the Auth0 and dashboard pages are included in the build:

- `/api/auth/[...auth0]` - Auth0 authentication routes
- `/api/profile` - Profile API endpoint
- `/dashboard` - Main dashboard page
- `/dashboard/profile` - Profile editing page
- `/dashboard/settings` - Settings page

Let me create a summary of what has been implemented:

✅ **GitHub Issue #22 - Auth0 Authentication Implementation Complete**

I have successfully implemented the Auth0 authentication system with Google SSO and comprehensive user profile management features as requested in GitHub issue #22.

## 🎯 **Completed Features**

### **Authentication System**
- ✅ Auth0 integration with Google SSO support
- ✅ Login/logout functionality in navbar
- ✅ Session management with Auth0 v3.8.0 (stable version)
- ✅ Protected routes and API endpoints

### **User Dashboard** (`/dashboard`)
- ✅ User information display with Auth0 profile data
- ✅ Profile editing card with link to dedicated profile page
- ✅ Settings card with link to account management
- ✅ Responsive design with loading states

### **Profile Management** (`/dashboard/profile`)
- ✅ **Japanese Name Fields**: Family name and given name in Japanese
- ✅ **English Name Fields**: Family name and given name in English
- ✅ **Social Media Links**: X (Twitter), Instagram, Strava, Blog URL
- ✅ **Free Text Bio**: 1000 character limit with real-time counter
- ✅ Form validation and error handling
- ✅ Toast notifications for save success/failure
- ✅ Auto-save functionality

### **Settings Page** (`/dashboard/settings`)
- ✅ Account information display
- ✅ Privacy settings section
- ✅ Data management options
- ✅ Consistent UI design

### **Backend Infrastructure**
- ✅ Profile API endpoints (`/api/profile`) with GET/POST methods
- ✅ Redis storage integration using Upstash
- ✅ Session-based authentication validation
- ✅ Data persistence and retrieval

### **Technical Implementation**
- ✅ Auth0 SDK v3.8.0 for Next.js App Router compatibility
- ✅ TypeScript implementation with proper type safety
- ✅ Responsive UI using Tailwind CSS and shadcn/ui components
- ✅ React Hook Form for form management
- ✅ Zod schema validation
- ✅ Error handling and loading states

## 🔧 **Environment Configuration**
- ✅ Auth0 environment variables configured
- ✅ Redis/Upstash integration set up
- ✅ Development server running on localhost:3001

## 🧪 **Testing Results**
- ✅ TypeScript compilation passes
- ✅ Next.js build completes successfully
- ✅ Auth0 login endpoint working (302 redirect to Auth0)
- ✅ Profile API correctly returns 401 for unauthenticated requests
- ✅ Dashboard pages load correctly
- ✅ All routes and components render without errors

## 🚀 **Ready for Use**
The authentication system is fully functional and ready for users to:
1. Log in with Google via Auth0
2. Access their personalized dashboard
3. Edit their profile with Japanese/English names, social media links, and bio
4. Manage account settings
5. Have their data securely stored and retrieved

The implementation follows Next.js 15 App Router best practices and provides a complete user authentication and profile management solution as specified in the GitHub issue.

Task completed...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;タスクが完了したとのことです。&lt;/p&gt;
&lt;h2&gt;動作確認&lt;/h2&gt;
&lt;p&gt;早速動作確認のためにアプリケーションサーバを起動してみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; pnpm dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ログインボタンが既存のリンクと同じようなデザインで配置されました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-14-48-34.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Auth0側でアプリケーションの登録、callback URLの登録などを行い、ローカルの環境変数に設定します。&lt;/p&gt;
&lt;p&gt;Auth0のログインページが表示されます。
Googleですでにログインしているため、Googleのボタンを押して認証を進めます。
&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-14-52-54.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ログイン後にダッシュボードのボタンを押すとダッシュボードに移動します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-14-55-56.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;プロフィール編集ページ
&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-14-57-51.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;設定ページ
&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-14-58-05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一通りちゃんと動いています！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;これだけ抽象的な指示で、しかも認証機能のインテグレーションを実装するのは素晴らしいです。同じ機能の実装経験があるエンジニアが手で実装したとしても半日はかかると思います。&lt;/p&gt;
&lt;p&gt;このあと、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;テストコード&lt;/li&gt;
&lt;li&gt;Linterの設定&lt;/li&gt;
&lt;li&gt;GitHub ActionsでCI(test)を動かすようなコード
を追加で実装してもらいました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;テストコードとLinterの実装は、最初は失敗していましたが、テストを実行する際のコマンドを指定してそれがpassするようにするという自動ゴールを伝えると見事に1回で解決してくれました。&lt;/p&gt;
&lt;p&gt;今回作ったコードのpull requestの規模感。2624行の追加と、228行の削除です。削除と言っても変更分がほとんどです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-20-10-58-53.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;コスト&lt;/h2&gt;
&lt;p&gt;セッションを閉じると金額が表示されました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Closing current conversation...

┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────| Usage Metrics |─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│   Total Cost (USD):    $2.276928                                                                                                                                                                                                                                                                                                                                  │
│                                                                                                                                                                                                                                                                                                                                                                   │
│   Total Input Tokens:  3,092,110                                                                                                                                                                                                                                                                                                                                  │
│      Cache Hits:       3,040,539                                                                                                                                                                                                                                                                                                                                  │
│      Cache Writes:     226,229                                                                                                                                                                                                                                                                                                                                    │
│   Total Output Tokens: 24,113                                                                                                                                                                                                                                                                                                                                     │
│                                                                                                                                                                                                                                                                                                                                                                   │
│   Total Tokens:        3,116,223                                                                                                                                                                                                                                                                                                                                  │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

Conversation duration: 0h 47m 4s

Closed conversation 9dfd3176-d42e-404a-b073-c65f6581a2b9-88204aed8d8de86f
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;47分で、約330円でできました。&lt;/p&gt;
&lt;h2&gt;CLIからの利用&lt;/h2&gt;
&lt;p&gt;外部からコマンドやCIで動かすために標準入力からプロンプトを読み込めるとワークフロー内で使えるようになるので便利です。&lt;/p&gt;
&lt;p&gt;Claude Codeでもこの方法でスクリプトから呼び出す例が多く使われています。これができればコーディングエージェントの並走が可能になるので確認してみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ echo &apos;ダッシュボードのUIをかっこよくしてください&apos; | uvx --python 3.12 --from openhands-ai openhands
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;     ___                    _   _                 _
    /  _ \ _ __   ___ _ __ | | | | __ _ _ __   __| |___
    | | | | &apos;_ \ / _ \ &apos;_ \| |_| |/ _` | &apos;_ \ / _` / __|
    | |_| | |_) |  __/ | | |  _  | (_| | | | | (_| \__ \
    \___ /| .__/ \___|_| |_|_| |_|\__,_|_| |_|\__,_|___/
          |_|

OpenHands CLI v0.44.0

Initialized conversation 1b43dd91-fc8c-40a9-a80d-ad9f4aec3a51-6b6d2679854c6450

Let&apos;s start building!

What do you want to build? Type /help for help

&amp;gt; ダッシュボードのUIをかっこよくしてください

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;という感じで普通に標準入力の内容を元に起動してくれました！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-19-16-21-51.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;よって、CI での実行、並列実行はできそうです。しかしながら、コンテナ内ではなくてローカルのファイルシスを直接変更する仕様なので &lt;a href=&quot;https://zenn.dev/minedia/articles/container-use&quot;&gt;container-use&lt;/a&gt;と組み合わせるのが良いと思います。&lt;/p&gt;
&lt;h2&gt;実験の考察&lt;/h2&gt;
&lt;p&gt;OpenHands CLI を使うと一発で動く機能を作ることができました。しかも test、linter もちゃんと通るように作ってくれました。&lt;/p&gt;
&lt;p&gt;Claude Code や Cline では今回のような抽象的な指示では完了に持っていけないため、OpenHands を使うことで抽象度の高いタスクを行える印象です。&lt;/p&gt;
&lt;p&gt;上記を踏まえると、以下のように整理できると考えます：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Code&lt;/strong&gt;: LLM を使うためのインタフェース。コーディングエージェント要素が少なめ&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OpenHands&lt;/strong&gt;: LLM を使ってプログラミングをするコーディングエージェント。抽象度高め&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;OpenHands CLIとClaude Codeの比較&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;OpenHands CLI&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;抽象度&lt;/td&gt;
&lt;td&gt;高い&lt;/td&gt;
&lt;td&gt;低い&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;自律性&lt;/td&gt;
&lt;td&gt;高い&lt;/td&gt;
&lt;td&gt;低い&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;適用場面&lt;/td&gt;
&lt;td&gt;機能実装全体&lt;/td&gt;
&lt;td&gt;細かい修正・改善&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;学習コスト&lt;/td&gt;
&lt;td&gt;低い&lt;/td&gt;
&lt;td&gt;中程度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;利用可能LLM&lt;/td&gt;
&lt;td&gt;複数のLLM対応&lt;/td&gt;
&lt;td&gt;Anthropic社のみ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;抽象度の高いタスクは OpenHands CLI が適しており、マイクロタスクは Claude Code といった直接 LLM を使う方法が適していると感じました。&lt;/p&gt;
&lt;p&gt;用途に応じて使い分けることで、効率的な開発が可能になりそうです。&lt;/p&gt;
&lt;p&gt;GitHub 上で Claude Code に実装指示を出してノーエディターで開発を進める場面に最適だと思いました。&lt;/p&gt;
&lt;p&gt;次は GitHub Actions 上で OpenHands CLI を起動して利用したいです。&lt;/p&gt;
</content:encoded></item><item><title>「Claude Codeで効率的に開発するための知見管理」をコマンド1発で自分のプロジェクトに反映する方法</title><link>https://blog.teraren.com/posts/claude-code-knowledge-management/</link><guid isPermaLink="true">https://blog.teraren.com/posts/claude-code-knowledge-management/</guid><description>開発プロジェクトにおいて、コードの知識管理やドキュメント整備は重要ですが、手間がかかる作業でもあります。しかし、LLM の力を借りることで、先駆者が構築した知見を瞬時に自分のプロジェクトに適用できる時代が到来しました。</description><pubDate>Thu, 12 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;開発プロジェクトにおいて、コードの知識管理やドキュメント整備は重要ですが、手間がかかる作業でもあります。しかし、LLM の力を借りることで、先駆者が構築した知見を瞬時に自分のプロジェクトに適用できる時代が到来しました。&lt;/p&gt;
&lt;h2&gt;背景：話題になった記事&lt;/h2&gt;
&lt;p&gt;こちらの記事が開発者コミュニティで話題になっています。&lt;/p&gt;
&lt;p&gt;https://zenn.dev/driller/articles/2a23ef94f1d603&lt;/p&gt;
&lt;p&gt;この記事では、Claude を使った効果的なコード知識管理システムの構築方法が紹介されています。&lt;/p&gt;
&lt;h2&gt;課題&lt;/h2&gt;
&lt;p&gt;上の記事を読むと普通のかたは「自分のリポジトリにも適用して試したい！」と思います。
しかしながら、実際に自分のリポジトリに取り込むとなると以下の手順が必要そうだなぁと考えると思います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;記事を読んで内容を理解し、大まかな手順を理解する。&lt;/li&gt;
&lt;li&gt;細かい設定やドキュメントを新規作成していく。&lt;/li&gt;
&lt;li&gt;自分のプロジェクトに合わせてカスタマイズ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そうすると、めんどくさくなって放置してしまいます。&lt;/p&gt;
&lt;h2&gt;LLM時代の知識習得&lt;/h2&gt;
&lt;p&gt;しかし、このような**「Before LLM」の思考パターンは既に古い**ものです。&lt;/p&gt;
&lt;p&gt;現在は、LLM の力により、&lt;strong&gt;攻殻機動隊や映画Matrixのように知識を瞬時にインストールできる時代&lt;/strong&gt;が到来しています。&lt;/p&gt;
&lt;h2&gt;実践方法&lt;/h2&gt;
&lt;h3&gt;ワンライナーコマンドで完了&lt;/h3&gt;
&lt;p&gt;以下のコマンドをコピー&amp;amp;ペーストするだけで導入が完了します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &apos;https://zenn.dev/driller/articles/2a23ef94f1d603 上記の記事を理解して、今作っているリポジトリに対しても同じファイル構成で作って。&apos; | claude
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;こんな雑なプロンプトでもマルチモーダルなLLMなのでちゃんとURLを読みに行って理解して、自分のリポジトリに反映してくれます！&lt;/p&gt;
&lt;h3&gt;結果：数分で知見を獲得&lt;/h3&gt;
&lt;p&gt;数分後には、自分のリポジトリでも&lt;a href=&quot;https://zenn.dev/driller&quot;&gt;driller&lt;/a&gt;さんが蓄積した知見を活用できるようになります。&lt;/p&gt;
&lt;h3&gt;生成されるファイル構成&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;❯ tree .claude
.claude
├── common-patterns.md
├── context.md
├── debug
│   ├── archive
│   ├── sessions
│   └── temp-logs
├── debug-log.md
├── project-improvements.md
├── project-knowledge.md
└── settings.local.json
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;実際の生成例&lt;/h2&gt;
&lt;p&gt;TypeScriptで構築した&lt;a href=&quot;https://ai-triathlon-result.teraren.com/&quot;&gt;個人開発サービス&lt;/a&gt;のリポジトリで実行した結果、以下のようなドキュメントが生成されました：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ head -n 20 .claude/**/*md
==&amp;gt; .claude/common-patterns.md &amp;lt;==
# よく使用するパターン

## 開発コマンド

### 基本開発フロー

```bash
# 開発サーバー起動（デバッグインスペクター付き）
pnpm dev

# ビルド（サイトマップ自動生成付き）
pnpm build

# 本番サーバー起動
pnpm start

# リンティング
pnpm lint

# サイトマップのみ生成

==&amp;gt; .claude/context.md &amp;lt;==
# プロジェクトコンテキスト

## 概要

- プロジェクト名: トライアスロン リザルト分析アプリケーション
- 技術スタック: Next.js 15.3 + TypeScript 5.2 + Tailwind CSS 4.1
- 目標: 日本のトライアスロン大会結果分析と AI によるパフォーマンス分析・トレーニング提案

## プロジェクトの背景

- 日本のトライアスロン大会の結果データを分析
- 選手の過去の成績から傾向を分析し、AI（llama3-70b-8192）による個別のトレーニング提案を提供
- 2011 年から 2025 年までの豊富なデータを活用した統計分析

## 制約条件

- **データソース**: TSV ファイルベース（データベース不使用）
- **パフォーマンス**: Vercel Speed Insights 使用、レスポンス重視
- **SEO**: サイトマップ自動生成、OGP 設定必須
- **モバイル対応**: レスポンシブデザイン必須

==&amp;gt; .claude/debug-log.md &amp;lt;==
# 重要なデバッグ記録

## [2024-12-10] TSV ヘッダーマッピングエラー

**症状**: 新しい年度のデータ追加時に「undefined column」エラーが発生 **環境**: Node.js 18.17.0,
Next.js 15.3 **再現手順**:

1. 新しい年度の TSV ファイルを`public/master/2025/race_name/result.tsv`に配置
2. ページアクセス時にデータ読み込みエラー

**試行錯誤**:

- ❌ TSV ファイルの列名確認 → 列名は正しい
- ❌ ファイルパス確認 → パスも正しい
- ✅ `lib/data.ts`の headerMappings に該当年度・大会の設定がない

**最終解決方法**:

```typescript
// lib/data.ts のheaderMappingsに追加

==&amp;gt; .claude/project-improvements.md &amp;lt;==
# 改善履歴

## 2024-12-15: TSV データ処理の統一化

**問題**: 年度・大会ごとに異なる TSV 列名により、個別処理が必要で保守性が悪い

**試行錯誤**:

- ❌ 各年度・大会別に個別の処理関数作成 → コード重複、バグ多発
- ❌ 固定ヘッダー前提の処理 → 実データとの乖離
- ✅ headerMappings による統一的なマッピングシステム → 90%の処理統一化

**最終解決策**:

1. `lib/data.ts`に headerMappings オブジェクト作成
2. 年度・大会をキーとした動的マッピング
3. デフォルト値とエラーハンドリングの統一
4. 型安全な変換処理の実装

**教訓**: 設定駆動のアプローチにより、データ構造の変化に柔軟に対応可能

==&amp;gt; .claude/project-knowledge.md &amp;lt;==
# プロジェクト知見集

## アーキテクチャ決定

### データ処理システム

- **TSV ファイルベース**: データベース不使用でファイルベースのデータ管理を採用
- **理由**: シンプルな構成、Vercel での静的ホスティング最適化、データの透明性
- **学習**: 当初はデータベース検討したが、データ更新頻度とホスティングコストを考慮し変更

### ヘッダーマッピングシステム

- `lib/data.ts`の`headerMappings`で年度・大会別の列名差異を吸収
- **理由**: 各年度・大会で TSV の列名が異なるため統一的な処理が必要
- **学習**: 初期は個別処理していたが、メンテナンス性が悪く統一システムに変更

### AI 統合アーキテクチャ

- Groq SDK + llama3-70b-8192 による高速推論
- Upstash Redis による応答キャッシュ
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;生成されたドキュメントの特徴&lt;/h3&gt;
&lt;p&gt;生成されたドキュメントには以下のような実用的な情報が含まれています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;プロジェクトコンテキスト&lt;/strong&gt;: 技術スタック、制約条件、背景情報&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デバッグ記録&lt;/strong&gt;: 過去に発生した問題と解決方法の詳細&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;改善履歴&lt;/strong&gt;: 試行錯誤の過程と最終的な解決策&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アーキテクチャ決定&lt;/strong&gt;: 設計判断の理由と学習内容&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;この手法の価値&lt;/h2&gt;
&lt;h3&gt;時間効率の劇的な改善&lt;/h3&gt;
&lt;p&gt;従来であれば：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;記事を読み込む（30 分〜1 時間）&lt;/li&gt;
&lt;li&gt;自分のプロジェクトに合わせて設定を調整（1〜2 時間）&lt;/li&gt;
&lt;li&gt;試行錯誤しながら導入（数時間）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;LLM を活用することで：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;コマンド実行（1 分）&lt;/li&gt;
&lt;li&gt;生成結果の確認と微調整（10〜15 分）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;知識の民主化&lt;/h3&gt;
&lt;p&gt;優秀な開発者が蓄積した知見を、経験の浅い開発者でも瞬時に活用できるようになります。これにより、チーム全体の開発効率とコード品質の向上が期待できます。&lt;/p&gt;
&lt;h2&gt;注意点とベストプラクティス&lt;/h2&gt;
&lt;h3&gt;生成されたドキュメントの検証&lt;/h3&gt;
&lt;p&gt;LLM が生成したドキュメントは、必ず内容を確認し、自分のプロジェクトに適合するかチェックしましょう。&lt;/p&gt;
&lt;h3&gt;継続的な更新&lt;/h3&gt;
&lt;p&gt;プロジェクトの進化に合わせて、生成されたドキュメントも定期的に更新することが重要です。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;LLM の力を活用することで、先駆者が構築した知見を瞬時に自分のプロジェクトに取り込むことが可能になりました。&lt;/p&gt;
&lt;p&gt;この手法により：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;開発効率の向上&lt;/strong&gt;: 設定時間の大幅短縮&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;知識の共有&lt;/strong&gt;: 優秀な開発者の知見を誰でも活用可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;品質の向上&lt;/strong&gt;: 実証済みのベストプラクティスを即座に導入&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;「Before LLM」の思考から脱却し、新しい時代の開発手法を積極的に取り入れることで、より効率的で質の高い開発が実現できるでしょう。&lt;/p&gt;
</content:encoded></item><item><title>コーディングエージェントごとに独立したコンテナを提供するcontainer-useを動かしてLLMを並列同時実行してみた</title><link>https://blog.teraren.com/posts/container-use/</link><guid isPermaLink="true">https://blog.teraren.com/posts/container-use/</guid><description>Docker の創業者の 1 人が、特定のワークツリーをコンテナ内に配置してコーディングエージェントを動作させるツール「container-use」を開発しました。</description><pubDate>Mon, 09 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;container-use&lt;/strong&gt;で Docker コンテナ内にコーディングエージェントの実行環境を独立して作成可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;複数のエージェントを並列実行&lt;/strong&gt;してローカルで安全に開発環境を管理できる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MCP経由&lt;/strong&gt;で Claude Code、Cursor、goose などから簡単に操作可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git worktree&lt;/strong&gt;よりもクリーンで管理しやすい環境分離を実現&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ローカルで複数のコーディングエージェントを並列実行したい&lt;/strong&gt;方&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dockerコンテナ内で安全にAI開発環境を管理したい&lt;/strong&gt;方&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude Code、Cursor、gooseなどのMCP対応クライアント&lt;/strong&gt;を使っている方&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git worktreeの代替手法&lt;/strong&gt;を探している方&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;Docker の創業者の 1 人が、特定のワークツリーをコンテナ内に配置してコーディングエージェントを動作させるツール「container-use」を開発しました。
https://www.publickey1.jp/blog/25/container_usedocker.html&lt;/p&gt;
&lt;p&gt;2025 年 5 月頃には Git worktree を駆使してローカルで複数のコーディングエージェントの環境を作る手法が紹介されていましたが、個人的には ghq を使ったリポジトリ管理にそぐわないため、あまり注目していませんでした。&lt;/p&gt;
&lt;p&gt;理想的には、Docker コンテナ内で独立した環境を構築することで、ローカルで複数のコーディングエージェントを並行実行できるようにしたいと考えていました。&lt;/p&gt;
&lt;p&gt;そんな中、container-use がリリースされました。まさに求めていた機能だったので、早速試してみることにしました。&lt;/p&gt;
&lt;p&gt;container-use の動作概念図
&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-09-17-55-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;p&gt;まず、GitHub から container-use のリポジトリをクローンします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ ghq get git@github.com:dagger/container-use.git
     clone ssh://git@github.com/dagger/container-use.git -&amp;gt; /Users/yuki.matsukura/ghq/github.com/dagger/container-use
       git clone --recursive ssh://git@github.com/dagger/container-use.git /Users/yuki.matsukura/ghq/github.com/dagger/container-use
Cloning into &apos;/Users/yuki.matsukura/ghq/github.com/dagger/container-use&apos;...
remote: Enumerating objects: 735, done.
remote: Counting objects: 100% (144/144), done.
remote: Compressing objects: 100% (50/50), done.
remote: Total 735 (delta 129), reused 94 (delta 93), pack-reused 591 (from 2)
Receiving objects: 100% (735/735), 40.55 MiB | 8.85 MiB/s, done.
Resolving deltas: 100% (514/514), done.
❯ cd ~/ghq/github.com/dagger/container-use
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;cuコマンド経由で利用するようなので、cuコマンドをビルドします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ make
[+] Building 30.2s (11/11) FINISHED
 =&amp;gt; [internal] load build definition from Dockerfile
 =&amp;gt; =&amp;gt; transferring dockerfile: 396B
 =&amp;gt; [internal] load metadata for docker.io/library/golang:latest
 =&amp;gt; [auth] library/golang:pull token for registry-1.docker.io
 =&amp;gt; [internal] load .dockerignore
 =&amp;gt; =&amp;gt; transferring context: 120B
 =&amp;gt; [builder 1/4] FROM docker.io/library/golang:latest@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c
 =&amp;gt; =&amp;gt; resolve docker.io/library/golang:latest@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c
 =&amp;gt; =&amp;gt; sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c 9.74kB / 9.74kB
 =&amp;gt; =&amp;gt; sha256:f692138c53fd540f6d19fe65e259d0d1b681776d15187c50ab566297acf28227 2.32kB / 2.32kB
 =&amp;gt; =&amp;gt; sha256:1a12b4ea7c0ce04aa0e98be0a8c9942162bac71426f734fe6d3bf988bc9e2627 48.33MB / 48.33MB
 =&amp;gt; =&amp;gt; sha256:280bbe393e788ced1dcb033580604b24de083601624337be66b3ec31781dae40 23.55MB / 23.55MB
 =&amp;gt; =&amp;gt; sha256:9cd4095bdf35388c48f7b567b9a331abc514c2791a8beb35cd1558fb10d91285 2.82kB / 2.82kB
 =&amp;gt; =&amp;gt; sha256:1f4f297e4f699ae0f384d5cc1ea42065f58a115aa0a634d427cbb186f91cb4d0 64.36MB / 64.36MB
 =&amp;gt; =&amp;gt; sha256:90e45158653cee17fd0433bb95f654076603c1dace770784457d1f08ffc1f1bd 86.41MB / 86.41MB
 =&amp;gt; =&amp;gt; extracting sha256:1a12b4ea7c0ce04aa0e98be0a8c9942162bac71426f734fe6d3bf988bc9e2627
 =&amp;gt; =&amp;gt; sha256:f244882bda0eb70b1153262e9054d1f8801651888a3a6fc5a828db420391040e 75.23MB / 75.23MB
 =&amp;gt; =&amp;gt; sha256:d08d494a376b9ba066591a0d5e15795ecaa4ca7b89566facd3b70f93b58f9cfa 126B / 126B
 =&amp;gt; =&amp;gt; sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B
 =&amp;gt; =&amp;gt; extracting sha256:280bbe393e788ced1dcb033580604b24de083601624337be66b3ec31781dae40
 =&amp;gt; =&amp;gt; extracting sha256:1f4f297e4f699ae0f384d5cc1ea42065f58a115aa0a634d427cbb186f91cb4d0
 =&amp;gt; =&amp;gt; extracting sha256:90e45158653cee17fd0433bb95f654076603c1dace770784457d1f08ffc1f1bd
 =&amp;gt; =&amp;gt; extracting sha256:f244882bda0eb70b1153262e9054d1f8801651888a3a6fc5a828db420391040e
 =&amp;gt; =&amp;gt; extracting sha256:d08d494a376b9ba066591a0d5e15795ecaa4ca7b89566facd3b70f93b58f9cfa
 =&amp;gt; =&amp;gt; extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1
 =&amp;gt; [internal] load build context
 =&amp;gt; =&amp;gt; transferring context: 88.43kB
 =&amp;gt; [builder 2/4] WORKDIR /w
 =&amp;gt; [builder 3/4] COPY . .
 =&amp;gt; [builder 4/4] RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build go build -o /tmp/cu ./cmd/cu
 =&amp;gt; [stage-1 1/1] COPY --from=builder /tmp/cu .
 =&amp;gt; exporting to client directory
 =&amp;gt; =&amp;gt; copying files 21.24MB

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/wv9ddwk3l0o7bxmjts2g1cvfm
cu
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;cu&lt;/code&gt; コマンドをインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ make install &amp;amp;&amp;amp; hash -r

[+] Building 0.9s (10/10) FINISHED
 =&amp;gt; [internal] load build definition from Dockerfile
 =&amp;gt; =&amp;gt; transferring dockerfile: 396B
 =&amp;gt; [internal] load metadata for docker.io/library/golang:latest
 =&amp;gt; [internal] load .dockerignore
 =&amp;gt; =&amp;gt; transferring context: 120B
 =&amp;gt; [builder 1/4] FROM docker.io/library/golang:latest@sha256:db5d0afbfb4ab648af2393b92e87eaae9ad5e01132803d80caef91b5752d289c
 =&amp;gt; [internal] load build context
 =&amp;gt; =&amp;gt; transferring context: 1.33kB
 =&amp;gt; CACHED [builder 2/4] WORKDIR /w
 =&amp;gt; CACHED [builder 3/4] COPY . .
 =&amp;gt; CACHED [builder 4/4] RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build go build -o /tmp/cu ./cmd/cu
 =&amp;gt; CACHED [stage-1 1/1] COPY --from=builder /tmp/cu .
 =&amp;gt; exporting to client directory
 =&amp;gt; =&amp;gt; copying files 21.24MB

View build details: docker-desktop://dashboard/build/desktop-linux/desktop-linux/kdbpvxlq88med5tenxc9cyib6
cu
Installing cu to /Users/yuki.matsukura/.asdf/shims...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;asdfによってツールのバージョンを管理しているので、&lt;code&gt;cu&lt;/code&gt;は&lt;code&gt;~/.asdf/shims/cu&lt;/code&gt;にインストールされました。&lt;/p&gt;
&lt;h2&gt;使ってみる&lt;/h2&gt;
&lt;p&gt;MCP経由で操作できるので、MCPに対応しているクライアントからであれば何でも利用可能です。
今回はClaude Code経由で実行してみます。&lt;/p&gt;
&lt;h3&gt;Claude Codeに設定を追加&lt;/h3&gt;
&lt;p&gt;MCPサーバの設定を追加します。CLIから1発で登録できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ npx @anthropic-ai/claude-code mcp add container-use -- /Users/yuki.matsukura/.asdf/shims/cu stdio
Added stdio MCP server container-use with command: /Users/yuki.matsukura/.asdf/shims/ stdio to local config
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記のコマンドを実行すると、 以下のセクションが、&lt;code&gt;~/.claude.json&lt;/code&gt; へ追加されました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;/Users/yuki.matsukura/ghq/github.com/matsubo/cu-test&quot;: {
  &quot;allowedTools&quot;: [],
  &quot;history&quot;: [
    {
      &quot;display&quot;: &quot;/mcp &quot;,
      &quot;pastedContents&quot;: {}
    },
    {
      &quot;display&quot;: &quot;create a simple flask app\n&quot;,
      &quot;pastedContents&quot;: {}
    }
  ],
  &quot;dontCrawlDirectory&quot;: false,
  &quot;mcpContextUris&quot;: [],
  &quot;mcpServers&quot;: {
    &quot;container-use&quot;: {
      &quot;type&quot;: &quot;stdio&quot;,
      &quot;command&quot;: &quot;/Users/yuki.matsukura/.asdf/shims/cu&quot;,
      &quot;args&quot;: [
        &quot;stdio&quot;
      ],
      &quot;env&quot;: {}
    }
  },
  &quot;enabledMcpjsonServers&quot;: [],
  &quot;disabledMcpjsonServers&quot;: [],
  &quot;hasTrustDialogAccepted&quot;: true,
  &quot;projectOnboardingSeenCount&quot;: 0,
  &quot;hasClaudeMdExternalIncludesApproved&quot;: false,
  &quot;hasClaudeMdExternalIncludesWarningShown&quot;: false,
  &quot;hasCompletedProjectOnboarding&quot;: true,
  &quot;lastCost&quot;: 0.00041280000000000006,
  &quot;lastAPIDuration&quot;: 2617,
  &quot;lastDuration&quot;: 26041,
  &quot;lastLinesAdded&quot;: 0,
  &quot;lastLinesRemoved&quot;: 0,
  &quot;lastTotalInputTokens&quot;: 331,
  &quot;lastTotalOutputTokens&quot;: 37,
  &quot;lastTotalCacheCreationInputTokens&quot;: 0,
  &quot;lastTotalCacheReadInputTokens&quot;: 0,
  &quot;lastSessionId&quot;: &quot;877e8c9c-315a-4f4c-8a7e-xxxxxxxxxx&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;に、container-use上で実装させるための指示を追記します（存在していない場合は新規作成します）。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl https://raw.githubusercontent.com/dagger/container-use/main/rules/agent.md &amp;gt;&amp;gt; CLAUDE.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;container-useを使う前提として、
Gitリポジトリ上で最低1つのコミットが存在している前提で始めなければいけないという要件があります。&lt;/p&gt;
&lt;p&gt;今回はテスト用に作ったディレクトリなので、以下のように適当に初期化しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git init
git commit -m &apos;init&apos; CLAUDE.md
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Claude Code経由で実行&lt;/h3&gt;
&lt;p&gt;サンプルにあった以下のプロンプトで、超簡単なPythonのWebアプリを作ってみます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;create a simple flask app&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;新規でプロジェクト用のディレクトリを作成し、claudeコマンドを実行して初期化した後、以下のようにclaudeコマンドの標準入力へプロンプトを流し込みます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl https://raw.githubusercontent.com/dagger/container-use/refs/heads/main/examples/hello_world.md | claude
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のような出力が出て処理が進みます。
途中で何度か実装方針の確認のためにインタラクションが求められます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;╭──────────────────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                                    │
│                                                              │
│   /help for help, /status for your current setup             │
│                                                              │
│   cwd: /Users/yuki.matsukura/ghq/github.com/matsubo/cu-test  │
╰──────────────────────────────────────────────────────────────╯


 ※ Tip: Run claude --continue or claude --resume to resume a conversation

&amp;gt; create a simple flask app

⏺ I&apos;ll create a simple Flask app using the environment. Let me set up the development environment first.

⏺ container-use:environment_open (MCP)(source: &quot;/Users/yuki.matsukura/ghq/github.com/matsubo/cu-test&quot;, name: &quot;flask-app&quot;, explanation: &quot;Creating a development environment for a simple Flask application&quot;)
  ⎿  {
       &quot;id&quot;: &quot;flask-app/fast-guppy&quot;,
       &quot;base_image&quot;: &quot;ubuntu:24.04&quot;,
       &quot;setup_commands&quot;: null,
     … +7 lines (ctrl+r to expand)

⏺ container-use:environment_update (MCP)(environment_id: &quot;flask-app/fast-guppy&quot;, base_image: &quot;python:3.11-slim&quot;, setup_commands: [&quot;pip install flask&quot;], instructions: &quot;python Flask development environment with Flask installed&quot;, secrets: [], explanation: &quot;Setting up Python environment with Flask for web development&quot;)
  ⎿  {
       &quot;id&quot;: &quot;flask-app/fast-guppy&quot;,
       &quot;base_image&quot;: &quot;python:3.11-slim&quot;,
       &quot;setup_commands&quot;: [
     … +9 lines (ctrl+r to expand)

⏺ container-use:environment_file_write (MCP)(environment_id: &quot;flask-app/fast-guppy&quot;, target_file: &quot;app.py&quot;, contents: &quot;from flask import Flask\n\napp = Flask(__name__)\n\n@app.route(&apos;/&apos;)\ndef hello_world():\n    return &apos;Hello, World!&apos;\n\n@app.route(&apos;/about&apos;)\ndef about():\n    return &apos;This is a simple Flask application!&apos;\n\nif __name__ == &apos;__main__&apos;:\n
                                            app.run(debug=True, host=&apos;0.0.0.0&apos;, port=5000)&quot;, explanation: &quot;Creating the main Flask application file with basic routes&quot;)

╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Tool use                                                                                                                                                                                                                                                                                                                                                                               │
│                                                                                                                                                                                                                                                                                                                                                                                        │
│   container-use:environment_file_write(environment_id: &quot;flask-app/fast-guppy&quot;, target_file: &quot;app.py&quot;, contents: &quot;from flask import Flask\n\napp = Flask(__name__)\n\n@app.route(&apos;/&apos;)\ndef hello_world():\n    return &apos;Hello, World!&apos;\n\n@app.route(&apos;/about&apos;)\ndef about():\n    return &apos;This is a simple Flask application!&apos;\n\nif __name__ == &apos;__main__&apos;:\n    app.run(debug=True,    │
│   host=&apos;0.0.0.0&apos;, port=5000)&quot;, explanation: &quot;Creating the main Flask application file with basic routes&quot;) (MCP)                                                                                                                                                                                                                                                                        │
│   Write the contents of a file.                                                                                                                                                                                                                                                                                                                                                        │
│                                                                                                                                                                                                                                                                                                                                                                                        │
│ Do you want to proceed?                                                                                                                                                                                                                                                                                                                                                                │
│ ❯ 1. Yes                                                                                                                                                                                                                                                                                                                                                                               │
│   2. Yes, and don&apos;t ask again for container-use:environment_file_write commands in /Users/yuki.matsukura/ghq/github.com/matsubo/cu-test                                                                                                                                                                                                                                                │
│   3. No, and tell Claude what to do differently (esc)                                                                                                                                                                                                                                                                                                                                  │
│                                                                                                                                                                                                                                                                                                                                                                                        │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;コードが完成すると以下のメッセージが出てきました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;⏺ Created a simple Flask app! The application is now running at http://127.0.0.1:5192

  The app includes:
  - A home route at / that returns &quot;Hello, World!&quot;
  - An about route at /about with basic information

  To view your work: git checkout flask-app/fast-guppy

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;指定されたURLにアクセスすると以下の表示が出てきました。
&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-09-17-17-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;なんと簡単なアプリのコードが実装され、プレビュー用のサーバも立ち上がった状態です！&lt;/p&gt;
&lt;h3&gt;動作状態を確認する&lt;/h3&gt;
&lt;p&gt;どうやって実現しているのか軽く調べて見るために5192番ポートはどのプログラムが使っているのか調べてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ lsof -i :5192
COMMAND     PID           USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
dagger-0. 93633 yuki.matsukura    9u  IPv6 0x5e0f6ca282acbd35      0t0  TCP *:aol-2 (LISTEN)
dagger-0. 93633 yuki.matsukura   19u  IPv6 0x27afabb4da99321a      0t0  TCP [::127.0.0.1]:aol-2-&amp;gt;[::127.0.0.1]:49823 (CLOSED)
dagger-0. 93633 yuki.matsukura   22u  IPv6 0x3591df621981b1a0      0t0  TCP [::127.0.0.1]:aol-2-&amp;gt;[::127.0.0.1]:49834 (CLOSED)
dagger-0. 93633 yuki.matsukura   25u  IPv6 0x5869ccfc590c9e6b      0t0  TCP [::127.0.0.1]:aol-2-&amp;gt;[::127.0.0.1]:50072 (CLOSED)
dagger-0. 93633 yuki.matsukura   27u  IPv6 0x1d1e9ef498d1fd1f      0t0  TCP [::127.0.0.1]:aol-2-&amp;gt;[::127.0.0.1]:50077 (CLOSED)
dagger-0. 93633 yuki.matsukura   28u  IPv6 0x54ecff8288d4bfbb      0t0  TCP [::127.0.0.1]:aol-2-&amp;gt;[::127.0.0.1]:53232 (CLOSED)
dagger-0. 93633 yuki.matsukura   29u  IPv6 0x538b2f4cfbc2347f      0t0  TCP localhost:aol-2-&amp;gt;localhost:54005 (CLOSE_WAIT)
dagger-0. 93633 yuki.matsukura   30u  IPv6 0xbe8b89781820e36c      0t0  TCP localhost:aol-2-&amp;gt;localhost:54023 (CLOSE_WAIT)
dagger-0. 93633 yuki.matsukura   31u  IPv6 0x97cc532cfede2ef1      0t0  TCP localhost:aol-2-&amp;gt;localhost:54029 (CLOSE_WAIT)
dagger-0. 93633 yuki.matsukura   32u  IPv6 0xda67712e4db968cd      0t0  TCP localhost:aol-2-&amp;gt;localhost:54033 (CLOSE_WAIT)
dagger-0. 93633 yuki.matsukura   33u  IPv6 0xa63d580e5b1ab14a      0t0  TCP localhost:aol-2-&amp;gt;localhost:54622 (CLOSE_WAIT)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MCP Serverっぽいプロセスが立ち上がっています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ ps axu|grep dagger-0|grep -v grep
yuki.matsukura   93633   0.2  0.1 411972208  49168 s015  S+    5:13PM   0:05.77 /Users/yuki.matsukura/Library/Caches/dagger/dagger-0.18.9 session --label dagger.io/sdk.name:go --label dagger.io/sdk.version:0.18.9
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;コンテナは1つだけしか立ち上がらないようです。LLMの実行中もモニタリングしていましたが1つだけでした。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ docker ps
CONTAINER ID   IMAGE                               COMMAND                  CREATED          STATUS          PORTS                    NAMES
6bd9e55c455e   registry.dagger.io/engine:v0.18.9   &quot;dagger-entrypoint.s…&quot;   12 minutes ago   Up 12 minutes                            dagger-engine-v0.18.9

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このコンテナの中で、開発環境のコードの実行をプレビューするためのプロセスが立ち上がっていることがわかります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ docker exec -it 6bd9 ps axu
PID   USER     TIME  COMMAND
    1 root      0:51 /usr/local/bin/dagger-engine --config /etc/dagger/engine.toml --debug
   52 root      0:00 /usr/sbin/dnsmasq --keep-in-foreground --log-facility=- --log-debug -u root --conf-file=/var/run/containers/cni/dnsname/dagger/dnsmasq.conf
 1343 root      0:00 buildctl dial-stdio
 1353 root      0:00 buildctl dial-stdio
 1363 root      0:00 buildctl dial-stdio
 1476 root      0:00 buildctl dial-stdio
 1536 root      0:00 /usr/local/bin/runc --log /var/lib/dagger/worker/executor/runc-log.json --log-format json run --bundle /var/lib/dagger/worker/executor/vworhos7now5ohy2fu91ulocj --keep vworhos7now5ohy2fu91ulocj
 1548 root      0:00 /.init sh -c python app.py
 1563 root      0:00 sh -c python app.py
 1564 root      0:00 python app.py
 1565 root      0:00 /usr/local/bin/python app.py
 1619 root      0:00 /usr/local/bin/runc --log /var/lib/dagger/worker/executor/runc-log.json --log-format json run --bundle /var/lib/dagger/worker/executor/y5fwt2a2auf01ig0x8j4tu6qg --keep y5fwt2a2auf01ig0x8j4tu6qg
 1634 root      0:00 /.init sh -c python app.py
 1647 root      0:00 sh -c python app.py
 1648 root      0:00 python app.py
 1649 root      0:00 /usr/local/bin/python app.py
 1833 root      0:00 /usr/local/bin/runc --log /var/lib/dagger/worker/executor/runc-log.json --log-format json run --bundle /var/lib/dagger/worker/executor/joafz8klnzs7cyq5au6qoqxxr --keep joafz8klnzs7cyq5au6qoqxxr
 1846 root      0:00 /.init sh -c uvicorn main:app --host 0.0.0.0 --port 8000
 1860 root      0:00 sh -c uvicorn main:app --host 0.0.0.0 --port 8000
 1861 root      0:00 {uvicorn} /usr/local/bin/python3.11 /usr/local/bin/uvicorn main:app --host 0.0.0.0 --port 8000
 1915 root      0:00 /usr/local/bin/runc --log /var/lib/dagger/worker/executor/runc-log.json --log-format json run --bundle /var/lib/dagger/worker/executor/4prsmjji1quxzpulajwnrwofy --keep 4prsmjji1quxzpulajwnrwofy
 1930 root      0:00 /.init sh -c uvicorn main:app --host 0.0.0.0 --port 8000
 1944 root      0:00 sh -c uvicorn main:app --host 0.0.0.0 --port 8000
 1945 root      0:00 {uvicorn} /usr/local/bin/python3.11 /usr/local/bin/uvicorn main:app --host 0.0.0.0 --port 8000
 1966 root      0:00 ps axu

What&apos;s next:
    Try Docker Debug for seamless, persistent debugging tools in any container or image → docker debug 6bd9
    Learn more at https://docs.docker.com/go/debug-cli/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;tig --all&lt;/code&gt; コマンドでリビジョングラフを確認してみると、勝手にブランチが作られて、自分の名前でコミットが3つ積まれていました。
&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-09-17-24-58.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一応ステップごとにコミットを分けてブランチを生やして実装してくれるようです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cu watch&lt;/code&gt;コマンドでcontainer-useの動作状態を見られるとのことなのでコマンドを実行してみましたが、どうやら裏ではGit logコマンドを1秒おきに実行しているだけのようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-09-17-27-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;並列で複数のコーディングエージェントを動かしてみる&lt;/h3&gt;
&lt;p&gt;サンプルにあったプロンプトを使ってみます。
2つのアプリの実装を指示するプロンプトです。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Create 2 variations of a simple hello world app using Flask and FastAPI. each in their own environment. Give me the URL of each app&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上記のプロンプトをClaude Codeに渡します。
何度も確認が求められます。1度の質問ごとにコミットが積まれていく感じなので、1つ作ってコミットして質問することを繰り返しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl https://raw.githubusercontent.com/dagger/container-use/refs/heads/main/examples/parallel.md | claude
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   132  100   132    0     0    279      0 --:--:-- --:--:-- --:--:--   279
╭──────────────────────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code!                                    │
│                                                              │
│   /help for help, /status for your current setup             │
│                                                              │
│   cwd: /Users/yuki.matsukura/ghq/github.com/matsubo/cu-test  │
╰──────────────────────────────────────────────────────────────╯


 ※ Tip: Create custom slash commands by adding .md files to .claude/commands/ in your project or ~/.claude/commands/ for commands that work in any project

&amp;gt; Create 2 variations of a simple hello world app using Flask and FastAPI. each in their own environment. Give me the URL of each app

⏺ I&apos;ll create two simple hello world apps - one using Flask and one using FastAPI, each in their own environment.
  ⎿  ☐ Create Flask hello world app in its own environment
     ☐ Create FastAPI hello world app in its own environment
     ☐ Start both apps and provide URLs to user
  ⎿  ☐ Create Flask hello world app in its own environment
     ☐ Create FastAPI hello world app in its own environment
     ☐ Start both apps and provide URLs to user

⏺ container-use:environment_open (MCP)(source: &quot;/Users/yuki.matsukura/ghq/github.com/matsubo/cu-test&quot;, name: &quot;flask-hello-world&quot;, explanation: &quot;Creating environment for Flask hello world app&quot;)
  ⎿  {
       &quot;id&quot;: &quot;flask-hello-world/relaxed-tarpon&quot;,
       &quot;base_image&quot;: &quot;ubuntu:24.04&quot;,
       &quot;setup_commands&quot;: null,
     … +7 lines (ctrl+r to expand)

⏺ container-use:environment_update (MCP)(environment_id: &quot;flask-hello-world/relaxed-tarpon&quot;, explanation: &quot;Setting up Python environment with Flask for hello world app&quot;, base_image: &quot;python:3.11-slim&quot;, instructions: &quot;This environment contains a simple Flask hello world application. Use &apos;python app.py&apos; to run the Flask server.&quot;, setup_commands: [&quot;pip install flask&quot;],
                                        secrets: [])
  ⎿  {
       &quot;id&quot;: &quot;flask-hello-world/relaxed-tarpon&quot;,
       &quot;base_image&quot;: &quot;python:3.11-slim&quot;,
       &quot;setup_commands&quot;: [
     … +9 lines (ctrl+r to expand)

⏺ container-use:environment_file_write (MCP)(environment_id: &quot;flask-hello-world/relaxed-tarpon&quot;, target_file: &quot;app.py&quot;, explanation: &quot;Creating Flask hello world application&quot;, contents: &quot;from flask import Flask\n\napp = Flask(__name__)\n\n@app.route(&apos;/&apos;)\ndef hello_world():\n    return &apos;Hello, World! This is a Flask app.&apos;\n\nif __name__ == &apos;__main__&apos;:\n
                                            app.run(host=&apos;0.0.0.0&apos;, port=5000, debug=True)&quot;)
  ⎿  file app.py written successfully, changes pushed to container-use/flask-hello-world/relaxed-tarpon

⏺ container-use:environment_run_cmd (MCP)(environment_id: &quot;flask-hello-world/relaxed-tarpon&quot;, command: &quot;python app.py&quot;, background: true, ports: [5000], explanation: &quot;Starting Flask hello world app in background&quot;)
  ⎿  Command started in the background. Endpoints are {&quot;5000&quot;:{&quot;internal&quot;:&quot;mlr2r7877less:5000&quot;,&quot;external&quot;:&quot;127.0.0.1:5727&quot;}}

     Any changes to the container workdir (/workdir) WILL NOT be committed to container-use/flask-hello-world/relaxed-tarpon

     Background commands are unaffected by filesystem and any other kind of changes. You need to start a new command for changes to take effect.
  ⎿  ☒ Create Flask hello world app in its own environment
     ☐ Create FastAPI hello world app in its own environment
     ☐ Start both apps and provide URLs to user

⏺ container-use:environment_open (MCP)(source: &quot;/Users/yuki.matsukura/ghq/github.com/matsubo/cu-test&quot;, name: &quot;fastapi-hello-world&quot;, explanation: &quot;Creating environment for FastAPI hello world app&quot;)
  ⎿  {
       &quot;id&quot;: &quot;fastapi-hello-world/champion-satyr&quot;,
       &quot;base_image&quot;: &quot;ubuntu:24.04&quot;,
       &quot;setup_commands&quot;: null,
     … +7 lines (ctrl+r to expand)

⏺ container-use:environment_update (MCP)(environment_id: &quot;fastapi-hello-world/champion-satyr&quot;, explanation: &quot;Setting up Python environment with FastAPI for hello world app&quot;, base_image: &quot;python:3.11-slim&quot;, instructions: &quot;This environment contains a simple FastAPI hello world application. Use &apos;uvicorn main:app --host 0.0.0.0 --port 8000&apos; to run the FastAPI server.&quot;,
                                        setup_commands: [&quot;pip install fastapi uvicorn&quot;], secrets: [])
  ⎿  {
       &quot;id&quot;: &quot;fastapi-hello-world/champion-satyr&quot;,
       &quot;base_image&quot;: &quot;python:3.11-slim&quot;,
       &quot;setup_commands&quot;: [
     … +9 lines (ctrl+r to expand)

⏺ container-use:environment_file_write (MCP)(environment_id: &quot;fastapi-hello-world/champion-satyr&quot;, target_file: &quot;main.py&quot;, explanation: &quot;Creating FastAPI hello world application&quot;, contents: &quot;from fastapi import FastAPI\n\napp = FastAPI()\n\n@app.get(\&quot;/\&quot;)\ndef read_root():\n    return {\&quot;message\&quot;: \&quot;Hello, World! This is a FastAPI app.\&quot;}&quot;)
  ⎿  file main.py written successfully, changes pushed to container-use/fastapi-hello-world/champion-satyr

⏺ container-use:environment_run_cmd (MCP)(environment_id: &quot;fastapi-hello-world/champion-satyr&quot;, command: &quot;uvicorn main:app --host 0.0.0.0 --port 8000&quot;, background: true, ports: [8000], explanation: &quot;Starting FastAPI hello world app in background&quot;)
  ⎿  Command started in the background. Endpoints are {&quot;8000&quot;:{&quot;internal&quot;:&quot;4abousts0jpik:8000&quot;,&quot;external&quot;:&quot;127.0.0.1:5033&quot;}}

     Any changes to the container workdir (/workdir) WILL NOT be committed to container-use/fastapi-hello-world/champion-satyr

     Background commands are unaffected by filesystem and any other kind of changes. You need to start a new command for changes to take effect.
  ⎿  ☒ Create Flask hello world app in its own environment
     ☒ Create FastAPI hello world app in its own environment
     ☒ Start both apps and provide URLs to user

⏺ Both hello world apps are now running! Here are the URLs:

  Flask App: http://127.0.0.1:5727
  FastAPI App: http://127.0.0.1:5033

  To view the code for each app:
  - Flask: git checkout flask-hello-world/relaxed-tarpon
  - FastAPI: git checkout fastapi-hello-world/champion-satyr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完成しました。&lt;/p&gt;
&lt;p&gt;それぞれのURLが表示されるのでアクセスしてみました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-09-17-42-58.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ブランチは以下のような感じに作られました。
&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-09-17-45-41.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;よく確認してみると、リモートブランチに作られています。
ということは、リモートブランチはどこに指定されているのか確認してみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ grep &apos;remote &quot;container-use&quot;&apos;  .git/config -A 2
[remote &quot;container-use&quot;]
        url = /Users/yuki.matsukura/.config/container-use/repos/cu-test
        fetch = +refs/heads/*:refs/remotes/container-use/*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;なんと、ホームディレクトリの&lt;code&gt;.config&lt;/code&gt; ディレクトリ以下に保存されています。このリモートリポジトリは環境を作成するたびに肥大化していくため、定期的な管理が必要です。現在のところ環境を削除する専用のコマンドは提供されていないため、不要になった環境のデータは手動で削除する必要があります。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;container-use を使って並列で複数のコーディングエージェントを動かすことが可能になったので、手元で複数のエージェントを並行で安全に動作させて実行できるようになりました。&lt;/p&gt;
&lt;p&gt;GitHub Actions で Claude Code を実行すると Actions の稼働時間を消費してしまうので、ローカルで動かせるエージェントはローカルで動かすことでコスト削減できます。&lt;/p&gt;
&lt;p&gt;今まではきれいに並列でコーディングエージェントを動かす方法がありませんでしたが、container-use によってコンテナ内に閉じた個別に独立した環境でエージェントが実装を進められるようになります。&lt;/p&gt;
&lt;p&gt;（自分で作ろうかなと思っていたら、ちょうどリリースされました）。&lt;/p&gt;
</content:encoded></item><item><title>デジタルアドレスの問題点と将来像 〜日本郵便のサービスをビジネス視点で考える〜</title><link>https://blog.teraren.com/posts/digital-address-critic/</link><guid isPermaLink="true">https://blog.teraren.com/posts/digital-address-critic/</guid><description>日本郵便が住所を 7 桁の英数字で表現する新サービス「デジタルアドレス」の提供を 2025 年 5 月 26 日に開始しました。</description><pubDate>Fri, 06 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;日本郵便が 2025 年 5 月 26 日に&lt;strong&gt;デジタルアドレス&lt;/strong&gt;サービスを開始&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全ステークホルダーにとってデメリットが利便性を上回る&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;技術的なセキュリティ対策が不十分で利用規約頼み&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;住所管理システムを開発している&lt;/strong&gt;エンジニア&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;プライバシー技術に興味がある&lt;/strong&gt;方&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新しいAPI&lt;/strong&gt;の導入を検討している開発者&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティリスク&lt;/strong&gt;を評価する必要がある方&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;日本郵便が住所を 7 桁の英数字で表現する新サービス「デジタルアドレス」の提供を 2025 年 5 月 26 日に開始しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-05-20-38-32.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;10 年以上前から &lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;郵便番号検索のAPIサービス&lt;/a&gt;を運営している身として、また大学時代に位置情報、GIS、プライバシーなどの研究をしていたドメイン知識を活かして、このサービスを技術的に分析した結果、&lt;strong&gt;現状では課題が多く、サービス内容を見直さないと運用が微妙&lt;/strong&gt;という結論に至りました。&lt;/p&gt;
&lt;p&gt;課題と改善提案を各ステークホルダーごとにブレークダウンして説明します。&lt;/p&gt;
&lt;h2&gt;ステークホルダーの整理&lt;/h2&gt;
&lt;p&gt;このサービスには以下のステークホルダーが存在します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;デジタルアドレスを発行・管理する個人・法人&lt;/strong&gt;（ゆう ID 利用者）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デジタルアドレスを入力する個人・法人&lt;/strong&gt;（エンドユーザー）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デジタルアドレスの入力を受け付け保管・管理する者&lt;/strong&gt;（ユーザー）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自社のユーザや取引先の住所を管理する事業者&lt;/strong&gt;（ユーザー）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デジタルアドレスと住所の関連付けを管理主体&lt;/strong&gt;（郵便局・提供者）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;上記に加えて、セキュリティの観点で以下のアクターが存在します&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不正に住所情報を取得しようとする悪意のある人&lt;/strong&gt;（第三者）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;各ステークホルダーに対してのデメリット&lt;/h2&gt;
&lt;p&gt;メリットに関しては &lt;a href=&quot;https://news.yahoo.co.jp/articles/133bc09910298599dc471c16583a39fbfd0cc7b5?page=2&quot;&gt;郵便局が発信&lt;/a&gt;しているのでここではその逆であるデメリットについて述べます。&lt;/p&gt;
&lt;h3&gt;デジタルアドレスを発行・管理する個人・法人（ゆうID利用者）&lt;/h3&gt;
&lt;h4&gt;利便性の問題&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;住所を伝達する際に、デジタルアドレスの 7 桁だけを伝えればすむから良いが、&lt;strong&gt;長いので覚えづらい&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;普通に自分の住所も覚えておく必要があるので&lt;strong&gt;使う頻度は少ない&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;わざわざ利用するときに記録したメモなどを参照するほうが面倒になる&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Webフォームでの必要性の低さ&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Web のフォームで入力する場合はコピー&amp;amp;ペーストで済むかもしれないが、そもそも&lt;strong&gt;Webのフォームであればブラウザのオートコンプリートで住所が入力される&lt;/strong&gt;からそもそも問題がない&lt;/li&gt;
&lt;li&gt;わざわざデジタルアドレスを使う必要性が無い&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;深刻なプライバシーリスク&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;デジタルアドレスを自分以外の人や組織に伝えることによって、&lt;strong&gt;最新の住所がトラッキングできる状態になる&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;そのデジタルアドレスが住所以外の情報と結びつくことによって個人情報となる&lt;/li&gt;
&lt;li&gt;デジタルアドレスを使わなければ、もし住所情報が漏洩したら最悪の場合は引っ越せば良いが、&lt;strong&gt;デジタルアドレスが漏洩した場合はデジタルアドレスを作り直したうえで引っ越す必要がある&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;古いデジタルアドレスを共有されている人や事業者にとっては最新の住所を参照できるキーであるデジタルアドレスの意味がなくなってしまう&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;名寄せリスク&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;インターネット上で複数の事業者からデジタルアドレスを含むアカウント情報が漏洩した場合、&lt;strong&gt;デジタルアドレスをキーとして名寄せをされてしまう&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;今までであればメールアドレスや電話番号によって名寄せできていたが同じように ID 性の高いキーによって名寄せを促進させる状態になってしまう&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;監視・管理の不可能性&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;自分のデジタルアドレスの管理のために、&lt;strong&gt;誰がどのようにして自分のデジタルアドレスを検索しているのかを知りたいが、知るすべがない&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;もし、不正に利用されそうだったら即座にそのデジタルアドレスを止めたいのに、知るすべがない&lt;/li&gt;
&lt;li&gt;デジタルアドレスが漏洩したとしても把握できない&lt;/li&gt;
&lt;li&gt;本来ならば、管理画面上で自分のデジタルアドレスを参照したユーザのエンティティを知れる状態を作るべき&lt;/li&gt;
&lt;li&gt;例えば、Amazon にデジタルアドレスに登録したのに、使うべきではない言葉なので修正してください DM を送りつける会社が自分のデジタルアドレスを検索していたら止めたいので&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;div class=&quot;warning&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;利便性が微小だが、漏洩した際のリスクが大きい&lt;/strong&gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h3&gt;デジタルアドレスを入力する個人・法人（エンドユーザー）&lt;/h3&gt;
&lt;h4&gt;記憶・使用の困難さ&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;使用頻度が低いから覚えるのがちょっと難しい&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;住所を使う機会のほうが圧倒的に多いのでわざわざ同じ情報を表現するために 2 つのことを覚えるのは難しい&lt;/li&gt;
&lt;li&gt;しかもランダムだから覚えづらい&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;ブラウザ対応の問題&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ブラウザがオートコンプリートに対応してくれればよいが、&lt;strong&gt;日本の独自仕様なので対応する可能性が低い&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;ブラウザから見たら、郵便番号の 1 つとして見られると思う&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;既存機能との競合&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;そもそも、&lt;strong&gt;ブラウザにオートコンプリートが付いているのでデジタルアドレスを入力しないでもオートコンプリートを使う&lt;/strong&gt;ので入力の手間は低いのでデジタルアドレスを使うベネフィットが低い&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;個人間共有での問題&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;普段の生活において個人間での荷物のやり取りなどで住所を共有するケースがある&lt;/li&gt;
&lt;li&gt;ここでデジタルアドレスを利用すれば簡単に住所が共有できることになる&lt;/li&gt;
&lt;li&gt;しかしながら、&lt;strong&gt;デジタルアドレスは恒久的にその人の住所を表現するアドレスになるので誰にどのデジタルアドレスを共有しておいたかを覚えておかないと引っ越した時とかにリセットできなくなる&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;デジタルアドレスの入力を受け付け保管・管理する者（ユーザー）&lt;/h3&gt;
&lt;h4&gt;認証の複雑化&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;デジタルアドレスの入力を受け付けるために、デジタルアドレスから住所を検索する API を使う&lt;/li&gt;
&lt;li&gt;しかしながら、&lt;strong&gt;第三者によってブルートフォースなどによるアタックを防ぐために誰でもアクセスできる状態にあるところにデジタルアドレスから住所を求めるサービスを置けない&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ユーザ認証した後でないとデジタルアドレスの入力を受け付けることができない&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;その際のユーザ認証はそこそこ重要度が高くて個人が特定できるような電話番号が検証できているユーザや、捨てアドではないメールアドレスで到達性が確認できているメールアドレスを使って認証されたユーザの必要がある&lt;/li&gt;
&lt;li&gt;そもそもデジタルアドレスは EC といった場面で使うことが想定されているが、&lt;strong&gt;住所入力は個人認証に近いユーザ認証が終わってから出ないといけない&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;離脱リスクの増加&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;例えば事業者にとっては最低限、配送先と決済がおわればよいのに&lt;strong&gt;個人認証に近いことをやらなければいけないので離脱リスクが増えてしまう&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;監視負担の増加&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;デジタルアドレスから住所を検索する API が不正に利用されるのを防ぐために、&lt;strong&gt;事業者がエンドユーザに提供しているサービスの不正利用を細かく監視する必要がある&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;デジタルアドレスを検索しようとするアタッカーから常に守らなければならない&lt;/li&gt;
&lt;li&gt;もし、不正に利用されると&lt;strong&gt;自社のアカウントの信頼性が低くなるリスクがある&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;データ管理の複雑化&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;エンドユーザからデジタルアドレスを取得した場合、上記のような事項があるからデジタルアドレスだけではなくて現住所の情報も保管するのが一般的なユースケースかと考える&lt;/li&gt;
&lt;li&gt;その場合、同じ住所情報が 2 つあるので短期的には問題が無いが、&lt;strong&gt;引っ越したりしてどちらかが異なるような状態になったときに事業者はどちらを正として扱うか困惑する&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;あらかじめルールを決めたうえで運用し、エンドユーザにも認知させる必要がある&lt;/li&gt;
&lt;li&gt;例えば、デジタルアドレスを入力している場合はデジタルアドレスが主となると言った具合に&lt;/li&gt;
&lt;li&gt;しかし、&lt;strong&gt;デジタルアドレスはエンドユーザによって消去できたりもするので文字の住所情報が正しくてデジタルアドレスが検索できない状態になる状態も存在する&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;よって、&lt;strong&gt;住所情報を利用する際には毎回API検索が発生してしまって使い勝手が悪い&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;個人情報管理負担の増加&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;デジタルアドレスはエンドユーザのかなり重要な情報であるので、取り扱う個人情報が追加で増えてしまう&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;また、漏洩したときのリスクとエンドユーザに強いる操作が多くなる&lt;/li&gt;
&lt;li&gt;もし、デジタルアドレスと同時に氏名や電話番号が漏洩した場合はリスクを低くするためにデジタルアドレスを消去してもらうことをエンドユーザに依頼することとなる&lt;/li&gt;
&lt;li&gt;そうなると、&lt;strong&gt;エンドユーザにとって他の場所でも使っているデジタルアドレスがすべて無効になってしまうのでエンドユーザはデジタルアドレスのベネフィットを享受できなくなるばかりかリスク軽減のための運用を強いられてしまう&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;自社のユーザや取引先の住所を管理する事業者（ユーザー）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;3 に似ているが、ここでは社内利用。エンドユーザには提供しないケース&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;初めてこのケースでメリットのほうが大きくなりそうではある&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;デジタルアドレスの関連付けがpublicになっても問題ないケースではメリットのほうが大きいと考える&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;法人は、高頻度で引っ越すのでデジタルアドレスを取引先マスタの情報として持っておくと利便性は高い&lt;/li&gt;
&lt;li&gt;荷物を配送する前にデジタルアドレスを検証すれば不着になるリスクも抑えられる&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;デジタルアドレスと住所の関連付けを管理主体（郵便局・提供者）&lt;/h3&gt;
&lt;h4&gt;セキュリティリスク&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ブルートフォースによる不正アクセスから守らなければいけない&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;また&lt;strong&gt;関連付けのマスタ情報は機密性が高く狙われやすいので厳重に管理されていなければならない&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一度でも流出したら全個人ユーザに発行し直しとそのデジタルアドレスを登録しているサービスに対してすべて登録しなおしてもらう依頼をだすことになる&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;認証の脆弱性&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;現時点で、&lt;strong&gt;ゆうIDはメアドとパスワードだけでログインできてしまう&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;エンドユーザはパスワードを使いまわしているケースが多いので別のサイトで漏洩したメアドとパスワードでログインされてしまうリスクがあるので&lt;strong&gt;MFAを実装しなければリスクが高い&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;KYC を実装しないと、悪意のあるものが大量のアカウントを発行し、デジタルアドレスのブルートフォースに利用できてしまう。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;運用負担&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;デジタルアドレスの管理システムを長期的に運用し続けなければいけない&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;止めたくても止められない&lt;/li&gt;
&lt;li&gt;公共性が高いという理由で運用していても良いが、&lt;strong&gt;デジタルアドレスが存在することによって利用者の利便性が上がればよいが、デメリットのほうが上回る&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;あえてメリットがあるケース&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;公共性の高い住所の運用では利便性がありそう&lt;/strong&gt;です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;法人住所&lt;/strong&gt;や&lt;strong&gt;行政機関の住所&lt;/strong&gt;といったエンティティと住所が公に広く知れ渡ったほうが便益があるようなケース&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの場合、プライバシーリスクよりも利便性が上回る可能性があります。これにより秘匿する情報がなくなるのでセキュリティリスクは無くなります。&lt;/p&gt;
&lt;h2&gt;関連技術&lt;/h2&gt;
&lt;p&gt;住所と ID を紐づける既存の方法は存在していますが、どちらも利用方法が限定的です。プライバシーの問題を含まないスコープで運用するか、プライバシーの問題より利便性が上回る場合です。&lt;/p&gt;
&lt;h3&gt;大口事業所個別番号&lt;/h3&gt;
&lt;p&gt;大口事業所個別番号は、日本国内の大口事業所のみに発行されます。&lt;/p&gt;
&lt;p&gt;例えば、&lt;a href=&quot;https://postcode.teraren.com/postcodes/1048325&quot;&gt;〒104-8325&lt;/a&gt;は、&lt;code&gt;東京都中央区京橋２丁目９−２第一ぬり彦ビル 株式会社　読売新聞社　事業局&lt;/code&gt; を示します。&lt;/p&gt;
&lt;p&gt;この情報は基本的には法人なので情報はパブリックであり、ステークホルダー全てにメリットがあります。
大口事業所番号を割り当てる者（郵便局）、 荷物をおくる者（エンドユーザ）にとって住所入力の手間が減ります。もし、移転が発生したとしても同じ管轄であれば、大口事業所番号は変わりません。&lt;/p&gt;
&lt;h3&gt;Plus Codes&lt;/h3&gt;
&lt;p&gt;関連情報として住所表記にランダムな文字列を使う Plus Address（Plus Codes）があります。&lt;/p&gt;
&lt;p&gt;Plus Codes の特徴は以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;オープンソース&lt;/strong&gt;のデジタルアドレッシングシステム&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;緯度経度ベース&lt;/strong&gt;で場所を示す&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;住所がない場所でも利用可能&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;オフライン対応&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;言語非依存&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Plus Codes は 2 つのユースケースで実運用されています。
1 つは、住所表記が困難なスラム街での運用です。前提として、区画の表現が困難な地域において住所を識別する必要があるためです。こちらはデジタルアドレスと同様に匿名性という観点では問題にはなるのですが、匿名性より利便性のほうがまさるので運用されています。&lt;/p&gt;
&lt;p&gt;2 つ目は公共性の高い場所を示す場合や一時的に位置情報を共有する場合です。&lt;/p&gt;
&lt;p&gt;1 つ目のケースは、プライバシーの問題を含んでいますがそれを超える利便性があるから運用されており、2 つ目のケースはプライバシーの問題が起きないスコープで運用されています。&lt;/p&gt;
&lt;h2&gt;私の主張：「サービス内容の見直しが必要」&lt;/h2&gt;
&lt;p&gt;以上の点から、&lt;strong&gt;現状のデジタルアドレスサービスは課題が多く、サービス内容の見直しが必要&lt;/strong&gt;と考えます。&lt;/p&gt;
&lt;h3&gt;主な課題&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;利便性が微小なのに漏洩時のリスクが甚大&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;全ステークホルダー（社内利用以外）にデメリットが存在&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;技術的なセキュリティ対策が不十分&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;既存技術（ブラウザオートコンプリート）で十分&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;改善提案&lt;/h3&gt;
&lt;p&gt;もしデジタルアドレスサービスを継続するなら、以下の改善が必要と考えます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;文字列長の拡張&lt;/strong&gt;: 7 桁ではなく、少なくとも 16 桁以上に変更してセキュリティを強化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;技術的セキュリティ対策&lt;/strong&gt;: レート制限、IP 制限、異常検知などの実装&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MFA必須化&lt;/strong&gt;: ゆう ID の取得には KYC を実施する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;透明性の向上&lt;/strong&gt;: 利用統計の開示、不正利用の通知機能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;利用範囲の限定&lt;/strong&gt;: まずは法人・行政機関など公共性の高い住所に限定する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;現状のサービス内容ではすべてを満たすことは不可能なので、何かしら機能強化をするかスコープを限定するべきと考えます。&lt;/p&gt;
</content:encoded></item><item><title>WordPressをSQLite対応してGitで管理し、AWS Lightsail Containerへデプロイする構成</title><link>https://blog.teraren.com/posts/wordpress-sqlite-repository-lightsail/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-sqlite-repository-lightsail/</guid><description>WordPress で運用されているサイトは大量に存在しますよね。用途は多種多様ですが、今回は開発環境、ステージング環境、本番環境などの**複数の環境が存在するようなコーポレートサイト、プラグイン開発、テーマ開発**を行っている方を対象とし</description><pubDate>Fri, 06 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;WordPressをSQLiteで運用&lt;/strong&gt;することで、すべてをファイルで管理できるようになる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git + Docker + Lightsail Container&lt;/strong&gt;で使うべきではない言葉なので修正してくださいの運用ワークフローが構築できる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;管理画面を無効化&lt;/strong&gt;してセキュリティリスクを大幅削減&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;月$7で本格的なコンテナ運用&lt;/strong&gt;が可能&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WordPress の運用で&lt;strong&gt;バージョン管理に困っている&lt;/strong&gt;方&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開発環境・ステージング・本番環境&lt;/strong&gt;の同期が大変だと感じている方&lt;/li&gt;
&lt;li&gt;コーポレートサイトなどの更新頻度が少ない WordPress を&lt;strong&gt;よりモダンな開発フローで運用したい&lt;/strong&gt;方&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;セキュリティを重視&lt;/strong&gt;した WordPress 運用を考えている方&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コンテナ技術&lt;/strong&gt;で WordPress を運用してみたい方&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;WordPress で運用されているサイトは大量に存在しますよね。用途は多種多様ですが、今回は開発環境、ステージング環境、本番環境などの&lt;strong&gt;複数の環境が存在するようなコーポレートサイト、プラグイン開発、テーマ開発&lt;/strong&gt;をしている方を対象としています。&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;WordPress の表示は&lt;strong&gt;ファイル × データベースの内容の組み合わせ&lt;/strong&gt;になっています。
開発環境でテーマファイルやプラグインを変更した場合は、各環境でファイルとデータベースの内容を同期する必要があるのですが、&lt;strong&gt;これがかなり運用上大変&lt;/strong&gt;なんですよね...😅&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-06-23-06-39.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;具体的には、次のような問題があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;バージョン管理ができなくて辛い&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;不具合が起きたときに、&lt;strong&gt;ファイルが原因なのか入稿されているデータが原因か特定するのが難しい&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;環境間でのデータ同期が煩雑&lt;/li&gt;
&lt;li&gt;ロールバックが困難&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;WordPress の
バックアップを難しくしているのは
データベース内に入っているデータと
ファイルシステム上にあるファイルが存在していて一緒にバックアップを取る必要がありますが、データベースのバックアップを取得するのが面倒です。そのデータベースをファイルとして扱えるように SQLite を使ってサイトを構築します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-06-22-25-52.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そうすれば、ファイルとしてバックアップするだけでスナップショットが取れます。スナップショットがファイルとして簡単に取得できるということはそれを様々な環境へ適用できます。
そのデータファイルもテーマファイルやプラグインと&lt;strong&gt;バージョン管理システムに入れることでスナップショットとして管理&lt;/strong&gt;することが可能になります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-06-23-07-05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;WordPress を SQLite で運用する詳細な方法については、こちらの記事で解説しています！
https://zenn.dev/matsubokkuri/articles/wordpress-sqlite
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;アプローチの評価を以下にまとめます。メリットが多いので新規で構築する際はこの方法を取ることを強く推奨します！&lt;/p&gt;
&lt;h3&gt;メリット&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;すべての状態をファイルで管理&lt;/strong&gt;することが可能になり、差分が明確になるしロールバックも容易に行える&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開発環境はDocker composeで立ち上げ&lt;/strong&gt;ることが可能になる（めちゃくちゃ楽！）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本番環境はコンテナで運用&lt;/strong&gt;できるようになり、スケールアウトが可能になる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SQLiteのデータファイルはバイナリデータ&lt;/strong&gt;ではあるがポータビリティがあるので OS のアーキテクチャ非依存&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本番はコンテナの運用なので管理画面を無効化&lt;/strong&gt;できるのでログイン画面へのアタックがなくなる（セキュリティ使うべきではない言葉なので修正してください！　🛡️）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WordPressの本体は公式イメージを使う&lt;/strong&gt;のでコア機能の更新が容易&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;デメリット&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Webでコンテンツの更新ができなくなる&lt;/strong&gt;。コンテンツを更新する際はローカルなどで行う必要がある&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;データベース上のデータはバイナリファイル&lt;/strong&gt;なので差分がテキストではわからない（コミットフックで差分を毎回取ってファイルとして dump しても良いがやり過ぎ感がある）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS Lightsail Containerがちょっと高い&lt;/strong&gt;。具体的には月に$7 USD/month かかる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;Web でのコンテンツ更新ができなくなるのは一見デメリットに見えますが、実際にはコンテンツの変更履歴が残るので、むしろメリットと考えることもできます！
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;h2&gt;設定方法&lt;/h2&gt;
&lt;p&gt;まず、&lt;strong&gt;ローカルでDocker composeでWordPress + SQLiteが立ち上がる環境&lt;/strong&gt;を作ります。&lt;/p&gt;
&lt;p&gt;ディレクトリ構成は以下のようになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.
├── docker-compose.yml
├── Makefile
├── themes/          # WordPressテーマ
├── plugins/         # WordPressプラグイン
├── uploads/         # アップロードファイル
├── database/        # データベースファイル
├── db.php          # SQLiteを使うためのドロップイン
└── custom.ini      # PHP設定のオーバーライド
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WordPressの本体は&lt;a href=&quot;https://hub.docker.com/_/wordpress&quot;&gt;docker image&lt;/a&gt;を利用するので&lt;strong&gt;カスタマイズする部分だけを管理&lt;/strong&gt;します。これがポイントです！&lt;/p&gt;
&lt;p&gt;次に重要なファイルを解説していきます。&lt;/p&gt;
&lt;h3&gt;docker-compose.yml&lt;/h3&gt;
&lt;p&gt;中身は以下のようになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  wordpress:
    image: wordpress:latest
    user: &quot;${UID:-1000}:${GID:-1000}&quot;
    restart: always
    volumes:
       - ./themes:/var/www/html/wp-content/themes
       - ./plugins:/var/www/html/wp-content/plugins
       - ./uploads:/var/www/html/wp-content/uploads
       - ./database:/var/www/html/wp-content/database
       - ./db.php:/var/www/html/wp-content/db.php
       - ./custom.ini:/usr/local/etc/php/conf.d/custom.ini
    ports:
      - &quot;8080:80&quot;
    environment:
      # 日本語ロケール設定
      LANG: ja_JP.UTF-8
      LANGUAGE: ja_JP:ja
      LC_ALL: ja_JP.UTF-8
      WORDPRESS_DB_HOST: dummy
      WORDPRESS_DB_NAME: dummy
      WORDPRESS_DB_USER: dummy
      WORDPRESS_CONFIG_EXTRA: |
        define(&apos;WP_HOME&apos;, &apos;${WP_HOME}&apos;);
        define(&apos;WP_SITEURL&apos;, &apos;${WP_HOME}&apos;);
        define(&apos;WP_AUTO_UPDATE_CORE&apos;, ${WP_AUTO_UPDATE_CORE:-false});
        define(&apos;WP_DEBUG_LOG&apos;, ${WP_DEBUG_LOG:-true});
        define(&apos;WP_DEBUG_DISPLAY&apos;, ${WP_DEBUG_DISPLAY:-true});
      WORDPRESS_AUTH_KEY: ${WORDPRESS_AUTH_KEY:-dummy}
      WORDPRESS_SECURE_AUTH_KEY: ${WORDPRESS_SECURE_AUTH_KEY:-dummy}
      WORDPRESS_LOGGED_IN_KEY: ${WORDPRESS_LOGGED_IN_KEY:-dummy}
      WORDPRESS_NONCE_KEY: ${WORDPRESS_NONCE_KEY:-dummy}
      WORDPRESS_AUTH_SALT: ${WORDPRESS_AUTH_SALT:-dummy}
      WORDPRESS_SECURE_AUTH_SALT: ${WORDPRESS_SECURE_AUTH_SALT:-dummy}
      WORDPRESS_LOGGED_IN_SALT: ${WORDPRESS_LOGGED_IN_SALT:-dummy}
      WORDPRESS_NONCE_SALT: ${WORDPRESS_NONCE_SALT:-dummy}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記のファイルが&lt;strong&gt;すべてのスタートとなるので重要&lt;/strong&gt;です。コンテナは1つだけなのでシンプルな構成になっています。公式のWordPressのイメージはApache + PHPという構成になっています。&lt;/p&gt;
&lt;p&gt;次に主要なセクションを解説します。&lt;/p&gt;
&lt;h4&gt;volumes セクション&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;volumes&lt;/code&gt; セクションで公式のWordPressでは空っぽになる部分を、&lt;strong&gt;自分で管理するためにローカルのファイルシステムをマウント&lt;/strong&gt;します。&lt;/p&gt;
&lt;p&gt;PHPの設定は適切な場所にファイルを置けば、勝手に読んでくれるので、そのまま使います。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;custom.ini&lt;/code&gt; には以下の設定を入れています。初期設定では&lt;strong&gt;大きな画像がアップロードできない&lt;/strong&gt;ので、大きめに設定しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;post_max_size = 200M
upload_max_filesize = 200M
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;environment セクション&lt;/h4&gt;
&lt;p&gt;環境変数である &lt;code&gt;environment&lt;/code&gt; について説明します。&lt;/p&gt;
&lt;p&gt;以下の設定は&lt;strong&gt;SQLiteなので不要&lt;/strong&gt;なのですが、WordPress側が公式にサポートしていないということもあり何かしらの値を設定する必要があるので&lt;strong&gt;ダミーの文字列を設定&lt;/strong&gt;しています。ちょっとかっこ悪いですがこれがないと動きません😅&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;WORDPRESS_DB_HOST: dummy
WORDPRESS_DB_NAME: dummy
WORDPRESS_DB_USER: dummy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WordPressのデータベース上には&lt;strong&gt;自分のサイトのURLを記録する必要&lt;/strong&gt;がありますが、それを環境ごとに外部から指定するために上の2つの環境変数を設定します。本番環境では、プラグインなどの自動更新は不要なので、&lt;code&gt;WP_AUTO_UPDATE_CORE&lt;/code&gt; を &lt;code&gt;false&lt;/code&gt; にします。また、ローカルといった開発環境では&lt;strong&gt;デバッグ関連の出力を多く出す&lt;/strong&gt;ために &lt;code&gt;WP_DEBUG_LOG&lt;/code&gt; と &lt;code&gt;WP_DEBUG_DISPLAY&lt;/code&gt; を &lt;code&gt;true&lt;/code&gt; にします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;WORDPRESS_CONFIG_EXTRA: |
  define(&apos;WP_HOME&apos;, &apos;${WP_HOME}&apos;);
  define(&apos;WP_SITEURL&apos;, &apos;${WP_HOME}&apos;);
  define(&apos;WP_AUTO_UPDATE_CORE&apos;, ${WP_AUTO_UPDATE_CORE:-false});
  define(&apos;WP_DEBUG_LOG&apos;, ${WP_DEBUG_LOG:-true});
  define(&apos;WP_DEBUG_DISPLAY&apos;, ${WP_DEBUG_DISPLAY:-true});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;秘密鍵を設定&lt;/strong&gt;するために &lt;code&gt;WORDPRESS_AUTH_KEY&lt;/code&gt; などの環境変数を設定します。この設定はなくても良いのですが、設定しないとコンテナの起動のたびにランダムな英数字が設定されます。それによって、&lt;strong&gt;ログインしているセッションがすべて破棄される&lt;/strong&gt;ので何かしらを設定しておいたほうが便利です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;WORDPRESS_AUTH_KEY: ${WORDPRESS_AUTH_KEY:-dummy}
WORDPRESS_SECURE_AUTH_KEY: ${WORDPRESS_SECURE_AUTH_KEY:-dummy}
WORDPRESS_LOGGED_IN_KEY: ${WORDPRESS_LOGGED_IN_KEY:-dummy}
WORDPRESS_NONCE_KEY: ${WORDPRESS_NONCE_KEY:-dummy}
WORDPRESS_AUTH_SALT: ${WORDPRESS_AUTH_SALT:-dummy}
WORDPRESS_SECURE_AUTH_SALT: ${WORDPRESS_SECURE_AUTH_SALT:-dummy}
WORDPRESS_LOGGED_IN_SALT: ${WORDPRESS_LOGGED_IN_SALT:-dummy}
WORDPRESS_NONCE_SALT: ${WORDPRESS_NONCE_SALT:-dummy}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;.envファイル&lt;/h3&gt;
&lt;p&gt;.envファイルの最低限の設定は以下のような感じになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;UID=501
GID=20
WP_HOME=&quot;http://localhost:8080&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;その他のファイル&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;db.php&lt;/code&gt; ファイルは&lt;a href=&quot;https://raw.githubusercontent.com/aaemnnosttv/wp-sqlite-db/refs/heads/master/src/db.php&quot;&gt;こちら&lt;/a&gt;のファイルです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Makefile&lt;/code&gt; には&lt;a href=&quot;https://gist.github.com/matsubo/cfaa37606f1a54327ea65610c9d3e1fb&quot;&gt;こちらの&lt;/a&gt;のような内容を入れています。なくてもよいのですが、&lt;strong&gt;docker関連の地味な権限周りの修正&lt;/strong&gt;などを行うためにあったほうが楽です。&lt;/p&gt;
&lt;h3&gt;起動方法&lt;/h3&gt;
&lt;p&gt;一通りファイルを揃えて、以下のコマンドを打てば立ち上がるはずです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;make up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そして、&lt;code&gt;http://localhost:8080&lt;/code&gt; にアクセスすると&lt;strong&gt;WordPressが表示されます&lt;/strong&gt;！　🎉&lt;/p&gt;
&lt;h2&gt;デプロイメント&lt;/h2&gt;
&lt;p&gt;ここまででWordPressを&lt;strong&gt;しっかりとファイルで管理できるようになった&lt;/strong&gt;らどこにでも簡単にデプロイできます。rsyncでサーバに同期しても良いです。ここでは、&lt;strong&gt;より柔軟な方法を使ってインフラを運用&lt;/strong&gt;するのでコンテナ環境でデプロイします。&lt;/p&gt;
&lt;p&gt;lightsailでは&lt;strong&gt;TLSのターミネーションをしてくれる&lt;/strong&gt;ので証明書の更新も自動化できます。&lt;/p&gt;
&lt;h3&gt;ファイルの準備&lt;/h3&gt;
&lt;p&gt;デプロイするイメージを作るための&lt;strong&gt;Dockerfile&lt;/strong&gt;を用意します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FROM wordpress:latest

# 日本語ロケールのインストールと設定
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y locales \
    &amp;amp;&amp;amp; sed -i &apos;/ja_JP.UTF-8/s/^# //g&apos; /etc/locale.gen \
    &amp;amp;&amp;amp; locale-gen \
    &amp;amp;&amp;amp; apt-get clean \
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*

ENV LANG=ja_JP.UTF-8
ENV LANGUAGE=ja_JP:ja
ENV LC_ALL=ja_JP.UTF-8

# カスタムPHP設定をコピー
COPY custom.ini /usr/local/etc/php/conf.d/custom.ini

# WordPressファイルをコピー（日本語ファイル名対応）
COPY themes/ /var/www/html/wp-content/themes/
COPY plugins/ /var/www/html/wp-content/plugins/
COPY uploads/ /var/www/html/wp-content/uploads/
COPY database/ /var/www/html/wp-content/database/
COPY db.php /var/www/html/wp-content/db.php

# WordPress管理機能の無効化
RUN rm -f /usr/src/wordpress/wp-login.php \
          /usr/src/wordpress/wp-config-sample.php \
          /usr/src/wordpress/readme.html \
          /usr/src/wordpress/license.txt \
          /usr/src/wordpress/wp-trackback.php \
          /usr/src/wordpress/wp-comments-post.php

# ポート80を公開
EXPOSE 80

# WordPressを起動
CMD [&quot;apache2-foreground&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;簡単に解説すると、docker composeでやっていることとほとんど同じです。デプロイする環境では&lt;strong&gt;WordPressの管理機能は使わせられない&lt;/strong&gt;ので管理画面に必要なファイルや運用に関係ないファイルを削除しています。&lt;/p&gt;
&lt;h3&gt;GitHub Actions設定&lt;/h3&gt;
&lt;p&gt;ステージング環境へデプロイするGitHub Actionsのワークフローファイルを以下に記載します。&lt;strong&gt;developブランチにpushするとlightsailのステージング環境へデプロイ&lt;/strong&gt;します。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.github/workflows/deploy-staging.yml&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Deploy to Staging

on:
  push:
    branches: [develop]
  workflow_dispatch:

env:
  AWS_REGION: ap-northeast-1
  LIGHTSAIL_SERVICE_NAME: mysite-staging
  IMAGE_NAME: wordpress-staging
  DOMAIN_NAME: example.com
  CONTAINER_NAME: wordpress
  CONTAINER_PORT: 80

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: Staging

    steps:
    - name: Set up locale for Japanese filenames
      run: |
        sudo apt-get update
        sudo apt-get install -y locales
        sudo locale-gen ja_JP.UTF-8
        echo &quot;LANG=ja_JP.UTF-8&quot; &amp;gt;&amp;gt; $GITHUB_ENV
        echo &quot;LC_ALL=ja_JP.UTF-8&quot; &amp;gt;&amp;gt; $GITHUB_ENV
        echo &quot;LANGUAGE=ja_JP:ja&quot; &amp;gt;&amp;gt; $GITHUB_ENV

    - name: Checkout code
      uses: actions/checkout@v4

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v4
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ env.AWS_REGION }}

    - name: Install AWS CLI Lightsail plugin
      run: |
        curl &quot;https://s3.us-west-2.amazonaws.com/lightsailctl/latest/linux-amd64/lightsailctl&quot; -o &quot;lightsailctl&quot;
        sudo mv lightsailctl /usr/local/bin/lightsailctl
        sudo chmod +x /usr/local/bin/lightsailctl

    - name: Build Docker image
      run: |
        export LANG=ja_JP.UTF-8
        export LC_ALL=ja_JP.UTF-8
        export LANGUAGE=ja_JP:ja
        docker build -t ${{ env.IMAGE_NAME }}:latest .

    - name: Push image to Lightsail
      id: push-image
      run: |
        IMAGE_LABEL=&quot;${{ env.LIGHTSAIL_SERVICE_NAME }}&quot;
        aws lightsail push-container-image \
          --region ${{ env.AWS_REGION }} \
          --service-name ${{ env.LIGHTSAIL_SERVICE_NAME }} \
          --label $IMAGE_LABEL \
          --image ${{ env.IMAGE_NAME }}:latest
        echo &quot;image_label=$IMAGE_LABEL&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT

    - name: Create deployment files
      run: |
        cat &amp;gt; containers.json &amp;lt;&amp;lt; EOF
        {
          &quot;${{ env.CONTAINER_NAME }}&quot;: {
            &quot;image&quot;: &quot;:${{ env.LIGHTSAIL_SERVICE_NAME }}.${{ steps.push-image.outputs.image_label }}.latest&quot;,
            &quot;environment&quot;: {
              &quot;WORDPRESS_DB_HOST&quot;: &quot;dummy&quot;,
              &quot;WORDPRESS_DB_NAME&quot;: &quot;dummy&quot;,
              &quot;WORDPRESS_DB_USER&quot;: &quot;dummy&quot;,
              &quot;WORDPRESS_CONFIG_EXTRA&quot;: &quot;define(&apos;WP_HOME&apos;, &apos;https://${{ env.DOMAIN_NAME }}&apos;); define(&apos;WP_SITEURL&apos;, &apos;https://${{ env.DOMAIN_NAME }}&apos;); define(&apos;WP_AUTO_UPDATE_CORE&apos;, false); define(&apos;WP_DEBUG_LOG&apos;, true); define(&apos;WP_DEBUG_DISPLAY&apos;, false);&quot;,
              &quot;WORDPRESS_AUTH_KEY&quot;: &quot;${{ secrets.WORDPRESS_AUTH_KEY }}&quot;,
              &quot;WORDPRESS_SECURE_AUTH_KEY&quot;: &quot;${{ secrets.WORDPRESS_SECURE_AUTH_KEY }}&quot;,
              &quot;WORDPRESS_LOGGED_IN_KEY&quot;: &quot;${{ secrets.WORDPRESS_LOGGED_IN_KEY }}&quot;,
              &quot;WORDPRESS_NONCE_KEY&quot;: &quot;${{ secrets.WORDPRESS_NONCE_KEY }}&quot;,
              &quot;WORDPRESS_AUTH_SALT&quot;: &quot;${{ secrets.WORDPRESS_AUTH_SALT }}&quot;,
              &quot;WORDPRESS_SECURE_AUTH_SALT&quot;: &quot;${{ secrets.WORDPRESS_SECURE_AUTH_SALT }}&quot;,
              &quot;WORDPRESS_LOGGED_IN_SALT&quot;: &quot;${{ secrets.WORDPRESS_LOGGED_IN_SALT }}&quot;,
              &quot;WORDPRESS_NONCE_SALT&quot;: &quot;${{ secrets.WORDPRESS_NONCE_SALT }}&quot;
            },
            &quot;ports&quot;: {
              &quot;${{ env.CONTAINER_PORT }}&quot;: &quot;HTTP&quot;
            }
          }
        }
        EOF

        cat &amp;gt; public-endpoint.json &amp;lt;&amp;lt; EOF
        {
          &quot;containerName&quot;: &quot;${{ env.CONTAINER_NAME }}&quot;,
          &quot;containerPort&quot;: ${{ env.CONTAINER_PORT }},
          &quot;healthCheck&quot;: {
            &quot;healthyThreshold&quot;: 2,
            &quot;unhealthyThreshold&quot;: 2,
            &quot;timeoutSeconds&quot;: 5,
            &quot;intervalSeconds&quot;: 30,
            &quot;path&quot;: &quot;/&quot;,
            &quot;successCodes&quot;: &quot;200-499&quot;
          }
        }
        EOF

    - name: Deploy to Lightsail
      run: |
        aws lightsail create-container-service-deployment \
          --region ${{ env.AWS_REGION }} \
          --service-name ${{ env.LIGHTSAIL_SERVICE_NAME }} \
          --containers file://containers.json \
          --public-endpoint file://public-endpoint.json

    - name: Get deployment status
      run: |
        aws lightsail get-container-services \
          --region ${{ env.AWS_REGION }} \
          --service-name ${{ env.LIGHTSAIL_SERVICE_NAME }}

    - name: Notify deployment completion
      run: |
        echo &quot;🚀 Staging deployment completed successfully!&quot;
        echo &quot;Site URL: https://${{ env.DOMAIN_NAME }}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;簡単に説明すると、&lt;strong&gt;imageをbuildして、pushして、登録するだけ&lt;/strong&gt;です。秘密鍵などが必要になりますので&lt;strong&gt;GitHub側に必要に応じて登録&lt;/strong&gt;しておく必要があります。&lt;/p&gt;
&lt;h3&gt;環境変数の登録例&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-06-17-49-47.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;本番環境用のワークフロー&lt;/h3&gt;
&lt;p&gt;production側もほぼ同等です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Deploy to Production

on:
  push:
    branches: [ main ]
  release:
    types: [ published ]
  workflow_dispatch:

env:
  AWS_REGION: ap-northeast-1
  LIGHTSAIL_SERVICE_NAME: mysite-production
  IMAGE_NAME: wordpress-production
  DOMAIN_NAME: example.com
  CONTAINER_NAME: wordpress
  CONTAINER_PORT: 80

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: Production

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v4
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ env.AWS_REGION }}

    - name: Install AWS CLI Lightsail plugin
      run: |
        curl &quot;https://s3.us-west-2.amazonaws.com/lightsailctl/latest/linux-amd64/lightsailctl&quot; -o &quot;lightsailctl&quot;
        sudo mv lightsailctl /usr/local/bin/lightsailctl
        sudo chmod +x /usr/local/bin/lightsailctl

    - name: Build Docker image
      run: docker build -t ${{ env.IMAGE_NAME }}:latest .

    - name: Push image to Lightsail
      id: push-image
      run: |
        IMAGE_LABEL=&quot;${{ env.LIGHTSAIL_SERVICE_NAME }}&quot;
        aws lightsail push-container-image \
          --region ${{ env.AWS_REGION }} \
          --service-name ${{ env.LIGHTSAIL_SERVICE_NAME }} \
          --label $IMAGE_LABEL \
          --image ${{ env.IMAGE_NAME }}:latest
        echo &quot;image_label=$IMAGE_LABEL&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT

    - name: Create deployment files
      run: |
        cat &amp;gt; containers.json &amp;lt;&amp;lt; EOF
        {
          &quot;${{ env.CONTAINER_NAME }}&quot;: {
            &quot;image&quot;: &quot;:${{ env.LIGHTSAIL_SERVICE_NAME }}.${{ steps.push-image.outputs.image_label }}.latest&quot;,
            &quot;environment&quot;: {
              &quot;WORDPRESS_DB_HOST&quot;: &quot;dummy&quot;,
              &quot;WORDPRESS_DB_NAME&quot;: &quot;dummy&quot;,
              &quot;WORDPRESS_DB_USER&quot;: &quot;dummy&quot;,
              &quot;WORDPRESS_CONFIG_EXTRA&quot;: &quot;define(&apos;WP_HOME&apos;, &apos;https://${{ env.DOMAIN_NAME }}&apos;); define(&apos;WP_SITEURL&apos;, &apos;https://${{ env.DOMAIN_NAME }}&apos;); define(&apos;WP_AUTO_UPDATE_CORE&apos;, false); define(&apos;WP_DEBUG_LOG&apos;, false); define(&apos;WP_DEBUG_DISPLAY&apos;, false); define(&apos;SCRIPT_DEBUG&apos;, false); define(&apos;CONCATENATE_SCRIPTS&apos;, true);&quot;,
              &quot;WORDPRESS_AUTH_KEY&quot;: &quot;${{ secrets.WORDPRESS_AUTH_KEY }}&quot;,
              &quot;WORDPRESS_SECURE_AUTH_KEY&quot;: &quot;${{ secrets.WORDPRESS_SECURE_AUTH_KEY }}&quot;,
              &quot;WORDPRESS_LOGGED_IN_KEY&quot;: &quot;${{ secrets.WORDPRESS_LOGGED_IN_KEY }}&quot;,
              &quot;WORDPRESS_NONCE_KEY&quot;: &quot;${{ secrets.WORDPRESS_NONCE_KEY }}&quot;,
              &quot;WORDPRESS_AUTH_SALT&quot;: &quot;${{ secrets.WORDPRESS_AUTH_SALT }}&quot;,
              &quot;WORDPRESS_SECURE_AUTH_SALT&quot;: &quot;${{ secrets.WORDPRESS_SECURE_AUTH_SALT }}&quot;,
              &quot;WORDPRESS_LOGGED_IN_SALT&quot;: &quot;${{ secrets.WORDPRESS_LOGGED_IN_SALT }}&quot;,
              &quot;WORDPRESS_NONCE_SALT&quot;: &quot;${{ secrets.WORDPRESS_NONCE_SALT }}&quot;
            },
            &quot;ports&quot;: {
              &quot;${{ env.CONTAINER_PORT }}&quot;: &quot;HTTP&quot;
            }
          }
        }
        EOF

        cat &amp;gt; public-endpoint.json &amp;lt;&amp;lt; EOF
        {
          &quot;containerName&quot;: &quot;${{ env.CONTAINER_NAME }}&quot;,
          &quot;containerPort&quot;: ${{ env.CONTAINER_PORT }},
          &quot;healthCheck&quot;: {
            &quot;healthyThreshold&quot;: 2,
            &quot;unhealthyThreshold&quot;: 2,
            &quot;timeoutSeconds&quot;: 5,
            &quot;intervalSeconds&quot;: 30,
            &quot;path&quot;: &quot;/&quot;,
            &quot;successCodes&quot;: &quot;200-499&quot;
          }
        }
        EOF

    - name: Deploy to Lightsail
      run: |
        aws lightsail create-container-service-deployment \
          --region ${{ env.AWS_REGION }} \
          --service-name ${{ env.LIGHTSAIL_SERVICE_NAME }} \
          --containers file://containers.json \
          --public-endpoint file://public-endpoint.json

    - name: Get deployment status
      run: |
        aws lightsail get-container-services \
          --region ${{ env.AWS_REGION }} \
          --service-name ${{ env.LIGHTSAIL_SERVICE_NAME }}

    - name: Notify deployment completion
      run: |
        echo &quot;🚀 Production deployment completed successfully!&quot;
        echo &quot;Site URL: https://${{ env.DOMAIN_NAME }}&quot;
  
  release:
    needs: deploy
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    - name: Release Drafter
      uses: release-drafter/release-drafter@v6
      with:
        publish: true
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ステージングと異なるところは、&lt;strong&gt;release-drafterを利用して本番へのデプロイのたびに自動的にリリースノートの作成と、タグを付ける&lt;/strong&gt;ようにしています。&lt;strong&gt;誰がいつどのように本番サイトを変更したかを記録&lt;/strong&gt;することが可能になります。&lt;/p&gt;
&lt;h2&gt;AWS側の設定&lt;/h2&gt;
&lt;h3&gt;前提条件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;AWSアカウントが作成済み&lt;/li&gt;
&lt;li&gt;AWS CLIがインストール済み&lt;/li&gt;
&lt;li&gt;GitHubリポジトリへのアクセス権限&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;IAMユーザーの作成&lt;/h3&gt;
&lt;p&gt;GitHub Actions用のIAMユーザーを作成します。&lt;/p&gt;
&lt;h4&gt;IAMユーザー作成&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# AWS CLIでIAMユーザーを作成
aws iam create-user --user-name github-actions-lightsail

# プログラマティックアクセス用のアクセスキーを作成
aws iam create-access-key --user-name github-actions-lightsail
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;必要な権限を付与&lt;/h4&gt;
&lt;p&gt;以下のポリシーをユーザーにアタッチします：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Action&quot;: [
                &quot;lightsail:*&quot;
            ],
            &quot;Resource&quot;: &quot;*&quot;
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ポリシーの作成とアタッチ：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ポリシーファイルを作成
cat &amp;gt; lightsail-policy.json &amp;lt;&amp;lt; EOF
{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Action&quot;: [
                &quot;lightsail:*&quot;
            ],
            &quot;Resource&quot;: &quot;*&quot;
        }
    ]
}
EOF

# ポリシーを作成
aws iam create-policy \
    --policy-name LightsailFullAccess \
    --policy-document file://lightsail-policy.json

# AWSアカウントIDを取得
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

# ユーザーにポリシーをアタッチ
aws iam attach-user-policy \
    --user-name github-actions-lightsail \
    --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/LightsailFullAccess
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Lightsail Container Service の作成&lt;/h3&gt;
&lt;h4&gt;ステージング環境の作成&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# ステージング用コンテナサービスを作成
aws lightsail create-container-service \
    --region ap-northeast-1 \
    --service-name mysite-staging \
    --power nano \
    --scale 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;本番環境の作成&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 本番用コンテナサービスを作成
aws lightsail create-container-service \
    --region ap-northeast-1 \
    --service-name mysite-production \
    --power nano \
    --scale 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;サービス状態の確認&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# サービス一覧を確認
aws lightsail get-container-services --region ap-northeast-1

# 特定のサービスの詳細を確認
aws lightsail get-container-service \
    --region ap-northeast-1 \
    --service-name mysite-staging
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;カスタムドメインの設定&lt;/h3&gt;
&lt;h4&gt;SSL証明書の作成&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# ステージング用SSL証明書
aws lightsail create-certificate \
    --region ap-northeast-1 \
    --certificate-name mysite-staging-cert \
    --domain-name staging.example.com

# 本番用SSL証明書
aws lightsail create-certificate \
    --region ap-northeast-1 \
    --certificate-name mysite-production-cert \
    --domain-name example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;ドメインの検証&lt;/h4&gt;
&lt;p&gt;証明書作成後、&lt;strong&gt;DNS検証が必要&lt;/strong&gt;です。出力されたCNAMEレコードをDNSに追加してください。&lt;/p&gt;
&lt;h4&gt;カスタムドメインの有効化&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# ステージング環境にカスタムドメインを設定
aws lightsail attach-certificate-to-distribution \
    --region ap-northeast-1 \
    --certificate-name mysite-staging-cert

# 本番環境にカスタムドメインを設定
aws lightsail attach-certificate-to-distribution \
    --region ap-northeast-1 \
    --certificate-name mysite-production-cert
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GitHub Secrets の設定&lt;/h3&gt;
&lt;p&gt;GitHubリポジトリのSettings &amp;gt; Secrets and variables &amp;gt; Actionsで以下のSecretsを設定してください：&lt;/p&gt;
&lt;h4&gt;AWS認証情報&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;: 作成したIAMユーザーのアクセスキーID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;: 作成したIAMユーザーのシークレットアクセスキー&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;WordPress認証キー&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://api.wordpress.org/secret-key/1.1/salt/&quot;&gt;generator&lt;/a&gt;などで作成したキーを設定します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;WORDPRESS_AUTH_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WORDPRESS_SECURE_AUTH_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WORDPRESS_LOGGED_IN_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WORDPRESS_NONCE_KEY&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WORDPRESS_AUTH_SALT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WORDPRESS_SECURE_AUTH_SALT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WORDPRESS_LOGGED_IN_SALT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;WORDPRESS_NONCE_SALT&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;GitHub CLIを使用したSecrets登録&lt;/h3&gt;
&lt;p&gt;GitHub CLIを使用して&lt;strong&gt;コマンドラインからSecretsを登録&lt;/strong&gt;できます：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# GitHub CLIのインストール（macOS）
brew install gh

# GitHub CLIのインストール（Ubuntu/Debian）
sudo apt install gh

# GitHubにログイン
gh auth login

# AWS認証情報を登録
gh secret set AWS_ACCESS_KEY_ID --body &quot;your-access-key-id&quot;
gh secret set AWS_SECRET_ACCESS_KEY --body &quot;your-secret-access-key&quot;

# WordPress認証キーを登録（.envファイルから）
gh secret set WORDPRESS_AUTH_KEY --body &quot;$(grep WORDPRESS_AUTH_KEY .env | cut -d&apos;=&apos; -f2 | tr -d &apos;&quot;&apos;)&quot;
gh secret set WORDPRESS_SECURE_AUTH_KEY --body &quot;$(grep WORDPRESS_SECURE_AUTH_KEY .env | cut -d&apos;=&apos; -f2 | tr -d &apos;&quot;&apos;)&quot;
gh secret set WORDPRESS_LOGGED_IN_KEY --body &quot;$(grep WORDPRESS_LOGGED_IN_KEY .env | cut -d&apos;=&apos; -f2 | tr -d &apos;&quot;&apos;)&quot;
gh secret set WORDPRESS_NONCE_KEY --body &quot;$(grep WORDPRESS_NONCE_KEY .env | cut -d&apos;=&apos; -f2 | tr -d &apos;&quot;&apos;)&quot;
gh secret set WORDPRESS_AUTH_SALT --body &quot;$(grep WORDPRESS_AUTH_SALT .env | cut -d&apos;=&apos; -f2 | tr -d &apos;&quot;&apos;)&quot;
gh secret set WORDPRESS_SECURE_AUTH_SALT --body &quot;$(grep WORDPRESS_SECURE_AUTH_SALT .env | cut -d&apos;=&apos; -f2 | tr -d &apos;&quot;&apos;)&quot;
gh secret set WORDPRESS_LOGGED_IN_SALT --body &quot;$(grep WORDPRESS_LOGGED_IN_SALT .env | cut -d&apos;=&apos; -f2 | tr -d &apos;&quot;&apos;)&quot;
gh secret set WORDPRESS_NONCE_SALT --body &quot;$(grep WORDPRESS_NONCE_SALT .env | cut -d&apos;=&apos; -f2 | tr -d &apos;&quot;&apos;)&quot;

# 登録されたSecretsの確認
gh secret list
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;DNS設定&lt;/h3&gt;
&lt;h4&gt;Route53での設定&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# ホストゾーンの作成（example.comが未作成の場合）
aws route53 create-hosted-zone \
    --name example.com \
    --caller-reference $(date +%s)

# Aレコードの作成（Lightsailのパブリックドメインを指定）
aws route53 change-resource-record-sets \
    --hosted-zone-id YOUR_HOSTED_ZONE_ID \
    --change-batch file://dns-records.json
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;外部DNSプロバイダーでの設定&lt;/h4&gt;
&lt;p&gt;Lightsailコンテナサービスのパブリックドメインを確認：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;aws lightsail get-container-service \
    --region ap-northeast-1 \
    --service-name mysite-production \
    --query &apos;containerService.url&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このURLを&lt;strong&gt;CNAMEレコードとして設定&lt;/strong&gt;してください。&lt;/p&gt;
&lt;h3&gt;既存IAMユーザーへの権限追加&lt;/h3&gt;
&lt;p&gt;既にIAMユーザーが作成済みで、Lightsailのみを追加したい場合：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat &amp;gt; lightsail-policy.json &amp;lt;&amp;lt; EOF
{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Action&quot;: [
                &quot;lightsail:*&quot;
            ],
            &quot;Resource&quot;: &quot;*&quot;
        }
    ]
}
EOF

# Lightsail権限ポリシーを作成
aws iam create-policy \
    --policy-name LightsailContainerAccess \
    --policy-document file://lightsail-policy.json

# AWSアカウントIDを取得
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この環境が構築できれば、&lt;strong&gt;数クリックでスケールアウト可能な環境&lt;/strong&gt;になります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-06-18-06-01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;運用上のアドバイス&lt;/h2&gt;
&lt;h3&gt;静的解析&lt;/h3&gt;
&lt;p&gt;PHP の syntax check や画像の圧縮、難読化を&lt;strong&gt;GitHub Actionsで行うことで面倒なことを自動化&lt;/strong&gt;できます。&lt;/p&gt;
&lt;p&gt;最適化をとことん突き詰めたい方は、WordPress のテーマファイルの中身をチェックし、JavaScript, CSS, の難読化や画像の圧縮を行えます。&lt;/p&gt;
&lt;h3&gt;Claude Codeの利用&lt;/h3&gt;
&lt;p&gt;Claude Code を利用すれば、GitHub issue で起票して、それを Claude Code で実装させ、pull request を作って、merge するといったことができます。
軽微な修正であればこれでできます。&lt;/p&gt;
&lt;p&gt;例：
&lt;img src=&quot;../../assets/uploads/2025/06/2025-06-06-18-15-24.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;日本語ファイル名はアップロードはすべきではない&lt;/h3&gt;
&lt;p&gt;macOS で Docker compose を使う場合、&lt;strong&gt;アップロードするファイル名はアルファベットにする必要&lt;/strong&gt;があります。以下の記事で指摘されている問題にあたってしまって Docker container 上からファイルを参照できなくなります。&lt;/p&gt;
&lt;p&gt;https://zenn.dev/hacobell_dev/articles/68ccc92bffd6cc&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;WordPress を&lt;strong&gt;Gitリポジトリで管理してスナップショットを保存&lt;/strong&gt;できるようにし、&lt;strong&gt;Lightsail Containerにデプロイする方法&lt;/strong&gt;を説明しました。&lt;/p&gt;
&lt;p&gt;これにより、&lt;strong&gt;複雑でスナップショット管理ができなかったWordPressの運用を容易にし、スケールアウト可能なインフラを構築&lt;/strong&gt;することが可能になりました。&lt;/p&gt;
&lt;p&gt;特に以下の点が&lt;strong&gt;めちゃくちゃ便利&lt;/strong&gt;です：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;すべてファイルで管理できるので差分が明確&lt;/li&gt;
&lt;li&gt;ロールバックが簡単&lt;/li&gt;
&lt;li&gt;セキュリティリスクの大幅削減&lt;/li&gt;
&lt;li&gt;モダンな開発フローでの運用&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;おまけ&lt;/h2&gt;
&lt;p&gt;実際にこの構成で運用してみて感じたのは、WordPress の運用がこんなに楽になるのか！　ということでした。特に複数環境での同期の煩わしさから解放されたのは大きいです。&lt;/p&gt;
&lt;p&gt;将来的に PHP の Serverless が登場した際は低コストに運用できると思います。&lt;/p&gt;
&lt;p&gt;月$7 という費用も、従来の WordPress 運用にかかる手間を考えると&lt;strong&gt;コスパ使うべきではない言葉なので修正してください&lt;/strong&gt;だと思います。ぜひ試してみてください！&lt;/p&gt;
&lt;p&gt;引き続き、WordPress 周りの気になることを調査したり、実際の運用で得た知見も記事にしていきますので、良かったら &lt;a href=&quot;https://zenn.dev/matsubokkuri&quot;&gt;Zenn&lt;/a&gt;や&lt;a href=&quot;https://twitter.com/matsubokkuri&quot;&gt;Twitter&lt;/a&gt;のフォローをお願いします！　🙌&lt;/p&gt;
</content:encoded></item><item><title>Google StitchとVercel v0の比較検証：同じプロンプトで生成結果を比べた</title><link>https://blog.teraren.com/posts/google-stitch/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-stitch/</guid><description>Google StitchとVercel v0を同じプロンプトで比較検証し、AI駆動Web開発ツールとしての実用性を評価。</description><pubDate>Tue, 27 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Google Stitch&lt;/strong&gt;は Google が提供する AI 駆動の Web アプリ開発ツール&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;v0と比較&lt;/strong&gt;して実際の出力を比較してみた&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;業務での実用性&lt;/strong&gt;について率直に評価した結果をシェア&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;結論&lt;/strong&gt;: 用途によっては v0 より優れている部分もあるが...&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;v0を普段使っている&lt;/strong&gt;フロントエンド開発者&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI開発ツール&lt;/strong&gt;の比較検討をしている方&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Stitch&lt;/strong&gt;が実際どうなのか気になっている方&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{/* ## サマリー &lt;em&gt;/}
{/&lt;/em&gt; - 発表の目的 &lt;em&gt;/}
{/&lt;/em&gt; - Google Stitchの使用感の共有 &lt;em&gt;/}
{/&lt;/em&gt; - 概要 &lt;em&gt;/}
{/&lt;/em&gt; - 同じプロンプトでGoogle Stitchとv0の出力を比較 &lt;em&gt;/}
{/&lt;/em&gt; - 出力されたコードの評価 &lt;em&gt;/}
{/&lt;/em&gt; - マインディアビジネスや業務への示唆・効果 &lt;em&gt;/}
{/&lt;/em&gt; - ケースによってはv0より使える。 &lt;em&gt;/}
{/&lt;/em&gt; - 開発者にとっては辛い。 */}&lt;/p&gt;
&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;Google は日本時間 5 月 21 日未明に開幕した年次イベント「Google I/O 2025」で、自然言語で指示を入力すると自動的に Web UI を生成するツール「&lt;a href=&quot;https://stitch.withgoogle.com/&quot;&gt;Stitch&lt;/a&gt;」の&lt;a href=&quot;https://developers.googleblog.com/en/stitch-a-new-way-to-design-uis/&quot;&gt;ベータ公開&lt;/a&gt;を発表しました。&lt;/p&gt;
&lt;p&gt;私はふだんは v0 を愛用しているので、v0 より優れているのかが気になるところです。&lt;/p&gt;
&lt;p&gt;ということで、実際に手を動かして&lt;strong&gt;両方のツールを同じタスクで比較検証&lt;/strong&gt;してみることにしました！&lt;/p&gt;
&lt;p&gt;いまなら Google Stitch は&lt;strong&gt;無料&lt;/strong&gt;なので使いまくって使用感を確かめておくのがおすすめです。&lt;/p&gt;
&lt;h2&gt;デザイン力を調査してみる&lt;/h2&gt;
&lt;h3&gt;0. はじめに&lt;/h3&gt;
&lt;p&gt;Google Stitch の設定で、Standard Mode から Experimental Mode に切り替えて使ってみます。
Standard Mode では Gemini 2.5 Flash で、Experimental Mode だと gemini 2.5 Pro になります。
普段、Gemini 2.5 Pro を使っていますが、Flash に比べると格段に優秀なので。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-05-37-45.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;また、Google Stitch の場合は Mobile/PC 向けの UI を最初に選択する必要があります。モバイル向けだと情報量が少ないので PC 向けに設定しておきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-05-45-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;1. 定性調査のインタビュー画面&lt;/h3&gt;
&lt;p&gt;プロンプトは以下です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;定性調査のためのオンラインインタビューツールのUIを作ってください。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;考える人によって機能やUIがかなり異なるので普通なら要求定義をちゃんと
していかないといけないような代物を投げつけてみます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Google Stitch&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-05-44-29.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Standard Modeでも一応試してみました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-04-40-24.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;v0&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-04-40-54.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;考察&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;圧倒的にv0が良い。機能のアイデアも広げてくれる。&lt;/p&gt;
&lt;h3&gt;2. 調査票作成画面&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;アンケート調査の調査票を作成するUIを作ってください。
最終的には調査背景、調査目的、設問作成、回収数、ターゲットなどが出力されてほしいです。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Google Stitch&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-05-53-04.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-05-53-13.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-05-53-24.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-05-53-32.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Standard Modeでもやってみましたが、人によってはこちらのほうが良いと思います。
ただのUIだけではなくてサービスレベルで考えてくれて外部設計を作ってくれています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-04-58-00.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;v0&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-04-58-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;考察&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Google StitchのStandard Modeはサービスとしての外部設計を一通り作ってくれた感じです。工程で言えば、外部設計の第1段階という感じです。
それに対してv0は出力が1画面しか出力できないのでヒアリングのフォームだけを作ってくれた感じです。&lt;/p&gt;
&lt;p&gt;これは、圧倒的にGoogle Stitchが素晴らしいです。指示したこと以上に視野を広げてくれています。逆にv0は意図をあんまり汲み取れていないです。&lt;/p&gt;
&lt;h3&gt;3. 個人開発サービスの改善&lt;/h3&gt;
&lt;p&gt;プロンプト&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;以下のようなトライアスロンのリザルトを分析するサービスを提供しています。
もっと良いUIを作ってください。
https://ai-triathlon-result.teraren.com/archive/2025/tateyama_duathlon/athletes/athlete-459
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Google Stitch&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-06-30-31.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-06-30-47.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;v0&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-05-12-44.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;考察&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;どちらもありではあるが、オリジナルのUIからかなり情報が削られてしまっている。&lt;/p&gt;
&lt;h3&gt;4. Eコマースサイトのランディングページ&lt;/h3&gt;
&lt;p&gt;プロンプト&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;モダンなEコマースサイトのランディングページを作成してください。
- ヒーローセクション
- 商品一覧
- 特徴紹介
- お客様の声
- フッター
レスポンシブ対応で、アニメーションも含めてください。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Google Stitch&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-06-05-28.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-06-05-40.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-06-05-52.png&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-06-06-03.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;v0&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-05-21-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Google StitchはLPだけじゃなくて、他のページやコンポーネントも生成してきた。&lt;/p&gt;
&lt;h2&gt;コーディング力を調査してみる&lt;/h2&gt;
&lt;p&gt;このUIのコードを見てみる。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-06-05-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;HTML/CSS出力&lt;/h3&gt;
&lt;p&gt;以下のようなコードが出力される。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;クリックしてコードを表示:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;
&amp;lt;meta charset=&quot;utf-8&quot;/&amp;gt;
&amp;lt;link crossorigin=&quot;&quot; href=&quot;https://fonts.gstatic.com/&quot; rel=&quot;preconnect&quot;/&amp;gt;
&amp;lt;link as=&quot;style&quot; href=&quot;https://fonts.googleapis.com/css2?display=swap&amp;amp;amp;family=Noto+Sans%3Awght%40400%3B500%3B700%3B900&amp;amp;amp;family=Plus+Jakarta+Sans%3Awght%40400%3B500%3B700%3B800&quot; onload=&quot;this.rel=&apos;stylesheet&apos;&quot; rel=&quot;stylesheet&quot;/&amp;gt;
&amp;lt;link href=&quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200&quot; rel=&quot;stylesheet&quot;/&amp;gt;
&amp;lt;title&amp;gt;Stitch Design&amp;lt;/title&amp;gt;
&amp;lt;link href=&quot;data:image/x-icon;base64,&quot; rel=&quot;icon&quot; type=&quot;image/x-icon&quot;/&amp;gt;
&amp;lt;script src=&quot;https://cdn.tailwindcss.com?plugins=forms,container-queries&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;style type=&quot;text/tailwindcss&quot;&amp;gt;
  @layer base {
    :root {
    --primary-color: #0c77f2;
    --secondary-color: #e7edf4;
    --text-primary: #0d141c;
    --text-secondary: #49709c;
    --background-color: #f8fafc;}
    body {
    font-family: &quot;Plus Jakarta Sans&quot;, &quot;Noto Sans&quot;, sans-serif;
    color: var(--text-primary);
    }
    .icon-btn {
    @apply flex items-center justify-center size-10 rounded-lg bg-transparent text-slate-700 hover:bg-slate-200 transition-colors;
    }
  }
  .material-symbols-outlined {
    font-variation-settings:
    &apos;FILL&apos; 0,
    &apos;wght&apos; 400,
    &apos;GRAD&apos; 0,
    &apos;opsz&apos; 24
  }
  &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body class=&quot;bg-background-color&quot;&amp;gt;
&amp;lt;div class=&quot;relative flex size-full min-h-screen flex-col group/design-root overflow-x-hidden&quot;&amp;gt;
&amp;lt;div class=&quot;layout-container flex h-full grow flex-col&quot;&amp;gt;
&amp;lt;header class=&quot;flex items-center justify-between whitespace-nowrap border-b border-solid border-slate-200 px-6 sm:px-10 py-4 bg-white shadow-sm&quot;&amp;gt;
&amp;lt;div class=&quot;flex items-center gap-6 lg:gap-10&quot;&amp;gt;
&amp;lt;div class=&quot;flex items-center gap-3 text-primary-color&quot;&amp;gt;
&amp;lt;div class=&quot;size-6 text-primary-color&quot;&amp;gt;
&amp;lt;svg fill=&quot;none&quot; viewBox=&quot;0 0 48 48&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&amp;gt;
&amp;lt;path clip-rule=&quot;evenodd&quot; d=&quot;M24 4H6V17.3333V30.6667H24V44H42V30.6667V17.3333H24V4Z&quot; fill=&quot;currentColor&quot; fill-rule=&quot;evenodd&quot;&amp;gt;&amp;lt;/path&amp;gt;
&amp;lt;/svg&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;h2 class=&quot;text-xl font-bold tracking-tighter&quot;&amp;gt;FashionForward&amp;lt;/h2&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;nav class=&quot;hidden md:flex items-center gap-6 lg:gap-8&quot;&amp;gt;
&amp;lt;a class=&quot;text-slate-700 hover:text-primary-color text-sm font-medium transition-colors&quot; href=&quot;#&quot;&amp;gt;New Arrivals&amp;lt;/a&amp;gt;
&amp;lt;a class=&quot;text-slate-700 hover:text-primary-color text-sm font-medium transition-colors&quot; href=&quot;#&quot;&amp;gt;Men&amp;lt;/a&amp;gt;
&amp;lt;a class=&quot;text-slate-700 hover:text-primary-color text-sm font-medium transition-colors&quot; href=&quot;#&quot;&amp;gt;Women&amp;lt;/a&amp;gt;
&amp;lt;a class=&quot;text-slate-700 hover:text-primary-color text-sm font-medium transition-colors&quot; href=&quot;#&quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;
&amp;lt;a class=&quot;text-slate-700 hover:text-primary-color text-sm font-medium transition-colors&quot; href=&quot;#&quot;&amp;gt;Sale&amp;lt;/a&amp;gt;
&amp;lt;/nav&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;flex items-center gap-3 sm:gap-4&quot;&amp;gt;
&amp;lt;label class=&quot;relative flex-col min-w-32 !h-10 max-w-sm hidden sm:flex&quot;&amp;gt;
&amp;lt;div class=&quot;flex w-full flex-1 items-stretch rounded-lg h-full bg-slate-100&quot;&amp;gt;
&amp;lt;div class=&quot;text-slate-500 flex items-center justify-center pl-3&quot;&amp;gt;
&amp;lt;span class=&quot;material-symbols-outlined text-xl&quot;&amp;gt;search&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;input class=&quot;form-input flex w-full min-w-0 flex-1 resize-none overflow-hidden rounded-lg text-slate-700 focus:outline-0 focus:ring-2 focus:ring-primary-color/50 border-none bg-transparent h-full placeholder:text-slate-500 px-3 text-sm font-normal&quot; placeholder=&quot;Search products...&quot; value=&quot;&quot;/&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/label&amp;gt;
&amp;lt;div class=&quot;flex gap-1&quot;&amp;gt;
&amp;lt;button aria-label=&quot;Search Mobile&quot; class=&quot;icon-btn&quot; title=&quot;Search&quot;&amp;gt;
&amp;lt;span class=&quot;material-symbols-outlined sm:hidden&quot;&amp;gt;search&amp;lt;/span&amp;gt;
&amp;lt;/button&amp;gt;
&amp;lt;button aria-label=&quot;Wishlist&quot; class=&quot;icon-btn&quot; title=&quot;Wishlist&quot;&amp;gt;
&amp;lt;span class=&quot;material-symbols-outlined&quot;&amp;gt;favorite_border&amp;lt;/span&amp;gt;
&amp;lt;/button&amp;gt;
&amp;lt;button aria-label=&quot;Shopping Cart&quot; class=&quot;icon-btn&quot; title=&quot;Shopping Cart&quot;&amp;gt;
&amp;lt;span class=&quot;material-symbols-outlined&quot;&amp;gt;shopping_bag&amp;lt;/span&amp;gt;
&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;button class=&quot;ml-2&quot;&amp;gt;
&amp;lt;div class=&quot;bg-center bg-no-repeat aspect-square bg-cover rounded-full size-10 border-2 border-slate-200 hover:border-primary-color transition-colors&quot; style=&apos;background-image: url(&quot;https://lh3.googleusercontent.com/aida-public/AB6AXuARxqvbE3wZ7BIaNHTKx_ii3Y9WspWUS_9jGx99gtJp1W2z1Nfttx0F4Vm3--hQ3gsveZm2P7b71eW8CcE0FXQN9V3PL-02mUhbLpVWa39txa09v4ShBij9lSQwINXrq4DsEm-iMUmPjeKbJmbgCDF8pqy_RVTbmTpbxKZCQmTJZS99G4HgD84ngE0POGB6KaghByFat6svmGJ-NtoO_JpTH_pcuVydr24nv26fdiRHs90ywd0tExZ2g5UvPhSWWjdL_xAGTuvcvS4&quot;);&apos;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/header&amp;gt;
&amp;lt;main class=&quot;flex flex-1 justify-center items-center px-4 sm:px-6 lg:px-8 py-10 sm:py-16&quot;&amp;gt;
&amp;lt;div class=&quot;w-full max-w-6xl&quot;&amp;gt;
&amp;lt;div class=&quot;@container&quot;&amp;gt;
&amp;lt;div class=&quot;relative overflow-hidden rounded-xl shadow-2xl&quot;&amp;gt;
&amp;lt;div class=&quot;absolute inset-0 bg-cover bg-center bg-no-repeat&quot; style=&apos;background-image: url(&quot;https://lh3.googleusercontent.com/aida-public/AB6AXuC_tkVGaCvcqLyJ3y2pXrW3CWvUZwaElnVoR1hZjy5cB8DH3vGd4fHeGByomZUXIj5KKwQI6wYZtpoulARXzVXPGymX5wGUf-MKxD7VxTg7sbhg6QXDjr4RehcAXr8J8HiknnBARLA-TJLS2ZZ1jsKm7lhPjf0e7SMb5P2bGmMxwYLAAR_528_a7ytnJGEFOM-1Xqq8msmo-9R8I6EgotmaDAfEMOZVjFusFW8U3mcnapudWqO8sqsGKb8qTRTeIeRSqWhvlm_plBs&quot;);&apos;&amp;gt;
&amp;lt;div class=&quot;absolute inset-0 bg-gradient-to-t from-black/70 via-black/40 to-black/10&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class=&quot;relative flex min-h-[500px] sm:min-h-[600px] flex-col gap-6 items-center justify-center text-center p-6 sm:p-12 @[640px]:items-start @[640px]:text-left @[640px]:w-3/5 @[1024px]:w-1/2&quot;&amp;gt;
&amp;lt;div class=&quot;flex flex-col gap-4&quot;&amp;gt;
&amp;lt;h1 class=&quot;text-white text-4xl sm:text-5xl lg:text-6xl font-extrabold leading-tight tracking-tight&quot;&amp;gt;
          Step into Style
          &amp;lt;/h1&amp;gt;
&amp;lt;p class=&quot;text-slate-200 text-base sm:text-lg lg:text-xl font-normal leading-relaxed max-w-md @[640px]:max-w-none&quot;&amp;gt;
          Discover the latest trends and timeless classics in our curated collection. Elevate your wardrobe with pieces that speak to your unique style.
          &amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;a class=&quot;flex min-w-[120px] max-w-[280px] cursor-pointer items-center justify-center overflow-hidden rounded-lg h-12 px-6 sm:h-14 sm:px-8 bg-primary-color text-white text-base sm:text-lg font-bold leading-normal tracking-wide shadow-md hover:bg-blue-600 transition-all duration-300 ease-in-out transform hover:scale-105 focus:outline-none focus:ring-4 focus:ring-primary-color/50&quot; href=&quot;#&quot;&amp;gt;
&amp;lt;span class=&quot;truncate&quot;&amp;gt;Shop Now&amp;lt;/span&amp;gt;
&amp;lt;span class=&quot;material-symbols-outlined ml-2&quot;&amp;gt;arrow_forward&amp;lt;/span&amp;gt;
&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/main&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;実際に開発に使うために React に変換して使ってみます。
Visual Studio Code + Cline が適していると思うので HTML/CSS のコードを React にしてもらいつつ、リポジトリの初期設定をしてもらうようにプロンプトで指示しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-06-09-39.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;時間は 5 分ぐらいかかり、$0.4443 かかりました。&lt;/p&gt;
&lt;p&gt;コンポーネントを良い感じに分割して作ってくれました。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-11-17-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;動きました。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-11-17-41.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Figmaに出力してコードを生成&lt;/h3&gt;
&lt;p&gt;Google Stitch から Figma に出力できます。Figma からコードを生成できるので試してみたいと思います。
(現時点で、Google Chrome を使わないとできないです。Brave の最新では対応していませんでした。)&lt;/p&gt;
&lt;p&gt;Figma にコピーすると以下のような感じでコンポーネントが作られています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-12-42-06.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.figma.com/community/plugin/851183094275736358/figma-to-html&quot;&gt;Figma to HTML&lt;/a&gt;プラグインを使ってReactのコードを出力してみます。&lt;/p&gt;
&lt;p&gt;しかしながら、以下のダイアログが出たので Convert ボタンを押してもファイルがダウンロードされませんでした。
ブラウザの Developer Tool を見るとエラーが起きてました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-12-52-43.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Figma to HTML の最終更新日が 2 年以上前であり、プラグインのコメント欄にも「使えない！」というコメントの嵐なのでなので現在は使えないようです。&lt;/p&gt;
&lt;p&gt;課金して Locofy を使うなどしか無さそうです。Figma からソースコードへの変換は厳しそうです。&lt;/p&gt;
&lt;p&gt;もし Figma 経由で HTML コードを生成できるならばサービスの外部設計時に、以下のワークフローでも使えそうだなと思いましたが現状は無理そうです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google Stitch を何回も実行&lt;/li&gt;
&lt;li&gt;=&amp;gt; Figma に蓄積。&lt;/li&gt;
&lt;li&gt;=&amp;gt; コンポーネントなどを整理。&lt;/li&gt;
&lt;li&gt;=&amp;gt; Figma to HTML で React のコードを一気に生成。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;評価&lt;/h2&gt;
&lt;h3&gt;v0との機能比較&lt;/h3&gt;
&lt;p&gt;実際に使ってみて感じた両ツールの比較を表にまとめてみました：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;Google Stitch&lt;/th&gt;
&lt;th&gt;v0&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ベースフレームワーク&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HTML/CSS&lt;/td&gt;
&lt;td&gt;React/Next.js&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;デザインクオリティ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;シンプル・実用的&lt;/td&gt;
&lt;td&gt;モダン・洗練&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;料金&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;無料（制限あり）&lt;/td&gt;
&lt;td&gt;有料プラン推奨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;マルチモーダル&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Standard 非対応/Experimental対応&lt;/td&gt;
&lt;td&gt;対応&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;エコシステム&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Figma&lt;/td&gt;
&lt;td&gt;Vercel/GitHub&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;比較結果&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;Google Stitch&lt;/th&gt;
&lt;th&gt;v0&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;サービス全体設計&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;★★★★&lt;/td&gt;
&lt;td&gt;★★&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;デザイン品質&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;★★&lt;/td&gt;
&lt;td&gt;★★★★★&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;コード品質&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;★&lt;/td&gt;
&lt;td&gt;★★★★&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;実装速度&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;★★★&lt;/td&gt;
&lt;td&gt;★★★&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;カスタマイズ性&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;★&lt;/td&gt;
&lt;td&gt;★★★★★&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用感
&lt;ul&gt;
&lt;li&gt;Google Stitch
&lt;ul&gt;
&lt;li&gt;外部設計。UI デザインを作るというイメージ。ページのフローも生成してくれる。全体の外部設計。&lt;/li&gt;
&lt;li&gt;より抽象的な指示で全体最適ができそう。&lt;/li&gt;
&lt;li&gt;初回プロンプトを入力した後に絶対に確認が入ってから実行される。必ず Plan して Act する流れ。&lt;/li&gt;
&lt;li&gt;最大 6 画面の生成。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;v0
&lt;ul&gt;
&lt;li&gt;ページを作る感じ。React のコードがアウトプット出でてくる。&lt;/li&gt;
&lt;li&gt;ミクロな感じ。SPA に良い。&lt;/li&gt;
&lt;li&gt;作った UI がすぐに Deploy できるのでデモできちゃう。フロントエンドはほとんどこれで完成させられる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;現時点でのポジショニングはこんな感じになると思います。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-28-06-38-02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;実際に両方のツールを使ってみた結果、&lt;strong&gt;どちらも素晴らしいツール&lt;/strong&gt;だということがわかりました！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Google Stitch&lt;/strong&gt;は、特に&lt;strong&gt;プロトタイプ作成や小規模プロジェクト&lt;/strong&gt;では有効だと感じました。
一方で、&lt;strong&gt;v0&lt;/strong&gt;は&lt;strong&gt;デザイン品質と開発体験&lt;/strong&gt;において一歩リードしており、エンジニア向けという感じがしました。&lt;/p&gt;
&lt;p&gt;また、vercel には様々な SDK が提供されているので v0 で作ったフロントエンドに対して簡単にバックエンドを統合できる状態になっているという利点は大きいです。Google の既存アセットである Google Cloud を使って同じようなことをしてきたらとても強力かと思いますがそこを攻めてくるかどうかはわかりません。例えば Stitch で UI を作って、クリック 1 発で Cloud Run にデプロイといったこと。&lt;/p&gt;
&lt;p&gt;個人的には、&lt;strong&gt;用途に応じて使い分ける&lt;/strong&gt;のがベストだと考えています：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;アイデア検証段階、サービス設計段階&lt;/strong&gt;: Google Stitch&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本格開発段階&lt;/strong&gt;: v0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;みなさんも実際に両方試してみて、&lt;strong&gt;自分のプロジェクトに最適なツール&lt;/strong&gt;を見つけてみてくださいね！&lt;/p&gt;
</content:encoded></item><item><title>日本郵便のデジタルアドレス：7桁コードで届く仕組みの可能性と限界</title><link>https://blog.teraren.com/posts/digital-address/</link><guid isPermaLink="true">https://blog.teraren.com/posts/digital-address/</guid><description>最近、住所もデジタル化の波が来てるんですね！　日本郵便が提供する「デジタルアドレス」って聞いたことありますか？**物理的な住所に代わる新しい識別子**として注目されているんです。</description><pubDate>Mon, 26 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;デジタルアドレス&lt;/strong&gt;は日本郵便が提供する 7 桁のランダムな英数字で住所にマッピングする仕組み&lt;/li&gt;
&lt;li&gt;個人・法人利用ではデジタルアドレスと住所保持した場合、どちらが本当の住所なのかを明確にして保管する必要がある。&lt;/li&gt;
&lt;li&gt;API 利用は簡単だが、普及には多くのセキュリティの課題やユースケース上の問題があるので広く取り入れられることは難しそう。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;デジタルアドレスって何？　と思っている方&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日本郵便のAPI&lt;/strong&gt;を使ってみたい開発者の方&lt;/li&gt;
&lt;li&gt;住所管理の新しい仕組みに興味がある方&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;最近、住所もデジタル化の波が来てるんですね！　日本郵便が提供する「デジタルアドレス」って聞いたことありますか？&lt;strong&gt;物理的な住所に代わる新しい識別子&lt;/strong&gt;として注目されているんです。&lt;/p&gt;
&lt;p&gt;この記事では、日本郵便が提供する「郵便番号・デジタルアドレス for Biz API」を実際に触ってみて、デジタルアドレスの概要、API の使い方、そして&lt;strong&gt;正直なところの利便性と課題&lt;/strong&gt;について、私なりにまとめてみました！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-26-11-48-09.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;1. デジタルアドレスって何？&lt;/h2&gt;
&lt;p&gt;デジタルアドレスとは一体何でしょうか？　めちゃくちゃシンプルに言うと、&lt;strong&gt;ゆうID利用者が登録した住所を置き換えた、ランダムな英数字7桁の文字列&lt;/strong&gt;なんです！　例えば &lt;code&gt;A7E2FK2&lt;/code&gt; みたいな感じですね。&lt;/p&gt;
&lt;p&gt;これって、既存の住所システムと比較すると、大口事業所個別番号の空間を拡張したものとして理解するのが良さそうです。つまり、今まであった仕組みをベースに、もっと多くの住所に対応できるように名前空間を広げたって感じですね。&lt;/p&gt;
&lt;p&gt;7 桁の英数字ということは、 &lt;strong&gt;アドレス空間は2^35（約340億通り）&lt;/strong&gt; もあるので、十分すぎるほどの容量があります！　分かりづらい文字（0 と O など）は除外されている可能性もありますが、それでも相当な数のアドレスを生成できそうです。&lt;/p&gt;
&lt;h3&gt;デジタルアドレスの特徴&lt;/h3&gt;
&lt;p&gt;デジタルアドレスには、以下の特徴があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;個人・法人がデジタルアドレスの発行が可能&lt;/strong&gt;：住所からデジタルアドレスの作成ができます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;正引きが可能&lt;/strong&gt;：デジタルアドレスから住所の取得ができます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API経由でアクセス可能&lt;/strong&gt;：API 登録すればデジタルアドレスから住所を取得できます&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ユーザーが管理可能&lt;/strong&gt;：デジタルアドレスの関連付けを作成したユーザーが、削除や変更をできます&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;匿名性の解決はしていない&lt;/strong&gt;：デジタルアドレスから住所を簡単に求められるので、フリマなどで広まりつつある匿名配送のユースケースには使えません。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ただし、この「API 経由で住所検索が可能」という特性は、後で説明する運用管理とセキュリティや使い勝手が悪くなる理由になり、&lt;strong&gt;重要なポイント&lt;/strong&gt;になってきます。&lt;/p&gt;
&lt;h2&gt;2. APIを使ってみよう！&lt;/h2&gt;
&lt;p&gt;デジタルアドレスの情報は、「&lt;a href=&quot;https://guide-biz.da.pf.japanpost.jp/api/&quot;&gt;郵便番号・デジタルアドレス for Biz API&lt;/a&gt;」を通じて取得できます。このAPIは、デジタルアドレスの名前解決だけではなくて7桁の郵便番号の解決もしてくれるのでめちゃくちゃ便利です！
なぜなら、&lt;strong&gt;郵便番号から住所を補完する際は、このAPIを使っておけば郵便番号からの住所の補完だけでなく、デジタルアドレスからの住所の補完が行えます！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;提供される機能には、トークン発行や、デジタルアドレス、郵便番号、事業所個別郵便番号の検索などがあります。API の仕様は OpenAPI Specification で書かれているので開発者にとっては馴染みやすいと思います。&lt;/p&gt;
&lt;h3&gt;API利用開始までのステップ&lt;/h3&gt;
&lt;p&gt;API を使い始めるまでの手順はけっこうシンプルです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ゆうIDで認証&lt;/strong&gt;：まず有効なゆう ID が必要です&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;利用者登録&lt;/strong&gt;：ゆう ID の会員登録後、本サイト上でゆう ID で認証し、利用者登録をします&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API認証キーの発行&lt;/strong&gt;：利用者登録が完了し、本サービスの利用が承認されると、ダッシュボードから API 認証キー（クライアント ID、シークレットキー）を発行できます&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;API 認証キーは、ダッシュボードでサクッと発行・再発行できます。このキーをリクエストに含めることで、サービスを利用できるようになります！&lt;/p&gt;
&lt;h3&gt;提供される主なAPI&lt;/h3&gt;
&lt;p&gt;「郵便番号・デジタルアドレス for Biz API」で提供される主な API は以下の通りです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;searchcode API&lt;/strong&gt;: 郵便番号、事業所個別郵便番号、デジタルアドレスからの共通検索を行うエンドポイントです。いずれかのコードを指定して検索すると、住所情報が返されます。テスト用 API では、テスト用のデジタルアドレス 3 種と東京都千代田区の郵便番号、事業所個別郵便番号の検索が可能です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;addresszip API&lt;/strong&gt;: 住所の一部を用いて郵便番号や住所情報を検索する API です。テスト用 API では東京都千代田区に対してのみ検索が可能です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;token API&lt;/strong&gt;: API 利用に必要なトークン（JWT 形式）を取得する API です。OAuth2.0 の client_credentials に基づいており、クライアント ID とシークレットキーを指定してリクエストします。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;API 利用においては、利用範囲・仕様、アクセス回数、アクセス時間、情報更新頻度、送信データ容量などに制約が設けられる場合があります。ダッシュボードに掲載される最新の利用ガイドを参照することが推奨されています。&lt;/p&gt;
&lt;h3&gt;APIの仕様に関する注意点&lt;/h3&gt;
&lt;p&gt;実際に API を使ってみて気づいた点がいくつかあります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;送信元IPアドレスの登録&lt;/strong&gt;: API 利用時に送信元 IP アドレスの入力が必須になっていますが、実際にはその IP アドレス以外からでもアクセス可能でした。システム上での制約は特にないようです&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IPv4のみ対応&lt;/strong&gt;: 送信元 IP アドレスは IPv4 のみ指定可能で、ネットワークアドレスの指定や IPv6 には対応していません&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;x-forwarded-forヘッダー&lt;/strong&gt;: API ドキュメントでは必須とされていますが、実際には指定しなくても正常にレスポンスが返ってきます&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本番APIのホスト名&lt;/strong&gt;: この記事ではテスト用 API（&lt;code&gt;stub-qz73x.da.pf.japanpost.jp&lt;/code&gt;）を使用していますが、本番環境の API ホスト名は OpenAPI の仕様書に記載されています。(エンドポイント URL を展開すると見られる)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの点は、実際の運用時に知っておくと便利だと思います！&lt;/p&gt;
&lt;h3&gt;API呼び出し例とレスポンス&lt;/h3&gt;
&lt;p&gt;API を利用する際には、まず token API でトークンを取得し、そのトークンを Authorization ヘッダーに含めて他の API を呼び出します。&lt;/p&gt;
&lt;h4&gt;API利用トークン取得例&lt;/h4&gt;
&lt;p&gt;テスト用 API 認証情報として提供されているクライアント ID &lt;code&gt;Biz_DaPfJapanpost_MockAPI_j3QKS&lt;/code&gt; とシークレットキー &lt;code&gt;uXuN0ejHG7nAn89Afxxxxx&lt;/code&gt; を使用してトークンを取得する cURL コマンドの例です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -X POST &quot;https://stub-qz73x.da.pf.japanpost.jp/api/v1/j/token&quot; \
-H &quot;Content-Type: application/json&quot; \
-H &quot;x-forwarded-for: 192.0.2.0&quot; \ # 送信元IPアドレスは必須
-d &apos;{
  &quot;grant_type&quot;: &quot;client_credentials&quot;,
  &quot;client_id&quot;: &quot;Biz_DaPfJapanpost_MockAPI_xxxxx&quot;, # テスト用クライアントID
  &quot;secret_key&quot;: &quot;uXuN0ejHG7nAn89Afxxxxx&quot; # テスト用シークレットキー
}&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;成功すると、JWT形式のアクセストークンを含むレスポンスが返されます。このトークンを &lt;code&gt;Bearer&lt;/code&gt; スキームで使用します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;scope&quot;: &quot;J1&quot;,
  &quot;token_type&quot;: &quot;Bearer&quot;,
  &quot;expires_in&quot;: 123456,
  &quot;token&quot;: &quot;{アクセストークン}&quot; # ここに実際のトークンが入る
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;searchcode APIでの検索例&lt;/h4&gt;
&lt;p&gt;取得したトークンを使用してsearchcode APIを呼び出します。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;デジタルアドレスにハイフンが含まれている場合（誤った形式）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;テスト用デジタルアドレス &lt;code&gt;A7E-2FK2&lt;/code&gt; をハイフン付きで検索した場合の例です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -X GET &quot;https://stub-qz73x.da.pf.japanpost.jp/api/v1/searchcode/A7E-2FK2&quot; \
-H &quot;Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...&quot; # 取得したトークンを指定
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この場合、エラーが返されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{&quot;request_id&quot;:&quot;e6219453-ce21-45df-8369-8c9bf5411111&quot;,&quot;error_code&quot;:&quot;400-1029-0002&quot;,&quot;message&quot;:&quot;デジアドの形式が正しくありません&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;メッセージは「デジアドの形式が正しくありません」となっており、ハイフンは不要であることがわかります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;デジタルアドレスにハイフンがない場合（正しい形式）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;テスト用デジタルアドレス &lt;code&gt;A7E2FK2&lt;/code&gt; をハイフンなしで検索した場合の例です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -X GET &quot;https://stub-qz73x.da.pf.japanpost.jp/api/v1/searchcode/A7E2FK2&quot; \
-H &quot;Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...&quot; # 取得したトークンを指定
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;成功すると、紐づく住所情報を含むレスポンスが返されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;page&quot;: 1,
  &quot;limit&quot;: 1000,
  &quot;count&quot;: 1,
  &quot;searchtype&quot;: &quot;dgacode&quot;,
  &quot;addresses&quot;: [
    {
      &quot;dgacode&quot;: &quot;A7E2FK2&quot;,
      &quot;zip_code&quot;: &quot;100-0005&quot;,
      &quot;pref_code&quot;: &quot;13&quot;,
      &quot;pref_name&quot;: &quot;東京都&quot;,
      &quot;pref_kana&quot;: null,
      &quot;pref_roma&quot;: null,
      &quot;city_code&quot;: &quot;13101&quot;,
      &quot;city_name&quot;: &quot;千代田区&quot;,
      &quot;city_kana&quot;: null,
      &quot;city_roma&quot;: null,
      &quot;town_name&quot;: &quot;丸の内&quot;,
      &quot;town_kana&quot;: null,
      &quot;town_roma&quot;: null,
      &quot;biz_name&quot;: null,
      &quot;biz_kana&quot;: null,
      &quot;biz_roma&quot;: null,
      &quot;block_name&quot;: &quot;２丁目７−２&quot;,
      &quot;other_name&quot;: &quot;部屋番号：サンプル１&quot;,
      &quot;address&quot;: &quot;東京都千代田区丸の内２丁目７−２部屋番号：サンプル１&quot;,
      &quot;longitude&quot;: null,
      &quot;latitude&quot;: null
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このレスポンスから、テスト用デジタルアドレス &lt;code&gt;A7E2FK2&lt;/code&gt; は、東京都千代田区丸の内２丁目７−２部屋番号：サンプル１に紐づいていることがわかります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;該当するデジタルアドレスが存在しない場合&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;存在しないデジタルアドレスで検索した場合の例です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -X GET &quot;https://stub-qz73x.da.pf.japanpost.jp/api/v1/searchcode/XXXXXXX&quot; \
-H &quot;Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...&quot; # 取得したトークンを指定
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この場合、404 Not Foundエラーが返されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{&quot;request_id&quot;:&quot;105f833a-4982-47b9-9f61-a564dcf5d846&quot;,&quot;error_code&quot;:&quot;404-1029-0001&quot;,&quot;message&quot;:&quot;該当するデジアドがありませんでした&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;メッセージは「該当するデジアドがありませんでした」となっています。&lt;/p&gt;
&lt;h4&gt;addresszip APIでの検索例&lt;/h4&gt;
&lt;p&gt;addresszip APIはPOSTメソッドでリクエストボディに検索条件を指定します。テスト用APIでは東京都千代田区に対してのみ検索可能です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -X POST &quot;https://stub-qz73x.da.pf.japanpost.jp/api/v1/addresszip&quot; \
-H &quot;Content-Type: application/json&quot; \
-H &quot;Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...&quot; \ # 取得したトークンを指定
-d &apos;{
  &quot;pref_code&quot;: &quot;13&quot;, # 都道府県コードを指定
  &quot;city_code&quot;: &quot;13101&quot;, # 市区町村コードを指定
  &quot;page&quot;: 1,
  &quot;limit&quot;: 1000 # 取得最大レコード数。デフォルト1000
}&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;成功すると、指定した条件にマッチする住所情報や郵便番号を含むレスポンスが返されます。レスポンスにはマッチングレベルも含まれます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;addresses&quot;: [
    ... # 該当する住所情報がリストで含まれる
  ],
  &quot;level&quot;: 2, # マッチングレベル
  &quot;limit&quot;: 1000,
  &quot;count&quot;: 1,
  &quot;page&quot;: 1
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この例では、都道府県コードと市区町村コードで検索しているため、マッチングレベルは 2（市区町村レベルで一致）となることが想定されます。&lt;/p&gt;
&lt;h2&gt;3. 正直なところ、どうなの？（考察）&lt;/h2&gt;
&lt;p&gt;デジタルアドレスって&lt;strong&gt;物理的な住所の代替&lt;/strong&gt;として期待されてるんですが、実際に調べてみると&lt;strong&gt;利便性と課題の両面&lt;/strong&gt;が見えてきました。&lt;/p&gt;
&lt;h3&gt;セキュリティ面での気になるポイント&lt;/h3&gt;
&lt;p&gt;一番気になったのは、&lt;strong&gt;匿名性の課題&lt;/strong&gt;ですね。デジタルアドレスと住所の紐づけ自体は公開されていませんが、&lt;strong&gt;API登録すれば誰でもデジタルアドレスから住所を検索できる&lt;/strong&gt;んです。&lt;/p&gt;
&lt;p&gt;つまり、&lt;strong&gt;第三者に匿名性を確保したいからデジタルアドレスを教えても、実際には住所を教えたのと同じ&lt;/strong&gt;ことになってしまいます。&lt;/p&gt;
&lt;p&gt;また、デジタルアドレスがランダムな文字列とはいえ、&lt;strong&gt;総当たり攻撃（ブルートフォースアタック）に対して脆弱&lt;/strong&gt;という問題もあります。総当たり攻撃への対策については、現在のところ&lt;strong&gt;APIの利用規約でNGとしている程度&lt;/strong&gt;で、技術的な対策がどの程度講じられているかは、私が調べた範囲では読み取れませんでした。&lt;/p&gt;
&lt;p&gt;利用規約では、&lt;strong&gt;API認証キーは自己の費用と責任において厳重に管理する必要がある&lt;/strong&gt;と明記されており、管理不備や不正使用による損害はユーザーが一切の責任を負うとしています。また、API で取得した情報は、&lt;strong&gt;デジタルアドレスを作成したユーザーの同意なしに外部へ公開してはならない&lt;/strong&gt;という重要な注意点もあります。&lt;/p&gt;
&lt;h3&gt;実際のユースケースってどうなの？&lt;/h3&gt;
&lt;p&gt;個人レベルでは EC サイトで買い物する際に&lt;strong&gt;住所補完に使える可能性&lt;/strong&gt;がありますね。例えば、Web サイトの入力フォームでデジタルアドレスを入力すると、&lt;strong&gt;パパっと住所が入力される&lt;/strong&gt;ような機能です。&lt;/p&gt;
&lt;p&gt;でも、これが普及するためには、&lt;strong&gt;どれくらいのサイトが対応してくれるか&lt;/strong&gt;、そして&lt;strong&gt;ブラウザ自体がデジタルアドレスの補完に対応するか&lt;/strong&gt;が疑問なんですよね。もし単なる住所補完のユースケースだけであれば、&lt;strong&gt;ブラウザの機能である程度は要求を満たせてしまう&lt;/strong&gt;かもしれません。&lt;/p&gt;
&lt;p&gt;法人（企業）がデジタルアドレスを利用する場合、&lt;strong&gt;物理住所とデジタルアドレスの両方を管理する必要が生じて、めちゃくちゃ大変になる可能性&lt;/strong&gt;があります。&lt;/p&gt;
&lt;p&gt;また、デジタルアドレスは&lt;strong&gt;作成したユーザーが削除や変更をできる&lt;/strong&gt;ので、もしデジタルアドレスだけを ID として持っていると、&lt;strong&gt;ユーザーがデジタルアドレスを削除した場合に困る&lt;/strong&gt;ことになります。そのため、住所の ID としてデジタルアドレスのみを使用するのは難しそうです。&lt;/p&gt;
&lt;p&gt;これらの点から、&lt;strong&gt;正直なところ、デジタルアドレスを普及させることによるメリットがあまり多くない&lt;/strong&gt;と感じる人もいるかもしれません。一方で、法人のユースケースにおいては、正引き機能があることは&lt;strong&gt;なかなか良い点&lt;/strong&gt;だと思います！&lt;/p&gt;
&lt;h3&gt;利用規約から見る重要な注意点&lt;/h3&gt;
&lt;p&gt;「郵便番号・デジタルアドレス for Biz 利用規約」には、API 利用者（ユーザー）が遵守すべき重要な事項が多数記載されています。特に注意すべき点をいくつか挙げます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;エンドユーザーから取得したデジタルアドレス等の情報管理責任&lt;/strong&gt;：ユーザーは、エンドユーザーから取得・収集したデジタルアドレス及び登録住所に関する情報を&lt;strong&gt;自己の費用と責任において厳重に管理する責任&lt;/strong&gt;を負います。管理不備、使用上の過誤、第三者の不正使用等による損害は全てユーザーの責任となります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;同意なき第三者への開示・提供の禁止&lt;/strong&gt;：エンドユーザーから取得したデジタルアドレス等について、デジタルアドレスにより特定される本人の同意のない限り、&lt;strong&gt;ユーザーアプリケーションの利用に必要な範囲を超えて、第三者への開示、貸与、売買等を行うことはできません&lt;/strong&gt;。API で取得した情報をデジタルアドレスを作成したユーザーの同意なしに外部へ公開してはならない、という点は特に重要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API認証キーの厳重管理&lt;/strong&gt;：API 認証キー（クライアント ID 及びシークレットキー）は、&lt;strong&gt;自己の費用と責任において厳重に管理&lt;/strong&gt;する必要があり、管理不備や第三者の不正使用等による損害はユーザーが一切の責任を負います。業務委託関係のない第三者への開示、譲渡、使用させることは禁止されています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;当社による無保証と責任の限定&lt;/strong&gt;：当社（日本郵便株式会社）は、&lt;strong&gt;本サービスの提供に関していかなる種類の保証も行いません&lt;/strong&gt;。サービスの継続性、タイムリーな提供、エラーの有無、情報の有益性・正確性・信頼性、特定の目的への適合性などについて一切保証していません。また、ユーザーによる本サービスの利用に起因する損害、通信障害やシステム障害による不具合や損害、コンピューター・ウィルスなどによる損害、サービスの遅延・変更・中断・中止・廃止などに関し、&lt;strong&gt;一切の責任を負わない&lt;/strong&gt;と明記されています。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;禁止事項&lt;/strong&gt;：利用規約には、API のリバースエンジニアリング、許可なきスクレイピングやクローリング、サービスへの過剰な負荷、競合または競合するおそれのあるサービスの提供など、多数の禁止事項が定められています。これらの禁止事項に違反した場合、サービスの利用停止や利用許諾の取り消しが行われる可能性があり、それによりユーザーに生じた不利益や損害について当社は一切責任を負いません。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;個人情報の取扱い&lt;/strong&gt;：本サービスで取り扱う個人情報（登録情報やエンドユーザーの個人情報）は、プライバシーポリシー等及び本規約に従って取り扱われます。リクエストされたデジタルアドレスに対応する登録住所の提供は、当社において本人の同意に基づく個人データの第三者提供として行われ、ユーザーが提供された登録住所を個人データとして取得する場合には、個人情報保護法に基づき適切な管理措置を講じる責任があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの利用規約の内容は、API を利用してサービスを開発・提供するユーザーにとって非常に重要です。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;この記事では、日本郵便が提供するデジタルアドレスについて、&lt;strong&gt;実際にAPIを触りながら&lt;/strong&gt;調べてみました！&lt;/p&gt;
&lt;p&gt;デジタルアドレスは&lt;strong&gt;7桁のランダムな英数字文字列&lt;/strong&gt;で住所を置き換える仕組みで、大口事業所個別番号の空間を拡張したと考えると簡単に理解できます。&lt;/p&gt;
&lt;p&gt;ただし、利用規約には&lt;strong&gt;けっこう厳しい管理責任&lt;/strong&gt;や個人情報保護、禁止事項などが詳細に定められているので、利用者はこれらをしっかり守る必要があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;正直なところの課題&lt;/strong&gt;として、以下のような点が気になりました：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;総当たり攻撃への脆弱性&lt;/strong&gt;や情報漏洩リスク&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;普及には多くのサイト対応とブラウザ対応&lt;/strong&gt;が必要&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;法人では物理住所との二重管理&lt;/strong&gt;が負担になる可能性&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;デジタルアドレスが今後どのように活用され、普及していくのか、&lt;strong&gt;そのメリットが明確になって、利便性とセキュリティのバランスが取れるか&lt;/strong&gt;が鍵になりそうですね！&lt;/p&gt;
&lt;h2&gt;おまけ&lt;/h2&gt;
&lt;p&gt;デジタルアドレスについて調べてみて、&lt;strong&gt;新しい技術の導入って本当に難しい&lt;/strong&gt;なと改めて思いました。技術的には面白いアプローチだと思うんですが、実際の普及を考えると&lt;strong&gt;エコシステム全体での対応&lt;/strong&gt;が必要になってくるんですよね。&lt;/p&gt;
&lt;p&gt;実は、私が運営している &lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;ポストくん&lt;/a&gt;で、デジタルアドレスの付随機能を提供しようと思って検討してみたんです。でも、&lt;strong&gt;利用規約を詳しく読んでみると、便利なサービスを提供するのは無理そう&lt;/strong&gt;でした。単純に、APIの問い合わせに対してデジタルアドレスの正引きをproxyするような感じにすればすでにポストくんを利用してくれているユーザにはシームレスにサービス提供をできそうな気はします。&lt;/p&gt;
</content:encoded></item><item><title>JCOM CATVインターネット回線ベンチマーク</title><link>https://blog.teraren.com/posts/jcom-catv-internet/</link><guid isPermaLink="true">https://blog.teraren.com/posts/jcom-catv-internet/</guid><description>JCOM CATVインターネット回線ベンチマーク</description><pubDate>Thu, 22 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;テスト結果のCSVファイル&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/uploads/2025/05/speed-results-1747917845.csv&quot;&gt;speed-results-1747917845&lt;/a&gt;&lt;a href=&quot;/uploads/2025/05/speed-results-1747917845.csv&quot;&gt;ダウンロード&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;ダウンは200Mbpsという話だったけど帯域は太そう。latencyが22msもかかっていて辛いなぁ。。。&lt;/p&gt;
&lt;p&gt;uplinkが10Mbpsしか出なくて辛すぎる。&lt;/p&gt;
&lt;p&gt;貸与されたルーターはWiFi AP内蔵なのだが、OFFにできない。。。そして、ノイズが結構うるさい。&lt;/p&gt;
&lt;p&gt;貸与されたルーターの機種: KCM3101&lt;/p&gt;
</content:encoded></item><item><title>ThinkPad X1 Carbon CMOSバッテリー交換</title><link>https://blog.teraren.com/posts/thinkpad-carbon-cmos-battery-fix/</link><guid isPermaLink="true">https://blog.teraren.com/posts/thinkpad-carbon-cmos-battery-fix/</guid><description>ぼくは Thinkpad X1 Carbon を多数所有しています。なぜかって？**中古で安く手に入るから**です😉</description><pubDate>Thu, 22 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ThinkPad X1 Carbon&lt;/strong&gt;の CMOS バッテリー（時計用電池）が切れると起動時にエラーが出る&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CR2016電池&lt;/strong&gt;（100 円）を使って自分で修理可能！　サードパーティ部品（800 円）より&lt;strong&gt;7倍お得&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スポット溶接機&lt;/strong&gt;があれば 8.5 台以上で元が取れる計算&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人向けの記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ThinkPad X1 Carbon で起動時にエラーが出て困っている方&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DIY修理&lt;/strong&gt;に興味があるけど、初心者で不安な方&lt;/li&gt;
&lt;li&gt;コストを抑えて修理したい方&lt;/li&gt;
&lt;li&gt;複数台の ThinkPad を所有している方&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;ぼくは Thinkpad X1 Carbon を多数所有しています。なぜかって？&lt;strong&gt;中古で安く手に入るから&lt;/strong&gt;です😉&lt;/p&gt;
&lt;p&gt;でも在庫として置いておくと、ある問題が発生するんです..。&lt;/p&gt;
&lt;h2&gt;問題：CMOSバッテリーが切れるとどうなる？&lt;/h2&gt;
&lt;p&gt;長期間使わずに在庫していると、&lt;strong&gt;CMOSバッテリー&lt;/strong&gt;が消耗してしまいます。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CMOSバッテリーとは？&lt;/strong&gt;
PC の&lt;strong&gt;時計や基本設定を記憶しておく&lt;/strong&gt;ための小さな電池です。これが切れると、電源を切るたびに時間がリセットされたり、BIOS 設定が初期化されてしまいます。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;具体的には、PC 起動時に &lt;a href=&quot;https://www.reddit.com/r/Lenovo/comments/1dxijs0/error_0271_check_date_and_time_settings_cannot/&quot;&gt;以下のようなエラーメッセージ&lt;/a&gt;がBIOS起動時に表示されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Error 0271: Check Date and Time settings. Cannot modify Date/Time in BIOS
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;「あー、また時間設定がおかしくなってる...」&lt;/strong&gt; って経験、ありませんか？&lt;/p&gt;
&lt;h2&gt;解決方法：2つのアプローチ&lt;/h2&gt;
&lt;h3&gt;方法1：サードパーティ製部品を購入（簡単だけど高い）&lt;/h3&gt;
&lt;p&gt;Amazon でサードパーティー製の部品を購入すれば&lt;strong&gt;800円程度&lt;/strong&gt;で入手可能です。
&lt;strong&gt;メリット：&lt;/strong&gt; 簡単、確実
&lt;strong&gt;デメリット：&lt;/strong&gt; 複数台だとコストがかさむ&lt;/p&gt;
&lt;h3&gt;方法2：CR2016電池を加工して交換（今回の方法）&lt;/h3&gt;
&lt;p&gt;電池単体（&lt;strong&gt;CR2016&lt;/strong&gt;）を購入し、若干の加工を施すことで修理できます。CR2016 電池は&lt;strong&gt;1個100円程度&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;メリット：&lt;/strong&gt; 圧倒的に安い（約 1/8 のコスト！）。
&lt;strong&gt;デメリット：&lt;/strong&gt; 少し手間がかかる&lt;/p&gt;
&lt;p&gt;多数の機材を所有している場合、電池のみを購入して加工・交換する方が&lt;strong&gt;めちゃくちゃお得&lt;/strong&gt;です。
必要な資材もそれほど多くありません。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;安全に作業するために&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作業前に&lt;strong&gt;静電気を逃がす&lt;/strong&gt;（金属部分に触れる）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;電源を完全に切って&lt;/strong&gt;バッテリーも外す&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ショートしないよう&lt;/strong&gt;金属同士が触れないよう注意
&amp;lt;/div&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;必要な工具・材料&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;基本工具&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://amzn.to/3H73G18&quot;&gt;精密ドライバー&lt;/a&gt;（プラスドライバー）&lt;/li&gt;
&lt;li&gt;ラジオペンチまたはカッター、スクレイパー&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CR2016電池&lt;/strong&gt;（コンビニでも買えます！）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;本格的にやるなら（8.5台以上修理する場合）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://amzn.to/4jeoPnk&quot;&gt;スポット溶接機&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://amzn.to/4k5IYNF&quot;&gt;太めのコルゲートチューブ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://amzn.to/43I7fUc&quot;&gt;ヒートガン&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;所要時間：&lt;/strong&gt; 初回は 30 分程度、慣れれば 10 分程度&lt;/p&gt;
&lt;h2&gt;交換手順（ステップバイステップ）&lt;/h2&gt;
&lt;h3&gt;ステップ1：分解開始&lt;/h3&gt;
&lt;p&gt;PC を裏返し、&lt;a href=&quot;https://amzn.to/3H73G18&quot;&gt;精密ドライバー&lt;/a&gt;でネジを外します。
&lt;strong&gt;「あれ、ネジが小さくて見えない...」&lt;/strong&gt; って思った方、大丈夫です。慣れれば簡単です😉&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-18-47-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ステップ2：バッテリー位置の確認&lt;/h3&gt;
&lt;p&gt;バッテリーを手前に向けます。
&lt;strong&gt;ここがポイント：&lt;/strong&gt; バッテリーの向きを間違えないよう注意！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-18-48-47.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ステップ3：CMOSバッテリーを発見&lt;/h3&gt;
&lt;p&gt;バッテリーに付いている精密ネジを外します。コネクタを付けたまま、バッテリーをひっくり返すと...
&lt;strong&gt;おお！&lt;/strong&gt; リチウムイオンバッテリーの裏側に CR2016 バッテリーが隠れています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-18-56-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ステップ4：保護材の確認&lt;/h3&gt;
&lt;p&gt;今回は黄色い絶縁ビニールで覆われていますね。機種によっては熱圧縮チューブの場合もあります。
&lt;strong&gt;「なんか複雑そう...」&lt;/strong&gt; と思うかもしれませんが、実は単純な構造です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-18-57-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ステップ5：古い電池を取り外し&lt;/h3&gt;
&lt;p&gt;コネクタから電池を取り外します。
&lt;strong&gt;注意：&lt;/strong&gt; 無理に引っ張らず、ゆっくりと外しましょう。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-18-58-23.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ステップ6：被覆を剥がす&lt;/h3&gt;
&lt;p&gt;絶縁ビニールの被覆を剥がします。
&lt;strong&gt;ここで重要：&lt;/strong&gt; 中の金属端子を傷つけないよう慎重に！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-18-58-41.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ステップ7：スポット溶接部分の除去&lt;/h3&gt;
&lt;p&gt;スポット溶接されている箇所をラジオペンチやカッター、スクレイパーなどで取り外します。
&lt;strong&gt;初心者の方へ：&lt;/strong&gt; 力を入れすぎず、少しずつ剥がしていくのがコツです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-18-59-04.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ステップ8：絶縁材の確認&lt;/h3&gt;
&lt;p&gt;CR2016 の周囲に絶縁用のビニールが巻かれている場合もあります。
これも&lt;strong&gt;再利用&lt;/strong&gt;できるので、大切に保管しておきましょう。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-18-59-43.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ステップ9：新しい電池の取り付け（重要！）&lt;/h3&gt;
&lt;p&gt;接点をきれいに剥がせたら、平らにして再利用します。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;超重要な注意点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ボタン電池は&lt;strong&gt;側面もプラス極&lt;/strong&gt;になっています&lt;/li&gt;
&lt;li&gt;ステンレスが触れないように注意&lt;/li&gt;
&lt;li&gt;ショートしないよう、接点をわずかに折り曲げる工夫を
&amp;lt;/div&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://amzn.to/4jeoPnk&quot;&gt;スポット溶接機&lt;/a&gt;を使って新しいCR2016を取り付けます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-19-00-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ステップ10：絶縁処理&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://amzn.to/4k5IYNF&quot;&gt;太めのコルゲートチューブ&lt;/a&gt;を巻き、&lt;a href=&quot;https://amzn.to/43I7fUc&quot;&gt;ヒートガン&lt;/a&gt;で温めて圧着します。
&lt;strong&gt;「プロっぽい仕上がりになった！」&lt;/strong&gt; って思える瞬間です😊&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-19-01-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ステップ11：動作確認&lt;/h3&gt;
&lt;p&gt;バッテリーをねじ止めし、起動してエラーが出なければ&lt;strong&gt;交換完了&lt;/strong&gt;です！
最後に本締めして終わり。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「Error 0271が出なくなった！」&lt;/strong&gt; って瞬間は、めちゃくちゃ嬉しいですよ🎉&lt;/p&gt;
&lt;h2&gt;コスト計算とまとめ&lt;/h2&gt;
&lt;h3&gt;費用対効果の検証&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;1台あたりのコスト比較&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;サードパーティ部品：800 円&lt;/li&gt;
&lt;li&gt;CR2016 電池のみ：100 円&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;節約額：700円/台&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;スポット溶接機を購入する場合&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;スポット溶接機：約 6,000 円&lt;/li&gt;
&lt;li&gt;損益分岐点：6,000 円 ÷ 700 円 = &lt;strong&gt;8.5台&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;つまり、&lt;strong&gt;8.5台以上&lt;/strong&gt;交換する予定があるなら、スポット溶接機を購入した方がお得になります。&lt;/p&gt;
&lt;h3&gt;実際にやってみた感想&lt;/h3&gt;
&lt;p&gt;正直、最初は**「うまくいくかな...」** って不安でした。でも実際にやってみると、思ったより簡単！&lt;/p&gt;
&lt;p&gt;特に複数台持ってる方には&lt;strong&gt;めちゃくちゃオススメ&lt;/strong&gt;です。コストも抑えられるし、なにより DIY 修理の達成感がたまりません😉&lt;/p&gt;
&lt;h3&gt;最後に&lt;/h3&gt;
&lt;p&gt;ThinkPad の CMOS バッテリー交換、いかがでしたか？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「自分でも修理できそう！」&lt;/strong&gt; って思ってもらえたら嬉しいです。最初は緊張するかもしれませんが、慣れれば&lt;strong&gt;サクッと&lt;/strong&gt;できるようになりますよ。&lt;/p&gt;
&lt;p&gt;ぜひチャレンジしてみてくださいね！　もし分からないことがあれば、気軽に質問してください🙌&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;参考リンク&lt;/strong&gt;
https://amzn.to/4jeoPnk&lt;/p&gt;
</content:encoded></item><item><title>WordPressテーマのCI/CDをGitHub Actionsで構築する(Minifyを追加)</title><link>https://blog.teraren.com/posts/wordpress-theme-ci-cd-minify/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-theme-ci-cd-minify/</guid><description>このブログ記事では、WordPress テーマの CI/CD に、画像の最適化、JavaScript と CSS の minify 処理を追加する方法について解説します。</description><pubDate>Thu, 22 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;このブログ記事では、WordPress テーマの CI/CD に、画像の最適化、JavaScript と CSS の minify 処理を追加する方法について解説します。&lt;/p&gt;
&lt;h3&gt;対象読者&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;WordPress テーマの CI/CD に興味がある方&lt;/li&gt;
&lt;li&gt;GitHub Actions を使って WordPress テーマの CI/CD を構築したい方&lt;/li&gt;
&lt;li&gt;WordPress テーマのパフォーマンスを改善したい方&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;前提知識&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;WordPress の基本的な知識&lt;/li&gt;
&lt;li&gt;CI/CD の基本的な知識&lt;/li&gt;
&lt;li&gt;GitHub Actions の基本的な知識&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;CI/CDとは&lt;/h3&gt;
&lt;p&gt;CI/CD（継続的インテグレーション/継続的デリバリー）とは、ソフトウェア開発における変更をより頻繁かつ確実にリリースするためのプラクティスです。&lt;/p&gt;
&lt;h3&gt;Minifyとは&lt;/h3&gt;
&lt;p&gt;Minify とは、JavaScript や CSS などのファイルのサイズを小さくする処理のことです。具体的には、コメントや空白文字を削除したり、変数名を短くしたりします。&lt;/p&gt;
&lt;h3&gt;Minifyを行うメリット&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ファイルサイズが小さくなるため、Web サイトの表示速度が向上する。&lt;/li&gt;
&lt;li&gt;ファイルサイズが小さくなるため、サーバーの負荷が軽減される。&lt;/li&gt;
&lt;li&gt;ファイルサイズが小さくなるため、ユーザーのデータ通信量を削減できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今回は、Deploy する際に画像の最適化や CSS の minify と言った webpack が普通は行うようなビルドを少し取り入れます。&lt;/p&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;h3&gt;jpg, pngファイルを圧縮するカスタムアクション。&lt;/h3&gt;
&lt;p&gt;このアクションは、pngquant と jpegoptim を使って、リポジトリ内の PNG と JPG 画像を最適化します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;pngquant:&lt;/strong&gt; PNG 画像を非可逆圧縮するツールです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;jpegoptim:&lt;/strong&gt; JPG 画像を非可逆圧縮するツールです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;.github/actions/optimize-image/action.yml&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: &apos;Optimize Images with Pngquant &amp;amp; Jpegoptim&apos;
description: &apos;Finds and optimizes PNG and JPG images in the repository using pngquant and jpegoptim.&apos;

inputs:
  png_quality:
    description: &apos;Quality range for pngquant (e.g., 65-80)&apos;
    required: false
    default: &apos;65-80&apos;
  jpeg_quality:
    description: &apos;Quality for jpegoptim (0-100, lower is smaller file, more loss)&apos;
    required: false
    default: &apos;80&apos; # jpegoptim のデフォルト品質
  strip_metadata:
    description: &apos;Remove all metadata (EXIF, comments, etc.) from JPEGs (true/false)&apos;
    required: false
    default: &apos;true&apos;

outputs:
  optimized_png_count:
    description: &apos;Number of PNG images that were optimized.&apos;
    value: ${{ steps.optimize_png.outputs.optimized_count }}
  optimized_jpg_count:
    description: &apos;Number of JPG images that were optimized.&apos;
    value: ${{ steps.optimize_jpg.outputs.optimized_count }}

runs:
  using: &quot;composite&quot;
  steps:
    - name: Install image optimization tools
      run: |
        sudo apt-get update
        sudo apt-get install -y pngquant jpegoptim
      shell: bash

    - name: Find and optimize PNG images
      id: optimize_png # IDを明確に
      run: |
        optimized_count=0
        
        find . -type f -name &quot;*.png&quot; -print0 | while IFS= read -r -d $&apos;\0&apos; file; do
          original_size=$(stat -c %s &quot;$file&quot;)
          pngquant --quality=${{ inputs.png_quality }} --force --ext .png &quot;$file&quot;
          optimized_size=$(stat -c %s &quot;$file&quot;)
          
          if [ &quot;$original_size&quot; -ne &quot;$optimized_size&quot; ]; then
            echo &quot;Optimized PNG: $file (Original: $original_size bytes, Optimized: $optimized_size bytes)&quot;
            optimized_count=$((optimized_count + 1))
          else
            echo &quot;Skipped PNG (no change): $file&quot;
          fi
        done
        
        echo &quot;optimized_count=$optimized_count&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT
      shell: bash

    - name: Find and optimize JPG images
      id: optimize_jpg # IDを明確に
      run: |
        optimized_count=0
        
        find . -type f -iregex &quot;.*\.jpe?g$&quot; -print0 | while IFS= read -r -d $&apos;\0&apos; file; do
          original_size=$(stat -c %s &quot;$file&quot;)
          
          # jpegoptimのオプションを動的に設定
          JPEGOPTIM_OPTIONS=&quot;--max=${{ inputs.jpeg_quality }}&quot;
          if [ &quot;${{ inputs.strip_metadata }}&quot; == &quot;true&quot; ]; then
            JPEGOPTIM_OPTIONS+=&quot; --strip-all&quot;
          fi
          
          jpegoptim $JPEGOPTIM_OPTIONS &quot;$file&quot;
          
          optimized_size=$(stat -c %s &quot;$file&quot;)
          
          if [ &quot;$original_size&quot; -ne &quot;$optimized_size&quot; ]; then
            echo &quot;Optimized JPG: $file (Original: $original_size bytes, Optimized: $optimized_size bytes)&quot;
            optimized_count=$((optimized_count + 1))
          else
            echo &quot;Skipped JPG (no change): $file&quot;
          fi
        done
        
        echo &quot;optimized_count=$optimized_count&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT
      shell: bash

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;JavaScriptのminify&lt;/h3&gt;
&lt;p&gt;このアクションは、Terserを使って、JavaScriptファイルをminify（難読化）します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Terser:&lt;/strong&gt; JavaScriptファイルをminify（難読化）するツールです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;.github/actions/optimize-js/action.yml&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: &apos;Uglify JavaScript with Terser&apos;
description: &apos;Finds and minifies/uglifies JavaScript files using Terser.&apos;

inputs:
  paths:
    description: &apos;Glob pattern for JavaScript files to process (e.g., &quot;**/*.js&quot;).&apos;
    required: false
    default: &apos;**/*.js&apos;
  terser_options:
    description: &apos;JSON string of Terser minify options (e.g., {&quot;compress&quot;:{},&quot;mangle&quot;:true})&apos;
    required: false
    default: &apos;{&quot;compress&quot;:true,&quot;mangle&quot;:true}&apos; # デフォルトは圧縮と変数名の難読化

outputs:
  uglified_count:
    description: &apos;Number of JavaScript files that were uglified/minified.&apos;
    value: ${{ steps.uglify.outputs.uglified_count }}

runs:
  using: &quot;composite&quot;
  steps:
    - name: Set up Node.js
      uses: actions/setup-node@v4
      with:
        node-version: &apos;20&apos; # Terserの実行に必要なNode.jsのバージョン

    - name: Install Terser
      run: npm install -g terser # terserをグローバルインストール
      shell: bash

    - name: Find and uglify JavaScript files
      id: uglify
      run: |
        uglified_count=0
        
        # globパターンを配列として扱うための準備
        # find . -name &quot;*.js&quot; よりも柔軟な指定が可能
        
        # shopt -s globstar はワイルドカードを拡張する（bashでのみ有効）
        shopt -s globstar || true # エラーにならないように
        
        # inputs.paths で指定されたファイルを処理
        for file in ${{ inputs.paths }}; do
          if [ -f &quot;$file&quot; ]; then # ファイルが存在することを確認
            original_size=$(stat -c %s &quot;$file&quot;) # オリジナルファイルのサイズを取得
            
            # Terserで難読化（上書き）
            # input: JSON文字列をparseして渡す
            terser &quot;$file&quot; -o &quot;$file&quot; --config-file &amp;lt;(echo &apos;${{ inputs.terser_options }}&apos;)
            
            optimized_size=$(stat -c %s &quot;$file&quot;) # 難読化後のファイルのサイズを取得
            
            if [ &quot;$original_size&quot; -ne &quot;$optimized_size&quot; ]; then
              echo &quot;Uglified: $file (Original: $original_size bytes, Optimized: $optimized_size bytes)&quot;
              uglified_count=$((uglified_count + 1))
            else
              echo &quot;Skipped (no change): $file&quot;
            fi
          fi
        done
        
        echo &quot;uglified_count=$uglified_count&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT
      shell: bash


&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;CSSのminify&lt;/h3&gt;
&lt;p&gt;このアクションは、clean-css-cliを使って、CSSファイルをminifyします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;clean-css-cli:&lt;/strong&gt; CSSファイルをminifyするツールです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;.github/actions/optimize-css/action.yml&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: &apos;Minify CSS with Clean-CSS&apos;
description: &apos;Finds and minifies CSS files using clean-css-cli.&apos;

inputs:
  paths:
    description: &apos;Glob pattern for CSS files to process (e.g., &quot;**/*.css&quot;).&apos;
    required: false
    default: &apos;**/*.css&apos;
  clean_css_options:
    description: &apos;JSON string of clean-css options (e.g., {&quot;level&quot;:2})&apos;
    required: false
    default: &apos;{}&apos; # デフォルトは基本的な圧縮
  output_suffix:
    description: &apos;Suffix to add to the minified file name (e.g., .min for style.min.css). Leave empty to overwrite.&apos;
    required: false
    default: &apos;&apos; # デフォルトは上書き

outputs:
  minified_count:
    description: &apos;Number of CSS files that were minified.&apos;
    value: ${{ steps.minify.outputs.minified_count }}

runs:
  using: &quot;composite&quot;
  steps:
    - name: Set up Node.js
      uses: actions/setup-node@v4
      with:
        node-version: &apos;20&apos; # clean-css-cliの実行に必要なNode.jsのバージョン

    - name: Install clean-css-cli
      run: npm install -g clean-css-cli # clean-css-cliをグローバルインストール
      shell: bash

    - name: Find and minify CSS files
      id: minify
      run: |
        minified_count=0
        
        shopt -s globstar || true
        
        for file in ${{ inputs.paths }}; do
          if [ -f &quot;$file&quot; ]; then # ファイルが存在することを確認
            original_size=$(stat -c %s &quot;$file&quot;) # オリジナルファイルのサイズを取得
            
            output_file=&quot;$file&quot;
            if [ -n &quot;${{ inputs.output_suffix }}&quot; ]; then
              # 拡張子の前にサフィックスを追加 (e.g., style.css -&amp;gt; style.min.css)
              filename=&quot;${file%.*}&quot;
              extension=&quot;${file##*.}&quot;
              output_file=&quot;${filename}${inputs.output_suffix}.${extension}&quot;
            fi

            # clean-css-cliで圧縮
            # input: JSON文字列をparseして渡す
            # 圧縮後にファイルサイズが変わるか確認
            # clean-css-cli はデフォルトで上書きするが、
            # -o で出力ファイルを明示的に指定できるため、上書きまたは別名保存が可能
            
            # clean-css-cliのオプションを構築
            CLEAN_CSS_OPTIONS=&quot;&quot;
            if [ -n &quot;${{ inputs.clean_css_options }}&quot; ]; then
              # clean-css-cli はJSONファイルを直接受け取らないので、
              # オプションをコマンドライン引数に変換するか、stdin経由で渡す必要がある。
              # 最も簡単なのは、JSON文字列をそのまま渡すこと。
              # clean-css-cliは --config オプションがないので、
              # 各オプションを個別に渡すか、デフォルトを使う。
              # ここでは、デフォルトの動作に任せるか、カスタムオプションを考慮せず、
              # simpleに圧縮する。より高度なオプションが必要な場合は、スクリプト内でJSONをパースして引数に変換する必要がある。
              
              # しかし、clean-css-cliは`--config`オプションがないため、オプションは個別に渡す必要があります。
              # ここでは、`clean_css_options`をJSONとしてパースして引数に変換する例を示します。
              # ただし、これを行うには`jq`などのツールが必要になるため、ワークフローの複雑さを避けるため、デフォルトではシンプルな圧縮のみを行うか、特定のよく使うオプションのみをinputで受け取る形にするのが現実的です。
              
              # 今回は`clean-css-cli`のデフォルト挙動（強力な圧縮）に任せるか、よく使うオプション（例: `--level`）を直接inputで受け取る形にします。
              # `clean_css_options` は、ここでは直接利用せず、将来的な拡張ポイントとして残します。
              
              echo &quot;Warning: clean_css_options input is currently ignored due to clean-css-cli limitations for direct JSON config. Using default clean-css behavior or specified output_suffix.&quot;
            fi

            cleancss -o &quot;$output_file&quot; &quot;$file&quot; # 圧縮を実行

            optimized_size=$(stat -c %s &quot;$output_file&quot;) # 圧縮後のファイルのサイズを取得
            
            if [ &quot;$original_size&quot; -ne &quot;$optimized_size&quot; ]; then
              echo &quot;Minified: $file to $output_file (Original: $original_size bytes, Optimized: $optimized_size bytes)&quot;
              minified_count=$((minified_count + 1))
            else
              echo &quot;Skipped (no change): $file&quot;
            fi
          fi
        done
        
        echo &quot;minified_count=$minified_count&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT
      shell: bash
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Workflowへの組み込み方&lt;/h3&gt;
&lt;p&gt;これらのアクションをワークフローに組み込むには、&lt;code&gt;.github/workflows/main.yml&lt;/code&gt; ファイルに以下のステップを追加します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    - name: Optimize Images
      uses: ./.github/actions/optimize-image
      with:
        jpeg_quality: 70

    - name: Optimize JavaScript
      uses: ./.github/actions/optimize-js

    - name: Optimize CSS
      uses: ./.github/actions/optimize-css
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これらのステップは、&lt;code&gt;deploy&lt;/code&gt; ステップの&lt;strong&gt;前&lt;/strong&gt;に追加することを推奨します。&lt;/p&gt;
&lt;h3&gt;ワークフローファイルの全体像&lt;/h3&gt;
&lt;p&gt;ワークフローファイルは、以下のようになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: CI/CD

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up SSH key
        uses: webfactory/ssh-agent@v0.8.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

      - name: Optimize Images
        uses: ./.github/actions/optimize-image
        with:
          jpeg_quality: 70

      - name: Optimize JavaScript
        uses: ./.github/actions/optimize-js

      - name: Optimize CSS
        uses: ./.github/actions/optimize-css

      - name: Deploy
        run: |
          # デプロイ処理
          echo &quot;Deploying...&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;これらの最適化を行うことで、サイトを表示した際のアセットの読み込み時間を短縮できるようになりました。&lt;/p&gt;
&lt;p&gt;具体的には、アセットの合計サイズを 11.0MB から 7.7MB に削減できました。&lt;/p&gt;
&lt;p&gt;本来であれば、webp などのより高度な画像フォーマットを使用したいところですが、今回はオリジナルファイルを変更せずに、裏側で最適化できる範囲に留めました。&lt;/p&gt;
&lt;h2&gt;実行時間&lt;/h2&gt;
&lt;p&gt;画像の最適化に少し時間がかかります。1 分程度です。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-22-13-10-49.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;画像の圧縮ツールのインストールにネットワーク通信が必要になるため結構時間を消費しているようです。
可能なら画像は元のデータを圧縮してしまうのがおすすめです。Git 管理しているのでいつでももとに戻せるので。&lt;/p&gt;
&lt;h3&gt;今後の展望&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;webp などのより高度な画像フォーマットの導入&lt;/li&gt;
&lt;li&gt;JavaScript と CSS の更なる minify&lt;/li&gt;
&lt;li&gt;CDN の導入&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>WordPressテーマのCI/CDをGitHub Actionsで構築する</title><link>https://blog.teraren.com/posts/wordpress-theme-ci-cd/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-theme-ci-cd/</guid><description>この記事では、GitHub Actions を活用した WordPress テーマの CI/CD 構築について解説する。安全かつ効率的な運用を実現するための方法を紹介する。</description><pubDate>Wed, 21 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;この記事では、GitHub Actions を活用した WordPress テーマの CI/CD 構築について解説する。安全かつ効率的な運用を実現するための方法を紹介する。&lt;/p&gt;
&lt;h2&gt;背景：WordPress運用における課題&lt;/h2&gt;
&lt;p&gt;WordPress は手軽にブログや Web サイトを始められる便利な CMS だが、DevOps の観点からはいくつかの課題がある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;開発環境、ステージング環境、本番環境の運用が煩雑になりがち。&lt;/li&gt;
&lt;li&gt;テーマファイルの管理が難しい。
&lt;ul&gt;
&lt;li&gt;ファイルを直接編集するとバージョン管理ができない。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.archlinux.jp/index.php/Etckeeper&quot;&gt;etckeeper&lt;/a&gt;を使っても、ステージング環境と本番環境のファイルを同期するきれいな方法がない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;バージョン管理ができない。
&lt;ul&gt;
&lt;li&gt;更新するたびに ZIP ファイルを作成してアップロードするのは手間がかかる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DB 内のデータ（記事、ページ）とファイル（プラグイン、テーマ、アセット）が密接に連携しているため、コードレベルでのスナップショットが取りづらい。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;解決策：GitHub ActionsによるCI/CD&lt;/h2&gt;
&lt;p&gt;これらの課題を解決するために、GitHub Actions を活用して WordPress テーマの CI/CD を構築する。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;テーマファイルを GitHub リポジトリで管理する&lt;/li&gt;
&lt;li&gt;GitHub Actions で、develop ブランチへの push をトリガーにステージング環境へデプロイする&lt;/li&gt;
&lt;li&gt;GitHub Actions で、main ブランチへの push をトリガーに本番環境へデプロイする&lt;/li&gt;
&lt;li&gt;CI で PHP の構文チェックを行い、本番環境でのエラーを未然に防ぐ&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;システム設計&lt;/h2&gt;
&lt;p&gt;このシステムでは、以下の要素を組み合わせて WordPress テーマの CI/CD を実現します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub リポジトリ：テーマファイルのソースコードを管理する。&lt;/li&gt;
&lt;li&gt;GitHub Actions：CI/CD のワークフローを定義し、実行する。&lt;/li&gt;
&lt;li&gt;SSH：GitHub Actions から WordPress サーバーへ安全にファイルを転送する。&lt;/li&gt;
&lt;li&gt;rsync：効率的にファイルを同期する。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定手順&lt;/h2&gt;
&lt;h3&gt;1. GitHubリポジトリの準備&lt;/h3&gt;
&lt;p&gt;まず、WordPress テーマのファイルを GitHub リポジトリに登録する。&lt;/p&gt;
&lt;h3&gt;2. GitHub Actionsのワークフロー設定&lt;/h3&gt;
&lt;p&gt;次に、GitHub Actions のワークフローを設定する。&lt;/p&gt;
&lt;h4&gt;ステージング環境へのデプロイ&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;.github/workflows/deploy-staging.yml&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Deploy to Staging

on:
  push:
    branches: [ develop ]
  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    - name: PHP Syntax Check
      uses: ./.github/actions/php-syntax-check
  deploy:
    needs: test
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Set up SSH
      uses: webfactory/ssh-agent@v0.9.0
      with:
        ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY_STAGING }}
        # known_hosts: ${{ secrets.KNOWN_HOSTS_STAGING }} # よりセキュアにする場合は有効化

    - name: Ensure target theme directory exists on remote
      run: |
        SSH_HOST=&quot;${{ secrets.STAGING_SERVER_HOST }}&quot;
        SSH_USER=&quot;${{ secrets.STAGING_SERVER_USER }}&quot;
        THEME_PATH=&quot;${{ secrets.STAGING_THEME_PATH }}&quot;
        ssh -o StrictHostKeyChecking=no &quot;${SSH_USER}&quot;@&quot;${SSH_HOST}&quot; &quot;mkdir -p \&quot;${THEME_PATH}\&quot;&quot;

    - name: Rsync theme files to Staging
      run: |
        SSH_HOST=&quot;${{ secrets.STAGING_SERVER_HOST }}&quot;
        SSH_USER=&quot;${{ secrets.STAGING_SERVER_USER }}&quot;
        THEME_PATH=&quot;${{ secrets.STAGING_THEME_PATH }}&quot;
        rsync -avzc --delete --exclude=&apos;.*&apos; --exclude README.md -e &quot;ssh -o StrictHostKeyChecking=no&quot; ./ &quot;${SSH_USER}&quot;@&quot;${SSH_HOST}&quot;:&quot;${THEME_PATH}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このワークフローは、&lt;code&gt;develop&lt;/code&gt; ブランチへのpushをトリガーに、以下の処理を行う。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;コードをチェックアウトする&lt;/li&gt;
&lt;li&gt;PHPの構文チェックを行う&lt;/li&gt;
&lt;li&gt;SSHでWordPressサーバーに接続し、テーマファイルをrsyncで同期する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;このrsyncを実行する際のオプションは重要である。特に重要なオプションを以下に示す。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-c&lt;/code&gt; オプション：ファイルのチェックサムで比較し、同一ファイルであれば変更しない。GitHub Actionsでコピー元のファイルが準備される際、タイムスタンプがcheckout時のものになるため、更新日時がサーバと異なることを避けるために使用する。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-u&lt;/code&gt; オプション：サーバに新しいファイルが存在する場合、上書きしない。今回はすべてのファイルを上書きするため、このオプションは使用しない。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--exclude&lt;/code&gt;：機密情報を含まないように、ドキュメントやGit関連ファイルを除外する。&lt;/p&gt;
&lt;h4&gt;本番環境へのデプロイ&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;.github/workflows/deploy-production.yml&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Deploy to Production

on:
  push:
    branches: [ main ]
  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    - name: PHP Syntax Check
      uses: ./.github/actions/php-syntax-check
  deploy:
    needs: test
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v4

    - name: Set up SSH
      uses: webfactory/ssh-agent@v0.9.0
      with:
        ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY_PRODUCTION }}
        # known_hosts: ${{ secrets.KNOWN_HOSTS_PRODUCTION }} # よりセキュアにする場合は有効化

    - name: Ensure target theme directory exists on remote
      run: |
        SSH_HOST=&quot;${{ secrets.PRODUCTION_SERVER_HOST }}&quot;
        SSH_USER=&quot;${{ secrets.PRODUCTION_SERVER_USER }}&quot;
        THEME_PATH=&quot;${{ secrets.PRODUCTION_THEME_PATH }}&quot;
        ssh -o StrictHostKeyChecking=no &quot;${SSH_USER}&quot;@&quot;${SSH_HOST}&quot; &quot;mkdir -p \&quot;${THEME_PATH}\&quot;&quot;

    - name: Rsync theme files to PRODUCTION
      run: |
        SSH_HOST=&quot;${{ secrets.PRODUCTION_SERVER_HOST }}&quot;
        SSH_USER=&quot;${{ secrets.PRODUCTION_SERVER_USER }}&quot;
        THEME_PATH=&quot;${{ secrets.PRODUCTION_THEME_PATH }}&quot;
        rsync -avzc --delete --exclude=&apos;.*&apos; --exclude README.md -e &quot;ssh -o StrictHostKeyChecking=no&quot; ./ &quot;${SSH_USER}&quot;@&quot;${SSH_HOST}&quot;:&quot;${THEME_PATH}&quot;

    - name: Clear WordPress Cache
      run: |
        SSH_HOST=&quot;${{ secrets.PRODUCTION_SERVER_HOST }}&quot;
        SSH_USER=&quot;${{ secrets.PRODUCTION_SERVER_USER }}&quot;
        ssh -o StrictHostKeyChecking=no &quot;${SSH_USER}&quot;@&quot;${SSH_HOST}&quot; &quot;wp w3-total-cache flush all&quot;

  release:
    needs: deploy
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    - name: Release Drafter
      uses: release-drafter/release-drafter@v6
      with:
        publish: true
        version: ${{ steps.version.outputs.version-without-v }}
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このワークフローは、&lt;code&gt;main&lt;/code&gt; ブランチへのpushをトリガーに、以下の処理を行う。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;コードをチェックアウトする&lt;/li&gt;
&lt;li&gt;PHPの構文チェックを行う&lt;/li&gt;
&lt;li&gt;SSHでWordPressサーバーに接続し、テーマファイルをrsyncで同期する&lt;/li&gt;
&lt;li&gt;WordPressのキャッシュをクリアする&lt;/li&gt;
&lt;li&gt;リリースノートを自動生成する&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;PHP構文チェック&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;.github/actions/php-syntax-check/action.yml&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: PHP Syntax Check
description: Checks PHP syntax for errors.
runs:
  using: &quot;composite&quot;
  steps:
    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: &apos;7.4&apos;
    - name: Run PHP Syntax Check
      shell: bash
      run: |
        find . -name &quot;*.php&quot; -print0 | xargs -0 -n1 php -l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このアクションは、PHPの構文チェックを行います。&lt;/p&gt;
&lt;h4&gt;リリースノート自動生成&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;.github/release-drafter.yml&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name-template: &apos;v$RESOLVED_VERSION 🌈&apos;
tag-template: &apos;v$RESOLVED_VERSION&apos;
categories:
  - title: &apos;🚀 Features&apos;
    labels:
      - &apos;feature&apos;
      - &apos;enhancement&apos;
  - title: &apos;🐛 Bug Fixes&apos;
    labels:
      - &apos;fix&apos;
      - &apos;bugfix&apos;
  - title: &apos;🧰 Maintenance&apos;
    label: &apos;chore&apos;
change-template: &apos;- $TITLE @$AUTHOR (#$NUMBER)&apos;
change-title-escapes: &apos;\&amp;lt;*_&amp;amp;&apos; # You can add # and @ to disable mentions, and add ` to disable code blocks.
version-resolver:
  major:
    labels:
      - &apos;major&apos;
  minor:
    labels:
      - &apos;minor&apos;
  patch:
    labels:
      - &apos;patch&apos;
  default: patch
template: |
  ## Changes

  $CHANGES
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このファイルは、リリースノートの自動生成に関する設定を記述します。&lt;/p&gt;
&lt;h3&gt;3. GitHub Secretsの設定&lt;/h3&gt;
&lt;p&gt;GitHub ActionsからWordPressサーバーへSSH接続するために、GitHub Secretsを設定します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SSH_PRIVATE_KEY_STAGING&lt;/code&gt;: ステージング環境へのSSH接続に使用する秘密鍵&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SSH_PRIVATE_KEY_PRODUCTION&lt;/code&gt;: 本番環境へのSSH接続に使用する秘密鍵&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STAGING_SERVER_HOST&lt;/code&gt;: ステージング環境のホスト名&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STAGING_SERVER_USER&lt;/code&gt;: ステージング環境のユーザー名&lt;/li&gt;
&lt;li&gt;&lt;code&gt;STAGING_THEME_PATH&lt;/code&gt;: ステージング環境のテーマファイルのパス&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PRODUCTION_SERVER_HOST&lt;/code&gt;: 本番環境のホスト名&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PRODUCTION_SERVER_USER&lt;/code&gt;: 本番環境のユーザー名&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PRODUCTION_THEME_PATH&lt;/code&gt;: 本番環境のテーマファイルのパス&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. WordPressサーバーの設定&lt;/h3&gt;
&lt;p&gt;WordPressサーバーに、GitHub ActionsからWordPressサーバーへSSH接続できるように設定します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WordPressを運用しているホストにはGithub Actionsからsshで接続できるようにしておく必要があります。
&lt;ul&gt;
&lt;li&gt;Github actionsのIPアドレスの空間が膨大なのでligthsailだと制限をかけるのが不可能です。&lt;/li&gt;
&lt;li&gt;Github actionsのsource IP addressは&lt;a href=&quot;https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-githubs-ip-addresses&quot;&gt;API&lt;/a&gt;で公開されています。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;sshキーペアの作り方はこんな感じです。生成された秘密鍵をGithub Actionsのsecretsに登録し、公開鍵をwordpressの.ssh/authorized_keysに追加します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ssh-keygen -t ed25519 -C &quot;github-actions-staging@example.com&quot; -f ~/.ssh/github_actions_deploy_key_staging
% ssh-keygen -t ed25519 -C &quot;github-actions-production@example.com&quot; -f ~/.ssh/github_actions_deploy_key_production
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;実行結果&lt;/h2&gt;
&lt;p&gt;GitHub Actions のワークフローを実行すると、ステージング環境と本番環境へテーマファイルが自動的にデプロイされます。&lt;/p&gt;
&lt;p&gt;ステージングは 1 分程度で完了します。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-16-47-34.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本番も 1 分程度で完了します。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-21-16-48-07.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;今後の展望&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WordPress を SSG（Static Site Generator）に移行することで、より高速かつ安全な Web サイトを構築できる可能性があります。&lt;/li&gt;
&lt;li&gt;カオスになりやすい WordPress の運用に少しでも秩序を導入できたのでこれでしばらくは延命できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;GitHub Actions を活用することで、WordPress テーマの CI/CD を簡単に構築できます。
これにより、開発効率が向上し、安全な運用を実現できます。&lt;/p&gt;
</content:encoded></item><item><title>AI PMワークフロー「aipm_v0」の使用例と応用を考える</title><link>https://blog.teraren.com/posts/aipm-online-qualitative-research/</link><guid isPermaLink="true">https://blog.teraren.com/posts/aipm-online-qualitative-research/</guid><description>みやっち氏作のAI PMワークフロー「aipm_v0」を、オンライン定性調査プラットフォーム構築に適用して検証した記録。</description><pubDate>Thu, 08 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3秒まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;この記事の目的&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;みやっち氏作の AI PM ワークフローの理解と社内プロジェクトへの応用可能性の探求&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内容&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;AI PM の概要とコンセプト&lt;/li&gt;
&lt;li&gt;「aipm_v0」の説明&lt;/li&gt;
&lt;li&gt;「オンライン定性調査プラットフォーム構築」における活用シミュレーション。8 年前に企画してローンチしたサービス。&lt;/li&gt;
&lt;li&gt;考察や応用事例。示唆が多いので解説。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;期待される効果&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;プロジェクト管理業務の効率化と質の向上&lt;/li&gt;
&lt;li&gt;AI Agent や Digital Twin、ドキュメントワークフローへの応用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;AI PMとは？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AI を活用した、プロジェクトマネジメントの新しいアプローチです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;目的&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;プロジェクト計画の自動生成・最適化&lt;/li&gt;
&lt;li&gt;タスクの割り当てと進捗管理の支援&lt;/li&gt;
&lt;li&gt;リスク予測と早期警告&lt;/li&gt;
&lt;li&gt;コミュニケーションの円滑化&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;期待されるメリット&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;プロジェクトマネージャー（PM）の負担軽減&lt;/li&gt;
&lt;li&gt;意思決定の迅速化と精度向上&lt;/li&gt;
&lt;li&gt;プロジェクト成功率の向上&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;知ったきっかけ&lt;/h2&gt;
&lt;p&gt;https://x.com/miyatti/status/1919257337556246728&lt;/p&gt;
&lt;h2&gt;みやっち氏作「aipm_v0」の概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href=&quot;https://github.com/miyatti777/aipm_v0&quot;&gt;miyatti777/aipm_v0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コンセプト (リポジトリのREADMEなどから引用・要約):&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;例: LLM を活用し、プロジェクトの初期構想からタスク分解、進捗管理までを支援するツール&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;主な機能 (同上):&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;プロジェクト概要からの WBS 生成&lt;/li&gt;
&lt;li&gt;タスクカードの自動作成&lt;/li&gt;
&lt;li&gt;進捗報告の集約と分析&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特徴 (同上):&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;特定の LLM に依存しない設計（想定されています）&lt;/li&gt;
&lt;li&gt;シンプルなインタフェース&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;aipm_v0のワークフロー&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/miyatti777/aipm_v0/blob/main/README.md&quot;&gt;本家のreadme&lt;/a&gt;が崩れていたので引用して整形。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;┌──────────────────────────────┐   trigger（チャットコマンド）
│ 00_master_rules.mdc          │◀───────────────────────┐
└─────────┬────────────────────┘                        │
          │call                                         │
┌─────────▼────────────┐   発散/収束も Draft 化           │
│ 01‑06_pmbok_*.mdc    │──────────────────┐             │
│ 08_flow_assist.mdc   │    create_draft  │             │
└─────────┬────────────┘                  │             │
          │                               │             │
         ▼ Draft (.md)                    │             │
      Flow/YYYYMM/YYYY‑MM‑DD/─────────────┘             │
         │  human review + &quot;確定反映して&quot;                 │
         ▼                                              │
     Stock/programs/PROGRAM/projects/PROJECT/.. ← flow_to_stock_rules.mdc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;もう少し簡略化すると以下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    A[ルール/テンプレート/成果物参照: pmbok_*.mdc, flow_assist.mdc] --&amp;gt;|トリガー/チャットコマンド| B[Draft生成]
    B --&amp;gt;|human review + 確定反映| C[Stock: 確定済みドキュメント]
    
    subgraph マスタールール
    A
    end
    
    subgraph 作業ディレクトリ
    B[Draft: Flow/YYYYMM/YYYY-MM-DD/]
    end
    
    subgraph 成果物格納
    C[Stock/programs/PROGRAM/projects/PROJECT/]
    end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;要するに、事前に定義されたルールやテンプレートを使って一時的な文書（Draft）を生成し、人間がレビューした後に確定版（Stock）として保存するというワークフローです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/miyatti777/aipm_v0/blob/main/README.md&quot;&gt;README&lt;/a&gt;を読んだのですが、いろいろな知見、理論が組み込まれています。すぐに理解するのは難しいのでサラッと読んで以下の実行例を見てみると雰囲気をつかめると思います。&lt;/p&gt;
&lt;h2&gt;ケーススタディ：社内プロジェクトへの適用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;プロジェクトテーマ&lt;/strong&gt;:
「オンラインで完結する定性調査プラットフォームの構築」&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;背景&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;既存の定性調査プロセスにおける課題（時間、コスト、地理的制約など）&lt;/li&gt;
&lt;li&gt;オンライン化による効率化とリーチ拡大の期待&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AI PM (aipm_v0) を使った実践:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;プロジェクトの起案 (aipm_v0へのインプット作成)&lt;/li&gt;
&lt;li&gt;AIによるタスク分解とスケジュール案の生成&lt;/li&gt;
&lt;li&gt;生成された計画の評価と調整&lt;/li&gt;
&lt;li&gt;開発管理のシミュレーション&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ここ以降の流れで作ったドキュメント類はこちらにpushしてあります。こちらを見たほうがわかりやすいかも。
https://github.com/matsubo/aipm_v0_qualitative_research&lt;/p&gt;
&lt;h3&gt;0. 初期設定&lt;/h3&gt;
&lt;p&gt;リポジトリをcloneし、初期セットアップスクリプトを実行します。
これは、メインとなるルールのダウンロードとサンプルとなるプロジェクトのダウンロードが行われます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone git@github.com:miyatti777/aipm_v0.git
cd aipm_v0
./setup_workspace_simple.sh setup_config.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;本来はこのあたりをカスタマイズする必要がありますが、今回はそのまま使用します。
以下のディレクトリ構成が作られました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ tree .cursor/
.cursor/
└── rules
    └── basic
        ├── 00_master_rules.mdc
        ├── 01_pmbok_initiating.mdc
        ├── 02_pmbok_discovery.mdc
        ├── 02_pmbok_research.mdc
        ├── 03_pmbok_planning.mdc
        ├── 04_pmbok_executing.mdc
        ├── 05_pmbok_monitoring.mdc
        ├── 06_pmbok_closing.mdc
        ├── 07_task_management.mdc
        ├── 08_pmbok_flow_assist.mdc
        ├── 09_pmbok_development.mdc
        ├── 90_rule_maintenance.mdc
        ├── pmbok_paths.mdc
        └── templates
            ├── daily_tasks_template.md
            ├── meeting_minutes_template.md
            └── weekly_review_template.md
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;❯ tree
.
├── Archived
│   └── projects
├── Flow
│   └── 202505
│       └── 2025-05-08
├── README.md
├── scripts
│   └── test.sh
├── setup_config.sh
├── setup_workspace_simple.sh
└── Stock
    └── programs
        ├── 夕食作り
        │   └── projects
        │       └── カレー
        │           ├── documents
        │           │   ├── 1_initiating
        │           │   │   └── project_charter.md
        │           │   ├── 2_discovery
        │           │   │   ├── persona.md
        │           │   │   ├── problem_statement.md
        │           │   │   └── solution_definition.md
        │           │   ├── 3_planning
        │           │   │   ├── backlog
        │           │   │   │   ├── backlog.yaml
        │           │   │   │   ├── epics.yaml
        │           │   │   │   └── stories
        │           │   │   │       └── US-001.md
        │           │   │   ├── roadmap
        │           │   │   │   └── product_roadmap.md
        │           │   │   └── wbs.md
        │           │   └── 4_executing
        │           │       ├── daily_tasks
        │           │       │   └── daily_tasks_2025-05-05.md
        │           │       └── sprint_goals
        │           │           └── sprint_goals_1.md
        │           └── README.md
        └── Common
            └── Public
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cursor用のProject Ruleで書かれています。&lt;/p&gt;
&lt;p&gt;Cursor要のProject Ruleとmdcの説明は以下を参照。&lt;/p&gt;
&lt;p&gt;https://zenn.dev/channnnsm/articles/0df0ea29d63be3&lt;/p&gt;
&lt;p&gt;私はCursorを使用していないため、Clineで代用します。&lt;em&gt;Clineもmdcで書かれたProject Ruleを理解してくれます。&lt;/em&gt;
LLMには、最近筆者が気に入っているGemini 2.5 Proを使用します。&lt;/p&gt;
&lt;p&gt;Custom Instructionには、&lt;code&gt;aipm_v0&lt;/code&gt; のREADMEにある手順に従い、以下の情報を入力しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#========================================================
# 0. ベースポリシー
#========================================================
! Always respond in 日本語
- 成果物はできるだけファイルとして出力（細かく分割）
- MCP やファイル閲覧など可能な作業は自律実行
- タスク依頼時は不足情報を確認し、自ら計画→ゴールまで進行
- 立てた計画はタスクリストとして提示
- 日付に関する処理をやるときは、必ずdate関数で正確な情報を確認

#========================================================
# 1. 必須ルールファイル参照（pre‑load）
#========================================================

required_rule_files:
  - .cursor/rules/basic/
  - .cursor/rules/basic/01_pmbok_initiating.mdc
  - .cursor/rules/basic/03_pmbok_planning.mdc
  - .cursor/rules/basic/04_pmbok_executing.mdc
  - .cursor/rules/basic/02_pmbok_discovery.mdc
  - .cursor/rules/basic/02_pmbok_research.mdc
  - .cursor/rules/basic/pmbok_paths.mdc
  - .cursor/rules/basic/06_pmbok_closing.mdc
  - .cursor/rules/basic/90_rule_maintenance.mdc
  - .cursor/rules/basic/09_pmbok_development.mdc
  - .cursor/rules/basic/templates
  - .cursor/rules/basic/templates/daily_tasks_template.md
  - .cursor/rules/basic/templates/meeting_minutes_template.md
  - .cursor/rules/basic/templates/weekly_review_template.md
  - .cursor/rules/basic/00_master_rules.mdc
  - .cursor/rules/basic/07_task_management.mdc
  - .cursor/rules/basic/08_pmbok_flow_assist.mdc
  - .cursor/rules/basic/05_pmbok_monitoring.mdc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-08-23-55-44.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;1. 立ち上げ&lt;/h3&gt;
&lt;p&gt;これは、プロジェクトの初期設定に相当します。&lt;/p&gt;
&lt;p&gt;READMEの指示通りに、プロジェクトのドキュメントを構築するためのコマンドを実行します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-00-01-08.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最初にプロジェクト名を尋ねられるため、以下のように入力しました。 このプロジェクトは、筆者が所属する企業の創業時に考案したシステムの内容です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;オンラインで定性調査するプラットフォームサービスの構築&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;10年近く前に考案した内容ですが、企画立案からサービスローンチ、運用、機能開発まで一通り経験したサービスであるため、LLMの出力と実際の経験との差分を比較しながら評価しやすいと考え、これを選定しました。&lt;/p&gt;
&lt;p&gt;次に、&quot;プロジェクトの背景と目的&quot; を尋ねられました。 背景を説明すると長くなるため、今回はGemini 2.5 Proに生成を依頼しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 背景

1.  **地理的・時間的制約の克服:**
    * 従来の対面でのインタビューやグループ調査では、参加者が特定の場所に集まる必要があり、地理的な制約や移動に伴う時間的・経済的コストが発生していました。特に、広範囲な地域からの意見収集や、多忙な参加者へのアプローチが困難でした。
    * オンライン化により、居住地に関わらず多様な参加者を集めることが可能になり、日程調整の柔軟性も向上します。

2.  **コスト効率の改善:**
    * 会場費、交通費、謝礼以外の運営コスト（人件費の一部など）を削減できる可能性があります。
    * これにより、従来は予算的に難しかった小規模な調査や、頻繁な調査実施のハードルが下がります。

3.  **多様な参加者へのアクセス:**
    * ニッチなターゲット層や、特定の属性（例：子育て中の親、特定の疾患を持つ患者、地方在住者など）を持つ人々にも、オンラインであればリーチしやすくなります。
    * 匿名性を確保しやすいオンライン環境は、デリケートなテーマに関してより率直な意見を引き出せる可能性も秘めています。

4.  **デジタルトランスフォーメーション（DX）の流れ:**
    * あらゆる業界でDXが加速しており、マーケティングリサーチの分野も例外ではありません。企業はより迅速かつ効率的なデータ収集・分析手法を求めています。
    * オンラインツールを活用した業務効率化は、現代のビジネスにおける標準となりつつあります。

5.  **新しい生活様式と働き方の定着:**
    * 新型コロナウイルス感染症のパンデミック以降、オンラインコミュニケーションが一般化し、人々はオンラインでの活動に慣れ親しんでいます。
    * リモートワークの普及などにより、オンラインでの調査参加への心理的な抵抗感も低減していると考えられます。

6.  **テクノロジーの進化:**
    * 高品質なビデオ会議システム、チャットツール、オンラインホワイトボード、AIを活用した文字起こしや感情分析ツールなどが登場し、オンラインでも質の高い定性調査を実施できる環境が整ってきました。
    * これらの技術を活用することで、対面調査に近い、あるいはそれ以上の体験価値を提供できる可能性があります。

# 目的

1.  **より多くの企業・組織に定性調査の機会を提供:**
    * 地理的・時間的・コスト的な制約を軽減することで、これまで定性調査の実施をためらっていた企業や組織（特に中小企業やスタートアップ、地方の団体など）にも、その活用を促進します。
    * これにより、顧客理解を深め、より的確な意思決定を行うためのインサイト獲得を支援します。

2.  **調査プロセスの効率化と迅速化:**
    * 参加者の募集・スクリーニング、インタビューやグループディスカッションの実施、記録・分析といった一連のプロセスをプラットフォーム上で一元管理できるようにし、調査担当者の負担を軽減します。
    * 従来よりも短期間で調査を完了させ、スピーディーな意思決定に貢献することを目指します。

3.  **質の高いインサイトの獲得支援:**
    * 多様なバックグラウンドを持つ参加者からの、より本質的で深層心理に迫る意見を効率的に収集できる環境を提供します。
    * 動画や音声、テキストデータだけでなく、チャットログ、画面共有、オンラインホワイトボード上の共同作業など、多様な形式のデータを収集・分析できる機能を提供し、より多角的な分析を可能にします。

4.  **新しい調査手法の開拓と提供:**
    * オンラインならではの特性を活かした新しい定性調査手法（例：非同期型インタビュー、オンラインエスノグラフィ、バーチャル空間でのグループディスカッションなど）を開発・提供し、定性調査の可能性を広げます。
    * AIなどの最新技術を積極的に取り入れ、データ分析の高度化や効率化を図ります。

5.  **ユーザーフレンドリーなプラットフォームの実現:**
    * 調査依頼者、調査実施者（モデレーター）、調査参加者のそれぞれにとって、直感的で使いやすいインターフェースと体験を提供します。
    * セキュリティとプライバシー保護にも万全を期し、安心して利用できる環境を構築します。

6.  **定性調査市場における新たな価値創造:**
    * 既存の調査手法の課題を解決し、オンラインの強みを最大限に活かすことで、定性調査市場において独自のポジションを確立し、新たな価値を提供することを目指します。
    * 将来的には、収集された定性データのナレッジベース化や、他のデータとの連携による新たなインサイト創出なども視野に入れる可能性があります。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;コアな部分や、課題の核心を突くような深みはまだ見られませんが、もっともらしい立派な文章を生成してくれます。スコープや表面的な内容は適切だと思われるため、このまま進めます。
次に、「含まれる範囲」についてです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 含まれる範囲

**１．機能的な範囲（プラットフォームで何ができるか）**

* **コア機能:**
    * **オンラインインタビュー支援:** 1対1のデプスインタビューや、複数名でのグループインタビューを実施するためのビデオ通話、チャット、画面共有、録画・録音機能。
    * **参加者管理:** 調査参加者の募集（外部連携含む）、スクリーニング、スケジュール調整、インセンティブ管理支援。
    * **実査サポート:** インタビューガイドの表示、資料共有、オンラインホワイトボードなどの共同作業ツール。
    * **データ管理・簡易分析支援:** 録画データの保存・共有、自動文字起こし（外部連携または内製）、発言内容のタグ付けやコメント付与といった簡易的なコーディング機能。
* **将来的/段階的に検討する機能:**
    * より高度なテキストマイニングや感情分析機能。
    * レポーティング支援機能（簡易レポート自動生成など）。

**２．対象ユーザーの範囲（誰が使うのか、誰を対象にするのか）**

* **主な利用企業・部門:**
    * 新製品・サービス開発や既存事業の改善に取り組む企業のマーケティング部門、商品企画部門、UXリサーチャー。
    * 顧客理解を深めたいスタートアップ企業。
    * 広告代理店やコンサルティングファームのリサーチ部門。
* **調査参加者:**
    * 初期は国内の一般消費者を主な対象とし、将来的には特定の属性（BtoB、専門職など）や海外の参加者への拡張も視野に入れます。
    * リクルーティングは、クライアント保有リストの活用、提携パネル事業者との連携、SNSなどを通じた公募などを想定しています。

**３．サービス提供範囲（どこまでサポートするか）**

* **プラットフォーム提供:** 上記機能を有するSaaSとしてのプラットフォーム提供が基本となります。
* **サポート体制:**
    * システムの利用方法に関するテクニカルサポート。
    * 初期導入時のオンボーディング支援。
* **オプション/将来検討:**
    * 調査設計のコンサルテーション。
    * モデレーターやリクルーティング代行などの付加サービス（自社またはパートナー連携）。
    * 多言語対応（現在は日本語を想定）。

**現時点でのスコープ外（何を含まないか）**

* オフラインでの会場手配や実査運営。
    * 大規模な定量調査の実施・分析機能。
    * 高度な専門知識を要する学術研究レベルの分析ツール（初期フェーズでは）。

**基本的な考え方**

まずは、オンラインでの定性調査を「手軽に」「効率的に」「質の高いインサイトを得られる形で」実施できるコアな機能群に絞り、利用者のフィードバックを得ながら段階的に機能拡充と対象範囲の拡大を図っていく方針です。特に、ユーザー自身が直感的に操作でき、調査の準備から実査、簡易的なデータ整理までをスムーズに行える点に注力いたします。

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、「含まれない範囲」についてです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 含まれない範囲

**１．オフラインでの調査実施および関連業務全般**

* **会場手配・運営:** インタビューやグループディスカッションのための物理的な会場の予約、設営、当日の運営サポートなどは行いません。
* **調査員の派遣:** モデレーターや書記、受付スタッフなどを現地に派遣するサービスは提供いたしません。
* **郵送調査・訪問調査の管理:** 調査票の郵送、回収管理、または調査員が対象者の自宅や職場を訪問して行う調査のロジスティクス管理は範囲外です。
    * *理由：私たちの強みはオンラインに特化しており、オフライン業務は専門外であるためです。*

**２．大規模な定量調査の機能**

* **アンケート配信システム:** 数百～数千人規模のアンケートを作成し、一斉に配信・回収・集計するような、いわゆる「定量調査」を主目的としたシステム機能は搭載していません。
* **高度な統計解析ツール:** 複雑な統計モデルを用いた分析や、多変量解析といった高度な統計処理機能は提供範囲外です。
    * *理由：本プラットフォームは、数値データで捉えきれない「なぜそう思うのか」「どのような背景があるのか」といった質的な情報を深く掘り下げることに特化しているためです。*

**３．フルサービス型のリサーチプロジェクト代行**

* **総合的な調査企画・設計コンサルティング:** お客様の課題抽出から、最適な調査手法の選定、設問設計までを全て弊社が請け負う形のコンサルティングサービスは、プラットフォームの標準機能には含まれません。
* **リサーチ実査・分析・報告書作成の完全アウトソース:** モデレーション、対象者リクルーティング、データ分析、洞察の抽出、最終報告書の作成まで、調査プロジェクト全体を丸ごと代行するサービスは、現時点では提供しておりません。
    * *理由：私たちは、お客様自身が主体的に、かつ効率的に定性調査を実施するための「ツール」と「環境」を提供することに主眼を置いています。ただし、操作サポートや一部オプション（例：提携モデレーターの紹介など）は検討可能です。*

**４．専門分野に特化した特殊な機能やサービス**

* **特定の学術研究用の高度な分析ツール:** 例えば、特定の心理学理論に基づいたコーディングシステムや、特定の生体計測データと連動するような専門性の高い分析機能は含みません。
* **法務・医療などの特定業界の厳格な規制に完全準拠した特殊機能:** 一般的なビジネス利用におけるセキュリティや個人情報保護には万全を期しますが、特定の業界（例：医療における治験データの超厳密な管理など）に特化した監査証跡機能や特殊なデータ形式への対応は、現時点では範囲外です。
* **翻訳・通訳サービス:** 多言語対応を将来的に検討する可能性はありますが、プラットフォーム利用における専門の翻訳者やリアルタイム通訳者の手配までは標準サービスに含みません。
    * *理由：汎用性と使いやすさを重視し、まずは幅広いお客様にご利用いただけるオンライン定性調査のコア機能の充実に注力するためです。*

**５．プラットフォーム利用と直接関連しない業務サポート**

* **参加者のPC環境や通信トラブルへの個別詳細サポート:** プラットフォーム自体の不具合には対応しますが、調査参加者個人のデバイス設定やインターネット環境に起因する問題解決までを弊社が全面的にサポートするわけではありません（一般的なトラブルシューティングガイドの提供などは検討します）。

これらの範囲設定は、私たちが提供するオンライン定性調査プラットフォームの中核的価値にリソースを集中させ、お客様にとって真に有用なサービスを開発・提供していくためのものです。もちろん、市場のニーズや事業の進捗に応じて、将来的に範囲を見直す可能性はございます。

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このあたりは、&lt;a href=&quot;https://ja.wikipedia.org/wiki/PMBOK&quot;&gt;PMBOK&lt;/a&gt;に準拠した内容という印象です。チャット形式で入力できるため、PMBOKの知識がなくても手軽に進められます。
次に、ステークホルダーについて尋ねられました。これについては、スタートアップの雰囲気を出すために2名としました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ステークホルダー

「ご質問ありがとうございます。私たちは現在創業前であり、ビジネス担当とCTOの2名がコアメンバーとしてMVP開発を進めています。この状況における主要なステークホルダーは、以下の通りです。

**【コアチーム（事実上の社内ステークホルダー）】**

1.  **創業者（私たち自身）:**
    * **ビジネス担当（P&amp;amp;G出身）:**
        * **役割:** プロダクトビジョン策定、事業戦略立案、顧客開発（ターゲット顧客の特定とヒアリング）、MVPの仮説検証、マーケティング戦略（初期）、資金調達準備（将来的に）、法務・会計などのバックオフィス基盤準備。
        * **関心事:** PMF（プロダクトマーケットフィット）の達成、トラクション獲得、事業の持続可能性。
    * **CTO（システム開発担当）：**
        * **役割:** 技術戦略策定、MVPのアーキテクチャ設計・開発、技術選定、開発プロセスの構築、プロダクトの品質担保、スケーラビリティの考慮。
        * **関心事:** 実現可能な技術によるMVPの迅速な構築、安定したプロダクト提供、将来の技術的負債の低減。
    * **私たち2名の共通の関心事:**
        * ユーザーの課題を解決する価値あるプロダクトの創出。
        * 迅速な意思決定と実行によるアジャイルな開発。
        * 限られたリソース（時間、資金、人的資本）の最適配分。
        * 明確なコミュニケーションと信頼に基づく強力なパートナーシップ。

**【主要な社外ステークホルダー】**

1.  **ターゲット顧客 / アーリーアダプター:**
    * **対象例:** 私たちが初期に課題解決を目指す、オンライン定性調査に強いニーズを持つ企業担当者（マーケティング、UXリサーチ、新規事業開発など）や、新しいツールを積極的に試したいと考えているリサーチャー。
    * **関わり方・重要性:** MVPの仮説検証とPMF達成のために最も重要な存在です。彼らの抱える「具体的な課題」や「既存の解決策への不満」を深くヒアリングし、MVPに対する率直なフィードバック（良い点、悪い点、改善要望）を得ることで、プロダクトを正しい方向に進化させます。デモ、試用、インタビューなどを通じて密接な関係を構築します。

2.  **（潜在的な）調査参加者:**
    * **対象例:** 上記のターゲット顧客が調査を行いたいと考える一般消費者や、特定の属性を持つ人々。
    * **関わり方・重要性:** プラットフォームの価値を成立させるために不可欠な存在です。MVP段階では、どのようにしてこれらの参加者を集め、快適かつ信頼できる調査体験を提供できるかが課題となります。ターゲット顧客が実際に調査を実施できる状態を作るために、この層への配慮も必要です。

3.  **メンター / アドバイザー:**
    * **対象例:** スタートアップ経営経験者、リサーチ業界の専門家、P&amp;amp;Gや技術系のネットワークを通じて得られる経験豊富な方々、エンジェル投資家でメンタリングも行う方など。
    * **関わり方・重要性:** 私たちの経験や知識を補完し、客観的な視点から事業戦略、プロダクト開発、市場アプローチなどについて貴重なアドバイスやフィードバックを提供してくれます。PMF達成への道のりを短縮し、致命的な間違いを避ける上で非常に重要です。積極的に探し、関係を構築すべき対象です。

4.  **（必要に応じた）技術パートナー / 外部サービス提供者:**
    * **対象例:** 特定のAPI（例: ビデオ会議、AI文字起こし）提供企業、クラウドサービスプロバイダー、フリーランスのデザイナーや専門家（短期的な協力が必要な場合）。
    * **関わり方・重要性:** MVP開発を迅速かつ効率的に進めるために、自前で全て開発するのではなく、既存の優れた技術やサービスを適切に活用する場合の協力先です。

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、予算に関する「スポンサー」についてです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# スポンサー

実質的な意味でこのプロジェクトを支え、推進している「スポンサー」は、**私たち創業者自身**であると言えます。

具体的には、以下の側面で私たちがスポンサーの役割を担っています。

1.  **資金的スポンサーとして：**
    * プロジェクトに必要な初期費用は、私たち2名が自らの資金を出し合います。予算は100万円です。つまり、自分たちのアイデアと将来性に対して、自分たち自身が最初の投資家となっている状態です。

2.  **リソース（時間・労力）提供者として：**
    * 本業以外の貴重な余暇時間をこのプロジェクトの開発と準備に充てています。これは、金銭的な投資以上に重要な「時間」と「情熱」という資源を、プロジェクトの成功のために注ぎ込んでいることを意味します。

3.  **ビジョンと推進力の源泉として：**
    * このプラットフォームのアイデア、それが解決できる課題、そして目指すべきビジョンを最も強く信じ、実現に向けて情熱を持って取り組んでいるのは、私たち自身です。プロジェクトを前進させる原動力そのものです。

言い換えれば、現時点では、**私たち自身がこのプロジェクトの最大の支援者であり、すべてのリスクを負い、その成功に向けて全面的にコミットしている**という体制です。

この自己完結的なアプローチにより、外部の意思決定プロセスに左右されることなく、迅速かつ柔軟にMVP（Minimum Viable Product）の開発と仮説検証を進めることが可能になっています。

プロダクトの開発がうまくいけば、すぐに売上が見込めるので金銭的な初期投資は登記費用とバーチャルオフィスの月額費用のみで済みます。これにより、私たちのリスクは最小限に抑えられています。


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;その後、いくつかの細かい質問に回答していきます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;プロジェクトの開始日と終了日を尋ねられたため、本日を開始日とし、6ヶ月後を終了日として設定しました。&lt;/li&gt;
&lt;li&gt;プロジェクトマネージャーは、Biz担当者としました。&lt;/li&gt;
&lt;li&gt;予算は、金銭面で10万円とし、加えて筆者の余暇時間（自己投資のため0円として計上）としました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これにより、プロジェクト憲章のドラフトが作成されました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# プロジェクト憲章
**プロジェクト名**: オンラインで定性調査を行うプラットフォームサービスの構築

## 1. 背景と目的
# 背景

1.  **地理的・時間的制約の克服:**
    * 従来の対面でのインタビューやグループ調査では、参加者が特定の場所に集まる必要があり、地理的な制約や移動に伴う時間的・経済的コストが発生していました。特に、広範囲な地域からの意見収集や、多忙な参加者へのアプローチが困難でした。
    * オンライン化により、居住地に関わらず多様な参加者を集めることが可能になり、日程調整の柔軟性も向上します。

2.  **コスト効率の改善:**
    * 会場費、交通費、謝礼以外の運営コスト（人件費の一部など）を削減できる可能性があります。
    * これにより、従来は予算的に難しかった小規模な調査や、頻繁な調査実施のハードルが下がります。

3.  **多様な参加者へのアクセス:**
    * ニッチなターゲット層や、特定の属性（例：子育て中の親、特定の疾患を持つ患者、地方在住者など）を持つ人々にも、オンラインであればリーチしやすくなります。
    * 匿名性を確保しやすいオンライン環境は、デリケートなテーマに関してより率直な意見を引き出せる可能性も秘めています。

4.  **デジタルトランスフォーメーション（DX）の流れ:**
    * あらゆる業界でDXが加速しており、マーケティングリサーチの分野も例外ではありません。企業はより迅速かつ効率的なデータ収集・分析手法を求めています。
    * オンラインツールを活用した業務効率化は、現代のビジネスにおける標準となりつつあります。

5.  **新しい生活様式と働き方の定着:**
    * 新型コロナウイルス感染症のパンデミック以降、オンラインコミュニケーションが一般化し、人々はオンラインでの活動に慣れ親しんでいます。
    * リモートワークの普及などにより、オンラインでの調査参加への心理的な抵抗感も低減していると考えられます。

6.  **テクノロジーの進化:**
    * 高品質なビデオ会議システム、チャットツール、オンラインホワイトボード、AIを活用した文字起こしや感情分析ツールなどが登場し、オンラインでも質の高い定性調査を実施できる環境が整ってきました。
    * これらの技術を活用することで、対面調査に近い、あるいはそれ以上の体験価値を提供できる可能性があります。

# 目的

1.  **より多くの企業・組織に定性調査の機会を提供:**
    * 地理的・時間的・コスト的な制約を軽減することで、これまで定性調査の実施をためらっていた企業や組織（特に中小企業やスタートアップ、地方の団体など）にも、その活用を促進します。
    * これにより、顧客理解を深め、より的確な意思決定を行うためのインサイト獲得を支援します。

2.  **調査プロセスの効率化と迅速化:**
    * 参加者の募集・スクリーニング、インタビューやグループディスカッションの実施、記録・分析といった一連のプロセスをプラットフォーム上で一元管理できるようにし、調査担当者の負担を軽減します。
    * 従来よりも短期間で調査を完了させ、スピーディーな意思決定に貢献することを目指します。

3.  **質の高いインサイトの獲得支援:**
    * 多様なバックグラウンドを持つ参加者からの、より本質的で深層心理に迫る意見を効率的に収集できる環境を提供します。
    * 動画や音声、テキストデータだけでなく、チャットログ、画面共有、オンラインホワイトボード上の共同作業など、多様な形式のデータを収集・分析できる機能を提供し、より多角的な分析を可能にします。

4.  **新しい調査手法の開拓と提供:**
    * オンラインならではの特性を活かした新しい定性調査手法（例：非同期型インタビュー、オンラインエスノグラフィ、バーチャル空間でのグループディスカッションなど）を開発・提供し、定性調査の可能性を広げます。
    * AIなどの最新技術を積極的に取り入れ、データ分析の高度化や効率化を図ります。

5.  **ユーザーフレンドリーなプラットフォームの実現:**
    * 調査依頼者、調査実施者（モデレーター）、調査参加者のそれぞれにとって、直感的で使いやすいインターフェースと体験を提供します。
    * セキュリティとプライバシー保護にも万全を期し、安心して利用できる環境を構築します。

6.  **定性調査市場における新たな価値創造:**
    * 既存の調査手法の課題を解決し、オンラインの強みを最大限に活かすことで、定性調査市場において独自のポジションを確立し、新たな価値を提供することを目指します。
    * 将来的には、収集された定性データのナレッジベース化や、他のデータとの連携による新たなインサイト創出なども視野に入れる可能性があります。

## 2. スコープ
- **含む**: # 含まれる範囲

**１．機能的な範囲（プラットフォームで何ができるか）**

* **コア機能:**
    * **オンラインインタビュー支援:** 1対1のデプスインタビューや、複数名でのグループインタビューを実施するためのビデオ通話、チャット、画面共有、録画・録音機能。
    * **参加者管理:** 調査参加者の募集（外部連携含む）、スクリーニング、スケジュール調整、インセンティブ管理支援。
    * **実査サポート:** インタビューガイドの表示、資料共有、オンラインホワイトボードなどの共同作業ツール。
    * **データ管理・簡易分析支援:** 録画データの保存・共有、自動文字起こし（外部連携または内製）、発言内容のタグ付けやコメント付与といった簡易的なコーディング機能。
* **将来的/段階的に検討する機能:**
    * より高度なテキストマイニングや感情分析機能。
    * レポーティング支援機能（簡易レポート自動生成など）。

**２．対象ユーザーの範囲（誰が使うのか、誰を対象にするのか）**

* **主な利用企業・部門:**
    * 新製品・サービス開発や既存事業の改善に取り組む企業のマーケティング部門、商品企画部門、UXリサーチャー。
    * 顧客理解を深めたいスタートアップ企業。
    * 広告代理店やコンサルティングファームのリサーチ部門。
* **調査参加者:**
    * 初期は国内の一般消費者を主な対象とし、将来的には特定の属性（BtoB、専門職など）や海外の参加者への拡張も視野に入れます。
    * リクルーティングは、クライアント保有リストの活用、提携パネル事業者との連携、SNSなどを通じた公募などを想定しています。

**３．サービス提供範囲（どこまでサポートするか）**

* **プラットフォーム提供:** 上記機能を有するSaaSとしてのプラットフォーム提供が基本となります。
* **サポート体制:**
    * システムの利用方法に関するテクニカルサポート。
    * 初期導入時のオンボーディング支援。
* **オプション/将来検討:**
    * 調査設計のコンサルテーション。
    * モデレーターやリクルーティング代行などの付加サービス（自社またはパートナー連携）。
    * 多言語対応（現在は日本語を想定）。

**現時点でのスコープ外（何を含まないか）**

* オフラインでの会場手配や実査運営。
    * 大規模な定量調査の実施・分析機能。
    * 高度な専門知識を要する学術研究レベルの分析ツール（初期フェーズでは）。

**基本的な考え方**

まずは、オンラインでの定性調査を「手軽に」「効率的に」「質の高いインサイトを得られる形で」実施できるコアな機能群に絞り、利用者のフィードバックを得ながら段階的に機能拡充と対象範囲の拡大を図っていく方針です。特に、ユーザー自身が直感的に操作でき、調査の準備から実査、簡易的なデータ整理までをスムーズに行える点に注力いたします。
- **含まない**: # 含まれない範囲

**１．オフラインでの調査実施および関連業務全般**

* **会場手配・運営:** インタビューやグループディスカッションのための物理的な会場の予約、設営、当日の運営サポートなどは行いません。
* **調査員の派遣:** モデレーターや書記、受付スタッフなどを現地に派遣するサービスは提供いたしません。
* **郵送調査・訪問調査の管理:** 調査票の郵送、回収管理、または調査員が対象者の自宅や職場を訪問して行う調査のロジスティクス管理は範囲外です。
    * *理由：私たちの強みはオンラインに特化しており、オフライン業務は専門外であるためです。*

**２．大規模な定量調査の機能**

* **アンケート配信システム:** 数百～数千人規模のアンケートを作成し、一斉に配信・回収・集計するような、いわゆる「定量調査」を主目的としたシステム機能は搭載していません。
* **高度な統計解析ツール:** 複雑な統計モデルを用いた分析や、多変量解析といった高度な統計処理機能は提供範囲外です。
    * *理由：本プラットフォームは、数値データで捉えきれない「なぜそう思うのか」「どのような背景があるのか」といった質的な情報を深く掘り下げることに特化しているためです。*

**３．フルサービス型のリサーチプロジェクト代行**

* **総合的な調査企画・設計コンサルティング:** お客様の課題抽出から、最適な調査手法の選定、設問設計までを全て弊社が請け負う形のコンサルティングサービスは、プラットフォームの標準機能には含まれません。
* **リサーチ実査・分析・報告書作成の完全アウトソース:** モデレーション、対象者リクルーティング、データ分析、洞察の抽出、最終報告書の作成まで、調査プロジェクト全体を丸ごと代行するサービスは、現時点では提供しておりません。
    * *理由：私たちは、お客様自身が主体的に、かつ効率的に定性調査を実施するための「ツール」と「環境」を提供することに主眼を置いています。ただし、操作サポートや一部オプション（例：提携モデレーターの紹介など）は検討可能です。*

**４．専門分野に特化した特殊な機能やサービス**

* **特定の学術研究用の高度な分析ツール:** 例えば、特定の心理学理論に基づいたコーディングシステムや、特定の生体計測データと連動するような専門性の高い分析機能は含みません。
* **法務・医療などの特定業界の厳格な規制に完全準拠した特殊機能:** 一般的なビジネス利用におけるセキュリティや個人情報保護には万全を期しますが、特定の業界（例：医療における治験データの超厳密な管理など）に特化した監査証跡機能や特殊なデータ形式への対応は、現時点では範囲外です。
* **翻訳・通訳サービス:** 多言語対応を将来的に検討する可能性はありますが、プラットフォーム利用における専門の翻訳者やリアルタイム通訳者の手配までは標準サービスに含みません。
    * *理由：汎用性と使いやすさを重視し、まずは幅広いお客様にご利用いただけるオンライン定性調査のコア機能の充実に注力するためです。*

**５．プラットフォーム利用と直接関連しない業務サポート**

* **参加者のPC環境や通信トラブルへの個別詳細サポート:** プラットフォーム自体の不具合には対応しますが、調査参加者個人のデバイス設定やインターネット環境に起因する問題解決までを弊社が全面的にサポートするわけではありません（一般的なトラブルシューティングガイドの提供などは検討します）。

これらの範囲設定は、私たちが提供するオンライン定性調査プラットフォームの中核的価値にリソースを集中させ、お客様にとって真に有用なサービスを開発・提供していくためのものです。もちろん、市場のニーズや事業の進捗に応じて、将来的に範囲を見直す可能性はございます。

## 3. ステークホルダー
- **スポンサー**: # スポンサー

実質的な意味でこのプロジェクトを支え、推進している「スポンサー」は、**私たち創業者自身**であると言えます。

具体的には、以下の側面で私たちがスポンサーの役割を担っています。

1.  **資金的スポンサーとして：**
    * プロジェクトに必要な初期費用は、私たち2名が自らの資金を出し合います。予算は100万円です。つまり、自分たちのアイデアと将来性に対して、自分たち自身が最初の投資家となっている状態です。

2.  **リソース（時間・労力）提供者として：**
    * 本業以外の貴重な余暇時間をこのプロジェクトの開発と準備に充てています。これは、金銭的な投資以上に重要な「時間」と「情熱」という資源を、プロジェクトの成功のために注ぎ込んでいることを意味します。

3.  **ビジョンと推進力の源泉として：**
    * このプラットフォームのアイデア、それが解決できる課題、そして目指すべきビジョンを最も強く信じ、実現に向けて情熱を持って取り組んでいるのは、私たち自身です。プロジェクトを前進させる原動力そのものです。

言い換えれば、現時点では、**私たち自身がこのプロジェクトの最大の支援者であり、すべてのリスクを負い、その成功に向けて全面的にコミットしている**という体制です。

この自己完結的なアプローチにより、外部の意思決定プロセスに左右されることなく、迅速かつ柔軟にMVP（Minimum Viable Product）の開発と仮説検証を進めることが可能になっています。

プロダクトの開発がうまくいけば、すぐに売上が見込めるので金銭的な初期投資は登記費用とバーチャルオフィスの月額費用のみで済みます。これにより、私たちのリスクは最小限に抑えられています。
- **主要ステークホルダー**: # ステークホルダー

「ご質問ありがとうございます。私たちは現在創業前であり、ビジネス担当とCTOの2名がコアメンバーとしてMVP開発を進めています。この状況における主要なステークホルダーは、以下の通りです。

**【コアチーム（事実上の社内ステークホルダー）】**

1.  **創業者（私たち自身）:**
    * **ビジネス担当（P&amp;amp;G出身）:**
        * **役割:** プロダクトビジョン策定、事業戦略立案、顧客開発（ターゲット顧客の特定とヒアリング）、MVPの仮説検証、マーケティング戦略（初期）、資金調達準備（将来的に）、法務・会計などのバックオフィス基盤準備。
        * **関心事:** PMF（プロダクトマーケットフィット）の達成、トラクション獲得、事業の持続可能性。
    * **CTO（システム開発担当）：**
        * **役割:** 技術戦略策定、MVPのアーキテクチャ設計・開発、技術選定、開発プロセスの構築、プロダクトの品質担保、スケーラビリティの考慮。
        * **関心事:** 実現可能な技術によるMVPの迅速な構築、安定したプロダクト提供、将来の技術的負債の低減。
    * **私たち2名の共通の関心事:**
        * ユーザーの課題を解決する価値あるプロダクトの創出。
        * 迅速な意思決定と実行によるアジャイルな開発。
        * 限られたリソース（時間、資金、人的資本）の最適配分。
        * 明確なコミュニケーションと信頼に基づく強力なパートナーシップ。

**【主要な社外ステークホルダー】**

1.  **ターゲット顧客 / アーリーアダプター:**
    * **対象例:** 私たちが初期に課題解決を目指す、オンライン定性調査に強いニーズを持つ企業担当者（マーケティング、UXリサーチ、新規事業開発など）や、新しいツールを積極的に試したいと考えているリサーチャー。
    * **関わり方・重要性:** MVPの仮説検証とPMF達成のために最も重要な存在です。彼らの抱える「具体的な課題」や「既存の解決策への不満」を深くヒアリングし、MVPに対する率直なフィードバック（良い点、悪い点、改善要望）を得ることで、プロダクトを正しい方向に進化させます。デモ、試用、インタビューなどを通じて密接な関係を構築します。

2.  **（潜在的な）調査参加者:**
    * **対象例:** 上記のターゲット顧客が調査を行いたいと考える一般消費者や、特定の属性を持つ人々。
    * **関わり方・重要性:** プラットフォームの価値を成立させるために不可欠な存在です。MVP段階では、どのようにしてこれらの参加者を集め、快適かつ信頼できる調査体験を提供できるかが課題となります。ターゲット顧客が実際に調査を実施できる状態を作るために、この層への配慮も必要です。

3.  **メンター / アドバイザー:**
    * **対象例:** スタートアップ経営経験者、リサーチ業界の専門家、P&amp;amp;Gや技術系のネットワークを通じて得られる経験豊富な方々、エンジェル投資家でメンタリングも行う方など。
    * **関わり方・重要性:** 私たちの経験や知識を補完し、客観的な視点から事業戦略、プロダクト開発、市場アプローチなどについて貴重なアドバイスやフィードバックを提供してくれます。PMF達成への道のりを短縮し、致命的な間違いを避ける上で非常に重要です。積極的に探し、関係を構築すべき対象です。

4.  **（必要に応じた）技術パートナー / 外部サービス提供者:**
    * **対象例:** 特定のAPI（例: ビデオ会議、AI文字起こし）提供企業、クラウドサービスプロバイダー、フリーランスのデザイナーや専門家（短期的な協力が必要な場合）。
    * **関わり方・重要性:** MVP開発を迅速かつ効率的に進めるために、自前で全て開発するのではなく、既存の優れた技術やサービスを適切に活用する場合の協力先です。

## 4. 期間・予算
| 項目 | 値 |
|------|----|
| 開始 | 2025-05-09 |
| 終了 | 2025-11-09 |
| 予算 | 金銭的なところで10万円+余暇時間（自分の時間なので0円） 万円 |

## 5. 承認
| 役割 | 氏名 | 署名 | 日付 |
|------|------|------|------|
| スポンサー | 私たち創業者自身 | | |

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これはドラフト版のため、Flowディレクトリ内で作成されます。続いて、指示通りに「確定して」と入力し、Stockディレクトリに移動させます。&lt;/p&gt;
&lt;p&gt;ディレクトリ構成は以下のようになっています。緑の文字が今回作成されたものです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-00-24-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;移動が完了すると、元のdraftファイルは自動的に削除されました。&lt;/p&gt;
&lt;p&gt;これで、プロジェクトの初期設定は完了です。&lt;/p&gt;
&lt;h3&gt;2. 発見&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-00-26-50.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;READMEの指示通りに、
&lt;code&gt;仮説マップ&lt;/code&gt;
の作成を試みます。&lt;/p&gt;
&lt;p&gt;質問とそれに対する回答は以下の通りです。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-00-36-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;生成された仮説マップは以下の通りです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-00-39-53.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;次に、&lt;code&gt;ペルソナ&lt;/code&gt; を作成します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-00-44-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;生成されたペルソナは以下の通りです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-00-44-46.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;次に、&lt;code&gt;市場規模予測&lt;/code&gt; を行います。
以下のように回答しました。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-00-50-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;すると、Web検索し、市場規模の精度を高めようとする動作が見られました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-00-51-17.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;MCP経由でWeb検索しようとしていました。MCPの設定が手間だったため、Geminiに必要な情報を収集させました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 市場規模予測

* ご要望の数値、特に「推定数」「平均回数」「年間予算」といったものは、網羅的かつ正確な公式統計が存在しない場合が多く、調査レポートによっても数値が異なることがあります。
* 企業規模、業種、マーケティング戦略、調査の目的や内容によって、これらの数値は大きく変動します。
* 東南アジアは国によって市場環境や調査文化が大きく異なるため、地域全体を一般化することは非常に困難です。

以上の点を踏まえ、現時点（2025年5月9日）で得られた情報に基づいて回答します。

**1. 国内および東南アジアにおける、定性調査を実施している企業の推定数**

* **国内:**
    * 「定性調査を実施している企業数」を直接示す、まとまった公的統計や広範な調査データを見つけることはできませんでした。
    * 参考として、一般社団法人 日本マーケティング・リサーチ協会（JMRA）の正会員社数は2021年時点で100社強でしたが、これはリサーチ専門会社の一部であり、一般事業会社でリサーチを行う企業や非加盟の会社は含まれていません。
    * 日本のマーケティングリサーチ市場全体の規模は、調査機関によって見解が異なりますが、年間2,000億円以上とする報告もあります。この市場規模から逆算して企業数を推定することも試みられますが、多くの仮定を置く必要があり、正確性は限定的です。

* **東南アジア:**
    * 東南アジア全体での「定性調査を実施している企業数」に関する信頼できる推定数を見つけることは、国内以上に困難です。各国の経済発展状況、市場の成熟度、ビジネス慣習が大きく異なるためです。
    * デジタル経済の成長は著しいものの、それが直接的に定性調査実施企業数にどう結びつくかのデータは限定的です。

**2. それらの企業が年間に実施する定性調査（インタビューやグループディスカッション）の平均回数**

* **国内・東南アジア共通:**
    * 企業が年間に実施する定性調査の「平均回数」に関する信頼性の高い統計データは、国内外ともに見つけることができませんでした。
    * これは、企業のマーケティング予算、製品開発サイクル、市場戦略、顧客理解への重視度など、多くの要因に左右されるため、一般化が非常に難しい指標です。
    * 例えば、新製品開発が多い企業や、顧客中心主義を掲げる企業では実施頻度が高い傾向にあると考えられますが、全企業をならした平均値を出すのは困難です。

**3. 1回の調査あたりの平均的な費用（外部委託の場合など）**

* **国内:**
    * 外部のリサーチ会社に委託する場合、調査手法や対象者の条件、調査規模（人数、地域など）、報告書の詳細度などによって費用は大きく変動します。
    * いくつかの情報源によると、一般的な目安としては以下のような範囲が示されています（2024年頃の情報を含む）。
        * **デプスインタビュー（1対1の深層面接）：** 1人あたり数万円～十数万円、1プロジェクトあたりでは10万円～40万円程度から。対象者のリクルーティング難易度や人数により変動。
        * **グループインタビュー（フォーカスグループ）：** 1グループ（4～6名程度）あたり数十万円から。例えば、40万円～130万円程度。モデレーターのスキル、対象者のリクルーティング、会場費などを含む。
        * **オンラインインタビュー：** オフラインに比べて会場費などが抑えられる場合がありますが、プラットフォーム利用料や対象者のリクルーティング費用は発生します。費用感としては、40万円～80万円程度という情報も見られますが、これも内容次第です。
    * これらはあくまで目安であり、実際の見積もりは個別の調査設計によって大きく変わります。

* **東南アジア:**
    * 東南アジアも国や都市によって物価水準や人件費が大きく異なるため、一概に平均費用を提示するのは困難です。
    * 一般的に、シンガポールのような先進国は費用が高くなる傾向があり、その他の国では相対的に抑えられる可能性があります。
    * リモート（オンライン）での定性調査は、従来の渡航を伴う調査に比べてコストを抑えられる可能性がありますが、現地のリクルーティング費用や通訳・翻訳費用、現地の文化や言語に精通したモデレーターの費用などが別途必要になる場合があります。

**4. オンライン調査ツールへの年間予算の推定額**

* **国内・東南アジア共通:**
    * 企業が「オンライン調査ツール（定性調査プラットフォームや関連ソフトウェアを含む）」に特化してどれくらいの年間予算を組んでいるか、という直接的かつ具体的な統計データを見つけることはできませんでした。
    * 企業のDX（デジタルトランスフォーメーション）投資やマーケティング関連ツールの予算の一部として組み込まれることが多いと考えられますが、その内訳は企業ごとに大きく異なります。
    * 参考として、日本国内の「定性データ分析ソフトウェア市場」については、2020年に約5.5億米ドル、2028年には約8.7億米ドルに成長するという予測（Verified Market Research）がありますが、これは主に分析フェーズのソフトウェア市場であり、調査実施プラットフォーム全体を指すものではありません。
    * 多くの企業では、必要に応じてプロジェクトベースでツール利用料を支払うケースや、年間契約でも他のマーケティングツールと一括で予算管理されているケースなどが考えられます。

**まとめ**

ご要望の数値について、ピンポイントでの正確な情報提供が難しく、大変申し訳ありません。
市場予測を行う上では、これらの一般的な傾向や入手可能な関連データ（市場規模、特定のソフトウェア市場の成長率など）を参考にしつつ、ご自身のサービスがターゲットとする顧客セグメントの特性や課題、支払い意欲などを個別にヒアリングや調査を通じて把握し、仮説を立てて検証していくことが重要になるかと存じます。

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下の市場規模予測が出力されました。
一部を抜粋して紹介します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-00-58-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;予測にはかなり幅があります。本来であれば、さらにイテレーションを重ねて精度を高める必要がありそうですが、今回は次へ進みます。
それにしても、これほどの内容を生成してくれるのは驚きです。&lt;/p&gt;
&lt;p&gt;Discoveryフェーズはこのあたりで終え、次に進みます。&lt;/p&gt;
&lt;h3&gt;3. リサーチ&lt;/h3&gt;
&lt;p&gt;次に、&lt;code&gt;顧客調査&lt;/code&gt; を試みます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-01-05-50.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;詳細なやり取りは長くなるため、ここでは省略します。&lt;/p&gt;
&lt;p&gt;先ほどと同様に、ヒアリング項目に回答していきます。&lt;/p&gt;
&lt;h3&gt;4. 計画&lt;/h3&gt;
&lt;p&gt;いよいよ計画フェーズです。
どのような計画が出力されるか楽しみです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-01-20-53.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下の内容が出力されました。
期待していたよりもシンプルな内容でした。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# オンラインで定性調査を行うプラットフォームサービスの構築 - 作業分解構造図 (WBS)

**プロジェクト期間:** 2025/5/9 - 2025/11/9
**プロジェクトマネージャー:** Biz担当
**作成日:** 2025-05-09
**最終更新日:** 2025-05-09

## 1. プロジェクト概要

オンラインで定性調査を行うプラットフォームサービスを構築する。

## 2. 主要デリバラブル

- インフラ構築され、アプリケーションがデプロイされた状態で、SaaSとして使える状態になっている。

## 3. WBS階層

*   **1. 機能A**
    *   1.1 スキーマ構築
    *   1.2 ビジネスロジック実装
    *   1.3 UI実装
    *   1.4 テストコード作成
*   **2. 機能B**
    *   2.1 スキーマ構築
    *   2.2 ビジネスロジック実装
    *   2.3 UI実装
    *   2.4 テストコード作成
*   **3. 機能C**
    *   3.1 スキーマ構築
    *   3.2 ビジネスロジック実装
    *   3.3 UI実装
    *   3.4 テストコード作成
*   **4. インフラ構築**
    *   4.1 環境選定・設計
    *   4.2 環境構築
    *   4.3 デプロイメントパイプライン構築
    *   4.4 監視設定
*   **5. 全体テスト**
    *   5.1 結合テスト
    *   5.2 システムテスト
    *   5.3 受入テスト支援
*   **6. プロジェクト管理**
    *   6.1 進捗管理
    *   6.2 課題管理
    *   6.3 コミュニケーション

*(注: 上記は基本的な構造例です。実際の機能名やタスクはプロジェクトに応じて詳細化が必要です)*

## 4. リソース計画

- Biz担当: プロジェクト管理、要件定義、受入テスト
- CTO: 技術選定、アーキテクチャ設計、開発リード、インフラ構築

## 5. スケジュールサマリー

- 全体期間: 2025/5/9 - 2025/11/9 (約6ヶ月)
- 各機能・タスクのスケジュールは別途詳細化が必要。

## 6. 進捗状況

- 未着手

## 7. 注記

- 本WBSは初期ドラフトであり、プロジェクト進行に伴い更新される。
- 各タスクの担当者、工数見積もり、依存関係は別途定義する。

## 8. 更新履歴

- 2025-05-09: 初版作成

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;殆どの情報が欠落してしまったので、Geminiに作ってもらいました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;**1.0 プロジェクト管理**
    1.1 プロジェクト計画策定
        1.1.1 プロジェクトスコープ定義 (MVPスコープ含む)
        1.1.2 スケジュール作成・マイルストーン設定
        1.1.3 体制・役割分担定義
        1.1.4 コミュニケーション計画
    1.2 進捗管理
        1.2.1 定例ミーティング実施
        1.2.2 進捗報告書作成
        1.2.3 課題管理表作成・更新
    1.3 リスク管理
        1.3.1 リスク洗い出しと評価
        1.3.2 対応策検討・実施
    1.4 品質管理
        1.4.1 品質基準設定
        1.4.2 レビュー体制構築・実施
    1.5 予算管理 (該当する場合)

**2.0 企画・要件定義**
    2.1 市場・競合調査分析 (再確認・ドキュメント化)
    2.2 ターゲットユーザー定義・ペルソナ定義 (再確認・ドキュメント化)
    2.3 提供価値・サービスコンセプト定義 (再確認・ドキュメント化)
    2.4 ユースケース洗い出し・定義
    2.5 機能要件定義
        2.5.1 ユーザー管理機能（登録、ログイン、プロフィール等）
        2.5.2 プロジェクト管理機能（作成、設定、ステータス管理等）
        2.5.3 参加者管理機能（招待、同意取得、スケジュール調整支援等）
        2.5.4 オンラインインタビュー実施機能（ビデオ/音声通話、チャット、画面共有、録画/録音制御等）
        2.5.5 モデレーター支援機能（質問ガイド表示、タイムキーパー、メモ機能等）
        2.5.6 データ管理機能（録画データ保存・一覧・再生、チャットログ保存等）
        2.5.7 （MVP以降）文字起こし連携/機能
        2.5.8 （MVP以降）簡易分析・共有機能
        2.5.9 （SaaSの場合）プラン・決済管理機能
    2.6 非機能要件定義
        2.6.1 パフォーマンス・可用性
        2.6.2 セキュリティ（データ保護、アクセス制御等）
        2.6.3 UI/UX（ユーザビリティ、アクセシビリティ）
        2.6.4 運用・保守性
    2.7 要求仕様書作成・承認

**3.0 設計**
    3.1 システムアーキテクチャ設計
        3.1.1 全体構成図作成
        3.1.2 技術選定（言語、フレームワーク、DB等）
    3.2 UI/UX設計
        3.2.1 情報設計・画面フロー設計
        3.2.2 ワイヤーフレーム作成
        3.2.3 プロトタイプ作成・検証
        3.2.4 UIデザイン作成（デザイントークン、スタイルガイド含む）
    3.3 データベース設計
        3.3.1 ER図作成
        3.3.2 テーブル定義書作成
    3.4 API設計
        3.4.1 APIエンドポイント定義
        3.4.2 リクエスト/レスポンスフォーマット定義
    3.5 セキュリティ設計
        3.5.1 脅威分析・対策検討
        3.5.2 データ暗号化・アクセス制御方式設計
    3.6 インフラ設計 (クラウド利用前提)
        3.6.1 ネットワーク構成設計
        3.6.2 サーバー構成設計
        3.6.3 監視・バックアップ設計
    3.7 詳細設計書作成 (各機能・モジュールごと)

**4.0 開発**
    4.1 開発環境構築
        4.1.1 バージョン管理システム設定 (Git等)
        4.1.2 CI/CD環境構築準備
        4.1.3 各開発者ローカル環境構築
    4.2 バックエンド開発
        4.2.1 共通基盤開発（認証、API基盤等）
        4.2.2 機能別モジュール開発 (2.5の機能要件に基づく)
            4.2.2.1 ユーザー管理機能開発
            4.2.2.2 プロジェクト管理機能開発
            4.2.2.3 オンラインインタビューセッション管理開発
            4.2.2.4 データ永続化処理開発
            4.2.2.5 その他コア機能開発
        4.2.3 API実装
        4.2.4 （SaaSの場合）決済システム連携開発
    4.3 フロントエンド開発
        4.3.1 共通コンポーネント開発
        4.3.2 各画面開発 (UIデザインに基づく)
            4.3.2.1 ユーザー登録・ログイン画面
            4.3.2.2 ダッシュボード画面
            4.3.2.3 プロジェクト作成・管理画面
            4.3.2.4 オンラインインタビュー画面
            4.3.2.5 データ閲覧画面
            4.3.2.6 その他画面開発
        4.3.3 API連携処理実装
    4.4 外部サービス連携開発 (必要な場合)
        4.4.1 文字起こしサービス連携
        4.4.2 その他分析ツール連携

**5.0 テスト**
    5.1 テスト計画策定
        5.1.1 テスト方針・範囲定義
        5.1.2 テスト環境構築
    5.2 単体テスト (開発と並行)
        5.2.1 テストケース作成
        5.2.2 テスト実施・不具合修正
    5.3 結合テスト
        5.3.1 テストシナリオ作成
        5.3.2 テスト実施・不具合修正
    5.4 システムテスト（総合テスト）
        5.4.1 機能テスト（要求仕様書との整合性確認）
        5.4.2 非機能テスト（パフォーマンス、セキュリティ、ユーザビリティ等）
        5.4.3 テスト実施・不具合修正
    5.5 受入テスト (UAT)
        5.5.1 UATシナリオ作成 (ビジネス担当主体)
        5.5.2 UAT実施・フィードバック収集
        5.5.3 最終調整
    5.6 テスト報告書作成

**6.0 リリース準備・デプロイ**
    6.1 本番環境構築・設定
    6.2 データ移行 (必要な場合)
    6.3 リリース手順書作成
    6.4 リハーサル実施
    6.5 最終確認・承認
    6.6 本番デプロイ作業
    6.7 リリース後動作確認・モニタリング

**7.0 運用・保守 (初期フェーズ)**
    7.1 サービス監視体制構築・ツール導入
    7.2 障害対応フロー整備・訓練
    7.3 ユーザーサポート体制準備
        7.3.1 FAQ作成
        7.3.2 問い合わせ窓口設置
    7.4 定期メンテナンス計画
    7.5 フィードバック収集・分析体制
    7.6 セキュリティパッチ適用・アップデート対応

**8.0 ドキュメンテーション**
    8.1 要件定義書 (2.7で作成)
    8.2 設計書 (各種、3.0で作成)
    8.3 ソースコード・APIドキュメント
    8.4 テスト関連ドキュメント (5.0で作成)
    8.5 運用マニュアル
    8.6 ユーザーマニュアル (ヘルプドキュメント、FAQ)

**9.0 法務・規約関連**
    9.1 利用規約作成
    9.2 プライバシーポリシー作成
    9.3 特定商取引法に基づく表記 (SaaSモデルの場合)
    9.4 その他関連法規遵守確認
    9.5 （必要な場合）外部専門家（弁護士等）レビュー
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このような形で回答を進めました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-01-32-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;出力された内容は以下の通りです。&lt;/p&gt;
&lt;p&gt;epic.yaml&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# エピック定義
project_id: オンラインで定性調査を行うプラットフォームサービスの構築
epics:
  - id: &quot;E01&quot;
    title: &quot;ユーザーとアクセス管理 (User &amp;amp; Access Management)&quot;
    description: &quot;ユーザーが安全かつ適切にプラットフォームを利用するための基盤機能群。&quot;
    priority: &quot;high&quot;
    status: &quot;new&quot;
  - id: &quot;E02&quot;
    title: &quot;調査プロジェクトのライフサイクル管理 (Research Project Lifecycle Management)&quot;
    description: &quot;定性調査プロジェクト全体を効率的に管理するための機能群。&quot;
    priority: &quot;high&quot;
    status: &quot;new&quot;
  - id: &quot;E03&quot;
    title: &quot;インタビュー参加者の獲得と管理 (Participant Recruitment &amp;amp; Management)&quot;
    description: &quot;調査に適した参加者を見つけ、インタビュー実施までスムーズに管理するための機能群。&quot;
    priority: &quot;medium&quot;
    status: &quot;new&quot;
  - id: &quot;E04&quot;
    title: &quot;高度なオンラインインタビュー実行環境 (Advanced Online Interview Environment)&quot;
    description: &quot;質の高いオンラインインタビュー（1on1、グループ）を実施するためのコア機能群。&quot;
    priority: &quot;high&quot;
    status: &quot;new&quot;
  - id: &quot;E05&quot;
    title: &quot;モデレーションとオブザベーション支援 (Moderation &amp;amp; Observation Support)&quot;
    description: &quot;インタビューを円滑に進行し、観察者との連携を深めるための支援機能群。&quot;
    priority: &quot;medium&quot;
    status: &quot;new&quot;
  - id: &quot;E06&quot;
    title: &quot;インサイト抽出とデータ活用 (Insight Generation &amp;amp; Data Utilization)&quot;
    description: &quot;収集した定性データを整理・分析し、価値あるインサイトを引き出すための機能群。&quot;
    priority: &quot;medium&quot;
    status: &quot;new&quot;
  - id: &quot;E07&quot;
    title: &quot;セキュリティとコンプライアンス (Security &amp;amp; Compliance)&quot;
    description: &quot;ユーザーデータとプライバシーを保護し、法令遵守を担保するための機能群。&quot;
    priority: &quot;high&quot;
    status: &quot;new&quot;
  - id: &quot;E08&quot;
    title: &quot;サブスクリプションとアカウント請求 (Subscription &amp;amp; Account Billing) (※SaaSモデルの場合)&quot;
    description: &quot;サービス利用料金の管理と請求処理を行うための機能群。&quot;
    priority: &quot;low&quot; # MVPでは優先度低めの可能性
    status: &quot;new&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;backlog.yaml&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# プロダクトバックログ定義
project_id: オンラインで定性調査を行うプラットフォームサービスの構築
name: &quot;オンライン定性調査プラットフォーム バックログ&quot;
description: |
  その深い共感から生まれるインサイトが、より良い製品・サービス、ひいてはより良い社会を迅速に共創していく未来を実現する
product_vision: |
  その深い共感から生まれるインサイトが、より良い製品・サービス、ひいてはより良い社会を迅速に共創していく未来を実現する
priority_criteria: |
  開発効率。ユーザーストーリーを流すうえでの最初の方から。
  もし、技術的難易度が高いところがあればそのPoC。例えば、インタビューツールのWebRTCを使った実装とか。
estimation_method: &quot;Tシャツサイジング (XS, S, M, L, XL)&quot;
wbs_relation: &quot;IDで関連付け&quot;

# バックログアイテム定義 (ユーザーストーリーは別ファイルで管理し、ここでは参照のみ、または主要なもののみ記載)
items:
  # 例: エピックE01に紐づくユーザーストーリー
  - id: &quot;US-001&quot;
    title: &quot;（例）新規ユーザーとしてアカウントを作成できる&quot;
    description: &quot;初めてプラットフォームを利用するユーザーが、必要な情報を入力してアカウントを登録できるようにする。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;M&quot; # Tシャツサイズで見積もり
    epic_id: &quot;E01&quot;
    acceptance_criteria:
      - &quot;メールアドレスとパスワードで登録できる&quot;
      - &quot;登録後、確認メールが送信される&quot;
      - &quot;確認メール内のリンクをクリックするとアカウントが有効化される&quot;
    dependencies: []
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;2.5.1, 4.2.2.1, 4.3.2.1&quot; # 関連するWBS ID

  # 他のユーザーストーリーやタスクをここに追加していく
  # ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;より詳細なブレークダウンを期待しましたが、そこまでは生成されませんでした。
そのため、Geminiに別途生成させました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;project_id: オンラインで定性調査を行うプラットフォームサービスの構築
name: &quot;オンライン定性調査プラットフォーム バックログ&quot;
description: |
  あらゆる企業が、顧客一人ひとりの真実の声に、いつでも、どこからでも、深く耳を傾けられるようにする。
  そして、その深い共感から生まれるインサイトが、より良い製品・サービス、
  ひいてはより良い社会を迅速に共創していく未来を実現する。
product_vision: |
  あらゆる企業が、顧客一人ひとりの真実の声に、いつでも、どこからでも、深く耳を傾けられるようにする。
  そして、その深い共感から生まれるインサイトが、より良い製品・サービス、
  ひいてはより良い社会を迅速に共創していく未来を実現する。
priority_criteria: |
  開発効率。ユーザーストーリーを流すうえでの最初の方から。
  もし、技術的難易度が高いところがあればそのPoC。例えば、インタビューツールのWebRTCを使った実装とか。
estimation_method: &quot;Tシャツサイジング (XS, S, M, L, XL)&quot;
wbs_relation: &quot;IDで関連付け (各アイテムのwbs_id参照)&quot;

items:
  # 技術検証 (PoC) - 優先度基準に基づき最優先
  - id: &quot;TSK-E04-000&quot;
    title: &quot;WebRTCを利用したリアルタイムビデオ・音声通話機能の技術検証 (PoC)&quot;
    description: &quot;オンラインインタビュー機能のコアとなるWebRTCを用いたビデオ・音声通話について、実現可能性、パフォーマンス、必要なライブラリ/サービスを検証する。&quot;
    priority: &quot;critical&quot;
    type: &quot;task&quot;
    estimate: &quot;L&quot; # PoCは時間がかかる可能性あり
    epic_id: &quot;E04&quot;
    acceptance_criteria:
      - &quot;基本的な1対1のビデオ・音声通信がブラウザ間で確立できること&quot;
      - &quot;遅延や品質について基本的な評価が行えること&quot;
      - &quot;利用する技術スタック（ライブラリ、STUN/TURNサーバー等）の目処が立つこと&quot;
      - &quot;主要ブラウザ（Chrome, Firefox, Safari）での動作互換性を確認する&quot;
    dependencies: []
    assignee: &quot;CTO&quot; # 技術検証はCTO担当
    status: &quot;new&quot;
    wbs_id: &quot;WBS-3.1, WBS-4.2.2.3&quot; # WBSのアーキテクチャ設計や該当機能開発の前段階

  # E01: ユーザーとアクセス管理
  - id: &quot;US-E01-001&quot;
    title: &quot;新規ユーザーとしてメールアドレスとパスワードでアカウント登録できる&quot;
    description: &quot;ユーザーはサービスを利用するために、メールアドレスとパスワードを使用して新しいアカウントを作成する。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;M&quot;
    epic_id: &quot;E01&quot;
    acceptance_criteria:
      - &quot;有効なメールアドレス形式であること&quot;
      - &quot;パスワードが指定された強度（例：8文字以上、英数記号混在など）を満たしていること&quot;
      - &quot;登録ボタンをクリックすると、アカウントが作成待ち状態になる&quot;
      - &quot;登録確認メールが指定のメールアドレスに送信される&quot;
      - &quot;確認メール内のユニークなリンクをクリックすることでアカウントが有効化される&quot;
    dependencies: []
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-4.2.2.1, WBS-4.3.2.1&quot;

  - id: &quot;US-E01-002&quot;
    title: &quot;登録ユーザーとしてメールアドレスとパスワードでログインできる&quot;
    description: &quot;既存のユーザーは、登録したメールアドレスとパスワードを使用してプラットフォームにログインする。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;S&quot;
    epic_id: &quot;E01&quot;
    acceptance_criteria:
      - &quot;メールアドレスとパスワードの入力フィールドが表示される&quot;
      - &quot;有効化されたアカウントの正しい認証情報でログインボタンをクリックすると、ダッシュボードにリダイレクトされる&quot;
      - &quot;誤った認証情報や未有効化アカウントの場合は、適切なエラーメッセージが表示される&quot;
    dependencies: [&quot;US-E01-001&quot;]
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-4.2.2.1, WBS-4.3.2.1&quot;

  # E07: セキュリティとコンプライアンス (基本部分)
  - id: &quot;TSK-E07-001&quot;
    title: &quot;ユーザーパスワードはハッシュ化してデータベースに保存する&quot;
    description: &quot;セキュリティ強化のため、ユーザーが設定したパスワードは不可逆的なハッシュ関数（ソルト付き）を用いてハッシュ化し、そのハッシュ値をデータベースに保存する。&quot;
    priority: &quot;high&quot;
    type: &quot;task&quot;
    estimate: &quot;S&quot;
    epic_id: &quot;E07&quot;
    acceptance_criteria:
      - &quot;パスワード保存時に業界標準のハッシュアルゴリズム（例：bcrypt, Argon2）が使用されている&quot;
      - &quot;各ユーザーごとに異なるソルトが使用されている&quot;
      - &quot;元のパスワードがデータベースに平文で保存されていないことを確認するテストがある&quot;
    dependencies: [&quot;US-E01-001&quot;]
    assignee: &quot;CTO&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-3.5&quot;

  - id: &quot;US-E07-002&quot;
    title: &quot;ユーザーは利用規約とプライバシーポリシーに同意した上でサービスを利用開始できる&quot;
    description: &quot;新規アカウント登録時または初回ログイン時に、ユーザーはサービスの利用規約およびプライバシーポリシーを確認し、同意する。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;S&quot;
    epic_id: &quot;E07&quot;
    acceptance_criteria:
      - &quot;アカウント登録画面または初回ログイン画面に、利用規約とプライバシーポリシーへのリンクが表示される&quot;
      - &quot;内容を確認するためのモーダルウィンドウまたは別ページで規約が表示できる&quot;
      - &quot;同意チェックボックスが用意されており、チェックしないと登録/利用開始プロセスが完了しない&quot;
      - &quot;ユーザーが同意した日時と規約のバージョンが記録される（将来の監査用）&quot;
    dependencies: [&quot;US-E01-001&quot;]
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-9.1, WBS-9.2&quot;

  # E02: 調査プロジェクトのライフサイクル管理 (MVP Core)
  - id: &quot;US-E02-001&quot;
    title: &quot;ログインユーザーとして新しい調査プロジェクトを作成できる&quot;
    description: &quot;ユーザーはプラットフォーム上で新しい定性調査プロジェクトを開始するために、プロジェクト名、調査目的などの基本情報を入力して作成する。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;M&quot;
    epic_id: &quot;E02&quot;
    acceptance_criteria:
      - &quot;プロジェクト作成フォームから必須項目（例：プロジェクト名）と任意項目（例：調査目的、ターゲット属性メモ）を入力できる&quot;
      - &quot;「作成」ボタンを押すと新しいプロジェクトが生成され、そのプロジェクトのダッシュボード/詳細ページに遷移する&quot;
      - &quot;必須項目が入力されていない場合は、適切なエラーメッセージが表示され作成できない&quot;
    dependencies: [&quot;US-E01-002&quot;]
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-4.2.2.2, WBS-4.3.2.3&quot;

  - id: &quot;US-E02-002&quot;
    title: &quot;作成した調査プロジェクトの一覧をダッシュボードで確認できる&quot;
    description: &quot;ユーザーはログイン後、自身が作成または参加している調査プロジェクトのリストをダッシュボードで確認し、各プロジェクトに簡単にアクセスできる。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;S&quot;
    epic_id: &quot;E02&quot;
    acceptance_criteria:
      - &quot;ダッシュボードに、プロジェクト名、作成日（または最終更新日）、ステータス（MVPでは「進行中」など簡易的でも可）がリスト表示される&quot;
      - &quot;リスト内の各プロジェクト名をクリックすると、該当プロジェクトの詳細ページ（インタビューセッション管理など）に遷移できる&quot;
    dependencies: [&quot;US-E02-001&quot;]
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-4.3.2.2&quot;

  # E04: 高度なオンラインインタビュー実行環境 (MVP Core)
  - id: &quot;US-E04-001&quot;
    title: &quot;プロジェクトオーナーとしてオンラインインタンタビュールームを作成（予定）し、参加者用URLを発行できる&quot;
    description: &quot;調査プロジェクトの責任者は、インタビュー実施のために専用のオンラインルームをスケジュール（MVPでは即時作成でも可）し、インタビュー参加者がアクセスするためのユニークなURLを取得する。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;M&quot;
    epic_id: &quot;E04&quot;
    acceptance_criteria:
      - &quot;プロジェクト詳細画面から「新しいインタビューセッションを作成」オプションを選択できる&quot;
      - &quot;セッション名（任意）などを設定すると、ユニークな参加者用招待URLが生成・表示される&quot;
      - &quot;生成されたURLはクリップボードにコピーできる機能がある&quot;
    dependencies: [&quot;US-E02-001&quot;, &quot;TSK-E04-000&quot;] # PoCによる技術的目処が前提
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-4.2.2.3, WBS-4.3.2.4&quot;

  - id: &quot;US-E04-002&quot;
    title: &quot;インタビュアーとしてルームに入室し、1対1のビデオ・音声通話を開始できる&quot;
    description: &quot;インタビュアーは作成（予定）されたルームに入室し、マイク・カメラのテストを行った後、参加者の入室を待ってビデオ・音声によるインタビューを開始する。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;L&quot; # WebRTC実装の主要部分
    epic_id: &quot;E04&quot;
    acceptance_criteria:
      - &quot;インタビュアー用のURLまたはプロジェクト内のリンクからルームに入室できる&quot;
      - &quot;入室前にブラウザからマイクとカメラの使用許可を求められ、許可するとデバイスが有効になる&quot;
      - &quot;自分のカメラ映像のプレビューとマイク入力レベルの確認ができる&quot;
      - &quot;参加者が入室すると、その旨が通知され、通話相手（参加者）と映像・音声が双方向に通信できる状態になる&quot;
    dependencies: [&quot;US-E04-001&quot;]
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-4.2.2.3, WBS-4.3.2.4&quot;

  - id: &quot;US-E04-003&quot;
    title: &quot;インタビュアーとしてビデオ・音声通話を録画・録音できる（クライアントサイド録画も検討）&quot;
    description: &quot;インタビュアーは、インタビュー中に通話内容（ビデオと音声）をプラットフォーム上に記録する。MVPではクライアントサイドでの録画も検討し、サーバー負荷を軽減する。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;M&quot; # 録画機能
    epic_id: &quot;E04&quot;
    acceptance_criteria:
      - &quot;インタビュー画面に明確な「録画開始」「録画停止」ボタンがある&quot;
      - &quot;録画開始時に参加者にも録画中であることが明確に通知される（法的・倫理的配慮）&quot;
      - &quot;録画されたデータ（ビデオと音声）は、インタビュー終了後、プラットフォームの指定された場所にアップロード/保存される&quot;
      - &quot;録画ファイルの形式は一般的なもの（例: webm, mp4）である&quot;
    dependencies: [&quot;US-E04-002&quot;]
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-4.2.2.3, WBS-4.2.2.4&quot;

  - id: &quot;US-E04-004&quot;
    title: &quot;インタビュー参加者として発行されたURLからルームに入室し、ビデオ・音声通話に参加できる&quot;
    description: &quot;インタビューに招待された参加者は、提供されたURLを通じて簡単にインタビュールームに入室し、マイク・カメラを準備してインタビューに参加する。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;M&quot;
    epic_id: &quot;E04&quot;
    acceptance_criteria:
      - &quot;招待URLにアクセスすると、シンプルなルーム入室画面が表示される&quot;
      - &quot;ブラウザからマイクとカメラの使用許可を求められ、許可するとデバイスが有効になる&quot;
      - &quot;自分のカメラ映像のプレビューとマイク入力レベルの確認ができる&quot;
      - &quot;表示名（ニックネームなど）を入力して入室できる&quot;
      - &quot;インタビュアーと映像・音声が双方向に通信できる状態になる&quot;
    dependencies: [&quot;US-E04-001&quot;] # インタビュアーによるルーム作成が前提
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-4.3.2.4&quot;

  # E06: インサイト抽出とデータ活用 (MVP Core - 録画データの確認)
  - id: &quot;US-E06-001&quot;
    title: &quot;インタビュアーとして録画されたインタビュー動画をプラットフォーム上で再生できる&quot;
    description: &quot;インタビュー実施後、インタビュアーはプラットフォームに保存された録画データ（ビデオ・音声）をストリーミング再生し、内容を振り返る。&quot;
    priority: &quot;high&quot;
    type: &quot;story&quot;
    estimate: &quot;M&quot;
    epic_id: &quot;E06&quot;
    acceptance_criteria:
      - &quot;プロジェクト詳細ページやインタビューセッション履歴から、録画された動画ファイルにアクセスできる&quot;
      - &quot;動画ファイルを選択すると、埋め込みビデオプレーヤーで再生が開始される&quot;
      - &quot;再生、一時停止、ミュート、音量調整、プログレスバーによるシークなどの基本的な再生コントロールが利用できる&quot;
    dependencies: [&quot;US-E04-003&quot;] # 録画機能が前提
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-4.2.2.4, WBS-4.3.2.5&quot;

  # E05: モデレーションとオブザベーション支援 (MVP Minimum - あれば嬉しい機能)
  - id: &quot;US-E05-001&quot;
    title: &quot;インタビュアーとしてインタビュー中に簡易的なテキストメモを記録できる&quot;
    description: &quot;インタビュアーは、オンラインインタビュー中に気付いた点や重要な発言などを、インタビュー画面内でテキストメモとして記録する。&quot;
    priority: &quot;low&quot; # MVPでは優先度低め。 Nice to have.
    type: &quot;story&quot;
    estimate: &quot;S&quot;
    epic_id: &quot;E05&quot;
    acceptance_criteria:
      - &quot;インタビュー画面に専用のメモ入力エリアがある&quot;
      - &quot;入力したメモは自動的に保存される（または保存ボタンがある）&quot;
      - &quot;記録したメモは、インタビュー終了後、録画データと関連付けて確認できる（MVPではセッションごとのテキストとして保存でも可）&quot;
    dependencies: [&quot;US-E04-002&quot;]
    assignee: &quot;&quot;
    status: &quot;new&quot;
    wbs_id: &quot;WBS-4.2.2.3, WBS-4.3.2.4&quot; # インタビュー画面内の機能
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この辺のアウトプットはすごいです。肌感と違うところがあるので、1つ前のステップのWBSでもっとつめて検証をするのが良さそうです。&lt;/p&gt;
&lt;p&gt;まぁ、80点ぐらいなのでとりあえず先に進みます。&lt;/p&gt;
&lt;p&gt;次に、ロードマップを作成します。&lt;/p&gt;
&lt;p&gt;同様に、ヒアリング項目に回答していきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-01-45-59.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
doc_targets: [&apos;roadmap&apos;]
importance: 5
project_name: &apos;オンラインで定性調査を行うプラットフォームサービスの構築&apos;
project_id: &apos;オンラインで定性調査を行うプラットフォームサービスの構築&apos; # project_idは別途管理推奨
start_date: &apos;2025-05-09&apos;
end_date: &apos;2025-11-09&apos;
phases: &apos;3&apos; # 仮設定
---

# リリースロードマップ – オンラインで定性調査を行うプラットフォームサービスの構築

## 基本情報

**プロジェクト名**: オンラインで定性調査を行うプラットフォームサービスの構築
**作成日**: 2025/05/09
**バージョン**: v0.0.1
**作成者**: Biz担当
**最終更新日**: 2025-05-09

## 1. プロジェクト概要

オンラインで定性調査を行うプラットフォームサービスを構築する。

**プロジェクト期間**: 2025/05/09 - 2025/11/09（全体）
**MVPリリース期限**: 2025/11/09 (正式リリース目標)

### 1.1 主要目標

- プロトタイプ完成
- ステークホルダークライアントデモ (複数回)
- α版ローンチ
- β版ローンチ
- 正式リリース

### 1.2 成果物 (主要機能テーマ)

- クライアント向けダッシュボード
- パネル向け機能
- 管理者機能
- パネル募集機能
- インタビュー実施画面

## 2. 開発フェーズとマイルストーン (目標とリリース時期に基づく仮構成)

### フェーズ1: プロトタイプ開発と初期検証 (～2025/07/01)
**期間**: 2025/05/09 - 2025/07/01
**概要**: コア機能のプロトタイプ開発と内部・協力者による検証
#### 主要マイルストーン：
- M1: コア機能（インタビュー実施画面、基本認証）プロトタイプ完成 (2025/06中旬)
- M2: ステークホルダー/クライアントデモ① (2025/07/01)
#### 主要タスク：
- コア機能の技術検証(WebRTC等)
- 基本的なユーザー認証機能開発
- インタビュー画面プロトタイプ開発
- デモ準備

### フェーズ2: α版開発と限定テスト (～2025/09/01)
**期間**: 2025/07/02 - 2025/09/01
**概要**: 主要機能（クライアントダッシュボード、パネル管理基礎）を実装し、α版として限定ユーザーでテスト
#### 主要マイルストーン：
- M3: クライアント向けダッシュボード基本機能実装 (2025/07下旬)
- M4: α版ローンチ (2025/08/01)
- M5: ステークホルダー/クライアントデモ② (α版) (2025/08月中旬)
- M6: パネル管理機能基礎実装 (2025/08下旬)
- M7: β版開発開始 (2025/09/01)
#### 主要タスク：
- クライアントダッシュボード開発
- プロジェクト管理機能基礎開発
- α版テスト準備・実施・フィードバック収集
- パネル管理機能基礎開発

### フェーズ3: β版開発と公開テスト (～2025/11/09)
**期間**: 2025/09/02 - 2025/11/09
**概要**: 管理者機能、パネル募集連携などを追加し、β版として公開テスト、正式リリースへ
#### 主要マイルストーン：
- M8: 管理者機能実装 (2025/09下旬)
- M9: β版ローンチ (2025/10/01)
- M10: ステークホルダー/クライアントデモ③ (β版) (2025/10月中旬)
- M11: パネル募集機能連携 (2025/10下旬)
- M12: 正式リリース準備完了 (2025/11月初旬)
- M13: 正式リリース (2025/11/09)
#### 主要タスク：
- 管理者機能開発
- β版テスト準備・実施・フィードバック収集・改善
- パネル募集機能連携開発
- 課金システム連携 (SaaSの場合)
- 利用規約・プライバシーポリシー最終化
- 本番環境準備・デプロイ

## 3. 機能リリース計画 (テーマと時期に基づく仮構成)

### MVP1 (プロトタイプ - 2025/07/01 デモ目標)
- インタビュー実施画面 (コア機能: 1on1ビデオ通話、録画)
- ユーザー認証 (基本ログイン)

### MVP2 (α版 - 2025/08/01 ローンチ目標)
- クライアント向けダッシュボード (プロジェクト一覧、作成)
- パネル向け機能 (招待URLからの参加)
- (MVP1機能の改善)

### MVP3 (β版 - 2025/10/01 ローンチ目標)
- 管理者機能 (ユーザー管理基礎)
- パネル募集機能 (外部連携または簡易機能)
- (MVP2機能の改善)

### 正式リリース (2025/11/09 目標)
- β版からの改善
- 課金機能 (SaaSの場合)
- その他、優先度の高い機能

## 4. リソース計画

### 4.1 人的リソース
- Biz担当: プロジェクト管理、要件定義、顧客開発、テスト、ドキュメント作成
- CTO: 技術リード、アーキテクチャ設計、開発、インフラ管理、テスト

### 4.2 技術リソース
- (技術選定フェーズで決定)

### 4.3 予算計画
- 初期予算: 10万円 (登記費用、バーチャルオフィス等) + 創業者時間
- 開発ツール、クラウド費用等は別途見積もり

## 5. リスクと対策
- (別途リスク管理計画で詳細化)
    - 例: WebRTC技術習得の遅延 → PoC早期実施、外部リソース検討
    - 例: アーリーアダプター獲得の遅れ → ネットワーク活用、インセンティブ設計
    - 例: 開発リソース不足 → スコープ調整、優先順位見直し

## 6. コミュニケーション計画
- 定例ミーティング: 週1回 (Biz担当、CTO)
- ステークホルダーデモ: 各マイルストーン達成時 (ターゲット顧客、メンター等)
- ツール: (Slack, Google Workspace等を想定)

## 7. リリース準備とバリデーション
- 各リリース前にテスト計画に基づき検証を実施
- デモとフィードバック収集を繰り返し、プロダクトを改善

## 8. 承認
| 役割 | 氏名 | 署名 | 日付 |
|------|------|------|------|
| プロジェクトマネージャー | Biz担当 |  |  |
| CTO | CTO |  |  |
| (メンター/アドバイザー) | (氏名) |  |  |

## 9. 更新履歴
| 日付 | 更新者 | 変更内容 |
|------|-------|---------|
| 2025/05/09 | Biz担当 | 初版作成 |


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;実現性は無視して、とりあえず締切とWBSの内容を詰め込んだ感じになります。
最初に定義したリソースは完全に無視されているというか、LLMがあるんだから一人でもできるよね。という前提で作ってくれている気がしますね。むしろ、トップダウンでこんな感じで切ってくれたほうがこれをどう実現するかを思考するようになるので良いかもです。
言い換えれば、テックリードの意見を全く聞かないでBizサイドでトップダウンでスケジュールを切った感じです。&lt;/p&gt;
&lt;h3&gt;5. 実行&lt;/h3&gt;
&lt;p&gt;次に、&lt;code&gt;開発環境初期化&lt;/code&gt; を行います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-01-57-30.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;これについては、テクノロジースタックの選定と、関連ドキュメントを簡易的に作成するのみでした。&lt;/p&gt;
&lt;p&gt;次に、実行順序計画を作成させました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-01-56-42.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;素晴らしいことに、依存関係やビジネス価値を考慮した計画が作成されました。&lt;/p&gt;
&lt;p&gt;次に、ユーザーストーリーの実装に移ります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-01-59-33.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下のようなIssueが起票されました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-02-00-39.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ここまでくれば、あとはこの指示に従って実装を進めることになります。&lt;/p&gt;
&lt;p&gt;本日のタスクを作成させます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-02-04-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;様々なファイルを参照し、WBSなどを確認した上で、以下の内容が作成されました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-02-05-02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;作業が完了したと仮定し、タスクを更新して確定させます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-02-08-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一連の作業を終えた後のディレクトリとファイルの状況です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-02-13-05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ここまで到達するのに時間は4時間ぐらいです。ほとんどLLMの出力待ちの時間です。出力まちの時間にこの記事を同時進行で書いていました。&lt;/p&gt;
&lt;h3&gt;番外編: プレゼン資料作成&lt;/h3&gt;
&lt;p&gt;プレゼン資料を作成もできるので作ってもらいました。&lt;/p&gt;
&lt;p&gt;プロンプトはこんな感じです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-10-10-50-34.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Marpで作ってくれます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-10-10-57-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;「投資家向けにもっと細かく作って」と指示したら25枚くらいのスライドを作ってくれました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-10-11-00-00.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Marp(Markdown)で作られたファイルをPDFやPPTXにはコマンド一発で変換できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ npx @marp-team/marp-cli Flow/202505/2025-05-10/presentation_investor_modern_brown.md --pptx
[  INFO ] Converting 1 markdown...
[  INFO ] Flow/202505/2025-05-10/presentation_investor_modern_brown.md =&amp;gt; Flow/202505/2025-05-10/presentation_investor_modern_brown.pptx

❯ npx @marp-team/marp-cli Flow/202505/2025-05-10/presentation_investor_modern_brown.md --pdf
[  INFO ] Converting 1 markdown...
[  INFO ] Flow/202505/2025-05-10/presentation_investor_modern_brown.md =&amp;gt; Flow/202505/2025-05-10/presentation_investor_modern_brown.pdf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;作ったプレゼン資料はこちらにpushしてあります。
https://github.com/matsubo/aipm_v0_qualitative_research/tree/main/Stock/programs/%E6%96%B0%E8%A6%8F%E9%96%8B%E7%99%BA/projects/%E3%82%AA%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%A7%E5%AE%9A%E6%80%A7%E8%AA%BF%E6%9F%BB%E3%82%92%E8%A1%8C%E3%81%86%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E6%A7%8B%E7%AF%89/documents/4_executing/presentations&lt;/p&gt;
&lt;h2&gt;生成された計画の評価と調整&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;評価ポイント:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;タスクの網羅性: 詳細な評価には熟読が必要ですが、概観した限りでは8割程度は網羅されていそうです。&lt;/li&gt;
&lt;li&gt;依存関係の妥当性: 良好です。検討が煩雑になりがちな部分ですが、しっかりと作成されています。&lt;/li&gt;
&lt;li&gt;見積もりの現実性: LLMに慣れていないエンジニアが普通にやると厳しいかもしれないけど、LLMを使ってレバレッジできればできると思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;調整例:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;例：LLMが出力したものに対して都度評価することで、精度向上が期待できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;h3&gt;1. DifyとAI PM（ファイルベース管理）の比較&lt;/h3&gt;
&lt;p&gt;Difyでワークフローやエージェントを構築するのと同列で考えられる。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;カテゴリ&lt;/th&gt;
&lt;th&gt;メトリック&lt;/th&gt;
&lt;th&gt;Dify&lt;/th&gt;
&lt;th&gt;AI PM (ファイルベース管理)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;構築&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;容易さ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;△&lt;/strong&gt; &amp;lt;br /&amp;gt;GUIで直感的に構築できるが、機能が多く学習コストはやや高め&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;◯&lt;/strong&gt; &amp;lt;br /&amp;gt;テキストベースでシンプル、既存の知見を活かしやすい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;バージョン管理&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;△&lt;/strong&gt; &amp;lt;br /&amp;gt;プラットフォーム依存（エクスポート機能はある）&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;◎&lt;/strong&gt; &amp;lt;br /&amp;gt;Gitなどの既存のバージョン管理システムをそのまま利用可能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;カスタマイズの容易さ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;△&lt;/strong&gt; &amp;lt;br /&amp;gt;GUIの範囲内でのカスタマイズが主。コード埋め込み等も可能だが制約あり&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;◎&lt;/strong&gt; &amp;lt;br /&amp;gt;プロンプト、スクリプト、設定ファイルなど、あらゆる要素を自由に編集可能&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;利用&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;容易さ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;◯&lt;/strong&gt; &amp;lt;br /&amp;gt;GUIで操作が統一されており、非エンジニアにも比較的優しい&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;△&lt;/strong&gt; &amp;lt;br /&amp;gt;CUI操作やファイル編集が基本となるため、ある程度の慣れが必要&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;カスタマイズの容易さ&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;△&lt;/strong&gt; &amp;lt;br /&amp;gt;利用者側でのUIカスタマイズは限定的&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;◯&lt;/strong&gt; &amp;lt;br /&amp;gt;利用者が直接プロンプトや設定を調整しやすい&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;＜表の補足＞&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dify&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;構築の容易さ&lt;/strong&gt;: GUIベースでワークフローを組めるため、プログラミング知識がなくても始めやすいです。ただし、ノードの種類や設定項目が多く、使いこなすにはある程度の学習が必要です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バージョン管理&lt;/strong&gt;: Difyプラットフォーム内で変更履歴が管理される場合がありますが、Gitのように詳細なバージョン管理やブランチ運用は難しい場合があります。DSL（YAMLなど）でのエクスポート・インポート機能は存在します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;カスタマイズの容易さ（構築）&lt;/strong&gt;: 基本的にはDifyが提供するノードや機能の範囲でのカスタマイズとなります。カスタムツールとして外部APIを連携させたり、CodeノードでPython/Node.jsを記述したりもできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;利用の容易さ&lt;/strong&gt;: Web UIを通じて実行できるため、エンドユーザーにとっては比較的簡単に利用できます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;カスタマイズの容易さ（利用）&lt;/strong&gt;: エンドユーザーがワークフローの内部構造を意識せずに利用できる反面、実行時の細かい挙動をユーザー自身が調整するのは難しい場合があります（事前に設定された変数入力程度）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI PM (ファイルベース管理)&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;構築の容易さ&lt;/strong&gt;: テキストエディタとターミナルがあれば始められ、既存のシェルスクリプトやプログラミング言語の知識を活かせます。一方で、ワークフロー全体の設計や各コンポーネント間の連携は自前で考える必要があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バージョン管理&lt;/strong&gt;: プロンプト、設定ファイル、スクリプトなど、すべてがテキストファイルとして管理できるため、Gitなどの分散バージョン管理システムとの相性が非常に良いです。変更履歴の追跡、ブランチでの試行錯誤、チームでの共同編集などが容易です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;カスタマイズの容易さ（構築）&lt;/strong&gt;: プロンプトの内容、使用するLLMモデル、処理フロー、外部ツール連携など、あらゆる要素を自由に、かつ細かくカスタマイズできます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;利用の容易さ&lt;/strong&gt;: 主にCUI（コマンドラインインタフェース）での操作や、設定ファイルを直接編集する必要があるため、GUIに慣れたユーザーにとっては敷居が高い場合があります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;カスタマイズの容易さ（利用）&lt;/strong&gt;: 利用者自身がプロンプトを微調整したり、設定値を変更したりすることで、挙動を柔軟に変えやすいです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Difyより手触り感があるので、エンジニアにはフィットしそうです。なによりも一元管理できたりもするし、もう最高かなと思います。もし、ドキュメントをpublicに出したければsubmoduleで追加して、それを外部公開用のリポジトリにしちゃえばよいでしょうし。&lt;/p&gt;
&lt;p&gt;しかも、アーキテクチャなら無料で行えます。LLMへの課金だけで終わる！&lt;/p&gt;
&lt;h3&gt;2. 応用ユースケース&lt;/h3&gt;
&lt;p&gt;PMなどのマネジメント業務をすごい雑にブレークダウンするといかになると考えています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;マネジメント業務 = 理論 x 環境&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;そう考えるとマネジメント業務って、ピンキリで大量に存在するのでどのレベルでもこの設計を応用できると考えられます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;拡大して使う場合
&lt;ul&gt;
&lt;li&gt;会社経営&lt;/li&gt;
&lt;li&gt;戦略コンサルティング&lt;/li&gt;
&lt;li&gt;研究開発&lt;/li&gt;
&lt;li&gt;銀行のシステム移行プロジェクト(青い銀行のシステム移管プロジェクトとかのドキュメントを食わせてみたい)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;縮小して使う場合
&lt;ul&gt;
&lt;li&gt;調査票作成&lt;/li&gt;
&lt;li&gt;既存の開発プロジェクトに入れる&lt;/li&gt;
&lt;li&gt;機能開発のissue作成&lt;/li&gt;
&lt;li&gt;見積書作成&lt;/li&gt;
&lt;li&gt;プレゼン資料作成&lt;/li&gt;
&lt;li&gt;Blog記事作成&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. LLMを使ったアセットの概念の提唱&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;aipm_v0&lt;/code&gt; の根幹にあるワークフローのモデルを図にすると以下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;stateDiagram-v2
    [*] --&amp;gt; FileAsset
    FileAsset --&amp;gt; WorkingDesk: read
    WorkingDesk --&amp;gt; WorkingDesk: edit
    WorkingDesk --&amp;gt; FileAsset: add or update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このフローは、何ら新しい概念ではなは日常のオフィスワークと同じ考え方です&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ファイルキャビネット → 作業机&lt;/strong&gt;：必要な書類をキャビネットから取り出して、作業机に広げる&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;作業机で編集&lt;/strong&gt;：書類に赤ペンで修正を入れたり、内容を整理したりする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;作業机 → ファイルキャビネット&lt;/strong&gt;：完成した書類をきちんとフォルダに入れて保管する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;LLMはこの「作業机」の役割を果たし、私たちのファイル資産を活用して編集作業をサポートしてくれます。この方法なら編集履歴も残せるため、チームでの作業にも最適です。&lt;/p&gt;
&lt;p&gt;また、コンピュータのアーキテクチャと同じ考え方です。ストレージ（ハードディスク）からRAM（メモリ）にデータを読み込み、CPUで処理して、また保存するという流れそのものです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ファイルシステム（ストレージ）&lt;/strong&gt; = プロジェクトの資産を保管する場所&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLMの作業領域（メモリ）&lt;/strong&gt; = 一時的に情報を展開し、加工する場所&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;人間の判断（CPU）&lt;/strong&gt; = 内容を確認し、意思決定する処理装置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この単純でありながら強力なモデルが、何十年もの間コンピュータの基本設計として機能してきたように、LLMを活用したドキュメント非常に適していることがわかります。&lt;/p&gt;
&lt;h3&gt;4. 新たな作業方法の可能性&lt;/h3&gt;
&lt;p&gt;AI PMからの質問に対し、Geminiに回答を生成させていると、まるでAI同士が対話（A2A: AI to AI）しているような感覚でした。実際には間に人間（Human）が介在しているため、A2H2A（AI to Human to AI）といった構図です。
人間はコピー&amp;amp;ペーストとクオリティチェック、問題が起きたときの介入といった作業に専念できました。&lt;/p&gt;
&lt;p&gt;左画面にCline（AI PM）、右画面にCopilot（Gemini）という構成で作業を進めました。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-01-54-09.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;まるで「Vibe PM」のような感覚&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;いわゆる「Vibe Coding」（AI補助のもとでコーディングする新たな開発スタイル）ならぬ「Vibe PM」とでも呼べる新しいプロジェクト管理の形が見えてきました。AIとの対話を通じて、プロジェクトの立ち上げから計画、実行までをスムーズに進められることで、従来のプロジェクト管理の概念が大きく変わりつつあります。&lt;/p&gt;
&lt;p&gt;人間はビジョンと判断を提供し、AIが実務的なドキュメント作成や計画立案をサポートする—このコラボレーションが、これからのプロジェクト管理の標準になるかもしれません。&lt;/p&gt;
&lt;h3&gt;5. 構成はいたってシンプル&lt;/h3&gt;
&lt;p&gt;自分でも同じものを作りたいとなった時。難しそうに思うかもしれませんが、中身はとてもシンプル。ここまでシンプルにエッセンスを抽出して最低限の指示でこのようなモデルを作った&lt;a href=&quot;https://x.com/miyatti&quot;&gt;みやっち&lt;/a&gt;氏はすごいと思った。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;aipm_v0&lt;/code&gt; の中身はこれだけ&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-08-23-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中身の説明&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;グラウンドルールのファイル
&lt;ul&gt;
&lt;li&gt;1つだけ&lt;/li&gt;
&lt;li&gt;今回は1200行程度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;知識のファイル
&lt;ul&gt;
&lt;li&gt;PMBOKなどの理論に即したワークフローの定義軍&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;テンプレ
&lt;ul&gt;
&lt;li&gt;知識のファイルからテンプレ性の高い部分だけ外に出した&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;mdcフォーマットで作る。&lt;/p&gt;
&lt;p&gt;00_master_rules.mdcの抜粋。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--
description: 
globs: 
alwaysApply: true
---
path_reference: &quot;basic/pmbok_paths.mdc&quot;

master_triggers:


  #-----
  # プロジェクト初期化フェーズ
  #-----
  - trigger: &quot;(プロジェクト初期化|プロジェクト開始|プロジェクト立ち上げ)&quot;
    priority: high
    steps:
      - name: &quot;start_info_collection&quot;
        action: &quot;call basic/01_pmbok_initiating.mdc =&amp;gt; project_init_questions&quot;
        message: &quot;プロジェクト初期化に必要な情報を収集します。以下の質問に回答してください。&quot;
      - name: &quot;wait_user_responses&quot;
        action: &quot;wait_for_all_answers&quot;
        message: &quot;必要な回答が揃うまで先に進みません。&quot;
      - name: &quot;confirm_project_creation&quot;
        action: &quot;confirm&quot;
        message: &quot;以下の内容でプロジェクトを初期化します：\n\nプログラム: {{program_id}}\nプロジェクト: {{project_id}}\n\nよろしいですか？&quot;
      - name: &quot;create_program_dir&quot;
        action: &quot;execute_shell&quot;
        command: &quot;mkdir -p {{dirs.programs}}/{{program_id}}&quot;
        message: &quot;プログラムディレクトリを作成します...&quot;
      - name: &quot;create_project_dir&quot;
        action: &quot;execute_shell&quot;
        command: &quot;mkdir -p {{patterns.project_dir}}&quot;
        message: &quot;プロジェクトディレクトリを作成します...&quot;
      - name: &quot;create_document_dirs&quot;
        action: &quot;execute_shell&quot;
        command: &quot;mkdir -p {{patterns.doc_initiating}} {{patterns.doc_discovery}} {{patterns.doc_research}} {{patterns.doc_planning}} {{patterns.doc_executing}} {{patterns.doc_monitoring}} {{patterns.doc_closing}}&quot;
        message: &quot;プロジェクト文書ディレクトリを作成します...&quot;
      - name: &quot;create_readme&quot;
        action: &quot;create_markdown_file&quot;
        path: &quot;{{patterns.project_dir}}/README.md&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめと今後の展望&lt;/h2&gt;
&lt;h3&gt;AI PMの可能性と意義&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;プロジェクト管理の変革&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI PMは単なる自動化ツールではなく、プロジェクト管理の思考プロセスそのものを拡張する可能性を秘めています。特に &lt;code&gt;aipm_v0&lt;/code&gt; のようなファイルベースのアプローチは、既存の開発フローと親和性が高く、導入障壁が低いという利点があります。&lt;/li&gt;
&lt;li&gt;PMBOKに準拠した体系的なアプローチにより、大規模プロジェクトの立ち上げから実行までを一貫してサポートできることが実証されました。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;多様なユースケース&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;今回のケーススタディで示したように、スタートアップの新規サービス構築のような複雑なプロジェクトに適用できます。&lt;/li&gt;
&lt;li&gt;さらに、会社経営や戦略コンサルティングといった大規模な領域から、調査票作成やissue作成といった小規模なタスクまで、スケーラブルに活用できる柔軟性を持っています。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;「aipm_v0」の実践から得られた知見&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;良かった点&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flow（ドラフト）とStock（確定版）というシンプルながら効果的なワークフローは、アイデアの発散と収束を自然に促進します。&lt;/li&gt;
&lt;li&gt;プロジェクト初期化のヒアリングプロセスは、主観に偏りがちな計画立案を客観的な視点で補完し、より堅牢なプロジェクト基盤の構築に貢献します。&lt;/li&gt;
&lt;li&gt;LLMとの対話を通じて、プロジェクト管理の理論と実践を学ぶ教育的側面も見出せました。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;改善の余地&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一部のステップで出力内容が大幅に欠落するケースが見られました。これはLLMの制約によるものですが、分割処理などの工夫で改善できる可能性があります。&lt;/li&gt;
&lt;li&gt;プロジェクトの規模や特性に応じて、生成するドキュメントをより柔軟に選択・カスタマイズできる仕組みがあると実用性が高まるでしょう。&lt;/li&gt;
&lt;li&gt;複数のLLMを組み合わせた「A2A（AI to AI）」連携の自動化により、人間の介在をさらに減らせる可能性があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;新たな働き方の展望&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;「Vibe PM」の可能性&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;今回の実験で垣間見えた「Vibe PM」とも呼べる新しいプロジェクト管理のスタイルは、AIと人間の協働による新たな働き方を示唆しています。&lt;/li&gt;
&lt;li&gt;人間はビジョンと判断を提供し、AIが実務的なドキュメント作成や計画立案をサポートするという役割分担により、創造的な業務に集中できる環境が実現できるでしょう。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;LLMを活用したアセット管理の普及&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ファイルシステム（ストレージ）、LLMの作業領域（メモリ）、人間の判断（CPU）という単純かつ強力なモデルは、今後のナレッジワークの基本設計として広く採用される可能性があります。&lt;/li&gt;
&lt;li&gt;このモデルはGitなどの既存のバージョン管理システムとの親和性も高く、チーム開発においても大きな価値を発揮するでしょう。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;今後の発展方向&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;技術的な発展&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;より大きなコンテキストウィンドウを持つLLMの登場により、複雑なプロジェクト全体を一度に把握・処理できるようになれば、AI PMの能力はさらに向上するでしょう。&lt;/li&gt;
&lt;li&gt;専門分野に特化したファインチューニングモデルの開発により、特定の業界や領域に最適化されたAI PMツールが登場する可能性があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自動化と連携の拡張&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub Actionsなどの自動化ツールと連携することで、AI PMの活用範囲が大きく広がります。例えば：
&lt;ul&gt;
&lt;li&gt;毎朝の定期実行により、プロジェクトの進捗状況を自動的に分析し、チームメンバーに今日のタスクリストをSlackやメールで配信&lt;/li&gt;
&lt;li&gt;コードリポジトリの変更を検知して、自動的にドキュメントの更新や課題の進捗状況の更新を提案&lt;/li&gt;
&lt;li&gt;スプリントの終了時に自動的に振り返りレポートを生成し、次のスプリント計画の素案を提示&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;これらの自動化により、プロジェクト管理の多くの定型業務が効率化され、PMはより戦略的な意思決定に集中できるようになります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;社会的な影響&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI PMの普及により、これまでプロジェクト管理の専門知識を持たなかった個人や小規模チームでも、高品質なプロジェクト管理が可能になります。&lt;/li&gt;
&lt;li&gt;一方で、プロジェクトマネージャーの役割は、AIとの協働を前提とした新たなスキルセットへと進化していくことが予想されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;みやっち氏が開発した &lt;code&gt;aipm_v0&lt;/code&gt; は、そのシンプルな構成ながらも強力な機能を持ち、LLM を活用したプロジェクト管理の新たな地平を切り開くものです。今後、このようなアプローチがさらに洗練され、様々な領域で活用されることで、知識労働の生産性と創造性が大きく向上することを期待しています。&lt;/p&gt;
&lt;p&gt;この AI PM を作り込んでいけばこの状態になりそうだなと思いました。
&lt;img src=&quot;../../assets/uploads/2025/05/2025-05-09-11-29-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>日立洗濯機C09エラーを無料修理 | BD-SX110CL</title><link>https://blog.teraren.com/posts/2025-04-26-hitachi-sentakuk-c09/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2025-04-26-hitachi-sentakuk-c09/</guid><description>5年使用の日立洗濯機BD-SX110CLでC09エラー（ドアロック故障）が発生。メーカー修理を依頼したところ、ドアロック部品交換・パッキン交換・ファームアップが無料で対応された体験記。</description><pubDate>Sat, 26 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;問題の発生&lt;/h2&gt;
&lt;p&gt;5年前くらいに買った日立の洗濯乾燥機が調子悪くなってきました。&lt;/p&gt;
&lt;p&gt;ドアがちゃんと閉まっているのに**C09エラー（ドアロック故障）**が出て洗濯が始まらない！&lt;/p&gt;
&lt;p&gt;DIYで治せれば良いなぁと思っていたけど部品交換やファームアップ（ソフトウェア更新）による対処が普通のようなので諦めて修理依頼をしました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_1002.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_1003-1-1024x769.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;機種情報&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;型番&lt;/strong&gt;: BD-SX110CL（日立ビッグドラム）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用頻度&lt;/strong&gt;: 平均年300回（約5年で1,500回）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;使用状況&lt;/strong&gt;: 3分の2は洗濯乾燥モード&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;メンテナンス&lt;/strong&gt;: オーバーホールなし、洗濯槽クリーニングは年1回程度&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;修理依頼&lt;/h2&gt;
&lt;p&gt;ウェブから訪問修理受付をして、希望日を入力しました。最短で2日後だったので2日後に予約しました。&lt;/p&gt;
&lt;p&gt;当日の朝まで折り返しや、時間の連絡がないので少し不安でしたが、朝9時ごろに電話が来て時間を調整して、時間が決定する流れでした。&lt;/p&gt;
&lt;p&gt;その時間に1人の作業員がやってきました。&lt;/p&gt;
&lt;h2&gt;修理作業&lt;/h2&gt;
&lt;p&gt;大きな箱と工具を持ってきました。C09エラーとだけ書くだけで、交換する部材が決まっているくらい当たり前の問題っぽい！&lt;/p&gt;
&lt;p&gt;30分ほど洗濯機を分解したりして作業して完了しました。手元には一切紙が残っていないのでよくわかりませんが、口頭で言われたのは以下の通りです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ドアロック部品の交換&lt;/li&gt;
&lt;li&gt;ドアパッキン交換&lt;/li&gt;
&lt;li&gt;ファームアップ（ソフトウェア更新）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この機種のこのくらい経過した場合はファームアップだけでは直らないので部品交換も必要とのことでした。&lt;/p&gt;
&lt;h2&gt;修理費用&lt;/h2&gt;
&lt;p&gt;注目の料金はなんと&lt;strong&gt;無料&lt;/strong&gt;！作業報告にサインをして終わりました。無料ならもっと早く依頼しておけばよかったです。&lt;/p&gt;
&lt;p&gt;また、洗濯乾燥機は内部にゴミが溜まる恐れがあるので心配と相談したら、中身をチェックしてくれました。綺麗に使っているから全く問題なしと言われました。&lt;/p&gt;
&lt;p&gt;洗濯機の耐用年数は7年で作られているとのことでした。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;日立洗濯機BD-SX110CLのC09エラーは無料修理で対応&lt;/li&gt;
&lt;li&gt;修理内容: ドアロック部品・パッキン交換、ファームアップ&lt;/li&gt;
&lt;li&gt;所要時間: 約30分&lt;/li&gt;
&lt;li&gt;修理後は問題なく稼働&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;とりあえず、これ以降は問題がないので様子見ます。ここ半年でテレビ、食洗機が壊れたので家電が壊れまくります。。。&lt;/p&gt;
</content:encoded></item><item><title>AdGuard Homeを自宅に導入してBraveブラウザでも8%の広告をブロックした</title><link>https://blog.teraren.com/posts/adguard-home/</link><guid isPermaLink="true">https://blog.teraren.com/posts/adguard-home/</guid><description>AdGuard Home は、ネットワークレベルで広告やトラッカーをブロックできる DNS キャッシュサーバーです。Pi-Holeと同じ感じです。</description><pubDate>Thu, 17 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;3秒まとめ&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;自宅で AdGuard Home を導入してみた&lt;/li&gt;
&lt;li&gt;Brave ブラウザを使っていても、&lt;strong&gt;8％の広告やトラッカーの名前解決がブロック&lt;/strong&gt;されている&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DNSの名前解決による情報漏えいを防止&lt;/strong&gt;できる&lt;/li&gt;
&lt;li&gt;DoT (DNS-over-TLS)や DoQ (DNS-over-QUIC)にも対応していて&lt;strong&gt;セキュア&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Tailscale と組み合わせて使うと、スマホや出先からも設定なしで対応できる&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;AdGuard Homeとは？&lt;/h1&gt;
&lt;p&gt;AdGuard Home は、ネットワークレベルで広告やトラッカーをブロックできる DNS キャッシュサーバーです。&lt;a href=&quot;https://pi-hole.net/&quot;&gt;Pi-Hole&lt;/a&gt;と同じ感じです。
通常のブラウザの広告ブロック拡張機能とは異なり、&lt;strong&gt;ネットワーク全体&lt;/strong&gt;で広告をブロックできるため、スマホアプリやスマート TV など、あらゆるデバイスの広告をブロックできます。&lt;/p&gt;
&lt;p&gt;自宅のネットワークに設置することで、家のすべてのデバイスの広告をまとめてブロックできるというわけです。&lt;/p&gt;
&lt;h1&gt;DHCPで振られたDNSを利用する問題&lt;/h1&gt;
&lt;p&gt;普段何気なく使っているインターネットですが、実は DNS の名前解決によって&lt;strong&gt;どこのホストに接続しているのかが第三者に漏洩してしまう&lt;/strong&gt;という問題があります。&lt;/p&gt;
&lt;p&gt;例えば、アクセスしようとしているホスト名に会社名や組織を識別する情報が含まれていると、あなたがどの会社のサービスを利用しているのか、どんなウェブサイトを見ているのかといった情報が筒抜けになってしまいます。具体的には、&lt;code&gt;login.company-name.com&lt;/code&gt; のような URL にアクセスすると、あなたがその会社のサービスを利用していることが DNS キャッシュサーバーの運営者に知られてしまうんです。&lt;/p&gt;
&lt;p&gt;参考資料:   &lt;a href=&quot;https://www.dnsops.jp/event/20190628/SD2019-DNSprivacy.pdf&quot;&gt;DNSとプライバシー&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;この問題を解決する方法として、&lt;strong&gt;ローカルで名前解決をする&lt;/strong&gt;という方法があります。しかし、これにはデメリットもあります：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;キャッシュ効率が悪くなる&lt;/strong&gt; - 同じドメインの名前解決を多くのデバイスが個別に行うことになり、効率が悪い&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リソースを消費する&lt;/strong&gt; - 各デバイスで DNS 解決のためのリソースを使うことになる&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;そこで最適な解決策となるのが、&lt;strong&gt;信頼できる安全なホストで運用されているDNSキャッシュサーバーを利用する&lt;/strong&gt;ことです。これにより、プライバシーを保ちながら効率的な名前解決が可能になります。&lt;/p&gt;
&lt;p&gt;AdGuard Home はまさにこの役割を果たしてくれるツールなんです。自宅のネットワーク内で安全に DNS サーバーを運用できるため、プライバシーを守りながら広告ブロックの恩恵も受けられるというわけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;graph TD
    subgraph &quot;AdGuard Homeを使用&quot;
        D[ユーザーのデバイス] --&amp;gt;|&quot;login.company-name.comのIPアドレスは？&quot;| E[AdGuard Home]
        E --&amp;gt;|&quot;zoneの問い合わせ&quot;| G[zoneサーバー]
        F[ルールセット] --&amp;gt;|フィルタルール| E
    end
    subgraph &quot;通常のDNS解決&quot;
        A[ユーザーのデバイス] --&amp;gt;|&quot;login.company-name.comのIPアドレスは？&amp;lt;br&amp;gt;=情報漏洩！&quot;| B[ISPのDNSキャッシュサーバー]
        B --&amp;gt;|&quot;zoneの問い合wせ&quot;| C[zoneサーバー]
    end
    
    
    style A fill:#f9d5e5,stroke:#333,stroke-width:1px
    style B fill:#eeac99,stroke:#333,stroke-width:1px
    style C fill:#e06377,stroke:#333,stroke-width:1px
    style D fill:#f9d5e5,stroke:#333,stroke-width:1px
    style E fill:#b8e0d2,stroke:#333,stroke-width:1px
    style F fill:#809bce,stroke:#333,stroke-width:1px
    style G fill:#95b8d1,stroke:#333,stroke-width:1px
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この図のように、通常の DNS 解決では、あなたのアクセスしているホスト名が ISP や第三者に漏れる可能性があります。
AdGuard Home を使うことでプライバシーを保護しながら広告ドメインをブロックできます。&lt;/p&gt;
&lt;h1&gt;なぜAdGuard Homeを導入したのか&lt;/h1&gt;
&lt;p&gt;私は Brave ブラウザを普段から使っています。Brave は&lt;strong&gt;標準で広告ブロック機能&lt;/strong&gt;が搭載されているので、かなり快適にウェブブラウジングができるんですよね。&lt;/p&gt;
&lt;p&gt;でも、「本当にすべての広告がブロックされているのかな？」という疑問がありました。そこで、ネットワークレベルでの広告ブロックを試してみようと思い、AdGuard Home を導入してみることにしました。&lt;/p&gt;
&lt;h1&gt;導入してみた結果&lt;/h1&gt;
&lt;p&gt;AdGuard Home を導入して驚いたのは、&lt;strong&gt;Braveを使っているのに8％もの広告やトラッカーの名前解決がブロック&lt;/strong&gt;されていたことです！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/2025-04-17-09-58-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ダッシュボードを見ると、全体の DNS クエリ数が 327,076 件で、そのうち 27,573 件（約 8％）がブロックされています。これは Brave ブラウザを使っていても、まだ広告やトラッカーの一部が通過していることを示しています。&lt;/p&gt;
&lt;h2&gt;上位のDNSキャッシュサーバ (upstream)&lt;/h2&gt;
&lt;p&gt;複数の upstream を設定し、ラウンドロビンでしばらく運用してみた結果です。各 DNS キャッシュサーバの応答時間が表示されるので取捨選択もしやすいです。
&lt;img src=&quot;../../assets/uploads/2025/04/2025-04-21-10-55-09.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ちなみに、upstream を設定しない場合、AdGuard Home は自身で DNS クエリを Root Hints から辿って名前解決します。
これは「フルリゾルバー」または「再帰 DNS サーバー」と呼ばれる動作です。&lt;/p&gt;
&lt;h1&gt;DNS blocklists&lt;/h1&gt;
&lt;p&gt;AdGuard Home では、DNS ブロックリストを使って広告やトラッカーをブロックします。デフォルトでは上の 2 つのリストが有効になっていますが、わたしはいくつか追加してみました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/2025-04-17-09-58-49.png&quot; alt=&quot;DNS blocklists&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ブロックリストには様々な種類があり、広告専用、トラッカー専用、マルウェア対策など、目的に応じて選べます。リストを追加するほどブロック率は上がりますが、誤検知のリスクも高まるので、バランスが大事です。&lt;/p&gt;
&lt;p&gt;追記: 自分でもトラッキングサービスの運用をしているので追加で登録したリストは幅が広すぎたため結局はデフォルトに登録されているリストと、uBlock のみを使うようになりました。&lt;/p&gt;
&lt;h1&gt;セキュリティ面の強化&lt;/h1&gt;
&lt;p&gt;AdGuard Home は DoT (DNS-over-TLS)や DoQ (DNS-over-QUIC)に対応しているので、&lt;strong&gt;DNSクエリを暗号化&lt;/strong&gt;できます。これにより、ISP や第三者からの DNS クエリの監視を防ぐことができます。&lt;/p&gt;
&lt;p&gt;通常の DNS は平文で通信するため、どのサイトにアクセスしているか漏れる可能性があります。DoT や DoQ を使えばそのリスクを減らせるので、セキュリティを重視する方には嬉しい機能ですね。&lt;/p&gt;
&lt;p&gt;TLS を利用するためにはサーバ証明書を取得する必要があるので追加でひと手間がかかります。&lt;/p&gt;
&lt;h1&gt;Tailscaleとの組み合わせ&lt;/h1&gt;
&lt;p&gt;わたしは &lt;a href=&quot;https://tailscale.com/&quot;&gt;Tailscale&lt;/a&gt;を使っています。Tailscaleを使うと、外出先からでもDNSの名前解決をVPN上で稼働しているAdGuardに投げることによってDNSのリゾルバを常時自分で動かしているホストに向けることができます。&lt;/p&gt;
&lt;p&gt;Tailscale を導入しているクライアントホストでは、DNS キャッシュサーバーとして 100.100.100.100 という仮想ネットワークの仮想 IP アドレスが使われています。このアドレスは実際のネットワークには存在せず、Tailscale 内部で使われるものです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/2025-04-17-09-59-05.png&quot; alt=&quot;Tailscaleのネームサーバー設定&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Tailscale において、DNS キャッシュサーバーは 100.100.100.100 という仮想ネットワークの仮想 IP アドレスが使われていますが、実際には DNS キャッシュサーバーを指定できるオプションがあります。そのため、AdGuard が動いているサーバーの IP アドレスを指定できます。&lt;/p&gt;
&lt;p&gt;これにより、スマホからも&lt;strong&gt;特別な設定なしで&lt;/strong&gt;AdGuard Home を使った DNS フィルタリングが可能になりました。外出先でも VPN 経由で自宅の AdGuard Home を使えるので、広告ブロックの恩恵を受けられます。&lt;/p&gt;
&lt;h1&gt;まとめ&lt;/h1&gt;
&lt;p&gt;AdGuard Home を導入してみて、Brave ブラウザを使っていても 8％もの広告やトラッカーがブロックされることがわかりました。ネットワークレベルでの広告ブロックは、ブラウザレベルの広告ブロックを補完する形で効果を発揮します。&lt;/p&gt;
&lt;p&gt;また、Tailscale と組み合わせることで、外出先でも VPN 経由で広告ブロックの恩恵を受けられるのは大きなメリットです。&lt;/p&gt;
&lt;p&gt;プライバシーやセキュリティを重視する方は、ぜひ AdGuard Home の導入を検討してみてください。設定は少し手間がかかりますが、一度設定してしまえば、家のすべてのデバイスで広告なしの快適なインターネット環境を実現できますよ！&lt;/p&gt;
</content:encoded></item><item><title>Panasonic食洗機DIY修理で3万円節約 | 水漏れ解消</title><link>https://blog.teraren.com/posts/2025-04-03-panasonic-dish-washer/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2025-04-03-panasonic-dish-washer/</guid><description>Panasonic NP-45RS7の水漏れアラームを自分で修理。原因は排水トラップのヘドロ詰まり。分解清掃で修理費用3万円を節約した手順と、定期メンテナンスの重要性を解説。</description><pubDate>Thu, 03 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;この記事について&lt;/h2&gt;
&lt;h3&gt;学べること&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Panasonicビルトイン食洗機（システムキッチンに組み込まれた食器洗い機）の水漏れアラーム原因と対処法&lt;/li&gt;
&lt;li&gt;DIY修理による3万円のコスト削減方法&lt;/li&gt;
&lt;li&gt;分解・清掃・組み立ての具体的な手順&lt;/li&gt;
&lt;li&gt;予防メンテナンスの重要性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;想定読者&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;同じ水漏れアラームエラーで困っている方&lt;/li&gt;
&lt;li&gt;修理費用を節約したい方&lt;/li&gt;
&lt;li&gt;食洗機のメンテナンス方法を知りたい方&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;前提条件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;必要工具: プラスドライバー、パイプ掃除用ブラシ（または自作可能）&lt;/li&gt;
&lt;li&gt;推定所要時間: 2-3時間（分解・清掃・組み立て含む）&lt;/li&gt;
&lt;li&gt;難易度: 中級（配管の取り扱いに注意）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;ビルトインのPanasonic食洗機を5年前から使っているのですが、稼働しだすと数分で「ピーピー」というアラート音が鳴ってしばらく動いて排水された後、停止する症状になりました。&lt;/p&gt;
&lt;p&gt;食洗機を始動してから注水中または注水後（数分後）に、&lt;strong&gt;ピーピーとアラームが鳴って、「節電」と「強力」ランプが点滅&lt;/strong&gt;します。以下の動画のような状態です。&lt;/p&gt;
&lt;p&gt;https://youtube.com/shorts/BuUP3r4Q9KQ?si=4Bm2F6wEMt4LjqYV&lt;/p&gt;
&lt;p&gt;説明書を調べると&lt;strong&gt;水漏れの警報&lt;/strong&gt;のようです。&lt;/p&gt;
&lt;p&gt;2019年9月頃から使いだしました。最初の半年間ぐらいはほぼ使わない状態でした。&lt;/p&gt;
&lt;p&gt;それから、2020年のCovid-19になって、自宅で食事をすることが多くなってそれから、1日1回から2日に1回ぐらい稼働していました。その間に、旅行や実家への帰省で使わないことも長期間あったので大体1000回ぐらい回したかと思います。&lt;/p&gt;
&lt;p&gt;型番は、Panasonic NP-45RS7（2016年発売のミドルグレードモデル）です。Panasonicのビルトイン食洗機は過去15年ほど基本構造が大きく変わっていないため、他の型番でも同様の対処法が有効な可能性があります。&lt;/p&gt;
&lt;h2&gt;修理 VS 買い替え&lt;/h2&gt;
&lt;p&gt;修理費用は、&lt;a href=&quot;https://comfortable-and-happy-life.net/2019/02/15/panasonic/&quot;&gt;2019年の記事で2万円&lt;/a&gt;とあるので5年後の&lt;strong&gt;現在は3万円&lt;/strong&gt;ぐらいになると思います。&lt;/p&gt;
&lt;p&gt;買い替えるとなると最低10万円ぐらいっぽいです。結構高いので、直せるなら直したほうが良いです。食洗機の耐用年数も大体10年っぽいので修理してもまぁ、あと5年は使えるはずです。&lt;/p&gt;
&lt;h2&gt;トラブルシューティング&lt;/h2&gt;
&lt;p&gt;すぐに元栓は閉めて、食洗機の周囲を確認してみましたが水漏れは確認できませんでした。&lt;/p&gt;
&lt;h3&gt;試行1: 電源リセット&lt;/h3&gt;
&lt;p&gt;電源を抜いて、しばらく放置して、電源を入れても症状は変化なし。&lt;/p&gt;
&lt;h3&gt;試行2: 庫内の徹底清掃&lt;/h3&gt;
&lt;p&gt;普段掃除していないところで、調子が悪くなった可能性もあるのでこの動画を参考にメーカーが推奨しないところまで頑張って掃除してみましたが、症状は変化しませんでした。&lt;/p&gt;
&lt;p&gt;https://youtu.be/Smc30e-rPEE?si=v6x0gLfjVH27kb18&lt;/p&gt;
&lt;p&gt;むしろ、この程度は1年に1回やっています。&lt;/p&gt;
&lt;h2&gt;解体&lt;/h2&gt;
&lt;p&gt;仕方がないので問題箇所を探していきます。もし、探せなかったらPanasonicのサポートに頼ろうと思って進めます。&lt;/p&gt;
&lt;p&gt;食洗機の&lt;a href=&quot;https://sumai.panasonic.jp/dishwasher/manual/pdf/201611_tori_NP-45RS7.pdf&quot;&gt;利用説明書&lt;/a&gt;を見ても大したことはないので、食洗機の&lt;a href=&quot;https://sumai.panasonic.jp/dishwasher/manual/pdf/201611_koji_NP-45MS_VS_RS7.pdf&quot;&gt;施工説明書&lt;/a&gt;をダウンロードして、逆の順番をたどれば分解できます。&lt;/p&gt;
&lt;p&gt;まずは、筐体下に2箇所ネジ止めされている箇所があるので外します。写真は外した後の状態です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0477.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;食洗機の蓋を締めた状態で、手前にぐいっと引っ張ると食洗機のユニットが抜けます。食洗機の引き出し部分が取り外せると想定していましたが、引き出し部分は筐体からは簡単に外せません。裏に給排水の配管もあるので簡単には外れないようになっています。&lt;/p&gt;
&lt;p&gt;裏には給排水、電源、アースの配管がつながっているのでユニットを無理やり引き出さないように少しずつ引き出します。&lt;/p&gt;
&lt;p&gt;この時点で、&lt;strong&gt;水が前のパネルの下からドバドバ垂れてきます&lt;/strong&gt;。センサーの故障でアラートが鳴っていることを期待していましたが、本当にで&lt;strong&gt;食洗機が漏水&lt;/strong&gt;しています。バスタオルを2枚ぐらい持ってきて水が全部出るまで前に倒して出し切りました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0476.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;給排水の配管が最低の長さになっているので完全には引き出せませんでした。作業はしづらいですが、施工のクオリティとしては良いです。最短の長さになってます。&lt;/p&gt;
&lt;p&gt;オットマンがちょうどよい高さなのでビニールシートを敷いてその上に食洗機のユニットを乗せて作業します。&lt;/p&gt;
&lt;p&gt;写真の左下に写っている黒いケーブルが付いているのが漏水検知センサーです。今回はこのセンサーによって漏水が検知されました。&lt;/p&gt;
&lt;p&gt;ユニットの底面は水浸しです。傾けると水が出てきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0480.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;給水を外そうとなるとモンキーレンチなどで外さないといけないので面倒です。なので、どうしても外さないといけない場合を除いては外さないほうが良いです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0482.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そして、はずせる部品を外したりして、掃除して、再度稼働させてみてを繰り返してました。でもやはりしばらく放置して水漏れ状態を確認すると漏れてます。&lt;/p&gt;
&lt;p&gt;そこで、&lt;strong&gt;電源を切ったときに偶然にもポンプが作動して水漏れ箇所を発見&lt;/strong&gt;できました！&lt;/p&gt;
&lt;p&gt;下の写真の赤色の部分から&lt;strong&gt;水がびちゃびちゃと漏れて&lt;/strong&gt;きていました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上の黒い蓋を外して、カプラーを外して、蓋を外しました。&lt;/p&gt;
&lt;p&gt;そしたら、&lt;strong&gt;非常に汚れた部品&lt;/strong&gt;を見つけました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0483.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;裏側。ヘドロがこびりついています。ぷにぷにしてます。コラーゲン的な感じの感触。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0484.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;蓋のパーツがこれだけ汚れているということは、下のタンクも汚いです。&lt;/p&gt;
&lt;p&gt;上の蓋を外すときに周囲にヘドロがこぼれ落ちてます。。。汚い。。。そして、タンクの下も真っ黒！5年でこの有り様。。。&lt;/p&gt;
&lt;p&gt;こんな&lt;strong&gt;下水のような水で食器を洗い続けていたことにショック&lt;/strong&gt;を受けました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0485.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;キッチンペーパーを使ってこそぎ落とします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0486.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;この左側のタンクです。実は、このタンクは食洗機庫内の排水部分に繋がっています！&lt;/p&gt;
&lt;p&gt;しかも、細いです。。。**おそらくここがヘドロで詰まって、このタンクが溢れているんだと思います。**っていうか、ほぼ確定です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0487.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;この管が細すぎて、指が入りません。熱帯魚関係で使うようなパイプ掃除用のスポンジがあればよいのですが断捨離してしまったのでありません。&lt;/p&gt;
&lt;p&gt;そこで、作りました。&lt;/p&gt;
&lt;p&gt;車の配線用にストックしている電線に食器用のニトリのスポンジを切ってくくりつけました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0489.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;理想は、以下のようなものがあるとよいです。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00H1KYFAS&quot; kw=&quot;コジット 毛づまりごっそりパイプ職人スリム&quot;}&lt;/p&gt;
&lt;p&gt;この治具を食洗機庫内にある小さい穴に入れて出し入れします。黒いヘドロがゴソゴソ出てきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/img_0488.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;出てきたヘドロは、キッチンペーパーで絡め取って捨てます。&lt;/p&gt;
&lt;p&gt;これを何度か繰り返しました。&lt;/p&gt;
&lt;p&gt;そして、&lt;strong&gt;水を庫内に入れて、排水するために乾燥モードにするというのを3回&lt;/strong&gt;ぐらい繰り返したらヘドロが出なくなりました。&lt;/p&gt;
&lt;p&gt;これできれいスッキリしました！&lt;/p&gt;
&lt;p&gt;あとは、組み付けて完了です。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;今回は、分解してわかったことではありますが、普段から以下の部分のお手入れをしておければ防げる問題でした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;この部分には汚れが堆積することがわかったので定期的にブラシを入れて掃除するのが最適な運用な気がします。&lt;/p&gt;
&lt;p&gt;おそらく、このプラスチックの部品が排水トラップ（下水の臭いが逆流しないように水を溜めておく仕組み）の役割を果たしていると考えられます。常時浸水している構造のため、ヘドロが蓄積しやすい箇所です。&lt;/p&gt;
&lt;p&gt;結果としてわかりましたが、&lt;a href=&quot;https://bbs.kakaku.com/bbs/21274010034/SortID=21947507/&quot;&gt;この書き込み&lt;/a&gt;と同じ問題でした。今回の場合はスイッチの接点部分は大丈夫そうでしたので単純にヘドロがそこに堆積して詰まったことが原因だと思います。&lt;/p&gt;
&lt;p&gt;また、スイッチの接点部分は若干サビが浮いていたの防錆剤が入っている&lt;a href=&quot;https://amzn.to/4hWgDYj&quot;&gt;ラスペネ&lt;/a&gt;を吹いておきました。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;修理費用3万円と修理までのリードタイムを節約&lt;/strong&gt;できました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;プラスドライバーとパイプブラシがあればできるので工具の出費は無いです。食洗機自体が結構重いので着脱がたいへんでした。。。。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;庫内を掃除するときに、どうしても排水部分に水が溜まっていて掃除不可能な箇所があって今まで気になってましたが、やはりそれが原因でヘドロが発生して配管が詰まるというのが今回の現象でした。定期的にクリーナーを使ってこのヘドロを融解するようなメンテナンスをする必要がありそうです。（取れるかもわかりませんが）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;注意&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;「節電」モードだと温度を下げて運転するから油汚れが溜まりやすい気がする。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1ヶ月に1回はクリーニングをする必要があるらしいです。いままで5年間やったことが無かったです。。。はい。すいません。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B097D6T7D9&quot;}&lt;/p&gt;
</content:encoded></item><item><title>新卒エンジニアへ贈る、エンジニア歴20年CTOからのメッセージ</title><link>https://blog.teraren.com/posts/2025-04-01-message-to-new-engineers/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2025-04-01-message-to-new-engineers/</guid><description>4 月 1 日。新しい門出の日ですね！　期待と不安が入り混じった状態で新たなライフステージの始まりの日のことを今でも鮮明に覚えています。</description><pubDate>Tue, 01 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;3秒まとめ 🚀&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;エンジニアとしての成長に「正解」はない&lt;/strong&gt; - 自分なりの道を見つけよう&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;技術は手段であって目的ではない&lt;/strong&gt; - 何を実現したいかを常に考えよう&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;失敗を恐れるより、失敗から学ぶ姿勢が大切&lt;/strong&gt; - 失敗は最高の教材&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;チームでの協働が個人の力を何倍にも増幅させる&lt;/strong&gt; - コミュニケーション能力は使うべきではない言葉なので修正してくださいの武器&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;学び続ける習慣が未来の自分を作る&lt;/strong&gt; - 今日から始めよう&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;新卒エンジニアのみなさん、おめでとう！ そして、ようこそ！ 🎉&lt;/h1&gt;
&lt;p&gt;4 月 1 日。新しい門出の日ですね！　期待と不安が入り混じった状態で新たなライフステージの始まりの日のことを今でも鮮明に覚えています。&lt;/p&gt;
&lt;p&gt;「コードが書けるか不安...」
「先輩たちについていけるだろうか...」
「本当にエンジニアとしてやっていけるのか...」&lt;/p&gt;
&lt;p&gt;そんな不安を抱えていませんか？　大丈夫です。&lt;strong&gt;私たちは全員、そこからスタートしました。&lt;/strong&gt; 今日は、エンジニア歴 20 年、現在 CTO として働く私から、新しい旅を始めるあなたへのメッセージです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/2025-04-01-11-14-42.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;私の20年前と今：LLM登場前と後の世界&lt;/h2&gt;
&lt;p&gt;20 年前、私も新卒エンジニアでした。当時は PHP と MySQL でウェブアプリケーションを作るのが主流で、jQuery が登場する前の JavaScript は扱いづらく、CSS でレイアウトを組むのも一苦労でした。スマートフォンはまだ普及しておらず、レスポンシブデザインなんて言葉もありませんでした。&lt;/p&gt;
&lt;p&gt;何より、&lt;strong&gt;AIアシスタントやLLM（大規模言語モデル）は存在しませんでした&lt;/strong&gt;。コードを書くときは、本やドキュメントを読み漁り、エラーが出れば自分で原因を特定し、解決策を考える必要がありました。Stack Overflow ですら、私が新卒だった頃はまだ黎明期でした。&lt;/p&gt;
&lt;p&gt;現在、私は Mindia, Inc.の CTO として、チームを率いています。この 20 年間で技術は劇的に変化しました。React、TypeScript、Docker、クラウドサービス...。そして最も革命的な変化は、&lt;strong&gt;ChatGPTやGitHub Copilotに代表されるLLMの登場&lt;/strong&gt;です。これらのツールは、コーディングの方法、問題解決のアプローチ、さらには学習プロセス自体を根本から変えました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;私が新卒の頃に使っていた技術の多くは、今や「レガシー」と呼ばれています。&lt;/strong&gt; 😅 時の流れは速いですね！　でも、変わらないものもあります。それは、エンジニアとして大切にすべき姿勢や考え方です。今日はそんな「変わらないもの」と、&lt;strong&gt;LLMの時代だからこそ重要になる新しい考え方&lt;/strong&gt;について、私の経験から学んだことをシェアしたいと思います。&lt;/p&gt;
&lt;h2&gt;LLM時代の技術習得：流行り廃りに振り回されないために&lt;/h2&gt;
&lt;p&gt;新卒エンジニアの皆さんは、最新の技術トレンドに敏感だと思います。大学や専門学校で最新のフレームワークやツールを学んできたかもしれません。それはとても素晴らしいことです。&lt;/p&gt;
&lt;p&gt;でも、ここで 1 つ覚えておいてほしいことがあります。&lt;strong&gt;技術は道具であって、目的ではありません。&lt;/strong&gt; これ、めちゃくちゃ大事です！&lt;/p&gt;
&lt;p&gt;「React 使ってるからすごい」
「TypeScript マスタしたからエリート」
「AI エンジニアになれば将来安泰」&lt;/p&gt;
&lt;p&gt;...そんな考え方は危険です。なぜなら、技術の流行りは驚くほど早く変わるからです。&lt;/p&gt;
&lt;p&gt;私がキャリアを始めた頃、流行りの技術やツールを追いかけるのに必死でした。しかし、長い目で見ると、表面的なトレンドよりも&lt;strong&gt;コンピュータサイエンスの基本原理&lt;/strong&gt;を理解していることが遥かに価値があることに気づきました。 例えば、データ構造とアルゴリズムの知識は、言語やフレームワークが変わっても普遍的に役立ちます。効率的なソートアルゴリズムを理解していれば、どんな言語でもパフォーマンスの良いコードが書けます。同様に、関数型プログラミングの考え方や、オブジェクト指向設計の原則は、数十年経った今でも価値のある概念です。 逆に、特定のフレームワークの細かい構文や設定方法だけを覚えても、そのフレームワークが廃れたら知識の多くが使い物にならなくなります。&lt;/p&gt;
&lt;p&gt;技術の寿命を予測するのは難しいんです。だからこそ重要なのは、特定の技術に依存するのではなく、&lt;strong&gt;技術の本質や背景にある考え方を理解すること&lt;/strong&gt;。技術は進化し続けますが、優れたアーキテクチャの原則や設計思想は長く価値を保ち続けるものなんです。&lt;/p&gt;
&lt;h3&gt;LLM時代に求められる新しいスキルセット&lt;/h3&gt;
&lt;p&gt;LLM の登場により、エンジニアに求められるスキルセットも変化しています。20 年前は「コードをたくさん書ける人」が評価されていましたが、今は**「LLM と効果的に協働できる人」**が価値を生み出します。&lt;/p&gt;
&lt;p&gt;具体的には：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;プロンプトエンジニアリング能力&lt;/strong&gt; - AI に適切な指示を出し、質の高い結果を得る力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIの出力を評価・検証する力&lt;/strong&gt; - 生成されたコードの品質や安全性を判断できる目&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIと人間の役割分担の最適化&lt;/strong&gt; - どの作業を AI に任せ、どの部分を人間が担当すべきか判断する力&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIツールの特性理解&lt;/strong&gt; - 各 AI ツールの得意・不得意を理解し、適材適所で活用する知恵&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの新しいスキルに加えて、従来から重要な普遍的なスキルも引き続き価値があります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;問題を分析し、適切な解決策を見つける力&lt;/li&gt;
&lt;li&gt;複雑なシステムを理解し、シンプルに説明できる力&lt;/li&gt;
&lt;li&gt;チームで協力して大きな目標を達成する力&lt;/li&gt;
&lt;li&gt;新しい技術を素早く学び、適用する力&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特定の言語やフレームワークの細かい構文は、今や LLM に聞けば即座に教えてくれます。でも、&lt;strong&gt;なぜその技術が生まれたのか、どんな問題を解決するために設計されたのか&lt;/strong&gt;を理解することは、AI では代替できない人間の強みです。そういった「なぜ」を理解していれば、新しい技術も素早く習得できるようになります！&lt;/p&gt;
&lt;h2&gt;失敗こそ最高の教材&lt;/h2&gt;
&lt;p&gt;私の 20 年のキャリアは、華々しい成功体験だけで彩られているわけではありません。むしろ、&lt;strong&gt;数え切れないほどの失敗の連続&lt;/strong&gt;でした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本番環境でデータを消してしまい、冷や汗が止まらなかった日 😱&lt;/li&gt;
&lt;li&gt;セキュリティホールを見逃してサービスがハッキングされ、休日返上で対応した時&lt;/li&gt;
&lt;li&gt;無理なスケジュールを約束してしまい、徹夜の連続で体調を崩した月&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの失敗は、当時は本当に辛かったです。眠れない夜もありましたし、「もうエンジニアを辞めよう」と思ったこともあります。でも今振り返ると、&lt;strong&gt;これらの経験が私を成長させてくれた&lt;/strong&gt;ことは間違いありません。むしろ、失敗しなかった日々よりも、失敗から立ち直った経験の方が鮮明に記憶に残っています。&lt;/p&gt;
&lt;p&gt;新卒の皆さんにお伝えしたいのは、&lt;strong&gt;失敗を恐れないでほしい&lt;/strong&gt;ということです。もちろん、無謀な挑戦や無責任な行動を推奨しているわけではありません。でも、完璧を求めるあまり何も挑戦しないのは、もっと大きな失敗です。&lt;/p&gt;
&lt;p&gt;失敗したら、次の 3 つのステップを踏んでみてください：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;何が起きたのかを正確に理解する（事実を直視する勇気）&lt;/li&gt;
&lt;li&gt;なぜそれが起きたのかを分析する（根本原因を探る冷静さ）&lt;/li&gt;
&lt;li&gt;同じ失敗を繰り返さないための対策を考える（改善する知恵）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;そして最も重要なのは、&lt;strong&gt;失敗を一人で抱え込まないこと&lt;/strong&gt;です。チームに共有し、一緒に解決策を考えましょう。そうすることで、あなたの失敗はチーム全体の財産になります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/2025-04-01-11-11-00.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;チームの力を最大化するコミュニケーション&lt;/h2&gt;
&lt;p&gt;エンジニアというと、黙々とコードを書くイメージがあるかもしれません。確かに、集中してコーディングする時間は大切です。でも、現代のソフトウェア開発は、&lt;strong&gt;チームスポーツ&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;私が新卒の頃は「コードさえ書ければいい」と思っていました。コミュニケーションが苦手で、できるだけ一人で仕事をしたいと考えていたんです。でも、キャリアが進むにつれて、&lt;strong&gt;最も価値のある仕事は常にチームで行われる&lt;/strong&gt;ことに気づきました。&lt;/p&gt;
&lt;p&gt;特に日本の開発現場では、「阿吽の呼吸」や「空気を読む」文化があります。これは素晴らしい面もありますが、時に誤解や非効率を生むこともあります。「言わなくても分かるだろう」が最大の落とし穴なんです。だからこそ、&lt;strong&gt;明確なコミュニケーション&lt;/strong&gt;が重要です。&lt;/p&gt;
&lt;p&gt;具体的には：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;わからないことは素直に質問する勇気を持つ（「分からない」と言える強さ）&lt;/li&gt;
&lt;li&gt;自分の考えや進捗を定期的に共有する習慣をつける（小さな更新でも OK！）&lt;/li&gt;
&lt;li&gt;チームメンバーの話をしっかり聞き、理解しようとする姿勢を持つ（傾聴の力）&lt;/li&gt;
&lt;li&gt;技術的な議論と人格批判を混同しない（コードに対する批判 ≠ あなたへの批判）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特に最後の点は重要です。コードレビューで指摘を受けたとき、それを個人攻撃と受け取らないでください。&lt;strong&gt;良いエンジニアは自分のコードと自分自身を分けて考えられる人&lt;/strong&gt;です。&lt;/p&gt;
&lt;h2&gt;LLM時代の学習法：20年後の自分を作る新しい習慣&lt;/h2&gt;
&lt;p&gt;テクノロジーの世界は常に変化しています。20 年前に私が学んだ技術の多くは今や使われていません。逆に、今日のスタンダードな技術の多くは、20 年前には存在していませんでした。そして、LLM の登場により、&lt;strong&gt;学び方そのものが根本から変わりつつあります&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;LLM以前の学習と現在の学習の違い&lt;/h3&gt;
&lt;p&gt;20 年前、新しい技術を学ぶには：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;分厚い技術書を購入して読み込む&lt;/li&gt;
&lt;li&gt;公式ドキュメントを最初から最後まで読む&lt;/li&gt;
&lt;li&gt;サンプルコードを手打ちで写経する&lt;/li&gt;
&lt;li&gt;エラーが出たら自分で調査して解決する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これらのプロセスは時間がかかりましたが、その分、深い理解が得られました。&lt;/p&gt;
&lt;p&gt;一方、LLM 時代の学習は：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ChatGPT に「○○の基本を教えて」と質問する&lt;/li&gt;
&lt;li&gt;エラーが出たらそのまま AI に質問して解決策を得る&lt;/li&gt;
&lt;li&gt;サンプルコードを AI に生成してもらう&lt;/li&gt;
&lt;li&gt;わからない概念があればその場で AI に説明してもらう&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;この新しい学習法は&lt;strong&gt;圧倒的に効率的&lt;/strong&gt;です。でも、表面的な理解に留まるリスクもあります。&lt;/p&gt;
&lt;h3&gt;LLM時代に効果的な学習習慣&lt;/h3&gt;
&lt;p&gt;この変化のスピードについていくには、&lt;strong&gt;学び続ける習慣&lt;/strong&gt;が不可欠です。でも、「勉強しなきゃ」というプレッシャーから学ぶのは長続きしません。大切なのは、&lt;strong&gt;学ぶことを楽しむ姿勢&lt;/strong&gt;です。好きこそものの上手なれというやつですね！&lt;/p&gt;
&lt;p&gt;私自身、新しい技術や概念を学ぶときは、「これを使って何が作れるだろう？」「これによって何が改善されるだろう？」と考えるようにしています。&lt;strong&gt;好奇心&lt;/strong&gt;こそが、長期的な学習の原動力です。&lt;/p&gt;
&lt;p&gt;LLM 時代の効果的な学習方法としては：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AIと人間の強みを組み合わせる&lt;/strong&gt; - AI に基本を教えてもらい、人間は「なぜ」を深く考える&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;実際に手を動かしてプロジェクトを作る&lt;/strong&gt; - AI が生成したコードをそのまま使うのではなく、理解して改良する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIとの対話を通じて概念を深める&lt;/strong&gt; -「これはなぜそうなるの？」「別の方法はある？」と掘り下げる質問をする&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIの限界を知り、人間の判断力を磨く&lt;/strong&gt; - AI の回答を鵜呑みにせず、検証する習慣をつける&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自分の学びをブログやSNSでアウトプットする&lt;/strong&gt; - AI の助けを借りつつも、自分の言葉で説明する力を養う&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特に最後のアウトプットは重要です。私自身、この Zenn やブログでの発信を通じて、多くの気づきや出会いがありました。&lt;strong&gt;教えることは、最も効果的な学びの形&lt;/strong&gt;なんです。「誰かに説明できる」が本当の理解の証です！&lt;/p&gt;
&lt;h2&gt;LLM時代のエンジニアキャリア：幸せな道を見つけるために&lt;/h2&gt;
&lt;p&gt;LLM の登場により、エンジニアの役割や価値も変化しています。「コードを書く」という作業の多くは AI が担うようになり、人間のエンジニアには&lt;strong&gt;より創造的で戦略的な役割&lt;/strong&gt;が求められるようになるでしょう。&lt;/p&gt;
&lt;p&gt;新卒の皆さんは、これからどんなエンジニアになりたいですか？　🤔&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI と協働して複雑な問題を解決するプロンプトエンジニア？&lt;/li&gt;
&lt;li&gt;AI ツールを活用して生産性を最大化するプロダクティビティスペシャリスト？&lt;/li&gt;
&lt;li&gt;AI の限界を理解し、人間ならではの創造性を発揮するクリエイティブエンジニア？&lt;/li&gt;
&lt;li&gt;AI システムの倫理や安全性を確保する AI 倫理スペシャリスト？&lt;/li&gt;
&lt;li&gt;AI と人間のチームを率いる AI 時代のテックリード？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;正解はありません。&lt;strong&gt;あなた自身の価値観や強み、興味に合った道を見つけることが大切&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;私の場合、技術が好きなのはもちろんですが、それ以上に「技術で人々の生活を良くすること」に情熱を感じています。コードを書くことが目的ではなく、そのコードが誰かの問題を解決することに喜びを感じるんです。だからこそ、単なる技術的な挑戦だけでなく、&lt;strong&gt;ユーザーにとっての価値&lt;/strong&gt;を常に考えるようにしています。&lt;/p&gt;
&lt;h3&gt;LLM時代の新卒エンジニアへのアドバイス&lt;/h3&gt;
&lt;p&gt;新卒の皆さんも、ぜひ自分自身の「なぜ」を見つけてください。なぜエンジニアになったのか。何を実現したいのか。その「なぜ」が、困難な時期を乗り越える力になります。&lt;/p&gt;
&lt;p&gt;最後に、LLM 時代を生きる新卒エンジニアへの私からのシンプルなアドバイスです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AIと協働する姿勢を身につけよう&lt;/strong&gt; - AI を敵視するのではなく、パートナーとして活用する&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AIが苦手な領域を理解し、そこで価値を発揮しよう&lt;/strong&gt; - 創造性、倫理的判断、共感は AI が不得意&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;謙虚に学び続けよう&lt;/strong&gt; - 知れば知るほど、自分の無知に気づくもの&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;失敗を恐れず挑戦しよう&lt;/strong&gt; - 挑戦しない人生より、失敗のある人生の方が豊か&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;仲間と共に成長しよう&lt;/strong&gt; - 一人で登る山より、仲間と登る山の方が景色が美しい&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自分の価値観を大切にしよう&lt;/strong&gt; - 他人の期待ではなく、自分の情熱に従おう&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;何より、エンジニアであることを楽しもう！&lt;/strong&gt; - 楽しさこそが継続の秘訣&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;エンジニアという職業は、世界を変える力を持っています。そして今、LLM という強力なツールを手にした皆さんには、私たちの世代以上に大きな可能性が広がっています。その力を持った皆さんの活躍を、心から楽しみにしています！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/04/2025-04-01-11-12-44.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;おまけ：自己紹介 👋&lt;/h2&gt;
&lt;p&gt;松倉友樹（まつくらゆうき）と申します。Mindia, Inc.の CTO として、日々チームと共にプロダクト開発に取り組んでいます。学生時代から数えると約 26 年（学生エンジニア 6 年+社会人エンジニア歴約 20 年）のエンジニア経験があり、ウェブ開発、モバイルアプリ開発、クラウドインフラ、最近では AI 活用など幅広い領域に携わってきました。&lt;/p&gt;
&lt;p&gt;個人的な（&lt;a href=&quot;https://blog.teraren.com/&quot;&gt;テックブログ&lt;/a&gt;）や&lt;a href=&quot;https://zenn.dev/matsubokkuri&quot;&gt;Zenn&lt;/a&gt;でも技術情報を発信しています。また、Xでは&lt;a href=&quot;https://twitter.com/matsubokkuri&quot;&gt;@matsubokkuri&lt;/a&gt;で日々の気づきや学びをつぶやいています。&lt;/p&gt;
&lt;p&gt;皆さんとどこかでお会いできる日を楽しみにしています。エンジニアとしての新たな旅の始まりを心から祝福します。素晴らしいキャリアになることを願っています！　🎉&lt;/p&gt;
</content:encoded></item><item><title>LLMを活用してDockerfileを最適化し15%のサイズ削減を実現した話</title><link>https://blog.teraren.com/posts/dockerfile-refactoring-by-llm/</link><guid isPermaLink="true">https://blog.teraren.com/posts/dockerfile-refactoring-by-llm/</guid><description>長年運用している Dockerfile は複雑化していく傾向にあります。</description><pubDate>Tue, 25 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3行まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;LLM を活用して Dockerfile のリファクタリングを実施し、イメージサイズを 15％削減（1.96GB → 1.75GB）&lt;/li&gt;
&lt;li&gt;LLM 登場前に書いたコードを LLM にリファクタさせるのは良い結果を生む（最近これが楽しい）&lt;/li&gt;
&lt;li&gt;slim イメージへの移行とパッケージ最適化により、ビルド時間と pull 時間を改善&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;長年運用している Dockerfile は複雑化していく傾向にあります。&lt;/p&gt;
&lt;p&gt;リファクタリングはリグレッションのリスクがあり、手を出しづらいです。&lt;/p&gt;
&lt;p&gt;最近、Devin による &lt;a href=&quot;https://tech.layerx.co.jp/entry/2025/02/06/110027&quot;&gt;Dockerfileリファクタリングの成功事例&lt;/a&gt;を見て、自プロジェクトでも試してみることにしました。&lt;/p&gt;
&lt;h2&gt;最適化前の状態&lt;/h2&gt;
&lt;p&gt;まず、変更前の Docker image のサイズを調べておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ docker images minedia-www-app
REPOSITORY        TAG       IMAGE ID       CREATED      SIZE
minedia-www-app   latest    7e88a3086cb9   4 days ago   1.96GB
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2GBありました。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;Devinにやってもらおうかと思いましたが、そもそもこんなDockerfileのリファクタだったらClineで十分だと思うのでClineでClaude sonnet 3.5(少し前に行ったので古い)で実行してみました。&lt;/p&gt;
&lt;p&gt;プロンプトは、ラフに「Dockerfileをリファクタリングして」という指示だけです。&lt;/p&gt;
&lt;h2&gt;LLMによる主要な変更点&lt;/h2&gt;
&lt;h3&gt;1. ベースイメージの最適化&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;-FROM ruby:3.4.1
+FROM ruby:3.4.1-slim
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;必要最低限しか入っていない &lt;code&gt;-slim&lt;/code&gt; をbase imageとして使うようになりました。&lt;/p&gt;
&lt;p&gt;いままでも導入を検討していましたが、開発時にはツールが少なかったり、リグレッションが発生してしまうリスクがあるのであんまり導入に積極的に離れませんでしたがそこを踏み込んで変更してくれました。&lt;/p&gt;
&lt;h3&gt;2. 環境変数とパッケージインストールの効率化&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;-ENV LANG=&quot;C.UTF-8&quot; TZ=&quot;UTC&quot;
-
-RUN apt update -qq &amp;amp;&amp;amp; DEBIAN_FRONTEND=noninteractive apt -yq dist-upgrade &amp;amp;&amp;amp;\
-  DEBIAN_FRONTEND=noninteractive apt install -yq\
-    build-essential\
-    default-mysql-client\
-    ffmpeg\
+
+ENV LANG=&quot;C.UTF-8&quot; \
+    TZ=&quot;UTC&quot; \
+    APP_HOME=/app \
+    LUA_LIB=&quot;/usr/lib/liblua5.1.so.0&quot;
+
+# Install system dependencies
+RUN apt-get update -qq &amp;amp;&amp;amp; \
+    DEBIAN_FRONTEND=noninteractive apt-get -yq dist-upgrade &amp;amp;&amp;amp; \
+    DEBIAN_FRONTEND=noninteractive apt-get install -yq \
+    build-essential \
+    curl \
+    default-mysql-client \
+    ffmpeg \
     liblua5.1-0 \
-    pandoc &amp;amp;&amp;amp;\
-    apt clean &amp;amp;&amp;amp;\
-    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* &amp;amp;&amp;amp;\
+    pandoc \
+    imagemagick \
+    libmagickwand-dev &amp;amp;&amp;amp; \
+    ln -s /usr/lib/`uname -m`-linux-gnu/liblua5.1.so.0 ${LUA_LIB} &amp;amp;&amp;amp; \
+    # Install Node.js
+    curl -fsSL https://deb.nodesource.com/setup_22.x | bash - &amp;amp;&amp;amp; \
+    apt-get install -y nodejs &amp;amp;&amp;amp; \
+    # Cleanup
+    apt-get clean &amp;amp;&amp;amp; \
+    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* &amp;amp;&amp;amp; \
     truncate -s 0 /var/log/*log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;今までは人間が見やすいようにするメンテナナンス性や、build cacheを使うためにステップごとに処理をある程度区切っていましたが
build layerを少なくするために1コマンドで色々行うように変更されました。&lt;/p&gt;
&lt;p&gt;人間がメンテナンスしづらくはなりますが、LLM経由でメンテナンスできるならばこれで問題無いと思います。&lt;/p&gt;
&lt;h2&gt;ベースイメージのサイズ比較&lt;/h2&gt;
&lt;p&gt;サイズ削減の効果を調査するために、そもそもslimとそうでないイメージでどのくらいサイズの差があるのかを調べてみたら、5倍ちかく容量が違いました。&lt;/p&gt;
&lt;h3&gt;通常イメージ&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;❯ docker images ruby:3.4.1
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
ruby         3.4.1     79e67c837851   5 weeks ago   1.01GB
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Slimイメージ&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;❯ docker images ruby:3.4.1-slim
REPOSITORY   TAG          IMAGE ID       CREATED       SIZE
ruby         3.4.1-slim   eb3ae63a0b49   8 weeks ago   219MB
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;最終的な成果&lt;/h2&gt;
&lt;h3&gt;最適化の結果&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;最適化前&lt;/th&gt;
&lt;th&gt;最適化後&lt;/th&gt;
&lt;th&gt;削減率&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ベースイメージ&lt;/td&gt;
&lt;td&gt;1.0GB&lt;/td&gt;
&lt;td&gt;219MB&lt;/td&gt;
&lt;td&gt;78.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;アプリケーションイメージ&lt;/td&gt;
&lt;td&gt;1.96GB&lt;/td&gt;
&lt;td&gt;1.75GB&lt;/td&gt;
&lt;td&gt;10.7%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;ベースイメージの大幅な軽量化により、全体で約250MB（約15％）のサイズ削減に成功しました。
これによりビルド時間の短縮やコンテナのpull時間改善など、CI/CDパイプライン全体の効率化につながりました。&lt;/p&gt;
&lt;h2&gt;(余談)Docker Gordonでの試み&lt;/h2&gt;
&lt;p&gt;Docker Desktopに統合されたAI機能（&lt;a href=&quot;https://www.docker.com/ja-jp/blog/meet-gordon-an-ai-agent-for-docker/&quot;&gt;Gordon&lt;/a&gt;）も試してみましたが、現時点では正常に動作しませんでした。&lt;/p&gt;
&lt;p&gt;設定を有効化し、規約に同意しても機能が利用できない状態でした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/03/2025-02-21-18-29-09.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/03/2025-02-21-18-28-23.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;本番環境へのデプロイ時の注意&lt;/h2&gt;
&lt;p&gt;このDockerfileの最適化を行った後、入念なテストを経て本番にデプロイしました。&lt;/p&gt;
&lt;p&gt;1つだけ問題が発生しました。AWS ECSのhealthcheckにて &lt;code&gt;ps&lt;/code&gt; コマンドによるsidekiqプロセスの有無をチェックしてhealthyかどうかを判定していました。
&lt;code&gt;slim&lt;/code&gt; imageにはpsコマンドすら入っていなかったので別のコマンドでチェックするようにtask definitionsを変更しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cat /proc/*/cmdline | tr &apos;\0&apos; &apos; &apos; | grep sidekiq || exit 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;イメージサイズを 15％削減（約 250MB）できました。
&lt;ul&gt;
&lt;li&gt;すでにある程度はきれいにしているのでそんなに無駄は無いので &lt;a href=&quot;https://tech.layerx.co.jp/entry/2025/02/06/110027&quot;&gt;70％&lt;/a&gt;も削る余地が無かったです。&lt;/li&gt;
&lt;li&gt;ビルド時間の短縮と pull 時間の改善&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LLM を活用することで、従来は困難だった最適化作業を効率的に実施できた&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>WordPressをSQLiteで動かしてみた！パフォーマンス比較とセットアップ方法</title><link>https://blog.teraren.com/posts/wordpress-sqlite/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-sqlite/</guid><description>WordPress が公式に対応しているデータベースは MySQL（または MariaDB）のみです。数年前に SQLiteにも対応したいという表明がありましたが、未だに公式サポートの告知はありません。</description><pubDate>Tue, 25 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;3行まとめ&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;SQLite を使用した WordPress は標準構成より&lt;strong&gt;約17％高速&lt;/strong&gt;で、メモリ使用量が&lt;strong&gt;約32％少ない&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;DB サーバーが不要になり、設定が簡素化。&lt;/li&gt;
&lt;li&gt;DB への参照がほとんどの場合や開発環境に最適であり、バックアップも単一ファイルで完結するようになる&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;背景&lt;/h1&gt;
&lt;p&gt;WordPress が公式に対応しているデータベースは MySQL（または MariaDB）のみです。数年前に &lt;a href=&quot;https://make.wordpress.org/core/2022/09/12/lets-make-wordpress-officially-support-sqlite/&quot;&gt;SQLiteにも対応したい&lt;/a&gt;という表明がありましたが、未だに公式サポートの告知はありません。&lt;/p&gt;
&lt;p&gt;MySQL は優れたデータベースですが、小規模サイトや開発環境では以下のような課題があります：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;サーバーリソースを多く消費する&lt;/li&gt;
&lt;li&gt;設定や管理が比較的複雑である&lt;/li&gt;
&lt;li&gt;小規模サイトではオーバースペックである&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一方、SQLite は：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;軽量でリソース消費が少ない&lt;/li&gt;
&lt;li&gt;ファイルベースで設定が簡単である&lt;/li&gt;
&lt;li&gt;小〜中規模のサイトに適している&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最近調査したところ、&lt;a href=&quot;https://github.com/aaemnnosttv/wp-sqlite-db&quot;&gt;wp-sqlite-db&lt;/a&gt;というdrop-inプラグインを使えばWordPressをSQLiteで動かせることがわかりました。このプラグインはWordPressのデータベース接続層を置き換え、SQLiteを使用できるようにします。&lt;/p&gt;
&lt;p&gt;今回はこのプラグインを活用し、WordPress を SQLite で動かす方法と MySQL とのパフォーマンス比較について紹介します。&lt;/p&gt;
&lt;h1&gt;セットアップ手順&lt;/h1&gt;
&lt;p&gt;手軽に試すために、ローカル環境で Docker Compose を使って新規に WordPress 環境を構築します。&lt;/p&gt;
&lt;h2&gt;1. プロジェクトディレクトリの作成&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% mkdir sqlite_wordpress
% cd sqlite_wordpress
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. Docker Compose設定ファイルの作成&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;compose.yml&lt;/code&gt; ファイルを作成し、以下の内容を記述します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  wordpress:
    image: wordpress:latest
    volumes:
      - wp_data:/var/www/html
    ports:
      - 80:80
    restart: always
    environment:
      WORDPRESS_DB_HOST: dummy
      WORDPRESS_DB_NAME: dummy
      WORDPRESS_DB_USER: dummy

volumes:
  wp_data:
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;重要なポイント&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DBコンテナが不要&lt;/strong&gt;: 通常のWordPress構成ではMySQLコンテナが必要だが、SQLiteを使用するため不要である&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ダミー環境変数&lt;/strong&gt;: MySQL接続用の環境変数にダミー値を設定する
&lt;ul&gt;
&lt;li&gt;これにより、WordPressの初期設定ページでデータベース接続情報の入力をスキップできる&lt;/li&gt;
&lt;li&gt;SQLiteを使用するため、実際にはこれらの値は使用されない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この設定は、WordPressの初期化プロセスを騙して、データベース設定画面をスキップさせるためのものです。SQLite用のdrop-inプラグインがデータベース接続を管理するため、実際のMySQL接続は必要ありません。&lt;/p&gt;
&lt;h2&gt;3. SQLite用drop-inプラグインのインストール&lt;/h2&gt;
&lt;p&gt;以下のコマンドを実行してWordPressコンテナに入ります：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose run wordpress bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;コンテナ内で以下のコマンドを実行し、SQLite用のdrop-inプラグインをインストールします：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# wp-contentディレクトリに移動
cd wp-content

# SQLite用のdrop-inファイルをダウンロード
curl https://raw.githubusercontent.com/aaemnnosttv/wp-sqlite-db/refs/heads/master/src/db.php &amp;gt; db.php

# SQLiteデータベースファイル用のディレクトリを作成
mkdir database

# 権限を設定（Webサーバーがファイルを書き込めるようにする）
chown www-data database
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これらのコマンドで：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;WordPressのデータベース接続処理を置き換えるdrop-inファイル（db.php）をダウンロード&lt;/li&gt;
&lt;li&gt;SQLiteデータベースファイルを保存するディレクトリを作成&lt;/li&gt;
&lt;li&gt;Webサーバープロセス（www-data）がデータベースファイルに書き込めるよう権限を設定&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これでSQLite用の設定は完了です。シンプルな3ステップで、WordPressをSQLiteで動かす準備が整いました。&lt;/p&gt;
&lt;h1&gt;起動と初期設定&lt;/h1&gt;
&lt;h2&gt;1. WordPressコンテナの起動&lt;/h2&gt;
&lt;p&gt;次のコマンドでWordPressコンテナを起動します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. 初期設定の実施&lt;/h2&gt;
&lt;p&gt;コンテナが起動したら、ブラウザで以下のURLにアクセスします：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;http://localhost/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;初期設定の流れ&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;言語選択画面&lt;/strong&gt;&lt;br /&gt;
最初に言語選択画面が表示されます。日本語を選択します。
&lt;img src=&quot;../../assets/uploads/2025/03/2025-03-26-01-26-41.png&quot; alt=&quot;言語選択画面&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;サイト情報設定画面&lt;/strong&gt;&lt;br /&gt;
次に管理者アカウントとサイト名を設定する画面が表示されます。
&lt;img src=&quot;../../assets/uploads/2025/03/2025-03-26-01-27-40.png&quot; alt=&quot;サイト情報設定&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注目ポイント&lt;/strong&gt;: 通常のWordPress設定では、この前にデータベース接続情報の入力画面がありますが、環境変数を設定しているためスキップされています。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;設定完了&lt;/strong&gt;&lt;br /&gt;
必要情報を入力して「WordPressをインストール」ボタンをクリックすると初期化が完了します。&lt;/p&gt;
&lt;p&gt;SQLiteのデータ自体は、デフォルトでは &lt;code&gt;wp-content/database/.ht.sqlite&lt;/code&gt; に保存されます。変更したい場合は&lt;a href=&quot;https://github.com/aaemnnosttv/wp-sqlite-db?tab=readme-ov-file#overview&quot;&gt;環境変数&lt;/a&gt;で設定できます。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;3. 管理画面へのログイン&lt;/h2&gt;
&lt;p&gt;設定したユーザー名とパスワードで管理画面にログインすれば、WordPressの利用を開始できます。&lt;/p&gt;
&lt;h2&gt;使用感&lt;/h2&gt;
&lt;p&gt;SQLiteを使用したWordPressの最も顕著な特徴は、&lt;strong&gt;驚異的な応答速度&lt;/strong&gt;である。管理画面での操作やページの読み込みが非常に高速で、特に以下の点で体感できる：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;投稿の保存や公開が瞬時に完了する&lt;/li&gt;
&lt;li&gt;管理画面の各ページ間の移動がスムーズである&lt;/li&gt;
&lt;li&gt;プラグインのインストールや有効化が高速である&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通常のMySQL環境では数秒かかる操作が、SQLite環境ではほぼ瞬時に完了する。この速度差は特に管理作業を頻繁に行う場合に大きなメリットとなる。&lt;/p&gt;
&lt;h1&gt;パフォーマンス比較&lt;/h1&gt;
&lt;p&gt;SQLiteとMariaDBを使用したWordPress環境のパフォーマンスを比較するため、簡単なベンチマークテストを実施した。&lt;/p&gt;
&lt;h2&gt;測定環境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;同一ハードウェア上でテスト&lt;/li&gt;
&lt;li&gt;Apache Benchを使用（&lt;code&gt;ab&lt;/code&gt; コマンド）&lt;/li&gt;
&lt;li&gt;500リクエスト、10並列でトップページにアクセス&lt;/li&gt;
&lt;li&gt;初期インストール直後の状態で測定&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;WordPress with SQLite&lt;/h2&gt;
&lt;h3&gt;メモリ使用量&lt;/h3&gt;
&lt;p&gt;SQLiteを使用した場合、単一のWordPressコンテナのみで動作する：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
7d22d5c46e2c   sqlite_wordpress-wordpress-1       0.01%     151MiB / 20.24GiB     0.73%     1.91MB / 7.18MB   0B / 17.4MB       11
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;パフォーマンス測定結果&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;❯ ab -n 500 -c 10 &apos;http://localhost/&apos;|grep Request
Requests per second:    245.71 [#/sec] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;平均レスポンスタイム: &lt;strong&gt;42.365ms&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;WordPress with MariaDB（標準構成）&lt;/h2&gt;
&lt;p&gt;比較のため、WordPressが公式に提供しているDocker Compose設定（MySQL/MariaDB使用）でも同様のテストを実施しました。&lt;/p&gt;
&lt;h3&gt;メモリ使用量&lt;/h3&gt;
&lt;p&gt;MariaDBを使用した場合は、WordPressコンテナとデータベースコンテナの2つが必要です：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CONTAINER ID   NAME                               CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
065ec00a760f   sqlite_wordpress-wordpress-1       0.01%     138MiB / 20.24GiB     0.67%     6.7MB / 3.22MB    180kB / 88.1MB    11
ef148bfb4007   sqlite_wordpress-db-1              0.02%     83.31MiB / 20.24GiB   0.40%     1.81MB / 5.15MB   6.28MB / 35.5MB   21
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;パフォーマンス測定結果&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;❯ ab -n 500 -c 10 &apos;http://localhost/&apos;|grep Request
Requests per second:    209.41 [#/sec] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;平均レスポンスタイム: &lt;strong&gt;47.869ms&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;比較結果&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;WordPress with SQLite&lt;/th&gt;
&lt;th&gt;WordPress with MariaDB&lt;/th&gt;
&lt;th&gt;差分&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;メモリ使用量&lt;/td&gt;
&lt;td&gt;151 MiB&lt;/td&gt;
&lt;td&gt;138 MiB + 83.31 MiB = 221.31 MiB&lt;/td&gt;
&lt;td&gt;SQLiteの方が約70 MiB少ない（約32％削減）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;リクエスト/秒&lt;/td&gt;
&lt;td&gt;245.71 req/sec&lt;/td&gt;
&lt;td&gt;209.41 req/sec&lt;/td&gt;
&lt;td&gt;SQLiteの方が約17％高速&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;平均レスポンスタイム&lt;/td&gt;
&lt;td&gt;42.365 ms&lt;/td&gt;
&lt;td&gt;47.869 ms&lt;/td&gt;
&lt;td&gt;SQLiteの方が約5.5 ms速い（約11％改善）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;考察&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;メモリ使用量&lt;/strong&gt;: SQLite を使用することで、約 32％のメモリ使用量削減が実現できます。これは特に限られたリソースの環境（VPS や共有ホスティングなど）で大きなメリットとなります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;パフォーマンス&lt;/strong&gt;: SQLite はシンプルなファイルベースのデータベースにもかかわらず、MariaDB よりも高いパフォーマンスを示しています。これは主に以下の理由によると考えられます：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;プロセス間通信のオーバーヘッドがありません&lt;/li&gt;
&lt;li&gt;シンプルなクエリ実行パスです&lt;/li&gt;
&lt;li&gt;ファイルシステムキャッシュを効率的に利用できます&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;SQLite版WordPressの適用シナリオ&lt;/h1&gt;
&lt;p&gt;SQLite を使用した WordPress は、以下のようなシナリオで特に有効です：&lt;/p&gt;
&lt;h2&gt;最適な利用シーン&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;小〜中規模のWebサイト&lt;/strong&gt;: アクセス数が多くない個人ブログや小規模企業サイト向けである&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;開発・テスト環境&lt;/strong&gt;: 本番環境と同じ WordPress を軽量に動かしたい場合に適している&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リソース制約のある環境&lt;/strong&gt;: 低スペックの VPS やレンタルサーバーで効果的である&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;バックアップが容易なサイト&lt;/strong&gt;: SQLite はファイル 1 つでバックアップ可能である&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;注意点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;大規模サイトには不向き&lt;/strong&gt;: 同時接続数が多い場合は SQLite の制約が問題になる可能性がある&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一部のプラグイン互換性&lt;/strong&gt;: 特定の MySQL の機能に依存するプラグインは動作しない場合がある&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;公式サポート外&lt;/strong&gt;: WordPress の公式サポート対象外であるため、問題発生時の対応は自己責任となる&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;今後の展望&lt;/h1&gt;
&lt;p&gt;個人的には、以下の点で今後 SQLite 版 WordPress を活用していく予定である：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;既存の小規模サイトの移行&lt;/strong&gt;: 現在運用している小規模な WordPress サイトの一部を SQLite ベースに移行し、リソース使用量とパフォーマンスの改善を図る&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;開発環境の標準化&lt;/strong&gt;: 開発・テスト環境では SQLite を標準とし、環境構築の簡素化と高速化を実現&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;バックアップ戦略の簡素化&lt;/strong&gt;: SQLite ファイル単体でのバックアップにより、データベースダンプが不要になるメリットを活かす&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;SQLite を使用した WordPress は適切なユースケースにおいて従来の MySQL 構成よりも多くのメリットをもたらす可能性がある。個人ブログや小規模サイトでの利用は特に検討する価値が十分にあるだろう。&lt;/p&gt;
&lt;h1&gt;まとめ&lt;/h1&gt;
&lt;p&gt;WordPress を SQLite で動かすことで、以下のメリットが判明しました&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;シンプルな構成&lt;/strong&gt;: DB サーバー不要で構成がシンプル&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リソース効率&lt;/strong&gt;: メモリ使用量が約 32％削減&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高速なレスポンス&lt;/strong&gt;: リクエスト処理が約 17％高速化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;簡単なバックアップ&lt;/strong&gt;: データベースがファイル 1 つで完結&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SQLite を使用した WordPress は公式サポート対象外ではあるものの、適切なシナリオでは非常に魅力的な選択肢となる。特に小規模サイトや開発環境においては、そのシンプルさと効率性が大きな強みとなるだろう。&lt;/p&gt;
&lt;p&gt;今後も継続的に検証を進め、実運用での知見を深めていく予定である。&lt;/p&gt;
</content:encoded></item><item><title>Xiaomi 14T Proをメインスマホにできるか検証</title><link>https://blog.teraren.com/posts/xiaomi-14t-pro/</link><guid isPermaLink="true">https://blog.teraren.com/posts/xiaomi-14t-pro/</guid><description>iPhoneからの乗り換えを検討してXiaomi 14T ProをAliexpressで購入し、カメラ性能や日本語対応・アプリ互換性などをiPhoneと比較検証したレビュー</description><pubDate>Sun, 23 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;最近、iPhoneが高すぎるし、スマホで写真を撮りまくっているのでカメラ性能が良いXiaomi 14T Proを試してみて良ければ移行しようと思う。&lt;/p&gt;
&lt;p&gt;iPhoneにインストールされているアプリをカウントしたら330個ぐらいあって、これも減らしたいと思ってます。（頑張って掃除はしているけどなかなか減らない）&lt;/p&gt;
&lt;h2&gt;開封&lt;/h2&gt;
&lt;p&gt;Aliexpressで注文して1週間ほどで届いた。注文時は1ヶ月後に到着予定と書かれているがでたらめ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ミニマムなパッケージ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8764.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;スマホに最適化された緩衝材！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8765.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;日本向けに用意したのか、電源プラグ変換アダプタがスマホの箱とは別に同梱されていた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8766.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;iPhone 16 Proより一回り大きい。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8767.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;120WのACアダプタが入ってる。強力すぎる！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8768.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;スマホケースが同梱。画面のフィルムも元から貼り付けてあるので楽！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8769.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8770.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;自分でケースに入れる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8771.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;独自OS。。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8772.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;巨大！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8773.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8774.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.antutu.com/en/ranking/rank11.htm&quot;&gt;antutu&lt;/a&gt;から抜粋。&lt;/p&gt;
&lt;h3&gt;Xiaomi 14T Pro&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;iPhone 16 Pro&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;カメラ性能&lt;/h2&gt;
&lt;p&gt;手元にあるiPhone 16 Proとの比較をしていきます。&lt;/p&gt;
&lt;p&gt;牛丼。食べ物の色の表現は意外と難しい。&lt;/p&gt;
&lt;p&gt;https://x.com/matsubokkuri/status/1893168256317563150&lt;/p&gt;
&lt;p&gt;https://x.com/matsubokkuri/status/1893205539682750861
https://x.com/matsubokkuri/status/1892966419840512500&lt;/p&gt;
&lt;h3&gt;まとめ&lt;/h3&gt;
&lt;p&gt;光学性能はXiaomi 14T Pro勝ち。&lt;/p&gt;
&lt;p&gt;センサはiPhone 16 Proが勝ち。特に高感度は歴然。&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;h3&gt;レンズ内に曇りが発生&lt;/h3&gt;
&lt;p&gt;しばらく使っていたら、望遠レンズに水滴が付いた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/IMG_8854.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Webを検索すると同じ症状の事例が多数出てきた。製造時に混入している模様。&lt;/p&gt;
&lt;p&gt;https://www.reddit.com/r/Xiaomi/comments/1b314x0/xiaomi_14s_camera_lens_is_fogging/&lt;/p&gt;
&lt;p&gt;ziplockなどにスマホと乾燥剤を入れてしばらく放置して抜くしか無い。&lt;/p&gt;
&lt;p&gt;レンズの曇りを取る方法は&lt;a href=&quot;https://new-ams.c.mi.com/global/post/847738&quot;&gt;このページ&lt;/a&gt;に以下のように紹介されていた。&lt;/p&gt;
&lt;p&gt;推奨修正法 1&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;スマートフォンの外側が乾いてきれいな状態であることを確認し、必要に応じてマイクロファイバークロスで拭きます。&lt;/li&gt;
&lt;li&gt;SIMトレイを開けます。&lt;/li&gt;
&lt;li&gt;SIMトレイを引き出します。&lt;/li&gt;
&lt;li&gt;30分から1時間ほど自然乾燥させます。&lt;/li&gt;
&lt;li&gt;8K解像度で10〜30分間ビデオ撮影し、スマートフォンを少し温めます。&lt;/li&gt;
&lt;li&gt;SIMトレイを元に戻し、状況を確認します。&lt;/li&gt;
&lt;li&gt;これで湿気の問題が解決するはずです。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;推奨修正法2&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;スマートフォンの外側が乾いてきれいな状態であることを確認し、必要に応じてマイクロファイバークロスで拭きます。&lt;/li&gt;
&lt;li&gt;SIMトレイを開けます。&lt;/li&gt;
&lt;li&gt;SIMトレイを引き出します。&lt;/li&gt;
&lt;li&gt;3Dmarkをダウンロードします。&lt;/li&gt;
&lt;li&gt;約20分間ストレステストを実行します。&lt;/li&gt;
&lt;li&gt;これによりスマートフォンが熱くなりますが、バッテリーが約45℃になると熱制御が働くため、完全に安全です。&lt;/li&gt;
&lt;li&gt;ストレステストが終了したら、SIMトレイを出したままにします。&lt;/li&gt;
&lt;li&gt;屋外で5〜10分間、8Kビデオ撮影をテストします。&lt;/li&gt;
&lt;li&gt;曇りがなければ、SIMトレイを元に戻します。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;しかし、上記の方法ではスマホのバッテリーは痛むし、無駄にCPUやSSDを消費するのでスマホの寿命を削ってしまいます。冷蔵庫に入れて冷やすのもリチウムイオン電池的にも良くない。&lt;/p&gt;
&lt;p&gt;日本では&lt;a href=&quot;https://ameblo.jp/iikotoiimono/entry-12686705541.html&quot;&gt;この方法&lt;/a&gt;が一般的だと思う。ジップロックにスマホと乾燥剤を入れて放置。その際にSIMトレーは外す感じが良いと思う。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B005DJISNO&quot;}&lt;/p&gt;
&lt;h3&gt;Xiaomi独自OS&lt;/h3&gt;
&lt;p&gt;プリインされているアプリが削除できない。&lt;/p&gt;
&lt;p&gt;AndroidとXiaomiの独自機能が癒着してしまっています。&lt;/p&gt;
&lt;h2&gt;良い点&lt;/h2&gt;
&lt;h3&gt;ベンチマーク結果は同じだが、価格が半額&lt;/h3&gt;
&lt;p&gt;iPhone 16 Proとベンチマークやスペックは近似しているなかで、価格は半額というのは魅力的。&lt;/p&gt;
&lt;h3&gt;指紋でアンロック&lt;/h3&gt;
&lt;p&gt;画面上で指紋認識ができるのでいちいち顔を向けなくてもアンロックできる。&lt;/p&gt;
&lt;h2&gt;結論&lt;/h2&gt;
&lt;p&gt;iPhoneからAndroidへの移行は断念。&lt;/p&gt;
&lt;p&gt;ハードウェアは良いけど、AndroidのUXに慣れなさそうなので諦める。&lt;/p&gt;
&lt;p&gt;iOSで設定を最適化しすぎた気もする。。。今まで1ステップで実行できていたことが2ステップになることが増えてしまって面倒に感じた。&lt;/p&gt;
&lt;p&gt;夜景が汚いのが残念。&lt;/p&gt;
&lt;p&gt;ゼロイチでセットアップするならAndroidでも良い気がする。&lt;/p&gt;
</content:encoded></item><item><title>デスクトップの音響環境を測定してみる</title><link>https://blog.teraren.com/posts/check-by-room-acoustics-software/</link><guid isPermaLink="true">https://blog.teraren.com/posts/check-by-room-acoustics-software/</guid><description>REW（Room Acoustics Software）を使ってGENELEC 8020スピーカーとUSB-DACを用いたデスクトップのリスニング環境を測定・分析した実践レポート</description><pubDate>Sat, 22 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;ちょっと音響環境を調べる必要が出てきたので&lt;a href=&quot;https://www.roomeqwizard.com&quot;&gt;REW&lt;/a&gt; (Room Acoustics Software) で計測してみました。&lt;/p&gt;
&lt;p&gt;Javaで動くのでMacでも動きます。最近のJavaは軽快なのか、PCのスペックが良くなったからかわかりませんが起動は速く、ストレスなく動きます。&lt;/p&gt;
&lt;p&gt;とりあえず手元にある機材で計測していきます。&lt;/p&gt;
&lt;h2&gt;音響環境&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;/posts/desktop/&quot;&gt;PCで作業するデスクトップ&lt;/a&gt;です。&lt;/p&gt;
&lt;h3&gt;スピーカー&lt;/h3&gt;
&lt;p&gt;GENELEC 8020&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B06XTBPZNZ&quot;}&lt;/p&gt;
&lt;h3&gt;USB-DAC&lt;/h3&gt;
&lt;p&gt;::amazon{asin=&quot;B07VDQQY95&quot;}&lt;/p&gt;
&lt;h2&gt;測定&lt;/h2&gt;
&lt;h3&gt;準備&lt;/h3&gt;
&lt;p&gt;マイク、USB-DACのキャリブレーションをすべきですが、手元にあるマイクが現在はUSBで接続されているのでループバック接続するのが面倒なのでスキップしました。&lt;/p&gt;
&lt;p&gt;使っているマイクはこちら。ミニジャックはありますが&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07NZZZ746&quot;}&lt;/p&gt;
&lt;p&gt;まずは、音量のキャリブレーション。音圧を定量的に測定するのにこれは必要です。実測値はこれも簡易的にiPhoneのアプリを使って計測。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;SPL&lt;/h3&gt;
&lt;p&gt;周波数特性。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;サブウーファーが無いので下の方は出ていません。&lt;/p&gt;
&lt;p&gt;ほかはフラット。3kHz〜4kHzに盛り上がりがあるのはエコライザで持ち上げすぎているからかと思います。&lt;/p&gt;
&lt;p&gt;ちなみに、スピーカーにはカットオフができる機能がありますが単体で使っているので全てOFFです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Distortion&lt;/h3&gt;
&lt;p&gt;高調波歪みとノイズ&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;相対的に同じくらいのレベルなので大丈夫そう。目立ってDistortionが大きいところはない。&lt;/p&gt;
&lt;h3&gt;Impulse&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;250msで急に落ちてる。距離換算すると85mだが、それっぽい原因がわからない。部屋の特性かなと。&lt;/p&gt;
&lt;h3&gt;RT60&lt;/h3&gt;
&lt;p&gt;どのくらい残響が収まるのに時間がかかったか。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;T30で169msなので残響が少ない。物が多いからかな。&lt;/p&gt;
&lt;h3&gt;Clarity&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;100%に近いので良い！&lt;/p&gt;
&lt;h3&gt;Waterfall&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;低音の残響が多め。SPFで出てた、3〜4kHzが大きめ。&lt;/p&gt;
&lt;h3&gt;Spectrogram&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;p&gt;めちゃくちゃわかりやすい。&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/watch?v=9TVkrzxjNRo&lt;/p&gt;
&lt;p&gt;他の動画も見ましたけど、このかた、すごい知識量。理論的です。いままで音響の世界は定性的なよくわからない表現が多くて困ってましたが、定量的に解説してくれているので　その理由が明らかになります。&lt;/p&gt;
&lt;p&gt;っていうか、&lt;a href=&quot;https://www.linkedin.com/in/yoshiyuki-kobayashi-52023212/?locale=ja_JP&quot;&gt;SONYの主任研究員&lt;/a&gt;ですね。専門は機械学習のようです。オーディオは趣味っぽい。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;さすがGENELECです。スピーカー性能に問題ないです。左右差もありません。&lt;/p&gt;
&lt;p&gt;リスニングしていても不満は無いので。（たまに重低音がほしいときはありますが）&lt;/p&gt;
</content:encoded></item><item><title>LLMS.txt: AI時代のWebサイト最適化ガイド</title><link>https://blog.teraren.com/posts/llmtxt-in-action/</link><guid isPermaLink="true">https://blog.teraren.com/posts/llmtxt-in-action/</guid><description>1. **/llms.txt**</description><pubDate>Thu, 20 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3行まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;主要な LLM プラットフォームが対応し、効率的なサイト情報提供が可能になります。&lt;/li&gt;
&lt;li&gt;NotebookLM などのツールを使って、サイトの情報を効果的に活用できます。&lt;/li&gt;
&lt;li&gt;自分のサイト 2 つを LLMS.txt に対応し、NotebookLM にナレッジとして組み入れて遊んでみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;なぜLLMS.txtか？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2024 年末から注目度が上昇&lt;/li&gt;
&lt;li&gt;日本国内での認知度が向上&lt;/li&gt;
&lt;li&gt;主要 LLM プラットフォームが積極的に対応&lt;/li&gt;
&lt;li&gt;Web サイトの新しい標準として確立しつつある&lt;/li&gt;
&lt;li&gt;自分が書いた blog の RAG 用データとして使えそう&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;LLMS.txtとは&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;LLM 向けの構造化された Web サイト情報提供ファイル&lt;/li&gt;
&lt;li&gt;2024 年 9 月に Jeremy Howard 氏が &lt;a href=&quot;https://llmstxt.org/&quot;&gt;提案&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Markdown 形式による構造化と標準化&lt;/li&gt;
&lt;li&gt;AI が効率的に解析可能な形式&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/AnswerDotAI/llms-txt&quot;&gt;詳細仕様&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;従来のWebファイルとの違い&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ファイル&lt;/th&gt;
&lt;th&gt;目的&lt;/th&gt;
&lt;th&gt;対象&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;robots.txt&lt;/td&gt;
&lt;td&gt;クローラーのアクセス制御&lt;/td&gt;
&lt;td&gt;検索エンジン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sitemap.xml&lt;/td&gt;
&lt;td&gt;インデックス可能なページリスト&lt;/td&gt;
&lt;td&gt;検索エンジン&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLMS.txt&lt;/td&gt;
&lt;td&gt;サイト情報の効率的な提供&lt;/td&gt;
&lt;td&gt;AI（LLM）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;LLMS.txtとrobots.txtの仕様の関係性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;仕様レベルでの関係性は無い。&lt;/li&gt;
&lt;li&gt;robots.txt のほうが広く知られているので llms.txt への参照を追加する可能性はあると思う。&lt;/li&gt;
&lt;li&gt;robots.txt は &lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc9309&quot;&gt;RFC 9309&lt;/a&gt;で仕様化されているが、LLMS.txtはRFCではない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;LLMS.txtの種類&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;/llms.txt&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;サイト構造のサマリー&lt;/li&gt;
&lt;li&gt;コンパクトな情報提供&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;/llms-full.txt&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;完全なドキュメント内容&lt;/li&gt;
&lt;li&gt;詳細な情報を含む&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;llms.txtの中身の例&lt;/h3&gt;
&lt;p&gt;拡張子は txt ですが中身は Markdown です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# プロジェクト名

&amp;gt; 概要説明

## ドキュメント

- [リンクタイトル](URL): 詳細説明

## 例

- [サンプル](URL)

## その他

- [オプショナルリンク](URL)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;どこまでが仕様で、どこまでが自由記述なのか分かりづらいですが、Markdownで書かれた内容はすべて自由記述です。&lt;/p&gt;
&lt;h3&gt;導入のメリット予想&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;LLMによる効率的なサイト理解と情報抽出&lt;/li&gt;
&lt;li&gt;将来のAIモデル学習時の優先的なインデックス化&lt;/li&gt;
&lt;li&gt;サービスの自動化・統合の促進
&lt;ul&gt;
&lt;li&gt;例：LLMを介したサービス利用の自動化&lt;/li&gt;
&lt;li&gt;APIやサービス機能の効率的な活用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;事例I：&lt;a href=&quot;https://docs.anthropic.com/llms.txt&quot;&gt;Anthropic&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# Anthropic

## Docs

- [Get API Key](https://docs.anthropic.com/en/api/admin-api/apikeys/get-api-key)
- [List API Keys](https://docs.anthropic.com/en/api/admin-api/apikeys/list-api-keys)
- [Update API Keys](https://docs.anthropic.com/en/api/admin-api/apikeys/update-api-key)
- [Create Invite](https://docs.anthropic.com/en/api/admin-api/invites/create-invite)
- [Delete Invite](https://docs.anthropic.com/en/api/admin-api/invites/delete-invite)
- [Get Invite](https://docs.anthropic.com/en/api/admin-api/invites/get-invite)


省略
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;事例：&lt;a href=&quot;https://sdk.vercel.ai/llms.txt&quot;&gt;Vercel&lt;/a&gt;&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#---
title: Node.js HTTP Server
description: Learn how to use the AI SDK in a Node.js HTTP server
tags: [&apos;api servers&apos;, &apos;streaming&apos;]
---

# Node.js HTTP Server

You can use the AI SDK in a Node.js HTTP server to generate text and stream it to the client.

## Examples
&amp;lt;snip&amp;gt;
&amp;lt;Note&amp;gt;
  The examples use the OpenAI `gpt-4o` model. Ensure that the OpenAI API key is
  set in the `OPENAI_API_KEY` environment variable.
&amp;lt;/Note&amp;gt;

**Full example**: [github.com/vercel/ai/examples/node-http-server](https://github.com/vercel/ai/tree/main/examples/node-http-server)

### Data Stream

You can use the `pipeDataStreamToResponse` method to pipe the stream data to the server response.

省略
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;LLMS.txt対応サイトの一覧&lt;/h3&gt;
&lt;p&gt;LLMSに対応しているサイトのリストは以下で見られます。
https://llmstxt.site/
https://directory.llmstxt.cloud/&lt;/p&gt;
&lt;h3&gt;自社サービスをLLMS.txtに対応するアプローチ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;LLMに単純にテキストファイルを作らせる&lt;/li&gt;
&lt;li&gt;LLMに実装を作らせる&lt;/li&gt;
&lt;li&gt;仕様書を流用する&lt;/li&gt;
&lt;li&gt;WordPressなら&lt;a href=&quot;https://wordpress.org/plugins/website-llms-txt/&quot;&gt;plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;良さげな使い方&lt;/h2&gt;
&lt;p&gt;NotebookLMに突っ込んで、音声サマリーを作ったり、サマリーを作ったり、FAQを作ったりするのが良いとのことです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-20-03-52-47.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;早速試してみましょう。&lt;/p&gt;
&lt;h2&gt;個人開発しているサイト(郵便番号検索API)に導入&lt;/h2&gt;
&lt;p&gt;エンドポイントURLはこちらです。&lt;/p&gt;
&lt;p&gt;https://postcode.teraren.com/llms.txt
https://postcode.teraren.com/llms-full.txt&lt;/p&gt;
&lt;p&gt;Claude 3.5 Sonnetに書かせました。リポジトリのデータを元に作っているはずなのに結構間違った情報で作られたので人間が加筆修正しています。&lt;/p&gt;
&lt;p&gt;それでもまだ足りていないですが、とりあえず主要なAPIは解説されているのでこれで良しとしてみます。&lt;/p&gt;
&lt;p&gt;Clineでリポジトリを開いた状態で打ち込んだプロンプトは以下です。llms.txtが新しいのでClaude 3.5が知らなかったので仕様のURLを渡してます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;llms.txt作って。llms.txtの仕様はhttps://llmstxt.org/です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;ソースコード抜粋&lt;/h3&gt;
&lt;p&gt;Ruby on Railsで実装しているので少しコードを追加するだけで実装できました。&lt;/p&gt;
&lt;p&gt;一部抜粋しておきます。&lt;/p&gt;
&lt;p&gt;@controller&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;+  def llms_txt
+    expires_in 1.day, public: true
+    response.content_type = &apos;text/markdown&apos;
+    render template: &apos;home/llms&apos;, formats: [:text]
+  end
+
+  def llms_full_txt
+    expires_in 1.day, public: true
+    response.content_type = &apos;text/markdown&apos;
+    render template: &apos;home/llms_full_txt&apos;, formats: [:text]
+  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;@routes&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;+  get &apos;/llms.txt&apos; =&amp;gt; &apos;home#llms_txt&apos;, :format =&amp;gt; false
+  get &apos;/llms-full.txt&apos; =&amp;gt; &apos;home#llms_full_txt&apos;, :format =&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;@view&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;+++ b/app/views/home/llms.text.erb
@@ -0,0 +1,85 @@
+# Japanese Postcode Search
+
+&amp;gt; A comprehensive Japanese postcode search service that provides detailed address information, including buildings and offices, with support for Japanese, kana, and romanized text.
+
+This service maintains a database of Japanese postcodes with associated address information at multiple levels (prefecture, city, 
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;NotebookLMに入れて使ってみる&lt;/h3&gt;
&lt;p&gt;短い方のドキュメントを1つ入れるだけです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-20-04-14-38.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;赤坂の郵便番号を調べる問い合わせ方法を聞いてみると、ちゃんと返ってきます。長ったらしいですけど。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-20-04-16-01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;API問い合わせのためのRubyクライアントライブラリを書かせてみました。良い感じに作ってくれました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-20-04-16-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;API問い合わせのためのgoクライアントライブラリを書かせてみました。エンティティの定義が空っぽですが作ってくれました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-20-04-16-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;WordPressで導入してみる&lt;/h2&gt;
&lt;p&gt;自社のコーポレートサイトとか、テックブログとか、SDKなどを公開する際に使えるかと思います。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://wordpress.org/plugins/website-llms-txt/&quot;&gt;プラグイン&lt;/a&gt;をインストールして有効化するだけで完了。&lt;/p&gt;
&lt;p&gt;こちらの個人ブログで有効化してみました。記事のタイトルの一覧と、記事のテキストがズラッと並びます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl -s &apos;https://blog.teraren.com/llms.txt&apos; | head -n 20
# Matsubo Tech Blog

&amp;gt; Ruby on Rails, Web Services, Software Development, Startups


## 固定ページ

- [History](https://blog.teraren.com/history-of-this-blog/): このブログのヒストリー 2003/5/2...
- [Author](https://blog.teraren.com/yuki-matsukura/): 概要 こんにちは！matsuboです。2...
- [Privacy policy](https://blog.teraren.com/privacy-policy/): 私たちについて 私たちのサイトアドレスは...
- [Copyright](https://blog.teraren.com/copyright/): https://blog. terare...
- [About Me](https://blog.teraren.com/about/): see: https://www. wa...

## 投稿

- [タブレット端末を壁掛けして情報端末として使うといろいろ捗る](https://blog.teraren.com/2024/08/27/tablet-on-the-wall/): 概要 半年ぐらい前から、壁にタブレット端...
- [Web魚拓: 「研究」と「勉強」の違い](https://blog.teraren.com/2024/08/27/diff-study-research/): 概要 過去に何度も参照している以下のペー...
- [寝室のライトを「とったらリモコン」に変更して快適子育て生活](https://blog.teraren.com/2024/08/15/downlight-remote-control/): 概要 リビングの調光スイッチを「とったら...
- [生成系AIサービスから自分のサイトをブロックする方法](https://blog.teraren.com/2024/08/02/block-llm-crawler/): サイトのトップに以下のrobots. t...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;NotebookLM に入れて、LLMS.txt を元にしたサマリーを出力してみます。
レジュメにかけそうな紹介文を書いてくれてます。
（Google のロケールが英語っぽいので英語出でてきちゃってます）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-20-04-27-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ブログの内容に関連した問い合わせをしてみます。
文章ではまとめてないけど拾ってきて理解してくれています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-20-04-35-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;会話形式のサマリーが作れます。&lt;/p&gt;
&lt;p&gt;特に意味は無いけど、クオリティが高いです。Rebuild みたいな感じで 2 人が対話を聞いていくことで人間が学習できます。。
音声で人間が知識をインプットするときにはちょうど良さそう。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-20-04-42-04.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://notebooklm.google.com/notebook/ceca14a6-8624-4be4-aee1-63c6f0231e88/audio&quot;&gt;今回のサンプル音声&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;右下のところにある機能も面白いです。FAQ の作成、時系列での整理などをショートカットで行えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-20-04-44-57.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;LLMS.txtの考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;戦略的なコンテンツ整備
&lt;ul&gt;
&lt;li&gt;企業情報・サービス説明の構造化&lt;/li&gt;
&lt;li&gt;製品カタログ・技術文書の最適化&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;サービス連携の強化
&lt;ul&gt;
&lt;li&gt;LLM からの API 呼び出しやサービス利用に使えそう&lt;/li&gt;
&lt;li&gt;API・サービス機能の可視化&lt;/li&gt;
&lt;li&gt;他サービスに保管してあるデータを自社で運用している RAG に入れるときのプロトコルとして使うとかも良いかもしれません&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;将来への準備
&lt;ul&gt;
&lt;li&gt;AI エージェント時代への対応&lt;/li&gt;
&lt;li&gt;デジタルプレゼンスの最適化&lt;/li&gt;
&lt;li&gt;Search Engine Optimization とともに LLM Optimization の必要性が高まりそう&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>AIを使ってブラウザ操作を行う事例とツールの紹介</title><link>https://blog.teraren.com/posts/llm-operator/</link><guid isPermaLink="true">https://blog.teraren.com/posts/llm-operator/</guid><description>AI の世界は急速に進化しており、大規模言語モデル（LLM）が自律的にブラウザを操作する能力を獲得しています。この進展は、LLM に目と手を与えるようなものであり、最小限の人間の介入で複雑なタスクを実行できるようになります。本記事では、LL</description><pubDate>Tue, 04 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;AI の世界は急速に進化しており、大規模言語モデル（LLM）が自律的にブラウザを操作する能力を獲得しています。この進展は、LLM に目と手を与えるようなものであり、最小限の人間の介入で複雑なタスクを実行できるようになります。本記事では、LLM によるブラウザ操作の最新の進展を探り、可能性の限界を押し広げる 3 つの強力なツールを紹介します。&lt;/p&gt;
&lt;h2&gt;重要なポイント&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ブラウザを操作する LLM は、目と手を与えられたようなものです。&lt;/li&gt;
&lt;li&gt;最近の LLM によるブラウザ操作の進展は目覚ましいものがあります。&lt;/li&gt;
&lt;li&gt;3 つのブラウザ操作ツールを実際に紹介します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;なぜ重要なのか&lt;/h2&gt;
&lt;p&gt;LLM がブラウザ操作を扱うことの利点は何でしょうか？　LLM は自律的にウェブインタフェースをナビゲートし、抽象的な指示に従い、目標に向かって独立して進むことができます。この強化により、LLM の能力が大幅に拡張され、より多用途で強力になります。&lt;/p&gt;
&lt;h3&gt;ブラウザ操作の最近の動向&lt;/h3&gt;
&lt;p&gt;OpenAI は Operator を発表しましたが、日本ではまだリリースされていません。専用アプリケーション内で動作し、シームレスなブラウザ操作を実現しているようです。&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/watch?v=CSE77wAdDLg&lt;/p&gt;
&lt;h3&gt;OpenAPI Operatorの使用例&lt;/h3&gt;
&lt;p&gt;デモの中では以下のようなユースケースが紹介されていました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;タスク自動化&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;繰り返し業務の自動処理&lt;/li&gt;
&lt;li&gt;複数アプリケーション間のワークフロー連携&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;インテリジェントアシスタント&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自然言語でのユーザー問い合わせへの即時応答&lt;/li&gt;
&lt;li&gt;個人スケジュール管理とリマインダー設定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;データ分析支援&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大規模データセットからの傾向抽出&lt;/li&gt;
&lt;li&gt;予測モデルの自動構築と可視化&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;開発者向けツール&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コード生成とデバッグ支援&lt;/li&gt;
&lt;li&gt;API 連携の自動セットアップ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;カスタマーサポート&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;24 時間対応のチャットボット&lt;/li&gt;
&lt;li&gt;問い合わせのトリアージと優先度付け&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;タスク自動化&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;繰り返し業務の自動処理&lt;/li&gt;
&lt;li&gt;複数アプリケーション間のワークフロー連携&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;インテリジェントアシスタント&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自然言語でのユーザー問い合わせへの即時応答&lt;/li&gt;
&lt;li&gt;個人スケジュール管理とリマインダー設定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;データ分析支援&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大規模データセットからの傾向抽出&lt;/li&gt;
&lt;li&gt;予測モデルの自動構築と可視化&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;開発者向けツール&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コード生成とデバッグ支援&lt;/li&gt;
&lt;li&gt;API 連携の自動セットアップ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;カスタマーサポート&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;24 時間対応のチャットボット&lt;/li&gt;
&lt;li&gt;問い合わせのトリアージと優先度付け&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ブラウザ操作の例&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://note.com/teramotodaiki/n/n9340513acf56&quot;&gt;Devinの観察日記&lt;/a&gt;では、居酒屋でウェブ注文のQRコードをスキャンし、口頭で指示を出して注文する例が紹介されています。その精度は驚くべきもので、一読の価値があります。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-04-00-28-00.png&quot; alt=&quot;w:800&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;既存のツールの紹介&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.openhands.com&quot;&gt;OpenHands&lt;/a&gt;: LLM を活用したプログラミングツール&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.webpilot.com&quot;&gt;WebPilot&lt;/a&gt;: Chrome Extension で動く&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.browseruseui.com&quot;&gt;Browser Use UI&lt;/a&gt;: ホスト OS のブラウザを子プロセスで立ち上げて操作&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;OpenHandsとは&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;無料&lt;/li&gt;
&lt;li&gt;本来は LLM を使ってシステム開発をするアプリケーション&lt;/li&gt;
&lt;li&gt;LLM は外部の API 呼び出し&lt;/li&gt;
&lt;li&gt;実行環境は Docker コマンド 1 発で立ち上がる&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;docker run -it --rm --pull=always \
  -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:0.22-nikolaik \
  -e LOG_ALL_EVENTS=true \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v ~/.openhands-state:/.openhands-state \
  -p 3100:3000 \
  --add-host host.docker.internal:host-gateway \
  --name openhands-app \
  docker.all-hands.dev/all-hands-ai/openhands:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;動作アーキテクチャ&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;コンテナ上で動作する&lt;/li&gt;
&lt;li&gt;ヘッドレスブラウザを裏で立ち上げている。&lt;/li&gt;
&lt;li&gt;1つの命令でコンテナを作り直しているので初回は遅い。安全。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;プロンプトに指示をしてみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-04-00-25-23.png&quot; alt=&quot;w:700&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ブラウザでYahoo!のニュースページに飛んで、ニュースの要約を作ってくれました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-04-00-25-57.png&quot; alt=&quot;w:700&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Webページが複雑なUIだと処理が止まる。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image.png&quot; alt=&quot;w:500&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;WebPilotとは&lt;/h3&gt;
&lt;p&gt;少し毛色が違いますが便利なUXなので紹介しておきます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chromeブラウザプラグインで使うのが一番良いUX&lt;/li&gt;
&lt;li&gt;既存のブラウザを使えるのが良い。&lt;/li&gt;
&lt;li&gt;独自LLMの無料枠あり。APIでLLMも呼べる。&lt;/li&gt;
&lt;li&gt;(ちょっと毛色が違うけど便利だから紹介)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;( このUXはブラウザ側でAI APIsとして同じような機能が実装されるはずです)&lt;/p&gt;
&lt;p&gt;Web上のクイズを解かせてみました。 Web試験と相性が良さそうです。
下の部分のモーダルがWebPilotです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-1.png&quot; alt=&quot;w:600&quot; /&gt;&lt;/p&gt;
&lt;p&gt;思考の過程を表示してくれて、それっぽい論理を展開してくれていましたが&lt;strong&gt;見事に不正解です&lt;/strong&gt;。5問ほどやらせてみましたが、2問は不正解でした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-04-01-00-25.png&quot; alt=&quot;w:1000&quot; /&gt;&lt;/p&gt;
&lt;p&gt;長文のサマリーもやらせてみました。
良い感じです。もう少し文量を減らして要点を明確にはできそうですけど合格点かなと思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-04-01-02-43.png&quot; alt=&quot;w:700&quot; /&gt;&lt;/p&gt;
&lt;p&gt;もう少し具体的な指示の元サマリーを作成してみましたが、良い感じに動いています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-04-00-09-32.png&quot; alt=&quot;w:600&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Browser-use-webui&lt;/h3&gt;
&lt;p&gt;今のところ、一番これが良い感じに動きます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OSS&lt;/li&gt;
&lt;li&gt;見た目が面白い&lt;/li&gt;
&lt;li&gt;Xでよく紹介されているやつはこれ&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;セットアップ&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/browser-use/web-ui.git
cd web-ui
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;uv venv --python 3.11
source .venv/bin/activate
uv pip install -r requirements.txt
playwright install
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;cat .env
CHROME_PATH=&quot;/Applications/Google Chrome.app/Contents/MacOS/Google Chrome&quot;
CHROME_USER_DATA=&quot;~/Library/Application Support/Google/Chrome/Default&quot;

ANONYMIZED_TELEMETRY=false

OPENAI_API_KEY=sk-proj-*****
# ANTHROPIC_API_KEY=********
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;実行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python webui.py --ip 127.0.0.1 --port 7788
open http://127.0.0.1:7788/
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;setting&lt;/h4&gt;
&lt;p&gt;ブラウザ上から追加の設定。普段使っているブラウザの Cookie を使いたければ、シークレットブラウザではなく自分のブラウザを立ち上げるように設定を変更します&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/image-2.png&quot; alt=&quot;w:800&quot; /&gt;&lt;/p&gt;
&lt;p&gt;「NISSAN の EV を試乗予約して！」という感じの雑なプロンプトを投げるとどんどん先に進んで操作してくれます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-04-01-19-50.png&quot; alt=&quot;w:700&quot; /&gt;&lt;/p&gt;
&lt;p&gt;試乗できる EV を探してる&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-04-01-55-15.png&quot; alt=&quot;w:700&quot; /&gt;&lt;/p&gt;
&lt;p&gt;EV を選んで、次へ進んで近くのディーラーを探してる&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-04-01-56-21.png&quot; alt=&quot;w:700&quot; /&gt;&lt;/p&gt;
&lt;p&gt;適当な名前で申し込みを入れようとしている。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/02/2025-02-04-01-57-43.png&quot; alt=&quot;w:700&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ここで、停止。スクロールをうまく行ってくれません。手動でスクロールしてあげれば先に進みますが送信ボタンまでは押してくれませんでした。&lt;/p&gt;
&lt;h4&gt;操作動画&lt;/h4&gt;
&lt;p&gt;https://youtu.be/Hqelnd6EFag&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;どれも動作が重いので何度も PC が不安定になる&lt;/li&gt;
&lt;li&gt;OpenAI Operator は OpenHands に近そう&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;おまけ&lt;/h2&gt;
&lt;p&gt;AI で確定申告をやらせてみた。note に詳細をまとめてあります。&lt;/p&gt;
&lt;p&gt;https://note.com/matsubokkuri/n/nc976d5258e37&lt;/p&gt;
</content:encoded></item><item><title>オンライン消費者調査の現在と未来：LLMがもたらすパラダイムシフト</title><link>https://blog.teraren.com/posts/customer-research/</link><guid isPermaLink="true">https://blog.teraren.com/posts/customer-research/</guid><description>日本のマーケティングリサーチ市場の変遷を振り返り、LLMが定量・定性調査の各工程をどう変革し、リサーチャーの役割をどう変えるかを考察します。</description><pubDate>Sun, 05 Jan 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;strong&gt;はじめに&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;消費者理解を起点とするマーケティング活動において、オンラインでの消費者調査は不可欠な羅針盤として機能してきた。その手法はテクノロジーの進化と共に変容を遂げ、特に2020年代に入り、大規模言語モデル（LLM）という新たな技術的潮流が、業界の根幹を揺るがすほどのパラダイムシフトを予感させている。&lt;/p&gt;
&lt;p&gt;本稿では、オンライン消費者調査の過去から現在に至るまでの軌跡をデータに基づき概観し、その標準的なワークフローをより詳細に定義する。その上で、LLMが各ワークフローにどのような変革をもたらし、リサーチャーの役割をどう変えていくのかを論じる。最後に、AIによる代替の可能性とその難易度を評価し、業界が迎える未来の姿を展望したい。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/07/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;第1章：オンラインリサーチ市場の変遷&lt;/strong&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;1.1. 市場規模とインターネット調査の台頭&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;日本のマーケティングリサーチ市場は、長らく安定した成長を続けてきた。&lt;a href=&quot;https://lab.testee.co/h2r-scale-of-internetresearch/&quot;&gt;日本マーケティング・リサーチ協会（JMRA）の調査によれば、2017年度に2,147億円だった市場規模は、2022年には2,590億円へと拡大している&lt;/a&gt;。この成長を牽引してきたのが、インターネット調査である。&lt;/p&gt;
&lt;p&gt;2002年度にはアドホック調査市場のわずか10%（約80億円）に過ぎなかった&lt;a href=&quot;https://iwparchives.jp/files/pdf/iwp2004/iwp2004-ch06-01-p294.pdf&quot;&gt;インターネットリサーチは、時間とコストの削減効果を武器に急成長を遂げ、訪問調査や郵送調査からのシフトを加速させた&lt;/a&gt;。その結果、&lt;a href=&quot;https://www.jmra-net.or.jp/activities/trend/investigation/20230718.html&quot;&gt;2010年代後半にはアドホック調査の過半数を占めるに至った&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;しかし、その成長にも変化の兆しが見える。&lt;a href=&quot;https://www.jmra-net.or.jp/activities/trend/investigation/20230718.html&quot;&gt;2021年から2022年にかけて、インターネット調査の成長率は100.5%と伸び悩み、一方でグループインタビューなどを含む既存手法が112.1%と復調した&lt;/a&gt;。さらに&lt;a href=&quot;https://www.jmra-net.or.jp/activities/trend/investigation/20240723.html&quot;&gt;2023年には、インターネット調査が前年比98.8%とマイナスに転じ、市場全体が停滞する一因となった&lt;/a&gt;。これは、単なる量的拡大の時代の終焉と、リアルな接点を求める「揺り戻し」や、より複合的な調査手法への移行を示唆しているのかもしれない。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;1.2. 定量調査と定性調査の役割&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;市場の中心が、量的な傾向を把握する「定量調査」、特にオンラインアンケートであったことは論を俟たない。一方で、消費者の深層心理や行動の背景にある「なぜ」を探る&lt;a href=&quot;https://www.macromill.com/service/column/entry-004/&quot;&gt;「定性調査」（グループインタビュー、デプスインタビューなど）も、仮説構築やインサイト発見のために重要な役割を担い続けてきた&lt;/a&gt;。近年のリアル調査への回帰は、この定性的な理解への価値が再認識されていることの表れとも考えられる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/01/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;第2章：現代のオンラインリサーチの構造&lt;/strong&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;2.1. 業界地図と主要プレイヤー&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://qiqumo.jp/contents/knowhow/2666/&quot;&gt;マーケティングリサーチ業界は、売上高20億円未満の企業が8割を占めるなど、多数の中小規模プレイヤーによって構成されている&lt;/a&gt;。その中で、プライム市場に上場する&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;インテージホールディングス&lt;/strong&gt;、&lt;strong&gt;マクロミル&lt;/strong&gt;、&lt;strong&gt;クロス・マーケティンググループ&lt;/strong&gt;の&lt;a href=&quot;https://www.kotora.jp/c/74659-2/&quot;&gt;3社が大手として市場を牽引している&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/01/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;インテージグループ:&lt;/strong&gt; 1960年創業の国内最大手。&lt;a href=&quot;https://www.intageholdings.co.jp/ir/investor/naruhodo/advantage/&quot;&gt;60年以上の歴史で培った信頼性と、SCI®（全国消費者パネル調査）に代表される高品質・大規模なパネルデータが最大の強みである&lt;/a&gt;。近年は&lt;a href=&quot;https://www.intage-technosphere.co.jp/company/strength/&quot;&gt;AIやデータハンドリング技術への投資も積極的で、データ解析力とソリューション提供能力で他をリードする&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;マクロミル:&lt;/strong&gt; オンラインリサーチで国内トップシェアを誇る。&lt;a href=&quot;https://www.fisco.co.jp/wordpress/wp-content/uploads/FISCO/macromill20241001.pdf&quot;&gt;自社・提携合わせて3,600万人規模の広範なパネルネットワークを武器に、年間2万件以上の調査実績を持つ&lt;/a&gt;。&lt;a href=&quot;https://invest-n.jp/ir/1628/&quot;&gt;創業時からリサーチ業務の分業制を導入し、各専門人材の育成による効率性とスピードを強みとする&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;クロス・マーケティンググループ:&lt;/strong&gt; &lt;a href=&quot;https://www.cross-m.co.jp/company&quot;&gt;国内最大級の1,285万人のパネルネットワークを活用し、年間1万件以上の調査実績を持つ&lt;/a&gt;。&lt;a href=&quot;https://www.cross-m.co.jp/feature&quot;&gt;リサーチ事業を中核としながら、データマーケティングやITソリューションなど事業を多角化し、顧客の課題解決に一気通貫で対応する「総合力」を特徴とする&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの大手は、独自の強固なパネル基盤とテクノロジーへの投資を背景に、業界内での存在感を高めている。一方で、こうした大手とは異なるアプローチで市場に新たな価値を提案するスタートアップも登場している。例えば、&lt;a href=&quot;https://corporate.minedia.com/&quot;&gt;株式会社マインディア&lt;/a&gt;のように、テクノロジーを活用してオンラインでの定性調査をより手軽かつ迅速に実施できるプラットフォームを提供する企業は、従来の時間とコストが課題であった定性調査の民主化を推し進めている。こうした動きは、リサーチ業界におけるイノベーションの新たな潮流となっている。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2.2. オンライン定量調査の標準的ワークフロー&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;オンライン定量調査、特にインターネットリサーチは、多くのステップを経て実施される。その標準的なワークフローは以下のように分解できる。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;ビジネス課題のヒアリング・要件定義:&lt;/strong&gt; クライアントが抱える課題を明確にする。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;調査目的・仮説の設定:&lt;/strong&gt; 何を明らかにするための調査なのか、その結果どういった仮説が検証できるのかを定義する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;調査手法・対象者条件の決定:&lt;/strong&gt; 調査手法（Webアンケートなど）や対象者の属性（年齢、性別など）を決定する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;質問項目の洗い出し:&lt;/strong&gt; 仮説検証に必要な質問項目を網羅的にリストアップする。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;調査票ドラフト作成:&lt;/strong&gt; 洗い出した項目を基に、回答者が答えやすいように質問文や選択肢を構成する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;調査票のロジック設計・確認:&lt;/strong&gt; 特定の回答をした人だけが次の質問に進むといった分岐（スキップロジック）を設計・確認する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;アンケート画面作成（プログラミング）:&lt;/strong&gt; 調査票をWebアンケートシステム上で動作するようにプログラミングする。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;テスト配信・デバッグ:&lt;/strong&gt; 画面表示やロジックに誤りがないか、少人数にテスト配信して確認する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;本配信・データ収集:&lt;/strong&gt; 対象者全体にアンケートを配信し、データを回収する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;データクリーニング・集計:&lt;/strong&gt; 不誠実な回答や矛盾した回答を除外し、データを集計する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;集計表・グラフ作成:&lt;/strong&gt; 集計結果を基に、クロス集計表やグラフを作成する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;分析・考察:&lt;/strong&gt; データから傾向を読み解き、示唆を導き出す。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;レポート作成・報告:&lt;/strong&gt; 分析結果をまとめてクライアントに報告する。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/01/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;2.3. オンライン定性調査の標準的ワークフロー&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;オンラインでのグループインタビューなどに代表される定性調査は、より人間系のスキルが求められるプロセスで構成され、そのワークフローは以下のように詳細化できる。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;調査目的・課題の明確化:&lt;/strong&gt; なぜその調査が必要なのか、核心的な問いを定める。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対象者条件の設定（リクルーティング要件定義）:&lt;/strong&gt; どのような経験や価値観を持つ人に話を聞くべきかを詳細に定義する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インタビューフローの設計:&lt;/strong&gt; 対象者から深いインサイトを引き出すための質問の流れや構成を設計する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;募集画面の作成:&lt;/strong&gt; 対象者を募集するための告知ページや文面を作成する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;スクリーニングアンケートによる対象者選定:&lt;/strong&gt; 応募者の中から、条件に合致する対象者をアンケートで絞り込む。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対象者への参加依頼・調整:&lt;/strong&gt; 選定された対象者に連絡を取り、インタビューの日時や方法を調整する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インタビューの実施・進行（モデレーション）:&lt;/strong&gt; 場の空気を作り、対象者がリラックスして本音を話せるようにインタビューを進行する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;録画・録音データの確認:&lt;/strong&gt; インタビュー内容を後から確認できるように、記録データを確認・整理する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文字起こし・発言録作成:&lt;/strong&gt; インタビューの発言をすべてテキスト化する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;発言内容の構造化・分析:&lt;/strong&gt; 発言録を読み解き、内容をテーマごとに分類・構造化する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;インサイト抽出・レポート作成:&lt;/strong&gt; 分析結果から本質的な示唆（インサイト）を抽出し、レポートにまとめる。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/01/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2.4. AI活用リサーチの既存事例（国内・海外）&lt;/h3&gt;
&lt;p&gt;LLMによる変革を語る上で、すでに国内外でAIを活用してリサーチ業界の課題解決に取り組む企業が登場していることは注目に値する。これらは未来の潮流を占う試金石と言える。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;【国内事例】AI活用の動向&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;株式会社マインディア:&lt;/strong&gt; オンライン定性調査プラットフォームを提供する同社は、インタビュー後の分析工程の自動化にAIを積極的に活用。従来、多大な時間を要した文字起こし作業に加え、長大な発言録から要点を抽出するサマリー作成、さらには分析結果を基にしたレポート作成の自動化にも取り組んでおり、リサーチャーがより本質的なインサイト発見に集中できる環境を構築している。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;【海外事例】多様なアプローチで価値を創出&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;海外では、より多角的なアプローチでAIを活用するプレイヤーが台頭している。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Quantilope (ドイツ):&lt;/strong&gt; 「End-to-Endの自動化」を掲げ、調査設計から分析、レポーティングまでの一連のプロセスをAIで自動化するプラットフォームを提供。リサーチの全工程を高速化する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zappi (英国):&lt;/strong&gt; 「アジャイルな意思決定」を支援。AIベースの調査テンプレートを事前に設計しておくことで、広告や新商品のコンセプトテストといった特定の調査を高速で繰り返し実行できる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remesh (米国):&lt;/strong&gt; 「大規模定性調査」という新たな領域を開拓。AIモデレーターが数百人規模の参加者とリアルタイムで対話し、その自由回答を瞬時に分析・可視化することで、定性的な深さと定量的な規模感を両立させる。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entropik (インド):&lt;/strong&gt; 「非言語データの活用」に強みを持つ。視線や表情、声色といった感情データをAIで解析し、ユーザーが言葉にしない本音を炙り出す、次世代のUX・広告評価調査を提供する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Black Swan Data (英国):&lt;/strong&gt; 「外部データのインサイト化」に特化。SNSの投稿など、膨大なオープンデータをAIで分析し、消費者の無意識なトピックや未来のトレンドを予測・抽出する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これらの事例から、AIの活用法は一様ではないことがわかる。国内では&lt;strong&gt;マインディア&lt;/strong&gt;のようにインタビュー後の分析工程の自動化に注力する動きがある一方、海外では&lt;strong&gt;Quantilope&lt;/strong&gt;のように全工程の自動化を目指すプレイヤー、&lt;strong&gt;Remesh&lt;/strong&gt;や&lt;strong&gt;Entropik&lt;/strong&gt;のように定性調査の可能性を拡張するプレイヤー、&lt;strong&gt;Black Swan Data&lt;/strong&gt;のように新たなデータソースから価値を生むプレイヤーが存在する。この国内外の潮流は、リサーチ業界がAIによって労働集約的な構造から脱却し、より戦略的で高度なインサイトを提供する産業へと進化していく必然性を示している。&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;第3章：LLMが拓くオンラインリサーチの未来&lt;/strong&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;3.1. ワークフローの自動化と設計例&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;LLMの登場は、前章で定義したワークフローを単に効率化するだけでなく、その実行プロセス自体を再設計する。ここでは、各ワークフローをLLMで自動化するための具体的な設計思想とプロセスを詳述する。&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;3.1.1. 定量調査ワークフローの設計例&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;対象工程：調査票作成からアンケート画面実装まで&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;設計思想:&lt;/strong&gt; リサーチャーの「意図」を自然言語で受け取り、直接実行可能なアンケートシステム用の設定ファイル（JSON, XML等）を生成する「意図-実行変換（Intent-to-Execution）」モデルを構築する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;具体的なプロセス:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;入力（リサーチャーの意図）:&lt;/strong&gt; 「30代男性会社員を対象に、缶コーヒーの飲用習慣に関する調査をしたい。頻度、購入場所、重視点を聴取し、週1回未満のライトユーザーには、その理由を深掘りする質問を追加してほしい」といった自然言語での指示。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLMによる処理（思考連鎖）:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;エンティティ抽出:&lt;/strong&gt; LLMはまず指示を分解し、[対象者: 30代男性会社員]、[テーマ: 缶コーヒー]、[聴取項目: 頻度, 場所, 重視点]、[条件分岐: 週1回未満→理由深掘り]といった構成要素を抽出する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;質問生成:&lt;/strong&gt; 各聴取項目に基づき、具体的な質問文と選択肢を生成する。「Q1. あなたは普段、どのくらいの頻度で缶コーヒーを飲みますか？ (SA) 1. 毎日 2. 週に4-5回... 6. 飲まない」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ロジックの定式化:&lt;/strong&gt; 自然言語のロジックを、システムが解釈可能な形式 &lt;code&gt;{&quot;condition&quot;: &quot;Q1.answer == 6&quot;, &quot;action&quot;: &quot;show_question&quot;, &quot;target&quot;: &quot;Q1_follow_up&quot;}&lt;/code&gt; に変換する。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;出力（実行可能な設定ファイル）:&lt;/strong&gt; 全ての質問とロジックを構造化データ（例：JSON）として出力する。このファイルをアンケートシステムにインポートするだけで、テスト可能な画面が即座に構築される。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;対象工程：分析とレポーティング&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;設計思想:&lt;/strong&gt; 「データ分析エージェント」と「レポーティングエージェント」を連携させるマルチエージェントシステムを構築し、データ投入からレポートドラフト作成までをパイプライン化する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;具体的なプロセス:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;入力:&lt;/strong&gt; 回収済みのアンケートデータ（CSV形式）と、「男女別の購入ブランドランキングと、年代別の飲用頻度の違いに焦点を当てたレポートを作成せよ」という指示。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;データ分析エージェントの実行:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;Code Interpreter機能を持つLLMが、Python（pandas, matplotlib）コードを生成・実行する。&lt;/li&gt;
&lt;li&gt;クロス集計（性別×ブランド、年代×頻度）を行い、統計的に有意な差があるかを検定する。&lt;/li&gt;
&lt;li&gt;結果を可視化するためのグラフ（棒グラフ、円グラフ等）を生成する。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;レポーティングエージェントの実行:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;分析エージェントから出力された集計表やグラフデータを読み込む。&lt;/li&gt;
&lt;li&gt;LLMがそのデータを解釈し、「30代では『毎日飲む』層が45%を占める一方、50代では20%に留まり、健康志向の高まりが示唆される」といったインサイトのテキスト記述を生成する。&lt;/li&gt;
&lt;li&gt;事前に定義されたレポートテンプレートに沿って、タイトル、サマリー、各グラフとそれに対応する考察を自動で配置し、PowerPointやWord形式のドラフトを生成する。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;&lt;strong&gt;3.1.2. 定性調査ワークフローの設計例&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;対象工程：インタビューフローの設計&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;設計思想:&lt;/strong&gt; 優れたモデレーターの思考プロセスを模倣する「ペルソナプロンプティング」を活用し、質の高いインタビューフローのたたき台を生成する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;具体的なプロセス:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;入力:&lt;/strong&gt; 調査企画書（調査背景、目的、対象者プロファイルなど）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLMへの指示（ペルソナ設定）:&lt;/strong&gt; 「あなたは20年の経験を持つベテランモデレーターです。以下の調査企画書に基づき、60分のデプスインタビューのフローを作成してください。導入のアイスブレイクから始め、対象者の生活実態、カテゴリ関与、そして本題の製品評価へと自然に移行する流れを意識してください。各質問には、その質問で何を引き出したいのかという『狙い』も併記すること。」&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;出力:&lt;/strong&gt; 時間配分、具体的な質問例、質問の狙いが明記された、構造化されたインタビューフローが出力される。これにより、リサーチャーはゼロから考えるのではなく、AIが生成した質の高いドラフトを基に、より戦略的な調整に集中できる。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;対象工程：発言録の構造化と分析&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;設計思想:&lt;/strong&gt; 長大な非構造テキストである発言録を、多段階のLLM処理（パイプライン）を通じて、構造化されたインサイトデータへと変換する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;具体的なプロセス:&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;入力:&lt;/strong&gt; インタビューのフルテキスト発言録。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第1段階（セグメンテーション＆要約）:&lt;/strong&gt; LLMが発言録を意味のあるトピック単位（例：「自己紹介」「普段の食生活」「製品Aの第一印象」）に分割し、各セグメントを簡潔に要約する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第2段階（コード化＆ラベリング）:&lt;/strong&gt; 別のLLMが、各発言に対して「ポジティブな感情」「価格への不満」「競合製品Bへの言及」といった分析コード（ラベル）を付与していく。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第3段階（テーマ抽出）:&lt;/strong&gt; 全ての発言録に付与されたコード群をクラスタリングし、「パッケージの高級感が購入の決め手」「後味の悪さがリピートを阻害」といった、複数の発言を横断する共通のインサイトテーマを抽出する。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;出力:&lt;/strong&gt; 重要な発言、それに対応する分析コード、そして抽出されたインサイトテーマが一覧化された分析サマリー。マーケティング担当者がAIに最も期待する「分析・インサイト抽出」を直接的に支援するアウトプットとなる。&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;3.2. AIによる代替の難易度評価&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;LLMは万能ではない。詳細化されたワークフローの各ステップをAIが代替する難易度には明確な差が存在する。&lt;/p&gt;
&lt;h4&gt;定量調査&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/01/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;難易度&lt;/p&gt;
&lt;p&gt;ワークフローのステップ&lt;/p&gt;
&lt;p&gt;理由・具体例&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;高&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ビジネス課題のヒアリング・要件定義&lt;/p&gt;
&lt;p&gt;分析・考察&lt;/p&gt;
&lt;p&gt;クライアントの暗黙的なニーズを汲み取り、ビジネス全体の文脈を理解した上で、データの裏にある本質的な意味を解釈し、戦略的な示唆を導き出す能力は、依然として高度な人間的知性が不可欠。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;中&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;調査目的・仮説の設定&lt;/p&gt;
&lt;p&gt;調査票のロジック設計・確認&lt;/p&gt;
&lt;p&gt;レポート作成・報告&lt;/p&gt;
&lt;p&gt;LLMは優れたドラフトを生成できるが、最終的な妥当性の判断や、クライアントの特性に合わせた微調整、説得力のあるストーリーテリングには人間の介入が必要。特に複雑なロジックの最終確認は重要。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;低&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;調査手法・対象者条件の決定&lt;/p&gt;
&lt;p&gt;質問項目の洗い出し&lt;/p&gt;
&lt;p&gt;調査票ドラフト作成&lt;/p&gt;
&lt;p&gt;アンケート画面作成&lt;/p&gt;
&lt;p&gt;テスト配信・デバッグ&lt;/p&gt;
&lt;p&gt;本配信・データ収集&lt;/p&gt;
&lt;p&gt;データクリーニング・集計&lt;/p&gt;
&lt;p&gt;集計表・グラフ作成&lt;/p&gt;
&lt;p&gt;明確なルールやパターンに基づいており、自動化との親和性が非常に高い領域。調査票作成から画面作成までの自動化はすでに実用化が進んでいる。データ処理や集計も大半が自動化可能。&lt;/p&gt;
&lt;h4&gt;定性調査&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/01/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;難易度&lt;/p&gt;
&lt;p&gt;ワークフローのステップ&lt;/p&gt;
&lt;p&gt;理由・具体例&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;高&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;調査目的・課題の明確化&lt;/p&gt;
&lt;p&gt;インタビューの実施・進行（モデレーション）&lt;/p&gt;
&lt;p&gt;インサイト抽出・レポート作成&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;モデレーション&lt;/strong&gt;は、相手の非言語的サイン（表情、声色）を読み取り、信頼関係を築き、予期せぬ発言を深掘りする共感性と即興性が求められ、AIによる完全な代替は最も困難。ただし、「AIモデレーター」のような、構造化されたヒアリングを自動化するサービスも登場し始めており、部分的な活用は進む可能性がある。&lt;br /&gt;
&lt;strong&gt;インサイト抽出&lt;/strong&gt;は、複数の発言の断片を繋ぎ合わせ、背景にある文化や価値観までを洞察する飛躍的な思考を要するため、難易度が高い。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;中&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;対象者条件の設定&lt;/p&gt;
&lt;p&gt;発言内容の構造化・分析&lt;/p&gt;
&lt;p&gt;LLMはペルソナ定義の支援や、発言録の分類・タグ付けは高精度に行える。しかし、その分類が調査目的に対して本当に意味のあるものか、どの分析軸が重要かを見極める最終判断は人間に委ねられる。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;低&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;インタビューフローの設計&lt;/p&gt;
&lt;p&gt;募集画面の作成&lt;/p&gt;
&lt;p&gt;スクリーニングアンケートによる対象者選定&lt;/p&gt;
&lt;p&gt;対象者への参加依頼・調整&lt;/p&gt;
&lt;p&gt;録画・録音データの確認&lt;/p&gt;
&lt;p&gt;文字起こし・発言録作成&lt;/p&gt;
&lt;p&gt;目的や条件が明確であれば、LLMは高品質なドラフト作成や、単純な事務作業、音声のテキスト化を高効率に実行できる。これらは最も早期にAIに置き換わる領域となる。&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;結論&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;オンライン消費者調査の世界は、LLMという強力な触媒を得て、今まさに大きな化学反応の渦中にある。市場の成長は踊り場を迎え、プレイヤーは新たな付加価値の創出を迫られている。この状況下で、AIは脅威ではなく、リサーチの価値を再定義するための強力なパートナーとなるだろう。&lt;/p&gt;
&lt;p&gt;調査票のプログラミング、文字起こし、自由回答の分類、レポートのドラフト作成といった、これまで多大な時間を要した定型的かつ労働集約的なタスクは、今後急速にAIに代替されていく。その結果、リサーチャーの役割は、AIを使いこなす「オペレーター」から、AIでは代替不可能な領域、すなわち「&lt;strong&gt;問いを立てる力（課題設定・調査企画）&lt;/strong&gt;」「&lt;strong&gt;人の心を引き出す力（モデレーション）&lt;/strong&gt;」「&lt;strong&gt;意味を見出す力（インサイト発見と戦略提言）&lt;/strong&gt;」へと明確にシフトする。&lt;/p&gt;
&lt;p&gt;未来のリサーチは、AIが生成した膨大な分析結果の「点」を、経験豊かなリサーチャーがビジネス文脈に沿って結びつけ、価値ある「線」や「面」として描き出す、人間とAIの協働作業となるだろう。この変革に適応し、人間ならではの価値を磨き上げた者だけが、次世代のマーケティングリサーチをリードしていくに違いない。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2025/01/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Rails 8でWebサービスをPWA(Progressive Web Apps)対応。最低限の設定を速攻で。</title><link>https://blog.teraren.com/posts/rails8-minimum-pwa/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails8-minimum-pwa/</guid><description>この記事は、Ruby on Rails Advent Calendar 2024の21日目です。</description><pubDate>Wed, 25 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;はじめに&lt;/h1&gt;
&lt;p&gt;この記事は、&lt;a href=&quot;https://qiita.com/advent-calendar/2024/ruby-on-rails&quot;&gt;Ruby on Rails Advent Calendar 2024&lt;/a&gt;の21日目です。&lt;/p&gt;
&lt;p&gt;Rails 8 で簡単に PWA 対応ができるようになりました。この記事では、最小限の設定で Rails アプリケーションを PWA 化する方法を紹介します。&lt;/p&gt;
&lt;p&gt;本記事では郵便番号検索サービス「ポストくん」を PWA 対応してみます。&lt;/p&gt;
&lt;p&gt;https://postcode.teraren.com/&lt;/p&gt;
&lt;h2&gt;PWAとは？&lt;/h2&gt;
&lt;p&gt;Progressive Web App (PWA) は、Web アプリケーションでありながら、ネイティブアプリのような体験を提供する技術です。オフライン対応、ホーム画面へのインストール、プッシュ通知などの機能を実現できます。&lt;/p&gt;
&lt;p&gt;PWA 対応していると検索エンジンからの &lt;a href=&quot;https://html5experts.jp/miyuki-baba/25271/&quot;&gt;評価が上がる&lt;/a&gt;といった発言もあります。&lt;/p&gt;
&lt;h2&gt;Rails 8のPWA対応&lt;/h2&gt;
&lt;p&gt;Rails 8 では、PWA に必要な基本的なファイルが最初から用意されています。具体的には以下の 2 つです：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;マニフェストファイル (&lt;code&gt;manifest.json&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;サービスワーカー (&lt;code&gt;service-worker.js&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これらのファイルを使って、簡単に PWA 対応ができるようになりました。&lt;/p&gt;
&lt;h2&gt;最低限の設定手順&lt;/h2&gt;
&lt;h3&gt;1. ルーティングの設定&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;config/routes.rb&lt;/code&gt; に以下の 2 行を追加します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;get &quot;service-worker&quot; =&amp;gt; &quot;rails/pwa#service_worker&quot;, as: :pwa_service_worker
get &quot;manifest&quot; =&amp;gt; &quot;rails/pwa#manifest&quot;, as: :pwa_manifest
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. マニフェストファイルの作成&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;app/views/pwa/manifest.json.erb&lt;/code&gt; ファイルを作成し、以下のような内容を記述します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;あなたのアプリ名&quot;,
  &quot;short_name&quot;: &quot;短い名前&quot;,
  &quot;description&quot;: &quot;アプリの説明&quot;,
  &quot;start_url&quot;: &quot;/&quot;,
  &quot;display&quot;: &quot;standalone&quot;,
  &quot;background_color&quot;: &quot;#FFFFFF&quot;,
  &quot;theme_color&quot;: &quot;#000000&quot;,
  &quot;icons&quot;: [
    {
      &quot;src&quot;: &quot;&amp;lt;%= asset_path(&apos;icon-192x192.png&apos;) %&amp;gt;&quot;,
      &quot;sizes&quot;: &quot;192x192&quot;,
      &quot;type&quot;: &quot;image/png&quot;
    },
    {
      &quot;src&quot;: &quot;&amp;lt;%= asset_path(&apos;icon-512x512.png&apos;) %&amp;gt;&quot;,
      &quot;sizes&quot;: &quot;512x512&quot;,
      &quot;type&quot;: &quot;image/png&quot;
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. サービスワーカーの作成&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;app/views/pwa/service-worker.js&lt;/code&gt; ファイルを作成し、以下のような基本的な内容を記述します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;self.addEventListener(&apos;install&apos;, function(event) {
  console.log(&apos;Service Worker installing.&apos;);
});

self.addEventListener(&apos;activate&apos;, function(event) {
  console.log(&apos;Service Worker activated.&apos;);
});

self.addEventListener(&apos;fetch&apos;, function(event) {
  console.log(&apos;Fetching:&apos;, event.request.url);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;内容的にはなにもしていませんが、今後の実装のためのメモ的な位置づけです。&lt;/p&gt;
&lt;h3&gt;4. アプリケーションレイアウトの更新&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;app/views/layouts/application.html.erb&lt;/code&gt; ファイルの &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; セクション内に以下の行を追加します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link rel=&quot;manifest&quot; href=&quot;&amp;lt;%= pwa_manifest_path(format: :json) %&amp;gt;&quot;&amp;gt;
&amp;lt;meta name=&quot;apple-mobile-web-app-capable&quot; content=&quot;yes&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. アイコンの準備&lt;/h3&gt;
&lt;p&gt;PWA用のアイコンを &lt;code&gt;app/assets/images/&lt;/code&gt; ディレクトリに配置します。少なくとも192×192と512x512サイズのアイコンを用意しましょう。&lt;/p&gt;
&lt;h3&gt;6. JavaScriptでサービスワーカーを登録&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;app/javascript/application.js&lt;/code&gt; に以下のコードを追加して、サービスワーカーを登録します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (&apos;serviceWorker&apos; in navigator) {
  window.addEventListener(&apos;load&apos;, () =&amp;gt; {
    navigator.serviceWorker.register(&apos;/service-worker.js&apos;)
      .then(registration =&amp;gt; {
        console.log(&apos;Service Worker registered:&apos;, registration);
      })
      .catch(error =&amp;gt; {
        console.log(&apos;Service Worker registration failed:&apos;, error);
      });
  });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;あとはブラウザでアクセスするだけです。&lt;/p&gt;
&lt;h2&gt;動作確認&lt;/h2&gt;
&lt;p&gt;Chrome などでアクセスするとアドレスバーの横にこのように表示されてアプリとしてインストールできます。
2 回目以降はアプリへの動線が表示されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-26-06-43-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;PWA のアプリで開くと以下のような表示になります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-26-06-44-30.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;コマンドランチャーからも起動できるようになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-27-11-23-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;応用&lt;/h2&gt;
&lt;p&gt;PWA Builder というサイトを使うと PWA 対応しているサイトから iOS, Android 向けのアプリパッケージを作ってくれるサイトがあります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-27-11-32-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;PWA 対応を最低限するだけでは情報が不足しているので、アプリにもビルドできるように必要情報を拡充すればアプリのリリースも可能です。
(今回は最低限しか情報を記述していなかったり、アイコンを用意していないのでかなり不足してます。)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-27-11-30-29.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;以上の設定で、Rails 8 アプリケーションの基本的な PWA 対応が完了します。これだけで、ユーザーはあなたの Web アプリをホーム画面に追加できるようになります。&lt;/p&gt;
&lt;p&gt;さらに進んだ PWA 機能（オフラインサポート、プッシュ通知など）を実装する場合は、サービスワーカーの内容を拡張する必要があります。&lt;/p&gt;
&lt;p&gt;Rails 8 の PWA サポートにより、Web 開発者はより簡単にモバイルフレンドリーなアプリケーションを構築できるようになりました。ぜひ、あなたの Rails アプリケーションも PWA 化してみてください！&lt;/p&gt;
</content:encoded></item><item><title>New Relicで自宅サーバ監視・Railsアプリ測定・外形監視を導入した手順</title><link>https://blog.teraren.com/posts/new-relic-on-home-server/</link><guid isPermaLink="true">https://blog.teraren.com/posts/new-relic-on-home-server/</guid><description>この記事は New Relic Advent Calendar 2024の13日目の記事です。他の記事も見てね</description><pubDate>Thu, 12 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宅サーバと個人サービスに New Relic を導入してみました。&lt;/li&gt;
&lt;li&gt;9 年ぶりに New Relic を触りました。別物と言えるぐらい高機能化していました。セットアップも簡単で UI も使いやすい。&lt;/li&gt;
&lt;li&gt;無料で利用開始できるのでおすすめである。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この記事は &lt;a href=&quot;https://qiita.com/advent-calendar/2024/newrelic&quot;&gt;New Relic Advent Calendar 2024&lt;/a&gt;の13日目の記事です。他の記事も見てね&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;10 年ほど前に New Relic を無料版で使っていてたのですが、残念ながら
2015 年に、New Relic の無料版の提供が廃止されたのでそれ以降は別の監視サービスを転々と使ってきました。&lt;/p&gt;
&lt;p&gt;このたび、Qiita の Advent Calendar にて New Relic に無料版があるという記述があったのでしばらくぶりに使ってみました。&lt;/p&gt;
&lt;p&gt;このような監視サービスを選定する際は、自宅サーバで試してみて良かったら業務で使うという流れを取ることが多いので無料で提供されているのはとても助かります。&lt;/p&gt;
&lt;h3&gt;現在の監視運用&lt;/h3&gt;
&lt;p&gt;自宅サーバ、アプリケーションのリソース監視には Mackerel をかれこれ 7 年使い続けています。
1 日だけのリテンションであれば無料で使えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-34-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;グラフは見やすいし、アラートもトリガーできるので小規模サービスには適しているサービスかなと思います。&lt;/p&gt;
&lt;p&gt;また、HTTP による外形監視は無料ではできないので &lt;a href=&quot;https://uptimerobot.com/&quot;&gt;uptimerobot&lt;/a&gt;を利用しています。&lt;/p&gt;
&lt;h2&gt;Linuxサーバの監視&lt;/h2&gt;
&lt;p&gt;自宅サーバである Linux に NewRelic を入れて監視してみます。&lt;/p&gt;
&lt;p&gt;自宅サーバは Ubuntu 24 で運用しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ fastfetch
                             ....              matsu@gmk
              .&apos;,:clooo:  .:looooo:.           ---------
           .;looooooooc  .oooooooooo&apos;          OS: Ubuntu noble 24.04 x86_64
        .;looooool:,&apos;&apos;.  :ooooooooooc          Host: M2
       ;looool;.         &apos;oooooooooo,          Kernel: Linux 6.8.0-36-generic
      ;clool&apos;             .cooooooc.  ,,       Uptime: 164 days(!), 17 hours, 39 mins
         ...                ......  .:oo,      Packages: 1524 (dpkg), 5 (snap)
  .;clol:,.                        .loooo&apos;     Shell: fish 3.7.0
 :ooooooooo,                        &apos;ooool     Theme: Yaru [GTK3]
&apos;ooooooooooo.                        loooo.    Icons: Yaru [GTK3]
&apos;ooooooooool                         coooo.    Cursor: Adwaita
 ,loooooooc.                        .loooo.    Terminal: tmux 3.4
   .,;;;&apos;.                          ;ooooc     CPU: 11th Gen Intel(R) Core(TM) i7-11390H (8) @ 5.00 GHz
       ...                         ,ooool.     GPU: Intel Iris Xe Graphics @ 1.40 GHz [Integrated]
    .cooooc.              ..&apos;,,&apos;.  .cooo.      Memory: 14.08 GiB / 31.10 GiB (45%)
      ;ooooo:.           ;oooooooc.  :l.       Swap: 2.64 GiB / 8.00 GiB (33%)
       .coooooc,..      coooooooooo.           Disk (/): 199.40 GiB / 934.82 GiB (21%) - ext4
         .:ooooooolc:. .ooooooooooo&apos;           Local IP (enp2s0): 192.168.1.28/24
           .&apos;:loooooo;  ,oooooooooc            Locale: en_US.UTF-8
               ..&apos;;::c&apos;  .;loooo:&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;早速左上部にある &lt;code&gt;Integrations &amp;amp; Agents&lt;/code&gt; からLinuxを追加してエージェントを追加していきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-13-00-15-45.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;打つコマンドがコピー&amp;amp;ペーストできるように用意されているのでそのまま打ち込んでいきます。
コピペするだけなのでとても楽です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl -Ls https://download.newrelic.com/install/newrelic-cli/scripts/install.sh | bash &amp;amp;&amp;amp; sudo NEW_RELIC_API_KEY=NRAK-XXXXXXXXXXXXXXXXXXXXXXXXXXX NEW_RELIC_ACCOUNT_ID=00000 /usr/local/bin/newrelic install
Installing New Relic CLI v0.97.2
Installing to /usr/local/bin using sudo
[sudo] password for matsu:

 _   _                 ____      _ _
| \ | | _____      __ |  _ \ ___| (_) ___
|  \| |/ _ \ \ /\ / / | |_) / _ | | |/ __|
| |\  |  __/\ V  V /  |  _ |  __| | | (__
|_| \_|\___| \_/\_/   |_| \_\___|_|_|\___|

Welcome to New Relic. Let&apos;s set up full stack observability for your environment.
Our Data Privacy Notice: https://newrelic.com/termsandconditions/services-notices

◥ Connecting to New Relic Platform.


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記のメッセージが表示されて様々なパッケージのインストールが行われていきます。
5分ぐらいトータルで経過したと思います。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;インストールログ:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Installing New Relic

==&amp;gt; Installing Infrastructure Agent
Detecting available SSL ciphers...
 - SSLv3
 - TLSv1
 - TLSv1.2
 - TLSv1.3
Hit:1 https://nvidia.github.io/libnvidia-container/stable/deb/amd64  InRelease
Hit:2 http://jp.archive.ubuntu.com/ubuntu noble InRelease
Get:3 http://security.ubuntu.com/ubuntu noble-security InRelease [126 kB]
Get:4 http://jp.archive.ubuntu.com/ubuntu noble-updates InRelease [126 kB]
Get:5 https://pkgs.tailscale.com/stable/ubuntu noble InRelease
Get:6 https://esm.ubuntu.com/apps/ubuntu noble-apps-security InRelease [7,532 B]
Hit:7 https://ppa.launchpadcontent.net/zhangsongcui3371/fastfetch/ubuntu noble InRelease
Get:8 https://esm.ubuntu.com/apps/ubuntu noble-apps-updates InRelease [7,468 B]
Get:9 http://jp.archive.ubuntu.com/ubuntu noble-backports InRelease [126 kB]
Get:10 https://esm.ubuntu.com/infra/ubuntu noble-infra-updates InRelease [7,461 B]
Get:11 http://security.ubuntu.com/ubuntu noble-security/main amd64 Components [7,192 B]
Get:12 https://esm.ubuntu.com/infra/ubuntu noble-infra-security InRelease [7,462 B]
Get:13 http://security.ubuntu.com/ubuntu noble-security/restricted amd64 Components [212 B]
Get:14 http://security.ubuntu.com/ubuntu noble-security/universe amd64 Packages [564 kB]
Get:15 http://jp.archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages [706 kB]
Get:16 http://jp.archive.ubuntu.com/ubuntu noble-updates/main amd64 Components [151 kB]
Get:17 http://jp.archive.ubuntu.com/ubuntu noble-updates/restricted amd64 Components [212 B]
Get:18 http://jp.archive.ubuntu.com/ubuntu noble-updates/universe amd64 Packages [729 kB]
Get:19 http://security.ubuntu.com/ubuntu noble-security/universe amd64 Components [51.9 kB]
Get:20 http://security.ubuntu.com/ubuntu noble-security/multiverse amd64 Components [208 B]
Get:21 http://jp.archive.ubuntu.com/ubuntu noble-updates/universe amd64 Components [310 kB]
Get:22 http://jp.archive.ubuntu.com/ubuntu noble-updates/multiverse amd64 Components [940 B]
Get:23 http://jp.archive.ubuntu.com/ubuntu noble-backports/main amd64 Components [208 B]
Get:24 http://jp.archive.ubuntu.com/ubuntu noble-backports/restricted amd64 Components [216 B]
Get:25 http://jp.archive.ubuntu.com/ubuntu noble-backports/universe amd64 Components [11.7 kB]
Get:26 http://jp.archive.ubuntu.com/ubuntu noble-backports/multiverse amd64 Components [212 B]
Fetched 2,947 kB in 8s (370 kB/s)
Reading package lists...
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
OK
Get:1 https://download.newrelic.com/infrastructure_agent/linux/apt noble InRelease [10.8 kB]
Hit:2 https://nvidia.github.io/libnvidia-container/stable/deb/amd64  InRelease
Get:3 https://download.newrelic.com/infrastructure_agent/linux/apt noble/main amd64 Packages [20.8 kB]
Hit:4 http://jp.archive.ubuntu.com/ubuntu noble InRelease
Hit:5 http://security.ubuntu.com/ubuntu noble-security InRelease
Hit:6 http://jp.archive.ubuntu.com/ubuntu noble-updates InRelease
Get:7 https://pkgs.tailscale.com/stable/ubuntu noble InRelease
Hit:8 https://ppa.launchpadcontent.net/zhangsongcui3371/fastfetch/ubuntu noble InRelease
Hit:9 http://jp.archive.ubuntu.com/ubuntu noble-backports InRelease
Hit:10 https://esm.ubuntu.com/apps/ubuntu noble-apps-security InRelease
Hit:11 https://esm.ubuntu.com/apps/ubuntu noble-apps-updates InRelease
Hit:12 https://esm.ubuntu.com/infra/ubuntu noble-infra-updates InRelease
Hit:13 https://esm.ubuntu.com/infra/ubuntu noble-infra-security InRelease
Fetched 38.1 kB in 2s (16.0 kB/s)
Reading package lists...
W: https://download.newrelic.com/infrastructure_agent/linux/apt/dists/noble/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.
[master 7b2a993] saving uncommitted changes in /etc prior to apt run
 Author: Yuki Matsukura &amp;lt;matsubokkuri@gmail.com&amp;gt;
 4 files changed, 11 insertions(+)
 create mode 100644 apt/sources.list.d/newrelic-infra.list
 create mode 100644 apt/trusted.gpg
 create mode 100644 newrelic-infra.yml
Selecting previously unselected package libpq5:amd64.
(Reading database ... 412755 files and directories currently installed.)
Preparing to unpack .../libpq5_16.6-0ubuntu0.24.04.1_amd64.deb ...
Unpacking libpq5:amd64 (16.6-0ubuntu0.24.04.1) ...
Selecting previously unselected package fluent-bit.
Preparing to unpack .../fluent-bit_3.1.9_amd64.deb ...
Unpacking fluent-bit (3.1.9) ...
Selecting previously unselected package newrelic-infra.
Preparing to unpack .../newrelic-infra_1.58.0_amd64.deb ...
Unpacking newrelic-infra (1.58.0) ...
Setting up libpq5:amd64 (16.6-0ubuntu0.24.04.1) ...
Setting up newrelic-infra (1.58.0) ...
Created symlink /etc/systemd/system/multi-user.target.wants/newrelic-infra.service → /etc/systemd/system/newrelic-infra.service.
Setting up fluent-bit (3.1.9) ...
Processing triggers for libc-bin (2.39-0ubuntu8.3) ...
[master 9601789] committing changes in /etc made by &quot;apt-get -o DPkg::Lock::Timeout=60 install newrelic-infra -y -qq&quot;
 Author: Yuki Matsukura &amp;lt;matsubokkuri@gmail.com&amp;gt;
 12 files changed, 477 insertions(+)
 create mode 100644 fluent-bit/fluent-bit.conf
 create mode 100644 fluent-bit/parsers.conf
 create mode 100644 fluent-bit/plugins.conf
 create mode 100644 newrelic-infra/integrations.d/docker-config.yml
 create mode 100644 newrelic-infra/logging.d/file.yml.example
 create mode 100644 newrelic-infra/logging.d/fluentbit.yml.example
 create mode 100644 newrelic-infra/logging.d/syslog.yml.example
 create mode 100644 newrelic-infra/logging.d/systemd.yml.example
 create mode 100644 newrelic-infra/logging.d/tcp.yml.example
 create mode 120000 systemd/system/multi-user.target.wants/newrelic-infra.service
 create mode 100644 systemd/system/newrelic-infra.serviceo

 [snip]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;色々インストールされたみたいです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; --------------------
Installation Summary

✔  Golden Signal Alerts  (installed)
✔  Infrastructure Agent  (installed)
✔  Logs Integration  (installed)
−  PostgreSQL Integration  (canceled)

View your data at the link below:
⮕  https://onenr.io/0PwJkmyg7R7

View your logs at the link below:
⮕  https://onenr.io/0qwyqxKMXwn
--------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最後に結果のサマリーが表示されます。
postgresqlはOSにはインストールされていないので、インストールはしなかったようです。&lt;/p&gt;
&lt;p&gt;Webの方に戻ってみると同様の結果が表示されています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-16-04-42.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;左のメニューからall entitiesを選択するとさきほどインストールしたホストが一覧に表示されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-16-13-05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;早速ですがメトリックがグラフになって表示されています。特に設定はしていなくてもこのダッシュボードと計測メトリックがデフォルトで提供されます。楽です！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-16-13-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;短期間だとデータが溜まっていないのでしばらくしてから再度アクセスしてみました。色々溜まってます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-16-54-05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;別のニューを見てみます。OSのログもNew Relicに送信されているようでリアルタイムでログの出力が確認できます。
おそらく、/var/log/nginxに保存されているアクセスログが出力されているようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-17-24-53.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;network関連のメニュー&lt;/h3&gt;
&lt;p&gt;トラフィックが見られます&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-13-00-53-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;process関連のメニュー&lt;/h3&gt;
&lt;p&gt;メモリ利用量などが見られます&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-21-47.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;storage関連のメニュー&lt;/h3&gt;
&lt;p&gt;容量と、ディスクアクセスが見られます&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-22-04.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;systemのメニュー&lt;/h3&gt;
&lt;p&gt;Load Averageやメモリ使用量が見られます&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-22-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Dependenciesのメニュー&lt;/h3&gt;
&lt;p&gt;docker containerが一覧で見られる感じです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-23-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Diagnoseのメニュー&lt;/h3&gt;
&lt;p&gt;横断的に重要な指標が表示されています&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-23-42.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;特に設定をせずにAgentをインストールするだけで様々な指標がグラフィカルに表示できるようになりました。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ここまでで15分ぐらいしかかかっていないので導入の簡単さに驚きです。&lt;/p&gt;
&lt;h2&gt;APM&lt;/h2&gt;
&lt;p&gt;APMとは、アプリケーションやシステムのパフォーマンスを監視・管理するプロセス、またはそのためのツールを指します。&lt;/p&gt;
&lt;p&gt;APMの主な機能には、次のようなものがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;応答時間、スループット、エラー率などの主要なメトリックの監視&lt;/li&gt;
&lt;li&gt;障害の自動検出とリアルタイムなアラート通知&lt;/li&gt;
&lt;li&gt;リソースの使用状況のトラッキング&lt;/li&gt;
&lt;li&gt;サービスレベル指標の可視化&lt;/li&gt;
&lt;li&gt;エンド・ツー・エンドでの構成の可視化&lt;/li&gt;
&lt;li&gt;アプリケーションリリースや構成変更の記録&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-24-55.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Dockerの統計情報は、APMを入れないでも閲覧できました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-30-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-30-52.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Ruby on RailsへAPMの導入&lt;/h3&gt;
&lt;p&gt;個人サービスをRailsで運用しているのでRailsに
インストールしてみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-36-39.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;表示される手順通りにセットアップすれば完了します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-37-00.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bundler add newrelic_rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-47-00.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;表示されている設定内容を &lt;code&gt;config/newrelic.yml&lt;/code&gt; へ保存します。&lt;/p&gt;
&lt;p&gt;その後、Railsのアプリケーションサーバを再起動します。&lt;/p&gt;
&lt;p&gt;次に、エージェントのプログラムをインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@924713a52351:/app# curl -Ls https://download.newrelic.com/install/newrelic-cli/scripts/install.sh | bash &amp;amp;&amp;amp; sudo NEW_RELIC_API_KEY=NRAK-XXXXXXXXXXXXXXXXXXXXXX NEW_RELIC_ACCOUNT_ID=1111111 /usr/local/bin/newrelic install -n logs-integration
Installing New Relic CLI v0.97.2
Installing to /usr/local/bin

 _   _                 ____      _ _
| \ | | _____      __ |  _ \ ___| (_) ___
|  \| |/ _ \ \ /\ / / | |_) / _ | | |/ __|
| |\  |  __/\ V  V /  |  _ |  __| | | (__
|_| \_|\___| \_/\_/   |_| \_\___|_|_|\___|

Welcome to New Relic. Let&apos;s set up full stack observability for your environment.
Our Data Privacy Notice: https://newrelic.com/termsandconditions/services-notices

✔ Connecting to New Relic Platform
   Connected


Installing New Relic Logs Integration
  --------------------
  Installation Summary

  ⊘  Infrastructure Agent  (unsupported)
  ⊘  Logs Integration  (unsupported)

  Installation incomplete. Follow the instructions at the URL below to complete the installation process.

  ⮕  https://onenr.io/0ERz7nLxzjr

  --------------------


We encountered an issue during the installation: no recipes were installed.
If this problem persists, visit the documentation and support page for additional help here at https://docs.newrelic.com/docs/infrastructure/install-infrastructure-agent/get-started/requirements-infrastructure-agent/

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;インストールに失敗したというメセージが出てきましたが、NewRelicのWebを閲覧してみたら
Docker Containerの情報が出力されていました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-23-38-44.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;真ん中あたりにある、遅いリクエストトップ5が掲載されています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-23-46-51.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;クリックすると、ブレークダウンしてくれます。遅い処理を簡単に分析できます。すごい便利。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-23-47-45.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Webページの表示速度も自動的に計測してくます。LCP,INP,CLSのスコアを自動的に集計して表示してくれます。これは便利です。&lt;/p&gt;
&lt;p&gt;使うべきではない言葉なので修正してください間にビーコンを埋め込まれていたので、要注意ではありますね。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-23-44-41.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;脆弱性のあるパッケージのチェックをしてくれるようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-23-42-06.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;APM Forwardingというパッケージを入れるとアプリケーションのログを転送してくれるようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-23-39-48.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;E2E監視&lt;/h2&gt;
&lt;p&gt;無料版だとリクエスト数に制限がありますが、E2E監視も試せます。 無料だと6時間に1回ぐらいしか行えませんが設定を軽く試してみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-13-00-04-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;自分でスクリプトを書いて監視内容をカスタマイズできます。
今回は以下のようなスクリプトを書いてエンドポイントのヘルスチェックを行いました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var assert = require(&apos;assert&apos;);
$http.get(&apos;https://postcode.teraren.com/healthcheck.json&apos;,
  function (err, response, body) {
    // エラーチェック
    assert.equal(response.statusCode, 200, &apos;Expected a 200 OK response&apos;);
    
  }
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-13-00-14-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;レスポンスタイムや connection time などの指標も出してくれます。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;9年前と比較すると格段に使いやすくなっています。
しかも無料で開始できるので監視サービスの導入のハードルが低いです。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;また、豊富なテンプレがあるので監視エージェントを入れるだけでほとんど知りたいメトリックをきれいに表示してくれます。&lt;/p&gt;
&lt;p&gt;少し前まで datadog を利用していましたが設定が複雑でセットアップやカスタムメトリックを使ってダッシュボードを構築するのに自由度が高い反面、いろいろな監視項目を自分で設定する必要があってかなり大変でした。
Mackerel はグラフがきれいでシンプルなのは良いですが、アプリケーションの監視や OS の主要なメトリックを監視するためにもプラグインを入れていかないといけないので面倒な印象です。NewRelic のほうがちょっと触った感じでは datadog 良さそうな感じがします。&lt;/p&gt;
&lt;p&gt;個人サービスをやっていると、実運用しているサービスを使って導入検証のスクショをモザイク無しで掲載できるので皆様のお役に立てるような情報を提供できるかと思います。&lt;/p&gt;
&lt;h2&gt;今後&lt;/h2&gt;
&lt;p&gt;今後は、NewRelic のさらなる機能を試してみたいと考えています。具体的には以下の点を検討しています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;カスタムダッシュボードの作成&lt;/strong&gt;:
デフォルトのダッシュボードも非常に便利ですが、特定のニーズに合わせたカスタムダッシュボードを作成し、より詳細に監視したいと考えています。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;アラート設定の最適化&lt;/strong&gt;:
現在のアラート設定を見直し、より効果的なアラートを設定することで、問題の早期発見と対応を目指します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;他のサービスとの連携&lt;/strong&gt;:
NewRelic を他の監視ツールやサービスと連携させることで、より包括的な監視環境を構築したいと考えています。例えば、Slack や PagerDuty と連携させて、アラート通知を効率化することを検討しています。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;パフォーマンスの最適化&lt;/strong&gt;:
収集したデータを基に、サーバーやアプリケーションのパフォーマンスを最適化し、より効率的な運用を目指します。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これらの取り組みを通じて、NewRelic を活用した監視環境をさらに強化し、安定したサービス運用を実現していきたいと考えています。&lt;/p&gt;
&lt;h2&gt;会社での導入を検討&lt;/h2&gt;
&lt;p&gt;では法人でちゃんとしたサービスの監視に使えるかを少し考えてみます。
気になるお値段はこちら&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-13-00-42-56.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Free でも 1 ユーザだけなら機能は無制限に使えるようです。
普通は、Standard 以上になるのかなと思います。実際のサービスごとによって転送するログの量は異なるのでなんとも言えませんがかなり絞れば課金されないくらいなのかなと思います。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://zenn.dev/jtwulf/articles/58ba3654445934&quot;&gt;session replay&lt;/a&gt;機能はすごい魅力的。トラブルシュートに時間を使うことが多いので。&lt;/p&gt;
&lt;h2&gt;余談&lt;/h2&gt;
&lt;h3&gt;懐かしのスクリーンショット&lt;/h3&gt;
&lt;p&gt;9 年前である、2015 年に撮影した New Relic の管理画面がありました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/12/2024-12-12-22-19-09.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;現在は別物ってくらいに UI がきれいになってますね。&lt;/p&gt;
&lt;h3&gt;New Relicの正式表記がわからない&lt;/h3&gt;
&lt;p&gt;オフィシャルサイトでも表記ゆれしていそう。どれが正しいのだろう。この記事では「New Relic」にしましたが。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;new relic&lt;/li&gt;
&lt;li&gt;NewRelic&lt;/li&gt;
&lt;li&gt;New Relic&lt;/li&gt;
&lt;li&gt;newrelic&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>無料の郵便番号検索APIのレスポンススピード比較</title><link>https://blog.teraren.com/posts/teraren-postcode-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/teraren-postcode-benchmark/</guid><description>ポストくん、ZipCloud、ttskch/jp-postal-code-apiの3つの無料郵便番号検索APIのレスポンス速度をwrkで比較検証。</description><pubDate>Wed, 11 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;ベンチマークと高速化が大好きな &lt;a href=&quot;https://x.com/matsubokkuri&quot;&gt;@matsubokkuri&lt;/a&gt;です。&lt;/p&gt;
&lt;p&gt;郵便番号検索 API は、住所情報を取得する際に頻繁に利用される重要なツールです。
本記事では、3 つの郵便番号検索 API のレスポンススピードを比較し、それぞれのパフォーマンスについて考察します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;ポストくん&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zipcloud.ibsnet.co.jp/&quot;&gt;ZipCloud API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ttskch/jp-postal-code-api&quot;&gt;ttskch/jp-postal-code-api&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;計測概要&lt;/h2&gt;
&lt;h3&gt;使用したツール&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;wrk&lt;/strong&gt;: 高負荷テストツールを使用して、各 API のレスポンススピードを計測しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;計測条件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;テスト対象の URL：
&lt;ul&gt;
&lt;li&gt;ポストくん API: https://postcode.teraren.com/postcodes/1600023.json&lt;/li&gt;
&lt;li&gt;ZipCloud API: https://zipcloud.ibsnet.co.jp/api/search?zipcode=1600023&lt;/li&gt;
&lt;li&gt;ttskch/jp-postal-code-api: https://jp-postal-code-api.ttskch.com/api/v1/1600023.json&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;テスト時間：10 秒&lt;/li&gt;
&lt;li&gt;スレッド数：2&lt;/li&gt;
&lt;li&gt;接続数：10&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;テスト内容&lt;/h3&gt;
&lt;p&gt;各 API に対して 10 秒間リクエストを送り、以下の指標を計測しました：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;平均レイテンシー&lt;/strong&gt;（1 リクエストの平均応答時間）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;リクエスト数/秒&lt;/strong&gt;（1 秒間に処理できたリクエスト数）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;データ転送量/秒&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;計測結果&lt;/h2&gt;
&lt;h3&gt;ポストくん API&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Running 10s test @ https://postcode.teraren.com/postcodes/1600023.json
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    17.38ms    3.50ms  56.86ms   81.09%
    Req/Sec   287.60     22.71   343.00     79.00%
  5757 requests in 10.06s, 11.29MB read
Requests/sec:    572.01
Transfer/sec:      1.12MB
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ZipCloud API&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Running 10s test @ https://zipcloud.ibsnet.co.jp/api/search?zipcode=1600023
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   217.51ms   21.91ms 349.86ms   94.29%
    Req/Sec    22.67      8.09    40.00     78.01%
  455 requests in 10.10s, 101.51KB read
Non-2xx or 3xx responses: 404
Requests/sec:     45.07
Transfer/sec:     10.05KB
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ttskch/jp-postal-code-api&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;❯ wrk &apos;https://jp-postal-code-api.ttskch.com/api/v1/1600023.json&apos;
Running 10s test @ https://jp-postal-code-api.ttskch.com/api/v1/1600023.json
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    21.87ms   13.82ms 241.38ms   97.74%
    Req/Sec   239.94     24.27   272.00     87.00%
  4801 requests in 10.05s, 7.99MB read
Requests/sec:    477.52
Transfer/sec:    813.56KB
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;結果比較&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指標&lt;/th&gt;
&lt;th&gt;ポストくん API&lt;/th&gt;
&lt;th&gt;ZipCloud API&lt;/th&gt;
&lt;th&gt;ttskch/jp-postal-code-api&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;平均レイテンシー&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;17.38ms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;217.51ms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;21.87ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;リクエスト数/秒&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;572.01&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;45.07&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;477.52&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;データ転送量/秒&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.12MB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;10.05KB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;813.56KB&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;非2xx/3xxレスポンス数&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;404&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;h3&gt;パフォーマンスの違い&lt;/h3&gt;
&lt;p&gt;計測結果から、ポストくん API が最も高速であることが分かります。ttskch/jp-postal-code-api は 2 番目に高いパフォーマンスを示し、ZipCloud API は最も遅い結果となりました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;平均レイテンシー&lt;/strong&gt;: ポストくん API が最も短く、次いで ttskch/jp-postal-code-api、ZipCloud API の順です。ZipCloud API は他の 2 つの API と比較して約 10 倍以上のレイテンシーがあります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;リクエスト数/秒&lt;/strong&gt;: ポストくん API が最も多く、ttskch/jp-postal-code-api がそれに続きます。ZipCloud API は他の 2 つの API と比較して著しく少ないリクエスト処理能力を示しています。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;データ転送量/秒&lt;/strong&gt;: ポストくん API が最も多く、次いで ttskch/jp-postal-code-api、ZipCloud API の順です。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;エラーレスポンス&lt;/strong&gt;: ポストくん API と ttskch/jp-postal-code-api は非 2xx/3xx レスポンスがなく、安定性が高いことが示されています。一方、ZipCloud API ではエラーが発生しており、信頼性に課題があることが示唆されます。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;利用シナリオ別の選択肢&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;高速性と安定性が最優先の場合&lt;/strong&gt;: ポストくん API が最適です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高速性は重要だが、ポストくん APIほどの極限的なパフォーマンスが不要な場合&lt;/strong&gt;: ttskch/jp-postal-code-api も良い選択肢となります。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;低頻度のアクセスや簡易な利用の場合&lt;/strong&gt;: ZipCloud API も検討可能ですが、エラー処理の実装が必要です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;アクセスブロックに関して&lt;/h3&gt;
&lt;p&gt;ポストくんでは Cloudflare の CDN によるキャッシングを行っており、不正アクセス対策も行われています。今回の 10 秒間で 6000 リクエスト近いリクエストを送っても不正判定はされませんでした。
ZipCloud では大量アクセスに対して、rate limit が早期に掛かる可能性があります。&lt;/p&gt;
&lt;h2&gt;結論&lt;/h2&gt;
&lt;p&gt;今回の計測では、ポストくん API が最も高いパフォーマンスを示し、ttskch/jp-postal-code-api がそれに続く結果となりました。両 API とも安定性も高く、高速性や信頼性を重視するアプリケーションに適しています。&lt;/p&gt;
&lt;p&gt;特に、極限的な高速性が求められる場合はポストくん API が、それほどの極限的なパフォーマンスが不要な場合は ttskch/jp-postal-code-api も良い選択肢となるでしょう。ZipCloud API は、パフォーマンスと安定性の面で改善の余地があります。&lt;/p&gt;
&lt;p&gt;API の選択に当たっては、これらのパフォーマンス指標に加えて、API の機能、利用制限、料金体系なども考慮に入れる必要があります。アプリケーションの要件に最も適した API を選択することが重要です。&lt;/p&gt;
</content:encoded></item><item><title>港区スマイル商品券マップを開発しました</title><link>https://blog.teraren.com/posts/minato-ku-smile-ticket/</link><guid isPermaLink="true">https://blog.teraren.com/posts/minato-ku-smile-ticket/</guid><description>こんにちは！　今回は、港区のスマイル商品券を利用できる施設を簡単に検索・閲覧できる Google Maps ベースのウェブアプリケーションを開発した経験について共有したいと思います。</description><pubDate>Thu, 17 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;こんにちは！　今回は、港区のスマイル商品券を利用できる施設を簡単に検索・閲覧できる Google Maps ベースのウェブアプリケーションを開発した経験について共有したいと思います。&lt;/p&gt;
&lt;p&gt;https://www.google.com/maps/d/viewer?hl=ja&amp;amp;mid=1m90xJYsL4bTpX2OZp0s1RZG-IL21qWg&amp;amp;ll=35.65534032072766%2C139.7510863216841&amp;amp;z=14&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;港区では、地域経済の活性化を目的として「&lt;a href=&quot;https://minato.yomsubi.com/&quot;&gt;スマイル商品券&lt;/a&gt;」を発行しています。この商品券は区内の多くの店舗で使用可能ですが、利用可能な店舗を探すのが難しいという課題がありました[1]。&lt;/p&gt;
&lt;p&gt;私自身、過去に商品券の使用期限が迫っているにもかかわらず、使える店舗がわからずに困った経験がありました。この経験から、他の区民の方々も同じような問題を抱えているのではないかと考え、このプロジェクトを始めることにしました。&lt;/p&gt;
&lt;h2&gt;開発のプロセス&lt;/h2&gt;
&lt;h3&gt;1. データの収集と整理&lt;/h3&gt;
&lt;p&gt;まず、港区商店街連合会が &lt;a href=&quot;https://minato.yomsubi.com/shoplist/&quot;&gt;公開しているPDF&lt;/a&gt;から利用可能店舗のデータを抽出しました。このデータには店舗名、住所、業種などの情報が含まれていました。&lt;/p&gt;
&lt;p&gt;Google Maps 上に表示するためにはある程度規定のフォーマットでファイルを作って上げる必要があります。
1 つの Spreadsheet の 1 つ目のシートしか見てくれないのでメトリックごとに CSV ファイルを作って上げる必要があります。&lt;/p&gt;
&lt;p&gt;また、カラム名が重要なのでカラム名をつけた状態で作ります。&lt;/p&gt;
&lt;p&gt;今回は、通常券と限定券の 2 つのレジェンドに分割しました。&lt;/p&gt;
&lt;p&gt;限定券
https://docs.google.com/spreadsheets/d/1HGXGR41bCx-thOIWZN_Njv-6RwZO5vo3jj7mCO4ONfo/edit?usp=drive_link&lt;/p&gt;
&lt;p&gt;通常券
https://docs.google.com/spreadsheets/d/147fTCROTvHwnEksjmvi7EWAAVdv6GDkMa_sKx_UMSbQ/edit?usp=drive_link&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-17-10-55-00.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2. Google Mapsの活用&lt;/h3&gt;
&lt;p&gt;次に、Google Maps JavaScript API を使用して、抽出したデータを地図上にプロットしました。
&lt;strong&gt;GoogleのMy Map機能には住所からGocodingしてくれる機能があるので住所から緯度経度情報を取得してプロットしてくれます。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-17-10-54-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3. 検索機能の実装&lt;/h3&gt;
&lt;p&gt;ユーザーが現在地から近い店舗を簡単に見つけられるよう、位置情報を利用した検索機能を実装しました。また、業種によるフィルタリング機能も追加し、飲食店のみを表示するなどの絞り込みを可能にしました。&lt;/p&gt;
&lt;h3&gt;4. 詳細情報の表示&lt;/h3&gt;
&lt;p&gt;各マーカーをクリックすると、店舗の詳細情報（店舗名、住所、電子商品券・紙商品券の利用可否など）がポップアップで表示されるようにしました。&lt;/p&gt;
&lt;h2&gt;成果と反響&lt;/h2&gt;
&lt;p&gt;完成したアプリケーションは、&lt;a href=&quot;https://x.com/matsubokkuri/status/1845746876404121815&quot;&gt;Xで公開&lt;/a&gt;したところ、多くの方々から好評をいただきました。特に、現在地からの店舗検索や業種別フィルタリング機能が便利だという声が多く聞かれました。&lt;/p&gt;
&lt;h2&gt;今後の改善点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;データの自動更新&lt;/strong&gt;: 現在は手動でデータを更新していますが、港区の公式サイトから自動的にデータを取得・更新する仕組みを構築したいと考えています。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ユーザーレビュー機能&lt;/strong&gt;: 利用者が店舗の評価やコメントを投稿できる機能を追加することで、より有用な情報プラットフォームになると考えています。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;モバイルアプリ化&lt;/strong&gt;: 現在はウェブアプリケーションですが、将来的には iOS や Android のネイティブアプリとして開発することで、プッシュ通知などの機能を追加し、ユーザー体験を向上させたいと思います。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;このプロジェクトを通じて、オープンデータを活用することで地域の課題解決に貢献できることを実感しました。また、Google Maps のような既存のプラットフォームを利用することで、30 分で実用的なアプリケーションを開発できることも学びました。&lt;/p&gt;
&lt;p&gt;今後も、このようなプロジェクトを通じて、技術で地域に貢献していきたいと考えています。皆さんも、身近な課題に目を向けて、技術で解決できることはないか、考えていきます。&lt;/p&gt;
&lt;h2&gt;類似サービス&lt;/h2&gt;
&lt;p&gt;https://note.com/mah_mah/n/n682235de0b46&lt;/p&gt;
</content:encoded></item><item><title>ChatGPTと同様のUIを提供するOSSであるLibreChatを動かしてみた</title><link>https://blog.teraren.com/posts/librechat-ollama/</link><guid isPermaLink="true">https://blog.teraren.com/posts/librechat-ollama/</guid><description>一言でいうと、ChatGPT の OSS バージョンです。</description><pubDate>Thu, 10 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3行サマリー&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自社でゼロから LLM サービスの UI を運用するのは大変なので LibreChat を調査してみます。&lt;/li&gt;
&lt;li&gt;LibreChat をエンタープライズ利用に使えそうかを検証してみました。&lt;/li&gt;
&lt;li&gt;LibreChat + Ollama (Gemma2)を使ってプライベートな LLM サービスを作ってみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;LibreChatの特徴&lt;/h2&gt;
&lt;p&gt;一言でいうと、ChatGPT の OSS バージョンです。&lt;/p&gt;
&lt;p&gt;カスタマイズ性が高く、ユーザーは自分のニーズに合わせて機能やプラグインを追加できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-09-18-33-54.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ライセンス&lt;/h3&gt;
&lt;p&gt;MIT License なので商用利用可能です。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MIT Licenseの特徴&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自由な使用: MIT License は、ソフトウェアを商業目的、個人使用、教育目的を問わず自由に利用できることを許可します。&lt;/li&gt;
&lt;li&gt;改変と再配布: ユーザーはソフトウェアを改変し、その改変版を再配布できます。改変版の配布時には、元のライセンスを明示する必要があります。&lt;/li&gt;
&lt;li&gt;著作権の保持: ソフトウェアの著作権は元の作者に残りますが、ライセンスの下で使用する権利を他のユーザーにも与えます。&lt;/li&gt;
&lt;li&gt;責任の免除: MIT License には、ソフトウェアが提供される際の「現状有姿」での提供が明記されており、バグや問題に対して作者が責任を負わないことが明示されています。&lt;/li&gt;
&lt;li&gt;シンプルで短い: ライセンス文が非常にシンプルで短く、理解しやすいため、広く採用されています。
&amp;lt;/div&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ソフトウェアアーキテクチャ&lt;/h3&gt;
&lt;p&gt;コンポーネント&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;フロントエンド: ChatGPT に似たユーザーインタフェースを提供&lt;/li&gt;
&lt;li&gt;バックエンド: 様々な AI モデルとの連携やデータ管理を担当&lt;/li&gt;
&lt;li&gt;データベース: &lt;code&gt;MongoDB&lt;/code&gt; を使用してチャット履歴などのデータを保存&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;デプロイメントを以下に簡単に図示します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-10-09-37-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;使用言語とフレームワーク&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;フロントエンド: TypeScript (React, Vite)&lt;/li&gt;
&lt;li&gt;バックエンド: Node.js&lt;/li&gt;
&lt;li&gt;データベース: MongoDB&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;デプロイメント&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker サポート: コンテナ化されたデプロイメントが可能&lt;/li&gt;
&lt;li&gt;クラウドデプロイメント: AWS EC2 などのクラウドプラットフォームでのホスティングが可能&lt;/li&gt;
&lt;li&gt;ローカルデプロイメント: オフラインでの完全なローカル実行も可能&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;人気度&lt;/h3&gt;
&lt;p&gt;Fork 3k, Start 18k。すごい。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-10-09-39-31.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;活発度&lt;/h3&gt;
&lt;p&gt;かなり活発です。
&lt;code&gt;main&lt;/code&gt; ブランチに積極的にコミットされてます。安定性より機能の充実を優先しているように見えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-09-18-52-56.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;リリースはまだ v0 系です。
&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-10-09-40-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;セットアップ&lt;/h2&gt;
&lt;p&gt;使用感をチェックして見るために動かしてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git clone git@github.com:danny-avila/LibreChat.git
% cd LibreChat
% cp .env.example .env
% open &apos;http://localhost:3080/login&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ブラウザで開くと以下のような画面が表示されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-09-18-39-50.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;すんなり動きました。&lt;/p&gt;
&lt;p&gt;今回はソースコード自体をcloneしていますが、docker-compose.ymlファイルと.envファイルの設定だけで動きます。
docker-compose.ymlからはecrにおいてあるコンテナを取得しています。&lt;/p&gt;
&lt;h2&gt;ユースケースを試してみる&lt;/h2&gt;
&lt;h3&gt;OpenAIをAPI経由で利用してみる&lt;/h3&gt;
&lt;p&gt;OpenAIへのAPI接続はLibraChat本体でサポートしているので &lt;code&gt;.env&lt;/code&gt; ファイルにOpenAIのAPIキーを追加するだけで使えるようになります。&lt;/p&gt;
&lt;p&gt;追加する箇所は170行目あたりです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ diff .env.example .env
171c171
&amp;lt; OPENAI_API_KEY=user_provided
---
&amp;gt; OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;画面の左上から利用するモデルを選んで、テキストを打ち込みます。
以下の画像のような感じで動作します。UIはChatGPTと同様です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-10-08-14-44.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;左側のペインに、チャットの履歴、右側でLLMのパラメータ調整やプロンプトのスニペットを管理できます。&lt;/p&gt;
&lt;h3&gt;画像を生成してみる&lt;/h3&gt;
&lt;p&gt;デフォルトでは画像生成をサポートしていません。
画像生成で有名どころのOpenAIのDall-Eを使って見たいと思います。&lt;/p&gt;
&lt;p&gt;.envファイルで環境変数にAPIキーを設定します。OpenAI経由で使うのでOpenAIと同じキーを指定します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ diff .env.example .env
236,238c236,238
&amp;lt; # DALLE_API_KEY=
&amp;lt; # DALLE3_API_KEY=
&amp;lt; # DALLE2_API_KEY=
---
&amp;gt;  DALLE_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxx
&amp;gt; # DALLE3_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxx
&amp;gt; # DALLE2_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxxxx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;プラグインストアでDall−Eをインストールします。
&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-10-08-27-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上部から、&lt;code&gt;Plugins&lt;/code&gt; を選択して、LLMを選択肢、DALL−Eをチェックして利用します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-10-08-52-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上記で設定は終わりなので試してみましたが、残念ながらうまく生成してくれませんでした。
おそらく、追加で設定が必要のようです。DALL-Eのプラグインの不具合のようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-10-09-01-31.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;自分で立てたollamaを使ってみる&lt;/h3&gt;
&lt;p&gt;OpenAIといった外部サービスではなく自社で立ち上げているLLMサービスへ接続するケースがあると思うので試してみます。&lt;/p&gt;
&lt;p&gt;ollamaはHTTP経由のAPIで利用します。&lt;/p&gt;
&lt;p&gt;composeで一気に作りたいので以下を追加しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/docker-compose.yml b/docker-compose.yml
index 55686abd..85f2c5dd 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -67,6 +67,16 @@ services:
       - vectordb
     env_file:
       - .env
+  ollama:
+    image: ollama/ollama
+    container_name: ollama
+    ports:
+      - &quot;11434:11434&quot;
+    volumes:
+      - ollama:/root/.ollama
+

 volumes:
   pgdata2:
+  ollama:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gemma2の2Bモデルをダウンロードします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose exec ollama ollama pull gemma2:2b
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ollama単体で動作テストをしてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ docker compose exec ollama ollama run gemma2:2b
&amp;gt;&amp;gt;&amp;gt; 日本の最高峰は？
日本の最高峰は **富士山** です！ 🗻
 どんな情報に関心があるか教えていただければ、より詳細な情報を提供できますよ😊
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CPUで動かしても即座に返ってきました。&lt;/p&gt;
&lt;p&gt;LibreChatがデフォルトでサポートしていないLLMのサービスへ接続するためには、
別途カスタムの設定を記述したYAMLファイルを作成して、LibreChatへパラメータとして指定します。&lt;/p&gt;
&lt;p&gt;カスタムファイルのテンプレファイルをコピーします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cp ./librechat.example.yaml librechat.yaml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下の設定を108行目辺りの &lt;code&gt;custom&lt;/code&gt; セクションに追加します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ diff librechat.example.yaml librechat.yaml
108a109,131
&amp;gt;     - name: &quot;Ollama&quot;
&amp;gt;       apiKey: &quot;ollama&quot;
&amp;gt;       baseURL: &quot;http://ollama:11434/v1/chat/completions&quot;
&amp;gt;       models:
&amp;gt;         default: [
&amp;gt;           &quot;llama2&quot;,
&amp;gt;           &quot;gemma2&quot;,
&amp;gt;           &quot;mistral&quot;,
&amp;gt;           &quot;codellama&quot;,
&amp;gt;           &quot;dolphin-mixtral&quot;,
&amp;gt;           &quot;mistral-openorca&quot;
&amp;gt;           ]
&amp;gt;         # fetching list of models is supported but the name field must start
&amp;gt;         # with ollama (case-insensitive), as it does in this example.
&amp;gt;         fetch: true
&amp;gt;       titleConvo: true
&amp;gt;       titleModel: &quot;current_model&quot;
&amp;gt;       summarize: false
&amp;gt;       summaryModel: &quot;current_model&quot;
&amp;gt;       forcePrompt: false
&amp;gt;       modelDisplayLabel: &quot;Ollama&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;default&lt;/code&gt; セクションでモデル名を指定しています。&lt;code&gt;fetch&lt;/code&gt; セクションで &lt;code&gt;true&lt;/code&gt; を指定していれば、動的に ollama のサーバから取得するので気にしないで大丈夫です。
利用するモデルを制限する場合に使うとよいです。&lt;/p&gt;
&lt;p&gt;上部のメニューから Ollama を選択し、対応するモデルを選べば利用できました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-10-09-16-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Dify をワークフローとして使うケースにも対応できるかなと思って調べてみたら、2024 年 5 月に同様の issue が立ってました。
https://github.com/danny-avila/LibreChat/discussions/2830&lt;/p&gt;
&lt;h3&gt;GoogleのOAuthで認証する&lt;/h3&gt;
&lt;p&gt;OAuth でログインする設定を簡単に行えます。&lt;/p&gt;
&lt;p&gt;オフィシャルサイトの手順に従って Google 側で設定します。丁寧に解説されているのでマニュアル通りに実行すれば終わります。
https://www.librechat.ai/docs/configuration/authentication/OAuth2-OIDC/google&lt;/p&gt;
&lt;p&gt;特につまずくこと無く、SSO できました。エンタープライズに導入する際にはとても楽です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/10/2024-10-10-08-54-02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;高いカスタマイズ性とプライバシー保護を提供し、幅広い用途に使えそう。&lt;/li&gt;
&lt;li&gt;簡単なセットアップ手順と豊富なプラグインサポートにより、個人利用から企業導入まで柔軟に対応できそう。&lt;/li&gt;
&lt;li&gt;DALL-E が動かなかったので今後に期待。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;類似サービス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://openwebui.com/&quot;&gt;Open WebUI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.chatbotui.com/&quot;&gt;ChatbotUI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Cocoon用Amazon短縮リンク生成Chrome拡張機能を作ってみた</title><link>https://blog.teraren.com/posts/cocoon-affiliate-code-chrome-extension/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cocoon-affiliate-code-chrome-extension/</guid><description>Cocoonテーマ用のAmazonアフィリエイトショートコードをワンクリックで生成するChrome拡張機能を開発。</description><pubDate>Thu, 26 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;3行まとめ&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Cocoon テーマ用の Amazon アフィリエイトリンクを簡単に生成する Chrome 拡張機能を開発&lt;/li&gt;
&lt;li&gt;ワンクリックで商品 ASIN とキーワードを含むショートコードを生成&lt;/li&gt;
&lt;li&gt;除外キーワード機能で、不要な文字列を自動的に削除可能&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://github.com/matsubo/cocoon-amazon-shortcode&lt;/p&gt;
&lt;h1&gt;背景&lt;/h1&gt;
&lt;p&gt;WordPress の Cocoon テーマを使用している方々にとって、Amazon の商品リンクを記事に挿入するのは日常的な作業です。しかし、この作業は意外と手間がかかり、特に多くの商品リンクを扱う場合は生産性の低下につながります。&lt;/p&gt;
&lt;h1&gt;問題&lt;/h1&gt;
&lt;p&gt;従来の方法では、以下のような手順を踏む必要がありました：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Amazon 商品ページを開く&lt;/li&gt;
&lt;li&gt;ASIN を確認&lt;/li&gt;
&lt;li&gt;商品タイトルをコピー&lt;/li&gt;
&lt;li&gt;WordPress の投稿画面に戻る&lt;/li&gt;
&lt;li&gt;ショートコードを手動で入力&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;この過程は時間がかかるだけでなく、人為的ミスも発生しやすいです。&lt;/p&gt;
&lt;h1&gt;目的&lt;/h1&gt;
&lt;p&gt;この問題を解決するため、以下の目標を掲げて開発に取り組みました&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ワンクリックで Amazon アフィリエイトリンクを生成する&lt;/li&gt;
&lt;li&gt;Cocoon テーマの仕様に合わせたショートコードを自動生成する&lt;/li&gt;
&lt;li&gt;不要なキーワードを自動的に除外する機能を実装する&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;アプローチ&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-26-11-11-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;1. Chrome拡張機能の開発&lt;/h2&gt;
&lt;p&gt;Chrome 拡張機能を開発することで、Amazon の商品ページ上で直接操作できるようにしました。これにより、ユーザーはタブの切り替えなしでリンクを生成できます。&lt;/p&gt;
&lt;h2&gt;2. ASINと商品タイトルの自動取得&lt;/h2&gt;
&lt;p&gt;JavaScript を使用して、商品ページから ASIN と商品タイトルを自動的に抽出するロジックを実装しました。これにより、手動でのコピー&amp;amp;ペーストの必要がなくなりました。&lt;/p&gt;
&lt;h2&gt;3. ショートコード生成ロジック&lt;/h2&gt;
&lt;p&gt;Cocoon テーマで使用される以下のフォーマットに従ってショートコードを生成します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[amazon asin=&quot;&amp;lt;ASIN&amp;gt;&quot; kw=&quot;&amp;lt;商品名&amp;gt;&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このショートコードを Cocoon を利用している WordPress にそのまま貼り付けると以下のように展開されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-26-11-12-02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;4. 除外キーワード機能&lt;/h2&gt;
&lt;p&gt;ユーザーが指定した除外キーワードを商品タイトルから自動的に削除する機能を実装しました。これにより、「Amazon 限定」や「送料無料」などの不要な文字列を簡単に除去できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-26-11-12-49.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;5. クリップボードへの自動コピー&lt;/h2&gt;
&lt;p&gt;生成されたショートコードは自動的にクリップボードにコピーされます。ユーザーは WordPress の投稿画面に戻って直接ペーストするだけで済みます。&lt;/p&gt;
&lt;h1&gt;まとめ&lt;/h1&gt;
&lt;p&gt;この Chrome 拡張機能を使用することで、Cocoon テーマを使用している WordPress ブロガーの作業効率が大幅に向上します。特に以下の点で有用です：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;作業時間の短縮&lt;/li&gt;
&lt;li&gt;人為的ミスの削減&lt;/li&gt;
&lt;li&gt;一貫性のあるリンク生成&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;今後も、ユーザーフィードバックを基に機能を改善・拡張していく予定です。皆さんもぜひ試してみてください！&lt;/p&gt;
</content:encoded></item><item><title>AIによる契約書の自動レビュー機能を作ってみた</title><link>https://blog.teraren.com/posts/ai-legal-review/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ai-legal-review/</guid><description>こんな感じで契約書をレビューしてくれます。</description><pubDate>Fri, 20 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3行まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;契約書のレビュー、契約書のバージョン管理を効率的に行いかた向け。&lt;/li&gt;
&lt;li&gt;AI を活用した契約書レビューのワークフローを構築。&lt;/li&gt;
&lt;li&gt;GitHub の Pull Request 機能を使ってレビューするので複数人でのレビューがしやすく議論の結果が残る。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;こんな感じで契約書をレビューしてくれます。
&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-20-16-55-45.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ソースコード（基本はこの 1 ファイルのみ）。
https://github.com/matsubo/legal-document/blob/main/.github/workflows/ai-pr-reviewer.yml&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;社内の AI 技術勉強会にて、リーガルチェックに LLM を利用してみたときの事例を見ました。
その際に、契約書の 1 次チェックを LLM を使って行うと一定数の時短効果があるという考察がありました。&lt;/p&gt;
&lt;p&gt;悩んだポイントや使い方のノウハウが
&lt;a href=&quot;https://github.com/coderabbitai/ai-pr-reviewer&quot;&gt;Coderabbit&lt;/a&gt;や&lt;a href=&quot;https://github.com/Codium-ai/pr-agent&quot;&gt;PR-Agent&lt;/a&gt;を使ったLLMによるPull Request のレビューと似ていると思いまいした。&lt;/p&gt;
&lt;p&gt;そこで、ソースコード管理のメタファをと契約書のレビューに適用してみようと考えました。&lt;/p&gt;
&lt;h2&gt;目的&lt;/h2&gt;
&lt;p&gt;AI によるソースコードレビューを行うのと同じように、AI による契約書のレビューをするワークフローを作ります。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;契約書などの法務関連のドキュメントも基本的にはテキスト情報なのでソースコードと似ているので GitHub などのバージョン管理ツールを使ったワークフローに乗せてみる。&lt;/p&gt;
&lt;h3&gt;ワークフローのスコープ定義&lt;/h3&gt;
&lt;p&gt;印鑑を利用した契約書に関するユースケースを整理してみます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ドラフトの作成&lt;/li&gt;
&lt;li&gt;ドラフトの確認、修正&lt;/li&gt;
&lt;li&gt;A が捺印&lt;/li&gt;
&lt;li&gt;B が捺印&lt;/li&gt;
&lt;li&gt;双方で保管&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;電子化されたとしても上記の捺印が電子捺印に変わるだけなので同様に考えられます。&lt;/p&gt;
&lt;p&gt;今回は、契約締結ワークフローすべてを考えるとビジネス要件、法務要件などが絡んでくるので上野 2 つの&lt;strong&gt;ドラフトの作成、確認、修正&lt;/strong&gt;という点を LLM を使って処理できるようにしたいと思います。&lt;/p&gt;
&lt;h3&gt;ドキュメントのフォーマットの扱い&lt;/h3&gt;
&lt;p&gt;契約書は変更可能なドラフトの状態では docx, Google Docs で流通し、内容が合意できたあとは PDF で流通します。
docs や Google Docs の形式ではテキストエディタとの相性が悪いので Markdown に変換して扱います。&lt;/p&gt;
&lt;h3&gt;ワークフロー設計&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;契約書のドラフトを作成&lt;/li&gt;
&lt;li&gt;Markdown に変換&lt;/li&gt;
&lt;li&gt;pull request を作成&lt;/li&gt;
&lt;li&gt;pull request 上に行ごと、全体に対してレビューコメントをいれる&lt;/li&gt;
&lt;li&gt;満足が行くまで修正を繰り返す。&lt;/li&gt;
&lt;li&gt;main ブランチに merge し PDF を生成&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実装&lt;/h2&gt;
&lt;p&gt;今回は契約書のサンプルのために、Wor-Q の提供する &lt;a href=&quot;https://jtuc-network-support.com/useful-links/usli-cont&quot;&gt;契約書の雛形&lt;/a&gt;を利用させてもらいます。
今回は単発の業務委託契約書のテンプレを使います。(&lt;code&gt;ikkai-keiyaku-jyuninin.docx&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-20-16-04-59.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ファイルの変換&lt;/h3&gt;
&lt;p&gt;上記のサイトでは契約書の雛形は Word 形式(docx)で提供されているのでまずは扱いやすいように Markdown に変換します。
ドキュメント形式のファイル変換には &lt;a href=&quot;https://pandoc.org/&quot;&gt;pandoc&lt;/a&gt;を使うのが一般的です。&lt;/p&gt;
&lt;p&gt;pandoc をゼロからインストールするのは面倒なので Docker image を探してきて利用します。&lt;/p&gt;
&lt;p&gt;コマンド実行例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker run --rm \
             --volume &quot;$(pwd):/data&quot; \
             --user $(id -u):$(id -g) pandoc/core jtuc/ikkai-keiyaku-jyuninin.docx -o jtuc/ikkai-keiyaku-jyuninin.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;出力されたMarkdownのファイルはこちらになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;**業務委託契約書**

○○（以下「委託者」という。）と△△（以下「受託者」という。）は、委託者が受託者に対し、□□を委託するにあたって、次のとおり業務委託契約（以下「本契約」という。）を締結する。

第１条（委託業務の内容）

委託者は、受託者に対し、以下の内容で業務を委託する（以下「本業務」という。）。

業務内容：

業務期間：

委託料：

第２条（支払方法）

委託者は、本業務の委託料を、　　年　月　日までに受託者の指定する銀行口座に振り込む方法により支払う。ただし、振込手数料は委託者の負担とする。

第３条（報告）

受託者は、本業務の完了後、速やかに委託者に対し、業務完了報告書を交付する。

２．委託者は、前項の業務完了報告書を受領した日の翌日から起算して５営業日以内に、その内容を確認した旨の通知しなければならない。

３．前項に基づく委託者から受託者への通知があったときに本業務は完了したものとし、前項の期限内に前項の通知が受託者に到達しない場合も同様とする。

第４条（秘密保持）

受託者は、委託者の承諾なくして、本契約に関連して委託者から秘密であることを明示して開示された営業上又は技術上の秘密情報（以下「秘密情報」という。）を、第三者に対して開示、漏洩してはならず、本契約の履行以外の目的で使用してはならない。ただし、以下のいずれかに該当する情報は秘密情報には含まれない。

（１）開示された時点において、既に公知であった情報

（２）開示された後に受託者の責任によらないで公知になった情報

（３）開示された時点において、受託者が既に了知していた情報

（４）正当な権限を有する第三者から、受託者が秘密保持義務を負うことなく適法に取得した情報
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;予期していた内容とは異なります。
理想としては、第x条のところは見出し1でマークアップされて、第x項のところは見出し2でマークアップされてきてほしいですが、すべてがただのテキストとして出されてしまっています。&lt;/p&gt;
&lt;p&gt;もし、元のdocxにWordの「見出し」を使ってマークアップされていたらMarkdownでも見出し情報が維持されるのではないかと思って
テンプレのdocxファイルに対して見出しをいくつか使ってマークアップして変換してみました。&lt;/p&gt;
&lt;p&gt;その際の出力は以下のようになり、見出しとして出力されました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 第１条（委託業務の内容）

委託者は、受託者に対し、以下の内容で業務を委託する（以下「本業務」という。）。

業務内容：

業務期間：

委託料：

# 第２条（支払方法）

委託者は、本業務の委託料を、　　年　月　日までに受託者の指定する銀行口座に振り込む方法により支払う。ただし、振込手数料は委託者の負担とする。

# 第３条（報告）

受託者は、本業務の完了後、速やかに委託者に対し、業務完了報告書を交付する。

２．委託者は、前項の業務完了報告書を受領した日の翌日から起算して５営業日以内に、その内容を確認した旨の通知しなければならない。

３．前項に基づく委託者から受託者への通知があったときに本業務は完了したものとし、前項の期限内に前項の通知が受託者に到達しない場合も同様とする。

# 第４条（秘密保持）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;手動でこのようなマークアップを行うのも手間なので自動でやってみます。
以下のようなコードを書いて、LLMを利用してMarkdownファイルに見出し情報を付加してみました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import sys
import os
from openai import OpenAI

client = OpenAI(
    # This is the default and can be omitted
    api_key=os.environ.get(&quot;OPENAI_API_KEY&quot;),
)

def convert_markdown(input_file):
    # 入力ファイルを読み込む
    with open(input_file, &apos;r&apos;, encoding=&apos;utf-8&apos;) as file:
        content = file.read()

    # OpenAI APIにリクエストを送信
    response = chat_completion = client.chat.completions.create(
        messages=[
            {&quot;role&quot;: &quot;system&quot;, &quot;content&quot;: &quot;このファイルは契約書で法務文書です。タイトルや見出しをmarkdownで表現するようにフォーマットしてください。契約書のタイトルは見出し1，条項は見出し2を使うようにしてください。重要な文書なので文章の内容は変更しないでください。見出しやタイトルのマークアップだけを行ってください。また、見出しと同時に箇条書きに関しても可能ならばMarkdownで箇条書きにしてください。&quot;},
            {&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: content}
        ],
        model=&quot;gpt-4o&quot;,
    )

    # 変換された内容を取得
    converted_content = response.choices[0].message.content

    # 出力ファイルに書き込む
    with open(&apos;out.md&apos;, &apos;w&apos;, encoding=&apos;utf-8&apos;) as file:
        file.write(converted_content)

if __name__ == &quot;__main__&quot;:
    if len(sys.argv) != 2:
        print(&quot;使用方法: OPENAI_API_KEY=xxx python convert.py input_file.md&quot;)
        sys.exit(1)

    input_file = sys.argv[1]
    convert_markdown(input_file)
    print(f&quot;{input_file} を変換し、結果を out.md に保存しました。&quot;)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のようなコマンドで実行すると、out.mdというファイルに出力されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;OPENAI_API_KEY=sk-proj-xxxxx python3 convert.py jtuc/ikkai-keiyaku-jyuninin.md
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;vimdiff&lt;/code&gt; で差分を表示してみました。文章も変更されてしまっていますが、とりあえず今回はこれで進めます。
&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-20-16-30-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 業務委託契約書

○○（以下「委託者」という。）と△△（以下「受託者」という。）は、委託者が受託者に対し、□□を委託するにあたって、次のとおり業務委託契約（以下「本契約」という。）を締結する。

## 第１条（委託業務の内容）

委託者は、受託者に対し、以下の内容で業務を委託する（以下「本業務」という。）。

- 業務内容：
- 業務期間：
- 委託料：

## 第２条（支払方法）

委託者は、本業務の委託料を、　　年　月　日までに受託者の指定する銀行口座に振り込む方法により支払う。ただし、振込手数料は委託者の負担とする。

## 第３条（報告）

受託者は、本業務の完了後、速やかに委託者に対し、業務完了報告書を交付する。

1. 委託者は、前項の業務完了報告書を受領した日の翌日から起算して５営業日以内に、その内容を確認した旨の通知しなければならない。
2. 前項に基づく委託者から受託者への通知があったときに本業務は完了したものとし、前項の期限内に前項の通知が受託者に到達しない場合も同様とする。

## 第４条（秘密保持）

受託者は、委託者の承諾なくして、本契約に関連して委託者から秘密であることを明示して開示された営業上又は技術上の秘密情報（以下「秘密情報」という。）を、第三者に対して開示、漏洩してはならず、本契約の履行以外の目的で使用してはならない。ただし、以下のいずれかに該当する情報は秘密情報には含まれない。

- 開示された時点において、既に公知であった情報
- 開示された後に受託者の責任によらないで公知になった情報
- 開示された時点において、受託者が既に了知していた情報
- 正当な権限を有する第三者から、受託者が秘密保持義務を負うことなく適法に取得した情報

## 第５条（再委託の禁止）

受託者は、あらかじめ書面により委託者の承諾を得た場合、又は、正当な理由がある場合を除き、本業務の全部又は一部を、第三者に再委託することができない。

1. 受託者は、前項の規定により第三者に再委託する場合も、本契約に規定する受託者の義務を免れず、かつ第三者に対しても本契約上の義務を遵守させる義務を負う。

## 第６条（権利義務の譲渡等の禁止）

委託者及び受託者は、あらかじめ書面により相手方の承諾を得なければ、本契約上の権利義務ならびに本契約上の地位を、第三者に譲渡、移転その他の方法により処分してはならない。

## 第７条（損害賠償）

本契約に違反し、相手方に損害を負わせた当事者は、本契約の委託料を上限として当該違反に起因して発生した損害を賠償しなければならない。

## 第８条（不可抗力）

委託者及び受託者は、天災地変、戦争、内乱、暴動、疫病、感染症の流行等、当事者の合理的支配を超える事由により、義務の履行の全部又は一部が妨げられる範囲において、本契約に基づく義務の履行を免除され、一切の責任を負わない。

## 第９条（解除）

委託者及び受託者は、相手方が本契約に違反したときは、相当の期間を定めた催告をし、催告期間が終了しても違反が是正されない場合、本契約を解除できる。

1. 委託者及び受託者は、相手方に次の各号いずれかに該当する事由が生じたときは、何らの催告を要することなく、直ちに本契約を解除することができる。
    - 本契約の違反が重大なとき
    - 破産手続開始、民事再生手続開始、会社更生手続開始の申立てがあったとき
    - 差押え、仮差押え等の強制執行、または公租公課の滞納処分を受けたとき
    - 支払停止、または支払い不能に陥ったとき、若しくは手形が不渡となったとき
2. 前二項の定めにより本契約が解除された場合でも、解除権を行使した当事者は損害賠償の請求を妨げられない。

## 第１０条（契約の中途終了の場合の報酬請求）

本契約が解除その他の事由により途中で終了したときは、委託者は受託者に対して、終了までになされた履行割合に応じた額の委託料を支払うものとする。

## 第１１条（反社会的勢力の排除）

委託者及び受託者は、現在、暴力団、暴力団員、暴力団準構成員、暴力団関係企業、総会屋、社会運動等標榜ゴロ、その他これに準ずる者（以下「反社会的勢力」という。）のいずれにも該当しないことを表明し、かつ将来にわたっても該当しないことを確約する。

1. 委託者及び受託者は、相手方が次の各号のいずれかに該当する場合、ただちに本契約を解除することができ、解除により相手方に損害が生じてもこれを賠償することを要しない。
    - 相手方または相手方の役員が反社会的勢力に該当すると認められるとき
    - 相手方の経営に反社会的勢力が実質的に関与していると認められるとき
    - 相手方が反社会的勢力を利用していると認められるとき
    - 相手方が反社会的勢力に対して資金等を提供し、または便宜を供与するなどの関与をしていると認められるとき
    - 相手方または相手方の役員もしくは相手方の経営に実質的に関与している者が反社会的勢力と社会的に非難されるべき関係を有しているとき
    - 自らまたは第三者を利用して、暴力的な要求行為、法的な責任を超えた不当な要求行為、脅迫的な言動、暴力および風説の流布・偽計・威力を用いた信用毀損・業務妨害その他これらに準ずる行為に及んだとき
2. 委託者及び受託者は、自己が前項各号に該当したため相手方が本契約を解除した場合、相手方に生じた損害を賠償しなければならない。

## 第１２条（存続条項）

第４条（秘密保持）、第６条（損害賠償）、第１２条（管轄）の規定は、本契約の終了後も有効に存続する。

## 第１３条（管轄）

本契約に関する一切の紛争は、○○地方裁判所を第一審の専属的合意管轄裁判所とする。

## 第１４条（協議事項）

本契約に定めのない事項、ならびに本契約の解釈について疑義を生じたときは、当事者間で誠実に協議のうえ解決する。

本契約の締結を証するため、本書を２通作成し、委託者及び受託者記名押印の上、それぞれ１通を保有する。

２０　　年　　月　　日

（委託者）

（受託者）⏎
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Pull requestをレビューするコードの作成&lt;/h2&gt;
&lt;p&gt;Markdown形式の契約書を含むドキュメントがpull requestに上がってきたらレビューするワークフローを作ります。&lt;/p&gt;
&lt;p&gt;ゼロから作るのは大変なので、ソースコードをレビューする既存のOSSを改良してみます。&lt;/p&gt;
&lt;p&gt;ベースとしてai-pr-reviewerを使ってみます。
今はpublic archiveになっています。運営元は有料の別サービスを開始してそちらに本腰を入れているみたいです。
https://github.com/coderabbitai/ai-pr-reviewer?tab=readme-ov-file&lt;/p&gt;
&lt;p&gt;また、 PR-Agentも見てみましたが、ソースコードレビューに特化した機能が沢山入っていて取捨選択するのが大変なので、
作りがシンプルなai-pr-reviewerを応用してみたいと思います。&lt;/p&gt;
&lt;p&gt;応用といっても、LLMにわたすプロンプト自体がGitHub Actionsのワークフローにかかれているので変更するだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;permissions:
  contents: read
  pull-requests: write

on:
  pull_request:
  pull_request_review_comment:
    types: [created]
  workflow_dispatch:


concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  review:
    runs-on: ubuntu-latest
    if: (github.event_name == &apos;workflow_dispatch&apos;) || (github.event_name == &apos;pull_request&apos; &amp;amp;&amp;amp; !contains(github.event.pull_request.title, &apos;release&apos;))
    timeout-minutes: 15
    steps:
      - uses: coderabbitai/openai-pr-reviewer@latest
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        with:
          debug: false
          review_simple_changes: false
          review_comment_lgtm: false
          openai_light_model: gpt-4
          openai_heavy_model: gpt-4
          openai_timeout_ms: 900000
          language: ja-JP
          path_filters: |
            !db/**
            !**/*.lock
          system_message: |
            あなたは @coderabbitai（別名 github-actions[bot]）で、OpenAIによって訓練された言語モデルです。
            あなたの目的は、非常に経験豊富な法務専門家として機能し、契約書を徹底的にレビューし、
            以下のようなキーエリアを改善するためのアドバイスを提供することです：
              - 法的リスク
              - 契約条件の明確さ
              - 法的遵守
              - 紛争解決条項
              - 守秘義務
              - 知的財産権
              - 責任の制限
              - 契約の終了条件

            些細な文法の問題や、スタイルの欠落についてはコメントしないでください。
            重要な問題を特定し、解決して全体的な契約書の品質を向上させることを目指してくださいが、細かい問題は意図的に無視してください。
          summarize: |
            次の内容でmarkdownフォーマットを使用して、最終的な回答を提供してください。

              - *ウォークスルー*: 特定の条項ではなく、全体の契約書に関する高レベルの要約を80語以内で。
              - *変更点*: 条項とその要約のテーブル。スペースを節約するために、同様の変更を持つ条項を1行にまとめることができます。

            GitHubのプルリクエストにコメントとして追加されるこの要約には、追加のコメントを避けてください。
          summarize_release_notes: |
            このプルリクエストのために、その目的と契約書のユーザーストーリーに焦点を当てて、markdownフォーマットで簡潔なサマリーを作成してください。
            変更は次のように分類し箇条書きにすること:
              &quot;概要&quot;, &quot;自社にとってのリスク&quot;, &quot;契約相手にとってのリスク&quot;, &quot;表記揺れ&quot;
            例えば:, &quot;Correction&quot;
            ```
            - 概要: 守秘義務条項が追加されました
            ```            ⏎
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;実行&lt;/h3&gt;
&lt;p&gt;あとは、pull request を作れば自動的にレビューしてくれます。&lt;/p&gt;
&lt;h3&gt;全体に対するレビュー&lt;/h3&gt;
&lt;p&gt;以下のような指摘を上げてくれました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;概要: このプルリクエストでは、新たに業務委託契約書が追加されました。主な内容としては、業務の内容、支払方法、報告義務、秘密保持、再委託の禁止、権利義務の譲渡禁止、損害賠償、不可抗力、契約解除、反社会的勢力の排除等が含まれています。また、紛争解決のための管轄裁判所や協議事項についても規定されています。&lt;/li&gt;
&lt;li&gt;自社にとってのリスク: 再委託の禁止や権利義務の譲渡禁止など、自社の柔軟性を制限する可能性があります。また、損害賠償条項により、特定の状況下での責任が増大する可能性があります。&lt;/li&gt;
&lt;li&gt;契約相手にとってのリスク: 報告義務や秘密保持など、契約相手の負担を増やす可能性があります。また、契約解除条件が厳格である場合、契約相手が契約を終了する自由度が制限される可能性があります。&lt;/li&gt;
&lt;li&gt;表記揺れ: なし&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ウォークスルー:
新規に追加された業務委託契約書は、業務内容、支払方法、報告義務、秘密保持、再委託の禁止、権利義務の譲渡禁止、損害賠償、不可抗力、契約解除、反社会的勢力の排除などを含む全面的な条項をカバーしています。&lt;/p&gt;
&lt;p&gt;変更提案してくれた箇所と視点を一覧にまとめてくれています。
&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-20-16-52-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;個別に対するレビュー&lt;/h3&gt;
&lt;p&gt;行ごとに指摘を入れてくれるのでレビュー内容が見やすいです。
議論が必要だったらそこで議論も進められるし履歴も残るので非常に見やすい UI です。&lt;/p&gt;
&lt;p&gt;内容が抜けているところを指摘してくれています。テンプレなので当たり前ですが、本番ではチェックしてくれるべき内容なので素晴らしいです。
&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-20-16-53-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;なんと、&lt;strong&gt;契約書テンプレのtypo&lt;/strong&gt;を発見してくれてます。条項の番号参照がズレています。ファイルを変換する過程で入り込んだという可能性があるので差分を確認していったのですが、大元の docx ファイルに元から入っているミスです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-20-16-55-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;損害賠償の上限について設けるべきという提案をしてくれています。確かによく見る契約書では入っている気がします。
&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-20-16-55-45.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ソースコード&lt;/h2&gt;
&lt;p&gt;こちらにおいておきます。main ブランチを fork して API キーを設定すれば使えると思います。
https://github.com/matsubo/legal-document&lt;/p&gt;
&lt;p&gt;今回のレビューの結果はこちらに置いておきます。
https://github.com/matsubo/legal-document/pull/1&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;契約書を Markdown で管理する副次的な効果&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;差分が把握しやすい&lt;/li&gt;
&lt;li&gt;時系列、ファイル同士の関係性が追いやすい。&lt;/li&gt;
&lt;li&gt;プログラムで扱いやすい。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Markdown で不足している点は以下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;テキスト情報の意味付けがちょっと貧弱なので XML や独自のマークアップ記法が必要になりそうです。
&lt;ul&gt;
&lt;li&gt;タイトル、日付、契約主体、契約期間などはほとんど共通の事項なのでマークアップされていて欲しいです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;余談&lt;/h2&gt;
&lt;p&gt;契約締結業務を Git や GitHub を使って構築するのも可能かなと思いました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Git によるソースコードのバージョン管理は、ブロックチェインの Proof of Works のモデルに似ているところがあります。&lt;/li&gt;
&lt;li&gt;Git のリビジョンツリーに契約対象者それぞれがサインする対象の名前を書いてコミットすれば同意とみなしても良いなと思いました。&lt;/li&gt;
&lt;li&gt;Git の分散リポジトリという点も契約書の双方保管という意図には良さそうです。用途が違うので耐改ざん性などの問題はありそうですが 9 割型の要素はそのまま使えそうな気がしました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AI による契約書内容のチェックを実装してみました。&lt;/li&gt;
&lt;li&gt;プロンプトを改良したりすれば一定数業務でも使えるレベルかなと思いました。&lt;/li&gt;
&lt;li&gt;法務担当の居ない会社や個人の方はアドバイザ的な役割ですぐに使っても良いレベルかなと思います。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>LLMで難易度の高いゴールを達成するために：5つのデザインパターンで差をつける</title><link>https://blog.teraren.com/posts/llm-design-pattern/</link><guid isPermaLink="true">https://blog.teraren.com/posts/llm-design-pattern/</guid><description>回答を得るのに複雑なステップが必要な場合、定石となるパターンが存在します。主に 5 つ</description><pubDate>Tue, 10 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;概要&lt;/h1&gt;
&lt;p&gt;回答を得るのに複雑なステップが必要な場合、定石となるパターンが存在します。主に 5 つ
ピックアップしましたので紹介します。&lt;/p&gt;
&lt;p&gt;オブジェクト指向プログラミングで言う &lt;a href=&quot;https://ja.wikipedia.org/wiki/%E3%82%AE%E3%83%A3%E3%83%B3%E3%82%B0%E3%83%BB%E3%82%AA%E3%83%96%E3%83%BB%E3%83%95%E3%82%A9%E3%83%BC_(%E6%83%85%E5%A0%B1%E5%B7%A5%E5%AD%A6)&quot;&gt;GoF&lt;/a&gt;のデザインパターンに近いものとして考えても
らえると有益さがわかると思います。&lt;/p&gt;
&lt;h1&gt;LLMデザインパターン&lt;/h1&gt;
&lt;h2&gt;チェイン・オブ・ソート (Chain of Thought)&lt;/h2&gt;
&lt;p&gt;LLM を使用して問題を段階的に解決する手法です。LLM は中間的な思考過程を示すことがで
きるため、問題解決の途中経過を可視化できます。例えば、数学の問題を解く際に、LLM が
途中の計算ステップを示してくれることで、解答の過程を理解しやすくなります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-10-12-01-33.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ステップバイステップ推論 (Step-by-Step Reasoning)&lt;/h2&gt;
&lt;p&gt;ステップバイステップ推論は、問題を小さなステップに分解し、各ステップごとに LLM の出力を得る手法です。
例えば、複雑な論理パズルを解く際に、問題を小さな部分に分割し、 LLM が各ステップの解答を提供することで、全体の解答を導き出すことができます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-10-12-01-53.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;反復的精緻化 (Iterative Refinement)&lt;/h2&gt;
&lt;p&gt;初期の回答を基に、徐々に改善や詳細化を重ねていく手法です。
LLM が初期の回答を生成した後、その回答を元にさらなる情報を追加し、より正確な回答を得ることができます。例えば、文章の要約を生成する際に、LLM が初期の要約を提供し、その後、追加の文脈情報を与えることで、より適切な要約を作成できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-10-12-02-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;タスク分解 (Task Decomposition)&lt;/h2&gt;
&lt;p&gt;複雑なタスクを小さなサブタスクに分解し、それぞれを個別に処理する手法です。LLM が各サブタスクの解答を提供することで、全体のタスクを効率的に解決できます。例えば、プログラミングの問題を解く際に、大きな問題を小さな関数に分割し、LLM が各関数の実装をサポートすることで、全体のプログラムを完成させることができます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-10-12-02-39.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;自己一貫性 (Self-Consistency)&lt;/h2&gt;
&lt;p&gt;複数の推論パスを生成し、最も一貫性のある結果を選択する手法です。LLM が複数の解答候補を生成し、それらの一貫性を評価することで、最も信頼性の高い解答を選び出すことがで
きます。例えば、意思決定のサポートシステムにおいて、LLM が異なる選択肢に対する意見や理由を提供し、一貫性の高い結論を導くことができます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-09-10-12-03-01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;思ったこと&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;デザインパターンは、その領域で問題解決を何回も繰り返していると見えてくる共通の事象をモデル化した物です。LLM のデザインパターンが明確にまとめられていませんが経験上この 5 つは良く使います。&lt;/li&gt;
&lt;li&gt;デザインパターンを知っておくことで生成 LLM で自分の意図した結果が得られなかったときにどのように問題を解決するかといった知見を得られます。&lt;/li&gt;
&lt;li&gt;今までは LLM を使った問題解決が不可能だと思われていた事象をデザインパターンによって問題解決の手法を考えられるようになった。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Contributions&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;壁打ち: &lt;a href=&quot;https://claude.ai/chats&quot;&gt;Claude 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;挿絵: &lt;a href=&quot;https://www.napkin.ai/&quot;&gt;Napkin Al&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>AIで論文生成をするにはこんなふうに (AI Scientistの解説と実践)</title><link>https://blog.teraren.com/posts/ai-scientist-try/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ai-scientist-try/</guid><description>私の中で、論文の執筆というのは豊富な専門知識とアイデアが必要なので**LLMでの代替は困難かと思っていました**。 しかし、良く考えてみるれば、「アイデア＝既存の事象の組み合わせ」という 提言もあるのでLLMでの代替は可能かなと思い始めまし</description><pubDate>Fri, 06 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3行サマリー&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2024 年 8 月 13 日に &lt;a href=&quot;https://note.com/shi3zblog/n/nc8ef423e2461&quot;&gt;論文をLLMで生成する&lt;/a&gt;記事が公開されました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;難易度の高いゴールを達成するための複雑な過程&lt;/strong&gt;を LLM で扱うためのアプローチを紹介します。&lt;/li&gt;
&lt;li&gt;AI Scientist のソースコードの重要部分を解説します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;私の中で、論文の執筆というのは豊富な専門知識とアイデアが必要なので&lt;strong&gt;LLMでの代替は困難かと思っていました&lt;/strong&gt;。 しかし、良く考えてみるれば、「アイデア＝既存の事象の組み合わせ」という &lt;a href=&quot;https://amzn.to/4dygIjA&quot;&gt;提言&lt;/a&gt;もあるのでLLMでの代替は可能かなと思い始めました。&lt;/p&gt;
&lt;h3&gt;論文の定義&lt;/h3&gt;
&lt;p&gt;領域によって論文の定義が異なってくると思いますので、論文とはなにかを定義する必要があります。GPT-4 の回答の一部を引用すると以下です。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;新しい知識や発見、理論&lt;/strong&gt;を提案し、既存の知識に貢献することを目的としています。研究結果の報告、理論の検証、&lt;strong&gt;新しい視点&lt;/strong&gt;の提案などが含まれます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;主に理系の学術論文では、&lt;strong&gt;新しさ&lt;/strong&gt;が含まれていることが重要のようです。&lt;/p&gt;
&lt;p&gt;大学の研究室でもレビューされる際に「&lt;strong&gt;新規性は何なの？&lt;/strong&gt;」というテーマで一番最初にディスカッションしたことを思い出します。&lt;/p&gt;
&lt;h3&gt;アプローチ&lt;/h3&gt;
&lt;p&gt;ではその新規性を作り出し、論文というアウトプットをどのように作るかというところです。&lt;/p&gt;
&lt;p&gt;論文の執筆作業は単純でもありません。LLM に「機械学習の論文を書いて」といってもまともなものが出力されることは現時点では無いでしょう。&lt;/p&gt;
&lt;p&gt;今回の論文執筆というタスクは複雑で難しい思いますが、そのような事象を LLM を使って複雑な事象を扱うアプローチがあります。&lt;/p&gt;
&lt;p&gt;次に各アプローチと説明を紹介します。&lt;/p&gt;
&lt;h4&gt;チェイン・オブ・ソート (Chain of Thought)&lt;/h4&gt;
&lt;p&gt;LLM を使用して問題を段階的に解決する手法です。LLM は中間的な思考過程を示すことができるため、問題解決の途中経過を可視化できます。例えば、数学の問題を解く際に、LLM が途中の計算ステップを示してくれることで、解答の過程を理解しやすくなります。&lt;/p&gt;
&lt;h4&gt;ステップバイステップ推論 (Step-by-Step Reasoning)&lt;/h4&gt;
&lt;p&gt;ステップバイステップ推論は、問題を小さなステップに分解し、各ステップごとに LLM の出力を得る手法です。例えば、複雑な論理パズルを解く際に、問題を小さな部分に分割し、LLM が各ステップの解答を提供することで、全体の解答を導き出すことができます。&lt;/p&gt;
&lt;h4&gt;反復的精緻化 (Iterative Refinement)&lt;/h4&gt;
&lt;p&gt;初期の回答を基に、徐々に改善や詳細化を重ねていく手法です。LLM が初期の回答を生成した後、その回答を元にさらなる情報を追加し、より正確な回答を得ることができます。例えば、文章の要約を生成する際に、LLM が初期の要約を提供し、その後、追加の文脈情報を与えることで、より適切な要約を作成できます。&lt;/p&gt;
&lt;h4&gt;タスク分解 (Task Decomposition)&lt;/h4&gt;
&lt;p&gt;複雑なタスクを小さなサブタスクに分解し、それぞれを個別に処理する手法です。LLM が各サブタスクの解答を提供することで、全体のタスクを効率的に解決できます。例えば、プログラミングの問題を解く際に、大きな問題を小さな関数に分割し、LLM が各関数の実装をサポートすることで、全体のプログラムを完成させることができます。&lt;/p&gt;
&lt;h4&gt;自己一貫性 (Self-Consistency)&lt;/h4&gt;
&lt;p&gt;複数の推論パスを生成し、最も一貫性のある結果を選択する手法です。LLM が複数の解答候補を生成し、それらの一貫性を評価することで、最も信頼性の高い解答を選び出すことができます。例えば、意思決定のサポートシステムにおいて、LLM が異なる選択肢に対する意見や理由を提供し、一貫性の高い結論を導くことができます。&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;info&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;上記のアプローチの詳細は以下の記事にまとめました。
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;https://zenn.dev/minedia/articles/llm-design-pattern&lt;/p&gt;
&lt;h2&gt;AI Scientistを動かしてみる&lt;/h2&gt;
&lt;p&gt;システムの設計を頭に入れたうえで、各実装について確認していきます。&lt;/p&gt;
&lt;h3&gt;AI Scientistの構成&lt;/h3&gt;
&lt;p&gt;AI Scientist の構成図を以下に引用します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/2024-08-16-16-28-55.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;AI Scientist の中では、前述の 4 つのアプローチをすべて取り入れています。
やはり、LLM によって複雑な事象を扱うためには必然的にそのようなアプローチを取ることになるのかと思います。&lt;/p&gt;
&lt;h3&gt;動作環境のセットアップ&lt;/h3&gt;
&lt;p&gt;実際に自分の学習のために動かしてみます。&lt;/p&gt;
&lt;p&gt;基本的に詳細なセットアップの内容はオリジナルの readme にきちんと書かれているので、今回は私が実行したコマンドや設定を貼っておきます。&lt;/p&gt;
&lt;h4&gt;condaのセットアップ&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://anaconda.org/&quot;&gt;conda&lt;/a&gt;が必要なのでセットアップしていない場合はセットアップします。
色々聞かれますが、基本的にはデフォルトで大丈夫です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget https://repo.anaconda.com/archive/Anaconda3-2024.06-1-Linux-x86_64.sh
bash Anaconda3-2024.06-1-Linux-x86_64.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;fishを使っているので、環境変数を読み込みます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source /home/matsu/anaconda3/etc/profile.d/conda.csh
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;AI Scientistの準備&lt;/h4&gt;
&lt;p&gt;condaで環境を作成して、pipでインストールしていきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;conda create -n ai_scientist python=3.11
conda activate ai_scientist
pip install anthropic aider-chat backoff openai
pip install matplotlib pypdf pymupdf4llm
sudo apt-get install texlive-full -y
pip install torch numpy transformers datasets tiktoken wandb tqdm
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;API Keyの準備&lt;/h4&gt;
&lt;p&gt;最低限動かすだけならOpenAIのAPIキーだけで良いので設定しておきます。&lt;/p&gt;
&lt;h5&gt;bash&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;export OPENAI_API_KEY=&quot;YOUR KEY HERE&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;csh&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;set OPENAI_API_KEY &quot;YOUR KEY HERE&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;NanoGPTの準備&lt;/h4&gt;
&lt;p&gt;GPTに学習させてLLMを準備します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python data/enwik8/prepare.py
python data/shakespeare_char/prepare.py
python data/text8/prepare.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;今回はワークフローの全体感を掴むのが目的なので
liteバージョンで実行します。&lt;/p&gt;
&lt;p&gt;実行するので以下の方法で行います。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd templates/nanoGPT_lite &amp;amp;&amp;amp; python experiment.py --out_dir run_0 &amp;amp;&amp;amp; python plot.py
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GPUが刺さっていない場合は、以下のようにCPUに変更して実行します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ git diff
diff --git a/templates/nanoGPT/experiment.py b/templates/nanoGPT/experiment.py
index 303aebd..747755e 100644
--- a/templates/nanoGPT/experiment.py
+++ b/templates/nanoGPT/experiment.py
@@ -348,7 +348,7 @@ def train(dataset=&quot;shakespeare_char&quot;, out_dir=&quot;run_0&quot;, seed_offset=0):
     # DDP settings
     backend = &quot;nccl&quot;  # &apos;nccl&apos;, &apos;gloo&apos;, etc.
     # system
-    device = &quot;cuda&quot;  # Always use CUDA
+    device = &quot;cpu&quot;  # Always use CUDA
     dtype = (
         &quot;bfloat16&quot;
         if torch.cuda.is_available() and torch.cuda.is_bf16_supported()
diff --git a/templates/nanoGPT_lite/experiment.py b/templates/nanoGPT_lite/experiment.py
index 892ba72..f834b2f 100644
--- a/templates/nanoGPT_lite/experiment.py
+++ b/templates/nanoGPT_lite/experiment.py
@@ -348,7 +348,7 @@ def train(dataset=&quot;shakespeare_char&quot;, out_dir=&quot;run_0&quot;, seed_offset=0):
     # DDP settings
     backend = &quot;nccl&quot;  # &apos;nccl&apos;, &apos;gloo&apos;, etc.
     # system
-    device = &quot;cuda&quot;  # Always use CUDA
+    device = &quot;cpu&quot;  # Always use CUDA
     dtype = (
         &quot;bfloat16&quot;
         if torch.cuda.is_available() and torch.cuda.is_bf16_supported()
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;NPEETのインストール&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/gregversteeg/NPEET.git
cd NPEET
pip install .
pip install scikit-learn
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;NPEET（Non-parametric Entropy Estimation Toolbox）は、連続変数と離散変数の両方に対するエントロピー、相互情報量、条件付き相互情報量の推定を行うPythonライブラリです。このツールは、Kullback-Leibler分散や混合変数間の相互情報量の推定もサポートしています。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;8年前ぐらいに作られたライブラリです。pipで入らないのでcloneしてインストールします。&lt;/p&gt;
&lt;h4&gt;2D Diffusionの設定&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;cd templates/2d_diffusion &amp;amp;&amp;amp; python experiment.py --out_dir run_0 &amp;amp;&amp;amp; python plot.py
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Grokkingのセットアップ&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;cd templates/grokking &amp;amp;&amp;amp; python experiment.py --out_dir run_0 &amp;amp;&amp;amp; python plot.py
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;プログラムの実行&lt;/h4&gt;
&lt;p&gt;最低限の準備は上記でOKです。
必要な引数を設定して実行します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python launch_scientist.py --model &quot;gpt-4o-2024-05-13&quot; --experiment nanoGPT_lite --num-ideas 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これで、しばらく放置する感じです。&lt;/p&gt;
&lt;p&gt;実行を以下に掲載しておきますが、多分24時間ぐらい動かしておいてエラーで止まりました。最終的な論文は出力されませんでした。&lt;/p&gt;
&lt;p&gt;一旦、今回の記事スコープでは深追いしないでおきます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;実行出力:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ OPENAI_API_KEY=&apos;sk-pro-xxxxxxx&apos; python launch_scientist.py --model &quot;gpt-4o-2024-05-13&quot; --experiment nanoGPT_lite --num-ideas 1
Using GPUs: []
Using OpenAI API with model gpt-4o-2024-05-13.

Generating idea 1/1
Iteration 1/3
{&apos;Name&apos;: &apos;adaptive_embeddings&apos;, &apos;Title&apos;: &apos;Adaptive Embeddings: Context-Aware Token Representations for Enhanced Language Modeling&apos;, &apos;Experiment&apos;: &apos;Implement a mechanism to periodically update token embeddings based on attention weights. Modify the forward method of the GPT model to include a step where token embeddings are adjusted based on the attention weights from the transformer layers. Experiment with different update frequencies and evaluate the performance improvement compared to static embeddings.&apos;, &apos;Interestingness&apos;: 8, &apos;Feasibility&apos;: 5, &apos;Novelty&apos;: 7}
Iteration 2/3

{&apos;Name&apos;: &apos;adaptive_embeddings&apos;, &apos;Title&apos;: &apos;Adaptive Embeddings: Context-Aware Token Representations for Enhanced Language Modeling&apos;, &apos;Experiment&apos;: &apos;Implement a mechanism to periodically update token embeddings using a weighted sum of the current embedding and the attention-weighted context vector. Modify the forward method of the GPT model to include this update step. Experiment with different update frequencies, such as after each epoch or every few epochs, to balance computational efficiency and performance. Evaluate the performance improvement compared to static embeddings using validation los
s and generation quality metrics.&apos;, &apos;Interestingness&apos;: 8, &apos;Feasibility&apos;: 6, &apos;Novelty&apos;: 7}
Iteration 3/3
{&apos;Name&apos;: &apos;adaptive_embeddings&apos;, &apos;Title&apos;: &apos;Adaptive Embeddings: Context-Aware Token Representations for Enhanced Language Modeling&apos;, &apos;Experiment&apos;: &apos;Implement a mechanism to periodically update token embeddings using a weighted sum of the current embedding and the attention-weighted context vector. Modify the forward method of the GPT model to include this update step. Experiment with different update frequencies, such as after each epoch or every few epochs, to balance computational efficiency and performance. Evaluate the performance improvement compared to static embeddings using validation los
s and generation quality metrics.&apos;, &apos;Interestingness&apos;: 8, &apos;Feasibility&apos;: 6, &apos;Novelty&apos;: 7}
Idea generation converged after 3 iterations.

Checking novelty of idea 0: adaptive_block_size
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 0.3 seconds after 1 tries calling function search_for_papers at 08:45:59
Response Status Code: 200
Response Content: {&quot;total&quot;: 5042, &quot;offset&quot;: 0, &quot;next&quot;: 10, &quot;data&quot;: [{&quot;paperId&quot;: &quot;0e3ddf94053d06b40283f4250e37582bdcea0e9e&quot;, &quot;title&quot;: &quot;BlockLLM: Multi-tenant Finer-grained Serving for Large Language Models&quot;, &quot;abstract&quot;: &quot;The growing demand for Large Language Models (LLMs) across diverse applications has prompted a paradigm shift in the design of deep learning serving systems. Deploying LLMs, especially in multi-tenant environments, presents considerable challenges due to their high computational and memory demands
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 0.2 seconds after 1 tries calling function search_for_papers at 08:46:12
Response Status Code: 200
Response Content: {&quot;total&quot;: 429, &quot;offset&quot;: 0, &quot;next&quot;: 10, &quot;data&quot;: [{&quot;paperId&quot;: &quot;36daf0578aad5d3180d531cccbd32d65d62c8317&quot;, &quot;title&quot;: &quot;Extending Context Window in Large Language Models with Segmented Base Adjustment for Rotary Position Embeddings&quot;, &quot;abstract&quot;: &quot;In the realm of large language models (LLMs), extending the context window for long text processing is crucial for enhancing performance. This paper introduces SBA-RoPE (Segmented Base Adjustment for Rotary Position Embeddings), a novel approach designed to
Decision made: novel after round 2

Checking novelty of idea 1: layerwise_learning_rates
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 0.6 seconds after 1 tries calling function search_for_papers at 08:46:21
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 2.0 seconds after 2 tries calling function search_for_papers at 08:46:22


Response Status Code: 200
Response Content: {&quot;total&quot;: 16299, &quot;offset&quot;: 0, &quot;next&quot;: 10, &quot;data&quot;: [{&quot;paperId&quot;: &quot;3fa7f7565e815d8a5649441e4d1ba7db91e63ea0&quot;, &quot;title&quot;: &quot;Layer-wise Pruning and Auto-tuning of Layer-wise Learning Rates in Fine-tuning of Deep Networks&quot;, &quot;abstract&quot;: &quot;Existing fine-tuning methods use a single learning rate over all layers. In this paper, first, we discuss that trends of layer-wise weight variations by fine-tuning using a single learning rate do not match the well-known notion that lower-level layers extract general fea
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 0.4 seconds after 1 tries calling function search_for_papers at 08:46:32
Response Status Code: 200
Response Content: {&quot;total&quot;: 817, &quot;offset&quot;: 0, &quot;next&quot;: 10, &quot;data&quot;: [{&quot;paperId&quot;: &quot;fc4bb7f1bac92053bbd64850d1c6faf13c4cef88&quot;, &quot;title&quot;: &quot;Improving Knowledge Distillation in Transfer Learning with Layer-wise Learning Rates&quot;, &quot;abstract&quot;: &quot;Transfer learning methods start performing poorly when the complexity of the learning task is increased. Most of these methods calculate the cumulative differences of all the matched features and then use them to back-propagate that loss through all the layers. Contrary to these metho
Response Status Code: 200
Response Content: {&quot;total&quot;: 8738, &quot;offset&quot;: 0, &quot;next&quot;: 10, &quot;data&quot;: [{&quot;paperId&quot;: &quot;3fa7f7565e815d8a5649441e4d1ba7db91e63ea0&quot;, &quot;title&quot;: &quot;Layer-wise Pruning and Auto-tuning of Layer-wise Learning Rates in Fine-tuning of Deep Networks&quot;, &quot;abstract&quot;: &quot;Existing fine-tuning methods use a single learning rate over all layers. In this paper, first, we discuss that trends of layer-wise weight variations by fine-tuning using a single learning rate do not match the well-known notion that lower-level layers extract general feat
Decision made: novel after round 3

Checking novelty of idea 2: adaptive_embeddings
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 0.6 seconds after 1 tries calling function search_for_papers at 08:46:53
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 1.6 seconds after 2 tries calling function search_for_papers at 08:46:54
Response Status Code: 500
Response Content: {&quot;message&quot;: &quot;Internal Server Error&quot;}

Backing off 3.9 seconds after 3 tries calling function search_for_papers at 08:46:58
Response Status Code: 200
Response Content: {&quot;total&quot;: 2338, &quot;offset&quot;: 0, &quot;next&quot;: 10, &quot;data&quot;: [{&quot;paperId&quot;: &quot;f8b901c330e7f946ef93453b24682f294b8764a1&quot;, &quot;title&quot;: &quot;In-domain Context-aware Token Embeddings Improve Biomedical Named Entity Recognition&quot;, &quot;abstract&quot;: &quot;Rapidly expanding volume of publications in the biomedical doma
in makes it increasingly difficult for a timely evaluation of the latest literature. That, along with a push for automated evaluation of clinical reports, present opportunities for effective natural language processing me
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 0.3 seconds after 1 tries calling function search_for_papers at 08:47:16
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 0.6 seconds after 2 tries calling function search_for_papers at 08:47:16
Response Status Code: 200
Response Content: {&quot;total&quot;: 145, &quot;offset&quot;: 0, &quot;next&quot;: 10, &quot;data&quot;: [{&quot;paperId&quot;: &quot;ea6982a936a2b263bbf46ff6eb27fc0b63fddaf7&quot;, &quot;title&quot;: &quot;VL-GPT: A Generative Pre-trained Transformer for Vision and Language Understanding and Generation&quot;, &quot;abstract&quot;: &quot;In this work, we introduce Vision-Language Generative Pre-trained Transformer (VL-GPT), a transformer model proficient at concurrently perceiving and generating visual and linguistic data. VL-GPT achieves a unified pre-training approach for both image and text modalities
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 0.1 seconds after 1 tries calling function search_for_papers at 08:47:28
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 1.3 seconds after 2 tries calling function search_for_papers at 08:47:29
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 1.7 seconds after 3 tries calling function search_for_papers at 08:47:30
Response Status Code: 200
Response Content: {&quot;total&quot;: 14379, &quot;offset&quot;: 0, &quot;next&quot;: 10, &quot;data&quot;: [{&quot;paperId&quot;: &quot;c7a3f9cc61cfafdc307f8ae24430b6b1121f9b2c&quot;, &quot;title&quot;: &quot;ToolkenGPT: Augmenting Frozen Language Models with Massive Tools via Tool Embeddings&quot;, &quot;abstract&quot;: &quot;Augmenting large language models (LLMs) with external tools has emerged as a promising approach to solving complex problems. However, traditional methods, which finetune LLMs with tool demonstration data, can be both costly and restricted to a predefined set of tools. Recent in-cont
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 0.0 seconds after 1 tries calling function search_for_papers at 08:47:41
Response Status Code: 429
Response Content: {&quot;message&quot;: &quot;Too Many Requests. Please wait and try again or apply for a key for higher rate limits. https://www.semanticscholar.org/product/api#api-key-form&quot;, &quot;code&quot;: &quot;429&quot;}
Backing off 0.5 seconds after 2 tries calling function search_for_papers at 08:47:41
Response Status Code: 200
Response Content: {&quot;total&quot;: 213, &quot;offset&quot;: 0, &quot;next&quot;: 10, &quot;data&quot;: [{&quot;paperId&quot;: &quot;ec68079f15b620a8a7ad19b3477f895e2ecf193d&quot;, &quot;title&quot;: &quot;HeatViT: Hardware-Efficient Adaptive Token Pruning for Vision Transformers&quot;, &quot;abstract&quot;: &quot;While vision transformers (ViTs) have continuously achieved new milestones in the field of computer vision, their sophisticated network architectures with high computation and memory costs have impeded their deployment on resource-limited edge devices. In this paper, we propose a hardware-effic
Decision made: novel after round 4
Processing idea: adaptive_block_size
Failed to evaluate idea adaptive_block_size: [Errno 2] No such file or directory: &apos;templates/nanoGPT_lite/run_0/final_info.json&apos;
Processing idea: layerwise_learning_rates
Failed to evaluate idea layerwise_learning_rates: [Errno 2] No such file or directory: &apos;templates/nanoGPT_lite/run_0/final_info.json&apos;
Processing idea: adaptive_embeddings
Failed to evaluate idea adaptive_embeddings: [Errno 2] No such file or directory: &apos;templates/nanoGPT_lite/run_0/final_info.json&apos;
All ideas evaluated.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;アイデアは生成されていたのでこちらに転記しておきます。
https://gist.github.com/matsubo/c4aaf9ccecf431bf1dc8a046f7184940&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[
  {
    &quot;Name&quot;: &quot;adaptive_block_size&quot;,
    &quot;Title&quot;: &quot;Adaptive Block Size: Dynamic Context Window Adjustment for Efficient Training&quot;,
    &quot;Experiment&quot;: &quot;Modify the model to dynamically adjust its block size during training, starting with a smaller block size and gradually increasing it. This could potentially lead to faster initial training and better long-range dependency learning.&quot;,
    &quot;Interestingness&quot;: 6,
    &quot;Feasibility&quot;: 4,
    &quot;Novelty&quot;: 4,
    &quot;novel&quot;: true
  },
  {
    &quot;Name&quot;: &quot;layerwise_learning_rates&quot;,
    &quot;Title&quot;: &quot;Layer-wise Learning Rate Adaptation: Optimizing Training Dynamics in Transformer Models&quot;,
    &quot;Experiment&quot;: &quot;Implement layer-wise learning rates, where each transformer layer has its own learning rate. Modify the configure_optimizers function to assign different learning rates to different layers, with deeper layers having lower learning rates. Compare the training dynamics, convergence speed, and final performance with the baseline model.&quot;,
    &quot;Interestingness&quot;: 4,
    &quot;Feasibility&quot;: 6,
    &quot;Novelty&quot;: 2,
    &quot;novel&quot;: true
  },
  {
    &quot;Name&quot;: &quot;curriculum_learning&quot;,
    &quot;Title&quot;: &quot;Curriculum Learning: Incremental Difficulty for Efficient Language Model Training&quot;,
    &quot;Experiment&quot;: &quot;Implement curriculum learning by starting with shorter sequences and gradually increasing the sequence length during training. Modify the get_batch function to adjust the block_size based on the iteration number. For instance, start with block_size=64 and double it every 1000 iterations until the maximum block_size is reached. Compare the training dynamics, convergence speed, and final performance with the baseline model.&quot;,
    &quot;Interestingness&quot;: 7,
    &quot;Feasibility&quot;: 6,
    &quot;Novelty&quot;: 5,
    &quot;novel&quot;: false
  }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;novel&lt;/code&gt; というキーの部分が新規性があるかどうかという判断結果の値です。&lt;/p&gt;
&lt;h2&gt;コード解説&lt;/h2&gt;
&lt;p&gt;3ステップあるので各ステップ分けて重要なコードを紹介します。&lt;/p&gt;
&lt;h3&gt;アイデア生成&lt;/h3&gt;
&lt;p&gt;なにはともあれ一番最初にLLMに指示するためのプロンプトが記載されているコードがこちらです。&lt;/p&gt;
&lt;p&gt;https://github.com/SakanaAI/AI-Scientist/blob/2c41a92902cc40669059283a18d5923ff03fc8b2/ai_scientist/generate_ideas.py#L311-L326&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;You are an ambitious AI PhD student who is looking to publish a paper that will contribute significantly to the field.
You have an idea and you want to check if it is novel or not. I.e., not overlapping significantly with existing literature or already well explored.
Be a harsh critic for novelty, ensure there is a sufficient contribution in the idea for a new conference or workshop paper.
You will be given access to the Semantic Scholar API, which you may use to survey the literature and find relevant papers to help you make your decision.
The top 10 results for any search query will be presented to you with the abstracts.

You will be given {num_rounds} to decide on the paper, but you do not need to use them all.
At any round, you may exit early and decide on the novelty of the idea.
Decide a paper idea is novel if after sufficient searching, you have not found a paper that significantly overlaps with your idea.
Decide a paper idea is not novel, if you have found a paper that significantly overlaps with your idea.

{task_description}
&amp;lt;experiment.py&amp;gt;
{code}
&amp;lt;/experiment.py&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;長いので機械翻訳した日本語を掲載しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;あなたは、分野に大きく貢献する論文を発表したいと考えている野心的なAI博士課程の学生です。 あるアイデアがあり、それが新規性があるかどうか、すなわち既存の文献と大きく重複していないか、あるいはすでに十分に探究されていないかを確認したいと考えています。 新しい会議やワークショップの論文として十分な貢献があるかを確認するため、新規性について厳しく評価してください。

Semantic Scholar APIへのアクセスが与えられており、関連する文献を調査し、意思決定の支援を得ることができます。 検索クエリごとに上位10件の結果とその要旨が表示されます。

決定には{num_rounds}回のラウンドが与えられていますが、すべてを使用する必要はありません。 どのラウンドでも早めに終了して、アイデアの新規性について判断することができます。 十分な検索を行った後、あなたのアイデアと大きく重複する論文が見つからなければ、そのアイデアを新規であると判断してください。 逆に、アイデアと大きく重複する論文が見つかった場合、そのアイデアは新規でないと判断してください。

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;開始はここから。
https://github.com/SakanaAI/AI-Scientist/tree/2c41a92902cc40669059283a18d5923ff03fc8b2/launch_scientist.py#L139-L149&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ideas = check_idea_novelty(ideas)&lt;/code&gt; にてそのアイデアの新規性をチェックしてます。
https://github.com/SakanaAI/AI-Scientist/blob/2c41a92902cc40669059283a18d5923ff03fc8b2/launch_scientist.py#L376-L381&lt;/p&gt;
&lt;p&gt;&lt;code&gt;success = do_idea(idea)&lt;/code&gt; で各ideaを処理しています。
https://github.com/SakanaAI/AI-Scientist/blob/2c41a92902cc40669059283a18d5923ff03fc8b2/launch_scientist.py#L428-L437&lt;/p&gt;
&lt;p&gt;&lt;code&gt;do_idea&lt;/code&gt; の中身を見ていきます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;perform_experiments(idea)&lt;/code&gt; で実験する
https://github.com/SakanaAI/AI-Scientist/blob/2c41a92902cc40669059283a18d5923ff03fc8b2/launch_scientist.py#L201-L206&lt;/p&gt;
&lt;h3&gt;論文生成&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;perform_writeup(idea)&lt;/code&gt; で論文を作成
https://github.com/SakanaAI/AI-Scientist/blob/2c41a92902cc40669059283a18d5923ff03fc8b2/launch_scientist.py#L232-L236&lt;/p&gt;
&lt;p&gt;論文のアブストラクト（概要）を生成
https://github.com/SakanaAI/AI-Scientist/blob/2c41a92902cc40669059283a18d5923ff03fc8b2/ai_scientist/perform_writeup.py#L404-L414&lt;/p&gt;
&lt;p&gt;論文の各章をLLMに生成させる。
https://github.com/SakanaAI/AI-Scientist/blob/2c41a92902cc40669059283a18d5923ff03fc8b2/ai_scientist/perform_writeup.py#L421-L447&lt;/p&gt;
&lt;p&gt;&lt;code&gt;perform_review(paper_text)&lt;/code&gt; で査読
https://github.com/SakanaAI/AI-Scientist/blob/2c41a92902cc40669059283a18d5923ff03fc8b2/launch_scientist.py#L245-L261&lt;/p&gt;
&lt;p&gt;論文をレビューする際に人間が考えていることをしっかりと言語化してどのような観点でレビューするのかをプロンプトに設定しています。&lt;/p&gt;
&lt;p&gt;https://github.com/SakanaAI/AI-Scientist/blob/2c41a92902cc40669059283a18d5923ff03fc8b2/ai_scientist/perform_review.py#L38-L62&lt;/p&gt;
&lt;p&gt;レビューで指摘した内容を用いて改善します。
https://github.com/SakanaAI/AI-Scientist/blob/2c41a92902cc40669059283a18d5923ff03fc8b2/launch_scientist.py#L263-L288&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;複雑なワークフローもブレークダウンして適切なアプローチを踏むことでLLMでは解決不可能と思われていたことも実現可能&lt;/strong&gt;になりそうです。&lt;/li&gt;
&lt;li&gt;論文を生成する際のフレームワークとかライブラリかと思いましたが、LLM 領域の論文を生成するアプリケーションという位置付けでした。&lt;/li&gt;
&lt;li&gt;ある程度モジュールに分けられていたのでソースコードが読みやすかったです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;個人的に思ったこと&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;様々なプロンプトのテクニックが駆使されているのでとても勉強になりました。&lt;/li&gt;
&lt;li&gt;「AI ではまだ不可能」と考えていた事象が、「&lt;strong&gt;このように作ればできそう&lt;/strong&gt;」という考えができるようになりました。&lt;/li&gt;
&lt;li&gt;自分のやってほしいタスクを正確に LLM へ伝達するスキルが重要になると思いました。具体的には、&lt;strong&gt;テクニカルライティングスキル&lt;/strong&gt;と&lt;strong&gt;プロンプトの&lt;/strong&gt;手法です。&lt;/li&gt;
&lt;li&gt;LLM を高校生、大学生の思考力、格段に高い外部記容量を備えている人として捉えると、その人に対して丁寧に何をすればよいか説明することに作業がにてます。新人教育と同じ感じです。&lt;/li&gt;
&lt;li&gt;今回は Python で書かれたソースコードですが、同様の事を Dify で作れると思います。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Web魚拓: 「研究」と「勉強」の違い</title><link>https://blog.teraren.com/posts/diff-study-research/</link><guid isPermaLink="true">https://blog.teraren.com/posts/diff-study-research/</guid><description>慶應SFCの井庭崇教授による「研究とは知のフロンティアを開拓すること、勉強とはフロンティアまで辿り着くこと」という名解説の魚拓</description><pubDate>Tue, 27 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;過去に何度も参照している以下のページが消えてしまいそうな感じがするので魚拓として保管しておきます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://web.sfc.keio.ac.jp/~iba/sb/log/eid75.html&quot;&gt;https://web.sfc.keio.ac.jp/~iba/sb/log/eid75.html&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;本文&lt;/h2&gt;
&lt;p&gt;タイトル: 「研究」と「勉強」の違い&lt;/p&gt;
&lt;p&gt;2008.07.25 Friday &lt;a href=&quot;http://web.sfc.keio.ac.jp/~iba/sb/log/eid75.html&quot;&gt;23:50&lt;/a&gt; | posted by &lt;a href=&quot;http://web.sfc.keio.ac.jp/~iba/sb/sb.cgi?pid=0&quot;&gt;井庭 崇&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;研究会の新規履修者の面接をした。SFCでは、学部１年生から研究会に所属し、研究に従事できるので、１年生や２年生も新規希望者としてやって来る。&lt;/p&gt;
&lt;p&gt;井庭研の面接は、担当教員の僕が一人で行うのではなく、研究会の現役メンバーを数人交えて行う。というのは、研究会というのは一種の「生き物」であって、もはや僕だけのものではないという思いがあるからだ。僕との相性のみならず、研究会メンバーとの関係もかなり重要なのだ。面接では、新規希望者一人につき、３０分の時間をかけて、取り組みたい研究テーマや、興味・関心分野について話をきいていく。&lt;/p&gt;
&lt;p&gt;その研究会面接で、僕が必ず言う話がある。それは、「研究」と「勉強」の違いについての話だ。面接で、研究テーマをきいてみると、「～を勉強したい」と答える人が多くいる。こう答えるというのは、「研究」と「勉強」の違いがよくわかっていない証拠だ。研究テーマについて話しているのではなく、これから知りたいことを挙げているに過ぎない。そこで、僕は面接時に、「研究」と「勉強」はどう違うのか、ということを説明する。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/08/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://web.sfc.keio.ac.jp/~iba/sb/img/img236_ResearchFrontier.jpg&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;まず、「知のフロンティア」があるとしよう。こちら側には、人類が現在知ってる「既知」の領域が、そして向こう側には、人類がまだ知らない「未知」の領域が広がっている。これから研究を始めるとき、当然、僕らはフロンティアに立っているわけもなく、そこから遠いところにいるだろう。そして、少しずつ知識をつけて前に進んでいく。そしてあるとき、フロンティア・ラインの一地点に到達するだろう。このようにして、既知の領域を進んでいくことを「勉強」という。不勉強でビハインドだった自分が、授業や本、人の話などから知識を得て、いまどこがフロンティアなのかがわかるようになる。これが「勉強」をするということだ。&lt;/p&gt;
&lt;p&gt;これに対し、「研究」というのは、まったく異なるアクティビティだ。研究とは、フロンティアからさらに一歩前へ進み、既知の領域を広げるということ。もちろん、道なき道を開拓しながら進んでいくことになるので、それはとてもしんどい作業であり、一朝一夕にできるものではない。さて、ここで重要なのは、かならずフロンティアを開拓しなければならないということだ。すでに開拓されているところで、新たに開拓したとしても、それは「車輪の再発明」であり、研究にはならない。SFCカリキュラムの言葉に照らして言うと、「研究＝先端×創造」なのであり、「研究とは、先端領域で創造すること」なのだ。「研究」には「勉強」が不可欠だが、いくら「勉強」をしても「研究」にはならない。この「研究」と「勉強」の違いを意識することが、研究テーマを考える上でとても重要なのだ。&lt;/p&gt;
&lt;p&gt;この「研究」と「勉強」の違いという話は、実は、僕がまだ学部生だったころ、竹中平蔵先生が研究会でよく語っていた話だ。この話は、「研究」と「勉強」の違いを非常にクリアに言い表していると思う。そんなわけで、僕は毎年、この話を面接のときに繰り返し話す。&lt;/p&gt;
&lt;p&gt;研究会は「研究」のための場であるから、研究テーマをもった人たちの集まりだといえる。なので、研究会面接で熱く語ってほしいのは、勉強テーマではなく、研究テーマについてなのだ。荒削りでもいい。「研究」へと向かう志向性がほしい。そして、できるかできないか、という現実性よりも、何をやりたいのかというヴィジョンがほしい。&lt;/p&gt;
&lt;p&gt;以前紹介した&lt;a href=&quot;https://amzn.to/47174n8&quot;&gt;『音楽を「考える」』&lt;/a&gt;（茂木健一郎, 江村哲二, ちくまプリマー新書, 2007）のなかで、茂木さんと江村さんが、次のように語っている。まさにそのとおりだと思う。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(茂木)「若いときには自分の使える技法やツールと、胸に抱いている大志、夢見ている世界との間には明らかに大きすぎるギャップがある。それくらいアンバランスなやつじゃないと、表現者としては大成しないんだということが経験でわかりました。これはほとんど例外がない。」(p.47)&lt;/p&gt;
&lt;p&gt;(江村)「結局は、自分に何ができるかじゃなくて、何がしたいかなんです。何ができるかなんて言いはじめたら、何もできなくなっちゃう。まずはそんなことはどうでもよくて、ただただ自分は何がしたいと思っているのか、という問題に尽きます。」(p.48)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;面接で僕らが見ることに、自分の研究・活動をドライブするような内発性をもっているか、ということがある。なかなかそれを感じさせてくれる人がいないのが現状であるが。。。同僚の土屋さんは、研究テーマには「愛」か「憎しみ」がなければならない、という。研究へと自らを突き動かす「情熱」が必要なのだ。そうでなければ、しんどい研究作業など続けられるわけがない。&lt;/p&gt;
&lt;p&gt;繰り返し言うけれども、荒削りでもいいので、自分なりの研究テーマの糸口をもっていてほしい。そして、自分をドライブする内発性をもっていてほしい。それが、研究を志すみんなへの本質的なメッセージだ。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://web.sfc.keio.ac.jp/~iba/sb/sb.cgi?cid=52&quot;&gt;「研究」と「学び」について&lt;/a&gt; | - | -&lt;/p&gt;
</content:encoded></item><item><title>タブレット端末を壁掛けして情報端末として使うといろいろ捗る</title><link>https://blog.teraren.com/posts/tablet-on-the-wall/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tablet-on-the-wall/</guid><description>安価なCHUWI製Androidタブレットを壁に固定し、天気・カレンダー・赤ちゃん監視カメラの表示端末として活用。電工資格を使って壁内に電源を引き込む施工も紹介。</description><pubDate>Tue, 27 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;半年ぐらい前から、壁にタブレット端末があると便利だなと思ってました。&lt;/p&gt;
&lt;p&gt;カーナビもAndroidベースの端末をかれこれ2年以上使っていて不自由はしていません。&lt;/p&gt;
&lt;h2&gt;完成図&lt;/h2&gt;
&lt;p&gt;こんな感じ。&lt;/p&gt;
&lt;p&gt;天気を表示したりしてます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/img_3227.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;設定で常時画面をONにしています。安い端末なので、自動光量調整ができないです。MacroDroidを使って夜に暗く、朝に明るくする設定をしています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/image.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最近は、ベビーベッドの監視のためにカメラの内容をストリームしています。キッチンからベビーベッドを確認できるので楽です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/09/img_3229-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/07/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;赤外線ライト付きなので暗くても良く見えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/07/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Androidにログインするアカウントは、普段のアカウントとは別途作成しました。常時ログインしっぱなしなので。&lt;/p&gt;
&lt;p&gt;端末をゲストアカウントで運用するとなると、毎回データが消えてしまうので使いづらいと思います。&lt;/p&gt;
&lt;h2&gt;買ったもの&lt;/h2&gt;
&lt;p&gt;Androidの適当な安いやつを買いました。&lt;/p&gt;
&lt;p&gt;安すぎると動作が遅くてストレスが溜まるし、高いと使用頻度が少なくもったいないため、ちょうどよい具合のものを見つけるのに時間がかかりました。&lt;/p&gt;
&lt;p&gt;こちらの商品は、多少UIがもっさりしていますが使用頻度が少ないので我慢できます。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0CXDS73QJ&quot;}&lt;/p&gt;
&lt;p&gt;CHUWI製品は安いのにそこそこ良いクオリティなのでお気に入りです。一昔前のHuaweiという感じです。日本ではHuaweiが売られなくなったのでCHUWIは助かります。&lt;/p&gt;
&lt;h2&gt;施工&lt;/h2&gt;
&lt;p&gt;電源ケーブルが「たら〜ん」としているとカッコ悪いので壁から電源を引っ張ってきます。&lt;/p&gt;
&lt;p&gt;壁に穴を開けて、近くのコンセントから電源を引っ張ってきます。（要資格）&lt;/p&gt;
&lt;p&gt;壁の中にコンセントを取り付けて、USBアダプタを取り付け、ケーブルを出します。空いた穴には、切り取った石膏ボードを戻しておきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/07/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;タブレットの裏に少し隙間があるのでそこからケーブルを脇に持ってきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/07/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上下のホルダーは、100円均一で昔に買ってポストカードスタンドだと思います。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;施工は面倒でしたが、やってよかったです。&lt;/li&gt;
&lt;li&gt;レシピの表示、天気、カレンダーの予定の確認に重宝しています。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>寝室のライトを「とったらリモコン」に変更して快適子育て生活</title><link>https://blog.teraren.com/posts/downlight-remote-control/</link><guid isPermaLink="true">https://blog.teraren.com/posts/downlight-remote-control/</guid><description>寝室のライトを「とったらリモコン」に変更して快適子育て生活</description><pubDate>Thu, 15 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;リビングの調光スイッチを「とったらリモコン」に変更しました。&lt;/li&gt;
&lt;li&gt;乳児の子育て部屋には最適。もっと早くやっておけばよかった。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B07T844JQ6&quot;}&lt;/p&gt;
&lt;h2&gt;施工後の写真&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/08/IMG_2521.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;施工時間はスイッチパネルの入れ替えだけなので5分で終わりました。（要国家資格）&lt;/p&gt;
&lt;h2&gt;良い点、悪い点&lt;/h2&gt;
&lt;h3&gt;良い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;床に布団を敷いて生活しているのでライトをコントロールするのに立ち上がるのが大変だったが、リモコンでオンオフ、調光ができると非常に楽になった。&lt;/li&gt;
&lt;li&gt;壁のスイッチ側でも、クリックでオンオフ、長押しで調光ができるので楽。&lt;/li&gt;
&lt;li&gt;オンオフのときに、フワっと付いたり消えたりするので目に優しい。これは地味に重要。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;悪い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;お値段がちょっと高めの7,800円。ですが、基本的に壊れるものではないし、他の部屋に移設できるので1つは持っておいても良い気がします。&lt;/li&gt;
&lt;li&gt;明るさの調整が上げるか下げるかなので、今の明るさがどのへんなのかがわからない。何かしらのフィードバックが欲しいけど、無いので最大限明るくなっているのか暗くなっているのかがわからない。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>生成系AIサービスから自分のサイトをブロックする方法</title><link>https://blog.teraren.com/posts/block-llm-crawler/</link><guid isPermaLink="true">https://blog.teraren.com/posts/block-llm-crawler/</guid><description>生成系AIサービスから自分のサイトをブロックする方法</description><pubDate>Fri, 02 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;サイトのトップに以下のrobots.txtを設置または、コピペします。&lt;/p&gt;
&lt;p&gt;https://gist.github.com/matsubo/1b4e362ac5a30302b324b008de703487&lt;/p&gt;
&lt;p&gt;生成AI系サービスのuser agent名は以下から検索できます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://darkvisitors.com/agents&quot;&gt;https://darkvisitors.com/agents&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Dark Visitorを導入してみた&lt;/h2&gt;
&lt;p&gt;このBlogにDark Visitorのプラグインを導入してみてクロールしに来たBotを計測してみました。&lt;/p&gt;
&lt;p&gt;無料だと10,000イベントちょっと計測できないようです。導入して4日で使い切ったようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/08/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;その際のサマリーを軽く載せておきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/08/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>短縮URLサービスの利用を再考する：Bitlyの変更を機に探る最適な選択肢</title><link>https://blog.teraren.com/posts/stop-using-url-shortener-services/</link><guid isPermaLink="true">https://blog.teraren.com/posts/stop-using-url-shortener-services/</guid><description>Bitlyの無料プラン大幅縮小を受け、SMS送信コスト削減に使っていた短縮URLサービスの代替を調査し、自前実装も含めた移行先を検討した記録</description><pubDate>Fri, 02 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;bitlyのサービス内容が変更され、無料だと&lt;a href=&quot;https://bitly.com/pages/pricing&quot;&gt;月に10個&lt;/a&gt;しか作れなくなりました。それに伴い、課金して使うか検討したときの資料をまとめておきます。&lt;/p&gt;
&lt;p&gt;そもそも短縮URLを取り巻く環境はどうなっているのか調査して、対処方法を意思決定しました。&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;運用している複数のプロダクトでBitlyを使って短縮URLを生成していました。&lt;/p&gt;
&lt;p&gt;短縮URLを生成する目的は、SMSで自社のURLを送信する際に文字数制限があったりSMSのメッセージが分割されるのを可能な限り防ぎ、送信のコストを削減する目的で導入していました。&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;URLを短縮するだけにあまりコストを払いたくないです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://news.yahoo.co.jp/articles/3c1bf307b2a8fe0031af5ffea785f2b189ee4ea7#:~:text=%E7%B1%B3%E3%83%BB%E3%82%B0%E3%83%BC%E3%82%B0%E3%83%AB%E3%81%AF18%E6%97%A5,%E5%85%A8%E3%81%A6%E7%84%A1%E5%8A%B9%E3%81%AB%E3%81%AA%E3%82%8B%E8%A6%8B%E8%BE%BC%E3%81%BF%E3%80%82&quot;&gt;Googleが短縮URLサービスを停止&lt;/a&gt;したりしているので短縮URLは必要性が低くなってきているような雰囲気を感じます。&lt;/p&gt;
&lt;h2&gt;サーベイ&lt;/h2&gt;
&lt;p&gt;biltly以外の短縮URLサービスに乗り換えようと考えて、類似サービスを探していたのですが意外と欲しいサービスが見当たりませんでした。短縮URLサービスに求めることが意外と多いのです。&lt;/p&gt;
&lt;h3&gt;短縮URLサービスに求めることまとめ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;運営元がしっかりしていること。（広告を挟んだりされてしまうリスクがあるため）&lt;/li&gt;
&lt;li&gt;長期的に運用されそうなこと、長期的に運用してきていること。（途中で止まるとリンク切れになるため）&lt;/li&gt;
&lt;li&gt;ドメイン名が短いこと。&lt;/li&gt;
&lt;li&gt;短縮URLサービス名が広く認知されていること。（ユーザにとって見れば、自分が使っているサービスとは違うドメインのURLが掲載されているので）&lt;/li&gt;
&lt;li&gt;APIでURLを発行できること。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上記を満たすようなサービスはすごい少ないです。しかも、ドメイン名が短いと結構怪しい感じが出ちゃうのでサービス名が広く知られていることは重要だったりします。&lt;/p&gt;
&lt;p&gt;上記の要件を満たす候補は、tinyurl, Ow.lyぐらいしか無いです。&lt;/p&gt;
&lt;h3&gt;短縮URLサービスのリスク&lt;/h3&gt;
&lt;p&gt;もし短縮URLサービスに秘密のリンクを掲載して認証無しに設定したら短縮URLサービス側に悪意があったらその情報にアクセスできてしまいます。&lt;/p&gt;
&lt;p&gt;また、細かいことを言えばユーザにとって見れば、利用規約を踏んでいないのに他社のサービスを利用することになってしまいます。&lt;/p&gt;
&lt;p&gt;自社のプロダクト内で短縮URLサービスの生成に失敗してしまった場合に、エラーハンドリングを適切に行なっていなければ処理が落ちてしまって後続のSMS送信などが失敗するリスクがあります。コードレビューをしっかりする必要があります。&lt;/p&gt;
&lt;h3&gt;短縮URLサービスを使うメリット&lt;/h3&gt;
&lt;p&gt;そもそも短縮URLを使うメリットを考えてみます。主に以下の2点かなと思います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;トラッキングコードを入れてもURLが長くならない。&lt;/li&gt;
&lt;li&gt;SMSの送信コストを抑えられる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;上記を踏まえて、自社のプロダクトでどうするかのオプションを考えてみます。&lt;/p&gt;
&lt;h3&gt;bitlyを使い続ける&lt;/h3&gt;
&lt;p&gt;$8/monthを課金するだけで済むので1番楽です。コードを変更する必要もないです。　bit.lyというドメインの認知度はインターネットに慣れている人であれば高いですが、一般の人にとっては怪しく見えてしまうかもしれません。&lt;/p&gt;
&lt;h3&gt;自プロダクト内で実装する&lt;/h3&gt;
&lt;p&gt;ドメイン名がそこそこ短い場合は自社で実装してしまうのが良いかと思います。自社サービスと連動していればユーザに取ってみても認知されているドメイン名です。&lt;/p&gt;
&lt;p&gt;構築するのもそんなに手間ではないと思います。短縮URLは1度作成したら基本的には消せないのでデータ容量は気にする必要があります。&lt;/p&gt;
&lt;h3&gt;短縮URLを使わない&lt;/h3&gt;
&lt;p&gt;最近、SMSは&lt;a href=&quot;https://www.accrete-inc.com/useful_information/20220524/#:~:text=%E4%BB%A5%E5%89%8D%E3%81%AF70%E6%96%87%E5%AD%97%E3%81%BE%E3%81%A7,%E3%82%92%E3%82%84%E3%82%8A%E3%81%A8%E3%82%8A%E3%81%A7%E3%81%8D%E3%82%8B%E3%81%A7%E3%81%97%E3%82%87%E3%81%86%E3%80%82&quot;&gt;全角670文字&lt;/a&gt;ぐらいは送れるそうなので短縮URLサービスを使わないというのもオプションになります。&lt;/p&gt;
&lt;p&gt;短縮URLを使うより文字数が多くなってしまうのでSMS送信コストは増える可能性が高いです。&lt;/p&gt;
&lt;h2&gt;理想を考える&lt;/h2&gt;
&lt;p&gt;転送URLを使わないことが一番です。&lt;/p&gt;
&lt;p&gt;その次は、自プロダクトで短縮URL機能を作ること。&lt;/p&gt;
&lt;p&gt;最後に、社外の短縮URLSaaSを使うこと&lt;/p&gt;
&lt;p&gt;と考えます。&lt;/p&gt;
&lt;h2&gt;短縮URLサービスを使うことをやめてみて&lt;/h2&gt;
&lt;p&gt;手元のサービスで、短縮URLをつかなくなったことで1通あたり8円程度のSMSで送信コストがアップしてしまいました。&lt;/p&gt;
&lt;p&gt;140通/月以上送る場合は短縮URLを使ったほうが安いことになります。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;短縮URLを使うメリット・デメリットをまとめました。&lt;/p&gt;
&lt;p&gt;プロダクトの状況をや達成したい目標にあったアプローチを選定する必要があります。&lt;/p&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;2024/8/13&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dub.co/&quot;&gt;https://dub.co/&lt;/a&gt; というサービスを教えてもらいました。ゼロイチで開発するならばこのサービスが一番良いです。&lt;/p&gt;
&lt;p&gt;https://dub.co&lt;/p&gt;
&lt;p&gt;短縮URLのニーズは現在でも一定数はありそうです。手元のサービスにおいて短縮URLを使わないでSMSを配信したらコストが1.5倍になりました。SMSにURLを掲載する場合は短縮URLに課金したほうがトータルコストが安くなるケースが多そうです。&lt;/p&gt;
</content:encoded></item><item><title>Difyをローカルで動かしてみる。3分でコピペで可能。</title><link>https://blog.teraren.com/posts/dify-docker-compose/</link><guid isPermaLink="true">https://blog.teraren.com/posts/dify-docker-compose/</guid><description>LLM を使ったワークフローを作成するのに、</description><pubDate>Thu, 01 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;LLM を使ったワークフローを作成するのに、
Dify が良さそうなのでローカルで立ち上げて使ってみます。&lt;/p&gt;
&lt;p&gt;docker-compose.yml が用意されているので基本的には以下のページを参考にすればすんなり動きます。
https://docs.dify.ai/getting-started/install-self-hosted/docker-compose&lt;/p&gt;
&lt;h2&gt;Difyをローカルで動かす利点&lt;/h2&gt;
&lt;p&gt;主に以下の点があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アカウント登録不要で、無料で SaaS 版と同じ機能が使える。&lt;/li&gt;
&lt;li&gt;SaaS 版より動作が速い。&lt;/li&gt;
&lt;li&gt;テストで重要なデータを登録してみたりすると思いますが、ローカルでしか扱わないので自社のセキュリティポリシー内で運用し易い。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;手順&lt;/h2&gt;
&lt;p&gt;前提として、&lt;code&gt;git&lt;/code&gt; コマンドがインストールされていて、&lt;code&gt;Docker&lt;/code&gt; と &lt;code&gt;docker compose&lt;/code&gt; が利用できる状態が必要です。&lt;/p&gt;
&lt;p&gt;Dify のリポジトリを Clone します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/langgenius/dify.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;設定テンプレをコピーします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd dify/docker
cp .env.example .env
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;サービスを起動します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ブラウザで開きます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;open &apos;http://localhost/&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;起動直後の CPU 使用率、メモリ使用量はこのぐらいです。
&lt;img src=&quot;../../assets/uploads/2024/08/2024-07-21-16-38-00.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Dify の動作が不安定だったり、非同期で色々裏で動いているのが log やリソースモニタを表示しているとわかりやすいです。&lt;/p&gt;
&lt;p&gt;例えば、500MB のファイルをナレッジとして登録したときにブラウザ上では応答がなくなっちゃったりしますが裏では gunicorn と celery プロセスが CPU のコアを食い尽くしたりしているのがわかったりします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/08/2024-07-21-17-12-40.png&quot; alt=&quot;&quot; /&gt;
image は 3GB 分ぐらい使ってます。&lt;/p&gt;
&lt;h2&gt;UI上でセットアップ&lt;/h2&gt;
&lt;p&gt;アカウントを作成していきます。
&lt;img src=&quot;../../assets/uploads/2024/08/2024-07-21-12-46-02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;管理者カウントを作成します。言語設定を日本語にします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/08/2024-07-21-12-46-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こんな感じで初期設定を終えられます。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SaaS 版だと動作が不安定な時にトラブルシュートがし辛いですがローカルだと裏のプロセスがどの用に動いているかわかりやすいです。&lt;/li&gt;
&lt;li&gt;ローカルだと無料で動かせます。手軽に LLM アプリケーションを Cloudflare などを使ってトンネルしちゃえば作ってすぐに公開できます。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Postmanに法人番号検索REST APIを登録して世界へ公開！</title><link>https://blog.teraren.com/posts/postman-postcode-api/</link><guid isPermaLink="true">https://blog.teraren.com/posts/postman-postcode-api/</guid><description>業務で Web アプリケーションを作成しているときに、「こんな Web API があったら楽なのに」と思うことがあり、なければ作ってしまえば良いと思い、個人的に無料で簡単に利用できる REST API によるデータ公開しています。</description><pubDate>Mon, 08 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3行まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;この記事は &lt;a href=&quot;https://qiita.com/advent-calendar/2023/postman&quot;&gt;Postman Advent Calendar 2023&lt;/a&gt;のシリーズ2、17日目の記事です。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.postman.com/&quot;&gt;Postman&lt;/a&gt;にアカウント登録して既存のREST API 仕様を登録し、Flow、Test、Visualization を使ってみました。&lt;/li&gt;
&lt;li&gt;昔は無料でできることが少なかったのですが今は無料で色々できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;業務で Web アプリケーションを作成しているときに、「こんな Web API があったら楽なのに」と思うことがあり、なければ作ってしまえば良いと思い、個人的に無料で簡単に利用できる REST API によるデータ公開しています。&lt;/p&gt;
&lt;p&gt;例えば住所の自動補完に使う郵便番号 API、インボイス登録番号に関連した法人番号検索 API などです。&lt;/p&gt;
&lt;p&gt;今回は法人番号検索 API を扱います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/7f60c097-1aad-9ae6-7c2c-f019cfa97023.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;API は OpenAPI の仕様で公開しています。
https://corporation.teraren.com/openapi/corporation.teraren.com.yml&lt;/p&gt;
&lt;p&gt;その API 仕様を &lt;a href=&quot;https://github.com/Redocly/redoc&quot;&gt;redoc&lt;/a&gt;というJavaScriptライブラリを用いて見やすく表示しています。
https://corporation.teraren.com/doc/redoc&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;これらのサービス自体はなかなか認知されないです。
そして、開発者がテストで軽く使ってみようとしても CLI からじゃないとテストできなかったり、swagger editor に OpenAPI のファイルを読み込ませてからリクエストを出すと言ったことをしないといけないので利用までの敷居が高いです。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;Postman は世界的に広く使われている API 仕様を公開するサービスです。Postman を通じて開発者に広く知ってもらったり、開発者が使いやすい API の状態を作っていきたいと思います。&lt;/p&gt;
&lt;p&gt;redoc 仕様公開はいわばドキュメントの公開です。Postman は仕様の公開と実行環境の提供です。&lt;/p&gt;
&lt;h3&gt;Postmanとは&lt;/h3&gt;
&lt;p&gt;Postman は API 開発のための強力な SaaS プラットフォームです。&lt;/p&gt;
&lt;p&gt;API リクエストの作成、テスト、ドキュメント化、共有を容易にするツールを提供します。Postman は、REST、SOAP、GraphQL などの様々な API タイプに対応し、開発者が API のエンドポイントを簡単に検証できるようにします。&lt;/p&gt;
&lt;p&gt;また、環境変数の管理、テストスクリプトの作成、API レスポンスのモニタリングなどの機能も備えており、チームでの協業をサポートするためのチームワークスペースも提供しています。&lt;/p&gt;
&lt;p&gt;具体例でいうと、&lt;a href=&quot;https://www.postman.com/lunar-resonance-715260/workspace/switchbot-api-ws/collection/29245185-7f66f632-8299-4a90-8a2a-dcf845e146e0&quot;&gt;SwitchBotがPostmanでAPIを公開しています&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;https://www.postman.com/&lt;/p&gt;
&lt;h2&gt;PostmanにAPIを登録して設定&lt;/h2&gt;
&lt;p&gt;ユーザ登録をした上で、API を登録する準備を進めていく手順を紹介します。&lt;/p&gt;
&lt;h3&gt;初期化&lt;/h3&gt;
&lt;p&gt;API を登録するためにはワークスペースを作る必要があります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/5e15fdde-be4c-3fb2-8590-770efe846698.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;API 仕様はパブリックなので public を選びます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/eeac45af-9953-a45a-9652-e77da85ff341.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;public にする場合は、自分のプロフィールに公開用の情報を追加する必要があるのでダイアログに出たとおりに設定して OK を押します。&lt;/p&gt;
&lt;p&gt;ちなみにこちらが私のプロフィールページになります。
https://www.postman.com/matsubokkuri&lt;/p&gt;
&lt;p&gt;OpenAPI のファイルをインポートできる機能があったので早速 import してみます。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/615640b8-d453-246b-b333-7bce1f134f41.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;OpenAPIファイルをインポート&lt;/h3&gt;
&lt;p&gt;どうやってインポートをするか聞かれましたが、デフォルトで進んでみます。&lt;/p&gt;
&lt;p&gt;追記: 上の &lt;code&gt;Postman Collection&lt;/code&gt; は Postman での標準となる API 仕様のフォーマットです。下の、&lt;code&gt;OpenAPI 3.0 witha  Postman Collection&lt;/code&gt; は OpenAPI 3.0 との互換性を保った上での API 表現と、Postman 独自の Collection の両方に追加されます。今回は、Postman 専用に不可逆なファイルコンバートとして割り切ります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/0e774cb1-9768-70da-abe5-002c7294bc5a.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;インポートが完了すると左側のメニューに階層化されて表示されました。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/3ba5e040-2d5a-b0b1-a628-c649c2aa264e.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;しかしながら、階層が多いように感じたので適切なコレクションを作成して、エンドポイントを適切なコレクションに入れ直しました。ドラッグ&amp;amp;ドロップで移動できるので楽です。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/ac611ac7-5adf-c98b-e61b-950acef95379.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;エンドポイントの名前が見づらかったので少し修正しました。これで API を使う開発者にとってもかなり見やすくなったと思います。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/2714581d-b688-7c6f-a629-72966864a4cb.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;機能を使ってみる&lt;/h3&gt;
&lt;p&gt;早速テストで法人番号の一覧を表示する API を呼び出してみます。下のペインに結果が整形されて表示されました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/3ffbef07-50cc-7707-05ab-74c9ddf6b67b.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Visualization のタブを選ぶと上の JSON の結果がテーブルに勝手に整形されて表示されました。見やすいです。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/4dc75dfb-c389-778a-50ef-0977b67552a0.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;グラフ化できるような値の場合はグラフとして表示できるようです。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/32076222-572b-ec07-137d-625dbf806bd3.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;仮に line chart で描画してみました。メトリックや集計はできなさそうです。自動で選ばれたメトリックが X と Y に設定されました。自動で作成できるのは楽です。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/a00e3ddc-56ca-e071-fbe1-721e88ef4a79.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一覧の取得はパラメータを一切必要としませんでしたが、今度は 1 つの法人の情報を取得してみます。
変数となる部分は、collection のスコープで定義されているようです。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/e7075f73-aba8-a9c9-f3d6-597c3763b83b.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;左のメニューの一番上のコレクションを選択したら変数の一覧とデフォルト値が表示されました。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/f0b6bb48-9528-61d6-bde6-9c7bbaa628ff.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;有効な値に変更していきつつ、サーバの URL といった環境依存の変数は Environment に移します。
完成した設定がこちらです。コレクションスコープ。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/4fb69361-a02b-538b-87c8-40b3dcaa79be.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こちらは環境スコープです。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/9de70558-b33b-79e3-45e5-6782cf0f7229.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h5&gt;注意点&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;右上に「Save」ボタンがあるので毎回押し忘れないように気をつけましょう。&lt;/li&gt;
&lt;li&gt;Current Value のカラムにある値が使われるのでこちらも合わせて正しい値を設定しておきましょう。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということで、法人の情報を 1 件取得してみます。結果が下のペインに表示されました。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/06096511-d028-ec8e-025b-680fc549dfef.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;同様に、他のエンドポイントに対しても適切にパラメータや変数を設定していき、呼び出しができることを確認します。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/a141e499-0e41-4948-2deb-717a6d9cadad.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;APIの自動テスト&lt;/h3&gt;
&lt;p&gt;API が正常に動作しているか、適切なスキーマで返却されているかをテストできる機能があります。
テストの内容は、コレクション単位、エンドポイント単位で設定できます。&lt;/p&gt;
&lt;p&gt;以下の例は、コレクション単位で設定できるテストの部分に書いてあります。
単純に 200 番が返ってくるかどうかをテストするような汎用的な内容です。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/cb90ad3f-1438-fac3-366e-baf2bb7978d9.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上記を実行すると以下のようになります。各エンドポイントの呼び出しに対して評価されます。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/fd22230e-7075-0e7e-afa8-a4b8a5e53ad7.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;今度は、個別のエンドポイントでテストを書いてみます。
簡易的に、配列で値が返ってくるかを書いてみます。保存して、下のリフレッシュボタンを押すとテストを実行できます。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/6e973fe8-d2bb-7097-b500-ea4da12c4ba7.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;テスト内容は GPT に問い合わせることで半自動に作成でるので楽です。
しかしながら、デバッグ方法がちょっとわかりませんでした。console に出力してもその内容がどこに出るの発見できませんでした。&lt;/p&gt;
&lt;p&gt;今度は、コレクションの方に戻って定期的に自動テストを実行するように設定しておきます。これによって、API が仕様通りに動いているかを Postman を見るだけでひと目でわかるようになります。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/aa933ef3-0f5c-9ac8-4801-84aff53e1b8f.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;このあたりは OpenAPI のスキーマを自動的に読み込んで、自動的にテストを書いてほしいものです。&lt;/p&gt;
&lt;h3&gt;monitorの設定&lt;/h3&gt;
&lt;p&gt;外部監視が設定できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/b7fa3f12-2d8a-0243-9b7e-45037986bd42.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;定期的にテストを実行して死活監視してくれるようです。
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/b2f86350-125f-8b27-a70e-eb1ec675196c.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Flowの作成&lt;/h3&gt;
&lt;p&gt;Postman 上で API や計算処理をしてワークフローを構築できるサービスです。&lt;/p&gt;
&lt;p&gt;法事番号検索 API では、各都道府県ごとの法人数を返却するエンドポイントがあるのでシンプルですがグラフ化してみます。&lt;/p&gt;
&lt;p&gt;ものの 2 分でグラフが構築できました。簡易的なダッシュボードとしても使えそうです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/9b8d8707-c2a9-e6c1-2d2b-8c71173c3807.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;プロフィールの整備&lt;/h3&gt;
&lt;p&gt;最後にプロフィールを入力しておきます。
デフォルトのアイコンが何を意味しているのかよくわからないので写真も設定しておきました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/5af7b1d1-cd5a-cdb5-915f-7229c426c460.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こんな感じで表示されました。かっこ良いです！
&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/fd6f7a89-f5dc-bdfd-b815-3fede37cd48f.png&quot; alt=&quot;image.png&quot; /&gt;
https://www.postman.com/matsubokkuri&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;h3&gt;API仕様の提供方法&lt;/h3&gt;
&lt;p&gt;今まで使っていた Open API と Postman は同じレイヤのプロダクトなのでどちらをメインにして運用するかは考えどころです。→追記:GitHub 上の OpenAPI ファイルと Postman 上の仕様を同期できる機能があります。&lt;/p&gt;
&lt;p&gt;Open API で書いておけば &lt;a href=&quot;https://github.com/interagent/committee&quot;&gt;committee&lt;/a&gt;といったライブラリで自動的にリクエストとレスポンスのテストを行ってくれるのでこれはかなり重宝します。→追記:Postmanでも型をチェックしてくれます。しかし、エラーメッセージが抽象的で分かりづらいです。&lt;/p&gt;
&lt;p&gt;また、Open API はその名の通りオープンな仕様なので色々なツールで読み書きやクライアントライブラリの自動生成が可能です。&lt;/p&gt;
&lt;p&gt;Open API と相互運用できたら最高だなと思いました。→追記：相互運用できますが、Postman Enterprise Ultimate plan が必要です。&lt;/p&gt;
&lt;h3&gt;みやすさ&lt;/h3&gt;
&lt;p&gt;ユーザ（開発者）に取ってみれば Postman で API が提供されている方が楽にテストできるので便益性が高いです。
Open API のビューアは貧弱なので辛いです。玄人向けという感じです。&lt;/p&gt;
&lt;h3&gt;日本語対応&lt;/h3&gt;
&lt;p&gt;ワークスペース名に日本語を使うといくつかの機能において意味不明なエラーが出て使えなくなることがありました。
今回のテストは Workspace 名に日本語を使っていますがアルファベットだけにしておきましょう。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Postman の UI はかなり優れているしテストも GUI 上で書けるので便利です。&lt;/li&gt;
&lt;li&gt;Postman と OpenAPI との棲み分けがまだ整理できていないような感じがしました（理解が浅いだけかもしれません）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;Postman の思想がかなり自分の思い描く API のプラットフォームの価値観と一致したので、私が提供している郵便番号検索 API、銀行コード検索 API、駅・路線情報検索 API の仕様を Postman へ追加しました！&lt;/p&gt;
&lt;p&gt;Snowflake のようなプラットフォームの API 版という感じがしていてなかなか良さそうです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11793/f6ff575d-d005-e43c-f958-8afedef100ec.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>学校検索をもっと簡単に！REST APIサービスを公開</title><link>https://blog.teraren.com/posts/school-rest-api/</link><guid isPermaLink="true">https://blog.teraren.com/posts/school-rest-api/</guid><description>こんにちは、スタートアップの CTO をしている まつぼっくりです。今回は、私が開発した日本の学校情報APIについて紹介します。</description><pubDate>Mon, 08 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;こんにちは、スタートアップの CTO をしている &lt;a href=&quot;https://zenn.dev/matsubokkuri&quot;&gt;まつぼっくり&lt;/a&gt;です。今回は、私が開発した&lt;a href=&quot;https://school.teraren.com/&quot;&gt;日本の学校情報API&lt;/a&gt;について紹介します。&lt;/p&gt;
&lt;h2&gt;日本の学校情報APIとは？&lt;/h2&gt;
&lt;p&gt;日本の学校情報 API は、日本全国の小学校、中学校、高等学校の情報を簡単に検索・取得できる API サービスです。学校名、住所などの基本情報を提供しています。&lt;/p&gt;
&lt;p&gt;https://school.teraren.com/&lt;/p&gt;
&lt;h2&gt;なぜこのAPIを作ったのか&lt;/h2&gt;
&lt;p&gt;スタートアップの CTO として、様々なプロジェクトに携わる中で、学校情報を扱う機会が何度かありました。
その度に感じたのが、信頼できる学校データの取得の難しさです。&lt;/p&gt;
&lt;p&gt;「もっと簡単に学校情報を取得できないだろうか？」
「他の開発者も同じような悩みを抱えているのでは？」&lt;/p&gt;
&lt;p&gt;そんな思いから、日本の学校情報 API の開発がスタートしました。&lt;/p&gt;
&lt;h2&gt;APIの特徴&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;豊富なデータ&lt;/strong&gt;: 全国約 37,000 校の情報を網羅&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;簡単な利用&lt;/strong&gt;: RESTful API で、簡単にデータにアクセス可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;柔軟な検索&lt;/strong&gt;: 学校名、住所、電話番号など様々な条件で検索可能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;個人・商用利用無料&lt;/strong&gt;: 商用、非商用利用が可能です。アクセス数の制限はありません。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;開発で苦労したポイント&lt;/h2&gt;
&lt;h3&gt;1. データの収集と整理&lt;/h3&gt;
&lt;p&gt;信頼性の高いデータを提供するため、複数のソースから情報を収集し、クレンジングする必要がありました。この過程で、データの不整合や欠損に悩まされましたが、機械学習を活用した自動クレンジングシステムを構築することで、効率的にデータの質を向上させることができました。&lt;/p&gt;
&lt;h3&gt;2. APIのパフォーマンス最適化&lt;/h3&gt;
&lt;p&gt;大量のデータを高速に検索・提供するため、データベースの最適化に注力しました。インデックスの適切な設計や、キャッシュ戦略の実装により、応答速度を大幅に改善できました。&lt;/p&gt;
&lt;h3&gt;3. ユーザーフレンドリーなドキュメント&lt;/h3&gt;
&lt;p&gt;API の使いやすさは、ドキュメントの質に大きく依存します。開発者目線でのわかりやすさと、ビジネス利用者向けの説明のバランスを取るのに苦心しました。結果として、&lt;a href=&quot;https://school.teraren.com/doc&quot;&gt;API仕様書&lt;/a&gt;はとてもクリアで使いやすいものになったと自負しています。&lt;/p&gt;
&lt;h2&gt;API使用例&lt;/h2&gt;
&lt;h3&gt;学校情報をCSVで取得&lt;/h3&gt;
&lt;p&gt;REST API でありながら、CSV ファイルでの出力にも対応しています。&lt;/p&gt;
&lt;p&gt;日本全国の教育機関を全件取得&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl -s https://school.teraren.com/schools.csv | nkf -w | head -n 5
学校コード,学校種,都道府県番号,設置区分,本分校,学校名,学校所在地,郵便番号,属性情報設定年月日,属性情報廃止年月日,旧学校調査番号,移行後の学校コード
A101110000012,A1,01,1,1,北海道教育大学附属函館幼稚園,北海道函館市美原３丁目４８番６号,0410806,2020-12-22,,016501,
A101110000021,A1,01,1,1,北海道教育大学附属旭川幼稚園,北海道旭川市春光５条２丁目１番１号,0700875,2020-12-22,,016502,
A101210000010,A1,01,2,1,札幌市立手稲中央幼稚園,北海道札幌市手稲区手稲本町２条５丁目１３番１号,0060022,2020-12-22,,016511,
A101210110017,A1,01,2,1,札幌市立中央幼稚園,北海道札幌市中央区北２条西１１丁目,0600002,2020-12-22,,017527,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;東京都の高等学校を全件取得&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl -s https://school.teraren.com/prefectures/13/standard_areas/13000/school_types/D1.csv | nkf -w | head -n 5
学校コード,学校種,都道府県番号,設置区分,本分校,学校名,学校所在地,郵便番号,属性情報設定年月日,属性情報廃止年月日,旧学校調査番号,移行後の学校コード
D113110000012,D1,13,1,1,東京学芸大学附属高等学校,東京都世田谷区下馬４−１−５,1540002,2020-12-22,,135502,
D113110000021,D1,13,1,1,筑波大学附属高等学校,東京都文京区大塚１−９−１,1120012,2020-12-22,,135503,
D113110000030,D1,13,1,1,筑波大学附属駒場高等学校,東京都世田谷区池尻４−７−１,1540001,2020-12-22,,135504,
D113110000049,D1,13,1,1,東京工業大学附属科学技術高等学校,東京都港区芝浦３−３−６,1080023,2020-12-22,,135505,
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;教育機関個別の詳細を取得&lt;/h3&gt;
&lt;p&gt;東京大学の詳細を取得&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl -s https://school.teraren.com/schools/F113110102700.json | jq
{
  &quot;code&quot;: &quot;F113110102700&quot;,
  &quot;school_type&quot;: &quot;F1&quot;,
  &quot;prefecture_number&quot;: &quot;13&quot;,
  &quot;establishment_category&quot;: 1,
  &quot;main_branch_indicator&quot;: 1,
  &quot;name&quot;: &quot;東京大学&quot;,
  &quot;location&quot;: &quot;東京都文京区本郷７−３−１&quot;,
  &quot;postal_code&quot;: &quot;1130033&quot;,
  &quot;attribute_info_setup_date&quot;: &quot;2021-01-20&quot;,
  &quot;attribute_info_cancellation_date&quot;: null,
  &quot;old_school_survey_number&quot;: &quot;0172&quot;,
  &quot;post_transition_school_code&quot;: null,
  &quot;created_at&quot;: &quot;2024-06-02T02:45:53.123+09:00&quot;,
  &quot;updated_at&quot;: &quot;2024-06-02T02:45:53.123+09:00&quot;,
  &quot;url&quot;: &quot;https://school.teraren.com/schools/F113110102700.json&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;テキスト検索&lt;/h3&gt;
&lt;p&gt;「慶應」を含む教育機関を取得&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl -s &apos;https://school.teraren.com/schools.json?s=%E6%85%B6%E6%87%89&amp;amp;commit=%E6%A4%9C%E7%B4%A2&apos; | jq
[
  {
    &quot;code&quot;: &quot;D111322800026&quot;,
    &quot;school_type&quot;: &quot;D1&quot;,
    &quot;prefecture_number&quot;: &quot;11&quot;,
    &quot;establishment_category&quot;: 3,
    &quot;main_branch_indicator&quot;: 1,
    &quot;name&quot;: &quot;慶應義塾志木高等学校&quot;,
    &quot;location&quot;: &quot;埼玉県志木市本町４−１４−１&quot;,
    &quot;postal_code&quot;: &quot;3530004&quot;,
    &quot;attribute_info_setup_date&quot;: &quot;2020-12-22&quot;,
    &quot;attribute_info_cancellation_date&quot;: null,
    &quot;old_school_survey_number&quot;: &quot;116006&quot;,
    &quot;post_transition_school_code&quot;: null,
    &quot;created_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/schools/D111322800026.json&quot;
  },
  {
    &quot;code&quot;: &quot;B113311300026&quot;,
    &quot;school_type&quot;: &quot;B1&quot;,
    &quot;prefecture_number&quot;: &quot;13&quot;,
    &quot;establishment_category&quot;: 3,
    &quot;main_branch_indicator&quot;: 1,
    &quot;name&quot;: &quot;慶應義塾幼稚舎&quot;,
    &quot;location&quot;: &quot;東京都渋谷区恵比寿２−３５−１&quot;,
    &quot;postal_code&quot;: &quot;1500013&quot;,
    &quot;attribute_info_setup_date&quot;: &quot;2020-12-22&quot;,
    &quot;attribute_info_cancellation_date&quot;: null,
    &quot;old_school_survey_number&quot;: &quot;132048&quot;,
    &quot;post_transition_school_code&quot;: null,
    &quot;created_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/schools/B113311300026.json&quot;
  },
  {
    &quot;code&quot;: &quot;C113310300026&quot;,
    &quot;school_type&quot;: &quot;C1&quot;,
    &quot;prefecture_number&quot;: &quot;13&quot;,
    &quot;establishment_category&quot;: 3,
    &quot;main_branch_indicator&quot;: 1,
    &quot;name&quot;: &quot;慶應義塾中等部&quot;,
    &quot;location&quot;: &quot;東京都港区三田２−１７−１０&quot;,
    &quot;postal_code&quot;: &quot;1080073&quot;,
    &quot;attribute_info_setup_date&quot;: &quot;2020-12-22&quot;,
    &quot;attribute_info_cancellation_date&quot;: null,
    &quot;old_school_survey_number&quot;: &quot;134532&quot;,
    &quot;post_transition_school_code&quot;: null,
    &quot;created_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/schools/C113310300026.json&quot;
  },
  {
    &quot;code&quot;: &quot;D113310300024&quot;,
    &quot;school_type&quot;: &quot;D1&quot;,
    &quot;prefecture_number&quot;: &quot;13&quot;,
    &quot;establishment_category&quot;: 3,
    &quot;main_branch_indicator&quot;: 1,
    &quot;name&quot;: &quot;慶應義塾女子高等学校&quot;,
    &quot;location&quot;: &quot;東京都港区三田２−１７−２３&quot;,
    &quot;postal_code&quot;: &quot;1080073&quot;,
    &quot;attribute_info_setup_date&quot;: &quot;2020-12-22&quot;,
    &quot;attribute_info_cancellation_date&quot;: null,
    &quot;old_school_survey_number&quot;: &quot;135986&quot;,
    &quot;post_transition_school_code&quot;: null,
    &quot;created_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/schools/D113310300024.json&quot;
  },
  {
    &quot;code&quot;: &quot;B114310000119&quot;,
    &quot;school_type&quot;: &quot;B1&quot;,
    &quot;prefecture_number&quot;: &quot;14&quot;,
    &quot;establishment_category&quot;: 3,
    &quot;main_branch_indicator&quot;: 1,
    &quot;name&quot;: &quot;慶應義塾横浜初等部&quot;,
    &quot;location&quot;: &quot;神奈川県横浜市青葉区あざみ野南３−１−３&quot;,
    &quot;postal_code&quot;: &quot;2250012&quot;,
    &quot;attribute_info_setup_date&quot;: &quot;2020-12-22&quot;,
    &quot;attribute_info_cancellation_date&quot;: null,
    &quot;old_school_survey_number&quot;: &quot;140448&quot;,
    &quot;post_transition_school_code&quot;: null,
    &quot;created_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/schools/B114310000119.json&quot;
  },
  {
    &quot;code&quot;: &quot;C114310000199&quot;,
    &quot;school_type&quot;: &quot;C1&quot;,
    &quot;prefecture_number&quot;: &quot;14&quot;,
    &quot;establishment_category&quot;: 3,
    &quot;main_branch_indicator&quot;: 1,
    &quot;name&quot;: &quot;慶應義塾普通部&quot;,
    &quot;location&quot;: &quot;神奈川県横浜市港北区日吉本町１−４５−１&quot;,
    &quot;postal_code&quot;: &quot;2230062&quot;,
    &quot;attribute_info_setup_date&quot;: &quot;2020-12-22&quot;,
    &quot;attribute_info_cancellation_date&quot;: null,
    &quot;old_school_survey_number&quot;: &quot;143842&quot;,
    &quot;post_transition_school_code&quot;: null,
    &quot;created_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/schools/C114310000199.json&quot;
  },
  {
    &quot;code&quot;: &quot;C114320500040&quot;,
    &quot;school_type&quot;: &quot;C1&quot;,
    &quot;prefecture_number&quot;: &quot;14&quot;,
    &quot;establishment_category&quot;: 3,
    &quot;main_branch_indicator&quot;: 1,
    &quot;name&quot;: &quot;慶應義塾湘南藤沢中等部&quot;,
    &quot;location&quot;: &quot;神奈川県藤沢市遠藤５４６６&quot;,
    &quot;postal_code&quot;: &quot;2520816&quot;,
    &quot;attribute_info_setup_date&quot;: &quot;2020-12-22&quot;,
    &quot;attribute_info_cancellation_date&quot;: null,
    &quot;old_school_survey_number&quot;: &quot;144226&quot;,
    &quot;post_transition_school_code&quot;: null,
    &quot;created_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/schools/C114320500040.json&quot;
  },
  {
    &quot;code&quot;: &quot;D114310000222&quot;,
    &quot;school_type&quot;: &quot;D1&quot;,
    &quot;prefecture_number&quot;: &quot;14&quot;,
    &quot;establishment_category&quot;: 3,
    &quot;main_branch_indicator&quot;: 1,
    &quot;name&quot;: &quot;慶應義塾高等学校&quot;,
    &quot;location&quot;: &quot;神奈川県横浜市港北区日吉４−１−２&quot;,
    &quot;postal_code&quot;: &quot;2238524&quot;,
    &quot;attribute_info_setup_date&quot;: &quot;2020-12-22&quot;,
    &quot;attribute_info_cancellation_date&quot;: null,
    &quot;old_school_survey_number&quot;: &quot;145644&quot;,
    &quot;post_transition_school_code&quot;: null,
    &quot;created_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/schools/D114310000222.json&quot;
  },
  {
    &quot;code&quot;: &quot;D114320500093&quot;,
    &quot;school_type&quot;: &quot;D1&quot;,
    &quot;prefecture_number&quot;: &quot;14&quot;,
    &quot;establishment_category&quot;: 3,
    &quot;main_branch_indicator&quot;: 1,
    &quot;name&quot;: &quot;慶應義塾湘南藤沢高等部&quot;,
    &quot;location&quot;: &quot;神奈川県藤沢市遠藤５４６６&quot;,
    &quot;postal_code&quot;: &quot;2520816&quot;,
    &quot;attribute_info_setup_date&quot;: &quot;2020-12-22&quot;,
    &quot;attribute_info_cancellation_date&quot;: null,
    &quot;old_school_survey_number&quot;: &quot;145798&quot;,
    &quot;post_transition_school_code&quot;: null,
    &quot;created_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-02T02:45:51.505+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/schools/D114320500093.json&quot;
  },
  {
    &quot;code&quot;: &quot;F113310102984&quot;,
    &quot;school_type&quot;: &quot;F1&quot;,
    &quot;prefecture_number&quot;: &quot;13&quot;,
    &quot;establishment_category&quot;: 3,
    &quot;main_branch_indicator&quot;: 1,
    &quot;name&quot;: &quot;慶應義塾大学&quot;,
    &quot;location&quot;: &quot;東京都港区三田２−１５−４５&quot;,
    &quot;postal_code&quot;: &quot;1088345&quot;,
    &quot;attribute_info_setup_date&quot;: &quot;2021-01-20&quot;,
    &quot;attribute_info_cancellation_date&quot;: null,
    &quot;old_school_survey_number&quot;: &quot;2197&quot;,
    &quot;post_transition_school_code&quot;: null,
    &quot;created_at&quot;: &quot;2024-06-02T02:45:53.123+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-02T02:45:53.123+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/schools/F113310102984.json&quot;
  }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;学校種別の一覧を取得&lt;/h3&gt;
&lt;p&gt;D1やF1といったschool_typeの説明を取得&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl -s &apos;https://school.teraren.com/school_types.json&apos; | jq
[
  {
    &quot;code&quot;: &quot;A1&quot;,
    &quot;name&quot;: &quot;幼稚園&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.790+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.790+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/A1.json&quot;
  },
  {
    &quot;code&quot;: &quot;A2&quot;,
    &quot;name&quot;: &quot;幼保連携型認定こども園&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.793+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.793+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/A2.json&quot;
  },
  {
    &quot;code&quot;: &quot;B1&quot;,
    &quot;name&quot;: &quot;小学校&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.793+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.793+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/B1.json&quot;
  },
  {
    &quot;code&quot;: &quot;C1&quot;,
    &quot;name&quot;: &quot;中学校&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.793+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.793+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/C1.json&quot;
  },
  {
    &quot;code&quot;: &quot;C2&quot;,
    &quot;name&quot;: &quot;義務教育学校&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/C2.json&quot;
  },
  {
    &quot;code&quot;: &quot;D1&quot;,
    &quot;name&quot;: &quot;高等学校&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/D1.json&quot;
  },
  {
    &quot;code&quot;: &quot;D2&quot;,
    &quot;name&quot;: &quot;中等教育学校&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/D2.json&quot;
  },
  {
    &quot;code&quot;: &quot;E1&quot;,
    &quot;name&quot;: &quot;特別支援学校&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/E1.json&quot;
  },
  {
    &quot;code&quot;: &quot;F1&quot;,
    &quot;name&quot;: &quot;大学&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/F1.json&quot;
  },
  {
    &quot;code&quot;: &quot;F2&quot;,
    &quot;name&quot;: &quot;短期大学&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.794+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/F2.json&quot;
  },
  {
    &quot;code&quot;: &quot;G1&quot;,
    &quot;name&quot;: &quot;高等専門学校&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.795+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.795+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/G1.json&quot;
  },
  {
    &quot;code&quot;: &quot;H1&quot;,
    &quot;name&quot;: &quot;専修学校&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.795+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.795+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/H1.json&quot;
  },
  {
    &quot;code&quot;: &quot;H2&quot;,
    &quot;name&quot;: &quot;各種学校&quot;,
    &quot;created_at&quot;: &quot;2024-06-01T03:39:26.795+09:00&quot;,
    &quot;updated_at&quot;: &quot;2024-06-01T03:39:26.795+09:00&quot;,
    &quot;url&quot;: &quot;https://school.teraren.com/school_types/H2.json&quot;
  }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;今後の展望&lt;/h2&gt;
&lt;p&gt;現在のバージョンでも十分実用的ですが、さらに以下の機能を追加したいと考えています：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;学校の特徴（特色ある教育プログラムなど）の情報提供&lt;/li&gt;
&lt;li&gt;時系列データ（生徒数の推移など）の追加&lt;/li&gt;
&lt;li&gt;より柔軟な検索オプション（周辺施設との連携など）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;また、海外の学校情報も提供できるよう、データベースの拡張も検討中です。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;日本の学校情報 API の開発を通じて、改めてデータの重要性と、それを使いやすい形で提供することの価値を実感しました。この API が、教育関連のアプリケーション開発やリサーチなど、様々な場面で活用されることを願っています。&lt;/p&gt;
&lt;p&gt;みなさんも、「あったらいいな」と思う API やサービスがあれば、ぜひ開発にチャレンジしてみてください。ニッチな分野であっても、確実にニーズは存在するはずです。&lt;/p&gt;
&lt;p&gt;最後になりましたが、日本の学校情報 API へのフィードバックをお待ちしています。より良いサービスにしていくため、皆様のご意見をぜひお聞かせください！&lt;/p&gt;
&lt;h2&gt;参考リンク&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://school.teraren.com/&quot;&gt;日本の学校情報API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://school.teraren.com/doc&quot;&gt;API仕様書&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;みなさんの開発ライフがより充実することを願っています！&lt;/p&gt;
</content:encoded></item><item><title>MackerelプラグインでAPCのUPSを監視！「mackerel-plugin-apcupsd」の紹介</title><link>https://blog.teraren.com/posts/apc-mackerel-golang/</link><guid isPermaLink="true">https://blog.teraren.com/posts/apc-mackerel-golang/</guid><description>こんにちは、マインディアの CTO をしている まつぼっくりです。今回は、私が開発したMackerelプラグイン「mackerel-plugin-apcupsd」について紹介します。</description><pubDate>Tue, 02 Jul 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;こんにちは、マインディアの CTO をしている &lt;a href=&quot;https://zenn.dev/matsubokkuri&quot;&gt;まつぼっくり&lt;/a&gt;です。今回は、私が開発したMackerelプラグイン「&lt;a href=&quot;https://github.com/matsubo/mackerel-plugin-apcupsd&quot;&gt;mackerel-plugin-apcupsd&lt;/a&gt;」について紹介します。&lt;/p&gt;
&lt;p&gt;https://github.com/matsubo/mackerel-plugin-apcupsd&lt;/p&gt;
&lt;h2&gt;なぜUPS監視プラグインを作ったのか&lt;/h2&gt;
&lt;p&gt;スタートアップの CTO として、サービスの安定運用は常に頭を悩ませる問題です。特に、電源の安定性は見過ごせない重要なポイント。そこで目をつけたのが、UPS（無停電電源装置）の監視でした。&lt;/p&gt;
&lt;p&gt;「既存の Mackerel プラグインで UPS を監視できないかな？」と探してみたものの、ニーズにぴったり合うものがありません。「それなら自分で作っちゃえ！」というノリで開発を始めました。&lt;/p&gt;
&lt;h2&gt;プラグインの機能&lt;/h2&gt;
&lt;p&gt;このプラグインは、APC UPS の以下の項目を監視します：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;バッテリー残量&lt;/li&gt;
&lt;li&gt;入力電圧&lt;/li&gt;
&lt;li&gt;出力電圧&lt;/li&gt;
&lt;li&gt;負荷&lt;/li&gt;
&lt;li&gt;内部温度&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;データの取得には &lt;code&gt;apcupsd&lt;/code&gt; コマンドを利用しています。これらのデータを Mackerel で監視することで、UPS の状態をリアルタイムに把握し、潜在的な問題を早期に発見できるようになりました。&lt;/p&gt;
&lt;h2&gt;開発で苦労したポイント&lt;/h2&gt;
&lt;p&gt;開発中、最も苦労したのは &lt;code&gt;apcupsd&lt;/code&gt; コマンドの出力を適切にパースすることでした。出力形式が微妙に不規則で、単純な行分割では対応できない場合がありました。&lt;/p&gt;
&lt;p&gt;結局、以下のような正規表現を使って対応しました：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;re := regexp.MustCompile(`^(\w+)\s+:\s+(.*)$`)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この正規表現で、キーと値のペアを適切に抽出できるようになりました。&lt;/p&gt;
&lt;p&gt;また、Goの &lt;code&gt;testing&lt;/code&gt; パッケージを使ってユニットテストを書くことで、パースの正確性を担保しています。テスト駆動開発（TDD）の良さを改めて実感した開発でした。&lt;/p&gt;
&lt;h2&gt;プラグインの使い方&lt;/h2&gt;
&lt;p&gt;インストールは以下のコマンドで簡単に行えます：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo mkr plugin install matsubo/mackerel-plugin-apcupsd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;mackerel-agent.conf&lt;/code&gt; に以下の設定を追加するだけで使用可能です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[plugin.metrics.apcupsd]
command = &quot;/path/to/mackerel-plugin-apcupsd&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;設定を反映するためにmackerel-agentを再起動します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl restart mackerel-agent.service
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;今後の展望&lt;/h2&gt;
&lt;p&gt;現在のバージョンでも十分実用的ですが、さらに以下の機能を追加したいと考えています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;メトリックの単位ごとにグラフを変更する&lt;/li&gt;
&lt;li&gt;グラフのカスタマイズオプション&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;「mackerel-plugin-apcupsd」の開発を通じて、改めてオープンソースの素晴らしさを実感しました。自分のニーズを満たすツールを作り、それを他の人と共有できる。これこそがエンジニアの醍醐味だと思います。&lt;/p&gt;
&lt;p&gt;みなさんも、「あったらいいな」と思うツールがあれば、ぜひ自分で作ってみてください。そして、それをオープンソースとして公開することで、エンジニアコミュニティに貢献できるはずです。&lt;/p&gt;
&lt;p&gt;最後になりましたが、このプラグインへのフィードバックをお待ちしています。GitHub の Issue やプルリクエストをお待ちしています！&lt;/p&gt;
&lt;h2&gt;参考リンク&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/mackerel-plugin-apcupsd&quot;&gt;mackerel-plugin-apcupsd（GitHub）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;みなさんの UPS 監視ライフが充実することを願っています！&lt;/p&gt;
</content:encoded></item><item><title>UPSの状態をMackerelで可視化する: apcupsdとPythonを使ったカスタムプラグイン</title><link>https://blog.teraren.com/posts/apc-mackerel/</link><guid isPermaLink="true">https://blog.teraren.com/posts/apc-mackerel/</guid><description>サーバーの安定稼働にとって、電源の安定供給は非常に重要です。そのため、多くの環境で UPS（無停電電源装置）が使用されています。UPS の状態を常に監視することで、潜在的な問題を早期に発見し、対応できます。</description><pubDate>Sun, 30 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;UPSの状態をMackerelで可視化する: apcupsdとPythonを使ったカスタムプラグイン&lt;/h1&gt;
&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;p&gt;サーバーの安定稼働にとって、電源の安定供給は非常に重要です。そのため、多くの環境で UPS（無停電電源装置）が使用されています。UPS の状態を常に監視することで、潜在的な問題を早期に発見し、対応できます。&lt;/p&gt;
&lt;p&gt;この記事では、apcupsd を使用して UPS の情報を取得し、それを Python スクリプトで Mackerel に送信する方法を紹介します。これにより、UPS の状態をリアルタイムで可視化し、監視することが可能になります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/2024-07-01-01-26-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;前提条件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Linux 環境（Ubuntu, CentOS など）&lt;/li&gt;
&lt;li&gt;Python 3.x&lt;/li&gt;
&lt;li&gt;apcupsd&lt;/li&gt;
&lt;li&gt;Mackerel アカウントとエージェント&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;セットアップ手順&lt;/h2&gt;
&lt;h3&gt;1. apcupsdのインストールと設定&lt;/h3&gt;
&lt;p&gt;まず、apcupsd をインストールします：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install apcupsd  # Ubuntu/Debian
# または
sudo yum install apcupsd  # CentOS/RHEL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、&lt;code&gt;/etc/apcupsd/apcupsd.conf&lt;/code&gt; を編集します。
変更した差分は以下です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;320fc
&amp;gt; UPSNAME BR550S
---
&amp;lt; #UPSDNAME
90c90
&amp;gt;  #DEVICE /dev/ttyS0
---
&amp;lt; DEVICE /dev/ttyS0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;変更後の設定ファイル例を以下に記載します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;UPSNAME BR550S
UPSCABLE usb
UPSTYPE usb

NETSERVER on
NISIP 127.0.0.1
NISPORT 3551

ONBATTERYDELAY 6
BATTERYLEVEL 5
MINUTES 3
TIMEOUT 0

ANNOY 300
ANNOYDELAY 60
NOLOGON disable
KILLDELAY 0

EVENTSFILE /var/log/apcupsd.events
EVENTSFILEMAX 10

STATFILE /var/log/apcupsd.status
STATTIME 0

LOGSTATS off
DATATIME 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この設定では、USBでUPSに接続し、standaloneで動作する前提の設定ファイルです。&lt;/p&gt;
&lt;h3&gt;2. Pythonスクリプトの作成&lt;/h3&gt;
&lt;p&gt;以下のPythonスクリプトを作成し、&lt;code&gt;/etc/mackerel-agent/plugins/ups.py&lt;/code&gt; として保存します&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env python3

import subprocess
import re
import time

def get_apcaccess_output():
    result = subprocess.run([&apos;apcaccess&apos;], capture_output=True, text=True)
    return result.stdout

def parse_apcaccess_output(output):
    metrics = {}
    patterns = {
        &apos;linev&apos;: r&apos;LINEV\s+:\s+([\d.]+)\s+Volts&apos;,
        &apos;loadpct&apos;: r&apos;LOADPCT\s+:\s+([\d.]+)\s+Percent&apos;,
        &apos;bcharge&apos;: r&apos;BCHARGE\s+:\s+([\d.]+)\s+Percent&apos;,
        &apos;timeleft&apos;: r&apos;TIMELEFT\s+:\s+([\d.]+)\s+Minutes&apos;,
        &apos;battv&apos;: r&apos;BATTV\s+:\s+([\d.]+)\s+Volts&apos;
    }

    for key, pattern in patterns.items():
        match = re.search(pattern, output)
        if match:
            metrics[key] = float(match.group(1))

    return metrics

def main():
    output = get_apcaccess_output()
    metrics = parse_apcaccess_output(output)
    
    timestamp = int(time.time())
    
    for key, value in metrics.items():
        print(f&quot;ups.{key}\t{value}\t{timestamp}&quot;)

if __name__ == &apos;__main__&apos;:
    main()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;スクリプトに実行権限を付与します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo chmod +x /etc/mackerel-agent/plugins/ups.py
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. Mackerelエージェントの設定&lt;/h3&gt;
&lt;p&gt;Mackerelエージェントの設定ファイル（通常は &lt;code&gt;/etc/mackerel-agent/mackerel-agent.conf&lt;/code&gt;）に以下の設定を追加します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[plugin.metrics.ups]
command = [&quot;python3&quot;, &quot;/etc/mackerel-agent/plugins/ups.py&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;設定後、Mackerelエージェントを再起動します：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo systemctl restart mackerel-agent
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;動作確認&lt;/h2&gt;
&lt;p&gt;設定が完了したら、Mackerelのダッシュボードを確認します。&quot;Ups&quot;という名前のグラフグループが作成され、以下のメトリクスが表示されるはずです：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ups.linev: 入力電圧 (V)&lt;/li&gt;
&lt;li&gt;ups.loadpct: 負荷率 (％)&lt;/li&gt;
&lt;li&gt;ups.bcharge: バッテリー充電率 (％)&lt;/li&gt;
&lt;li&gt;ups.timeleft: 残り稼働時間 (分)&lt;/li&gt;
&lt;li&gt;ups.battv: バッテリー電圧 (V)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;このセットアップにより、UPSの重要な情報をMackerelで可視化し、監視できます。異常な値が検出された場合にアラートを設定するなど、さらなるカスタマイズも可能です。&lt;/p&gt;
&lt;p&gt;UPSの状態を常に把握することで、電源関連の問題を事前に察知し、サーバーの安定稼働を維持するための対策を講じることができます。&lt;/p&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;mackerelの慣習に則って、&lt;code&gt;mkr&lt;/code&gt; コマンドでインストールできるように Go でも書いておきました。&lt;/p&gt;
&lt;p&gt;https://github.com/matsubo/mackerel-plugin-apcupsd&lt;/p&gt;
</content:encoded></item><item><title>路線・駅情報のREST API開発と公開</title><link>https://blog.teraren.com/posts/stations-rest-api/</link><guid isPermaLink="true">https://blog.teraren.com/posts/stations-rest-api/</guid><description>ekidata.jpのデータをベースに、路線の駅一覧や最寄り駅検索ができるREST APIを作って公開した。</description><pubDate>Sun, 30 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ekidata.jp/&quot;&gt;ekidata.jp&lt;/a&gt;の路線・駅データを使ったREST APIを作った&lt;/li&gt;
&lt;li&gt;路線の停車駅一覧、駅の詳細情報、座標ベースの最寄り駅検索ができる&lt;/li&gt;
&lt;li&gt;Rails + MySQL 8.4で、自宅サーバ + Cloudflareで公開中&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://train.teraren.com/&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/2024-07-01-01-51-05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;技術スタック&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;レイヤー&lt;/th&gt;
&lt;th&gt;技術&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;バックエンド&lt;/td&gt;
&lt;td&gt;Ruby on Rails&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;データベース&lt;/td&gt;
&lt;td&gt;MySQL 8.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ホスティング&lt;/td&gt;
&lt;td&gt;自宅サーバ + Cloudflare&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;APIの使い方&lt;/h2&gt;
&lt;h3&gt;山手線の全停車駅を取得&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;❯ curl -s &apos;https://train.teraren.com/lines/11302/stations.json&apos; | jq &apos;.[].station_name&apos;
&quot;大崎&quot;
&quot;五反田&quot;
&quot;目黒&quot;
&quot;恵比寿&quot;
&quot;渋谷&quot;
&quot;原宿&quot;
&quot;代々木&quot;
&quot;新宿&quot;
&quot;新大久保&quot;
&quot;高田馬場&quot;
&quot;目白&quot;
&quot;池袋&quot;
&quot;大塚&quot;
&quot;巣鴨&quot;
&quot;駒込&quot;
&quot;田端&quot;
&quot;西日暮里&quot;
&quot;日暮里&quot;
&quot;鶯谷&quot;
&quot;上野&quot;
&quot;御徒町&quot;
&quot;秋葉原&quot;
&quot;神田&quot;
&quot;東京&quot;
&quot;有楽町&quot;
&quot;新橋&quot;
&quot;浜松町&quot;
&quot;田町&quot;
&quot;高輪ゲートウェイ&quot;
&quot;品川&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;座標から最寄り駅を検索&lt;/h3&gt;
&lt;p&gt;東京タワー付近の最寄り駅5件を取得する例。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ curl -s &apos;https://train.teraren.com/stations/near_by_stations.json?lon=139.7454329&amp;amp;lat=35.6585805&amp;amp;limit=5&apos; | jq
[
  {
    &quot;station_cd&quot;: 9930122,
    &quot;station_name&quot;: &quot;赤羽橋&quot;,
    &quot;station_g_cd&quot;: 9930122,
    &quot;distance&quot;: 0.42903606641634495
  },
  {
    &quot;station_cd&quot;: 2800317,
    &quot;station_name&quot;: &quot;神谷町&quot;,
    &quot;station_g_cd&quot;: 2800317,
    &quot;distance&quot;: 0.49008364939314947
  },
  {
    &quot;station_cd&quot;: 9930306,
    &quot;station_name&quot;: &quot;御成門&quot;,
    &quot;station_g_cd&quot;: 9930306,
    &quot;distance&quot;: 0.6242921448435772
  },
  {
    &quot;station_cd&quot;: 9930305,
    &quot;station_name&quot;: &quot;芝公園&quot;,
    &quot;station_g_cd&quot;: 9930305,
    &quot;distance&quot;: 0.6391377203522578
  },
  {
    &quot;station_cd&quot;: 9930121,
    &quot;station_name&quot;: &quot;大門&quot;,
    &quot;station_g_cd&quot;: 9930121,
    &quot;distance&quot;: 0.8572190503449685
  }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;レスポンス速度&lt;/h2&gt;
&lt;p&gt;GETリクエストはCDNに載るのでリモートからの正確なベンチマークは取りにくい。CDNキャッシュが効いていない初回リクエストで100ms程度。Wi-Fiのロスが10msぐらいあるので、実質90ms前後だと思う。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ time curl -s &apos;https://train.teraren.com/stations/near_by_stations.json?lon=138.754&amp;amp;lat=35.68&amp;amp;limit=5&apos; | jq
[
  {
    &quot;station_cd&quot;: 1131124,
    &quot;station_name&quot;: &quot;勝沼ぶどう郷&quot;,
    &quot;station_g_cd&quot;: 1131124,
    &quot;distance&quot;: 1.260601057731234
  },
  {
    &quot;station_cd&quot;: 1131125,
    &quot;station_name&quot;: &quot;塩山&quot;,
    &quot;station_g_cd&quot;: 1131125,
    &quot;distance&quot;: 3.307396894029273
  },
  {
    &quot;station_cd&quot;: 1131126,
    &quot;station_name&quot;: &quot;東山梨&quot;,
    &quot;station_g_cd&quot;: 1131126,
    &quot;distance&quot;: 4.871013008643865
  },
  {
    &quot;station_cd&quot;: 1131123,
    &quot;station_name&quot;: &quot;甲斐大和&quot;,
    &quot;station_g_cd&quot;: 1131123,
    &quot;distance&quot;: 5.162276817888356
  },
  {
    &quot;station_cd&quot;: 1131127,
    &quot;station_name&quot;: &quot;山梨市&quot;,
    &quot;station_g_cd&quot;: 1131127,
    &quot;distance&quot;: 6.436090680301475
  }
]

________________________________________________________
Executed in   94.13 millis    fish           external
   usr time   10.79 millis    0.12 millis   10.68 millis
   sys time    7.64 millis    1.38 millis    6.26 millis

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CDNキャッシュに入っていれば60ms程度で返ってくる。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;ekidata.jpのデータをRailsで薄くラップしただけのシンプルなAPIだけど、最寄り駅検索は地味に便利。自分の他のサービスからも内部的に使っている。&lt;/p&gt;
</content:encoded></item><item><title>ベビーベッドにGoogle Nest Miniを設置していつでも手軽に音楽再生</title><link>https://blog.teraren.com/posts/audio/</link><guid isPermaLink="true">https://blog.teraren.com/posts/audio/</guid><description>Google Nest MiniをベビーベッドにDIYで設置して童謡や子守唄をすぐ再生できる環境を構築。3ヶ月間の運用で感じたQoL向上と設置位置の改善点を紹介。</description><pubDate>Thu, 27 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;Google Nest Miniをベビーベッドに設置するとかなりQoLが高まります。設置には家に余っていた木ネジを使ってベビーベッドに打ち付けて、そこにNest Miniを引っ掛けます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1437.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1438.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;手軽に童謡を流したりできます。しかもGoogle Nestになってから音質がかなり良いです。&lt;/p&gt;
&lt;h2&gt;買ったもの&lt;/h2&gt;
&lt;p&gt;::amazon{asin=&quot;B0CQQ29K2W&quot;}&lt;/p&gt;
&lt;p&gt;よく使うコマンドは以下です。&lt;/p&gt;
&lt;p&gt;「童謡の音楽を再生して」&lt;/p&gt;
&lt;p&gt;「ジャンボリーミッキー流して」&lt;/p&gt;
&lt;p&gt;「子守唄を再生して」&lt;/p&gt;
&lt;p&gt;ちなみに、タブレットを設置して動画を流しっぱなしにするというアプローチもあるかと思いますが、教育上あまり良くないらしいのでタブレットは設置しない方針です。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;3ヶ月ほど運用してみました。おおかたとても役立っています。&lt;/p&gt;
&lt;p&gt;改善したい点としては、「OK Google」と言ったときに反応しているかどうかが本体LEDの点灯によって判別できないのでベッドの裏側ではなく本体を見やすい位置に設置すべきです。&lt;/p&gt;
</content:encoded></item><item><title>赤ちゃんのおむつ交換のための暗い照明環境の設置</title><link>https://blog.teraren.com/posts/lighting/</link><guid isPermaLink="true">https://blog.teraren.com/posts/lighting/</guid><description>夜中のおむつ交換で赤ちゃんが覚醒しないよう天井にダクトレールを設置して調光できる間接照明環境を構築。Panasonic製品の選定と電気工事のポイントも解説。</description><pubDate>Thu, 27 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;おそらく、夜中におむつ交換するときに微妙に薄暗いライトがほしい。直接照明だと覚醒してしまう可能性があるので、間接照明で。&lt;/p&gt;
&lt;p&gt;ということで、天井にダクトレールを設置して、調光できるようにしました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1439.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1440.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;設置したものは、&lt;a href=&quot;https://www2.panasonic.biz/jp/lighting/shop/duct/duct-rail/lineup.html&quot;&gt;Panasonicのダクトレール&lt;/a&gt;を天井にビスで固定してあります。&lt;/p&gt;
&lt;h2&gt;買ったもの&lt;/h2&gt;
&lt;p&gt;使っているダクトレールはこちらです。取り付けにあたっては資格が必要な電気工事が必要になるのでハードルは高いです。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0045U1SWA&quot;}&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00B2GY6AG&quot;}&lt;/p&gt;
&lt;p&gt;簡易的に設置できるものもあるので見栄えを犠牲にしてこういうのを使うのもありだと思います。1年ぐらいしか利用しないと思いますし。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0CJ9BKKFD&quot;}&lt;/p&gt;
&lt;p&gt;スポットライトに関しては、特にこだわりが無いので調光対応の安いものを使いました。&lt;/p&gt;
&lt;p&gt;しかしながら、LED調光ライトだと極限に暗くしたいときにある程度暗くなったところから消えてしまうのでちょっと微妙でした。&lt;/p&gt;
&lt;p&gt;かといって、現在だとLEDが主流なのでハロゲンとか電球を使うのもちょっと時代の流れ的に微妙です。できるだけ暗くて調光対応のもので、あとあと電球を入れ替えられそうな以下のものを試すのが良いと思います。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0B5SLR3R2&quot;}&lt;/p&gt;
</content:encoded></item><item><title>tapoカメラでの赤ちゃん監視と録画方法</title><link>https://blog.teraren.com/posts/tapo-baby-check/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tapo-baby-check/</guid><description>TP-LinkのTapoカメラをベビーベッドに固定して赤ちゃんを常時監視・録画。動体・泣き声検知の設定やONVIF対応、壁掛けAndroidタブレットへのストリーミング表示方法も紹介。</description><pubDate>Thu, 27 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;赤ちゃんを常時監視して異常があったら検知する方法です。&lt;/p&gt;
&lt;p&gt;異常検知しつつ、録画をしておけば成長記録にもなります。&lt;/p&gt;
&lt;h2&gt;買ったもの&lt;/h2&gt;
&lt;p&gt;監視カメラは多種多様なのですが、録画できて安くて屋内限定利用で充分です。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0CKWS1VWR&quot;}&lt;/p&gt;
&lt;p&gt;しかも、TapoカメラはONVIFプロトコル (Profile S) に対応しているため、サードパーティ製のNVRやNASに映像を保存できます。&lt;/p&gt;
&lt;p&gt;Tapoという変な名前ですが、TP-Link（大手）がメーカーなので安心です。過去にTP-LinkのWiFiアクセスポイントはコスパが良かったので5台くらい買いました。&lt;/p&gt;
&lt;p&gt;動画をローカルに記録するためにはmicroSDカードが別途必要になります。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0B2DCZDJZ&quot;}&lt;/p&gt;
&lt;h2&gt;設置&lt;/h2&gt;
&lt;p&gt;ベビーベッドに穴あけします。付属のネジは長過ぎるので、別途余っていた木ネジを使ってベビーベッドに固定します。&lt;/p&gt;
&lt;p&gt;足の方でも頭の方でもレンズの位置を移動できるので問題無いです。ベビーベッドに穴あけするのには少し躊躇しましたが、利便性が格段に上がるので穴あけして固定した方が良いです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1434.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;設置後はこんな感じ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1433.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;アプリから見るとこんな感じです。&lt;/p&gt;
&lt;p&gt;動体検知をしたときだけ録画する設定にしています。赤い部分は泣き声検知、オレンジの部分は伸びをしたときとかの動きを検知したときです。&lt;/p&gt;
&lt;p&gt;どんな感じのライフサイクルかがこれを見ると大体わかります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1449-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;壁掛けのAndroidタブレットを設置して、常時このカメラのストリームを表示しています。&lt;/p&gt;
&lt;p&gt;こうすることによってリビングからいつでもベビーベッドを確認できます。これは超便利です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1435.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;microSDに保存された動画はこんな感じです。定期的にファイルをバックアップしておけば成長記録になります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;tapoのカメラを設置しました。&lt;/p&gt;
&lt;p&gt;性能、価格、アプリの使い勝手はかなり良いのでおすすめです。&lt;/p&gt;
&lt;p&gt;私は設置場所に合わせて2台買いました。&lt;/p&gt;
</content:encoded></item><item><title>Go Proアタッチメントを使用したベビーベッド監視カメラの設置方法</title><link>https://blog.teraren.com/posts/tapo-stand-camera/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tapo-stand-camera/</guid><description>Tapo監視カメラをGoPro対応三脚に取り付けるDIY方法。専用台にドリルで穴を開けてGoPro変換アタッチメントを装着し、赤ちゃんを真上から撮影できるよう設置。</description><pubDate>Thu, 27 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;以前の記事でベビーベッドに監視カメラを設置して大変便利になりました。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/tapo-baby-check/&lt;/p&gt;
&lt;p&gt;追加で&lt;a href=&quot;https://www.aprica.jp/products/highlow/detail/manual/yuralism/&quot;&gt;ユラリズム&lt;/a&gt;や別の場所に赤ちゃんを置いているときにも監視できるように三脚にカメラを設置できるようにしました。&lt;/p&gt;
&lt;p&gt;普通にtapoのカメラを台やテーブルに置くだけでは赤ちゃんを撮影できません。なぜならカメラは設置した土台より下を撮影できなたいためです。そのため、カメラを下に向ける必要があるので設置方法はちょっと考える必要がありました。&lt;/p&gt;
&lt;h2&gt;台の作成&lt;/h2&gt;
&lt;p&gt;tapoのカメラには設置用の土台が付いてきます。しかし、アタッチメントがなくて壁などの平面に取り付ける前提なのでそのまま使えません。&lt;/p&gt;
&lt;p&gt;手元にあったGo Proアタッチメント対応の3000円ぐらいの三脚があるので、それを流用してみます。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0BF49J4ZM&quot;}&lt;/p&gt;
&lt;p&gt;まず、tapoの土台をGo Proマウントに変換するためアタッチメントを買いました。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B094XBSS3L&quot;}&lt;/p&gt;
&lt;p&gt;このアタッチメントのネジ部分は1/4inchのねじでカメラ取り付け用になっています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1468.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;tapoの土台に&lt;a href=&quot;https://amzn.to/4eIB7Dq&quot;&gt;5.5mmの穴をドリル&lt;/a&gt;で開けます。穴を開けたら、Go Pro用のアタッチメントをねじ込みます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1466.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;あとは、Unaziの三脚に設置すれば終わりです。アタッチメントはアルミなのでちょっと重いtapoのカメラでもしっかり固定されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1463.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;三脚側は前後にしか動けないけどカメラ側で350ぐらいは回転できるので大丈夫です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1464.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ねじもアルミだとより安心感が出ると思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1465.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;tapoアプリから見たプレビューです。こんな感じの角度で撮影できるようになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/img_1462-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;もっと安くできる方法を考えるために、1週間ぐらい設置方法を考えていましたが結局面倒なでアタッチメントを買ってしまいました。&lt;/p&gt;
&lt;p&gt;SeriaにGo Pro用のアタッチメントが昔は売っていたみたいなのでそれを流用したかったのですが今は売ってい無さそうです。&lt;/p&gt;
</content:encoded></item><item><title>電池駆動のメリーを電源供給に改造して電池代を節約</title><link>https://blog.teraren.com/posts/merry-ac-powered/</link><guid isPermaLink="true">https://blog.teraren.com/posts/merry-ac-powered/</guid><description>単2電池3本で動くベビーメリーをUSB電源駆動に改造するDIY。回路を分解して4.5V駆動を確認し、USBケーブルを加工して接続。電池切れを気にせず永続稼働できるように改造する手順を紹介。</description><pubDate>Tue, 25 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;以下のメリーを使っています。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B015XA8YHC&quot;}&lt;/p&gt;
&lt;p&gt;最初は「こんなおもちゃが赤ちゃんをあやせるわけ無いだろう」と思っていましたが、今となっては必需品です。これがないと生活できません。&lt;/p&gt;
&lt;p&gt;しかしながらこのメリーは単2電池3本で駆動しており電池消費を気にしながらいつまで使うのかわからないが単2電池のストックを管理する必要が出てきて面倒です。&lt;/p&gt;
&lt;p&gt;充電池を使ったとしても、充電池の初期コストと充電中に利用できなかったり単2電池用の充電器を買ったりしないといけないので初期出費がかなり高いです。この出資分の損益分岐が迎えられるとは思いませんでした。&lt;/p&gt;
&lt;p&gt;なので、電源から駆動するようにして電池を気にしないで無限に駆動できるように改造します。&lt;/p&gt;
&lt;h2&gt;分解&lt;/h2&gt;
&lt;p&gt;とりあえず回路がわからないといけないので、分解してみてみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/IMG_0796.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;電池は直列でつながっています。&lt;/p&gt;
&lt;p&gt;逆流防止用にダイオードが付いています。&lt;/p&gt;
&lt;p&gt;4.5V駆動の回路です。ACアダプターをこのためにだけに買うと1000円から2000円かかってしまうので、電圧が近い5VのUSB端子を使おうと思います。&lt;/p&gt;
&lt;p&gt;家にあった、適当な充電用USBケーブルのメス側をカットしてコードを延長して接点につけます。&lt;/p&gt;
&lt;p&gt;今後、電池で駆動させることは無いのでON/ONスイッチをつけるべきですが、省略します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/IMG_0797.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ついでに、ボタンの反応が悪くて強く押さないと反応しないので&lt;a href=&quot;https://amzn.to/4euriZM&quot;&gt;接点復活剤&lt;/a&gt;を塗布してウェスで拭き取っておきました。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B017CYN7NS&quot;}&lt;/p&gt;
&lt;p&gt;完成図。1A程度しか出力しないAC-USBアダプタを取り付けて終わり。電池切れを気にせず永遠に稼働させられます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/IMG_0800.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;LEDライトも電池を気にせずONにできます。精神衛生上とても良いです。&lt;/p&gt;
</content:encoded></item><item><title>neofetchが終了してfastfetchが引き継ぎ</title><link>https://blog.teraren.com/posts/neofetch-fastfetch/</link><guid isPermaLink="true">https://blog.teraren.com/posts/neofetch-fastfetch/</guid><description>neofetch開発終了に伴いfastfetchへの移行を解説。高速動作・低リソース消費・豊富なカスタマイズ性などfastfetchの特徴とneofetchとの詳細比較、Ubuntuへのインストール手順を紹介。</description><pubDate>Sun, 23 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;Fastfetchの概要&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fastfetch&lt;/strong&gt; は、システム情報を表示するための高速で効率的なツールです。このツールは、コンソールで動作し、オペレーティングシステム、カーネルバージョン、ディスプレイの解像度、メモリの使用量、CPU情報、GPU情報など、システムに関するさまざまな情報を美しく表示します。Fastfetchは、パフォーマンスとカスタマイズ性に重点を置いて設計されており、低リソース消費で高速に動作するのが特徴です。&lt;/p&gt;
&lt;h4&gt;特徴&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;高速動作&lt;/strong&gt;: 軽量であり、非常に高速にシステム情報を取得して表示します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;カスタマイズ性&lt;/strong&gt;: 表示内容やフォーマットを自由にカスタマイズ可能です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;低リソース消費&lt;/strong&gt;: メモリやCPUの使用量が少なく、リソースに優しい仕様です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Neofetchとの比較&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Neofetch&lt;/strong&gt; も同様にシステム情報を表示するツールですが、Fastfetchと比較するといくつかの違いがあります。&lt;/p&gt;
&lt;h4&gt;パフォーマンス&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fastfetch&lt;/strong&gt;: 高速で低リソース消費。多くの場合、Neofetchよりも情報表示が速い。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Neofetch&lt;/strong&gt;: デフォルト設定でも比較的高速ですが、Fastfetchほどではない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;カスタマイズ性&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fastfetch&lt;/strong&gt;: 設定オプションが豊富で、細かなカスタマイズが可能。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Neofetch&lt;/strong&gt;: カスタマイズも可能だが、Fastfetchほど柔軟ではない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;プラットフォームサポート&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fastfetch&lt;/strong&gt;: 多くのLinuxディストリビューションをサポート。WindowsやmacOSでも動作する。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Neofetch&lt;/strong&gt;: 幅広いプラットフォームで動作し、Linux、Windows、macOSを含む多くの環境で利用可能。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;インストール&lt;/h3&gt;
&lt;p&gt;Ubuntuの場合はrepositoryを追加する必要がある。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo add-apt-repository ppa:zhangsongcui3371/fastfetch
sudo apt update
sudo apt install fastfetch
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;実行&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>NECレンタルルータが辛すぎ</title><link>https://blog.teraren.com/posts/aterm-shit/</link><guid isPermaLink="true">https://blog.teraren.com/posts/aterm-shit/</guid><description>VDSLレンタルルータATERM-0A1129の発熱・不安定・DHCP64台制限・パケット詰まりなど多数の問題点を実体験から解説</description><pubDate>Sat, 15 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;VDSLのレンタルルータである、「ATERM-0A1129」が辛い。&lt;/p&gt;
&lt;h3&gt;辛い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;本体が大きい&lt;/li&gt;
&lt;li&gt;ファンレスではあるが発熱が大きい。
&lt;ul&gt;
&lt;li&gt;説明書に、上下左右は指定の空間を開けて設置する必要があると書いてある&lt;/li&gt;
&lt;li&gt;実際に発熱が大きくて温かい。筐体は40度ぐらい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DHCPサーバによる割当数がたった64しか無い。
&lt;ul&gt;
&lt;li&gt;見間違えかと思ったけど、本当に64しか配布できない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不安定
&lt;ul&gt;
&lt;li&gt;月に数回、勝手に再起動する。&lt;/li&gt;
&lt;li&gt;それによってテレカンが切れる。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;パケットが詰まる
&lt;ul&gt;
&lt;li&gt;テレカンしていると、回線品質が悪いというアラートが頻繁に出る。&lt;/li&gt;
&lt;li&gt;リアルタイム通信における音声や動画の送受信に支障をきたす。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ハードウェア、ファームウェアの問題なので新品に交換しても改善しなかった。&lt;/li&gt;
&lt;li&gt;回線品質が悪いから解約を申し出ても契約期間中の違約金なしでの解約ができなかった。&lt;/li&gt;
&lt;li&gt;管理画面から設定できないところにVDSLのアカウント情報が書き込まれているので、別のハードウェアを使えない。
&lt;ul&gt;
&lt;li&gt;レンタルすることが必須。&lt;/li&gt;
&lt;li&gt;他社のハードウェアを利用できない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DHCPサーバのオプションを書き換えられないので任意のDNSサーバやパラメータを配布できない。&lt;/li&gt;
&lt;li&gt;マニュアルに「電話回線として光ファイバーを利用し、電話機での通話を実現する電話サービスです。」という&lt;a href=&quot;https://www.aterm.jp/function/guide23/model/900/k/&quot;&gt;説明&lt;/a&gt;があるが意味がわからない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;良い点&lt;/h3&gt;
&lt;p&gt;無し&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;以前使っていた&lt;a href=&quot;/posts/nec-router-auto-reboot/&quot;&gt;NECのコンシューマ向けルータ&lt;/a&gt;も酷い状態だった。&lt;/p&gt;
&lt;p&gt;知り合いから設定を頼まれた家のルータがNECだったが、動作が不安定だった（設定通りに無線LANが動かない）。&lt;/p&gt;
&lt;p&gt;NECのコンシューマ向けルータは使わない方が良いと思う。&lt;/p&gt;
</content:encoded></item><item><title>QNAP TS-431Pを調達してNAS運用を始めました</title><link>https://blog.teraren.com/posts/qnap-ts-431p/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qnap-ts-431p/</guid><description>省電力化を目的にDELL PowerEdgeからQNAP TS-431Pへ移行し、RAID・ポートトランキング・ディスクスタンバイを設定した記録</description><pubDate>Sat, 15 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;QNAP TS-431Pを買ってNASのある生活を始めました。3.5万円ぐらいでした。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B01N2K147Q&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;いままで&lt;/h2&gt;
&lt;p&gt;DELL PowerEdge T320に以下のディスクを乗せて運用していました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OS領域 256GB SSDx2 RAID1&lt;/li&gt;
&lt;li&gt;データ領域 2TB HDDx4 RAID1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;しかしながら、RAIDコントローラのせいかHDDがスタンバイにならないので電力を食います。常時65W消費しています。昨今、電気代が結構高くなってきたので馬鹿にできない感じです。&lt;/p&gt;
&lt;p&gt;それに、個人利用なのでHDDもほとんど利用していないの回転していると無駄に寿命を消費するのでスタンバイにしておきたです。&lt;/p&gt;
&lt;p&gt;電気代とHDDのスタンバイ以外は最高です。ECC付きRAM、冗長化電源、XEON、Raidコントローラ、温度管理による安全な冷却。&lt;/p&gt;
&lt;h2&gt;TS-431Pの設定&lt;/h2&gt;
&lt;h3&gt;Raidの設定&lt;/h3&gt;
&lt;p&gt;最近のQNAPのOSはすごいです。色々できそうです。そもそも最新のQNAPのハードウェアは個人向けでも結構無駄にいろいろな機能が付いていて金額が10万円ぐらいしてしまうので旧世代のハードウェアを買いました。&lt;/p&gt;
&lt;p&gt;ディスクのプールを作るときには、Thin, Thick, Raidという謎な選択肢が出てきました。Thickにするとディスクの本数に応じて勝手にRaidレベルを変更するっぽいです。例えば、2本ならRaid1、3本ならRaid5といった感じです。&lt;/p&gt;
&lt;p&gt;今回は、Thinckにしてしまいましたが普通にRaidにしたほうが良かったです。勝手にRaidのレベルを変えられてしまって困ります。&lt;/p&gt;
&lt;h3&gt;ネットワークの設定&lt;/h3&gt;
&lt;p&gt;GbEのポートが2つあり、ポートトランキングできるので設定しました。NASはネットワークがボトルネックになることが多いので。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;その他の設定&lt;/h3&gt;
&lt;p&gt;アンチウィルスやメディアサーバとか色々アドオンできるっぽいです。&lt;/p&gt;
&lt;p&gt;とりあえず、ディスクのスタンバイ機能を有効にして、無駄な機能は切りまくりました。&lt;/p&gt;
&lt;p&gt;あと、ゴミ箱機能は有効にしてみました。あと、スナップショットも一応有効にして使ってみます。負荷が高かったら切ります。&lt;/p&gt;
&lt;p&gt;設定項目が分かりづらいので、&lt;a href=&quot;https://www.perplexity.ai/&quot;&gt;Perplexity&lt;/a&gt;に聞きながら色々進めました。&lt;/p&gt;
&lt;h2&gt;TS-431Pの運用&lt;/h2&gt;
&lt;h3&gt;統計指標&lt;/h3&gt;
&lt;p&gt;Disk3を入れ替えてリビルド中のスクリーンショット。いろいろな指標が確認できて良いです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ディスクの故障予期&lt;/h3&gt;
&lt;p&gt;SMART情報からディスクの寿命予測や、クリティカルな指標が出たらアラートを送ってくれます。&lt;/p&gt;
&lt;p&gt;私が以前から使っていたハードディスク4本中2本にwarningが出ていたので別のディスクに交換しました。&lt;/p&gt;
&lt;h3&gt;Raidのリビルドにかかる時間&lt;/h3&gt;
&lt;p&gt;2TBのディスクを追加してリビルドをかけると24時間ぐらいかかります。HDDが古いので遅いです。。。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Raid5で2TB x 4が動いています。Raidコントローラが壊れたら終わるのでなるべくRaid1で運用したいところではあります。&lt;/p&gt;
&lt;p&gt;しばらく様子を見てみます。&lt;/p&gt;
</content:encoded></item><item><title>WordPressをDockerizedしました</title><link>https://blog.teraren.com/posts/wordpress-dockerized/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-dockerized/</guid><description>LightsailからGMKtec自宅サーバへ移行し、WordPress10サイトをDocker化。MySQLコンテナ共有化やRAM32GBでの運用状況、起動負荷の課題も含めて報告。</description><pubDate>Sat, 15 Jun 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;クイックにWordPressを動かせる環境が欲しかったのでDocker composeで立ち上げられるようにしました。本番運用にも使えるように、動的に追加されるデータはファイルシステム上に保管されて永続化されるようにしています。&lt;/p&gt;
&lt;p&gt;テンプレートリポジトリを用意したので、forkして使うのが手っ取り早いです。&lt;/p&gt;
&lt;p&gt;https://github.com/matsubo/wordpress-docker-template&lt;/p&gt;
&lt;h2&gt;サーバ運用&lt;/h2&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair &lt;em&gt;/}
まず、Lightsail (月にで個人開発のサービスを一部運用していたのですが、データ量が多くなってきたのでストレージが足りなくなってきたことと、物理RAMが足りなくなってきたので自宅サーバへ移動しました。
{/&lt;/em&gt; textlint-enable ja-technical-writing/no-unmatched-pair */}&lt;/p&gt;
&lt;p&gt;Lightsailは以下のインスタンスを使っていました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;自宅サーバ自体もオーバースペック過ぎて、電気消費が大きいので新規に調達しました。&lt;/p&gt;
&lt;p&gt;調達したPCはこちら。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/gmktec-nucbox-m2/&lt;/p&gt;
&lt;p&gt;安くて良いです&lt;/p&gt;
&lt;h2&gt;サービス運用&lt;/h2&gt;
&lt;p&gt;物理RAMが32GBあり、しばらく運用している現状で20GBぐらい使っています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;すべてのサービスをDockerizedしました。&lt;/p&gt;
&lt;p&gt;DockerのRAMの利用常用はこんな感じです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/06/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;コンテナ数は30個ぐらいです。&lt;/p&gt;
&lt;p&gt;RAMをたくさん使っているのは、MySQLとRailsのアプリケーションサーバです。RSS領域で使っています。あとは、disk cacheとしてちょこちょこ使われています。&lt;/p&gt;
&lt;p&gt;WordPressサイトは10個ぐらいあります。1サイトごとにMySQLを立てているとメモリのMySQLサーバを立ち上げた直後の初期メモリ分が無駄になってしまうのでMySQLサーバは共有にしてアプリケーションサーバだけコンテナを個別にしました。MySQLは起動直後でも200MBぐらい消費するので、サイトごとに立てると馬鹿にならないです。128MBに制限したらメモリ不足で立ち上がりませんでした。&lt;/p&gt;
&lt;p&gt;1.5ヶ月ほど運用していますが問題は起きていないし速度もLightsailに比べるとだいぶ速いです。&lt;/p&gt;
&lt;h2&gt;Docker Composeの設定&lt;/h2&gt;
&lt;p&gt;設定を作るときにこだわったポイントは以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;動的に生成されるMySQLのデータや、WordPressでアップロードしたメディアやプラグイン、テーマはファイルシステム上に保存される&lt;/li&gt;
&lt;li&gt;必要最低限のパーミッションなので万が一クラックされても汚染されるスコープが狭い&lt;/li&gt;
&lt;li&gt;WordPress本体のバージョンの更新はイメージで行い、プラグインやテーマの更新はWeb上から動的に行える&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;単一サイト構成&lt;/h3&gt;
&lt;p&gt;以下が &lt;code&gt;docker-compose.yml&lt;/code&gt; です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  mysql:
    user: &quot;${UID:-1000}:${GID:-1000}&quot;
    image: mysql:latest
    restart: always
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/conf/custom.cnf:/etc/mysql/conf.d/custom.cnf
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE:-wordpress}
      MYSQL_USER: ${MYSQL_USER:-root}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}

  wordpress:
    image: wordpress:latest
    user: &quot;${UID:-1000}:${GID:-1000}&quot;
    restart: always
    volumes:
      - ./wordpress/themes:/var/www/html/wp-content/themes
      - ./wordpress/plugins:/var/www/html/wp-content/plugins
      - ./wordpress/uploads:/var/www/html/wp-content/uploads
    links:
      - mysql
    depends_on:
      - mysql
    ports:
      - &quot;${EXPOSE_PORT:-8080}:80&quot;
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_NAME: ${MYSQL_DATABASE:-wordpress}
      WORDPRESS_DB_USER: ${MYSQL_USER:-root}
      WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;複数サイト構成（MySQL共有）&lt;/h3&gt;
&lt;p&gt;MySQLコンテナをWordPressごとに立ち上げるとメモリを消費してしまうので、MySQLを1つ立ち上げて複数のWordPressサイトから接続して使うほうが効率的です。&lt;/p&gt;
&lt;p&gt;WordPressのコンテナの定義をコピー&amp;amp;ペーストして一部ハードコードして使います。複数のDBを扱うのでMySQLではrootで作業する必要が出てきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  mysql:
    user: &quot;${UID:-1000}:${GID:-1000}&quot;
    image: mysql:latest
    restart: always
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/conf/custom.cnf:/etc/mysql/conf.d/custom.cnf
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_ROOT_HOST: &apos;%&apos;

  production:
    image: wordpress:latest
    user: &quot;${UID:-1000}:${GID:-1000}&quot;
    restart: always
    volumes:
      - ./production/themes:/var/www/html/wp-content/themes
      - ./production/plugins:/var/www/html/wp-content/plugins
      - ./production/uploads:/var/www/html/wp-content/uploads
    links:
      - mysql
    depends_on:
      - mysql
    ports:
      - &quot;8080:80&quot;
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_NAME: production
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: ${MYSQL_ROOT_PASSWORD}

  staging:
    image: wordpress:latest
    user: &quot;${UID:-1000}:${GID:-1000}&quot;
    restart: always
    volumes:
      - ./staging/themes:/var/www/html/wp-content/themes
      - ./staging/plugins:/var/www/html/wp-content/plugins
      - ./staging/uploads:/var/www/html/wp-content/uploads
    links:
      - mysql
    depends_on:
      - mysql
    ports:
      - &quot;8081:80&quot;
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_NAME: staging
      WORDPRESS_DB_USER: root
      WORDPRESS_DB_PASSWORD: ${MYSQL_ROOT_PASSWORD}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;自分の環境ではこの複数サイト構成を使っています。&lt;/p&gt;
&lt;h3&gt;WordPressの大まかなインフラ設定&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;DBは1コンテナ&lt;/li&gt;
&lt;li&gt;WordPressのコンテナは&lt;a href=&quot;https://hub.docker.com/_/wordpress&quot;&gt;オフィシャルのイメージ&lt;/a&gt;を使っています。latestタグ。&lt;/li&gt;
&lt;li&gt;theme, uploads, pluginsの3つのディレクトリはローカルのファイルシステムに保存してコンテナ側からマウントしています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;1つのdocker-compose.ymlに上記の設定を入れています。&lt;/p&gt;
&lt;p&gt;1点、運用上ちょっと微妙なところはdocker compose経由でサービスを立ち上げると一気にコンテナを立ち上げてしまうので起動直後はCPU、Diskの負荷が増大します。&lt;/p&gt;
&lt;p&gt;依存関係をつけて順番に起動していくように書いても良いですが、実際には依存関係がないし順番の管理が面倒なので割愛します。&lt;/p&gt;
&lt;h2&gt;セットアップ&lt;/h2&gt;
&lt;p&gt;テンプレートとなるリポジトリをcloneしてきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git clone git@github.com:matsubo/wordpress-docker-template.git
% cd  wordpress-docker-template
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のコマンドを打って動作に必要な環境変数を一通り自動で作成します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo -n &amp;gt; .env
echo &quot;MYSQL_DATABASE=wordpress&quot; &amp;gt;&amp;gt; .env
echo &quot;MYSQL_USER=wordpress&quot; &amp;gt;&amp;gt; .env
echo &quot;MYSQL_ROOT_PASSWORD=$(tr -dc A-Za-z0-9 &amp;lt;/dev/urandom | head -c 15)&quot; &amp;gt;&amp;gt; .env
echo &quot;MYSQL_PASSWORD=$(tr -dc A-Za-z0-9 &amp;lt;/dev/urandom | head -c 15)&quot; &amp;gt;&amp;gt; .env
echo &quot;EXPOSE_PORT=8080&quot; &amp;gt;&amp;gt; .env
echo &quot;UID=$(id -u)&quot; &amp;gt;&amp;gt; .env
echo &quot;GID=$(id -g)&quot; &amp;gt;&amp;gt; .env
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そのあと、&lt;code&gt;docker compose up&lt;/code&gt; すれば初期設定が行われて、サーバ環境が立ち上がります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ブラウザでアクセスすれば初期設定画面が出るので、そのまま進めればOKです。&lt;/p&gt;
&lt;h2&gt;既存のWordPressからDockerに移行する方法&lt;/h2&gt;
&lt;p&gt;オンプレで運用しているWordPressから移行する場合は以下の手順でいけます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cp -ra /old/wordpress/wp-content/{plugins,themes,uploads} wordpress/
% mysqldump -u ${OLD_MYSQL_USER} --password=${OLD_MYSQL_PASSWORD} ${OLD_MYSQL_DB_NAME} | bzip2 &amp;gt; dump.sql.bz2
% docker compose cp dump.sql.bz2 mysql:/dump.sql.bz2
% docker compose exec mysql bash -c &apos;bzcat /dump.sql.bz2 | mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE&apos;
% docker compose exec mysql bash rm /dump.sql.bz2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;wp-contentの中身をコピーして、DBをdumpしてコンテナに流し込むだけなので簡単です。&lt;/p&gt;
&lt;h2&gt;PHPの設定変更&lt;/h2&gt;
&lt;p&gt;Dockerhubから提供されているデフォルトのWordPressイメージでは、HTTP経由でアップロードできるファイルサイズの最大容量がたった2MBしかないです。&lt;/p&gt;
&lt;p&gt;増やすためにはphp.iniによって設定をoverrideする必要があります。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;wordpress/custom.ini&lt;/code&gt; にファイルを作って中身を以下のように追加します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;post_max_size = 50M
upload_max_filesize = 50M
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;あとはWordPressのイメージを起動する際に上記のファイルをマウントしてしまえばよいだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;      volumes:
        - ./wordpress/custom.ini:/usr/local/etc/php/conf.d/custom.ini
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;WordPressのバージョン更新&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% docker pull wordpress:latest
% docker compose down &amp;amp;&amp;amp; docker compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;バックアップとリストア&lt;/h2&gt;
&lt;p&gt;クラウドじゃなくなったのでバックアップをしっかり取っていく必要があります。&lt;/p&gt;
&lt;p&gt;ホストOS側でバックアップが取りやすいのがこの構成の良いところです。一時停止が許容できるなら以下のtarで丸ごとバックアップするのが一番簡単です。&lt;/p&gt;
&lt;h3&gt;フルバックアップ&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% docker compose down
% tar jcf /path/to/backup.tar.bz2 .
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;フルバックアップからのリストア&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% tar xf /path/to/backup.tar.bz2
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;環境の削除&lt;/h2&gt;
&lt;p&gt;環境を潰して元どおりにする場合。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose down
% rm -rf mysql/data/*
% rm -rf wordpress/*/*
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;今後&lt;/h2&gt;
&lt;p&gt;ハードウェア故障に対してのBCPを考えていきます。&lt;/p&gt;
</content:encoded></item><item><title>TerraMasterを使ってMacOSでソフトウェアRaid1環境を構築してみる</title><link>https://blog.teraren.com/posts/post-15888/</link><guid isPermaLink="true">https://blog.teraren.com/posts/post-15888/</guid><description>TerraMasterエンクロージャと容量の異なるHDDを使い、macOS標準機能でソフトウェアRAID1を構築して様々なユースケースで動作検証した記録</description><pubDate>Thu, 25 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;MacOSではソフトウェアRAIDを組めるので実際に使ってみて使用感を確かめてみたいと思います。様々なユースケースでどの用に動作するかを検証してみたいと思います。&lt;/p&gt;
&lt;h2&gt;買ったもの&lt;/h2&gt;
&lt;h3&gt;エンクロージャ&lt;/h3&gt;
&lt;p&gt;TerraMaster D4-300 USB 3.1 Gen 1 タイプC ストレージ、外付けハードディスクエンクロージャー、HDD/SSD ホットスワップ&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B08CN4Z4PC&quot;}&lt;/p&gt;
&lt;h3&gt;用意したディスク&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;HDD1
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://amzn.to/4ddYKDm&quot;&gt;WD HDD 内蔵ハードディスク 3.5インチ 2TB Green&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HDD2
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://amzn.to/3Ux4ele&quot;&gt;Seagate BarraCuda 3.5インチ 4TB 内蔵 ハードディスク HDD PC 2年保証 6Gb/s 256MB 5400rpm 正規代理店品 ST4000DM004&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あえて2TBと4TBのディスクを用意してみました。&lt;/p&gt;
&lt;h2&gt;所感&lt;/h2&gt;
&lt;p&gt;HDD1をTerraMasterのエンクロージャへ、HDD2をTerraMasterを経由しないで直接Macにつなげたところ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;両方ともTerraMasterのエンクロージャへ入れたところ。OSから見える名称が異なるようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ディスク容量はちゃんと認識されています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;HDD1&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;HDD2&lt;/p&gt;
&lt;h2&gt;Raid1を構築&lt;/h2&gt;
&lt;p&gt;DiskUtilityの「ファイル」から「RAID アシスタント」&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Raid1を選択&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ディスクアレイを選択&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;右側にあるRoleはアクティブにするか、スタンバイにするかを選択できます。今回は2代のみなのでRAID Sliceを選択してアクティブにします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;次に、ディスクの名称とフォーマット方法を選択します。名前をわかりやすく変更しました。&lt;/p&gt;
&lt;p&gt;また、「Automatically rebuild」というオプションがあります。自動リビルドが走る設定のようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ディスクの内容を消えることを通知するアラートが出ます。そして、「Create」を押します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2分ぐらいで完了しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;フォーマットが完了した後の画面はこの用になります。&lt;/p&gt;
&lt;p&gt;物理ディスクと、ソフトウェアRaidによる論理ディスクが見えるようになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Unsplashからダウンロードした画像を適当に保存してみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;6.7GBのWindowsのディスクイメージを書き込んでみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;書き込みで42MB/s程度しか出ていません。USB 3.1接続のはずなのに遅すぎです。これではUSB2.0です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-17.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接続にはUGREENのUSB-Cケーブルを使って直接Macに接続しています。&lt;/p&gt;
&lt;h2&gt;ユースケースチェック&lt;/h2&gt;
&lt;h3&gt;HDD1を抜き差ししてみる&lt;/h3&gt;
&lt;p&gt;実験前の状態。2台のHDDがRaid1で組まれていてオンラインです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;HDD1を抜いたところ&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そのままHDD1を指し直します。そうするとリビルドが自動で走ります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;もともとオンラインだったHDD2をマスタとして、HDD1を再構築し始めました。&lt;/p&gt;
&lt;p&gt;ディスクのアクティビティを見ると、ReadとWriteが同程度活発に動いています。エンクロージャのランプは、HDD1が点灯して、HDD2が点灯しているのでディスクのデータをOS経由でコピーしているようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-23.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;リビルドのスピードはすごい遅いです。5分で0.2しか進みません。完了まで16時間ぐらいかかる見込みです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-24.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;時間がかかりすぎるので、Raidのメンバーから外してみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;10秒程度でリビルドが中止されてメンバーから外れました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Raidの状態は以下のようになり、「Missing/Dmaged」になりました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-27.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;今度は、明示的にRaidのメンバーとしてHDD1を追加してみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下の画面で5分程度待ちました。しばらくしたら、HDD1の電源が切れました。。。。処理が止まってしまっているようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-29.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;しかたがないので、TerraMasterの電源を強制的にオフ。&lt;/p&gt;
&lt;p&gt;再度、Raidのメンバーに追加しようとしましたが。同じ状況に陥りました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-30.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;DiskUtilityを強制終了してやり直します。&lt;/p&gt;
&lt;p&gt;今度は、「Repair」を選択します。そうしたら、30秒ぐらいで処理が完了して以下のようにスペアディスクとして追加されたようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-31.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;スペアディスクからメンバーには変換できないようなので、またHDD1をスペアから削除します。&lt;/p&gt;
&lt;p&gt;30秒程度で完了しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-32.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;再度、HDD1をRaid1のメンバーとして追加しますが、処理中から一向に動く気配がないです。HDD1のアクセスランプも一切動きません。&lt;/p&gt;
&lt;p&gt;OSを再起動しても同じ症状です。よって、MacosのソフトウェアRaidは運用では使えない感じです。。。&lt;/p&gt;
&lt;h3&gt;HDD2のデータを取り出せるのか&lt;/h3&gt;
&lt;p&gt;HDD2を取り出して、単体でデータを取り出せるのかを実験してみます。&lt;/p&gt;
&lt;p&gt;TerraMasterからHDD2を取り出して別のUSB接続の外付けドライブで接続してみます。&lt;/p&gt;
&lt;p&gt;ディスクは認識するのですが、パーティションが認識されていません。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-33.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;FirstAidを実行してみますがエラーで終わりました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-34.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;パーティションテーブルを見てみても何も表示されません。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そして、今度はHDD2をTerraMasterに戻します。そうしたら、ちゃんと認識されました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-36.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ソフトウェアraidを組んだでも、ファイルシステム的には同じに見えるものかと思っていましたが違うようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-38.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上記の記載が正しいのであれば、HDD2を抜いて、別の接続方式で接続してもraid1のディスクアレイの1台として認識されそうですがされないので良くわかりません。&lt;/p&gt;
&lt;h3&gt;HDD2を抜いて別のベイに刺してみる&lt;/h3&gt;
&lt;p&gt;TerraMaster上でのベイの入れ替えを行ったら正しく動くか検証してみます。&lt;/p&gt;
&lt;p&gt;もともとオンラインだったHDD2をbay-2からbay-1に移動してみました。そうしたら、ちゃんと認識されました。ディスクラベルも同一です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-39.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;TerraMaster外のディスクをraid1に追加できるか？&lt;/h3&gt;
&lt;p&gt;そもそもソフトウェアRaidなのでTerraMasterで接続していないディスクでRaidも組めるはずなので別の方法で接続したディスクを使ってみます。&lt;/p&gt;
&lt;p&gt;以下のように追加するウィザードは出てきました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-40.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;次の処理へ進むと、先ほどと同じ用に処理がスタックします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-41.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;この状態だと、Raid1を組んでもそのRaidのアレイにディスクを追加できないというソフトウェアRaidとして機能しない状態になります。&lt;/p&gt;
&lt;p&gt;どうやら、MacOSのソフトウェアRaidがまともに使えない感じです。&lt;/p&gt;
&lt;p&gt;Web上には同様のトラブルのドキュメントが見当たらないです。ユースケースとしてもmacOSでRaid1を組んでディスクアレイをぶっ壊す系の話なのであんまり無さそうです。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;macOSのソフトウェアRaidは使え無さそう&lt;/li&gt;
&lt;li&gt;TerraMasterの接続が非常に遅くて使えない。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Keychron K8 Proの初期化方法(factory reset)</title><link>https://blog.teraren.com/posts/post-15875/</link><guid isPermaLink="true">https://blog.teraren.com/posts/post-15875/</guid><description>Keychron K8 Proの初期化方法(factory reset)</description><pubDate>Mon, 08 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;オフィシャルサイトやマニュアルでは、以下のような記述があります&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Factory Reset:&lt;/strong&gt; Press fn + J + Z for 4 seconds until all the backlight flashes.&lt;/p&gt;
&lt;p&gt;日本語訳: &quot;fn + J + Z&quot; をすべてのバックライトが点滅するまで4秒間押し続けます。&lt;a href=&quot;https://github.com/Keychron/qmk_firmware/tree/bluetooth_playground/keyboards/keychron/k8_pro#keychron-k8-pro&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.keychron.com/blogs/archived/k8-pro-factory-reset-and-firmware-flash&quot;&gt;https://www.keychron.com/blogs/archived/k8-pro-factory-reset-and-firmware-flash&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;しかしながら、上記では無反応でした。&lt;/p&gt;
&lt;p&gt;色々試した結果、こちらに書いてある方法が正しそうです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Keychron/qmk_firmware/tree/bluetooth_playground/keyboards/keychron/k8_pro&quot;&gt;https://github.com/Keychron/qmk_firmware/tree/bluetooth_playground/keyboards/keychron/k8_pro&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Reset Key&lt;/strong&gt;: Connect the USB cable, toggle mode switch to &quot;Off&quot;, hold down the &lt;em&gt;Esc&lt;/em&gt; key or reset button underneath space bar, then toggle then switch to &quot;Cable&quot;.&lt;/p&gt;
&lt;p&gt;日本語訳: USBケーブルを接続し、モードスイッチを「Off」に切り替えます。&lt;br /&gt;
スペースバーの下にあるEscキーまたはリセットボタンを押し続けた状態で、&lt;br /&gt;
スイッチを「Cable」に切り替えてください。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;これでリセットできました。&lt;/p&gt;
</content:encoded></item><item><title>自宅サーバー用にGMKtec Nucbox M2(Intel Core i7)を買ったのでレビュー</title><link>https://blog.teraren.com/posts/gmktec-nucbox-m2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/gmktec-nucbox-m2/</guid><description>自宅サーバ用にGMKtec Nucbox M2（Core i7/32GB/1TB SSD）を53,000円で購入。CINEBENCHベンチマーク結果やUbuntu 22でのWiFiドライバ問題など実使用レポートを公開。</description><pubDate>Tue, 02 Apr 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;自宅サーバーで&lt;a href=&quot;/posts/home-server/&quot;&gt;PowerEdge T320&lt;/a&gt;を使っているが、大きいし消費電力が大きいのでちょっと買い変えを検討していた。&lt;/p&gt;
&lt;p&gt;自宅サーバでは、&lt;strong&gt;サービスのホスティング&lt;/strong&gt;と&lt;strong&gt;ストレージサーバ&lt;/strong&gt;という2つの役割があるが、両方を満たそうとするとどうしても巨大で高価なサーバになってしまう。&lt;/p&gt;
&lt;h2&gt;買ったもの&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0C534QGZK&quot;}&lt;/p&gt;
&lt;p&gt;主なスペック&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: &lt;a href=&quot;https://www.intel.co.jp/content/www/jp/ja/products/sku/217182/intel-core-i711390h-processor-12m-cache-up-to-5-00-ghz-with-ipu/specifications.html&quot;&gt;Intel core i7 11390H&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;RAM: 32GB(16GB*2) DDR4&lt;/li&gt;
&lt;li&gt;Disk: 1TB PCIe3.0 SSD&lt;/li&gt;
&lt;li&gt;GPU: Intel Iris Xe Graphics 1400MHz&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これが、今回はアマゾンのセールで53,000円ぐらいで買えた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;CINEBENCHの結果。&lt;/p&gt;
&lt;p&gt;Multi coreの場合: 5,067pts&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/cine-bench-multi-core.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Single core: 1,439pts&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/cine-bench.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;N100に比べるとCPUの消費電力は倍くらいです。クロック数も高いです。&lt;/p&gt;
&lt;p&gt;温度はファンの制御が細かくちゃんと動いているので100度以内です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/core-temp.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ディスクの速度も十分に速い。&lt;a href=&quot;/posts/chuwi-herobox-2023/&quot;&gt;HeroBox&lt;/a&gt;に比べると全体的に7倍くらい速い。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/04/CrystalDiskMark.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Linuxをインストールしてみる&lt;/h2&gt;
&lt;p&gt;Ubuntu 22 （LTS）をインストールしてみたところ、WiFiのチップセットが認識されませんでした。REALTEKの製品です。&lt;/p&gt;
&lt;p&gt;別途ドライバをインストールしたら、ネットワーク周りを起因としてkernel周りも不安定になったのでOSを初期化せざる負えなくなった。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;HeroBoxに比べると値段は3倍以上します。&lt;/p&gt;
&lt;p&gt;パフォーマンスはまずまず。&lt;/p&gt;
</content:encoded></item><item><title>CHUWI HeroBox 2023 (Intel N100搭載) を買ってみたのでベンチマーク</title><link>https://blog.teraren.com/posts/chuwi-herobox-2023/</link><guid isPermaLink="true">https://blog.teraren.com/posts/chuwi-herobox-2023/</guid><description>2万円台のミニPC CHUWI HeroBox 2023をCINEBENCHやCrystalDiskMarkで計測し、温度特性や用途適性を検証</description><pubDate>Wed, 13 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;CHUWI HeroBox 2023（Intel N100 / DDR5 8GB / 256GB SSD）を楽天スーパーセールで購入。価格は21,900円（税込・送料無料、2024/3/13時点）。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/03/image-7.png&quot; alt=&quot;CHUWI HeroBox 2023 外箱&quot; /&gt;&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair ja-technical-writing/sentence-length */}
&lt;a href=&quot;https://hb.afl.rakuten.co.jp/ichiba/3a70f013.fd78fca3.3a70f014.99329722/?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Fchuwi%2Fherobox%2F&amp;amp;link_type=picttext&amp;amp;ut=eyJwYWdlIjoiaXRlbSIsInR5cGUiOiJwaWN0dGV4dCIsInNpemUiOiIyNDB4MjQwIiwibmFtIjoxLCJuYW1wIjoicmlnaHQiLCJjb20iOjEsImNvbXAiOiJkb3duIiwicHJpY2UiOjEsImJvciI6MSwiY29sIjoxLCJiYnRuIjoxLCJwcm9kIjowLCJhbXAiOmZhbHNlfQ%3D%3D&quot;&gt;&lt;img src=&quot;https://transition.afl.rakuten.co.jp/items/list?surl=chuwi&amp;amp;iurl=herobox&amp;amp;e=35e4befa3a4b2e989e5817af8c98477615fc5640d78a86ef45049567d2f28cc9&amp;amp;scid=af_pc_etc&amp;amp;sc2id=af_101_0_0&quot; alt=&quot;CHUWI HeroBox 2023&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://hb.afl.rakuten.co.jp/ichiba/3a70f013.fd78fca3.3a70f014.99329722/?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Fchuwi%2Fherobox%2F&amp;amp;link_type=picttext&amp;amp;ut=eyJwYWdlIjoiaXRlbSIsInR5cGUiOiJwaWN0dGV4dCIsInNpemUiOiIyNDB4MjQwIiwibmFtIjoxLCJuYW1wIjoicmlnaHQiLCJjb20iOjEsImNvbXAiOiJkb3duIiwicHJpY2UiOjEsImJvciI6MSwiY29sIjoxLCJiYnRuIjoxLCJwcm9kIjowLCJhbXAiOmZhbHNlfQ%3D%3D&quot;&gt;CHUWI HeroBox 2023 Intel N100 DDR5 8GB+256GB SSD ミニPC&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://hb.afl.rakuten.co.jp/ichiba/3a70f013.fd78fca3.3a70f014.99329722/?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Fchuwi%2Fherobox%2F%3Fscid%3Daf_pc_bbtn&amp;amp;link_type=picttext&amp;amp;ut=eyJwYWdlIjoiaXRlbSIsInR5cGUiOiJwaWN0dGV4dCIsInNpemUiOiIyNDB4MjQwIiwibmFtIjoxLCJuYW1wIjoicmlnaHQiLCJjb20iOjEsImNvbXAiOiJkb3duIiwicHJpY2UiOjEsImJvciI6MSwiY29sIjoxLCJiYnRuIjoxLCJwcm9kIjowLCJhbXAiOmZhbHNlfQ==&quot;&gt;&lt;img src=&quot;https://static.affiliate.rakuten.co.jp/makelink/rl.svg&quot; alt=&quot;楽天で購入&quot; /&gt;&lt;/a&gt;
{/* textlint-enable ja-technical-writing/no-unmatched-pair ja-technical-writing/sentence-length */}&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B08L4XYP64&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/03/image-10.png&quot; alt=&quot;CHUWI HeroBox 2023 スペック&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ちなみにChuwiの読み方は「ツーウェイ」が正しい（オフィシャルサイトに記載あり）。「チューウィー」かと思っていた。&lt;/p&gt;
&lt;h2&gt;ハードウェア&lt;/h2&gt;
&lt;p&gt;一昔前のブロードバンドルーターや、WiFiアクセスポイントと行った感じに似てます。HDDが無いので軽いです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/03/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WUHDが出力できます。リフレッシュレートがかなり低い感じはしますが出力できているだけすごいです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/03/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ファンは常時稼働しています。音は聞こえてきます。CPU負荷が高くなるとファンの回転数も上がって音が大きくなります。&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/shorts/tVA4qElUNWU&lt;/p&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;CrystalDiskMarkではこんな感じです。速度が遅いので、128MiBで計測しています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/03/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;CINEBENCHのスコアはマルチコアで&lt;strong&gt;2520pts&lt;/strong&gt;, シングルコアで&lt;strong&gt;885pt&lt;/strong&gt;でした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/03/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;温度&lt;/h3&gt;
&lt;p&gt;CPU使用率が100％に張り付くことがよくあります。&lt;/p&gt;
&lt;p&gt;ブラウザのアップデートだったり、Windows Updateだったり、アプリケーションのインストールのときにはすぐに100％になります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/03/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;CPUコア温度を測定してみると、負荷が高い状況ですと大体76度程度。最高88度まで上がってます。&lt;/p&gt;
&lt;p&gt;ファンのスピードが負荷に即時に応じて上がるのでさほど高温にならないようにはなっています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/03/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;通常温度は45度程度です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/03/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;部屋の温度は21度です。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Raspberry Pi 4に比べると圧倒的に高性能。&lt;/li&gt;
&lt;li&gt;WUHDに出力できるしWebブラウジングはストレスありません。&lt;/li&gt;
&lt;li&gt;Windows Updateとかソフトウェアインストール時にCPU負荷が高くなるのでちょっとストレスを感じます。&lt;/li&gt;
&lt;li&gt;NASサーバや、K8sのクラスタを組むのに最適かと思います。SDカードじゃなくてSATA SSDですし。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Painting Keychron keyboard frame with WR blue mica</title><link>https://blog.teraren.com/posts/painting-keychron-keyboard-frame-with-wr-blue-mica/</link><guid isPermaLink="true">https://blog.teraren.com/posts/painting-keychron-keyboard-frame-with-wr-blue-mica/</guid><description>Keychron K6のアルミフレームをスバルWRX用のWRブルーマイカで塗装した手順と仕上がりを写真付きで紹介</description><pubDate>Tue, 27 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;I bought a &lt;a href=&quot;https://amzn.to/3wyM892&quot;&gt;Keychron K6 keyboard&lt;/a&gt;. Out of the box, the appearance is plain — two-tone keycaps and a single red escape key on an otherwise all-dark frame. Functional, but not exciting.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/img_7941-1.jpg&quot; alt=&quot;Keychron K6 stock appearance&quot; /&gt;&lt;/p&gt;
&lt;p&gt;While checking typing sound comparison videos on YouTube, I came across this one:&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/watch?v=ueL8_nh42wU&lt;/p&gt;
&lt;p&gt;The painted frame looked so good that I decided to give my keyboard a custom paint job too.&lt;/p&gt;
&lt;h2&gt;Color choice: WR Blue Mica&lt;/h2&gt;
&lt;p&gt;WR Blue Mica is the iconic color of Subaru&apos;s WRX STI rally cars. It&apos;s a deep blue with metallic flakes that shifts subtly in different lighting. Subaru enthusiasts will recognize it instantly.&lt;/p&gt;
&lt;p&gt;I chose this color because:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The metallic blue would contrast nicely with the dark keycaps&lt;/li&gt;
&lt;li&gt;The red escape key would pop against the blue (Subaru rally vibes!)&lt;/li&gt;
&lt;li&gt;Automotive-grade spray paint is durable enough for daily use&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Materials&lt;/h2&gt;
&lt;h3&gt;Silicon remover&lt;/h3&gt;
&lt;p&gt;Removes oils and contaminants from the metal surface so that paint adheres properly.&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00363PTSQ&quot;}&lt;/p&gt;
&lt;h3&gt;Primer and surfacer spray&lt;/h3&gt;
&lt;p&gt;The frame is aluminum, so a primer is needed to give the paint something to bond to. Without it, the paint will chip off within days.&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B002CPTTYY&quot;}&lt;/p&gt;
&lt;h3&gt;WR Blue Mica spray&lt;/h3&gt;
&lt;p&gt;The star of the show. This is the actual Subaru WRX color code in spray can form.&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B005UTHLSA&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/image-3.png&quot; alt=&quot;WR Blue Mica color reference&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Clear coat&lt;/h3&gt;
&lt;p&gt;WR Blue Mica contains metallic flakes, so a clear coat is required to protect the finish and give it a smooth, glossy surface.&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B002F1ODYQ&quot;}&lt;/p&gt;
&lt;p&gt;Total material cost was about 4,500 JPY. Since each can has enough paint for several projects, the per-keyboard cost is roughly 1,000 JPY.&lt;/p&gt;
&lt;h2&gt;Painting process&lt;/h2&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Clean with silicon remover&lt;/li&gt;
&lt;li&gt;Apply primer + surfacer&lt;/li&gt;
&lt;li&gt;WR Blue Mica × 2 coats&lt;/li&gt;
&lt;li&gt;Clear coat × 2 coats&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Allow 10–15 minutes of drying time between each coat.&lt;/p&gt;
&lt;h3&gt;Step 1: Primer&lt;/h3&gt;
&lt;p&gt;After cleaning the frame with silicon remover, I applied the primer + surfacer. This creates a uniform gray base for the color coat.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/img_7948.jpg&quot; alt=&quot;Frame after primer application&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Step 2: Color&lt;/h3&gt;
&lt;p&gt;Two coats of WR Blue Mica. Light, even passes from 15–20 cm distance to avoid drips. The metallic flakes start to shimmer after the second coat.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/img_7949.jpg&quot; alt=&quot;Frame after WR Blue Mica&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Step 3: Clear coat&lt;/h3&gt;
&lt;p&gt;Two coats of clear to seal the metallic paint and add gloss.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/img_7950.jpg&quot; alt=&quot;Frame after clear coat&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Result&lt;/h2&gt;
&lt;p&gt;I also painted the bolt heads with black metallic paint for a cleaner look.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/img_7951-1.jpg&quot; alt=&quot;Bolt detail&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/2417a873-c72b-4fe3-98ec-cba0103afb68-1.jpg&quot; alt=&quot;Reassembled keyboard - angle 1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/30fb9716-3a5d-47d4-a694-93f95b1993a2-1.jpg&quot; alt=&quot;Reassembled keyboard - angle 2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/53329545-79e6-42d9-b4bf-0aac98164d08-1.jpg&quot; alt=&quot;Reassembled keyboard - top view&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The contrast of the red escape key against the WR Blue Mica frame turned out great. It&apos;s giving off Subaru rally car energy.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/0a2940de-5431-429d-8425-d94599dbc8b8-1.jpg&quot; alt=&quot;Close-up of the finished keyboard&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Happy hacking!&lt;/p&gt;
</content:encoded></item><item><title>macOSでSDカードやUSBメモリをフォーマットする方法</title><link>https://blog.teraren.com/posts/macos-usb-memory-format/</link><guid isPermaLink="true">https://blog.teraren.com/posts/macos-usb-memory-format/</guid><description>Linux用に変更したパーティションテーブルのSDカードやUSBメモリをmacOSでフォーマットする方法。ディスクユーティリティが使えない場合にdiskutilコマンドで解決する手順を解説。</description><pubDate>Fri, 23 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;Linux用にパーティションテーブルを変更してしまったSDカードやUSBメモリだとmacOSのディスクユーティリティを使ってもフォーマットやパーティションテーブルの書き換えが行えません。&lt;/p&gt;
&lt;p&gt;かといって、フォーマットするためのアプリケーションを探してダウンロードするのが面倒です。&lt;/p&gt;
&lt;h2&gt;コマンド&lt;/h2&gt;
&lt;p&gt;diskutilコマンドでは、デバイス丸ごと（パーティションテーブルも含めて）フォーマットできるようなのでそれを使うのが良さそうです。&lt;/p&gt;
&lt;p&gt;FAT32でフォーマットするコマンド例は以下。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;diskutil eraseDisk FAT32 namae /dev/disk7&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;デバイスのIDを調べるためには以下のコマンドです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;diskutil list&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;実行例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diskutil list                                                                                                                      Fri Feb 23 19:41:26 2024
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *1.0 TB     disk0
   1:             Apple_APFS_ISC Container disk1         524.3 MB   disk0s1
   2:                 Apple_APFS Container disk3         994.7 GB   disk0s2
   3:        Apple_APFS_Recovery Container disk2         5.4 GB     disk0s3

/dev/disk3 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +994.7 GB   disk3
                                 Physical Store disk0s2
   1:                APFS Volume Macintosh HD            10.5 GB    disk3s1
   2:              APFS Snapshot com.apple.os.update-... 10.5 GB    disk3s1s1
   3:                APFS Volume Preboot                 11.9 GB    disk3s2
   4:                APFS Volume Recovery                1.8 GB     disk3s3
   5:                APFS Volume Data                    557.2 GB   disk3s5
   6:                APFS Volume VM                      8.6 GB     disk3s6

/dev/disk7 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *64.8 GB    disk7
   1:                        EFI EFI                     209.7 MB   disk7s1
   2:       Microsoft Basic Data NAMAE                   64.6 GB    disk7s2

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>HyperX QuadCast VS Anker Powerconf C200のマイク性能を比較</title><link>https://blog.teraren.com/posts/post-15780/</link><guid isPermaLink="true">https://blog.teraren.com/posts/post-15780/</guid><description>HyperX QuadCastとAnker PowerConf C200のマイク音質をヒーターノイズ・キーボード音入りの実験で比較し、ノイズキャンセリング性能の差を検証</description><pubDate>Fri, 23 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;HyperX QuadCastをかれこれ3年ぐらい使っています。&lt;/p&gt;
&lt;p&gt;性能に関しては全く文句はないです！ただ、デスク上の置き場を取ることが困ります。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07NZZZ746&quot;}&lt;/p&gt;
&lt;p&gt;Anker PowerConf C200はWebカメラでありつつ、マイクを内蔵しています。しかもそのマイクはノイズキャンセリング機能付きと書いてあります。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B09MHPFV4Q&quot;}&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;PowerConf C200のマイク性能が高ければ、HyperXのマイクを撤去できると考えました。ということで性能比較をしてみます。&lt;/p&gt;
&lt;h2&gt;実験&lt;/h2&gt;
&lt;p&gt;書斎の狭い部屋で同じ距離に置いて実験します。&lt;/p&gt;
&lt;h3&gt;実験1&lt;/h3&gt;
&lt;h4&gt;環境&lt;/h4&gt;
&lt;p&gt;ノイズを作るために電気ヒーターをON&lt;/p&gt;
&lt;h4&gt;テスト&lt;/h4&gt;
&lt;p&gt;Hyper-X QuadCast&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls src=&quot;/audio/2024/02/Test1.-Hyper-X-QuadCast.mp3&quot;&amp;gt;&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;PowerConf C200&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls src=&quot;/audio/2024/02/Test1.-PowerConf-C200.mp3&quot;&amp;gt;&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2024/02/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;考察&lt;/h4&gt;
&lt;p&gt;ぜんぜん違いますね。波形を見ると一目瞭然です。&lt;/p&gt;
&lt;p&gt;PowerConf C200の方は反響した音を拾っちゃっています。しかも、電気ファンヒーターのノイズを拾っています。&lt;/p&gt;
&lt;p&gt;それに比べて、Hyper-Xのほうは口元にマイクがあるかのような聞こえ方です。音声が鮮明です。さすが指向性のあるマイク。そして、マイクだけで2万円するだけあります。（C200の3倍の値段）&lt;/p&gt;
&lt;h3&gt;実験2&lt;/h3&gt;
&lt;h4&gt;環境&lt;/h4&gt;
&lt;p&gt;ノイズを作るために電気ファンヒーターをON&lt;/p&gt;
&lt;p&gt;Keychron K8 Proキーボードをタイピング&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0C9HQS2WP&quot;}&lt;/p&gt;
&lt;h4&gt;テスト&lt;/h4&gt;
&lt;p&gt;Hyper-X QuadCast&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls src=&quot;/audio/2024/02/Test1.-Hyper-X-QuadCast.mp3&quot;&amp;gt;&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;p&gt;PowerConf C200&lt;/p&gt;
&lt;p&gt;&amp;lt;audio controls src=&quot;/audio/2024/02/Test1.-PowerConf-C200.mp3&quot;&amp;gt;&amp;lt;/audio&amp;gt;&lt;/p&gt;
&lt;h4&gt;考察&lt;/h4&gt;
&lt;p&gt;両方ともタイピング音は入ります。やはりタイピング音は巨大です。HyperXの指向性を持ってしても排除できません。マイクと口との中間に位置するものなので排除が難しいのかと思います。&lt;/p&gt;
&lt;p&gt;それに対して、Powerconfは全然ノイズ除去できていません。これはノイズ除去を売り文句にしてはいけないと思います。&lt;/p&gt;
&lt;h2&gt;結論&lt;/h2&gt;
&lt;p&gt;PowerConf C200のノイズキャンセリング能力はほとんど無く、マイクの性能もHyperXQuadCastに比べると指向性がなくていまいち。&lt;/p&gt;
&lt;p&gt;HyperXを引き続き使います。&lt;/p&gt;
</content:encoded></item><item><title>gatsbyセットアップメモ</title><link>https://blog.teraren.com/posts/post-15683/</link><guid isPermaLink="true">https://blog.teraren.com/posts/post-15683/</guid><description>Gatsby.jsをゼロからセットアップし、Tailwind CSS・Google Analytics・MDX対応などを設定する手順をまとめたメモ</description><pubDate>Wed, 24 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;セットアップ&lt;/h2&gt;
&lt;p&gt;このあたりを参考に。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dev.classmethod.jp/articles/gatsby-project-init/&quot;&gt;https://dev.classmethod.jp/articles/gatsby-project-init/&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% npm init gatsby
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Need to install the following packages:
  create-gatsby@3.11.0
Ok to proceed? (y) y
create-gatsby version 3.11.0

                                                                                                     Welcome to Gatsby!

This command will generate a new Gatsby site for you in /Users/yuki.matsukura/ghq/github.com/matsubo/www.teraren.com with the setup you select. Let&apos;s answer some questions:

What would you like to call your site?
✔ · Teraren Corporate Site
What would you like to name the folder where your site will be created?
✔ www.teraren.com/ teraren-corporate-site
✔ Will you be using JavaScript or TypeScript?
· JavaScript
✔ Will you be using a CMS?
· No (or I&apos;ll add it later)
✔ Would you like to install a styling system?
· Tailwind CSS
✔ Would you like to install additional features with other plugins?
· Add the Google gtag script for e.g. Google Analytics
· Add responsive images
· Add an automatic sitemap
· Generate a manifest file
· Add Markdown and MDX support

Thanks! Here&apos;s what we&apos;ll now do:

    🛠  Create a new Gatsby site in the folder teraren-corporate-site
    🎨 Get you set up to use Tailwind CSS for styling your site
    🔌 Install gatsby-plugin-google-gtag, gatsby-plugin-image, gatsby-plugin-sitemap, gatsby-plugin-manifest, gatsby-plugin-mdx
  
✔ Shall we do this? (Y/n) · Yes
✔ Created site from template
✔ Installed Gatsby
✔ Installed plugins
✔ Created site in teraren-corporate-site
🔌 Setting-up plugins...
info Adding gatsby-plugin-postcss
info Adding gatsby-plugin-google-gtag
info Adding gatsby-plugin-image
info Adding gatsby-plugin-sitemap
info Adding gatsby-plugin-manifest
info Adding gatsby-plugin-mdx
info Adding gatsby-plugin-sharp
info Adding gatsby-transformer-sharp
info Adding gatsby-source-filesystem
info Adding gatsby-source-filesystem
info Installed gatsby-plugin-postcss in gatsby-config
success Adding gatsby-plugin-postcss to gatsby-config - 0.215s
info Installed gatsby-plugin-google-gtag in gatsby-config
success Adding gatsby-plugin-google-gtag to gatsby-config - 0.210s
info Installed gatsby-plugin-image in gatsby-config
success Adding gatsby-plugin-image to gatsby-config - 0.215s
info Installed gatsby-plugin-sitemap in gatsby-config
success Adding gatsby-plugin-sitemap to gatsby-config - 0.220s
info Installed gatsby-plugin-manifest in gatsby-config
success Adding gatsby-plugin-manifest to gatsby-config - 0.256s
info Installed gatsby-plugin-mdx in gatsby-config
success Adding gatsby-plugin-mdx to gatsby-config - 0.260s
info Installed gatsby-plugin-sharp in gatsby-config
success Adding gatsby-plugin-sharp to gatsby-config - 0.262s
info Installed gatsby-transformer-sharp in gatsby-config
success Adding gatsby-transformer-sharp to gatsby-config - 0.266s
info Installed gatsby-source-filesystem in gatsby-config
success Adding gatsby-source-filesystem (images) to gatsby-config - 0.278s
info Installed gatsby-source-filesystem in gatsby-config
success Adding gatsby-source-filesystem (pages) to gatsby-config - 0.281s
🎨 Adding necessary styling files...
🎉  Your new Gatsby site Teraren Corporate Site has been successfully created
at /Users/yuki.matsukura/ghq/github.com/matsubo/www.teraren.com/teraren-corporate-site.
Start by going to the directory with

  cd teraren-corporate-site

Start the local development server with

  npm run develop

See all commands at

  https://www.gatsbyjs.com/docs/reference/gatsby-cli/
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;% npm run develop
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;
&amp;gt; teraren-corporate-site@1.0.0 develop
&amp;gt; gatsby develop

success compile gatsby files - 0.270s
success load gatsby config - 0.022s
success load plugins - 0.511s
success onPreInit - 0.008s
success initialize cache - 0.076s
success copy gatsby files - 0.413s
success Compiling Gatsby Functions - 0.856s
success onPreBootstrap - 0.901s
success createSchemaCustomization - 0.012s
success Checking for changed pages - 0.001s
success source and transform nodes - 0.091s
success building schema - 0.107s
success createPages - 0.006s
success createPagesStatefully - 0.073s
info Total nodes: 47, SitePage nodes: 4 (use --verbose for breakdown)
success Checking for changed pages - 0.000s
success write out redirect data - 0.006s
success Build manifest and related icons - 0.097s
success onPostBootstrap - 0.100s
info bootstrap finished - 4.405s
success onPreExtractQueries - 0.001s
success extract queries from components - 0.806s
success write out requires - 0.006s
⠀
You can now view teraren-corporate-site in the browser.
⠀
  http://localhost:8000/
⠀
View GraphiQL, an in-browser IDE, to explore your site&apos;s data and schema
⠀
  http://localhost:8000/___graphql
⠀
Note that the development build is not optimized.
To create a production build, use gatsby build
⠀
success Building development bundle - 8.742s
success Writing page-data.json and slice-data.json files to public directory - 0.047s - 3/4 85.29/s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/07/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;いろいろやった結果&lt;/h2&gt;
&lt;p&gt;gatsbyのコミュニティが急速に衰退しているので微妙っす。デザインテンプレも良い感じのが出ない。&lt;/p&gt;
&lt;p&gt;Next.JSを使ったほうが良さげ。&lt;/p&gt;
</content:encoded></item><item><title>Google SpreadsheetやExcelでインボイス登録番号を求める方法</title><link>https://blog.teraren.com/posts/invoice-registration-number/</link><guid isPermaLink="true">https://blog.teraren.com/posts/invoice-registration-number/</guid><description>業務をしていると、インボイス登録番号を求めるケースや、インボイス登録番号を求められるケースがあるので自動的に処理できるように API サービスを作りました。</description><pubDate>Sat, 23 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;業務をしていると、インボイス登録番号を求めるケースや、インボイス登録番号を求められるケースがあるので自動的に処理できるように API サービスを作りました。&lt;/p&gt;
&lt;p&gt;この記事で言う、インボイス登録番号とは &lt;code&gt;適格請求書発行事業者番号&lt;/code&gt; を指します。&lt;/p&gt;
&lt;p&gt;以下のように法人番号からインボイス登録番号を表示できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/12/2023-12-24-02-36-43.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;インボイス番号とは&lt;/h2&gt;
&lt;p&gt;インボイス番号は、法人に対してと個人に対して付与されます。&lt;/p&gt;
&lt;p&gt;インボイス番号の採番方法は以下のようになっています。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;法人番号を有する課税事業者
「T」（ローマ字）　＋　法人番号（数字13桁）
上記以外の課税事業者（個人事業者、人格のない社団等）
「T」（ローマ字）　＋　数字13桁（注）
　（注）13桁の数字には、マイナンバー（個人番号）は用いず、法人番号とも重複しない事業者ごとの番号になります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;https://www.invoice-kohyo.nta.go.jp/about-toroku/index.html&lt;/p&gt;
&lt;p&gt;インボイス番号は法人番号から一意に求められますが、その法人がインボイス登録番号を取得しているかはわかりません。&lt;/p&gt;
&lt;p&gt;法人とインボイス番号は多対多の関係です。
個人とインボイス番号も多対多の関係です。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;以下の国税庁のサイトでは、インボイス登録番号から法人名や個人の番号の登録があるかは確認できますが、法人名や法人番号から検索はできません。&lt;/p&gt;
&lt;p&gt;https://www.invoice-kohyo.nta.go.jp/index.html&lt;/p&gt;
&lt;p&gt;以下のサイトから CSV や XML データでインボイス番号のダウンロードが行なえます。&lt;/p&gt;
&lt;p&gt;https://www.invoice-kohyo.nta.go.jp/download/zenken&lt;/p&gt;
&lt;h2&gt;API実装&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://corporation.teraren.com/&quot;&gt;法人番号検索APIのサイト&lt;/a&gt;に追加する形でインボイス番号を検索できるように実装しました。&lt;/p&gt;
&lt;p&gt;法人番号からインボイス番号を引けるように法人番号の子要素にインボイス番号を参照できるようにしました。&lt;/p&gt;
&lt;p&gt;例えば、&lt;code&gt;日本郵政株式会社&lt;/code&gt; の場合は以下の URL になります。&lt;/p&gt;
&lt;p&gt;https://corporation.teraren.com/corporations/5010001112697.json&lt;/p&gt;
&lt;p&gt;&lt;code&gt;invoice_registration_number&lt;/code&gt; というキーの下にインボイス番号の情報を付加しています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/12/2023-12-24-02-33-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;API 仕様は OpenAPI Speification 形式にて以下の URL で公開してあります。&lt;/p&gt;
&lt;p&gt;https://corporation.teraren.com/doc/redoc&lt;/p&gt;
&lt;h2&gt;表計算ソフトから利用する&lt;/h2&gt;
&lt;h3&gt;Google Spreadsheetから利用する&lt;/h3&gt;
&lt;p&gt;ここで紹介する方法は、こちらにサンプルのファイルを用意したのでコピーして利用できます。
https://docs.google.com/spreadsheets/d/1GWDqjeIVkAEFydl3ADE7ZCVW5FIa3gE-LvNyY5xEANI/edit#gid=72101969&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/12/2023-12-24-02-36-43.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;まずは法人番号を適当に取得しておきます。今回は「ソニー」というキーワードに合致する会社名と法人番号を取得してます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -s &apos;https://corporation.teraren.com/corporations.json?s=ソニー&apos;| jq &apos;.items[] | [.name,.corporate_number] | @csv&apos;                                                    Sun Dec 24 02:37:50 2023
&quot;\&quot;有限会社アンソニー\&quot;,6430002047180&quot;
&quot;\&quot;ソニーストレージメディアマニュファクチャリング株式会社\&quot;,3370601003097&quot;
&quot;\&quot;ソニーストレージメディア労働組合\&quot;,4370005009310&quot;
&quot;\&quot;株式会社アイソニーフーズ福島\&quot;,9380001009597&quot;
&quot;\&quot;ろばた焼ソニー有限会社\&quot;,6060002030513&quot;
&quot;\&quot;株式会社アンソニー・ケア\&quot;,5070001032295&quot;
&quot;\&quot;株式会社アンソニージャパン\&quot;,7070001024761&quot;
&quot;\&quot;有限会社ソニー\&quot;,5030002007911&quot;
&quot;\&quot;株式会社アイソニーフーズ\&quot;,9030001052533&quot;
&quot;\&quot;有限会社ソニーズフェラーリ\&quot;,5040002041117&quot;
&quot;\&quot;株式会社ソニー商事\&quot;,1010001089007&quot;
&quot;\&quot;ソニー銀行株式会社\&quot;,1010001126313&quot;
&quot;\&quot;株式会社レクソニーデジタルエンターテイメント\&quot;,1010401068601&quot;
&quot;\&quot;ソニービズネットワークス株式会社\&quot;,1010701026820&quot;
&quot;\&quot;ソニー損害保険株式会社\&quot;,1010801006342&quot;
&quot;\&quot;ソニー健康保険組合\&quot;,1700150004968&quot;
&quot;\&quot;ソニーフィナンシャルベンチャーズ株式会社\&quot;,2010001193311&quot;
&quot;\&quot;ソニーマーケティング株式会社\&quot;,2010401032358&quot;
&quot;\&quot;株式会社ソニー・ミュージックパブリッシング\&quot;,2010401040773&quot;
&quot;\&quot;ソニーリージョナルセールス株式会社\&quot;,2010401056489&quot;
&quot;\&quot;ソニーモバイルコミュニケーションズジャパン株式会社\&quot;,2010401103588&quot;
&quot;\&quot;ソニーネットワークコミュニケーションズコネクト株式会社\&quot;,2010701037387&quot;
&quot;\&quot;有限会社アンソニープラン\&quot;,2011302000453&quot;
&quot;\&quot;株式会社ソニー・ミュージックアクシス\&quot;,3010001074840&quot;
&quot;\&quot;ソニー生命保険株式会社\&quot;,3010401016260&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のスクリプトをApps Scriptに追加して保存します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getInvoiceRegistrationNumberFromCorporationNumber(corporation_number) {
  var url = &apos;https://corporation.teraren.com/corporations/&apos; + corporation_number  + &apos;.json&apos;;
  
  try {
    var response = UrlFetchApp.fetch(url, {&apos;muteHttpExceptions&apos;: true});
    response_object = JSON.parse(response);
    return response_object[&apos;invoice_registration_number&apos;][&apos;registrated_number&apos;];
  }catch(e){
    Logger.log(e);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このスクリプトでは、引数として法人番号を受け取り、それを元にAPIを呼び出し、APIのレスポンスの中からインボイス番号を取得して表示しています。&lt;/p&gt;
&lt;p&gt;その後は、上記の関数を呼び出すだけです。&lt;/p&gt;
&lt;p&gt;呼び出し例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=getInvoiceRegistrationNumberFromCorporationNumber(&quot;3370601003097&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;実際には別のカラムに法人番号があると思いますので以下のようになると思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/12/2023-12-24-02-41-33.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Excelから利用する&lt;/h3&gt;
&lt;p&gt;Excelからは簡単に利用できる関数があります。
以下の関数にURLを与えるとその返り値を表示できるようです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=WEBSERVICE(URL)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;サーバサイドで、上記の呼び出しに使えるエンドポイントを用意してあります。
例えば、日本郵政のインボイス番号を取得するには以下のURLになります。&lt;/p&gt;
&lt;p&gt;https://corporation.teraren.com/corporations/5010001112697/text/invoice_registration_number/registrated_number&lt;/p&gt;
&lt;p&gt;上記のエンドポイントはレスポンスがJSONではなくテキストで返却されます。&lt;/p&gt;
&lt;p&gt;A1のカラムに法人番号が書いてある場合は以下のように呼び出せばインボイス番号を取得できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=WEBSERVICE(&quot;https://corporation.teraren.com/corporations/&quot;+A1+&quot;/text/invoice_registration_number/registrated_number&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;法人番号からインボイス登録番号を取得するサービスを構築しました。&lt;/li&gt;
&lt;li&gt;Google spreadsheet と Excel からインボイス番号を取得する方法を紹介しました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>HTMLの&lt;input type=&quot;number&quot;&gt;フィールドにおけるマウスホイール動作の無効化</title><link>https://blog.teraren.com/posts/disable-wheel/</link><guid isPermaLink="true">https://blog.teraren.com/posts/disable-wheel/</guid><description>HTML において `&lt;input type=&quot;number&quot;&gt;` は、数値入力を容易にするためのフォームフィールドです。ユーザーはテキスト入力に加えて、マウスホイールやキーボードの矢印キーを使用して値を調整できます。これは便利な機能ですが</description><pubDate>Mon, 27 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;HTML において &lt;code&gt;&amp;lt;input type=&quot;number&quot;&amp;gt;&lt;/code&gt; は、数値入力を容易にするためのフォームフィールドです。ユーザーはテキスト入力に加えて、マウスホイールやキーボードの矢印キーを使用して値を調整できます。これは便利な機能ですが、一部の状況では意図しない挙動を引き起こす可能性があります。&lt;/p&gt;
&lt;p&gt;Rails で UI を作るときには、本当は &lt;a href=&quot;https://railsdoc.com/page/number_field&quot;&gt;number_field&lt;/a&gt;にしたかったところをわざわざ、&lt;a href=&quot;https://railsdoc.com/page/text_field&quot;&gt;text_filed&lt;/a&gt;にして実装していました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/11/2023-11-27-17-02-55.png&quot; alt=&quot;number fieldの例&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;input type=&quot;number&quot;&amp;gt;&lt;/code&gt; フィールド上にマウスカーソルがあるときに、ホイールを上下すると画面が上下しつつ、 &lt;strong&gt;フィールドの値も変わってしまいます&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;この問題はかなり昔からあって、5 年前ぐらいからは WebKit に存在していると思います。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;半ば諦めていたのですが、そもそも JavaScript でホイールを無効化してしまえば解決できると思ってコードを書きました。
これにより、マウスホイール操作による数値の変更を防ぎつつ、ページのスクロールはそのままにできます。&lt;/p&gt;
&lt;h2&gt;実装&lt;/h2&gt;
&lt;p&gt;ES のモジュールにしておきました。&lt;/p&gt;
&lt;p&gt;以下のコードスニペットは、&lt;code&gt;&amp;lt;input type=&quot;number&quot;&amp;gt;&lt;/code&gt; フィールドでのマウスホイールによる値変更を阻止する方法を示しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/**
 * Disable changing value using mouse wheel
 */
export function disableWheel(selector) {
  document.querySelectorAll(selector).forEach(input =&amp;gt; {
    input.addEventListener(&apos;wheel&apos;, event =&amp;gt; event.preventDefault(), { passive: false });
  });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この関数は、指定されたセレクタに一致する全ての要素にイベントリスナーを追加します。&lt;code&gt;wheel&lt;/code&gt; イベントが発生した際に &lt;code&gt;preventDefault&lt;/code&gt; メソッドを呼び出すことで、マウスホイールによる値の変更を阻止します。&lt;/p&gt;
&lt;p&gt;呼び出し方は以下の通りです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { disableWheel } from &apos;./disable-wheel.js&apos;;

window.addEventListener(&apos;load&apos;, function () {
  disableWheel(&apos;input[type=&quot;number&quot;]&apos;)
}, false);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;こちらにも置いておきます。
https://gist.github.com/matsubo/537aaecfbfd5389794da22f273afa01b&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;この実装は、特定の要素に対するユーザーインタラクションの制御において非常に効果的です。しかし、すべての &lt;code&gt;&amp;lt;input type=&quot;number&quot;&amp;gt;&lt;/code&gt; フィールドでこの挙動を無効化することは、ユーザーにとって予期せぬ経験をもたらすことがあります。したがって、この機能を適用する際は、ユーザビリティとのバランスを考慮することが重要です。また、将来的にブラウザのデフォルト挙動が変更される可能性も考慮し、継続的なメンテナンスとテストが必要となります。&lt;/p&gt;
</content:encoded></item><item><title>Tableau Serverをオンプレで運用する際のおすすめ設定</title><link>https://blog.teraren.com/posts/tableau-server-cron/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tableau-server-cron/</guid><description>以下の 2 行を設定しています。</description><pubDate>Wed, 27 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Tableau server をオンプレで運用する際のおすすめの設定を書いておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;cronの設定&lt;/h2&gt;
&lt;p&gt;以下の 2 行を設定しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5   9  * * * source /etc/profile.d/tableau_server.sh &amp;amp;&amp;amp; tsm maintenance cleanup --http-requests-table-retention 7 | logger 2&amp;gt;&amp;amp;1
10 */6  * * * source /etc/profile.d/tableau_server.sh &amp;amp;&amp;amp; tsm licenses refresh | logger 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1行目の設定&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;毎日、1週間より古いログは削除する&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;という設定です。&lt;/p&gt;
&lt;p&gt;Tableau Serverは常時大量のログファイルを書き込んでいます。&lt;/p&gt;
&lt;p&gt;以下のグラフはディスク容量の遷移です。ディスク容量は256GBです。普通に運用していると2ヶ月ぐらいで100％使い切ってしまいます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/09/2023-09-27-10-54-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;4月にこの設定を投入したので、直近は傾きが緩やかになっています。&lt;/p&gt;
&lt;h3&gt;2行目の設定&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;6時間ごとに &lt;code&gt;tsm licenses refresh&lt;/code&gt; を行う&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;という設定です。&lt;/p&gt;
&lt;p&gt;Tableau Serverのライセンスはオンラインで逐次Tableau側と同期が取られています。しかしながらその反映タイミングは不明です。
いつも手動で &lt;code&gt;tsm licenses refresh&lt;/code&gt; を行わないと反映されないです。&lt;/p&gt;
&lt;p&gt;手動は面倒なので自動にします。頻度は6時間に設定しました。判断基準は適当です。&lt;/p&gt;
&lt;h2&gt;共通設定&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;TSMコマンドを利用するためには以下の環境変数が記載されたファイルを読み込む必要が有るので冒頭で必ず読むように設定しています。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;source /etc/profile.d/tableau_server.sh&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ロギングはsyslogに丸投げします&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt; | logger 2&amp;gt;&amp;amp;1&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>Google Domains からドメイン保管料最安値のCloudflareへ移管しました</title><link>https://blog.teraren.com/posts/transfer-from-google-domain/</link><guid isPermaLink="true">https://blog.teraren.com/posts/transfer-from-google-domain/</guid><description>2023 年 6 月 15 日、Squarespace は、Google Domains からドメイン登録と関連する顧客アカウントを購入する意向を 発表しました。</description><pubDate>Fri, 22 Sep 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3行まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Google Domains がサービス終了に伴い、 &lt;strong&gt;放置しておくとSquarespaceに移管されて、約2倍の3,000円/年が課金&lt;/strong&gt; されることになってしまいます。&lt;/li&gt;
&lt;li&gt;最近のメジャーなドメインのレジストラを一通り調べて、一番安いレジストラを見つけて Cloudflare に移管してみました。&lt;/li&gt;
&lt;li&gt;Cloudflare の CDN とか reverse proxy などを使っていますが、相変わらず Cloudflare の UI やコストの低さは良いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;2023 年 6 月 15 日、Squarespace は、Google Domains からドメイン登録と関連する顧客アカウントを購入する意向を &lt;a href=&quot;https://support.google.com/domains/answer/13689670?hl=ja&quot;&gt;発表&lt;/a&gt;しました。&lt;/p&gt;
&lt;p&gt;「少なくとも 12 ヶ月間は既存の GoogleDomains ユーザーの料金プランを維持して利用できる」とアナウンスされているので、早急に何かする必要はありません。 放置しておくと Squarespace に事業が移管されます。&lt;/p&gt;
&lt;p&gt;個人的に.net と.com の 2 つのドメインを運用しています。&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;Squarespace のドメイン料金はアカウント登録をしてドメインの検索をしないとわからないような仕様になっています。
そこで、アカウント登録をして検索してみました。.com の保管料は&lt;strong&gt;3,000円/年&lt;/strong&gt;のようです。初年度は割引があります。
.net の保管料も 3000 円/年のようです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Google Domainsに比べると2年目は2倍の金額になります。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;このまま放置していると、高額なドメイン保管料を支払うことになってしまうので安いところを探してみます。&lt;/p&gt;
&lt;p&gt;メジャーなレジストラの &lt;code&gt;.com&lt;/code&gt; ドメインの保管料を調べた結果がこちらです。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;サービス名&lt;/th&gt;
&lt;th&gt;価格 (円/年)&lt;/th&gt;
&lt;th&gt;バーチャート&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;onamae.com&lt;/td&gt;
&lt;td&gt;4,375&lt;/td&gt;
&lt;td&gt;█████████████████████&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Squarespace&lt;/td&gt;
&lt;td&gt;3,000&lt;/td&gt;
&lt;td&gt;████████████████&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS&lt;/td&gt;
&lt;td&gt;1,919&lt;/td&gt;
&lt;td&gt;██████████&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;muumuu domain&lt;/td&gt;
&lt;td&gt;1,728&lt;/td&gt;
&lt;td&gt;█████████&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloudflare&lt;/td&gt;
&lt;td&gt;1,442&lt;/td&gt;
&lt;td&gt;███████&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Domains&lt;/td&gt;
&lt;td&gt;1,400&lt;/td&gt;
&lt;td&gt;███████&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Cloudflare ではドメイン保管料を &lt;a href=&quot;https://www.cloudflare.com/ja-jp/products/registrar/&quot;&gt;卸値で販売&lt;/a&gt;しているとのことです。
ということで、Cloudflare に移管します。&lt;/p&gt;
&lt;p&gt;余談ですが、&lt;code&gt;onamae.com&lt;/code&gt; に関しての注意です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.onamae.com/service/whois/images2.html&quot;&gt;whoisに代理情報を登録するのが有料&lt;/a&gt;です。
&lt;ul&gt;
&lt;li&gt;約 1,000 円/年という表記があります。&lt;/li&gt;
&lt;li&gt;whois には電話番号が必須なので個人の場合はどの電話番号を登録するかを考える必要があります。。&lt;/li&gt;
&lt;li&gt;既存で運用しているドメインのオプションを確認すると、 &lt;strong&gt;2,156円&lt;/strong&gt; と &lt;a href=&quot;https://twitter.com/matsubokkuri/status/1706922482735964418&quot;&gt;書かれていたり&lt;/a&gt;もするので本当に怖いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;値段だけでは評価できない罠がたくさんあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;h3&gt;Google Domains側の設定&lt;/h3&gt;
&lt;p&gt;ドメインの管理画面で、ロックの解除と認証コードを取得します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/09/2023-09-22-11-03-42.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;DNSSEC を使っている場合は、DNSSEC をオフにしておく必要があります。TTL によっては結構な時間を待ってから移行しないと nameserver の移管後に名前解決ができなくなってしまいます。&lt;/p&gt;
&lt;h3&gt;Cloudflare側の設定&lt;/h3&gt;
&lt;p&gt;前提として、Cloudflare で zone を管理している必要があります。
私の場合はすべてのドメインは Cloudflare で zone 管理しています。&lt;/p&gt;
&lt;p&gt;Cloudflare で zone 管理をするメリットは以下の記事で詳しく書いてあります。
https://zenn.dev/matsubokkuri/articles/cloudflare-service&lt;/p&gt;
&lt;p&gt;Google Domain 側でアンロックを行ってもすぐには移管できないようです。「アンロックしてから数時間待つ」という趣旨が書かれています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/09/2023-09-22-11-08-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2 時間ほど待ったら、ドメインが表示されました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/09/2023-09-22-15-16-38.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;次へ進むと、認証コードを入力画面になります。複数ドメインを一気に処理できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/09/2023-09-22-15-22-06.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;次に、ICANN に登録する個人情報を入力します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/09/2023-09-22-15-23-38.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;次に、以下のような画面になって移行がスタートします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/09/2023-09-22-15-25-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ステータスはドメイン一覧を表示すると閲覧できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/09/2023-09-22-15-26-40.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Google Domain側の作業&lt;/h3&gt;
&lt;p&gt;すぐに、Google Domain で利用しているメールアカウントへ最終確認のメールが来ます。メールのボタンをクリックして移行を許可します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/09/2023-09-22-15-30-31.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;確認&lt;/h2&gt;
&lt;p&gt;次に、whois コマンドで書き換わっているかを確認してみます。
(実際のドメイン名の部分は example.com に置き換えてます)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% whois example.com
# whois.verisign-grs.com

   Domain Name: EXAMPLE.COM
   Registry Domain ID: 1677305211_DOMAIN_COM-VRSN
   Registrar WHOIS Server: whois.cloudflare.com
   Registrar URL: http://www.cloudflare.com
   Updated Date: 2023-09-22T06:33:22Z
   Creation Date: 2011-09-16T01:04:50Z
   Registry Expiry Date: 2024-09-16T01:04:50Z
   Registrar: CloudFlare, Inc.
   Registrar IANA ID: 1910
   Registrar Abuse Contact Email:
   Registrar Abuse Contact Phone:
   Domain Status: clientTransferProhibited https://icann.org/epp#clientTransferProhibited
   Name Server: CRUZ.NS.CLOUDFLARE.COM
   Name Server: MAREK.NS.CLOUDFLARE.COM
   DNSSEC: signedDelegation
   DNSSEC DS Data: 2371 13 2 D718A03147EEF2F9D01774776C06F014EBE071258A1304E857DB56CF39E90F1F
   URL of the ICANN Whois Inaccuracy Complaint Form: https://www.icann.org/wicf/
&amp;gt;&amp;gt;&amp;gt; Last update of whois database: 2023-09-22T06:35:31Z &amp;lt;&amp;lt;&amp;lt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nameserverが引き継がれていることを確認しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% host -t ns example.com
example.com name server marek.ns.cloudflare.com.
example.com name server cruz.ns.cloudflare.com.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare のドメイン保管料はかなり安いですが、Cloduflare で zone 管理をする必要があります。&lt;/li&gt;
&lt;li&gt;8 ヶ月先まで有効なドメインが、Cloudflare にてなぜか 1 年間分課金されて更新されてしまいました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>npm, yarn, pnpmパッケージマネージャをベンチマークしてみた</title><link>https://blog.teraren.com/posts/2023-08-30-pnpm/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2023-08-30-pnpm/</guid><description>個人サービスである 銀行コード検索APIのpackage.jsonを使います。</description><pubDate>Wed, 30 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3行まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;pnpm が速いとのことなのでベンチマークをしてみましたが、Yarn v4 が最速です。&lt;/li&gt;
&lt;li&gt;Yarn v1 はキャッシュありのときにとても遅いでが、最新の v4 は全項目において最速です。&lt;/li&gt;
&lt;li&gt;Node.js の Docker image でデフォルトになっているのは Yarn v1 なのでご注意ください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;pnpm がどのくらい速いかを計測しています。&lt;/li&gt;
&lt;li&gt;Next.js や React を使ったときのベンチマークは掲載されていますが、実際自分のプロジェクトではどの程度かわるのかをベンチマークしてみたいと思います。&lt;/li&gt;
&lt;li&gt;pnpm とは何かを知りたい場合は &lt;a href=&quot;https://zenn.dev/azukiazusa/articles/pnpm-feature&quot;&gt;pnpm概要&lt;/a&gt;を参照するのが良いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実験環境&lt;/h2&gt;
&lt;p&gt;個人サービスである &lt;a href=&quot;https://bank.teraren.com/&quot;&gt;銀行コード検索API&lt;/a&gt;のpackage.jsonを使います。&lt;/p&gt;
&lt;p&gt;package.json の中身は以下のようになっています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;packageManager&quot;: &quot;yarn@1.22.15&quot;,
  &quot;private&quot;: true,
  &quot;dependencies&quot;: {
    &quot;@hotwired/turbo-rails&quot;: &quot;^7.3.0&quot;,
    &quot;@popperjs/core&quot;: &quot;^2&quot;,
    &quot;@rails/activestorage&quot;: &quot;^7.0&quot;,
    &quot;@rails/ujs&quot;: &quot;^7.0&quot;,
    &quot;bootstrap&quot;: &quot;^5.3&quot;,
    &quot;bootstrap-icons&quot;: &quot;^1.10.5&quot;,
    &quot;bootswatch&quot;: &quot;^5.3&quot;,
    &quot;esbuild&quot;: &quot;^0.18.17&quot;,
    &quot;jquery&quot;: &quot;^3.7&quot;
  },
  &quot;devDependencies&quot;: {
    &quot;eslint&quot;: &quot;^8.46.0&quot;,
    &quot;eslint-plugin-react&quot;: &quot;^7.33.1&quot;,
    &quot;npm-check-updates&quot;: &quot;^16.10.17&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;測定環境&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@1bf5d376c3a0:/app# node -v
v18.17.0
root@1bf5d376c3a0:/app# npm -v
9.8.1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;npmのbenchmark&lt;/h3&gt;
&lt;p&gt;まずは基本となる &lt;code&gt;npm&lt;/code&gt; を計測します。28秒。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@1bf5d376c3a0:/app# rm -rf node_modules/ package-lock.json
root@1bf5d376c3a0:/app# time npm install

added 383 packages, and audited 384 packages in 28s

80 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

real	0m28.308s
user	0m9.264s
sys	0m5.575s
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;yarn v1のbenchmark&lt;/h3&gt;
&lt;p&gt;Node.jsに標準で組み込まれたyarnは、13秒。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@1bf5d376c3a0:/app# rm -rf node_modules/ package-lock.json
root@1bf5d376c3a0:/app# time yarn install
yarn install v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 13.16s.

real	0m13.362s
user	0m5.338s
sys	0m6.641s/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;yarn v4のbenchmark&lt;/h3&gt;
&lt;p&gt;最新のyarnで計測します。なんと5.8秒！
計測ミスかと思って再度docker runして試しましたが同じ結果です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@1bf5d376c3a0:/# mkdir /app
root@1bf5d376c3a0:/# cat &amp;gt; package.json
root@1bf5d376c3a0:/app# yarn set version berry
root@1bf5d376c3a0:/app# yarn -v
4.0.2
root@1bf5d376c3a0:/app# time yarn install
➤ YN0000: · Yarn 4.0.2
➤ YN0000: ┌ Resolution step
➤ YN0085: │ + @hotwired/turbo-rails@npm:7.3.0, @popperjs/core@npm:2.11.8, and 474 more.
➤ YN0000: └ Completed in 3s 435ms
➤ YN0000: ┌ Fetch step
➤ YN0013: │ 455 packages were added to the project (+ 84.83 MiB).
➤ YN0000: └ Completed in 1s 442ms
➤ YN0000: ┌ Link step
➤ YN0000: │ ESM support for PnP uses the experimental loader API and is therefore experimental
➤ YN0007: │ esbuild@npm:0.18.20 must be built because it never has been before or the last one failed
➤ YN0000: └ Completed in 0s 501ms
➤ YN0000: · Done with warnings in 5s 438ms

real	0m5.816s
user	0m7.101s
sys	0m1.844s
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;pnpmのbenchmark&lt;/h3&gt;
&lt;p&gt;今回注目のpnpmは18秒。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@1bf5d376c3a0:/app# time pnpm i
Packages: +347
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 368, reused 0, downloaded 347, added 347, done
node_modules/.pnpm/esbuild@0.19.2/node_modules/esbuild: Running postinstall script, done in 93ms

dependencies:
+ @popperjs/core 2.11.8
+ @rails/activestorage 7.0.7-2
+ @rails/ujs 7.0.7-2
+ bootstrap-icons 1.10.5
+ bootswatch 5.3.1
+ esbuild 0.19.2
+ jquery 3.7.1

devDependencies:
+ eslint 8.48.0
+ npm-check-updates 16.13.2

Done in 17.9s

real	0m18.139s
user	0m7.202s
sys	0m5.991sx
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;余談: pnpmのエラー&lt;/h4&gt;
&lt;p&gt;余談ですが、2回目以降はエラーが出力されて計測できませんでした。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@1bf5d376c3a0:/app# rm -rf node_modules/ .pnpm-store/
root@1bf5d376c3a0:/app# time pnpm install
Packages: +438
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ERR_PNPM_LINKING_FAILED  Error: ENOENT: no such file or directory, copyfile &apos;/app/.pnpm-store/v3/files/cf/83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e&apos; -&amp;gt; &apos;/app/node_modules/.pnpm/resolve@2.0.0-next.4/node_modules/resolve_tmp_124/test/resolver/same_names/foo.js&apos;
Progress: resolved 459, reused 0, downloaded 438, added 197

real	0m20.723s
user	0m9.377s
sys	0m6.953s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;追記: &lt;code&gt;package-lock.json&lt;/code&gt; を削除したら成功しました。また、コンテナを立ち上げ直したら成功したりしたのでpnpmが内部で使っているハードリンク関連とDocker for macOSの相性が悪そうです。&lt;/p&gt;
&lt;h3&gt;キャッシュ無しベンチマーク結果&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package manager&lt;/th&gt;
&lt;th&gt;Result (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;npm&lt;/td&gt;
&lt;td&gt;28.308&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;yarn v1&lt;/td&gt;
&lt;td&gt;13.362&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;yarn v4&lt;/td&gt;
&lt;td&gt;5.816&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pnpm&lt;/td&gt;
&lt;td&gt;18.139&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/2023-12-20-13-11-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;考察&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;yarn v4がとても速いです。nodeのdocker imageのデフォルトではv1が使われてしまうので明示的にv4を設定する必要があります。&lt;/li&gt;
&lt;li&gt;今回は初回実行を計測しました。&lt;/li&gt;
&lt;li&gt;pnpmの初回は遅いですが、パッケージがシステム上で共有されること、依存関係の解決が高速なことを考えると2回目の実行はそこそこ速いです。
&lt;ul&gt;
&lt;li&gt;実際の開発では、CIや開発環境でパッケージの差分を追加していくと行った差分での利用が多いと思います。その際には高速に動作するので実運用では利点がありそうです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;次にパッケージマネージャを通して削除、追加する際のベンチマークを計測します。&lt;/p&gt;
&lt;h2&gt;パッケージの削除、追加の計測&lt;/h2&gt;
&lt;p&gt;実際の運用時に多いユースケースであるパッケージの追加、削除のときのベンチマークを計測してみます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;bootstrap&lt;/code&gt; パッケージを削除して、追加するケースを想定してベンチマークを取ってみます。&lt;/p&gt;
&lt;h3&gt;npm&lt;/h3&gt;
&lt;p&gt;トータル1.5秒。速いです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@7d57aaa10c85:/app/a# time npm uninstall bootstrap

removed 1 package, and audited 383 packages in 686ms

80 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

real	0m0.863s
user	0m0.772s
sys	0m0.160s
root@7d57aaa10c85:/app/a# time npm install bootstrap

added 1 package, and audited 384 packages in 767ms

81 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

real	0m0.943s
user	0m0.858s
sys	0m0.231s
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;yarn v1&lt;/h3&gt;
&lt;p&gt;トータル38秒。めちゃ遅いです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@7d57aaa10c85:/app/a# time yarn remove bootstrap
yarn remove v1.22.19
[1/2] Removing module bootstrap...
[2/2] Regenerating lockfile and installing missing dependencies...
success Uninstalled packages.
Done in 17.74s.

real	0m18.013s
user	0m5.547s
sys	0m8.845s
root@7d57aaa10c85:/app/a# time yarn add bootstrap
yarn add v1.22.19
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ bootstrap@5.3.1
info All dependencies
└─ bootstrap@5.3.1
Done in 20.55s.

real	0m20.919s
user	0m5.861s
sys	0m9.193s
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;yarn v4&lt;/h3&gt;
&lt;p&gt;addとremoveがそれぞれ1秒以内に終わります。速い！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@0c8caa909f49:/app# time yarn remove bootstrap
➤ YN0000: · Yarn 4.0.2
➤ YN0000: ┌ Resolution step
➤ YN0085: │ - bootstrap@npm:5.3.2
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: │ ESM support for PnP uses the experimental loader API and is therefore experimental
➤ YN0000: └ Completed
➤ YN0000: · Done with warnings in 0s 362ms

real	0m0.848s
user	0m0.778s
sys	0m0.375s
root@0c8caa909f49:/app# time yarn add  bootstrap
➤ YN0000: · Yarn 4.0.2
➤ YN0000: ┌ Resolution step
➤ YN0085: │ + bootstrap@npm:5.3.2
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0000: └ Completed
➤ YN0000: ┌ Link step
➤ YN0000: │ ESM support for PnP uses the experimental loader API and is therefore experimental
➤ YN0000: └ Completed
➤ YN0000: · Done with warnings in 0s 330ms

real	0m0.791s
user	0m0.820s
sys	0m0.171s
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;pnpm&lt;/h3&gt;
&lt;p&gt;トータル4.7秒。速いです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@7d57aaa10c85:/app# time pnpm remove bootstrap
Packages: -1
-
Progress: resolved 367, reused 346, downloaded 0, added 0, done

dependencies:
- bootstrap 5.3.1

Done in 2.2s

real	0m2.311s
user	0m2.041s
sys	0m0.906s
root@7d57aaa10c85:/app# time pnpm add bootstrap
Packages: +1
+
Progress: resolved 368, reused 347, downloaded 0, added 0, done

dependencies:
+ bootstrap 5.3.1

Done in 2.1s

real	0m2.239s
user	0m2.205s
sys	0m0.879s
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;remove/addのベンチマーク結果&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package manager&lt;/th&gt;
&lt;th&gt;Remove Result (s)&lt;/th&gt;
&lt;th&gt;Add Result (s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;npm&lt;/td&gt;
&lt;td&gt;0.863&lt;/td&gt;
&lt;td&gt;0.943&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;yarn v1&lt;/td&gt;
&lt;td&gt;18.013&lt;/td&gt;
&lt;td&gt;20.919&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;yarn v4&lt;/td&gt;
&lt;td&gt;0.8480&lt;/td&gt;
&lt;td&gt;0.791&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pnpm&lt;/td&gt;
&lt;td&gt;2.311&lt;/td&gt;
&lt;td&gt;2.239&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/2023-12-20-11-58-59.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;pnpmが公表している&lt;a href=&quot;https://pnpm.io/ja/benchmarks&quot;&gt;ベンチマーク結果&lt;/a&gt;とは違いましたやはり手元でやってみるのは意味があります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/pnpm-benchmark.png&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;jsbundling-rails&lt;/code&gt; は Yarn に依存しているので要注意です。&lt;/p&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://p.datadoghq.eu/sb/d2wdprp9uki7gfks-c562c42f4dfd0ade4885690fa719c818?tpl_var_npm%5B0%5D=%2A&amp;amp;tpl_var_pnpm%5B0%5D=%2A&amp;amp;tpl_var_yarn-classic%5B0%5D=no&amp;amp;tpl_var_yarn-modern%5B0%5D=%2A&amp;amp;tpl_var_yarn-nm%5B0%5D=no&amp;amp;tpl_var_yarn-pnpm%5B0%5D=no&amp;amp;from_ts=1685609076259&amp;amp;to_ts=1693385076259&amp;amp;live=true&quot;&gt;Package Manager Benchmarks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Amazon Linux 2023にfishを入れる方法</title><link>https://blog.teraren.com/posts/amazon-linux-2023-fish/</link><guid isPermaLink="true">https://blog.teraren.com/posts/amazon-linux-2023-fish/</guid><description>依存されているライブラリと、コンパイラをインストールしておきます。</description><pubDate>Tue, 29 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;まとめ&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Amazon Linux 2023 はどの Fedora, CentOS などのバージョンに対応するのか明示されていないのでソースからインストールしました。&lt;/li&gt;
&lt;li&gt;Fedora と Cent OS の該当しそうな rpm をインストールしようとしましたが、glibc 周りの依存関係にひっかかってインストールできませんでした。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Amazon Linux 2のEOLが2023年6月30日から 2025年6月30日に変更&lt;/code&gt; という &lt;a href=&quot;https://aws.amazon.com/jp/amazon-linux-2/faqs/&quot;&gt;ニュース&lt;/a&gt;が20222年末に公開されました。Amazon Linux 2023 の登場に伴い、Amazon Linux 2 がオワコン化したので Amazon Linux 2023 に趣味サービスを載せ替えました。ついでにインスタンスサイズも 1 つ下げました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;p&gt;依存されているライブラリと、コンパイラをインストールしておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo yum install ncurses-devel -y
% sudo yum install cmake gcc g++ -y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最新のソースコードをダウンロードしてビルドします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget https://github.com/fish-shell/fish-shell/releases/download/3.6.1/fish-3.6.1.tar.xz
% tar xf fish-3.6.1.tar.xz
% cd fish-3.6.1/
% mkdir build; cd build
% cmake ..
% make
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;インストールします。
&lt;code&gt;/usr/local/bin/fish&lt;/code&gt; に入ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;/usr/local/bin/fish&lt;/code&gt; を &lt;code&gt;/etc/shells&lt;/code&gt; に追加します。&lt;/p&gt;
&lt;p&gt;デフォルトのシェルを変更するためにchshしようとしたら、&lt;code&gt;-bash: chsh: command not found&lt;/code&gt; と怒られたので、chshをインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo dnf install util-linux-user
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そして、デフォルトのシェルを変更します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% chsh -s /usr/local/bin/fish
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;確認&lt;/h1&gt;
&lt;p&gt;無事入りました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% fish -v
fish, version 3.6.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/fish-amazon-linux-2023.png&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>MySQL Workbenchの後継であるMySQL Shell for VS Codeを使ってみる</title><link>https://blog.teraren.com/posts/post-15714/</link><guid isPermaLink="true">https://blog.teraren.com/posts/post-15714/</guid><description>MySQL Workbenchの後継であるMySQL Shell for VS Codeを使ってみる</description><pubDate>Tue, 29 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;MySQL Workbenchのサーバーをモニタリングする機能が&lt;a href=&quot;https://azure.microsoft.com/ja-jp/products/visual-studio-code&quot;&gt;VS Code&lt;/a&gt;のプラグインとしてリリースされているようなので軽く動作を見てみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;ssh tunnelの設定は相変わらずうまく接続できなかった（MySQL Workbenchのときも苦労しました）ので生のmysqlプロトコルで接続します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;グラフィカルに見栄えのするところは、左のメニューから「Performance Dashboard」を選んで、上部のメニューから「Performance Dashboard」を選択すると以下のようなグラフが表示されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Jupiter Notebookのような機能もあります。クエリーを実行して、その結果を動的にゴニョゴニョして行きます。トラブルシューティングのときに便利です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;普通にテーブルの中身を見たりもできます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Notebookは便利です。後々レポートを書くときなどに使いやすそう。&lt;/li&gt;
&lt;li&gt;全体的に動作が不安定でした。。。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>UbuntuでMySQLを8.0.34から8.1.0へアップグレード。Innovation Releaseを使う設定。</title><link>https://blog.teraren.com/posts/ubuntu-mysql-8-1/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ubuntu-mysql-8-1/</guid><description>MySQL 8.1.0のInnovation Releaseとは何かを解説し、UbuntuでMySQL 8.0からaptリポジトリ設定を変更してアップグレードする具体的な手順を紹介します。</description><pubDate>Tue, 29 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.oracle.com/jp/events/mysql-day/&quot;&gt;MySQL Innovation Day Tokyo 2023&lt;/a&gt;に行ってきました。（オフィスから徒歩8分なので楽！）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2023年7月18日 （今から約1ヶ月前）にMySQL&lt;a href=&quot;https://blogs.oracle.com/mysql-jp/post/mysql-810-is-out-thank-you-for-the-contributions-jp&quot;&gt;初のInnovation Release&lt;/a&gt;が行われました。バージョンは&lt;strong&gt;8.1.0&lt;/strong&gt;です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;最近のアップデート&lt;/h2&gt;
&lt;p&gt;あんまりMySQLの最新情報をキャッチアップしていなかったので軽くまとめます。&lt;/p&gt;
&lt;h3&gt;リリースサイクルの変更&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://blogs.oracle.com/mysql-jp/post/mysql-810-is-out-thank-you-for-the-contributions-jp&quot;&gt;2023年7月19日の記事&lt;/a&gt;にあるようにMySQLのリリースサイクルが変更になりました。&lt;/p&gt;
&lt;p&gt;https://blogs.oracle.com/mysql-jp/post/introducing-mysql-innovation-and-longterm-support-lts-versions-jp&lt;/p&gt;
&lt;p&gt;今後のリリースはLTSとInnovation Releaseの2つになります。Ubuntuと同じようなリリース体系を取ることとなります。バージョン表記は今までと変わらず&lt;a href=&quot;https://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%9E%E3%83%B3%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%8B%E3%83%B3%E3%82%B0#:~:text=%E3%82%BB%E3%83%9E%E3%83%B3%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E3%83%BB%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%8B%E3%83%B3%E3%82%B0%EF%BC%88%E8%8B%B1%E8%AA%9E%EF%BC%9ASemantic,%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%80%81%E3%83%91%E3%83%83%E3%83%81%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%A8%E5%91%BC%E3%81%B6%E3%80%82&quot;&gt;セマンティックバージョニング&lt;/a&gt;での表記になります。&lt;/p&gt;
&lt;p&gt;Innovation Releaseは1月ごとにマイナーバージョンが1つ上がります。LTSは2年に1回マイナーバージョンが上がります。よって、2年に1回はInnovation ReleseとLTSのバージョンが合致します。&lt;/p&gt;
&lt;p&gt;そして、LTSの方のバージョンはマイナーバージョン12個ずつ上がっていきます。Innovation Releaseのマイナーバージョンに関しては12で繰り上がり、メジャーバージョンが1つ上がるみたいです。（最初の方はイレギュラーにインクリメントされそうです）&lt;/p&gt;
&lt;p&gt;よって、LTSのバージョンは8.4.0, 9.7.0, 10.7.0....という具合に上がっていきます。（非常に分かりづらい。）&lt;/p&gt;
&lt;p&gt;LTSに対してパッチが当たるとリビジョンがインクリメントされます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://blogs.oracle.com/mysql-jp/post/introducing-mysql-innovation-and-longterm-support-lts-versions-jp&quot;&gt;https://blogs.oracle.com/mysql-jp/post/introducing-mysql-innovation-and-longterm-support-lts-versions-jp&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;MySQL8のバージョン樹形図&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/yoku0825&quot;&gt;@yoku0825&lt;/a&gt;さんのスライドにあるこの樹形図は参考になります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://speakerdeck.com/yoku0825/bokutatihamysql-8-dot-1todousheng-kiruka?slide=25&quot;&gt;https://speakerdeck.com/yoku0825/bokutatihamysql-8-dot-1todousheng-kiruka?slide=25&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;mysqlshのバージョン&lt;/h3&gt;
&lt;p&gt;mysqlshにはmysql serverのバージョンとは関係なく新機能をどんどん取り入れていくようです。言い換えると、Innovation Releaseと同じスパンで更新されていくような事を言ってました。&lt;/p&gt;
&lt;h3&gt;LTS or Innovation Release&lt;/h3&gt;
&lt;p&gt;ということで、業務や個人開発においてLTSか、Innovation Releaseのどちらを使うかが迷います。&lt;/p&gt;
&lt;p&gt;個人的には、数ヶ月に1回ぐらい追加機能が入るような感じが良かったので3ヶ月1回にリリースされるInnovation Releaseのストリームをトラッキングすることとします。LTSは2年スパンです。&lt;/p&gt;
&lt;p&gt;特に、MySQLは8.0になってからクリティカルなバグがリリースされる事件が数回起こっています。（過去、このバグを踏んで痛い目を見ました）&lt;/p&gt;
&lt;p&gt;業務はLTS、個人開発はInnovation Releaseで良いのかなと思ってます。OSのディストリビューションをLTSにするかしないかという意思決定と揃えるとポリシーが揃ってわかりやすいと思います。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://jp.ubuntu.com/download&quot;&gt;UbuntuのLTS&lt;/a&gt;のリリースも2年スパンなのでMySQLと同様です。Ubuntuは1年毎にメジャーバージョンが上がるので、偶数はLTSを意味することになります。&lt;/p&gt;
&lt;p&gt;Innovation Releaseも日々使っておいてキャッチアップすることも重要なので個人サービスや自宅サーバはInnovation Releaseを使っていきます。OSもUbuntu Serverの最新を使うようにしているのでポリシー的にも合致します。&lt;/p&gt;
&lt;h2&gt;MySQL 8.1へのアップグレード事前チェック&lt;/h2&gt;
&lt;p&gt;まずは、現在のMySQL Serverのバージョンを調べてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@localhost:test&amp;gt; select @@version;
+-------------------------+
| @@version               |
+-------------------------+
| 8.0.34-0ubuntu0.22.04.1 |
+-------------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MySQL Serverのapt lineはdebパッケージよって提供されています。このパッケージを入れることで自分が使いたいMySQLのメインストリームとなるLTSまたはInnovation Releaseのapt lineが追加されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget https://dev.mysql.com/get/mysql-apt-config_0.8.26-1_all.deb
% sudo dpkg -i mysql-apt-config_0.8.26-1_all.deb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;インストール中に以下のようなダイアログが立ち上がり、どのプロダクトを使いたいかを選択します。デフォルトではLTSになっています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;なので、mysql-innovationを選びます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;画面を戻ったら、更新されています。OKを押して完了します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;まずは、最近（と言っても数年前から）のトレンドであるmysqlshをインストールします。mysqlクライアントの高機能版です。JavaScriptのsyntaxでコマンドを発行できるし、管理機能が充実しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; sudo apt-get update
matsu@dell ~&amp;gt; sudo apt-get install mysql-shell
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following NEW packages will be installed:
  mysql-shell
0 upgraded, 1 newly installed, 0 to remove and 2 not upgraded.
Need to get 26.5 MB of archives.
After this operation, 226 MB of additional disk space will be used.
Get:1 http://repo.mysql.com/apt/ubuntu jammy/mysql-innovation amd64 mysql-shell amd64 8.1.1-1ubuntu22.04 [26.
5 MB]
Fetched 26.5 MB in 5s (5739 kB/s)
selecting previously unselected package mysql-shell:amd64.
Reading database ... 158313 files and directories currently installed.)
Preparing to unpack .../mysql-shell_8.1.1-1ubuntu22.04_amd64.deb ...
Unpacking mysql-shell:amd64 (8.1.1-1ubuntu22.04) ...
Setting up mysql-shell:amd64 (8.1.1-1ubuntu22.04) ...
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.1) ...
matsu@dell ~&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;とりあえず、バックアップをします。mysqlshを立ち上げて、以下のコマンドでdumpを行います。今までのmysqldumpに比べると超速いです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;util.dumpInstance(&quot;/home/matsu/20230828&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;実行結果&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; mysqlsh --user=root -p
Cannot set LC_ALL to locale en_US.UTF-8: No such file or directory
MySQL Shell 8.1.1

Copyright (c) 2016, 2023, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its affiliates.
Other names may be trademarks of their respective owners.

Type &apos;\help&apos; or &apos;\?&apos; for help; &apos;\quit&apos; to exit.
Creating a session to &apos;root@localhost&apos;
Fetching schema names for auto-completion... Press ^C to stop.
Your MySQL connection id is 29696 (X protocol)
Server version: 8.0.34-0ubuntu0.22.04.1 (Ubuntu)
No default schema selected; type \use &amp;lt;schema&amp;gt; to set one.
 MySQL  localhost:33060+ ssl  JS &amp;gt; util.dumpInstance(&quot;/home/matsu/20230828&quot;)
Acquiring global read lock
Global read lock acquired
Initializing - done
2 out of 6 schemas will be dumped and within them 54 tables, 0 views.
3 out of 6 users will be dumped.
Gathering information - done
All transactions have been started
Locking instance for backup
Global read lock has been released
Writing global DDL files
Writing users DDL
Running data dump using 4 threads.
NOTE: Progress information uses estimated values and may not be accurate.
NOTE: Table statistics not available for `matsu_blog_covid19`.`wp_cocoon_affiliate_tags`, chunking operation may be not optimal. Please consider running &apos;ANALYZE TABLE `matsu_blog_covid19`.`wp_cocoon_affiliate_tags`;&apos; f
irst.
NOTE: Table statistics not available for `matsu_blog_covid19`.`wp_cocoon_function_texts`, chunking operation may be not optimal. Please consider running &apos;ANALYZE TABLE `matsu_blog_covid19`.`wp_cocoon_function_texts`;&apos; f
irst.
NOTE: Table statistics not available for `matsu_blog_covid19`.`wp_users`, chunking operation may be not optimal. Please consider running &apos;ANALYZE TABLE `matsu_blog_covid19`.`wp_users`;&apos; first.
&amp;lt;snip&amp;gt;
Writing schema metadata - done
Writing DDL - done
Writing table metadata - done
Starting data dump
&amp;lt;snip&amp;gt;
Dump duration: 00:00:12s
Total duration: 00:00:12s
Schemas dumped: 2
Tables dumped: 54
Uncompressed data size: 1.59 GB
Compressed data size: 559.63 MB
Compression ratio: 2.8
Rows written: 4009346
Bytes written: 559.63 MB
Average uncompressed throughput: 129.15 MB/s
Average compressed throughput: 45.34 MB/s
 MySQL  localhost:33060+ ssl  JS &amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;圧縮後500MBのデータが12秒でdumpできました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; du -hs  20230828/
535M    20230828/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、MySQL 8.1をインストールします。&lt;/p&gt;
&lt;p&gt;本当はここでアップグレードの互換性チェックを行うべきです。この記事の下の方に記載してあります。&lt;/p&gt;
&lt;p&gt;まずは、apt-cache policy mysql-serverコマンドで、どのパッケージが使われるかをチェックしてみます。&lt;/p&gt;
&lt;p&gt;Ubuntuの8.0がインストール済みですが、8.1が入る事がわかります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; apt-cache policy mysql-server
mysql-server:
  Installed: 8.0.34-0ubuntu0.22.04.1
  Candidate: 8.1.0-1ubuntu22.04
  Version table:
     8.1.0-1ubuntu22.04 500
        500 http://repo.mysql.com/apt/ubuntu jammy/mysql-innovation amd64 Packages
 *** 8.0.34-0ubuntu0.22.04.1 500
        500 http://ftp.tsukuba.wide.ad.jp/Linux/ubuntu jammy-updates/main amd64 Packages
        500 http://ftp.tsukuba.wide.ad.jp/Linux/ubuntu jammy-security/main amd64 Packages
        100 /var/lib/dpkg/status
     8.0.28-0ubuntu4 500
        500 http://ftp.tsukuba.wide.ad.jp/Linux/ubuntu jammy/main amd64 Packages
matsu@dell ~&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ということで、インストール（アップグレード）します。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;sudo apt install mysql-client mysql-server&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; sudo apt install mysql-client mysql-server
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages were automatically installed and are no longer required:
  libcgi-fast-perl libcgi-pm-perl libclone-perl libencode-locale-perl libevent-pthreads-2.1-7 libfcgi-bin libfcgi-perl libfcgi0ldbl libhtml-parser-perl libhtml-tagset-perl libhtml-template-perl libhttp-date-perl
  libhttp-message-perl libio-html-perl liblwp-mediatypes-perl libprotobuf-lite23 libtimedate-perl liburi-perl
Use &apos;sudo apt autoremove&apos; to remove them.
The following additional packages will be installed:
  mysql-common mysql-community-client mysql-community-client-core mysql-community-client-plugins mysql-community-server mysql-community-server-core
The following packages will be REMOVED:
  mysql-client-8.0 mysql-client-core-8.0 mysql-server-8.0 mysql-server-core-8.0
The following NEW packages will be installed:
  mysql-client mysql-community-client mysql-community-client-core mysql-community-client-plugins mysql-community-server mysql-community-server-core
The following packages will be upgraded:
  mysql-common mysql-server
2 upgraded, 6 newly installed, 4 to remove and 0 not upgraded.
Need to get 31.0 MB of archives.
After this operation, 33.0 MB of additional disk space will be used.
Do you want to continue? [Y/n]
Get:1 http://repo.mysql.com/apt/ubuntu jammy/mysql-innovation amd64 mysql-server amd64 8.1.0-1ubuntu22.04 [66.5 kB]
Get:2 http://repo.mysql.com/apt/ubuntu jammy/mysql-innovation amd64 mysql-common amd64 8.1.0-1ubuntu22.04 [67.8 kB]
Get:3 http://repo.mysql.com/apt/ubuntu jammy/mysql-innovation amd64 mysql-community-client-plugins amd64 8.1.0-1ubuntu22.04 [1428 kB]
Get:4 http://repo.mysql.com/apt/ubuntu jammy/mysql-innovation amd64 mysql-community-client-core amd64 8.1.0-1ubuntu22.04 [2087 kB]
Get:5 http://repo.mysql.com/apt/ubuntu jammy/mysql-innovation amd64 mysql-community-client amd64 8.1.0-1ubuntu22.04 [2407 kB]
Get:6 http://repo.mysql.com/apt/ubuntu jammy/mysql-innovation amd64 mysql-client amd64 8.1.0-1ubuntu22.04 [66.5 kB]
Get:7 http://repo.mysql.com/apt/ubuntu jammy/mysql-innovation amd64 mysql-community-server-core amd64 8.1.0-1ubuntu22.04 [24.8 MB]
Get:8 http://repo.mysql.com/apt/ubuntu jammy/mysql-innovation amd64 mysql-community-server amd64 8.1.0-1ubuntu22.04 [78.2 kB]
Fetched 31.0 MB in 7s (4296 kB/s)
Preconfiguring packages ...
(Reading database ... 169877 files and directories currently installed.)
Preparing to unpack .../mysql-server_8.1.0-1ubuntu22.04_amd64.deb ...
Unpacking mysql-server (8.1.0-1ubuntu22.04) over (8.0.34-0ubuntu0.22.04.1) ...
(Reading database ... 169880 files and directories currently installed.)
Removing mysql-server-8.0 (8.0.34-0ubuntu0.22.04.1) ...
update-alternatives: using /etc/mysql/my.cnf.fallback to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Removing mysql-client-8.0 (8.0.34-0ubuntu0.22.04.1) ...
Removing mysql-client-core-8.0 (8.0.34-0ubuntu0.22.04.1) ...
Removing mysql-server-core-8.0 (8.0.34-0ubuntu0.22.04.1) ...
(Reading database ... 169679 files and directories currently installed.)
Preparing to unpack .../0-mysql-common_8.1.0-1ubuntu22.04_amd64.deb ...
Unpacking mysql-common (8.1.0-1ubuntu22.04) over (5.8+1.0.8) ...
Selecting previously unselected package mysql-community-client-plugins.
Preparing to unpack .../1-mysql-community-client-plugins_8.1.0-1ubuntu22.04_amd64.deb ...
Unpacking mysql-community-client-plugins (8.1.0-1ubuntu22.04) ...
Selecting previously unselected package mysql-community-client-core.
Preparing to unpack .../2-mysql-community-client-core_8.1.0-1ubuntu22.04_amd64.deb ...
Unpacking mysql-community-client-core (8.1.0-1ubuntu22.04) ...
Selecting previously unselected package mysql-community-client.
Preparing to unpack .../3-mysql-community-client_8.1.0-1ubuntu22.04_amd64.deb ...
Unpacking mysql-community-client (8.1.0-1ubuntu22.04) ...
Selecting previously unselected package mysql-client.
Preparing to unpack .../4-mysql-client_8.1.0-1ubuntu22.04_amd64.deb ...
Unpacking mysql-client (8.1.0-1ubuntu22.04) ...
Selecting previously unselected package mysql-community-server-core.
Preparing to unpack .../5-mysql-community-server-core_8.1.0-1ubuntu22.04_amd64.deb ...
Unpacking mysql-community-server-core (8.1.0-1ubuntu22.04) ...
Selecting previously unselected package mysql-community-server.
Preparing to unpack .../6-mysql-community-server_8.1.0-1ubuntu22.04_amd64.deb ...
Unpacking mysql-community-server (8.1.0-1ubuntu22.04) ...
Setting up mysql-common (8.1.0-1ubuntu22.04) ...
Installing new version of config file /etc/mysql/conf.d/mysql.cnf ...                                                                                                                                               [5/678]
Installing new version of config file /etc/mysql/my.cnf.fallback ...
Setting up mysql-community-server-core (8.1.0-1ubuntu22.04) ...
Setting up mysql-community-client-plugins (8.1.0-1ubuntu22.04) ...
Setting up mysql-community-client-core (8.1.0-1ubuntu22.04) ...
Setting up mysql-community-client (8.1.0-1ubuntu22.04) ...
Setting up mysql-client (8.1.0-1ubuntu22.04) ...
Setting up mysql-community-server (8.1.0-1ubuntu22.04) ...
Installing new version of config file /etc/apparmor.d/usr.sbin.mysqld ...
Installing new version of config file /etc/mysql/mysql.cnf ...
Installing new version of config file /etc/mysql/mysql.conf.d/mysqld.cnf ...
update-alternatives: using /etc/mysql/mysql.cnf to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Setting up mysql-server (8.1.0-1ubuntu22.04) ...
Processing triggers for man-db (2.10.2-1) ...
Processing triggers for libc-bin (2.35-0ubuntu3.1) ...
Scanning processes...
Scanning candidates...
Scanning processor microcode...
Scanning linux images...

The processor microcode seems to be up-to-date.

Restarting services...
Service restarts being deferred:
 systemctl restart NetworkManager.service
 systemctl restart networkd-dispatcher.service
 systemctl restart unattended-upgrades.service
 systemctl restart wpa_supplicant.service

No containers need to be restarted.

No user sessions are running outdated binaries.

No VM guests are running outdated hypervisor (qemu) binaries on this host.
matsu@dell ~&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;インストール中に、以下のダイアログが表示されました。稼働中のサービスから接続できなくなるリスクを排除するために、互換性を優先して下を選びました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;チェック&lt;/h3&gt;
&lt;p&gt;ちゃんとインストールが完了したかをチェックします。&lt;/p&gt;
&lt;p&gt;まずは、パッケージが入っているかをチェックしてみます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dpkg -l|grep mysql&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; dpkg -l|grep mysql
ii  mysql-apt-config                      0.8.26-1                                     all          Auto configuration for MySQL APT Repo.
ii  mysql-client                          8.1.0-1ubuntu22.04                           amd64        MySQL Client meta package depending on latest version
ii  mysql-common                          8.1.0-1ubuntu22.04                           amd64        Common files shared between packages
ii  mysql-community-client                8.1.0-1ubuntu22.04                           amd64        MySQL Client
ii  mysql-community-client-core           8.1.0-1ubuntu22.04                           amd64        MySQL Client Core Binaries
ii  mysql-community-client-plugins        8.1.0-1ubuntu22.04                           amd64        MySQL Client plugin
ii  mysql-community-server                8.1.0-1ubuntu22.04                           amd64        MySQL Server
ii  mysql-community-server-core           8.1.0-1ubuntu22.04                           amd64        MySQL Server Core Binaires
ii  mysql-server                          8.1.0-1ubuntu22.04                           amd64        MySQL Server meta package depending on latest version
rc  mysql-server-8.0                      8.0.34-0ubuntu0.22.04.1                      amd64        MySQL database server binaries and system database setup
ii  mysql-shell:amd64                     8.1.1-1ubuntu22.04                           amd64        MySQL Shell (part of MySQL Server) 8.0
rc  php8.0-mysql                          8.0.8-1ubuntu0.3                             amd64        MySQL module for PHP
rc  php8.1-mysql                          8.1.2-1ubuntu2.11                            amd64        MySQL module for PHP
ii  php8.2-mysql                          8.2.9-1+ubuntu22.04.1+deb.sury.org+1         amd64        MySQL module for PHP
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ちゃんとmysql-server 8.1がインストールされていそうです。&lt;/p&gt;
&lt;h3&gt;動いているサーバがMySQL 8.1かをチェック&lt;/h3&gt;
&lt;p&gt;早速mysqlshを使って検証してみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;\sql
SELECT @@version;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;番外編: データのアップグレードができるかチェック&lt;/h3&gt;
&lt;p&gt;本当はアップグレード前にやるべきでしたが、mysql-serverのバージョンアップに当たって問題がないかをチェックするコマンドの紹介です。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;util.checkForServerUpgrade();&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;番外編: mysqlsh&lt;/h3&gt;
&lt;p&gt;mysqlshの使い方は&lt;code&gt;\help&lt;/code&gt;と入力するととても長い説明が表示されますが、一通り読んでおくのが良いと思います。いろいろできるので。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;backup &amp;amp; recoveryに関しては以下の記事が詳しいです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://qiita.com/orakurara/items/9a1b992909794d993761&quot;&gt;https://qiita.com/orakurara/items/9a1b992909794d993761&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;数年ぶりにMySQLをキャッチアップ。。。。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.oracle.com/jp/mysql/heatwave/&quot;&gt;MySQL Heatwave&lt;/a&gt;はすごそう。場合によってはSnowflakeより速いらしい。アーキテクチャはAuroraって感じ。Snowflakeも似たようなものだだし最近のRDBの水平分割の流行りの形ぽい。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mysql.com/jp/products/cluster/&quot;&gt;MySQL Cluster&lt;/a&gt;の構築、運用が格段に楽になっているっぽい。Oracleに買収されて、Oracleの得意としている堅牢性を注入した感じがします。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>deviseはパスワードをどのように安全に保管しているか？</title><link>https://blog.teraren.com/posts/devise-password/</link><guid isPermaLink="true">https://blog.teraren.com/posts/devise-password/</guid><description>pictBLand と pictSQUARE に対する不正アクセスがあり、パスワードがソルトなしの MD5 ハッシュで保存されていたことが 話題になっています。</description><pubDate>Thu, 17 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3行まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Devise は&lt;strong&gt;ソルトとハッシュ値をDBに保存&lt;/strong&gt;している。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pepper(Secret Salt)値はデフォルトでは使われていない&lt;/strong&gt;。安全性を上げたければ追加したほうが良い。&lt;/li&gt;
&lt;li&gt;Devise を使っていればとりあえず安全そう。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;きっかけ&lt;/h2&gt;
&lt;p&gt;pictBLand と pictSQUARE に対する不正アクセスがあり、パスワードがソルトなしの MD5 ハッシュで保存されていたことが &lt;a href=&quot;https://qiita.com/ockeghem/items/d7324d383fb7c104af58&quot;&gt;話題&lt;/a&gt;になっています。&lt;/p&gt;
&lt;p&gt;Ruby on Rails で広く使われている Devise はどのようにパスワードを安全に保管しているのかを確認してみます。&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/heartcombo/devise&quot;&gt;Devise&lt;/a&gt;は、&lt;a href=&quot;https://rubygems.org/gems/devise&quot;&gt;1億6000万以上のダウンロード&lt;/a&gt;を誇るRails向けの認証ミドルウェアです。
暗号化操作のほとんどが抽象化されているため裏で何が起こっているかを使うべきではない言葉なので修正してくださいで使っている場合がほとんどです。&lt;/p&gt;
&lt;p&gt;Devise において、パスワードが保存されているストレージのカラム名は &lt;code&gt;encrypted_password&lt;/code&gt; です。
このカラムには、以下のような文字列が保管されていて、この文字列は一体何を意味しているのか、どの用に使われているのかを説明します。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;$2a$12$GfOja7i1byocYP7XuANk9OqyiE8KJPzG439mk0kZKB1rmggsxOHFu&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Devise は &lt;a href=&quot;https://github.com/bcrypt-ruby/bcrypt-ruby&quot;&gt;Bcrypt&lt;/a&gt;を使用して情報を安全に保存します。
Bcrypt のサイトには、「OpenBSD bcrypt() パスワード ハッシュ アルゴリズムを使用しているため、ユーザーのパスワードの安全なハッシュを簡単に保存できる」と記載されています。&lt;/p&gt;
&lt;p&gt;しかし、このハッシュとは一体何なのでしょうか?どのように機能し、保存されたパスワードをどのように安全性を保つのでしょうか?&lt;/p&gt;
&lt;h2&gt;Deviseにおけるパスワード保存の流れ&lt;/h2&gt;
&lt;p&gt;データベースに保存されているハッシュから暗号化と復号化のプロセスまでを保存されている文字列から逆に辿って検証してみます。&lt;/p&gt;
&lt;p&gt;まず、データベースに保存されている値を取得します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;irb&amp;gt; User.first.encrypted_password
=&amp;gt; &quot;$2a$12$GfOja7i1byocYP7XuANk9OqyiE8KJPzG439mk0kZKB1rmggsxOHFu&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この文字列、&lt;code&gt;$2a$12$GfOja7i1byocYP7XuANk9OqyiE8KJPzG439mk0kZKB1rmggsxOHFu&lt;/code&gt; は実際にはいくつかのコンポーネントで構成されています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scheme (&lt;code&gt;2a&lt;/code&gt;) - ハッシュの生成に使用される &lt;code&gt;bcrypt()&lt;/code&gt; アルゴリズムのバージョン&lt;/li&gt;
&lt;li&gt;Cost (&lt;code&gt;12&lt;/code&gt;) - ハッシュの作成に使用されるコスト係数&lt;/li&gt;
&lt;li&gt;Salt (&lt;code&gt;GfOja7i1byocYP7XuANk9O&lt;/code&gt;) - パスワードと組み合わせると一意になるランダムな文字列 (22文字)&lt;/li&gt;
&lt;li&gt;Checksum (&lt;code&gt;qyiE8KJPzG439mk0kZKB1rmggsxOHFu&lt;/code&gt;) - 保存されている実際のハッシュ部分 (31文字)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このフォーマットは&lt;a href=&quot;https://en.wikipedia.org/wiki/Bcrypt#Versioning_history&quot;&gt;MCF&lt;/a&gt;(Modular Crypt Format)です。
UNIXの/etc/shadowなどにも使われているメジャーなフォーマットです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/component.png&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最後の3つのパラメーターを調べてみましょう。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deviseを使用する場合、値は&lt;a href=&quot;https://github.com/heartcombo/devise/blob/715192a7709a4c02127afb067e66230061b82cf2/lib/devise.rb#L74&quot;&gt;ストレッチ&lt;/a&gt;Costと呼ばれるクラス変数によって設定され、デフォルト値は &lt;code&gt;12&lt;/code&gt; (&lt;a href=&quot;https://github.com/heartcombo/devise/commit/63ea6533de34b6457b31d375fb30cd44d6403616&quot;&gt;2019年に11から12になりました&lt;/a&gt;)です。パスワードをハッシュする回数を指定します。&lt;/li&gt;
&lt;li&gt;Saltは、元のパスワードと組み合わせるために使用されるランダムな文字列です。これは、同じパスワードが暗号化されて保存されるときに異なる値になる原因です。(なぜそれが重要なのか、またレインボーテーブル攻撃とは何なのかについては、&lt;a href=&quot;https://www.beyondidentity.com/glossary/rainbow-table-attack&quot;&gt;こちら&lt;/a&gt;を参照してください。)&lt;/li&gt;
&lt;li&gt;Checksumは、Saltと結合された後に実際に生成されたパスワードのハッシュです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ユーザーがアプリに登録するときは、パスワードを設定する必要があります。
このパスワードがデータベースに保存される前に、前述のコスト要因を考慮して、&lt;code&gt;BCrypt::Engine.generate_salt(cost)&lt;/code&gt; によってランダムなSaltが生成されます。
(注: &lt;a href=&quot;https://github.com/heartcombo/devise/blob/715192a7709a4c02127afb067e66230061b82cf2/lib/devise.rb#L155&quot;&gt;pepperクラス変数値&lt;/a&gt;が設定されている場合、Salt処理を行う前にその値がパスワードに追加されます。)&lt;/p&gt;
&lt;p&gt;そのSalt (例: &lt;code&gt;$2a$12$GfOja7i1byocYP7XuANk9O&lt;/code&gt;)を使用して、生成されたSaltとユーザーが入力したパスワードを使用して保存される最終ハッシュを計算します。&lt;code&gt;BCrypt::Engine.hash_secret(パスワード, Salt)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;その結果(例: &lt;code&gt;$2a$12$GfOja7i1byocYP7XuANk9OqyiE8KJPzG439mk0kZKB1rmggsxOHFu&lt;/code&gt;)がデータベースの &lt;code&gt;encrypted_password&lt;/code&gt; カラムに保存されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/hash.png&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;BCrypt::Password.create&lt;/code&gt; が &lt;code&gt;BCrypt::Engine.generate_salt(cost)&lt;/code&gt; によって呼ばれます。しかし、このハッシュが不可逆であり、Saltがによる呼び出しでランダムに生成される場合、それをユーザーのサインイン時にどのようにつかわれるのでしょうか？&lt;/p&gt;
&lt;p&gt;そこで、これらのさまざまなハッシュ コンポーネントが役立ちます。ユーザーがサインインするために指定したメールアドレスに一致するレコードが見つかった後、暗号化されたパスワード(=&lt;code&gt;encrypted_password&lt;/code&gt; の値)が取得され、上記のように5つのコンポーネント (&lt;code&gt;Bcrypt version&lt;/code&gt;, &lt;code&gt;Cost&lt;/code&gt;, &lt;code&gt;Salt&lt;/code&gt;, &lt;code&gt;Checksum&lt;/code&gt;) に分割されます。&lt;/p&gt;
&lt;p&gt;この最初の準備が完了したら、次の順番で処理が行われます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;入力されたパスワードを取得します(&lt;code&gt;ThisIsWeakPassword&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;保存されているパスワードのSaltを取得します(&lt;code&gt;$2a$12$GfOja7i1byocYP7XuANk9O&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;同じBcryptバージョンとコスト係数を使用して、パスワードとSaltからハッシュを生成します(&lt;code&gt;BCrypt::Engine.hash_secret(&apos;ThisIsWeakPassword&apos;, “$2a$12$GfOja7i1byocYP7XuANk9O”)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;保存されているハッシュがステップ3で計算されたものと同じかどうかを検証します(&lt;code&gt;$2a$12$GfOja7i1byocYP7XuANk9OqyiE8KJPzG439mk0kZKB1rmggsxOHFu&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これにより、Deviseはパスワードを安全に保存し、データベースが侵害された場合でもさまざまな攻撃からユーザーを保護します。&lt;/p&gt;
&lt;p&gt;上記の一連の流れを &lt;code&gt;rails console&lt;/code&gt; で実行すると以下のようになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;irb(main):042:0&amp;gt; user = User.first
  User Load (0.2ms)  SELECT &quot;users&quot;.* FROM &quot;users&quot; ORDER BY &quot;users&quot;.&quot;id&quot; ASC LIMIT ?  [[&quot;LIMIT&quot;, 1]]
=&amp;gt; #&amp;lt;User id: 1, email: &quot;foo@example.com&quot;, created_at: &quot;2023-08-17 11:27:10.671417000 +0000&quot;, updated_at: &quot;2023-08-17 11:32:20.492265000 +0000&quot;&amp;gt;
irb(main):043:0&amp;gt; salt = user.encrypted_password[0, 29]
=&amp;gt; &quot;$2a$12$GfOja7i1byocYP7XuANk9O&quot;
irb(main):044:0&amp;gt; BCrypt::Engine.hash_secret(&apos;ThisIsWeakPassword&apos;, salt) == user.encrypted_password
=&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;pepperに関して&lt;/h2&gt;
&lt;p&gt;Deviseではデフォルトでpepperは使われていません。pepperとは、Secret Saltとも呼ばれます。
Saltはレコードごとに生成されるランダムな数値ですが、pepperシステム固有の値で、データベースとは別のストレージに保管するべき秘密の文字列です。&lt;/p&gt;
&lt;p&gt;使い方は、ユーザが入力した文字列に対してpepperを連結して利用します。それにより、DBの値が第三者に流出してしまった場合でも、ハッシュによる総当たりを防ぐための仕組みで、より安全なパスワード運用を行えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/pepper.png&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Deviseではpepperの部分はデフォルトではコメントアウトされているので利用したい場合はコメントインをする必要があります。&lt;/p&gt;
&lt;p&gt;https://github.com/heartcombo/devise/blob/main/lib/generators/templates/devise.rb#L128-L129&lt;/p&gt;
&lt;p&gt;Deviseの&lt;a href=&quot;https://github.com/heartcombo/devise/blob/main/README.md#configuring-models&quot;&gt;README&lt;/a&gt;でもpepperに関しては殆ど触れられていません。deviseのセットアップドキュメントを見ても殆ど触れられていることはありません。&lt;/p&gt;
&lt;p&gt;initializerの設定ファイルを眺めていないと気ずけ無いですが設定しておくことをおすすめします。
Deviseのデフォルトでは、 &lt;code&gt;SecureRandom.hex(64)&lt;/code&gt; で生成された値が入ります。&lt;/p&gt;
&lt;p&gt;値の例はこのようになります。&lt;code&gt;59ef98ac93a05c22d065dab431e6fc23a8110577c0a18c7e4ac603cdd7f4d2c327e6f6350ef0721de280caadc348c8a3cd04199708e546775627067a2c5d9951&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Strechの値の運用&lt;/h2&gt;
&lt;p&gt;bcryptの計算難易度を調整するパラメータが4年前に &lt;code&gt;11&lt;/code&gt; から &lt;code&gt;12&lt;/code&gt; に変更されました。
4年より前に運用しだして、設定ファイルを更新していない場合は &lt;code&gt;11&lt;/code&gt; になっているので &lt;code&gt;12&lt;/code&gt; 以上に変更することをおすすめします。&lt;/p&gt;
&lt;p&gt;https://github.com/heartcombo/devise/blob/main/lib/generators/templates/devise.rb#L126&lt;/p&gt;
&lt;h3&gt;ベンチマーク&lt;/h3&gt;
&lt;p&gt;このStrechの値に対して計算コストは指数的に増加します。それにより、1回のパスワード検証コストを多くしてクラックされづらいようにします。&lt;/p&gt;
&lt;p&gt;本当に指数的に計算時間が増加するかを検証してみます。&lt;/p&gt;
&lt;p&gt;まずは以下のように検証用のコードを書いてみます。20回のハッシュ計算をします。costの値は運用する可能性がある5から15を利用しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require &apos;bcrypt&apos;
require &apos;benchmark&apos;

results = {}

(5..15).each do |cost|
  results[i] = Benchmark.measure {
    20.times do
      salt = BCrypt::Engine.generate_salt(cost)
      BCrypt::Engine.hash_secret(&apos;password&apos;, salt)
    end
  }.real
end

results.each do |key, value|
  puts &quot;Cost #{key} (20 iterations): #{value.round(5)} seconds&quot;
end

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記のコードの結果は以下のようになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Cost 5 (20 iterations): 0.05674 seconds
Cost 6 (20 iterations): 0.07473 seconds
Cost 7 (20 iterations): 0.14307 seconds
Cost 8 (20 iterations): 0.28359 seconds
Cost 9 (20 iterations): 0.56139 seconds
Cost 10 (20 iterations): 1.12196 seconds
Cost 11 (20 iterations): 2.24226 seconds
Cost 12 (20 iterations): 4.47873 seconds
Cost 13 (20 iterations): 8.95266 seconds
Cost 14 (20 iterations): 18.34221 seconds
Cost 15 (20 iterations): 36.58495 seconds


38.0|
36.0|                               *
34.0|
32.0|
30.0|
28.0|
26.0|
24.0|
22.0|
20.0|
18.0|                            *
16.0|
14.0|
12.0|
10.0|
 8.0|                         *
 6.0|
 4.0|                      *
 2.0|                *  *
 0.0+-*--*--*--*--*-------------------
      5  6  7  8  9 10 11 12 13 14 15

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例えば、costが &lt;code&gt;12&lt;/code&gt; の場合は1回の計算に&lt;strong&gt;約0.22秒&lt;/strong&gt;かかる事がわかり、そこそこ時間がかかります。
(測定環境は、Apple M1 Pro上でDocker上のmruby 3.0.3p157になります)&lt;/p&gt;
&lt;p&gt;saltの算出時間は、2×10⁻⁴ 秒程度なので無視できるくらい小さく、costの値に関係なくO(1)になります。&lt;/p&gt;
&lt;p&gt;それに付随して、rspecなどの静的テストのときに1回の計算ごとに時間をかけていたらテストの実行時間が長くなってしまうのでDeviseの初期設定ではRails.envが &lt;code&gt;test&lt;/code&gt; の際にはcostを &lt;code&gt;1&lt;/code&gt; で実行してテストの実行時間を短くしています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;config.stretches = Rails.env.test? ? 1 : 10
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;参考URL&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;How Devise keeps your Rails app passwords safe
&lt;ul&gt;
&lt;li&gt;https://www.freecodecamp.org/news/how-does-devise-keep-your-passwords-safe-d367f6e816eb/&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Amazon Linux 2にfishを入れる方法</title><link>https://blog.teraren.com/posts/amazon-linux2-fish/</link><guid isPermaLink="true">https://blog.teraren.com/posts/amazon-linux2-fish/</guid><description>現在の fish の 最新バージョンは `3.6.1` になっています。</description><pubDate>Fri, 04 Aug 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;まとめ&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Amazon Linux 2 の yum 経由でインストールされる fish がのバージョンが &lt;code&gt;2.3&lt;/code&gt; と 7 年前にリリースされたバージョンなので新しいバージョンを利用しようとしました。&lt;/li&gt;
&lt;li&gt;簡単にはインストールできなかったので、試行錯誤した結果を掲載しておきます。&lt;/li&gt;
&lt;li&gt;結果としては、Cent OS 7 用の rpm パッケージを直接入れるのが一番楽です。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Amazon Linux 2023&lt;/code&gt; へのインストール記事は &lt;a href=&quot;https://zenn.dev/matsubokkuri/articles/amazon-linux-2023-fish&quot;&gt;こちら&lt;/a&gt;です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;現在の fish の &lt;a href=&quot;https://fishshell.com/&quot;&gt;最新バージョン&lt;/a&gt;は &lt;code&gt;3.6.1&lt;/code&gt; になっています。&lt;/p&gt;
&lt;p&gt;それに対して、Amazon Linux 2 で利用している RHEL からインストールされる fish のバージョンは、&lt;code&gt;2.3.1&lt;/code&gt; となっています。
これは 2016 年 11 月 8 日にリリースされたバージョンなのでかなり古いです。&lt;/p&gt;
&lt;p&gt;(そもそも、Amazon Linux 2 は 2023 年 6 月 30 日までのサポートされないので注意です。)&lt;/p&gt;
&lt;p&gt;そこで、tmux のオフィシャルサイトにある rpm パッケージ経由のインストール方法を試してみました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/tmux-centos.png&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Amazon Linux 2 の RHEL のバージョンは 7 なので、&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ec2-user@ip-172-26-15-209 ~]$ rpm -E %{rhel}
7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cent OSの7のrpm repositoryを使ってインストールを試みましたが、glibcの依存関係を満たせないので解決が困難そうです。&lt;/p&gt;
&lt;p&gt;yum repositoryを追加してインストールしようとした際のエラーの内容を以下に記載しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-172-26-15-209 ec2-user]# cd /etc/yum.repos.d/
[root@ip-172-26-15-209 yum.repos.d]# wget https://download.opensuse.org/repositories/shells:fish:release:3/CentOS_7/shells:fish:release:3.repo
--2023-08-04 03:00:38--  https://download.opensuse.org/repositories/shells:fish:release:3/CentOS_7/shells:fish:release:3.repo
Resolving download.opensuse.org (download.opensuse.org)... 2001:67c:2178:8::13, 195.135.221.134
Connecting to download.opensuse.org (download.opensuse.org)|2001:67c:2178:8::13|:443...
connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://download.opensuse.org/repositories/shells:fish:release:/3/CentOS_7/shells:fish:release:3.repo [following]
--2023-08-04 03:00:39--  https://download.opensuse.org/repositories/shells:fish:release:/3/CentOS_7/shells:fish:release:3.repo
Reusing existing connection to [download.opensuse.org]:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://download.opensuse.org/repositories/shells:fish:/release:/3/CentOS_7/shells:fish:release:3.repo [following]
--2023-08-04 03:00:40--  https://download.opensuse.org/repositories/shells:fish:/release:/3/CentOS_7/shells:fish:release:3.repo
Reusing existing connection to [download.opensuse.org]:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://download.opensuse.org/repositories/shells:/fish:/release:/3/CentOS_7/shells:fish:release:3.repo [following]
--2023-08-04 03:00:40--  https://download.opensuse.org/repositories/shells:/fish:/release:/3/CentOS_7/shells:fish:release:3.repo
Reusing existing connection to [download.opensuse.org]:443.
HTTP request sent, awaiting response... 200 OK
Length: 299 [application/x-download]
Saving to: &apos;shells:fish:release:3.repo&apos;

100%[=====================================================================================================================================================================================================&amp;gt;] 299         --.-K/s   in 0s

2023-08-04 03:00:40 (46.6 MB/s) - &apos;shells:fish:release:3.repo&apos; saved [299/299]

[root@ip-172-26-15-209 yum.repos.d]# yum install fish
Failed to set locale, defaulting to C
Loaded plugins: etckeeper, extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                                                                                                                              | 3.7 kB  00:00:00
shells_fish_release_3                                                                                                                                                                                                   | 1.7 kB  00:00:00
Not using downloaded shells_fish_release_3/repomd.xml because it is older than what we have:
  Current   : Sat Jul 29 04:23:36 2023
  Downloaded: Fri Apr 14 08:56:31 2023
290 packages excluded due to repository priority protections
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package fish.x86_64 0:3.6.1-1.2 will be updated
---&amp;gt; Package fish.x86_64 0:3.6.1-1.5 will be an update
--&amp;gt; Processing Dependency: libc.so.6(GLIBC_2.34)(64bit) for package: fish-3.6.1-1.5.x86_64
--&amp;gt; Processing Dependency: libstdc++.so.6(GLIBCXX_3.4.29)(64bit) for package: fish-3.6.1-1.5.x86_64
--&amp;gt; Processing Dependency: libstdc++.so.6(CXXABI_1.3.13)(64bit) for package: fish-3.6.1-1.5.x86_64
--&amp;gt; Processing Dependency: libm.so.6(GLIBC_2.29)(64bit) for package: fish-3.6.1-1.5.x86_64
--&amp;gt; Finished Dependency Resolution
Error: Package: fish-3.6.1-1.5.x86_64 (shells_fish_release_3)
           Requires: libstdc++.so.6(GLIBCXX_3.4.29)(64bit)
Error: Package: fish-3.6.1-1.5.x86_64 (shells_fish_release_3)
           Requires: libc.so.6(GLIBC_2.34)(64bit)
Error: Package: fish-3.6.1-1.5.x86_64 (shells_fish_release_3)
           Requires: libm.so.6(GLIBC_2.29)(64bit)
Error: Package: fish-3.6.1-1.5.x86_64 (shells_fish_release_3)
           Requires: libstdc++.so.6(CXXABI_1.3.13)(64bit)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;また、&lt;a href=&quot;https://qiita.com/kiwatchi1991/items/56adb6c1d0d38e82a66b&quot;&gt;こちらの記事&lt;/a&gt;を見る感じではLinuxにhomebrewを入れてhomebrew経由でfishをインストールすることによって最新のfishがインストールできそうです。しかしながら、fishのためだけにhomebrewをインストールしたくはありません。&lt;/p&gt;
&lt;p&gt;色々試行錯誤した結果、fishのオフィシャルサイトが直接提供しているCent OS 7向けのrpmパッケージをインストールしたら比較的すんなりインストールできたので紹介します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/tmux-rpm.png&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;[ec2-user@ip-172-26-15-209 ~]$ sudo yum install pcre2-devel
Failed to set locale, defaulting to C
Loaded plugins: etckeeper, extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                                                                                                                                                                                                                                                                                                                                                                              | 3.7 kB  00:00:00
290 packages excluded due to repository priority protections
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package pcre2-devel.x86_64 0:10.23-11.amzn2.0.1 will be installed
--&amp;gt; Processing Dependency: pcre2-utf32(x86-64) = 10.23-11.amzn2.0.1 for package: pcre2-devel-10.23-11.amzn2.0.1.x86_64
--&amp;gt; Processing Dependency: pcre2-utf16(x86-64) = 10.23-11.amzn2.0.1 for package: pcre2-devel-10.23-11.amzn2.0.1.x86_64
--&amp;gt; Processing Dependency: libpcre2-32.so.0()(64bit) for package: pcre2-devel-10.23-11.amzn2.0.1.x86_64
--&amp;gt; Processing Dependency: libpcre2-16.so.0()(64bit) for package: pcre2-devel-10.23-11.amzn2.0.1.x86_64
--&amp;gt; Running transaction check
---&amp;gt; Package pcre2-utf16.x86_64 0:10.23-11.amzn2.0.1 will be installed
---&amp;gt; Package pcre2-utf32.x86_64 0:10.23-11.amzn2.0.1 will be installed
--&amp;gt; Finished Dependency Resolution

Dependencies Resolved

===============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
 Package                                                                                                              Arch                                                                                                            Version                                                                                                                        Repository                                                                                                           Size
===============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
Installing:
 pcre2-devel                                                                                                          x86_64                                                                                                          10.23-11.amzn2.0.1                                                                                                             amzn2-core                                                                                                          547 k
Installing for dependencies:
 pcre2-utf16                                                                                                          x86_64                                                                                                          10.23-11.amzn2.0.1                                                                                                             amzn2-core                                                                                                          192 k
 pcre2-utf32                                                                                                          x86_64                                                                                                          10.23-11.amzn2.0.1                                                                                                             amzn2-core                                                                                                          183 k

Transaction Summary
===============================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
Install  1 Package (+2 Dependent packages)

Total download size: 923 k
Installed size: 2.6 M
Is this ok [y/d/N]: ^Y
Is this ok [y/d/N]: y
Downloading packages:
(1/3): pcre2-devel-10.23-11.amzn2.0.1.x86_64.rpm                                                                                                                                                                                                                                                                                                                                                                                                                        | 547 kB  00:00:00
(2/3): pcre2-utf16-10.23-11.amzn2.0.1.x86_64.rpm                                                                                                                                                                                                                                                                                                                                                                                                                        | 192 kB  00:00:00
(3/3): pcre2-utf32-10.23-11.amzn2.0.1.x86_64.rpm                                                                                                                                                                                                                                                                                                                                                                                                                        | 183 kB  00:00:00
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total                                                                                                                                                                                                                                                                                                                                                                                                                                                          3.1 MB/s | 923 kB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
etckeeper: pre transaction commit
  Installing : pcre2-utf16-10.23-11.amzn2.0.1.x86_64                                                                                                                                                                                                                                                                                                                                                                                                                                       1/3
  Installing : pcre2-utf32-10.23-11.amzn2.0.1.x86_64                                                                                                                                                                                                                                                                                                                                                                                                                                       2/3
  Installing : pcre2-devel-10.23-11.amzn2.0.1.x86_64                                                                                                                                                                                                                                                                                                                                                                                                                                       3/3
etckeeper: post transaction commit
  Verifying  : pcre2-utf32-10.23-11.amzn2.0.1.x86_64                                                                                                                                                                                                                                                                                                                                                                                                                                       1/3
  Verifying  : pcre2-utf16-10.23-11.amzn2.0.1.x86_64                                                                                                                                                                                                                                                                                                                                                                                                                                       2/3
  Verifying  : pcre2-devel-10.23-11.amzn2.0.1.x86_64                                                                                                                                                                                                                                                                                                                                                                                                                                       3/3

Installed:
  pcre2-devel.x86_64 0:10.23-11.amzn2.0.1

Dependency Installed:
  pcre2-utf16.x86_64 0:10.23-11.amzn2.0.1                                                                                                                                                                                                        pcre2-utf32.x86_64 0:10.23-11.amzn2.0.1

Complete!
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[ec2-user@ip-172-26-15-209 ~]$ sudo rpm -Uvh https://download.opensuse.org/repositories/shells:/fish:/release:/3/CentOS_7/x86_64/fish-3.6.1-1.2.x86_64.rpm
Retrieving https://download.opensuse.org/repositories/shells:/fish:/release:/3/CentOS_7/x86_64/fish-3.6.1-1.2.x86_64.rpm
warning: /var/tmp/rpm-tmp.WSduVM: Header V3 RSA/SHA256 Signature, key ID d880c8e4: NOKEY
Preparing...                          ################################# [100%]
Updating / installing...
   1:fish-3.6.1-1.2                   ################################# [100%]
[ec2-user@ip-172-26-15-209 ~]$ which fish
/usr/bin/fish

&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;確認&lt;/h1&gt;
&lt;p&gt;無事入りました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[ec2-user@ip-172-26-15-209 ~]$ /usr/bin/fish --version
fish, version 3.6.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかしながら、rpm のリポジトリを設定したわけではないので自動更新は行われません。&lt;/p&gt;
&lt;h1&gt;余談&lt;/h1&gt;
&lt;p&gt;tmux も最新をインストールしてターミナル関連のバージョンを一新しました。&lt;/p&gt;
&lt;p&gt;ついでに、tmux と fish で powerline テーマを使って統一感を出しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/08/tmux-fish.png&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最新の設定ファイルは以下においてあります。
https://github.com/matsubo/matsu-shell-setting&lt;/p&gt;
</content:encoded></item><item><title>Ubuntu live patchを導入してみた</title><link>https://blog.teraren.com/posts/ubuntu-live-patch/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ubuntu-live-patch/</guid><description>Ubuntuカーネルパッチを再起動なしに適用できるLivepatchの仕組みと、Ubuntu Proアカウントでのトークン取得から有効化コマンド実行までの導入手順を解説します。</description><pubDate>Wed, 21 Jun 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Livepatchとは&lt;/h2&gt;
&lt;p&gt;Livepatchはその名の通り、Ubuntu(Linux系のos)で&lt;code&gt;apt-get upgrade&lt;/code&gt;された時に、kernelパッチを更新するためにーサーバーを再起動せずに適用できます。&lt;/p&gt;
&lt;p&gt;Ubuntu Pro向けなのですが、3ホストまでは無料で利用できるので個人利用をする程度ならちょうど良いです。&lt;/p&gt;
&lt;p&gt;live patchの仕組みは&lt;a href=&quot;https://pc.watch.impress.co.jp/img/pcw/docs/1447/406/html/livepatch_o.png.html&quot;&gt;こちらのページ&lt;/a&gt;の図がわかりやすいです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/06/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;起動中のkernelにパッチを適用するとなると、実行中のメモリの内容を変更することになってしまうけど、どうやっているのか不思議に思っていました。&lt;/p&gt;
&lt;p&gt;上記のように、新たなコードを別のメモリに確保した上で、実行コードをすげ替えてしまうというやり方であれば納得です。&lt;/p&gt;
&lt;p&gt;デメリットとしては抽象化のオーバーヘッドが増えるのと、パッチを適用していくとメモリのフラグメンテーションや無駄なメモリアロケーションが増える可能性がありそうです。&lt;/p&gt;
&lt;p&gt;また、Livepatch自体も万能ではなくてこの用に抽象化された部分の変更でなければkernelの再実行＝OSの再機動が必要になります。&lt;a href=&quot;https://cpoint-lab.co.jp/article/202002/13776/&quot;&gt;詳細&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;アカウント登録&lt;/h2&gt;
&lt;p&gt;利用する際に使うtokenはWebサイト上で発行されるのでアカウント登録をしてトークンを取得します。&lt;/p&gt;
&lt;p&gt;ユーザ登録後、&lt;a href=&quot;https://ubuntu.com/pro/dashboard&quot;&gt;このページ&lt;/a&gt;を開くとトークンが表示されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/06/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;Ubuntu 22.04で実行しています。&lt;/p&gt;
&lt;p&gt;基本的に、上記のサイトで表示されているコマンドを1発実行すれば完了します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~/&amp;gt; sudo pro attach &amp;lt;token&amp;gt;
[sudo] password for matsu: 
Enabling default service esm-apps
Updating package lists
Ubuntu Pro: ESM Apps enabled
Enabling default service esm-infra
Updating package lists
Ubuntu Pro: ESM Infra enabled
Enabling default service livepatch
Installing snapd
Updating package lists
Installing canonical-livepatch snap
Canonical livepatch enabled.
Unable to determine current instance-id
This machine is now attached to &apos;Ubuntu Pro - free personal subscription&apos;

SERVICE          ENTITLED  STATUS    DESCRIPTION
esm-apps         yes       enabled   Expanded Security Maintenance for Applications
esm-infra        yes       enabled   Expanded Security Maintenance for Infrastructure
livepatch        yes       enabled   Canonical Livepatch service
realtime-kernel  yes       disabled  Ubuntu kernel with PREEMPT_RT patches integrated

NOTICES
Operation in progress: pro attach

Enable services with: pro enable &amp;lt;service&amp;gt;

     Account: matsubokkuri@example.com
Subscription: Ubuntu Pro - free personal subscription

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;live patchのステータス表示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~/&amp;gt; sudo ua status
[sudo] password for matsu:
SERVICE          ENTITLED  STATUS    DESCRIPTION
esm-apps         yes       enabled   Expanded Security Maintenance for Applications
esm-infra        yes       enabled   Expanded Security Maintenance for Infrastructure
livepatch        yes       enabled   Canonical Livepatch service
realtime-kernel  yes       disabled  Ubuntu kernel with PREEMPT_RT patches integrated
usg              yes       disabled  Security compliance and audit tools

Enable services with: pro enable &amp;lt;service&amp;gt;

     Account: matsubokkuri@example.com
Subscription: Ubuntu Pro - free personal subscription

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;livepatchがenabledになっているので設定は完了しているようです。&lt;/p&gt;
&lt;p&gt;セキュリティのステータス表示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; sudo ua security-status
997 packages installed:
    853 packages from Ubuntu Main/Restricted repository
    101 packages from Ubuntu Universe/Multiverse repository
    25 packages from third parties
    18 packages no longer available for download

To get more information about the packages, run
    pro security-status --help
for a list of available options.

This machine is attached to an Ubuntu Pro subscription.

Main/Restricted packages are receiving security updates from
Ubuntu Pro with &apos;esm-infra&apos; enabled until 2032.

Universe/Multiverse packages are receiving security updates from
Ubuntu Pro with &apos;esm-apps&apos; enabled until 2032. You have received 13 security
updates.

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;この設定が影響しているかどうかわからないのですが、Dockerが調子悪くなりました。。。docker killでコンテナを停止できなくなってしまったりしました。&lt;/p&gt;
&lt;p&gt;スタートはできるからまぁ、ギリギリサービスは動くのですが。。。困りものです。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;kernel関連のzero day attackに対して安全に運用できるようになりました。&lt;/li&gt;
&lt;li&gt;仮想環境でサービスを運用しているホストに導入すると再機動の回数を減らせて良いです。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Cloudflare WarpをUbuntuで実行【無料VPN】</title><link>https://blog.teraren.com/posts/cloudflare-ubuntu-vpn/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cloudflare-ubuntu-vpn/</guid><description>こちらの手順通りで大丈夫でした。</description><pubDate>Wed, 07 Jun 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Linux のホストで気軽に IPv4 のグローバルアドレスを変えたかったので Cloudflare の warp を使ってみました。&lt;/li&gt;
&lt;li&gt;Ubuntu だと簡単に導入、接続できました。無料です。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/warp-client/get-started/linux/&quot;&gt;Cloudflareのドキュメント&lt;/a&gt;ではデスクトップ用(GUI)のアプリしか提供指定なさそうですが実際にはCLIによるプログラムが提供されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pkg.cloudflareclient.com/install&quot;&gt;こちら&lt;/a&gt;の手順通りで大丈夫でした。&lt;/p&gt;
&lt;p&gt;GPG を登録&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ curl https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;apt sourceを追加&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ echo &quot;deb [arch=amd64 signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main&quot; | sudo tee /etc/apt/sources.list.d/cloudflare-client.list
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ sudo apt update
$ sudo apt install warp-cli
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ warp-cli register
$ warp-cli connect
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Warpで接続できているかを検証するためのコマンドがこちらです。
&lt;code&gt;warp=on&lt;/code&gt; になっていれば成功です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -s https://www.cloudflare.com/cdn-cgi/trace/|grep warp
warp=on
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IPv4とIPv6のアドレスで外に出ていけます。すばらしいです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ curl -4 https://kakunin.teraren.com
104.28.211.105
$ curl -6 https://kakunin.teraren.com
2a09:bac1:3b20:10::16:xxxx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;切断するときのコマンドはこちら。リモートで接続している場合は切断される場合があるのでご注意ください。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ warp-cli disconnect
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;その他&lt;/h2&gt;
&lt;p&gt;統計を出力する場合はこんな感じ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ warp-cli warp-stats
Endpoints: 0.0.0.0, 2606:4700:d0::a29f:xxxx
Time since last handshake: 43s
Sent: 305.1MB; Received: 84.5MB
Estimated latency: 12ms
Estimated loss: 0.00%;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;回線のベンチマークもしてみます。遅い無料のOpen Proxyに比べれば十分です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ speedtest-cli
Retrieving speedtest.net configuration...
Testing from Cloudflare (104.28.211.105)...
Retrieving speedtest.net server list...
Selecting best server based on ping...
Hosted by Alyans Telekom (Vladivostok) [9716.25 km]: 273.563 ms
Testing download speed................................................................................
Download: 9.12 Mbit/s
Testing upload speed......................................................................................................
Upload: 18.09 Mbit/s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ルートの設定も行えるオプションがあるので細かいトラフィックの制御も行えそうです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell:~$ warp-cli help
CLI to the WARP service daemon

Usage: warp-cli [OPTIONS] &amp;lt;COMMAND&amp;gt;

Commands:
  register                     Register with the WARP API, replacing any existing registration (Must be run before first connection!)
  teams-enroll                 Enroll with Cloudflare for Teams
  delete                       Delete current registration
  rotate-keys                  Generate a new key-pair, keeping the current registration
  status                       Ask the daemon to send the current status
  warp-stats                   Retrieve the stats for the current WARP connection
  warp-dns-stats               Retrieve the DNS stats for the current WARP connection
  settings                     Retrieve the current application settings
  connect                      Connect to WARP whenever possible [aliases: enable-always-on]
  disconnect                   Disconnect from WARP [aliases: disable-always-on]
  disable-wifi                 Automatically disable WARP on Wi-Fi networks (disabled for Zero Trust customers)
  enable-wifi                  Allow WARP on Wi-Fi networks (disabled for Zero Trust customers)
  disable-ethernet             Automatically disable WARP on ethernet networks (disabled for Zero Trust customers)
  enable-ethernet              Allow WARP on ethernet networks (disabled for Zero Trust customers)
  add-trusted-ssid             Add a trusted Wi-Fi network for which WARP will be automatically disconnected
  remove-trusted-ssid          Remove a trusted Wi-Fi network
  exclude-private-ips          Exclude private IP ranges from tunnel
  enable-dns-log               Enable DNS logging (Use with the -l option)
  disable-dns-log              Disable DNS logging
  account                      Display the account associated with the current registration
  devices                      Display the list of devices associated with the current registration
  network                      Display the current network information
  get-virtual-networks         List the available virtual networks
  set-virtual-network          Set the currently connected virtual network via the id from get-virtual-networks
  set-mode                     Set the mode
  set-families-mode            Set the families mode
  set-license                  Attach the current registration to a different account using a license key
  set-gateway                  Force the app to use the specified Gateway ID for DNS queries
  clear-gateway                Clear the Gateway ID
  set-custom-endpoint          Force the client to connect to the specified IP:PORT endpoint (Zero Trust customers must run this command as a privileged user)
  clear-custom-endpoint        Remove the custom endpoint setting
  add-excluded-route           Add an excluded IP
  remove-excluded-route        Remove an excluded IP
  get-excluded-routes          Get the list of excluded routes
  get-included-routes          Get the list of included routes
  get-excluded-hosts           Get the list of excluded hosts
  get-included-hosts           Get the list of included hosts
  add-excluded-host            Add an excluded host
  remove-excluded-host         Remove an excluded host
  add-fallback-domain          Add a domain that should be resolved with the fallback resolver instead of WARP&apos;s
  remove-fallback-domain       Stop a domain from being resolved with the fallback resolver
  get-fallback-domains         Get the list of domains that go to the fallback resolver
  restore-fallback-domains     Restore the list of fallback resolver domains to its default value
  get-device-posture           Get the current device posture
  override                     Temporarily override MDM policies that require the client to stay enabled
  set-proxy-port               Set the listening port for WARP proxy (127.0.0.1:{port})
  is-mode-switch-allowed       Outputs true if Teams users should be able to change connection mode, or false if not
  reset-settings               Restore settings to default
  get-organization             Get the name of the Teams organization currently in settings
  access-reauth                Force refresh authentication with Cloudflare Access
  get-support-url              Get the support url for the current Teams organization
  get-pause-end                Retrieve the pause end time
  get-override-end             Retrieve the admin override end time
  disable-connectivity-checks  Disable the runtime connectivity checks
  enable-connectivity-checks   Enable the runtime connectivity checks
  dump-excluded-routes         Get split tunnel routing dump. For include-only mode, this shows routes NOT included
  get-alternate-network        Get the name of the currently detected alternate network, if any
  get-dex-data                 Get the most recently uploaded DEX data. Returns the most recent test for each dex metric
  help                         Print this message or the help of the given subcommand(s)

Options:
  -l, --listen      Listen for status changes and DNS logs (if enabled)
      --accept-tos  Accept the Terms of Service agreement
  -v, --verbose...  Enable verbose output. Multiple &quot;v&quot;s adds more verbosity
  -h, --help        Print help
  -V, --version     Print version
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Cloudflare の warp を使えば無料で簡単に VPN 経由でインターネットに接続できます。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>CloudWatchのlog insightでjsonデータに対してのフィルタ例</title><link>https://blog.teraren.com/posts/cloud-watch-log-insight/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cloud-watch-log-insight/</guid><description>アプリケーションのログが JSON で保存されているときの調査サンプル</description><pubDate>Wed, 31 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AWS の CloudWatch Logs にアプリケーションログを蓄積しています。&lt;/li&gt;
&lt;li&gt;データの messege の中身が JSON 形式であれば、特定のキーに対してフィルタをかけられます。&lt;/li&gt;
&lt;li&gt;しかしながら、クエリーが DSL なので毎回マニュアルを参照したりするのが面倒なのでメモを残しておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;クエリーの例&lt;/h2&gt;
&lt;p&gt;アプリケーションのログが JSON で保存されているときの調査サンプル&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;filter @logStream like &apos;app/app/&apos;
| filter @message like /include/
| filter @message not like /exclude/
| filter duration &amp;gt; 100
 | fields @timestamp, @message, duration
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2023/03/image-6.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2023/03/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Dockerを使ってHTTP3対応のnginxでホスティングする手順</title><link>https://blog.teraren.com/posts/docker-http3/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-http3/</guid><description>HTTP3 に対応したサイトが全世界の ウェブサイトの中で25％あるらしいです。</description><pubDate>Wed, 31 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;HTTP3 に対応したサイトが全世界の &lt;a href=&quot;https://w3techs.com/technologies/details/ce-http3&quot;&gt;ウェブサイトの中で25％ある&lt;/a&gt;らしいです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2023/02/image-2.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;nginx の roadmap 上では、3 年前から HTTP3 が入っているのに 2023 年 2 月 11 日現在ではまだ &lt;a href=&quot;https://trac.nginx.org/nginx/roadmap&quot;&gt;stableでのリリースは行われていません&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;HTTP3 を簡単に試してみるツール類は揃ってきているので今回は、HTTP3 対応の nginx を使ってどんな感じの運ようになるかをテストしてみます。&lt;/p&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;h3&gt;前提&lt;/h3&gt;
&lt;p&gt;nginx をリバースプロキシとして動かし、バックエンドとして localhost の 3005 番ポートで Ruby on Rails サービスが動いているという前提です。&lt;/p&gt;
&lt;p&gt;nginx には let’s encrypt で取得した TLS 証明書を使って HTTPS で接続しています。&lt;/p&gt;
&lt;p&gt;今回の対象サイト: &lt;a href=&quot;https://train.teraren.com/&quot;&gt;https://train.teraren.com/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;サーバサイドの設定&lt;/h3&gt;
&lt;p&gt;HTTP3 のデフォルトは UDP の 443 番ポートを使います。もちろん 443 番はデフォルトなだけであるので任意のポートも利用できます。&lt;/p&gt;
&lt;p&gt;とりあえず、以下のようなコマンドを打ち込んでみて localhost にて UDP の 443 ポートが使われていないことを確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% netstat -ln | grep 443 | grep udp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、以下のような設定ファイルを作成します。&lt;/p&gt;
&lt;p&gt;https://gist.github.com/matsubo/735eaf0bde87e8a89e6a55e8980cb03c#file-docker-compose-yml&lt;/p&gt;
&lt;p&gt;設定ファイルの内容は適宜変更してください。TLS証明書のファイルの場所、ドキュメントrootの場所を適宜変更します。&lt;/p&gt;
&lt;p&gt;proxy_passに指定するバックエンドのサービスのホスト名は、docker container内から参照できるIPアドレスまたはホスト名にする必要があります。ここで、localhostと指定してもコンテナ自体のホストを指すことになってしまいますので注意してください。&lt;/p&gt;
&lt;p&gt;そして、docker composeで立ち上げればOKです。let’s encryptのファイルの読み込みにはroot権限が必要になりますが、docker自体がroot権限で実行されるようなので一般ユーザで起動してもちゃんと読み込めてます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これで立ち上がります。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2023/02/image-3.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;これで、1つのバックエンドサービスに対して2つのWebサーバが立ち上がっている状態になります。1つは元から動いているnginx、2つ目は今回立ち上げたHTTP3対応nginxです。&lt;/p&gt;
&lt;p&gt;最後に、外部から接続できるようにfirewallやパケットフィルタの設定などでUDP 443への接続を許可します。&lt;/p&gt;
&lt;h3&gt;接続テスト&lt;/h3&gt;
&lt;p&gt;ブラウザ上ではhttp2もhttp3も同じURLになります。後述するalt-svcヘッダを出力する設定を元のnginx側で出力するようにする設定が必要になります（後述）&lt;/p&gt;
&lt;p&gt;よって、まずはCLIを使ってテストしてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker run -it --rm ghcr.io/unasuke/curl-http3:quiche-latest curl -IL https://train.teraren.com/ --http3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2023/02/image-4.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;正常な結果&lt;/p&gt;
&lt;p&gt;もし、HTTP3のnginxの設定が間違っていた場合は500系のエラーが返ってきます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2023/02/image-5.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;500系のエラー&lt;/p&gt;
&lt;p&gt;HTTP3のnginxを立ち上げたdocker composeの標準出力にアクセスログやエラーが表示されるのでその内容をチェックすれば良いと思います。&lt;/p&gt;
&lt;h3&gt;HTTP3に対応していることをブラウザへ　告知&lt;/h3&gt;
&lt;p&gt;現時点でブラウザは、httpsスキーマが指定されたらTCP 443番に対してTLSを使って接続し、HTTP 2.0などのアプリケーションプロトコルを使って接続を試みます。&lt;/p&gt;
&lt;p&gt;この状態では、ウェブサイトがHTTP3に対応しているかどうかわかりません。なので、このTCPで接続した際にHTTP3に対応していることをHTTPヘッダのレスポンスで返します。&lt;/p&gt;
&lt;p&gt;以下の設定をTCPで運用している元のnginxに追加します。これにより、ブラウザはHTTP3でのサービス提供が行われているサイトということを認識できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;add_header alt-svc &apos;h3=&quot;:443&quot;; ma=3600&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;外部のチェッカー&lt;/h3&gt;
&lt;p&gt;何故かエラーになる。。。(追記: 今は Cloudflare に載せ替えたのでエラーになりません)&lt;/p&gt;
&lt;p&gt;https://http3check.net/?host=https%3A%2F%2Ftrain.teraren.com%2F&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-6.png&quot; alt=&quot;../../assets/uploads/2023/02/image-6.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;余談&lt;/h3&gt;
&lt;p&gt;自分の使っているブラウザが HTTP3 に対応しているかどうかは以下のサイトなどでチェックできます。&lt;/p&gt;
&lt;p&gt;https://cloudflare-quic.com/&lt;/p&gt;
&lt;p&gt;手元の Brave ブラウザではなぜか HTTP3 での接続が行われない状態でした。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HTTP3 用 nginx を立ち上げると、同じような設定を 2 箇所で管理しないといけないので面倒です。早く stable で HTTP3 を対応してほしいです。&lt;/li&gt;
&lt;li&gt;すでに let’s encrypt で証明書を取得している場合は簡単に HTTP3 を試せます。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>GitHubでmerge後にブランチを自動削除すべきか：設定の判断基準</title><link>https://blog.teraren.com/posts/github-delete-branch-war/</link><guid isPermaLink="true">https://blog.teraren.com/posts/github-delete-branch-war/</guid><description>GitHub のリポジトリ運用において「Automatically delete head branches」を on にするか off にするか悩ましいところです。</description><pubDate>Wed, 31 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;GitHub のリポジトリ運用において「Automatically delete head branches」を on にするか off にするか悩ましいところです。&lt;/p&gt;
&lt;p&gt;デフォルトは off です。&lt;/p&gt;
&lt;h2&gt;GPTに聞いてみた&lt;/h2&gt;
&lt;p&gt;Q: GitHub の repository の設定にある、 “Automatically delete head branches” を on にするか off にするか悩んでます。どちらのほうが一般的でしょうか？&lt;/p&gt;
&lt;p&gt;A:「Automatically delete head branches」の設定は、プルリクエストがマージされた後に、そのブランチを自動的に削除する機能です。この設定をオンにするかオフにするかは、チームやプロジェクトのワークフローと好みによって異なります。しかし、一般的な考え方をいくつか紹介します。&lt;/p&gt;
&lt;p&gt;オンにする利点:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;リポジトリがきれいに保たれる: 不要なブランチが自動的に削除されるため、リポジトリが整理されやすくなります。&lt;/li&gt;
&lt;li&gt;ブランチの管理が楽になる: 作業が完了したブランチを手動で削除する必要がなくなり、メンテナンスが容易になります。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;オフにする利点:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;履歴の追跡: ブランチが削除されないため、過去の変更履歴を容易に確認できます。&lt;/li&gt;
&lt;li&gt;再利用可能: 削除されないため、同じブランチを再利用して追加の変更ができます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一般的には、プルリクエストがマージされた後にブランチを自動的に削除してリポジトリを整理しやすくするため、この機能をオンにすることが多いです。しかし、過去の変更履歴を追跡したい場合や、ブランチを再利用する必要がある場合はオフにすることもあります。&lt;/p&gt;
&lt;p&gt;最終的には、チームやプロジェクトの要件に基づいて判断してください。機能を試してみて、適切な設定を見つけるのも良い方法です。&lt;/p&gt;
&lt;h2&gt;Followerさんに聞いてみた&lt;/h2&gt;
&lt;p&gt;https://twitter.com/matsubokkuri/status/1679414967400013824&lt;/p&gt;
&lt;p&gt;on にしている人が多いです。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;GPT が回答した論点に関しては、すでに自分の中で考えていた論点と全く同じでした。&lt;/p&gt;
&lt;p&gt;GPT の回答から新たに得たインサイトとしては、&lt;strong&gt;onにしている方が多い&lt;/strong&gt;という情報です。&lt;/p&gt;
&lt;h2&gt;私の主張&lt;/h2&gt;
&lt;p&gt;ちなみに私は残しておく派。&lt;/p&gt;
&lt;p&gt;tig で見たときにブランチの目的が追いやすいから。&lt;/p&gt;
&lt;p&gt;そして、やっっぱり remote に push した情報って消しちゃいけないと思うんですよ。他の誰かが tracking しているかもしれないのでブランチが消えると追いづらくなってしまいます。&lt;/p&gt;
&lt;p&gt;容量は食わないし、見づらくなるぐらいのデメリットぐらいしか無いので、どんどん stock していくのが根本かなと思います。&lt;/p&gt;
&lt;p&gt;もし、ブランチ名を消す運用をしていて、再度同じブランチ名で別の feature branch を作り出したときに URI の指す中身が違ってしまうというのもあるからブランチ名はリポジトリーに対してユニークになっていることも重要です。&lt;/p&gt;
&lt;h2&gt;妥協点の模索&lt;/h2&gt;
&lt;p&gt;ブランチを残すことも、消すこともそれぞれメリットとデメリットがあります。それぞれの良いとこ取りをするための手法として、
ある程度時間が経過したブランチの重要性は下がるので古いブランチは消すという運用が考えられます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/beatlabs/delete-old-branches-action&quot;&gt;こちら&lt;/a&gt;のGithub Actiions を使えば上記の運用ができます。&lt;/p&gt;
&lt;p&gt;手元のリポジトリで運用して居る設定を記載しておきます。一年間残しておいて、tag は自動で消さないようにしてあります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Cleanup old branches
on:
  push:
    branches:
      - master
jobs:
  housekeeping:
    name: Cleanup old branches
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v2
      - name: Run delete-old-branches-action
        uses: beatlabs/delete-old-branches-action@v0.0.10
        with:
          repo_token: ${{ github.token }}
          date: &apos;6 months ago&apos;
          dry_run: false
          delete_tags: false
          minimum_tags: 5
          extra_protected_branch_regex: ^(foo|bar)$
          extra_protected_tag_regex: &apos;^v.*&apos;
          exclude_open_pr_branches: true
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>知的労働者のための究極のフルリモート環境構築例</title><link>https://blog.teraren.com/posts/home-office-desktop/</link><guid isPermaLink="true">https://blog.teraren.com/posts/home-office-desktop/</guid><description>知的労働者にとって作業環境は重要です。</description><pubDate>Wed, 31 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;3行まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;機材に 60 万円。部屋のリフォームに 50 万円ほどかけて家の作業環境を整えました。&lt;/li&gt;
&lt;li&gt;機材だけではなく、作業環境に関するノウハウも紹介します。&lt;/li&gt;
&lt;li&gt;機材は成功に行き着くまでに何回も買い直しした結果の良いものを紹介します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;どんな人のための記事？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在宅での PC 作業効率を上げたい人&lt;/li&gt;
&lt;li&gt;テレカンにおいて自分のカメラ写りを良くする方法。&lt;/li&gt;
&lt;li&gt;肩こり、目の疲れ、などの体の疲労を改善したい人&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;知的労働者にとって作業環境は重要です。&lt;/p&gt;
&lt;p&gt;良い機材にはお金をかけても効率が上がればすぐに回収できます。早く買えば、利用した日数で金額を割ると日割り金額が低く済みます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;私がトライアンドエラーしてたどり着いたデスク環境&lt;/strong&gt; を紹介するので参考にしていただければと思います。&lt;/p&gt;
&lt;p&gt;身体に触れる部分である、デスク、チェア、モニタ（視覚的に）には良いものを使う事によって肉体疲労が軽減されるので最重要部分です。&lt;/p&gt;
&lt;h2&gt;ユースケース定義&lt;/h2&gt;
&lt;p&gt;自分にとってベストなデスク環境を考えるために、デスクで何をするかを考えます。何をするにもベストな環境を目指すのは間違いです。何でもできるは何もできないです。目的をはっきりさせましょう。&lt;/p&gt;
&lt;p&gt;私の場合は以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;仕事: プログラミング、設計図書く、文書を書く、音楽を聞く、テレカンをする、写真のレタッチ。&lt;/li&gt;
&lt;li&gt;趣味: 電子工作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;主に PC を使った業務、趣味です。&lt;/p&gt;
&lt;h2&gt;要求定義&lt;/h2&gt;
&lt;p&gt;上記のユースケースを実現するための要求は以下になります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;電動の昇降機能付きデスク&lt;/li&gt;
&lt;li&gt;音質が良いスピーカー&lt;/li&gt;
&lt;li&gt;ノイズが少なくて指向性のあるマイク&lt;/li&gt;
&lt;li&gt;良い感じの Web カメラ&lt;/li&gt;
&lt;li&gt;長時間座っても疲れにくい椅子&lt;/li&gt;
&lt;li&gt;長時間使っても疲れないモニター。解像度が高いも煮た。モニタに光が反射しない環境。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;環境の説明&lt;/h2&gt;
&lt;p&gt;上記の要求を満たすための私なりの解を紹介します。たくさんあるので、物理的に大きい順で紹介します。&lt;/p&gt;
&lt;h3&gt;モニタ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;使っているのは、Dell U シリーズ &lt;a href=&quot;https://www.dell.com/ja-jp/shop/dell-u4021qw-40%E3%82%A4%E3%83%B3%E3%83%81%E3%83%AF%E3%82%A4%E3%83%89%E6%9B%B2%E9%9D%A2usb-c-hub-%E3%83%A2%E3%83%8B%E3%82%BF-5k2k-21-9-ips%E9%9D%9E%E5%85%89%E6%B2%A2-tbhdmix2dprj45-%E9%AB%98%E3%81%95%E8%AA%BF%E6%95%B4/apd/210-aypy/%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC-%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B5%E3%83%AA%E3%83%BC&quot;&gt;U4021QW&lt;/a&gt; 39.7 インチワイドモニタ－&lt;/p&gt;
&lt;p&gt;過去 15 年ぐらいは EIZO のモニタを使い続けていたのですが乗り換えました。乗り換える決断をした理由は 2 点あります。&lt;/p&gt;
&lt;p&gt;（1）&lt;strong&gt;高額&lt;/strong&gt;: カタログスペックでは表せない性能があるので高額なのは良いのですが、高額過ぎます。カタログスペックで等々の品と比べると 2 倍位する印象です。&lt;/p&gt;
&lt;p&gt;2. &lt;strong&gt;カタログスペック性能が低い&lt;/strong&gt;: 他社のモニタの大きさや解像度の高さに追随するようなメインのスペックから見ると液晶パネルの性能が低くて見劣りしてました。&lt;/p&gt;
&lt;p&gt;使用した結果、&lt;strong&gt;満足度は高い&lt;/strong&gt;です。コントラストは高く、チラツキが無く、ドット欠けは無し、EIZO から乗り換えても特に違和感はありませんでした。湾曲に関しても最初はちょっと違和感がありましたが、すぐに慣れました。逆にこのぐらい大きいと湾曲していないと端が見えないと思います。&lt;/p&gt;
&lt;p&gt;購入したのが 2021 年 4 月なので 2 年前です。2023 年 5 月の現在は 49 インチの &lt;a href=&quot;https://www.dell.com/ja-jp/shop/dell-u4919dw-49%E3%82%A4%E3%83%B3%E3%83%81%E3%83%AF%E3%82%A4%E3%83%89%E6%9B%B2%E9%9D%A2%E3%83%A2%E3%83%8B%E3%82%BF-dualqhd-32-9-ips%E9%9D%9E%E5%85%89%E6%B2%A2-usb-chdmix2dp-%E9%AB%98%E3%81%95%E8%AA%BF%E6%95%B4-srgb-99/apd/210-arfc/%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC-%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B5%E3%83%AA%E3%83%BC&quot;&gt;U4919DW&lt;/a&gt;のほうも検討に上がります。解像度は私が買った40インチと同じなのでDPIが低いです。視力が低めであればこちらのほうが良いかもです。&lt;/p&gt;
&lt;p&gt;以前、EIZO のモニタを 2 週間レンタルできる機会があったから、借りてみました。そして、会社から貸与されていた IIYAMA のモニタ（安いやつ）と EIZO のモニタを比較したら目の疲労具合が全然違いました。&lt;/p&gt;
&lt;p&gt;このクラスの DELL のモニタも長時間使っても目の疲れはあんまりありません。&lt;/p&gt;
&lt;p&gt;https://www.amazon.co.jp/dp/B08TBJ4YTM?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&lt;/p&gt;
&lt;h3&gt;デスク&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-36.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://amzn.to/4285ZpH&quot;&gt;FlexispotのE7B&lt;/a&gt;に朝日ウッドテックのブラックウォルナット天板の組み合わせです。&lt;/p&gt;
&lt;h3&gt;フレーム&lt;/h3&gt;
&lt;p&gt;まず、スタンディングデスクを選ぶ理由は以下の記事を読んでいただければと思います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gigazine.net/news/20141225-sitting-problem/&quot;&gt;https://gigazine.net/news/20141225-sitting-problem/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sukimaput.com/bauhutte-standingdesk/&quot;&gt;https://sukimaput.com/bauhutte-standingdesk/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;まず、デスクについてですが、&lt;strong&gt;絶対電動&lt;/strong&gt;が良いです。
手動のハンドルだと上下するのに時間がかかるので&lt;strong&gt;ほとんど動かさなくなります&lt;/strong&gt;。
それも、座った状態に固定されます。買った当初は頑張って立つようにしてますが、しばらくすると 1 日じゅう立ちっぱなしはそれはそれで疲れるので座った状態にして固定化されます。&lt;/p&gt;
&lt;p&gt;昇降範囲は 58-123cm ですが、特に下限や上限に不満はありませんでした。もっと高額なフレームは少広範囲が広かったのでちょっと迷ったのですがこの商品で問題ありませんでした。身長は 178cm です。&lt;/p&gt;
&lt;p&gt;https://www.amazon.co.jp/dp/B08F7MQL3S?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&lt;/p&gt;
&lt;h3&gt;天板&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.woodtec.co.jp/&quot;&gt;朝日ウッドテック&lt;/a&gt;のブラックウォルナットです。集成材の天板だけで10万円(送料・税込)しました。別のリフォームの流れで発注してしまったのですが、今となってはオンラインで注文したほうが良かったなと若干後悔しております。&lt;/p&gt;
&lt;p&gt;朝日ウッドテックは&lt;strong&gt;一流メーカーですので失敗は無い&lt;/strong&gt;です。保証もしっかりしています。当時、カウンター板のトラブル事例を見ていると不安になったという点も多少あります（しかし、使っていれば傷や凹みは付くのであんまり気にしなくてよかったです）&lt;/p&gt;
&lt;p&gt;とにかく、肌に触れるところには質感は重視したほうが良いです。プラスチックとか樹脂のデスクですと反発が強すぎて&lt;strong&gt;腕を置いていると赤くなったりマウスタコができたりします&lt;/strong&gt;。&lt;strong&gt;木材であればそのようなことは無くなりました&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;オンラインですと幅はぎ(100mm)で9万円ほどで買えます。&lt;/p&gt;
&lt;p&gt;無垢材の1枚板を検討しましたが重量が重くなるのと、使用環境によっては反りや割れが発生するらしくてメンテナンスが難しそうなのでやめました。かっこいいんですけど、作業用デスクには見た目的にもちょっとやりすぎ感もあるかなと思いました。&lt;a href=&quot;https://auctions.yahoo.co.jp/search/search?auccat=&amp;amp;tab_ex=commerce&amp;amp;ei=utf-8&amp;amp;aq=-1&amp;amp;oq=&amp;amp;sc_i=&amp;amp;exflg=1&amp;amp;p=%E7%84%A1%E5%9E%A2%E6%9D%90+1%E6%9E%9A&amp;amp;x=0&amp;amp;y=0&quot;&gt;中古の1枚ものはヤフオクで結構安く売られています&lt;/a&gt;。&lt;/p&gt;
&lt;h3&gt;チェア&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;社会人 3 年目にハーマンミラーの &lt;a href=&quot;https://amzn.to/43aZHXD&quot;&gt;Embody chair&lt;/a&gt;購入してそれからずっと職場で使っています。職場が変われば、Embody Chair を自費で赤帽を使って輸送して使っています。&lt;/p&gt;
&lt;p&gt;当時は肩こりが酷くてそれを緩和させたくて買いました。フィッティングの柔軟性が非常に高く、疲れた体の部位に負荷をかけないように微調整できるのが良いです。疲れたときにはそのままリクライニングにして寝っ転がる感じにもなれます。&lt;/p&gt;
&lt;p&gt;チェアを買うときに、アーロンチェアか Embody Chair にするか迷いましたが、Embody Chair のほうが上位っぽかったので決めました。&lt;/p&gt;
&lt;p&gt;今となっては新品が 25 万円ぐらいしますが 17 年前は 20 万円弱でした。現地では 10 万円ちょっとで売られていたのでアメリカから新品を個人輸入してトータル 15 万円ぐらいで手に入れました。&lt;/p&gt;
&lt;p&gt;https://www.amazon.co.jp/dp/B004HW814E?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&lt;/p&gt;
&lt;h3&gt;メイン照明&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;作業環境の観点と、テレカンの写りの観点で照明はとても重要です。このために&lt;strong&gt;リフォームを業者に発注しました&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;照明の重要さについて書かれている記事を載せておきます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.akiyan.com/blog/archives/2007/01/post_75.html&quot;&gt;https://www.akiyan.com/blog/archives/2007/01/post_75.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://diary.teraren.com/posts/2013-12-15-lighting/&quot;&gt;https://diary.teraren.com/posts/2013-12-15-lighting/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://logmi.jp/business/articles/191355&quot;&gt;https://logmi.jp/business/articles/191355&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;まず、液晶モニタに反射を作る原因は強い光源なので外光をあまり取り入れないようにして昼夜問わず安定した照明環境を作ることを基本としました。
外光の取り入れに関しては、自然の生活をするためには外光を取り入れたほうが良いとは思いますが外光の変化によって「あぁ、雨が振ってきたなぁ」とか「天気が悪いなぁ」といった集中力を削ぐ要因を排除する目的もあります。たぶん、自律神経に影響すると思いますが、朝に散歩をして太陽光を浴びたりしてカバーします。&lt;/p&gt;
&lt;p&gt;その上で、昼は白色、夜は暖色にしたかったので、ちょうど Panasonic から調色の LED 電気が発売されたので導入しました。&lt;/p&gt;
&lt;p&gt;テレカン時に顔への照明をまんべんなく当てるために間接照明を導入しました。以前、テレカンのときだけ顔用に照明を使ったりしていましたが、スイッチを入れるのが面倒だし照明が眩しいのですぐに使わなくなりました。&lt;/p&gt;
&lt;p&gt;部屋の照明を間接照明へするために、シーリングライトのコネクタを撤去してリフォーム業者に依頼してコープ照明にリフォームしました。&lt;/p&gt;
&lt;p&gt;利用したのは &lt;a href=&quot;https://amzn.to/3N17DVL&quot;&gt;ARCHITECTURAL LIGHT L=1200&lt;/a&gt; (YYY21260LB1)です。4 つ設置しました。&lt;/p&gt;
&lt;p&gt;調色を重視しているのであんまり発色は良くないのが残念です。設置直後は綺麗に発色していた気はしますが、最近はなんかほんの少し緑っぽさが出てきた気がしてます。&lt;/p&gt;
&lt;h3&gt;背景(バックスクリーン)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-23.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Web カメラ（普通の安いカメラも）の特性で、明るさ（露出）は写っている全体の光量を元に明るさを決めています。一般的には壁紙は白いので、白い壁紙の前で顔を写すと顔が相対的に暗くなります。それを防ぐためには背景を顔より暗い明度にするのが良いです。&lt;/p&gt;
&lt;p&gt;極端に言えば、黒い壁紙にすれば自分の顔がすごい白く写ります。&lt;/p&gt;
&lt;p&gt;そこで、ダークグレーのロールスクリーンを設置して背景を作りました。幅をぴったりに作りたかったのでオーダーで注文しました。&lt;/p&gt;
&lt;p&gt;TOSO の &lt;a href=&quot;https://www.toso.co.jp/products/rollscreen/blackout/plate/#link3&quot;&gt;プレート&lt;/a&gt;というシリーズです。4万円ぐらいしました。&lt;/p&gt;
&lt;p&gt;同じ照明の下で、背景の違いによる顔の印象を検証するために iPhone 13 Pro でサンプルを撮影してみました。無補正です。右の方が顔に影ができてしまっているし全体的に暗い印象になってしまっていますが、左側は白く明るい印象に写っています（iPhone 13 だと頭が良すぎてフォーカスが当たっているところの露出を基準にしちゃっているのであまり顕著には差が出ませんが）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;明度の低い背景&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;明度の高い背景&lt;/p&gt;
&lt;h3&gt;スポット照明&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;資材が余ったのでデスクの上にダクトレールを設置して、暖色の LED スポットライトを付けてみました。間接照明だけだと暗すぎるかと思ったので保険として用意しましたが、まったく使っておりません。&lt;/p&gt;
&lt;h3&gt;スピーカー&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/05/image-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;3 回スピーカーを買い替えた結果、&lt;a href=&quot;https://amzn.to/3qjxUW9&quot;&gt;GENELECの8020&lt;/a&gt;シリーズを使っています。めちゃくちゃ満足度は高いです。もう、これは騙されたと思って買ってみてほしいです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最適なスピーカーは部屋の大きさや、スピーカーまでの距離、スタンドの材質などによって変わる&lt;/strong&gt;ので環境の制約に合ったものを選ぶ必要があったのでここに行き着くまでが大変でした。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;大きくて高額なものを買えば安心というモノではないです。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;スピーカーが良ければテレカンにおいて、聞こえづらい部分とかも少しは明瞭になりますし、相手の声も聞き取りやすくなるので披露が軽減されます。&lt;/p&gt;
&lt;p&gt;スピーカー選定時の試行錯誤は &lt;a href=&quot;https://blog.teraren.com/2020/02/09/macos-audio-speaker/&quot;&gt;こちらの記事&lt;/a&gt;にまとめてあります。&lt;/p&gt;
&lt;h3&gt;マイク&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-34.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;HyperX QuadCast です。YouTuber がおすすめしていたので買いました。&lt;/p&gt;
&lt;p&gt;以前は、&lt;a href=&quot;https://amzn.to/3MA7dUO&quot;&gt;中華メーカーのUSBのコンデンサマイク&lt;/a&gt;を使っていたのですがノイズが酷かったです。マイクなんてどこも大して変わらないだろうと思っていましたが、ちゃんとしたメーカーのマイクを使う必要があると感じました。&lt;/p&gt;
&lt;p&gt;スピーカーの音をマイクが拾わないようにするために、マイクは指向性があったほうが良いです。&lt;/p&gt;
&lt;p&gt;あと、結果的に良かったのは普通のハンドマイクを使うより、直立していたほうがスペースを取らなくて良いです。どうしてもマイクは顔の近くに置く必要があるため邪魔にならない形状である必要があります。&lt;/p&gt;
&lt;p&gt;物理的に mute/unmute ができるものだと楽です。ソフトウェア上で mute/unmute をするとなると直感的ではないしすぐに操作したいときに困ります。&lt;/p&gt;
&lt;p&gt;https://www.amazon.co.jp/dp/B07NZZZ746?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&lt;/p&gt;
&lt;h3&gt;キーボード&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/2024-04-22-14-26-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以前は、&lt;a href=&quot;https://www.amazon.co.jp/dp/B082TWFV9C?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&quot;&gt;HHKB Professional HYBRID Type-S無刻印／墨（英語配列）&lt;/a&gt;
を使っていました。&lt;/p&gt;
&lt;p&gt;会社と自宅で同じキーボードを使いたかったので安価で良いものを探した結果、&lt;a href=&quot;https://amzn.to/3U6by5X&quot;&gt;EPOMAKER CIDOO V75&lt;/a&gt;にしました。
打鍵感、打鍵音、キーピッチ、PBT キーキャップ、ガスケットマウントととても良い感じです。&lt;/p&gt;
&lt;p&gt;オフィスで使うには、少しタイピング音が大きいので会社用のは
&lt;a href=&quot;https://amzn.to/4b1VgSq&quot;&gt;EPOMAKER Sea Salt 静音メカニカルスイッチ&lt;/a&gt;
に変更しています。&lt;/p&gt;
&lt;h3&gt;マウス&lt;/h3&gt;
&lt;p&gt;トラックボールを試しに使ってます。まぁ、普通のマウスでもどっちでも大丈夫です。唯一の欠点は曲線が書きづらいのと、トラックボールを定期的に掃除しないと動きが悪くなるということです。&lt;/p&gt;
&lt;p&gt;https://www.amazon.co.jp/dp/B074Z71C2M?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&lt;/p&gt;
&lt;h3&gt;ケーブル収納&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;サンワサプライのケーブル収納するやつ。めちゃくちゃキレイに収納できるのでおすすめです。&lt;/p&gt;
&lt;p&gt;この収納トレーは、ERD シリーズ専ようになっていてナットで天板に裏からビス止めできます。そのため、クランプ型だとどうしてもデスクに引っ掛ける部分が必要になりますが、こちらはデスク上には一切干渉しないです。その代わり、天板に穴あけ加工が必要になります。&lt;/p&gt;
&lt;p&gt;ネジの規格は M5 x 12mm になるので、穴側は、鬼目ナット側 &lt;a href=&quot;https://amzn.to/43wz2UR&quot;&gt;M5x10mm&lt;/a&gt;、下穴は7.5mmのビットで穴あけをしました。天板を外して作業したので2時間ぐらいかかりました。初期設置時にやっておくべきでした。&lt;/p&gt;
&lt;p&gt;以前は以下のような網のラックを使っていたのですが、クランプが卓上に見えてしまうのとケーブルが多くて収まりきらないし、ケーブル自体が見えてしまうので見た目が良くないです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;電源タップはこちらです。スピーカーそれぞれ、Google Home, モニタ、デスク裏の LED 照明に電源が必要なので結構コンセントを使うので 10 口ぐらいは必要です。&lt;/p&gt;
&lt;p&gt;https://www.amazon.co.jp/dp/B0877666H6?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&lt;/p&gt;
&lt;h3&gt;デスクLED照明&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2023/05/image-33.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-33.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Wi-Fi に接続してコントロールできるフルカラーLED テープを貼り付けています。&lt;/p&gt;
&lt;p&gt;作業中は緑色にすることで &lt;a href=&quot;https://jinjibu.jp/keyword/detl/1414/&quot;&gt;緑視率&lt;/a&gt;を上げることによる集中力向上を狙っています。&lt;/p&gt;
&lt;p&gt;この LED テープの密度が低いので普通に貼ったら斑（まだら）になってしまいました。そこで、ピッチが異なるように上と下になるように 2 重に貼り付けたらドットが見えなくなってきれいに発色するようになりました。高さ違い、ピッチ違いなので影ができづらくなり、面で発光しているように見えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;スマートホームと連携して、始業時間に点灯して深夜に消灯するルーチーンを設定しています。&lt;/p&gt;
&lt;p&gt;音に反応した照明でクラブっぽい演出もできます。電気信号でのコントロールではなく、音量を計測して発行しているので遅延が大きくて違和感があります。&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/watch?v=_d5A_hF68Wk&lt;/p&gt;
&lt;p&gt;https://www.amazon.co.jp/dp/B087339YX8?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&lt;/p&gt;
&lt;h3&gt;USBカメラ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Web でしか使わないので特にこだわりは無いです。オートフォーカスがついているし小さいので不満は無いです。この商品はティルト調整が良いです。&lt;/p&gt;
&lt;p&gt;https://www.amazon.co.jp/dp/B07QQR6G5N?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&lt;/p&gt;
&lt;h3&gt;USB DAC&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-29.png&quot; alt=&quot;Fosi Audio DAC-Q4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;USB-DAC は過去に 3 回書い直してます。無名なメーカーの USB-DAC は数ヶ月〜数年使っていると調子が悪くなってきます。PC に認識されなくなったり、左右の音色の差が出てきたりしました。&lt;/p&gt;
&lt;p&gt;この商品は口コミ数が多くて安心できそうなので買いました。低音と高音のエコライザがついているので多少音色の調整をアンプ側で変更できます。&lt;/p&gt;
&lt;p&gt;1 年ぐらい問題なく運用できています。&lt;/p&gt;
&lt;p&gt;https://www.amazon.co.jp/dp/B07VDQQY95?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&lt;/p&gt;
&lt;h3&gt;USBハブ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-30.png&quot; alt=&quot;ANKER USB hub&quot; /&gt;&lt;/p&gt;
&lt;p&gt;モニタについている USB-A ポートだけでは足りないので増設しています。USB セキュリティキー(&lt;a href=&quot;https://store.google.com/jp/product/titan_security_key?hl=ja&quot;&gt;Titan Security Key&lt;/a&gt;)を抜き差しするときに、USBポートが手元にあったほうが楽なのでUSB-DACの上に両面テープで貼り付けています。&lt;/p&gt;
&lt;p&gt;https://www.amazon.co.jp/dp/B07ST84PF5?tag=matsubo0e-22&amp;amp;linkCode=ogi&amp;amp;th=1&amp;amp;psc=1&lt;/p&gt;
&lt;h3&gt;PCスタンド&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-31.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;隙間の幅をネジで調整できるのでピッタリハマるように設定できます。&lt;/p&gt;
&lt;p&gt;https://amzn.to/3C0Atz7&lt;/p&gt;
&lt;h3&gt;Google Nest mini&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-32.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Nest になってから小さいけど音質がかなり向上したので適当な BGM を流すのに使ってます。&lt;/p&gt;
&lt;h3&gt;壁のリフォーム&lt;/h3&gt;
&lt;p&gt;夏の高多湿、冬の低湿度は日本に居るとかなり問題です。これを少しでも緩和するためにエコカラットを壁に貼り付けました。
賃貸の場合は難しいですが、分譲の場合は簡単にできるので DIY すると楽しいと思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/2024-04-22-14-23-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;シーンに応じた照明&lt;/h2&gt;
&lt;h3&gt;夜間の照明例&lt;/h3&gt;
&lt;p&gt;夜はブルーライトをカットしたほうが睡眠の質が高くなるので暖色で統一できるようにしました。&lt;/p&gt;
&lt;p&gt;暖色のスポットライトを点灯し、デスク裏の LED テープライトを黄色に点灯した状態。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/IMG_4588.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Cyberpunkぽい例&lt;/h3&gt;
&lt;p&gt;デスクの LED テープライトのみを点灯しただけ。ブラックライトに近い光り方をします。&lt;strong&gt;目が疲れます&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Railsにおいてユーザがプラットフォーム(多対多)となるシステムを作るときの権限モデルを設計</title><link>https://blog.teraren.com/posts/rails-authorization-model/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-authorization-model/</guid><description>Ruby on Rails における複雑な認可の設計と実装するための一例を紹介する。</description><pubDate>Wed, 31 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;Ruby on Rails における複雑な認可の設計と実装するための一例を紹介する。&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;手元で作っている Rails の B2B サービスの権限に関連する要件が複雑化してきたので、権限モデルをちょっと整理する。&lt;/p&gt;
&lt;p&gt;権限が複雑になる原因は、アクターや操作対象といった権限に関するメトリックが多くなること。要件レベルでどれだけメトリックを減らせるかが重要。&lt;/p&gt;
&lt;p&gt;ビジネスで利用するサービスの場合、細かい権限設定が要求されるのでメトリックが増えやすい。&lt;/p&gt;
&lt;p&gt;今回扱わなければいけないメトリックは以下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アクター種別&lt;/li&gt;
&lt;li&gt;ロール種別&lt;/li&gt;
&lt;li&gt;ステータス遷移&lt;/li&gt;
&lt;li&gt;Web or API による操作&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;メトリックが 3 つ以上になった時点で直交表が作成できなくなってしまうため、権限表を作るのが難しくなる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;メトリックが 3 つであれば、直交表を複数作ればギリギリ対応できる&lt;/li&gt;
&lt;li&gt;4 つになると表現が厳しい。そもそも理解、暗記、比較も困難。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例えば、Web から操作できる内容と API からできる操作を同様にすることによってメトリックを 1 つ減らせる。&lt;/p&gt;
&lt;p&gt;この権限に関する問題は、システム上で表現は可能だしテストケースも作成して担保できる。しかしながら、人間が理解する時や説明するときに困難。&lt;/p&gt;
&lt;p&gt;また、細かい要件定義を繰り返してミクロな議論によって実装要件を決めていくといつの間にか複雑に陥っているケースが多い。技術的負債とはまさにこのことである。&lt;/p&gt;
&lt;h2&gt;理想&lt;/h2&gt;
&lt;p&gt;あるべき論は &lt;a href=&quot;https://twitter.com/y_matsuwitter/status/1690880240577617921/photo/2&quot;&gt;以下のスライド&lt;/a&gt;に書いてあるとおりと考える。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/complicated.png&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
&lt;p&gt;しかしながら既存のワークフローを DX してリプレースをかける場合はすでに複雑な要件が決まっていたりするので要件を単純化する余地が少なかったりもする。&lt;/p&gt;
&lt;p&gt;どの程度の複雑性になったら複雑と呼べるのか、複雑さを表現するための評価軸を持っておく必要がある。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;クリーンアーキテクチャのレイヤと比較して、このような感じで考える。これ以上メトリックが増える場合は、独自にビジネスロジックのレイヤーを追加するなりして対応する必要がある。&lt;/p&gt;
&lt;p&gt;背景にあるメトリックを管理するために、Rails にて利用したミドルウェアとスタックを図にまとめた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/pundit.png&quot; alt=&quot;Alt text&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AASM によるステータス遷移&lt;/li&gt;
&lt;li&gt;ロールごとに pundit で管理
&lt;ul&gt;
&lt;li&gt;API 用、アクターごとに設定を用意する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このように図に整理するとどうやって権限を整理するときれいにできるかが見えてくる。
pundit の設定ファイルごとにまとめることによって権限はきれいに表現できそうということがわかる。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Rails のシステムにおいて認可をまとめるには以下のようにまとめるのが良さそう。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AASM ではビジネスロジックのステータス遷移についてまとめる&lt;/li&gt;
&lt;li&gt;アクターやアクセスする手段ごとに pundit を用意して pundit の設定ファイルごとに権限表を作成&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>知的労働者のための究極のホームオフィス環境ガイド</title><link>https://blog.teraren.com/posts/desktop/</link><guid isPermaLink="true">https://blog.teraren.com/posts/desktop/</guid><description>プログラミングやテレカンを快適にこなすために試行錯誤して選んだ昇降デスク・チェア・モニター・マイクなどのホームオフィス機材を詳しく紹介</description><pubDate>Mon, 29 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;知的労働者にとって作業環境は重要です。&lt;/p&gt;
&lt;p&gt;良い機材にはお金をかけても効率が上がればすぐに回収できます。早く買えば、利用した日数で金額を割ると日割り金額が低く済みます。&lt;/p&gt;
&lt;p&gt;ということで、私がトライアンドエラーしてたどり着いたデスク環境を紹介するので参考にしていただければと思います。&lt;/p&gt;
&lt;p&gt;身体に触れる部分である、デスク、チェアー、モニタ（視覚的に）には良いものを使いたいという思いが強いです。&lt;/p&gt;
&lt;h2&gt;ユースケース定義&lt;/h2&gt;
&lt;p&gt;デスクで何をするかを考えます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;仕事: プログラミング、設計図書く、文書を書く、音楽を聞く、テレカンをする、写真のレタッチ。&lt;/li&gt;
&lt;li&gt;趣味: 電子工作&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要求定義&lt;/h2&gt;
&lt;p&gt;上記のユースケースを実現するための要求は以下になります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;電動の昇降機能付きデスク&lt;/li&gt;
&lt;li&gt;音質が良いスピーカー&lt;/li&gt;
&lt;li&gt;ノイズが少なくて指向性のあるマイク&lt;/li&gt;
&lt;li&gt;良い感じのWebカメラ&lt;/li&gt;
&lt;li&gt;長時間座っても疲れにくい椅子&lt;/li&gt;
&lt;li&gt;長時間使っても疲れないモニター。解像度が高いモニタ。モニタに光が反射しない環境。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;環境の説明&lt;/h2&gt;
&lt;p&gt;上記の要求を満たすための私なりの解である環境を紹介します。物理的に大きい順で紹介します。&lt;/p&gt;
&lt;h3&gt;モニタ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;使っているのはこちらです。&lt;/p&gt;
&lt;p&gt;Dell Uシリーズ &lt;a href=&quot;https://www.dell.com/ja-jp/shop/dell-u4021qw-40%E3%82%A4%E3%83%B3%E3%83%81%E3%83%AF%E3%82%A4%E3%83%89%E6%9B%B2%E9%9D%A2usb-c-hub-%E3%83%A2%E3%83%8B%E3%82%BF-5k2k-21-9-ips%E9%9D%9E%E5%85%89%E6%B2%A2-tbhdmix2dprj45-%E9%AB%98%E3%81%95%E8%AA%BF%E6%95%B4/apd/210-aypy/%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC-%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B5%E3%83%AA%E3%83%BC&quot;&gt;U4021QW&lt;/a&gt; 39.7インチワイドモニター&lt;/p&gt;
&lt;p&gt;過去15年ぐらいはEIZOのモニタを使い続けていたのですが乗り換えました。乗り換える決断をした理由は2点あります。&lt;/p&gt;
&lt;p&gt;1．&lt;strong&gt;高額&lt;/strong&gt;: カタログスペックでは表せない性能があるので高額なのは良いのですが、高額過ぎます。カタログスペックで同等の品と比べると2倍位する印象です。&lt;/p&gt;
&lt;p&gt;2. &lt;strong&gt;カタログスペック性能が低い&lt;/strong&gt;: 他社のモニタの大きさや解像度の高さに追随するようなメインのスペックから見ると液晶パネルの性能が低くて見劣りしてました。&lt;/p&gt;
&lt;p&gt;使用した結果、&lt;strong&gt;満足度は高い&lt;/strong&gt;です。コントラストは高く、チラツキが無く、ドット欠けは無し、EIZOから乗り換えても特に違和感はありませんでした。湾曲に関しても最初はちょっと違和感がありましたが、すぐに慣れました。逆にこのぐらい大きいと湾曲していないと端が見えないと思います。&lt;/p&gt;
&lt;p&gt;購入したのが2021年4月なので2年前です。2023年5月の現在は49インチの&lt;a href=&quot;https://www.dell.com/ja-jp/shop/dell-u4919dw-49%E3%82%A4%E3%83%B3%E3%83%81%E3%83%AF%E3%82%A4%E3%83%89%E6%9B%B2%E9%9D%A2%E3%83%A2%E3%83%8B%E3%82%BF-dualqhd-32-9-ips%E9%9D%9E%E5%85%89%E6%B2%A2-usb-chdmix2dp-%E9%AB%98%E3%81%95%E8%AA%BF%E6%95%B4-srgb-99/apd/210-arfc/%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC-%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B5%E3%83%AA%E3%83%BC&quot;&gt;U4919DW&lt;/a&gt;のほうも検討に上がります。解像度は私が買った40インチと同じなのでDPIが低いです。視力が低めであればこちらのほうが良いかもです。&lt;/p&gt;
&lt;p&gt;以前、EIZOのモニタを2週間レンタルできる機会があったから、借りてみました。そして、会社から貸与されていたIIYAMAのモニタ（安いやつ）とEIZOのモニタを比較したら目の疲労具合が全然違いました。&lt;/p&gt;
&lt;p&gt;このクラスのDELLのモニタも長時間使っても目の疲れはあんまりありません。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B08TBJ4YTM&quot;}&lt;/p&gt;
&lt;h3&gt;デスク&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-36.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://amzn.to/4285ZpH&quot;&gt;FlexispotのE7B&lt;/a&gt;に朝日ウッドテックのブラックウォルナット天板の組み合わせです。&lt;/p&gt;
&lt;h3&gt;フレーム&lt;/h3&gt;
&lt;p&gt;まず、スタンディングデスクを選ぶ理由は以下の記事を読んでいただければと思います。&lt;/p&gt;
&lt;p&gt;https://gigazine.net/news/20141225-sitting-problem/&lt;/p&gt;
&lt;p&gt;https://sukimaput.com/bauhutte-standingdesk/&lt;/p&gt;
&lt;p&gt;まず、デスクについてですが、&lt;strong&gt;絶対電動&lt;/strong&gt;が良いです。手動のハンドルだと上下するのにめちゃくちゃ時間がかかるので&lt;strong&gt;ほとんど動かさなくなります&lt;/strong&gt;。それも、座った状態に固定されます。買った当初は頑張って立つようにしてますが、しばらくすると1日じゅう立ちっぱなしはそれはそれで疲れるので座った状態にして、ずっとそのままになります。&lt;/p&gt;
&lt;p&gt;昇降範囲は58-123cmですが、特に下限や上限に不満はありませんでした。もっと高額なフレームは昇降範囲が広かったのでちょっと迷ったのですがこの商品で問題ありませんでした。身長は178cmです。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B08F7MQL3S&quot;}&lt;/p&gt;
&lt;h3&gt;天板&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.woodtec.co.jp/&quot;&gt;朝日ウッドテック&lt;/a&gt;のブラックウォルナットです。集成材の天板だけで10万円(送料・税込)しました。別のリフォームの流れで発注してしまったのですが、今となってはオンラインで注文したほうが良かったなと若干後悔しております。&lt;/p&gt;
&lt;p&gt;朝日ウッドテックは&lt;strong&gt;一流メーカーですので失敗は無い&lt;/strong&gt;です。保証もしっかりしています。当時、カウンター板のトラブル事例を見ていると不安になったという点も多少あります。（しかし、使っていれば傷や凹みは付くのであんまり気にしなくてよかったです）&lt;/p&gt;
&lt;p&gt;とにかく、肌に触れるところには質感は重視したほうが良いです。プラスチックとか樹脂のデスクですと反発が強すぎて&lt;strong&gt;腕を置いていると赤くなったりマウスタコができたりします&lt;/strong&gt;。&lt;strong&gt;木材であればそのようなことは無くなりました&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://shop.woodworks-marutoku.com/&quot;&gt;オンラインですと6万円&lt;/a&gt;ほどで買えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/06/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;無垢材の1枚板を検討しましたが重量が重くなるのと、使用環境によっては反りや割れが発生するらしくてメンテナンスが難しそうなのでやめました。かっこいいんですけど、作業用デスクには見た目的にもちょっとやりすぎ感もあるかなと思いました。&lt;a href=&quot;https://auctions.yahoo.co.jp/search/search?auccat=&amp;amp;tab_ex=commerce&amp;amp;ei=utf-8&amp;amp;aq=-1&amp;amp;oq=&amp;amp;sc_i=&amp;amp;exflg=1&amp;amp;p=%E7%84%A1%E5%9E%A2%E6%9D%90+1%E6%9E%9A&amp;amp;x=0&amp;amp;y=0&quot;&gt;中古の1枚ものはヤフオクで結構安く売られています&lt;/a&gt;。&lt;/p&gt;
&lt;h3&gt;チェア&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;社会人3年目にハーマンミラーの&lt;a href=&quot;https://amzn.to/43aZHXD&quot;&gt;Embody chair&lt;/a&gt;購入してそれからずっと職場で使っています。職場が変われば、Embody Chairを自費で赤帽を使って輸送して使っています。&lt;/p&gt;
&lt;p&gt;当時は肩こりが酷くてそれを緩和させたくて買いました。フィッティングの柔軟性が非常に高く、疲れた体の部位に負荷をかけないように微調整できるのが良いです。疲れたときにはそのままリクライニングにして寝っ転がる感じにもなれます。&lt;/p&gt;
&lt;p&gt;チェアを買うときに、アーロンチェアかEmbody Chairにするか迷いましたが、Embody Chairのほうが上位っぽかったので決めました。&lt;/p&gt;
&lt;p&gt;今となっては新品が25万円ぐらいしますが17年前は20万円弱でした。現地では10万円ちょっとで売られていたのでアメリカから新品を個人輸入してトータル15万円ぐらいで手に入れました。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B004HW814E&quot;}&lt;/p&gt;
&lt;h3&gt;メイン照明&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;作業環境の観点と、テレカンの写りの観点で照明はとても重要です。このために部屋を&lt;strong&gt;リフォームかけました&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;照明の重要さについて書かれている記事を載せておきます。&lt;/p&gt;
&lt;p&gt;https://www.akiyan.com/blog/archives/2007/01/post_75.html&lt;/p&gt;
&lt;p&gt;https://diary.teraren.com/posts/2013-12-15-lighting/&lt;/p&gt;
&lt;p&gt;https://logmi.jp/business/articles/191355&lt;/p&gt;
&lt;p&gt;まず、液晶モニタに反射を作る原因は強い光源なので外光をあまり取り入れないようにして昼夜問わず安定した照明環境を作ることを基本としました。&lt;/p&gt;
&lt;p&gt;その上で、昼は白色、夜は暖色にできるようにしたかったのでちょうどPanasonicから調色のLED照明が発売されたので導入しました。&lt;/p&gt;
&lt;p&gt;テレカン時に顔への照明をまんべんなく当てるために間接照明にするのが良いです。以前、テレカンのときだけ顔用に照明を使ったりしていましたが、面倒だし眩しいのですぐに使わなくなりました。&lt;/p&gt;
&lt;p&gt;間接照明にするために、シーリングライトのコネクタを撤去してリフォーム業者に依頼してコーブ照明にリフォームしました。&lt;/p&gt;
&lt;p&gt;利用したのは&lt;a href=&quot;https://amzn.to/3N17DVL&quot;&gt;ARCHITECTURAL LIGHT L=1200&lt;/a&gt; (YYY21260LB1)です。4つ設置しました。&lt;/p&gt;
&lt;p&gt;調色を重視しているのであんまり発色は綺麗では無いのが残念です。設置直後はまんべんなく綺麗に発色していた気はしますが、最近はなんかほんの少し緑っぽさが出てきた気がしてます。&lt;/p&gt;
&lt;h3&gt;背景(バックスクリーン)&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-23.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Webカメラ（普通の安いカメラも）の特性で、明るさ（露出）は写っている全体の光量を元に明るさを決めています。一般的には壁紙は白いので、白い壁紙の前で顔を写すと顔が相対的に暗くなります。それを防ぐためには背景を顔より暗い明度にするのが良いです。&lt;/p&gt;
&lt;p&gt;極端に言えば、黒い壁紙にすれば自分の顔がすごい白く写ります。&lt;/p&gt;
&lt;p&gt;そこで、ダークグレーのロールスクリーンを設置して背景を作りました。幅をぴったりに作りたかったのでオーダーで注文しました。&lt;/p&gt;
&lt;p&gt;TOSOの&lt;a href=&quot;https://www.toso.co.jp/products/rollscreen/blackout/plate/#link3&quot;&gt;プレート&lt;/a&gt;というシリーズです。4万円ぐらいしました。&lt;/p&gt;
&lt;p&gt;同じ照明の下で、背景の違いによる顔の印象を検証するためにiPhone 13 Proでサンプルを撮影してみました。無補正です。右の方が顔に影ができてしまっているし全体的に暗い印象になってしまっていますが、左側は白く明るい印象に写っています。（iPhone 13だと頭が良すぎてフォーカスが当たっているところの露出を基準にしちゃっているのであまり顕著には差が出ませんが）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;明度の低い背景&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;明度の高い背景&lt;/p&gt;
&lt;h3&gt;スポット照明&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;資材が余ったのでデスクの上にダクトレールを設置して、暖色のLEDスポットライトを付けてみました。間接照明だけだと暗すぎるかと思ったので保険としてです。ですが、まったく使っておりません。&lt;/p&gt;
&lt;h3&gt;スピーカー&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/05/image-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;3回スピーカーを買い替えた結果、&lt;a href=&quot;https://amzn.to/3qjxUW9&quot;&gt;GENELECの8020&lt;/a&gt;シリーズを使っています。めちゃくちゃ満足度は高いです。もう、これは騙されたと思って買ってみてほしいです。&lt;/p&gt;
&lt;p&gt;スピーカーは部屋の大きさや、スピーカーまでの距離、スタンドの材質などによって変わるので環境の制約に合ったものを選ぶ必要があったのでここに行き着くまでが大変でした。&lt;/p&gt;
&lt;p&gt;大きくて高いものを買えば安心というモノではないです。&lt;/p&gt;
&lt;p&gt;スピーカーが良ければテレカンにおいて、聞こえづらい部分とかも少しは明瞭になりますし、相手の声も聞き取りやすくなります。&lt;/p&gt;
&lt;p&gt;詳細は&lt;a href=&quot;/posts/macos-audio-speaker/&quot;&gt;こちらの記事&lt;/a&gt;にまとめてあります。&lt;/p&gt;
&lt;h3&gt;マイク&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-34.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;HyperX QuadCastです。YouTuberがおすすめしていたので買いました。&lt;/p&gt;
&lt;p&gt;以前は、&lt;a href=&quot;https://amzn.to/3MA7dUO&quot;&gt;中華メーカーのUSBのコンデンサマイク&lt;/a&gt;を使っていたのですがノイズが酷かったです。マイクなんてどこも大して変わらないだろうと思っていましたが、ちゃんとしたメーカーのマイクを使う必要があると感じました。&lt;/p&gt;
&lt;p&gt;スピーカーの音を拾わないようにするためにマイクは指向性があるものが良いです。あと、結果的に良かったのは普通のハンドマイクを使うより、直立していたほうがスペースを取らなくて良いです。どうしてもマイクは顔の近くに置く必要があるため邪魔にならない形状である必要があります。&lt;/p&gt;
&lt;p&gt;物理的にmute/unmuteができるものだと楽です。ソフトウェア上でmute/unmuteをするとなると直感的ではないしすぐに操作したいときに困ります。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07NZZZ746&quot;}&lt;/p&gt;
&lt;h3&gt;キーボード&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;定番のHHKB Proです。HHKB Professional HYBRID Type-S 無刻印／墨（英語配列）&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B082TWFV9C&quot;}&lt;/p&gt;
&lt;p&gt;自作キーボードの道もありますが、カフェでノートPCを使って作業するときもあるので標準からずれないほうが良いという考えがあります。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://amzn.to/43sNJbw&quot;&gt;PFU Happy Hacking Keyboard Professional BT 無刻印/墨 PD-KB600BN&lt;/a&gt;を最初は買ったのですが、2週間ぐらいで買い替えました。たしか、PCを2台使っていて、Bluetoothによる接続切り替えができなかったためです。&lt;/p&gt;
&lt;h3&gt;マウス&lt;/h3&gt;
&lt;p&gt;トラックボールを試しに使ってます。まぁ、普通のマウスでもどっちでも大丈夫です。唯一の欠点は曲線が書きづらいのと、トラックボールを定期的に掃除しないと動きが悪くなるということです。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B074Z71C2M&quot;}&lt;/p&gt;
&lt;h3&gt;ケーブル収納&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B01N59ON4W&quot;}&lt;/p&gt;
&lt;p&gt;サンワサプライのケーブル収納するやつ。めちゃくちゃキレイに収納できるのでおすすめです。&lt;/p&gt;
&lt;p&gt;この収納トレーは、ERDシリーズ専用になっていてナットで天板に裏からビス止めできます。そのため、クランプ型だとどうしてもデスクに引っ掛ける部分が必要になりますが、こちらはデスク上には一切干渉しないです。その代わり、天板に穴あけ加工が必要になります。&lt;/p&gt;
&lt;p&gt;ネジの規格はM5 x 12mmになるので、穴側は、鬼目ナット側 &lt;a href=&quot;https://amzn.to/43wz2UR&quot;&gt;M5x10mm&lt;/a&gt;、下穴は7.5mmのビットで穴あけをしました。天板を外して作業したので2時間ぐらいかかりました。初期設置時にやっておくべきでした。&lt;/p&gt;
&lt;p&gt;以前は以下のような網のラックを使っていたのですが、クランプが卓上に見えてしまうのとケーブルが多くて収まりきらないし、ケーブル自体が見えてしまうので見た目が良くないです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;電源タップはこちらです。スピーカーそれぞれ、Google Home, モニタ、デスク裏のLED照明に電源が必要なので結構コンセントを使うので10口ぐらいは必要です。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0877666H6&quot;}&lt;/p&gt;
&lt;h3&gt;デスクLED照明&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-33.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WiFiに接続してコントロールできるフルカラーLEDテープを貼り付けています。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B087339YX8&quot;}&lt;/p&gt;
&lt;p&gt;作業中は緑色にすることで&lt;a href=&quot;https://jinjibu.jp/keyword/detl/1414/&quot;&gt;緑視率&lt;/a&gt;を上げることによる集中力向上を狙っています。&lt;/p&gt;
&lt;p&gt;このLEDテープの密度が低いので普通に貼ったら斑（まだら）になってしまいました。そこで、ピッチが異なるように上と下になるように2重に貼り付けたらドットが見えなくなってきれいに発色するようになりました。高さ違い、ピッチ違いなので影ができづらくなり、綺麗に発光しているように見えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;スマートホームと連携して始業時間に点灯するように設定して、深夜に消灯するようにしています。&lt;/p&gt;
&lt;p&gt;音に反応した照明でクラブっぽい演出もできます。電気信号でのコントロールではなく、音量を計測して発光しているので遅延が大きくて違和感あります。。。&lt;/p&gt;
&lt;p&gt;https://youtu.be/_d5A_hF68Wk&lt;/p&gt;
&lt;h3&gt;USBカメラ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;特にこだわりは無し。オートフォーカスがついているし小さいので別に不満は無いです。ティルト調整ができるので角度が変えられるのが良いです。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07QQR6G5N&quot;}&lt;/p&gt;
&lt;h3&gt;USB DAC&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-29.png&quot; alt=&quot;Fosi Audio DAC-Q4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;3回買い直してここに至ります。ちょっと無名なメーカーのアンプは数ヶ月〜数年使っていると調子が悪くなってきます。PCに認識されなくなったり、左右の音色の差が出てきたりしました。&lt;/p&gt;
&lt;p&gt;この商品は口コミ数が多くて安心できそうなので買いました。低音と高音のイコライザーがついているので多少音色の調整をアンプ側で変更できます。&lt;/p&gt;
&lt;p&gt;1年ぐらい問題なく運用できています。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07VDQQY95&quot;}&lt;/p&gt;
&lt;h3&gt;USBハブ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-30.png&quot; alt=&quot;ANKER USB hub&quot; /&gt;&lt;/p&gt;
&lt;p&gt;モニタについているUSB-Aポートだけでは足りないので増設しています。USBセキュリティキーを抜き差しするときに手元にあったほうが楽です。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07ST84PF5&quot;}&lt;/p&gt;
&lt;h3&gt;PCスタンド&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-31.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;隙間の幅をネジで調整できるのでピッタリハマるように設定できます。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07MFSK7ZB&quot;}&lt;/p&gt;
&lt;h3&gt;Google Nest mini&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-32.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Nestになってから小さいけど音質がかなり向上したので適当なBGMを流すのに使ってます。&lt;/p&gt;
&lt;h2&gt;シーンに応じた照明&lt;/h2&gt;
&lt;h3&gt;夜間の照明例&lt;/h3&gt;
&lt;p&gt;ブルーライトをカットする必要があるので、暖色で統一。&lt;/p&gt;
&lt;p&gt;暖色のスポットライトを点灯し、デスク裏のLEDテープライトを黄色に点灯した状態。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/IMG_4588.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Cyberpunkぽい例&lt;/h3&gt;
&lt;p&gt;デスクのLEDテープライトのみを点灯しただけ。ブラックライトに近い光り方をします。&lt;strong&gt;目が疲れます&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ミニモニタ&lt;/h3&gt;
&lt;p&gt;iPadを外部モニタとして使ったりもしていましたがイマイチでした。深夜にツール・ド・フランスのライブを見ながら作業するために設置しましたがどっちにも集中できないです。&lt;/p&gt;
&lt;p&gt;テレカンの画面をiPadに持ってきたり、タッチペンで操作して図形描画に使ったりもしていましたが、モニタのミラーモードと、iOSの切り替えが面倒でした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/05/image-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宅の作業環境を紹介しました。&lt;/li&gt;
&lt;li&gt;全部足すと、機材に60万円ほど。リフォームに50万円ほどかかっていると思います。&lt;/li&gt;
&lt;li&gt;ChatGPTにタイトルを付けさせたらなんか大げさなタイトルになってしまった。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Tableau serverをrpmでアップグレードする方法メモ</title><link>https://blog.teraren.com/posts/2023-05-24-tablea-userver/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2023-05-24-tablea-userver/</guid><description>以下のページから対象の rpm パッケージをダウンロードします。</description><pubDate>Wed, 24 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Tableau server は 1 年に 10 から 15 回ぐらいセキュリティ脆弱性対応や不具合対応のために新規バージョンがリリースされます。&lt;/li&gt;
&lt;li&gt;毎回一筋縄では更新できないのでメモを残しておきます。&lt;/li&gt;
&lt;li&gt;公式の手順書は &lt;a href=&quot;https://help.tableau.com/current/server-linux/ja-jp/server-upgrade-baseline-singlenode-setup.htm&quot;&gt;こちら&lt;/a&gt;になります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;やり方の例&lt;/h2&gt;
&lt;p&gt;以下のページから対象の rpm パッケージをダウンロードします。&lt;/p&gt;
&lt;p&gt;https://www.tableau.com/ja-jp/support/releases/server/2023.1.2&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget https://downloads.tableau.com/esdalt/2023.1.2/tableau-server-2023-1-2.x86_64.rpm
% wget https://downloads.tableau.com/esdalt/2023.1.2/tableau-tabcmd-2023-1-2.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;両方一気に更新してみますが、エラーが出ます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo yum install *rpm
Failed to set locale, defaulting to C
Loaded plugins: etckeeper, extras_suggestions, langpacks, priorities, update-motd
Examining tableau-server-2023-1-2.x86_64.rpm: tableau-server-20231.23.0511.1508-20231-23.0511.1508.x86_64
Marking tableau-server-2023-1-2.x86_64.rpm to be installed
Examining tableau-tabcmd-2023-1-2.noarch.rpm: tableau-tabcmd-20231.23.0511.1508-20231-23.0511.1508.noarch
Marking tableau-tabcmd-2023-1-2.noarch.rpm to be installed
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package tableau-server-20231.23.0511.1508.x86_64 0:20231-23.0511.1508 will be installed
---&amp;gt; Package tableau-tabcmd-20231.23.0511.1508.noarch 0:20231-23.0511.1508 will be installed
--&amp;gt; Finished Dependency Resolution
amzn2-core/2/x86_64                                                                                                                                                                                                                                                                  | 3.7 kB  00:00:00

Dependencies Resolved

============================================================================================================================================================================================================================================================================================================
 Package                                                                             Arch                                                     Version                                                               Repository                                                                         Size
============================================================================================================================================================================================================================================================================================================
Installing:
 tableau-server-20231.23.0511.1508                                                   x86_64                                                   20231-23.0511.1508                                                    /tableau-server-2023-1-2.x86_64                                                   4.6 G
 tableau-tabcmd-20231.23.0511.1508                                                   noarch                                                   20231-23.0511.1508                                                    /tableau-tabcmd-2023-1-2.noarch                                                    19 M

Transaction Summary
============================================================================================================================================================================================================================================================================================================
Install  2 Packages

Total size: 4.6 G
Installed size: 4.6 G
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test


Transaction check error:
  file /opt/tableau/tabcmd/NOTICES.txt from install of tableau-tabcmd-20231.23.0511.1508-20231-23.0511.1508.noarch conflicts with file from package tableau-tabcmd-20221.22.0823.1450-20221-22.0823.1450.noarch
  file /opt/tableau/tabcmd/bin/tabcmd from install of tableau-tabcmd-20231.23.0511.1508-20231-23.0511.1508.noarch conflicts with file from package tableau-tabcmd-20221.22.0823.1450-20221-22.0823.1450.noarch

Error Summary
-------------

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;tabcmdの方のパッケージにおいて、ファイルがコンフリクトしているみたいです。&lt;/p&gt;
&lt;h3&gt;tableau-server&lt;/h3&gt;
&lt;p&gt;まずはserverの方を単独で更新します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo yum install tableau-server-2023-1-2.x86_64.rpm
Failed to set locale, defaulting to C
Loaded plugins: etckeeper, extras_suggestions, langpacks, priorities, update-motd
Examining tableau-server-2023-1-2.x86_64.rpm: tableau-server-20231.23.0511.1508-20231-23.0511.1508.x86_64
Marking tableau-server-2023-1-2.x86_64.rpm to be installed
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package tableau-server-20231.23.0511.1508.x86_64 0:20231-23.0511.1508 will be installed
--&amp;gt; Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================================================================================================================================================================================
 Package                                                                             Arch                                                     Version                                                               Repository                                                                         Size
============================================================================================================================================================================================================================================================================================================
Installing:
 tableau-server-20231.23.0511.1508                                                   x86_64                                                   20231-23.0511.1508                                                    /tableau-server-2023-1-2.x86_64                                                   4.6 G

Transaction Summary
============================================================================================================================================================================================================================================================================================================
Install  1 Package

Total size: 4.6 G
Installed size: 4.6 G
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
etckeeper: pre transaction commit

Your hardware meets the minimum requirements for a trial of Tableau Server.
If you plan to run Tableau Server in a production environment, we recommend the following hardware specifications: http://www.tableau.com/products/server/specs
Tableau Server runs best with at least 128 GB memory, but found only 31 GB of memory.
Tableau Server runs best with at least 8 cores, but found only 4 core(s).

  Installing : tableau-server-20231.23.0511.1508-20231-23.0511.1508.x86_64                                                                                                                                                                                                                              1/1

Found existing installation version &apos;20223.22.1108.0821&apos; in /var/opt/tableau/tableau_server


Found existing installation version &apos;20223.22.1108.0821&apos; in /var/opt/tableau/tableau_server

After new version has been installed on every Tableau Server node, run:

    sudo /opt/tableau/tableau_server/packages/scripts.20231.23.0511.1508/upgrade-tsm --accepteula

on initial (controller) node to continue upgrading Tableau Server.

etckeeper: post transaction commit
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LC_COLLATE = &quot;C&quot;,
	LC_CTYPE = &quot;UTF-8&quot;,
	LANG = &quot;en_US.UTF-8&quot;
    are supported and installed on your system.
perl: warning: Falling back to the standard locale (&quot;C&quot;).
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LC_COLLATE = &quot;C&quot;,
	LC_CTYPE = &quot;UTF-8&quot;,
	LANG = &quot;en_US.UTF-8&quot;
    are supported and installed on your system.
perl: warning: Falling back to the standard locale (&quot;C&quot;).
  Verifying  : tableau-server-20231.23.0511.1508-20231-23.0511.1508.x86_64                                                                                                                                                                                                                              1/1

Installed:
  tableau-server-20231.23.0511.1508.x86_64 0:20231-23.0511.1508

Complete!

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更新できました。次に、規約に同意が必要なので同意します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo /opt/tableau/tableau_server/packages/scripts.20231.23.0511.1508/upgrade-tsm --accepteula
Upgrading Tableau Server to version 20231.23.0511.1508. See log file at /var/opt/tableau/tableau_server/logs/app-upgrade.log for progress.
Verifying that the upgrade script is running from the correct environment.
Validating Tableau Server version.
Verifying that the new packages have been installed on all cluster nodes.
Verifying Active Directory connection.
Verifying configuration is valid.
Performing preflight checks to ensure the server is in a good state to be upgraded.
Stopping service...
This operation will stop the server. To start server, run &apos;tsm start&apos; after the upgrade is completed. Do you want to continue?
(y/n): y
Reconnecting to asynchronous job...
Running - Disabling all services.Job id is &apos;461&apos;, timeout is 30 minutes.
50% - Disabling all services.
100% - Waiting for the services to stop.
Verifying Tableau Server is stopped.
Verifying that there is only one deployed Tableau Server Coordination Service ensemble.
Verifying that Tableau Server has been initialized.
Verifying licensing state.
Backing up repository.
Making prerequisite configuration changes prior to upgrading TSM services.
Reconnecting to asynchronous job...
Job id is &apos;462&apos;, timeout is 43 minutes.
11% - Retrieving the topology to deploy.
22% - Retrieving the configuration to deploy.
33% - Validating the new topology.
44% - Determining if server needs to be started.
55% - Updating nodes to new topology.
66% - Waiting for topology to be applied.
77% - Updating nodes to new configuration.
88% - Reconfiguring services.
100% - Waiting for services to reconfigure.
Upgrading TSM services.
Deploying new service packages.
Updating Tableau Server Coordination Service.
Updating Tableau Server Client File Service.
Adding Activation Service.
Updating configuration.
Reconnecting to asynchronous job...
Job id is &apos;463&apos;, timeout is 60 minutes.

Generating new credentials.
Reconnecting to asynchronous job...
Job id is &apos;464&apos;, timeout is 63 minutes.
7% - Generating passwords.
14% - Generating secret keys.
21% - Generating apigateway mutual SSL certificates.
28% - Generating Apache Gateway Internal mutual SSL certificates.
35% - Generating Unique Cluster Identifier.
42% - Generating Search Server SSL certificate.
50% - Generating Index And Search Server SSL certificate.
57% - Generating ActiveMQ Server SSL certificate.
64% - Generating internal Metadata API mutual SSL certificates.
71% - Generating key store.
78% - Generating Hyper SSL certificate.
85% - Generating TSIG logs service SSL certificate.
92% - Promoting configuration.
100% - Waiting for services to reconfigure.
Performing post-upgrade services and configuration operation.
Reconnecting to asynchronous job...
Job id is &apos;465&apos;, timeout is 30 minutes.
50% - Disabling all services.
100% - Waiting for the services to stop.
Updating asset keys.
Reconnecting to asynchronous job...
Job id is &apos;466&apos;, timeout is 2880 minutes.
100% - Migrating asset keys to configuration if needed.
Restoring repository.
Updating repository version in Tableau Server Coordination Service.
Updating repository.
Reconnecting to asynchronous job...
Job id is &apos;467&apos;, timeout is 120 minutes.
8% - Enabling the database services.
16% - Waiting for the database services to enable.
25% - Putting the repository into local trust mode.
33% - Creating roles and databases.
41% - Running migrations against the primary database.
50% - Setting the next active repository.
58% - Taking the repository out of local trust mode.
66% - Disabling database services.
75% - Waiting for database services to disable.
100% - Upgrading database
Updating data directory version.
Reconnecting to asynchronous job...
Job id is &apos;468&apos;, timeout is 44 minutes.
9% - Retrieving the topology to deploy.
18% - Retrieving the configuration to deploy.
27% - Validating the new topology.
36% - Determining if server needs to be started.
45% - Disabling all services.
54% - Waiting for the services to stop.
63% - Updating nodes to new topology.
72% - Waiting for topology to be applied.
81% - Updating nodes to new configuration.
90% - Reconfiguring services.
100% - Waiting for services to reconfigure.
upgrader.initializing_index_and_search_server
Rebuilding search index.
Reconnecting to asynchronous job...
Job id is &apos;469&apos;, timeout is 10 minutes.
14% - Disabling all services.
28% - Waiting for the services to stop.
42% - Starting backup restore services for search server reset.
57% - Resetting search server.
71% - Starting search server.
85% - Configuring search server.
100% - Stopping backup restore services.
Reconnecting to asynchronous job...
Job id is &apos;470&apos;, timeout is 1440 minutes.
25% - Enabling the services required for indexing.
50% - Connecting to Vizportal Maintenance.
75% - Rebuilding the search index.
100% - Disabling the services used for indexing.
Upgrading Analytics Extensions settings.
Resetting Metadata API Store.
Reconnecting to asynchronous job...
Job id is &apos;471&apos;, timeout is 10 minutes.
9% - Starting required services for resetting Metadata API Store.
18% - Stopping Metadata API Store related services.
27% - Enabling the maintenance app.
36% - Waiting for the maintenance app to start.
45% - Disabling database services.
54% - Waiting for database services to disable.
63% - Recreating Metadata API Store.
72% - Restoring Metadata API Store related services to previous state.
100% - Restoring required services to previous state.
Verifying licensing state.
Tableau Server has been upgraded to version 20231.23.0511.1508.
&amp;gt;&amp;gt; The upgraded Tableau binary directory will be added to PATH for new shells. To get the
&amp;gt;&amp;gt; updated path, either start a new session, or for bash users run:
&amp;gt;&amp;gt; source /etc/profile.d/tableau_server.sh

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;serverのパッケージを更新すると、Tableau server自体が停止するのでtsmコマンドを利用して明示的にサーバを起動します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tsm start
Starting service...
The last successful run of StartServerJob took 4 minute(s).

Job id is &apos;472&apos;, timeout is 60 minutes.

Service was started successfully.

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;tableau-cmd&lt;/h3&gt;
&lt;p&gt;一度uninstallすれば良いみたいなので、一度消してインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo yum remove tableau-tabcmd-20221.22.0823.1450-20221-22.0823.1450.noarch
% sudo yum install tableau-tabcmd-2023-1-2.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;毎回手動で作業しないといけないのが辛いです。yum で提供してほしいです。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>tableau serverをrpmでアップグレードする方法メモ</title><link>https://blog.teraren.com/posts/tableau-server-rpm-upgrade/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tableau-server-rpm-upgrade/</guid><description>Tableau ServerをLinux環境でRPMパッケージを使ってアップグレードする手順と、毎回発生しがちなエラーへの対処法をまとめた実践メモ</description><pubDate>Wed, 24 May 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;tableau serverは1年に3〜5回ぐらいセキュリティ脆弱性対応や不具合対応のために新規バージョンがリリースされます。&lt;/li&gt;
&lt;li&gt;毎回微妙に不具合が起きたりするのでメモを残しておきます。&lt;/li&gt;
&lt;li&gt;公式の手順書は&lt;a href=&quot;https://help.tableau.com/current/server-linux/ja-jp/server-upgrade-baseline-singlenode-setup.htm&quot;&gt;こちら&lt;/a&gt;になります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;やり方の例&lt;/h2&gt;
&lt;p&gt;以下のページから対象のrpmパッケージをダウンロードします。&lt;/p&gt;
&lt;p&gt;https://www.tableau.com/ja-jp/support/releases/server/2023.1.2&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget https://downloads.tableau.com/esdalt/2023.1.2/tableau-server-2023-1-2.x86_64.rpm
% wget https://downloads.tableau.com/esdalt/2023.1.2/tableau-tabcmd-2023-1-2.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;両方一気に更新してみますが、エラーが出ます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo yum install *rpm
Failed to set locale, defaulting to C
Loaded plugins: etckeeper, extras_suggestions, langpacks, priorities, update-motd
Examining tableau-server-2023-1-2.x86_64.rpm: tableau-server-20231.23.0511.1508-20231-23.0511.1508.x86_64
Marking tableau-server-2023-1-2.x86_64.rpm to be installed
Examining tableau-tabcmd-2023-1-2.noarch.rpm: tableau-tabcmd-20231.23.0511.1508-20231-23.0511.1508.noarch
Marking tableau-tabcmd-2023-1-2.noarch.rpm to be installed
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package tableau-server-20231.23.0511.1508.x86_64 0:20231-23.0511.1508 will be installed
---&amp;gt; Package tableau-tabcmd-20231.23.0511.1508.noarch 0:20231-23.0511.1508 will be installed
--&amp;gt; Finished Dependency Resolution
amzn2-core/2/x86_64                                                                                                                                                                                                                                                                  | 3.7 kB  00:00:00

Dependencies Resolved

============================================================================================================================================================================================================================================================================================================
 Package                                                                             Arch                                                     Version                                                               Repository                                                                         Size
============================================================================================================================================================================================================================================================================================================
Installing:
 tableau-server-20231.23.0511.1508                                                   x86_64                                                   20231-23.0511.1508                                                    /tableau-server-2023-1-2.x86_64                                                   4.6 G
 tableau-tabcmd-20231.23.0511.1508                                                   noarch                                                   20231-23.0511.1508                                                    /tableau-tabcmd-2023-1-2.noarch                                                    19 M

Transaction Summary
============================================================================================================================================================================================================================================================================================================
Install  2 Packages

Total size: 4.6 G
Installed size: 4.6 G
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test

Transaction check error:
  file /opt/tableau/tabcmd/NOTICES.txt from install of tableau-tabcmd-20231.23.0511.1508-20231-23.0511.1508.noarch conflicts with file from package tableau-tabcmd-20221.22.0823.1450-20221-22.0823.1450.noarch
  file /opt/tableau/tabcmd/bin/tabcmd from install of tableau-tabcmd-20231.23.0511.1508-20231-23.0511.1508.noarch conflicts with file from package tableau-tabcmd-20221.22.0823.1450-20221-22.0823.1450.noarch

Error Summary
-------------
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;tabcmdの方のパッケージにおいて、ファイルがコンフリクトしているみたいです。&lt;/p&gt;
&lt;h3&gt;tableau-server&lt;/h3&gt;
&lt;p&gt;まずはserverの方を単独で更新します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo yum install tableau-server-2023-1-2.x86_64.rpm
Failed to set locale, defaulting to C
Loaded plugins: etckeeper, extras_suggestions, langpacks, priorities, update-motd
Examining tableau-server-2023-1-2.x86_64.rpm: tableau-server-20231.23.0511.1508-20231-23.0511.1508.x86_64
Marking tableau-server-2023-1-2.x86_64.rpm to be installed
Resolving Dependencies
--&amp;gt; Running transaction check
---&amp;gt; Package tableau-server-20231.23.0511.1508.x86_64 0:20231-23.0511.1508 will be installed
--&amp;gt; Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================================================================================================================================================================================
 Package                                                                             Arch                                                     Version                                                               Repository                                                                         Size
============================================================================================================================================================================================================================================================================================================
Installing:
 tableau-server-20231.23.0511.1508                                                   x86_64                                                   20231-23.0511.1508                                                    /tableau-server-2023-1-2.x86_64                                                   4.6 G

Transaction Summary
============================================================================================================================================================================================================================================================================================================
Install  1 Package

Total size: 4.6 G
Installed size: 4.6 G
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
etckeeper: pre transaction commit

Your hardware meets the minimum requirements for a trial of Tableau Server.
If you plan to run Tableau Server in a production environment, we recommend the following hardware specifications: http://www.tableau.com/products/server/specs
Tableau Server runs best with at least 128 GB memory, but found only 31 GB of memory.
Tableau Server runs best with at least 8 cores, but found only 4 core(s).

  Installing : tableau-server-20231.23.0511.1508-20231-23.0511.1508.x86_64                                                                                                                                                                                                                              1/1

Found existing installation version &apos;20223.22.1108.0821&apos; in /var/opt/tableau/tableau_server

Found existing installation version &apos;20223.22.1108.0821&apos; in /var/opt/tableau/tableau_server

After new version has been installed on every Tableau Server node, run:

    sudo /opt/tableau/tableau_server/packages/scripts.20231.23.0511.1508/upgrade-tsm --accepteula

on initial (controller) node to continue upgrading Tableau Server.

etckeeper: post transaction commit
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LC_COLLATE = &quot;C&quot;,
	LC_CTYPE = &quot;UTF-8&quot;,
	LANG = &quot;en_US.UTF-8&quot;
    are supported and installed on your system.
perl: warning: Falling back to the standard locale (&quot;C&quot;).
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LC_COLLATE = &quot;C&quot;,
	LC_CTYPE = &quot;UTF-8&quot;,
	LANG = &quot;en_US.UTF-8&quot;
    are supported and installed on your system.
perl: warning: Falling back to the standard locale (&quot;C&quot;).
  Verifying  : tableau-server-20231.23.0511.1508-20231-23.0511.1508.x86_64                                                                                                                                                                                                                              1/1

Installed:
  tableau-server-20231.23.0511.1508.x86_64 0:20231-23.0511.1508

Complete!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更新できました。次に、規約に同意が必要なので同意します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo /opt/tableau/tableau_server/packages/scripts.20231.23.0511.1508/upgrade-tsm --accepteula
Upgrading Tableau Server to version 20231.23.0511.1508. See log file at /var/opt/tableau/tableau_server/logs/app-upgrade.log for progress.
Verifying that the upgrade script is running from the correct environment.
Validating Tableau Server version.
Verifying that the new packages have been installed on all cluster nodes.
Verifying Active Directory connection.
Verifying configuration is valid.
Performing preflight checks to ensure the server is in a good state to be upgraded.
Stopping service...
This operation will stop the server. To start server, run &apos;tsm start&apos; after the upgrade is completed. Do you want to continue?
(y/n): y
Reconnecting to asynchronous job...
Running - Disabling all services.Job id is &apos;461&apos;, timeout is 30 minutes.
50% - Disabling all services.
100% - Waiting for the services to stop.
Verifying Tableau Server is stopped.
Verifying that there is only one deployed Tableau Server Coordination Service ensemble.
Verifying that Tableau Server has been initialized.
Verifying licensing state.
Backing up repository.
Making prerequisite configuration changes prior to upgrading TSM services.
Reconnecting to asynchronous job...
Job id is &apos;462&apos;, timeout is 43 minutes.
11% - Retrieving the topology to deploy.
22% - Retrieving the configuration to deploy.
33% - Validating the new topology.
44% - Determining if server needs to be started.
55% - Updating nodes to new topology.
66% - Waiting for topology to be applied.
77% - Updating nodes to new configuration.
88% - Reconfiguring services.
100% - Waiting for services to reconfigure.
Upgrading TSM services.
Deploying new service packages.
Updating Tableau Server Coordination Service.
Updating Tableau Server Client File Service.
Adding Activation Service.
Updating configuration.
Reconnecting to asynchronous job...
Job id is &apos;463&apos;, timeout is 60 minutes.

Generating new credentials.
Reconnecting to asynchronous job...
Job id is &apos;464&apos;, timeout is 63 minutes.
7% - Generating passwords.
14% - Generating secret keys.
21% - Generating apigateway mutual SSL certificates.
28% - Generating Apache Gateway Internal mutual SSL certificates.
35% - Generating Unique Cluster Identifier.
42% - Generating Search Server SSL certificate.
50% - Generating Index And Search Server SSL certificate.
57% - Generating ActiveMQ Server SSL certificate.
64% - Generating internal Metadata API mutual SSL certificates.
71% - Generating key store.
78% - Generating Hyper SSL certificate.
85% - Generating TSIG logs service SSL certificate.
92% - Promoting configuration.
100% - Waiting for services to reconfigure.
Performing post-upgrade services and configuration operation.
Reconnecting to asynchronous job...
Job id is &apos;465&apos;, timeout is 30 minutes.
50% - Disabling all services.
100% - Waiting for the services to stop.
Updating asset keys.
Reconnecting to asynchronous job...
Job id is &apos;466&apos;, timeout is 2880 minutes.
100% - Migrating asset keys to configuration if needed.
Restoring repository.
Updating repository version in Tableau Server Coordination Service.
Updating repository.
Reconnecting to asynchronous job...
Job id is &apos;467&apos;, timeout is 120 minutes.
8% - Enabling the database services.
16% - Waiting for the database services to enable.
25% - Putting the repository into local trust mode.
33% - Creating roles and databases.
41% - Running migrations against the primary database.
50% - Setting the next active repository.
58% - Taking the repository out of local trust mode.
66% - Disabling database services.
75% - Waiting for database services to disable.
100% - Upgrading database
Updating data directory version.
Reconnecting to asynchronous job...
Job id is &apos;468&apos;, timeout is 44 minutes.
9% - Retrieving the topology to deploy.
18% - Retrieving the configuration to deploy.
27% - Validating the new topology.
36% - Determining if server needs to be started.
45% - Disabling all services.
54% - Waiting for the services to stop.
63% - Updating nodes to new topology.
72% - Waiting for topology to be applied.
81% - Updating nodes to new configuration.
90% - Reconfiguring services.
100% - Waiting for services to reconfigure.
upgrader.initializing_index_and_search_server
Rebuilding search index.
Reconnecting to asynchronous job...
Job id is &apos;469&apos;, timeout is 10 minutes.
14% - Disabling all services.
28% - Waiting for the services to stop.
42% - Starting backup restore services for search server reset.
57% - Resetting search server.
71% - Starting search server.
85% - Configuring search server.
100% - Stopping backup restore services.
Reconnecting to asynchronous job...
Job id is &apos;470&apos;, timeout is 1440 minutes.
25% - Enabling the services required for indexing.
50% - Connecting to Vizportal Maintenance.
75% - Rebuilding the search index.
100% - Disabling the services used for indexing.
Upgrading Analytics Extensions settings.
Resetting Metadata API Store.
Reconnecting to asynchronous job...
Job id is &apos;471&apos;, timeout is 10 minutes.
9% - Starting required services for resetting Metadata API Store.
18% - Stopping Metadata API Store related services.
27% - Enabling the maintenance app.
36% - Waiting for the maintenance app to start.
45% - Disabling database services.
54% - Waiting for database services to disable.
63% - Recreating Metadata API Store.
72% - Restoring Metadata API Store related services to previous state.
100% - Restoring required services to previous state.
Verifying licensing state.
Tableau Server has been upgraded to version 20231.23.0511.1508.
&amp;gt;&amp;gt; The upgraded Tableau binary directory will be added to PATH for new shells. To get the
&amp;gt;&amp;gt; updated path, either start a new session, or for bash users run:
&amp;gt;&amp;gt; source /etc/profile.d/tableau_server.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;serverのパッケージを更新すると、tableau server自体が停止するのでtsmコマンドで手動で起動します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tsm start
Starting service...
The last successful run of StartServerJob took 4 minute(s).

Job id is &apos;472&apos;, timeout is 60 minutes.

Service was started successfully.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;tableau-cmd&lt;/h3&gt;
&lt;p&gt;一度uninstallすれば良いみたいなので、一度消してインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo yum remove tableau-tabcmd-20221.22.0823.1450-20221-22.0823.1450.noarch
% sudo yum install tableau-tabcmd-2023-1-2.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;おわり&lt;/p&gt;
</content:encoded></item><item><title>個人開発のWebサービスをCloudflareに載せてみた【無料でここまでできる】</title><link>https://blog.teraren.com/posts/web-service-on-cloudflare/</link><guid isPermaLink="true">https://blog.teraren.com/posts/web-service-on-cloudflare/</guid><description>個人開発のWebサービスにCloudflareの無料プランを導入し、CDN・DDoS対策・WAF・自宅サーバのポート隠蔽まで実現する方法とその設定事例を紹介します。</description><pubDate>Sun, 23 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;私は個人でWebサイトやWebサービスを色々公開しております。&lt;/p&gt;
&lt;p&gt;この度、個人開発でWebサービスを運用するときにCloudflareを利用すると様々なリスクを無料でヘッジできるので事例を紹介します。&lt;/p&gt;
&lt;p&gt;しかも&lt;strong&gt;無料&lt;/strong&gt;です。&lt;/p&gt;
&lt;h2&gt;個人開発サービスの問題&lt;/h2&gt;
&lt;h3&gt;費用をかけられない&lt;/h3&gt;
&lt;p&gt;お金をかければWAFや計算処理の高いサーバやコンテナなどの環境を使えますが、テストで開発したサービスや収益化するかどうかわからないサービスをたくさん運用することになるので固定費は可能な限り抑える必要があります。&lt;/p&gt;
&lt;p&gt;いかに安く安定的にサービスを提供できるかは腕の見せどころでもあります。&lt;/p&gt;
&lt;h3&gt;複数サービスがダウンする可能性&lt;/h3&gt;
&lt;p&gt;固定費を抑えるために1ホストにいろいろなサービスを動かすことが多いと思います。&lt;/p&gt;
&lt;p&gt;よって、1つのサービスに対してDoS攻撃や突発的にWeb上でバズって大量のトラフィックが来ると捌ききれなくなってあるホストで運用しているサービスがすべてダウンしてしまうリスクがあります。&lt;/p&gt;
&lt;h3&gt;自宅サーバの場合はポートを解放しないといけない&lt;/h3&gt;
&lt;p&gt;費用を抑えるために自宅サーバを運用して居る場合もあると思いますが、自宅サーバを公開するためにはポートを開放する必要があります。また、ホストレベルでクラックされた場合には自宅LANに第三者が入れる状態になってしまうリスクがあります。&lt;/p&gt;
&lt;h2&gt;Cloudflareとは&lt;/h2&gt;
&lt;p&gt;主なサービスは、コンテンツ配信ネットワーク（CDN）、DDoS攻撃防御、Webアプリケーションファイアウォール（WAF）などのセキュリティ機能、およびインターネット最適化を提供します。Cloudflareの主な機能は以下になります。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;コンテンツ配信ネットワーク (CDN)&lt;/li&gt;
&lt;li&gt;DDoS保護&lt;/li&gt;
&lt;li&gt;Webアプリケーションファイアウォール (WAF)&lt;/li&gt;
&lt;li&gt;SSL/TLS暗号化&lt;/li&gt;
&lt;li&gt;DNSサービス&lt;/li&gt;
&lt;li&gt;Zero Trustセキュリティ&lt;/li&gt;
&lt;li&gt;エッジコンピューティング&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;これ以外にもたくさんのWebサービスを運用する上で便利な機能があります。&lt;/p&gt;
&lt;p&gt;概念的には以下のようなイメージです。主にレイヤー7のアプリケーション層においてのリスクをCloudflareで全部受け止めてくれるような使い方ができます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Cloudflareのダッシュボードをチラ見せしますとこんな感じになります。左のメニューを見てもらうとわかると思うのですが、Webサービスを運用する上で便利な機能が用意されています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-17.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;変更前インフラ&lt;/h2&gt;
&lt;p&gt;おそらく、個人開発しているサービスや小規模サービスは以下のようなインフラ構成になっていると思います。&lt;/p&gt;
&lt;p&gt;AWSでいえば、アプリケーションサーバはEC2やAWS Lightsail、自宅サーバで動かして、CDNに乗せられるようなコンテンツはCloud Frontを使うと言ったような感じです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-18.png&quot; alt=&quot;個人開発サービス・インフラデプロイ図&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上記の構成であれば、無料枠で収まるかなと思います。&lt;/p&gt;
&lt;p&gt;上記の構成を少し先に進めるために、WAFを入れたり、TLS証明書の自動更新を入れたりすると毎月数万円の金額がかかってきます。&lt;/p&gt;
&lt;h2&gt;Cloudflareでの設定&lt;/h2&gt;
&lt;h3&gt;フェーズ1&lt;/h3&gt;
&lt;p&gt;Cloudflareを利用するためにはドメインが切られている必要があり、zoneサーバをCloudflareでホスティングする必要があります。&lt;/p&gt;
&lt;p&gt;CloudflareのDNSだけを使うだけでも無料で運用できるのでそれだけでも価値はあったりしますが、まずはCloudflareの恩恵を受けるためには以下のような構成を作るのが1歩目です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;「Cloudflare as CDN」と書かれている部分が普通の概念とは異なるのですが、&lt;strong&gt;CDNとざっくり書いてしまいましがこの部分がCloudflareの超重要な部分&lt;/strong&gt;です。そして説明しづらいところなのであんまりCloudflareが認知されていない理由にもなっているのかなと思います。&lt;/p&gt;
&lt;p&gt;分かりやすく説明するために、1つのメインの機能としては、&lt;strong&gt;TLS termination&lt;/strong&gt;と&lt;strong&gt;Reverse Proxy&lt;/strong&gt;が動作しています。それにより、外部からの攻撃、リクエスト内容の検証、originへのトラフィックの制御を行えるようになっています。&lt;/p&gt;
&lt;p&gt;次に、設定の手順の概略を書いておきます。&lt;/p&gt;
&lt;h4&gt;DNS zoneの登録&lt;/h4&gt;
&lt;p&gt;なにはともあれ、Cloudflareを使うための第1ステップはドメインのzoneを登録するところからです。&lt;/p&gt;
&lt;p&gt;例えば、CloudflareのCDN（無料）だけを使いたかったとしてもDNS zoneをCloudflare上でホスティングする必要があります。Cloudflareの恩恵は受けられませんが、CloudflareのDNS zoneホスティングだけを使うと言ったことも無料で可能です。&lt;/p&gt;
&lt;p&gt;（スクショは英語ですが、すべて日本語の表示もできます）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;zoneを登録したら、各レコードを追加していきます。&lt;/p&gt;
&lt;p&gt;レコードを追加する際に普通とは違うのが、&quot;Proxy status&quot; というスイッチがあることです。このスイッチをonにするとDNS zoneサーバのレスポンスは登録したIPアドレスなどではなく、CloudflareのReverse proxyサーバのアドレスに置き換わります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair &lt;em&gt;/}
では、”Proxy status”をonにしたら左の項目に登録したIPアドレスはどう扱われるのかといいますと、Reverse Proxyのoriginのホストとして扱われます。
{/&lt;/em&gt; textlint-enable ja-technical-writing/no-unmatched-pair */}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;独特な概念ではあって最初からつまずきやすいですが、一度理解してしまえば大丈夫ですし、段階的に切り替えられます。まずはReverse proxyを&lt;strong&gt;off&lt;/strong&gt;にした状態でDNS zoneを移行するのが良いです。&lt;/p&gt;
&lt;p&gt;この&lt;a href=&quot;http://blog.teraren.com&quot;&gt;blog.teraren.com&lt;/a&gt;のサイト自体もCloudflareを使っているのでDNSを引くとReverse proxyのアドレスが返ってきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Reverse proxyで受けられるようにoriginを設定&lt;/h4&gt;
&lt;p&gt;既存のはorigin側のwebサーバの設定では、グローバルからリクエストを受ける設定になっているのでreverse proxyからアクセスを受けられるように設定します。&lt;/p&gt;
&lt;p&gt;今までは、ユーザに見せるホスト名でのTLS terminationなどを行ったいた設定をreverse proxyからのアクセスを前提とした設定にします。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://serverok.in/nginx-reverse-proxy-behind-cloudflare&quot;&gt;設定例: Configure Nginx Reverse Proxy behind Cloudflare&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;キャッシュルールの設定&lt;/h4&gt;
&lt;p&gt;Reverse Proxy自体がCDN機能を持っているので、どのコンテンツをキャッシュするかどうかを設定します。&lt;/p&gt;
&lt;p&gt;WebからわかりやすいUIで設定できるので自分のホスティングするサービスに応じてルールを書いていきます。&lt;/p&gt;
&lt;p&gt;無料だと10個までしかルールセットを作れません。私は&lt;strong&gt;キャッシュの期間ごとにルールセット&lt;/strong&gt;を作っています。&lt;/p&gt;
&lt;p&gt;1ヶ月キャッシュ、7日キャッシュ、1日キャッシュ、キャッシュ無しという分類です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-24.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;（2つ目と3つ目は同義です。もともとは別の期間を設定していた名残です。）&lt;/p&gt;
&lt;p&gt;私の環境における「キャッシュ無し」のスクショを書いておきます。&lt;/p&gt;
&lt;p&gt;WordPressの管理画面、ヘルスチェック用エンドポイント、動的なスクリプト、RSSフィードなどを記載してあります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;逆に1ヶ月の長期間を設定している設定はこちらになります。主に画像などの静的アセットになります。昨今はCDNを考慮したアセットの構築が行われているので内容が変わればURLも変わるという前提のためです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-27.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;CDN周りだけでも以下のような設定が簡単に行えます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Query Stringごとにキャッシュするかどうか&lt;/li&gt;
&lt;li&gt;ブラウザキャッシュのヘッダを付加するか&lt;/li&gt;
&lt;li&gt;Originが落ちたときにキャッシュをサーブするか&lt;/li&gt;
&lt;li&gt;CDNの一時的に一括無効化&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;CloudflareのCDNのすごいところはinvalidationが数秒で終わることです。Amazonだと数分とかかかったりしちゃいますが。&lt;/p&gt;
&lt;h4&gt;統計情報&lt;/h4&gt;
&lt;p&gt;Reverse ProxyとCDNを使いだすと以下のような統計情報が表示されてきます。眺めているだけでも楽しいです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-30.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;右にあるメニューに注目してほしいのですが、もしサービスが攻撃を受けていたら一時的に「Javascriptによる人間かどうかのチャレンジを挟む」というスイッチがあるのでONにすればoriginのサービスを過負荷から守れます。&lt;/p&gt;
&lt;p&gt;トラフィックの統計も細かく表示されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-29.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Webサイトへの攻撃に関する統計情報&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-31.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;プロトコルやどれだけ待機を節約できたかの情報も表示されます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;30日で見てみると、300GBのトラフィックを節約できたみたいです。&lt;/strong&gt;（無駄なトラフィックを節約することでCO2削減にも貢献！）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-32.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;WordPressの設定&lt;/h4&gt;
&lt;p&gt;WordPress用にCloudflareの&lt;a href=&quot;https://wordpress.org/plugins/cloudflare/&quot;&gt;プラグイン&lt;/a&gt;が用意されています。&lt;/p&gt;
&lt;p&gt;インストールしなくても使えることは使えるのですが、記事を更新すると自動でCDNの関連ページをpurgeしてくれます。あと、CDNでWordPressを運用するにあたってWordPressの挙動を勝手に裏で変更しているようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-38.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Cloudflare CDN を使う場合はこのプラグインは必須と言っていいです。物理的にはインストールしなくても動きますが、様々な運用上のユースケースに対応する機能が入っているので、入れておかないと予想外のコンテンツがキャッシュされてしまうリスクがあります。&lt;/p&gt;
&lt;p&gt;内部でどんなことをやっているのか軽く紹介します。&lt;/p&gt;
&lt;h5&gt;管理者ログイン時のキャッシュバイパス&lt;/h5&gt;
&lt;p&gt;WordPressは動的にページを生成しているので、管理者が記事を閲覧したときと一般ユーザが閲覧したときではコンテンツの内容が異なります（管理バーの表示など）。このプラグインは管理者がログインしている場合は CDN のキャッシュを使わないようにしてくれます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public function initAutomaticPlatformOptimization()
{
    // it could be too late to set the headers,
    // return early without triggering a warning in logs
    if (headers_sent()) {
        return;
    }

    // add header unconditionally so we can detect plugin is activated
    $cache = apply_filters(&apos;cloudflare_use_cache&apos;, !is_user_logged_in());
    if ($cache) {
        header(&apos;cf-edge-cache: cache,platform=wordpress&apos;);
    } else {
        header(&apos;cf-edge-cache: no-cache&apos;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;is_user_logged_in()&lt;/code&gt; で判定して、ログイン中は &lt;code&gt;cf-edge-cache: no-cache&lt;/code&gt; ヘッダを送信することで CDN にキャッシュさせない仕組みです。&lt;/p&gt;
&lt;h5&gt;記事・コメント更新時の自動キャッシュパージ&lt;/h5&gt;
&lt;p&gt;記事やコメントが更新されたら CDN の関連するページを自動で削除してくれます。Cloudflare の CDN は削除命令を出してから数秒で反映されるのでほぼリアルタイムです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public function purgeCacheOnPostStatusChange($new_status, $old_status, $post)
{
    if (&apos;publish&apos; === $new_status || &apos;publish&apos; === $old_status) {
        $this-&amp;gt;purgeCacheByRelevantURLs($post-&amp;gt;ID);
    }
}

public function purgeCacheOnCommentStatusChange($new_status, $old_status, $comment)
{
    if (!isset($comment-&amp;gt;comment_post_ID) || empty($comment-&amp;gt;comment_post_ID)) {
        return; // nothing to do
    }

    // in case the comment status changed, and either old or new status is &quot;approved&quot;,
    // we need to purge cache for the corresponding post
    if (($old_status != $new_status) &amp;amp;&amp;amp;
        (($old_status === &apos;approved&apos;) || ($new_status === &apos;approved&apos;))) {
        $this-&amp;gt;purgeCacheByRelevantURLs($comment-&amp;gt;comment_post_ID);
        return;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;記事のステータスが &lt;code&gt;publish&lt;/code&gt; に変わったとき、またはコメントのステータスが &lt;code&gt;approved&lt;/code&gt; に変わったときに関連URLのキャッシュをパージしています。この仕組みがあるおかげで、記事を更新したのにキャッシュが古いままという問題を気にしなくて済みます。&lt;/p&gt;
&lt;h4&gt;まとめ&lt;/h4&gt;
&lt;p&gt;IPv6対応、HTTP3/QUICK対応、DDoS対策、TLS証明書更新自動化、HSTS設定、CDN利用、DNSSECが行えてます。今までは自分で頑張って設定していたことがもうすでに用意されている感じです。&lt;/p&gt;
&lt;p&gt;Cloudfalreは昨今の面倒なWebサイト運用における設定をWebサービスの1レイヤー上で面倒を見てくれるようなサービスです。&lt;/p&gt;
&lt;p&gt;しかも&lt;strong&gt;無料&lt;/strong&gt;。。。申し訳なくなってきます。&lt;/p&gt;
&lt;h3&gt;フェーズ2&lt;/h3&gt;
&lt;p&gt;フェーズ1からより安全にする方法です。&lt;/p&gt;
&lt;p&gt;これにより、E2EEが実現でき、&lt;strong&gt;origin側のポート開放が不要&lt;/strong&gt;になってよりセキュアにサービス運用を行えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;tunnelのセットアップ&lt;/h4&gt;
&lt;p&gt;origin側にCloudflareのdaemonを動かして、tunnelを設定できます。cloudflareとoriginの間のトラフィックをこのtunnelを通すことによって&lt;strong&gt;originサーバ側でポート開放をする必要が無くなります&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;tunnelを使うためにはCloudflare上のZero Trustの管理画面で設定します。&lt;/p&gt;
&lt;p&gt;1ホストに対して1本のトンネルを作ってある設定例です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-33.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;daemonのインストールも非常に楽で管理画面上に表示されている例にあるコマンドを叩くだけです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-34.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下のようにpublicのホスト名と、originのサービス名を登録していきます。ここで登録するとCloudflareのDNSの設定にレコードが追加されていきます。既存のレコードと重複する場合はエラーが出ます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;tunnel経由でoriginへアクセス&lt;/h4&gt;
&lt;p&gt;1つ前のトンネルの設定をする際に、Cloudflareとoriginの通信を安全にしておくことをおすすめします。ブラウザとCloudflare間の設定はグローバルなのでLet&apos;s encryptといった枠組みでTLS証明書の発行と運用簡単に設定できますが、originへのアクセスはprivateネットワークなのでそう簡単にはできません。&lt;/p&gt;
&lt;p&gt;そこで、Cloudflareが発行する証明書をoriginサーバにインストールすることでCloudflareから発行された証明書がインストールされたoriginサーバということを担保する証明書を利用します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-23.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;その設定が完了すれば、上記のようにCloudflareを挟んでも安全にoriginの信頼性を保証できることになります。&lt;/p&gt;
&lt;p&gt;Cloudflare上ではこのことをE2EEと呼んでますが、TLS terminationをCloudflare上で行っているのでE2Eでの秘匿性と、完全制は保証できないですね。紛らわしいです。&lt;/p&gt;
&lt;p&gt;また、ここでは触れませんがsshなどのサービスもzero trustのサービスによってtunnel経由でアクセスできるように設定できるのでsshのポートすら空けないですみます。&lt;/p&gt;
&lt;h4&gt;BICはOFFにしたほうが良さそう&lt;/h4&gt;
&lt;p&gt;Security &amp;gt; Settingメニューに有るBrowser Integrity Checkはオフにしたほうが良さそうです。プログラムからアクセスされるAPIサービスを運用していると、このルールによってblockされているリクエストが存在します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-43.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;24時間以内に10件くらいがブロックされてしまっていました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-44.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Cloudflareの有料機能&lt;/h3&gt;
&lt;p&gt;これまでの設定はすべて無料で行える範囲です。トラフィックがどんなに増えても無料です。&lt;/p&gt;
&lt;p&gt;課金すれば、もっと良いサービスを利用できるので将来使いそうなサービスをいくつか紹介しておきます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Waiting page&lt;br /&gt;
急にサイトに大量のトラフィックが来たときに、Cloudflareでの待機ルームを表示してoriginが空くまでユーザを待たせる機能。チケット予約サイトとかはこれを使えば一発解決します。&lt;/li&gt;
&lt;li&gt;Image compression&lt;br /&gt;
pngやjpgなどの画像を次世代圧縮形式であるwebpに変換してブラウザにサーブしてくれる機能です。サーバサイドで色々設定しなくても済みます。&lt;/li&gt;
&lt;li&gt;Advanced WAF&lt;br /&gt;
怪しいアクセスをHTTPリクエストの内容を見て判断してくれます。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;Cloudflareを導入してみて大きく変わったことを書いておきます。&lt;/p&gt;
&lt;h3&gt;レスポンスタイムが超速い&lt;/h3&gt;
&lt;p&gt;CDNにキャッシュされると表示が一瞬で終わります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ab -c 5 -n 20 https://blog.teraren.com | grep &apos;Time per request&apos;
Time per request:       30.551 [ms] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;今見ているこのページをリロードしてみると、ブラウザキャッシュが読み込んだかのような速さで表示されると思います。&lt;/p&gt;
&lt;p&gt;wrk を使ってもう少し詳しくベンチマークしてみました。まずは CDN 経由のリクエスト。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ wrk  &apos;https://blog.teraren.com/&apos;
Running 10s test @ https://blog.teraren.com/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    28.82ms   90.99ms   1.40s    98.65%
    Req/Sec   257.79     43.32   353.00     73.50%
  5147 requests in 10.03s, 2.06GB read
Requests/sec:    512.91
Transfer/sec:    210.53MB
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;512.91req/sec&lt;/strong&gt;、平均レイテンシ &lt;strong&gt;28.82ms&lt;/strong&gt; です。&lt;/p&gt;
&lt;p&gt;参考までに WordPress の動的ページを直接叩いてベンチマークしてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;❯ wrk  -H &apos;Host: blog.teraren.com&apos; http://localhost:8080/
Running 10s test @ http://localhost:8080/
  2 threads and 10 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   611.64ms   94.75ms 948.43ms   74.05%
    Req/Sec     9.68      5.43    30.00     72.22%
  158 requests in 10.02s, 64.64MB read
Requests/sec:     15.77
Transfer/sec:      6.45MB
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;15.77req/sec&lt;/strong&gt;、平均レイテンシ &lt;strong&gt;611.64ms&lt;/strong&gt; でした。&lt;/p&gt;
&lt;p&gt;つまり、CDN を挟むことでスループットが &lt;strong&gt;約34倍&lt;/strong&gt;、レスポンス速度が &lt;strong&gt;約21倍&lt;/strong&gt; 改善しています。ここまで差が出ると CDN を使わない理由がありません。&lt;/p&gt;
&lt;p&gt;WordPressで運用しているサイトはそのままで運用しているとキャパが少ないので普通は&lt;a href=&quot;https://ja.wordpress.org/plugins/wp-super-cache/&quot;&gt;WP Super Cache&lt;/a&gt;を入れて運用すると思いますが、Cloudflare CDN を使えばページキャッシュは CDN 側でやってくれるので、cache関連のプラグインもこの際にすべて削除しました。&lt;/p&gt;
&lt;h3&gt;Webサーバ側の設定が激減&lt;/h3&gt;
&lt;p&gt;WordPressのサイトでは1サイトあたり約100行削減できました。&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-successive-word &lt;em&gt;/}
HTTPのリダイレクト、HSTS、text compressionの設定などなどを削減できてメンテナンス性が上がります。
{/&lt;/em&gt; textlint-enable */}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# git diff --stat a9d832ed7f1493ea0ce8e75664e7a1b70f95760e matsu.teraren.com.conf
 nginx/conf.d/matsu.teraren.com.conf | 178 ++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------
 1 file changed, 40 insertions(+), 138 deletions(-)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;TLS証明書更新から開放&lt;/h3&gt;
&lt;p&gt;以前はcertbotで自動で更新を書けていても、知らない間に動かなくなっていたりとか設定ファイルが変わっていたりして結局は手での運用が発生してしまっていました。&lt;/p&gt;
&lt;p&gt;Let&apos;s encryptからの更新のお知らせのメールも一切期にしなくて良くなるので運用の手間からかなり開放されました。&lt;/p&gt;
&lt;p&gt;TLS証明書に関連しては、HTTPからHTTPSのリダイレクト設定がスイッチ1つで行えたり、HSTSのヘッダ送信がUI上から行えるので非常に楽です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-36.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;HSTSの設定項目。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;自宅サーバ用の固定IPまたはDynamic DNSが不要&lt;/h3&gt;
&lt;p&gt;tunnelをCloudflareに張るだけなのでローカルで動いているサービスをインターネット上に公開できるので自宅の回線に固定IPアドレスやDynamic DNSが不要になりました。&lt;/p&gt;
&lt;p&gt;自宅ネットワークにDMZを作ったりVLANを切っている場合は、設定を無くせる場合もあります。（セキュリティ要件に応じてですが）&lt;/p&gt;
&lt;h3&gt;ポート開放が無くなった&lt;/h3&gt;
&lt;p&gt;外部から自宅のネットワークのポート開放を一切無くせました。Web系、SSHなどのリモートアクセス、場合によってはVPN関係のサービスを無くせます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ nmap &amp;lt;my home address&amp;gt;
Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-22 11:40 JST
Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn
Nmap done: 1 IP address (0 hosts up) scanned in 3.04 seconds
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;自宅のIPアドレスを晒さなくても良くなったので安心感があります。&lt;/p&gt;
&lt;p&gt;Webページのパフォーマンススコアが向上&lt;/p&gt;
&lt;p&gt;Webサイトのベストプラクティスを自動的に、または簡単に導入できるためGT metrixのスコアが上がります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/img_2751.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;最初はCloudflareのCDNが無料なので調査していたら、CloudflareはCDN以外の機能もかなり充実していてしかも無料で使えるサービスが沢山あるので今回は無料で使えるサービスをフルに活用して安全で安定的なサービス提供をできるように設定をしました。&lt;/p&gt;
&lt;p&gt;最初の設定が大変ですし、知識が必要になりますがその後は安心して高速で安全なWebサービスの提供を行えるようになります。&lt;/p&gt;
</content:encoded></item><item><title>AtlassianをSP、Google WorkspaceをIdPとしてSAMLを設定する方法</title><link>https://blog.teraren.com/posts/atlassian-saml-google-workspace/</link><guid isPermaLink="true">https://blog.teraren.com/posts/atlassian-saml-google-workspace/</guid><description>AtlassianとGoogle WorkspaceのSAML連携で証明書が切れた際の更新手順。Google管理コンソール側2箇所とAtlassian管理画面の3箇所を設定する方法を解説</description><pubDate>Thu, 20 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;SAMLの証明書が切れたので設定箇所をメモしておきます。&lt;/p&gt;
&lt;p&gt;SAMLに関する設定は2箇所あるので、両方を適切に設定する必要があります。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://support.atlassian.com/ja/provisioning-users/docs/connect-to-g-suite/&quot;&gt;Atlassianのドキュメント&lt;/a&gt;には設定1に関する事項しか載っていないので不十分でした。&lt;/p&gt;
&lt;h2&gt;設定1&lt;/h2&gt;
&lt;p&gt;SAMLの証明書マスタの設定。有効期限が未来の証明書を作っておく&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://admin.google.com/ac/security/ssocert&quot;&gt;https://admin.google.com/ac/security/ssocert&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;設定2&lt;/h2&gt;
&lt;p&gt;Atlassianアプリの設定側で、設定1で作成した証明書を選択しておく。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://admin.google.com/ac/apps/saml/93648076211/sp&quot;&gt;https://admin.google.com/ac/apps/saml/93648076211/sp&lt;/a&gt; （数字のところが各自違うかも）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;設定3&lt;/h2&gt;
&lt;p&gt;Atlassianの管理画面での設定です。&lt;/p&gt;
&lt;p&gt;以下のような感じでURLや証明書をコピペします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;注意&lt;/h2&gt;
&lt;p&gt;証明書は5年とかで切れるので、手動で更新する必要があります。&lt;/p&gt;
</content:encoded></item><item><title>末尾の半角スペースで困惑：ActiveModelとMySQLの連携問題</title><link>https://blog.teraren.com/posts/mysql-pad-space-and-active-record/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-pad-space-and-active-record/</guid><description>MySQLのPAD SPACEルールによりuniqueness検証で末尾スペース違いの値が重複扱いになる原因と、ActiveRecordとRSpecでの検証・回避策を解説します。</description><pubDate>Fri, 14 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ActiveModelのuniqueがあるアトリビュートの末尾に半角スペースがあると挙動がおかしくなるケースがありました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;以下のようにcodeがユニークなアトリビュートを定義してあるとします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class Product &amp;lt; ApplicationRecord
  validates :code, presence: true
  validates :code, uniqueness: true
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記の定義によれば、codeが &apos;aa &apos; と &apos;aa &apos;（末尾に半角スペースが2つ）のオブジェクトが存在できますが、実際には登録できません。&lt;/p&gt;
&lt;p&gt;以下のコードは正しく動くはずなのに、2つ目のオブジェクトがvalidになりません。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[2] pry(main)&amp;gt; p1 = FactoryBot.create(:product)
[3] pry(main)&amp;gt; p1.code = &apos;aa &apos;
=&amp;gt; &quot;aa &quot;
[4] pry(main)&amp;gt; p1.save
=&amp;gt; true
[5] pry(main)&amp;gt; p2 = FactoryBot.create(:product)
[6] pry(main)&amp;gt; p2.code = &apos;aa    &apos;
=&amp;gt; &quot;aa    &quot;
[7] pry(main)&amp;gt; p2.save
=&amp;gt; false
[8] pry(main)&amp;gt; p2.valid?
=&amp;gt; false
[9] pry(main)&amp;gt; p2.errors
=&amp;gt; #&amp;lt;ActiveModel::Errors:0x00007f6893d164d0
 @base=
  #&amp;lt;Product:0x00007f6893f534a0
   id: 2,
   code: &quot;aa    &quot;&amp;gt;,
 @errors=[#&amp;lt;ActiveModel::Error attribute=code, type=taken, options={:value=&amp;gt;&quot;aa    &quot;}&amp;gt;]&amp;gt;
[10] pry(main)&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ActiveRecord上では &apos;aa &apos; と &apos;aa &apos; が同一に扱われているようです。&lt;/p&gt;
&lt;p&gt;検証するために、ActiveRecordでcodeをキーに検索してみます。同時に、発行されているSQLを確認してみます。&lt;/p&gt;
&lt;p&gt;そうすると、末尾の半角スペースの数に関わらず、半角スペースが1つしか存在しないレコードがヒットしてしまいます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[115] pry(main)&amp;gt; Product.where(code: &apos;test0410&apos;).first.code
  Product Load (1.0ms)  SELECT `products`.* FROM `products` WHERE `products`.`code` = &apos;test0410&apos; ORDER BY `products`.`id` ASC LIMIT 1
=&amp;gt; &quot;test0410  &quot;

[116] pry(main)&amp;gt; Product.where(code: &apos;test0410  &apos;).count
  Product Load (1.0ms)  SELECT COUNT(*) FROM `products` WHERE `products`.`code` = &apos;test0410  &apos;
=&amp;gt; 1

[117] pry(main)&amp;gt; Product.where(code: &apos;test0410 &apos;).count
  Product load (0.6ms)  SELECT COUNT(*) FROM `products` WHERE `products`.`code` = &apos;test0410 &apos;
=&amp;gt; 1

[118] pry(main)&amp;gt; Product.where(code: &apos;test0410&apos;).count
  Product Load (0.5ms)  SELECT COUNT(*) FROM `products` WHERE `products`.`code` = &apos;test0410&apos;
=&amp;gt; 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;発行されているクエリーは正しそうな感じはします。（文字列に対してLIKEではなくてイコールで条件を書いているのが若干微妙ですが）&lt;/p&gt;
&lt;p&gt;SQLレベルで予期した動作をしていないので、SQLで検証してみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MySQL &amp;gt; update products set code = &apos;aa  &apos; where id = 2;
ERROR 1062 (23000): Duplicate entry &apos;1-aa  &apos; for key &apos;products.index_products_on_code&apos;
MySQL &amp;gt; update products set code = &apos;aa &apos; where id = 1;
Query OK, 0 rows affected (0.001 sec)
Rows matched: 1  Changed: 0  Warnings: 0

MySQL &amp;gt; update products set code = &apos;aa  &apos; where id = 2;
ERROR 1062 (23000): Duplicate entry &apos;1-aa  &apos; for key &apos;products.index_products_on_code&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記の内容により、&lt;strong&gt;MySQLの物理スキーマレベルで半角スペースの多さが同一に扱われてしまっています。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ということで問題はMySQLレベルにありそうです。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;最近の私のアシスタント（GPT-4）に聞いてみました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;なるほど。PAD SPACEという概念は知りませんでした。&lt;/p&gt;
&lt;p&gt;PAD SPACEというプロパティはcollationに従属している値です。&lt;/p&gt;
&lt;p&gt;ということで、現在のカラムのcollationがどうなっているのかを調べてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MySQL &amp;gt; SELECT COLUMN_NAME, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE  TABLE_NAME = &apos;products&apos;;
+-----------------------------+--------------------+
| COLUMN_NAME                 | COLLATION_NAME     |
+-----------------------------+--------------------+
| id                          | NULL               |
| code                        | utf8mb4_bin        |
+-----------------------------+--------------------+
34 rows in set (0.002 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;utf8mb4_binになっています。&lt;/p&gt;
&lt;p&gt;この、utf8mb4_binがPAD SPACEなのかを調べてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MySQL&amp;gt; SELECT COLLATION_NAME, PAD_ATTRIBUTE
    -&amp;gt;        FROM INFORMATION_SCHEMA.COLLATIONS
    -&amp;gt;        WHERE COLLATION_NAME LIKE &apos;utf8mb4_bin&apos;;
+----------------+---------------+
| COLLATION_NAME | PAD_ATTRIBUTE |
+----------------+---------------+
| utf8mb4_bin    | PAD SPACE     |
+----------------+---------------+
1 row in set (0.002 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PAD SPACEでした。ということで、現在利用中のcollationがPAD SPCAE属性があるcollationのため、末尾の半角スペースがいくつあっても同一に扱われてしまっていました。&lt;/p&gt;
&lt;p&gt;MySQLのオフィシャルドキュメントではここに記載してあります。&lt;/p&gt;
&lt;p&gt;https://dev.mysql.com/doc/refman/8.0/ja/charset-binary-collations.html&lt;/p&gt;
&lt;p&gt;そもそも、utf8mb4_binは、suffixにbinaryのbinが付いているのに、全然binaryで区別してくれなくて悲しいです。&lt;/p&gt;
&lt;h2&gt;テストコード&lt;/h2&gt;
&lt;p&gt;修正前と後でモデルが正常に動くかを検証するために、FactoryBotを使ったrspecのコードを書いておきます。&lt;/p&gt;
&lt;p&gt;spec/models/product_spec.rb&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require &apos;rails_helper&apos;

RSpec.describe Product do
  it &apos;should be valid&apos; do
    expect(create(:product, code: &apos;aa &apos;)).to be_valid
    expect(create(:product, code: &apos;aa  &apos;)).to be_valid
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;失敗してしまいます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@455cbca12654:/app# bundle exec rspec  spec/models/product_spec.rb
Randomized with seed 53478
F

Failures:

  1) Product should be valid
     Failure/Error: p2 = create(:product, code: &apos;aa  &apos;)

     ActiveRecord::RecordInvalid:
       バリデーションに失敗しました: codeはすでに存在します
     # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/evaluation.rb:18:in `create&apos;
     # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/strategy/create.rb:12:in `block in result&apos;
     # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/strategy/create.rb:9:in `result&apos;
     # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/factory.rb:43:in `run&apos;
     # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/factory_runner.rb:29:in `block in run&apos;
     # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/factory_runner.rb:28:in `run&apos;
     # /usr/local/bundle/gems/factory_bot-6.2.1/lib/factory_bot/strategy_syntax_method_registrar.rb:28:in `block in define_singular_strategy_method&apos;
     # ./spec/models/product_spec.rb:6:in `block (2 levels) in &amp;lt;top (required)&amp;gt;&apos;

Finished in 4.73 seconds (files took 2.42 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/models/product_spec.rb:4 # Product should be valid

Randomized with seed 53478
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;修正&lt;/h2&gt;
&lt;p&gt;no padのutf8mb4のbinaryに近いcollationを探してみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MySQL &amp;gt; show collation where collation like &apos;utf8mb4%&apos; and collation like &apos;%bin&apos;;
+------------------+---------+-----+---------+----------+---------+---------------+
| Collation        | Charset | Id  | Default | Compiled | Sortlen | Pad_attribute |
+------------------+---------+-----+---------+----------+---------+---------------+
| utf8mb4_0900_bin | utf8mb4 | 309 |         | Yes      |       1 | NO PAD        |
| utf8mb4_bin      | utf8mb4 |  46 |         | Yes      |       1 | PAD SPACE     |
+------------------+---------+-----+---------+----------+---------+---------------+
2 rows in set (0.004 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://mita2db.hateblo.jp/entry/2020/12/07/000000&quot;&gt;こちらの比較表&lt;/a&gt;からしても、用途としては基本的にすべて区別したいのでutf8mb4_0900_binが良さそうです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;change_column :products, :code, :string, null: false, collation: :utf8mb4_0900_bin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;migrationを実行した後にrspecを実行したら正常に終わりました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@6d3039d9f78e:/app# bundle exec rspec spec/models/product_spec.rb
Randomized with seed 38846
.

Finished in 2.95 seconds (files took 29.75 seconds to load)
1 example, 0 failures

Randomized with seed 38846
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;影響度調査&lt;/h2&gt;
&lt;p&gt;今回のような、サロゲートキーに対してUNIQUE KEYを貼って、厳密な検索や値を保管するときに問題になります。&lt;/p&gt;
&lt;p&gt;今回は、商品コード関連で気づくことができました。他にも同じようなサロゲートキーの使い方をしている箇所が10箇所以上あったのでcollationをすべて見直しました。&lt;/p&gt;
&lt;p&gt;サロゲートキーのカラム名をつける際に、命名規則に従っていれば以下のクエリーで一括で検索できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MySQL &amp;gt; SELECT table_name,COLUMN_NAME, data_type, collation_name  FROM INFORMATION_SCHEMA.COLUMNS where table_schema = &apos;&amp;lt;your database name&amp;gt;&apos; and column_name = &apos;code&apos;;
+----------------------+-------------+-----------+--------------------+
| TABLE_NAME           | COLUMN_NAME | DATA_TYPE | COLLATION_NAME     |
+----------------------+-------------+-----------+--------------------+
| table_1              | code        | varchar   | utf8mb4_0900_ai_ci |
| table_2              | code        | varchar   | utf8mb4_bin        |
| table_3              | code        | varchar   | utf8mb4_bin        |
| table_4              | code        | varchar   | utf8mb4_bin        |
| table_5              | code        | varchar   | utf8mb4_bin        |
| table_6              | code        | varchar   | utf8mb4_0900_ai_ci |
| table_7              | code        | varchar   | utf8mb4_bin        |
| table_8              | code        | varchar   | utf8mb4_bin        |
| table_9              | code        | varchar   | utf8mb4_bin        |
| table_10             | code        | varchar   | utf8mb4_bin        |
| table_11             | code        | varchar   | utf8mb4_bin        |
| table_12             | code        | varchar   | utf8mb4_bin        |
| table_13             | code        | varchar   | utf8mb4_bin        |
| table_14             | code        | varchar   | utf8mb4_bin        |
+----------------------+-------------+-----------+--------------------+
14 rows in set (0.006 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;MySQLのcollationによって、カラムの値にある最後の半角スペースがいくつあっても同一に扱われる場合がある。&lt;/p&gt;
&lt;p&gt;上記により、&apos;aa &apos; と &apos;aa &apos; が同一に扱われる。&lt;/p&gt;
&lt;p&gt;GPT-4すごい。&lt;/p&gt;
&lt;p&gt;ちなみに、GPT-3.5だと的確な原因を指摘するところまではやってくれませんでした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Raspberry PiのWiFiと有線LANに静的IPを振る</title><link>https://blog.teraren.com/posts/raspberry-pi-static-ip/</link><guid isPermaLink="true">https://blog.teraren.com/posts/raspberry-pi-static-ip/</guid><description>Raspberry Pi OS (Bullseye) でdhcpcd.confを編集して有線LANと無線LANそれぞれに静的IPを設定する手順。設定ファイルのdiff付きで解説。</description><pubDate>Sat, 08 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;デフォルトだとDHCPからIPを取得するので面倒なため、静的IPを振っておきます。OSはRaspberry Pi Lite 64bit(Debian GNU/Linux 11 (bullseye))です&lt;/p&gt;
&lt;p&gt;有線LANに 192.168.1.5/24、無線LANに192.168.1.6/24を振る例です。&lt;/p&gt;
&lt;p&gt;基本的には設定がコメントアウトしてあるのでコメントアウトを外していくだけです。IPv6の固定アドレスはちゃんと運用しないので一旦は設定しません。ちゃんと運用しないし。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/dhcpcd.conf b/dhcpcd.conf
index b34f11a..674fda9 100644
--- a/dhcpcd.conf
+++ b/dhcpcd.conf
@@ -41,11 +41,17 @@ require dhcp_server_identifier
 slaac private

 # Example static IP configuration:
-#interface eth0
-#static ip_address=192.168.0.10/24
+interface eth0
+static ip_address=192.168.1.5/24
+#static ip6_address=fd51:42f8:caae:d92e::ff/64
+static routers=192.168.1.1
+static domain_name_servers=192.168.1.1 1.1.1.1 fd51:42f8:caae:d92e::1
+
+interface wlan0
+static ip_address=192.168.1.6/24
 #static ip6_address=fd51:42f8:caae:d92e::ff/64
-#static routers=192.168.0.1
-#static domain_name_servers=192.168.0.1 8.8.8.8 fd51:42f8:caae:d92e::1
+static routers=192.168.1.1
+static domain_name_servers=192.168.1.1 1.1.1.1 fd51:42f8:caae:d92e::1

 # It is possible to fall back to a static IP if DHCP fails:
 # define static profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;反映するためには以下のコマンドです。コマンドを打った瞬間ネットワークのインターフェイスがダウンするのでご注意ください。うまくいけば新しく設定したIPアドレスで接続できるようになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo ifconfig wlan0 down &amp;amp;&amp;amp; sudo ifconfig wlan0 up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;NICにIPが振られているか確認&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;IPv6, IPv4で接続性があるかを動作確認&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;HTTP, HTTPSの接続性も確認&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Pintアプリの開発にFlutter + Firebaseを採用した理由とその結果</title><link>https://blog.teraren.com/posts/pint-made-by-flutter/</link><guid isPermaLink="true">https://blog.teraren.com/posts/pint-made-by-flutter/</guid><description>2021 年 12 月ごろ、Pintの企画が完成に近づき、UXの要求がまとまりつつありました。</description><pubDate>Fri, 07 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;2021 年 12 月ごろ、&lt;a href=&quot;https://lp.pint-app.com/&quot;&gt;Pint&lt;/a&gt;の企画が完成に近づき、UXの要求がまとまりつつありました。&lt;/p&gt;
&lt;p&gt;企画のユースケースを実現するためには慣れた Rails+Webview で構築するのが一番手っ取り早いですが UX があまり良くないので、ネイティブで構築するという方向性で検討を進めました。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;速く、安く作るには iOS と Android 上で動作するクロスプラットフォーム対応のフレームワークを採用することが第一候補となります。&lt;/p&gt;
&lt;p&gt;当時は、React Naive、IONIC Framework, Cordova などのフレームワークが存在していました。
どれも一定のプロダクションのアウトプットは出せる感じがありました。しかし、開発者の定着度合いがあまり良くなかったり、微妙な UI があるためこの中から選ぶのはあまり良くないなという感覚がありました。&lt;/p&gt;
&lt;p&gt;そして、当時は Flutter 2.8 がリリースされたあとでもあり、かなりいろいろなコンポーネントがリリースされてきて Flutter で作られたアプリケーションがちらほら出だしてきているときでした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-07-12-36-46.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;また、
&lt;a href=&quot;https://qiita.com/hara_taku_/items/dbb168b14d1008396a0d&quot;&gt;【初アプリ】未経験がFlutterで肉牛繁殖農家のためのアプリを作ってみた
&lt;/a&gt;というアプリが1ヶ月ぐらいの開発で良さそうなUIのアプリがリリースされていました。これを見て、Flutterのポテンシャルがかなり高く、ユースケースも実現できそうというのはなんとなく感じてました。&lt;/p&gt;
&lt;p&gt;新技術を使うときやフレームワークに乗る時にはやはりリスクが伴うので、カルチャーである Fail&amp;amp;Learn の考えのもと、薄く広く実装をしながら Flutter を学習しつつ実現したいユースケースを達成できるかというフィージビリティチェックも同時に進めていきました。&lt;/p&gt;
&lt;p&gt;また、アプリ開発においてはフロントエンドとバックエンドの両方の技術選定を決める必要があります。
そして、スタートアップなので速く、安く、持続可能な技術でプロダクトをデリバリーする必要があります。&lt;/p&gt;
&lt;h2&gt;もっと抽象的に作れるかを検討&lt;/h2&gt;
&lt;p&gt;Flutter より上位のレイヤーでノーコードに近い形でアプリを開発できたら良いなと思い、まずは FlutterFlow を検討してみました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://flutterflow.io/&quot;&gt;FlutterFlow&lt;/a&gt;はノーコードでFlutterアプリを構築できるというのが特徴です。デモのUI/UXもすごい良さそうに見えました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-01-20-29-05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;サンプルが豊富にあることや、UI からアプリのコードを生成できる機能があるため、アプリの基本形を作るまでのスピードは非常に速く、プロトタイプ作成などで特に有効なツールかと感じました。また、毎週のように新機能が追加されており、活発なプロダクトであったことも印象的です。&lt;/p&gt;
&lt;p&gt;とりあえず使ってみないとわからないので FlutterFlow をベースに開発を進めていましたが、手が届かないと感じる点も出てきました。
FlutterFlow にカスタムのメソッドを適用する機能もありますが、あくまで UI の何かの操作がトリガーのものに限定されるなど、カスタマイズ不能な範囲がどうしてもあります。
例えば郵便番号のバリデーションのようにユーザーが入力中に動いてほしいものや、複雑なユーザーのルーティング条件が必要な場合には対応できないユースケースがありました。&lt;/p&gt;
&lt;p&gt;そういったケースは、FlutterFlow から出力したコードを変更して対応します。
FlutterFlow からはソースコードに 1 方向でしか変換できないため、結局のところソースコードを書きかえていくと FlutterFlow 上の UI に差分が出つづけ、マージが手間になリます。&lt;/p&gt;
&lt;p&gt;また、FlutterFlow だけでは本番・ステージングなどの複数環境の切り替え機能がないことも、CI/CD など環境を構築するに当たって重要な要件を満たせないこともわかりました。&lt;/p&gt;
&lt;p&gt;こうした点を踏まえ、FlutterFlow の利用は諦めました。&lt;/p&gt;
&lt;h3&gt;Flutter上でDartを書くことに決定&lt;/h3&gt;
&lt;p&gt;FlutterFlow を使うときに、簡単なアプリであれば問題ないのですが、ちょっとはみ出たことをしようと思うとどう FlutterFlow を使って実現すれば良いのか、ドキュメントも少ない中で考える必要があります。&lt;/p&gt;
&lt;p&gt;一方 Flutter は公式ドキュメントが非常に充実しており、結局 0 から開発するほうが自由度高く、かつ早く開発できました。これはローコード・ノーコードツール全般に言えることだと思いますが、ビジネス要件がきっちり決まっている場合は、実現できることをツール側に寄せる必要のある開発スタイルではなく、フルスクラッチで開発するのが良いと思っています。&lt;/p&gt;
&lt;p&gt;また Flutter はウィジェットを組み立てて構築していくフレームワークなので、UI からアプリを組み立てていくことにこだわらなくても十分問題ないという言語特性もあります。&lt;/p&gt;
&lt;h2&gt;ソフトウェアアーキテクチャ選定&lt;/h2&gt;
&lt;p&gt;Flutter で構築する際に、重要になるのがソフトウェアアーキテクチャのモデル選定です。当時はデファクトスタンダードが無く、どれも一長一短ではありました。主に以下のアーキテクチャがオプションとしてはありました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stateful ウィジェット&lt;/li&gt;
&lt;li&gt;MVC&lt;/li&gt;
&lt;li&gt;MVVM&lt;/li&gt;
&lt;li&gt;MVVM + repsitory&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当時のトレンドの 1 つであった &lt;a href=&quot;https://github.com/wasabeef/flutter-architecture-blueprints&quot;&gt;flutter-architecture-blueprints&lt;/a&gt;をベースに、MVVM + repository の構成で設計を進めました。MVVM + repository に関する情報が Web に充実しておりまた最後発で様々なアーキテクチャ上の課題を解決しているためです。&lt;/p&gt;
&lt;h2&gt;利用したパッケージの紹介&lt;/h2&gt;
&lt;p&gt;今回、利用したパッケージの一部を紹介します。&lt;/p&gt;
&lt;h3&gt;riverpod + Flutter Hooks&lt;/h3&gt;
&lt;p&gt;状態管理には &lt;a href=&quot;https://pub.dev/packages/riverpod&quot;&gt;riverpod&lt;/a&gt; + &lt;a href=&quot;https://pub.dev/packages/flutter_hooks&quot;&gt;Flutter Hooks&lt;/a&gt;を使用しています。
&lt;a href=&quot;https://pub.dev/packages/freezed&quot;&gt;freezed&lt;/a&gt;
Model を copyWith でイミュータブルに扱ったり、JSON の de/serialize したりといったコードの自動生成をするために使用しています。&lt;/p&gt;
&lt;h3&gt;flutter_gen&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/FlutterGen/flutter_gen&quot;&gt;flutter_gen&lt;/a&gt;
画像などのリソースファイルへ安全にアクセスできるようにするため使用しています&lt;/p&gt;
&lt;h3&gt;search_choices&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://pub.dev/packages/search_choices&quot;&gt;search_choices&lt;/a&gt;
銀行口座を一覧から選択する際に、多数の項目から選択する UI が多いです。こちらのパッケージを使用することでテキスト入力からリアルタイムにフィルタリングして項目を絞れ込めます。&lt;/p&gt;
&lt;h2&gt;バックエンドの選定&lt;/h2&gt;
&lt;p&gt;バックエンドは Firebase を採用しました。&lt;/p&gt;
&lt;p&gt;Amplify なども検討しましたが、やはり Flutter と同じ Google が開発しているので、ドキュメント・パッケージともに Firebase との接続がサポートされているケースが多いです。
また JSON で様々なデータが扱えたり機能ごとにきちんと結びつきがあったりと親和性が高いです。&lt;/p&gt;
&lt;p&gt;Flutter を使って開発する場合はバックエンドを Firebase で構築するのがデファクト・スタンダードのような印象を受けました。
Firebase 上の処理が多くなってくるとコストが嵩んでくる問題はありそうでしたが、そのときには適宜バックエンドの再選定をしていくのが良いと思います。&lt;/p&gt;
&lt;h2&gt;Tips&lt;/h2&gt;
&lt;p&gt;Flutter で開発をしてみて、得られた知見をまとめておきます。&lt;/p&gt;
&lt;h3&gt;DartやFlutterの最新情報は要チェック&lt;/h3&gt;
&lt;p&gt;Dart や Flutter はマイナーバージョンの更新でも大きな仕様変更が入ります。
例えば、2022 年 5 月の Dart2.17 です。enhanced-enum という、enum の拡張機能が追加されたのですが、こちらが release されるまでは enum を自ら拡張して実装する必要がありました。
新興言語ということもあり、大きなアップデートが多いため、変化が多くて楽しいです。&lt;/p&gt;
&lt;h3&gt;アーキテクチャありきでなくても良い&lt;/h3&gt;
&lt;p&gt;FlutterFlow から切り替える際にはアーキテクチャから検討を始めましたが、まずは標準的な Stateful ウィジェットでの開発で進めても良かったかもしれません。&lt;/p&gt;
&lt;p&gt;というのも、多くのパッケージにおけるサンプルは Stateful ウィジェットで記載されているため、riverpod + Flutter Hooks を軸にしてしまうと、慣れるまでは置き換えるプロセスで手間がかかります。
特に Flutter 未経験の状態であったこともあり、なおさら標準スタイルで進めた方が結果的にリリースまでのスピードが速かったのかなと感じることがあります。
もちろん自社のリソースの技術スタックによりますが、まずは素直に Flutter の公式ドキュメントをベースに進めていくのが一番の近道かもしれません。&lt;/p&gt;
&lt;h3&gt;最初からきちんとデザインする&lt;/h3&gt;
&lt;p&gt;デザイナー不在もあり、今回の開発では未経験者の PdM が Material Design 等を無視してデザインをしましたが振り返ってみれば、Material Design を学んでもらって、それに則った開発をするべきだったなあという公開があります。それをすればテーマを当てるだけでよくなるのでコードが軽量化され実装面でも楽になります。&lt;/p&gt;
&lt;p&gt;学習コストはかかりますが、トータルで考えたときにペイするので、デザイナーがいない状態でも最初から Material Design に則って設計するべきだと思います。&lt;/p&gt;
&lt;p&gt;もちろんエンジニアも Material Design を理解しデザインを作る人とコミュニケーションを取れるようにすることが重要です。&lt;/p&gt;
&lt;h2&gt;終わりに&lt;/h2&gt;
&lt;h3&gt;Flutterを採用してどうだったか？&lt;/h3&gt;
&lt;p&gt;回り道もありましたが、総じて Flutter を採用したことは非常にプラスだったと感じています。
結果的にネイティブ開発の知識はビルドなどに関する設定が必要だった程度で、今回のチームでも無事に Android/iOS ともにストアへのリリースまで進めることができました。&lt;/p&gt;
&lt;p&gt;実際に開発してみたところ、Native で書くところはほとんどなく、Swift + Kotlin より早く、楽に開発できました&lt;/p&gt;
&lt;p&gt;Pint のアプリをリリースしてから半年が経ち、Flutter の勢いは当時よりも増しているように感じます。現時点では Pint アプリは今後も Flutter で開発、運用を続けます。&lt;/p&gt;
&lt;h3&gt;Pintについて&lt;/h3&gt;
&lt;p&gt;Pint はアプリを経由するだけで Amazon や楽天などの EC サイトでのお買い物でポイントがもらえるサービスです。この機会にぜひインストールして活用してみてください！&lt;/p&gt;
</content:encoded></item><item><title>Google WorkspaceとAzure ADFS環境でOffice 365のSAML証明書を更新する手順</title><link>https://blog.teraren.com/posts/google-workspace-ad-fs-saml/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-workspace-ad-fs-saml/</guid><description>ある日、突然 Office 365 へログインできなくなりました。</description><pubDate>Wed, 05 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;概要&lt;/h1&gt;
&lt;p&gt;ある日、突然 Office 365 へログインできなくなりました。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Error: malformed_certificate&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-06-02-29-45.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;原因は SAML の有効期限切れだったので、問題の発見方法と設定手順を説明します。&lt;/p&gt;
&lt;h1&gt;背景&lt;/h1&gt;
&lt;p&gt;弊社のアカウント管理がどのようになっているかを以下に説明します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google Workspace を利用しているので Google Workspace のユーザマスタを主として運用している。&lt;/li&gt;
&lt;li&gt;Microsoft Azure を利用して ADFS(Active Directory Federation Service)を使っている。&lt;/li&gt;
&lt;li&gt;ADFS を利用することによって Office 365 のユーザを ADFS のユーザと同期できるようになってライセンス付与を自動化している。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上記の設定によって以下のようなユースケースを実現しています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ユーザマスタ管理者が Google Workspace 上でユーザを作成&lt;/li&gt;
&lt;li&gt;自動的に Microsoft Azure の ADFS にユーザ情報が同期される（5 分ぐらいかかる）&lt;/li&gt;
&lt;li&gt;Office 365 のライセンスが Organization Unit に応じて付与される。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当時、ADFS の設定をしたときにはドキュメントがほとんど存在していなくて設定をするのにまる 1 日ぐらいかかったと思います。
今、検索してみたら以下の記事にわかりやすくまとまっているのを見つけました。&lt;/p&gt;
&lt;p&gt;https://zenn.dev/cestquigucci/articles/59175c03342c66&lt;/p&gt;
&lt;p&gt;(当時、手順書をかブログにまとめようと思っていましたが複雑だったのと、色々トライアンドエラーをしていたし、スクショにマスクをしないといけなかったりで面倒なので諦めました)&lt;/p&gt;
&lt;h1&gt;原因&lt;/h1&gt;
&lt;p&gt;最初に挙げた問題に対して軽く調べましたところ、原因は Google Workspace 上の Microsoft 365 アプリで発行した SAML の証明書が切れたからでした。&lt;/p&gt;
&lt;p&gt;SAML 連携の設定時に Service Provider へ IdP で発行した証明書を登録します。
関連づいている証明書はこちらから確認できます。スクショではすでに更新済みなので有効期限が未来になっています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-06-02-43-05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上記のボタンを押すと証明書の削除や新規発行が行える画面になるのでここで証明書の管理をします。本来なら有効期限が切れる前にこの操作をして登録をしておく必要があります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-06-02-46-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;更新手順&lt;/h1&gt;
&lt;p&gt;ADFS 環境にて &lt;a href=&quot;https://learn.microsoft.com/ja-jp/education/windows/configure-aad-google-trust?cid=kerryherger&quot;&gt;SAMLを設定するための手順書&lt;/a&gt;は存在しているのですが、更新する際の手順書が見つかりませんでした。&lt;/p&gt;
&lt;p&gt;この更新作業には Windows の PC が必要になります。Windows が手元に無いので Azure の VM を立ち上げて作業します。&lt;/p&gt;
&lt;p&gt;ちなみに、Azure 上の PowerShell で更新ができたら楽だったのですができませんでした。
&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-06-02-51-02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Azure 上で適当に Windows を立ち上げます。無料クレジットがあると思いますので、無料で立ち上げられると思います。
&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-06-02-52-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;手元の mac から Remote Desktop を使ってこの VM へ接続します。PowerShell を立ち上げます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-06-02-53-46.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;まず、設定を確認してみます。
以下のコマンドで ADFS に使っている SAML の設定情報を出力します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$DomainName = &quot;example.com&quot;
Get-MsolDomainFederationSettings -DomainName $DomainName
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-06-02-55-50.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;古い証明書が登録されていることを確認しておきます。&lt;/p&gt;
&lt;p&gt;まず、Federatedの状態を解除してManagedにします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Set-MsolDomainAuthentication -Authentication Managed -DomainName example.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-06-02-58-05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下のようなコマンドを打ち込んで、SAMLの設定を更新します。
&lt;code&gt;xxxxxxxx&lt;/code&gt; は伏せ字です&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ssoUrl = &quot;https://accounts.google.com/o/saml2/idp?idpid=xxxxxxxx&quot;
$entity = &quot;https://accounts.google.com/o/saml2?idpid=xxxxxxxx&quot;
$domain = &quot;xxxxxx&quot;
$cert = &quot;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&quot;

Set-MsolDomainAuthentication -Authentication Federated  -DomainName $domain -ActiveLogOnUri $ssoUrl -PassiveLogOnUri $ssoUrl -IssuerUri $entity -LogOffUri $ssoUrl -SigningCertificate $cert -PreferredAuthenticationProtocol SAMLP
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;証明書が更新されているかを以下のコマンドで確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$DomainName = &quot;example.com&quot;
Get-MsolDomainFederationSettings -DomainName $DomainName
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そのあと、以下のコマンドを打ち込んでドメインの状態がFederatedになっているかを確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Get-MsolDomainFederationSettings
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;テスト&lt;/h1&gt;
&lt;p&gt;Google WorkspaceのOffice 365のアプリ画面から &lt;code&gt;TEST SAML LOGIN&lt;/code&gt; をクリックしてログインが成功するかを検証します。冒頭のエラーが出なくログインできれば成功です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-06-03-05-38.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最後に、立ち上げたVMを綺麗サッパリ削除して終わりにします。&lt;/p&gt;
&lt;h1&gt;考察&lt;/h1&gt;
&lt;h2&gt;Federatedを解除しないで更新できるか？&lt;/h2&gt;
&lt;p&gt;できませんでした。
&lt;code&gt;Set-MsolDomainAuthentication&lt;/code&gt; コマンドを使って新しい証明書を設定しようとしましたができませんでした。コマンド自体は成功しますが、証明書が書き換わりませんでした。&lt;/p&gt;
&lt;h2&gt;VMを立ち上げないでCloud Shellでできるのか？&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Connect-MsolService&lt;/code&gt; で接続できないので無理かなと思います。&lt;/p&gt;
&lt;h2&gt;自動更新できないのか？&lt;/h2&gt;
&lt;p&gt;でき無さそう。自分でリマインダーを設定しておきましょう。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/2023-04-06-10-11-42.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>WordPressのoptions.phpページで保存できないときの対処法</title><link>https://blog.teraren.com/posts/wordpress-options/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-options/</guid><description>WordPressのoptions.phpで「設定を保存できませんでした」が出る場合、PHPのmax_input_varsがデフォルト1000では不足するため2000以上に増やす対処法</description><pubDate>Fri, 31 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;WordPressで、「options.php」ページにて、&lt;code&gt;image_default_link_type&lt;/code&gt;を&lt;code&gt;file&lt;/code&gt;に変更して、「変更を保存」をクリックすると、「&lt;strong&gt;設定を保存できませんでした。&lt;/strong&gt;」と表示されて変更できませんでした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;調べてみると、max_input_varsの値がデフォルトでは1000なのですが、options.phpの項目が1000個以上あるから弾かれているようです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-172-26-15-xxx etc]# git diff
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/php.ini b/php.ini
index aa8acc8..6459620 100644
--- a/php.ini
+++ b/php.ini
@@ -397,7 +397,7 @@ max_input_time = 60
 ;max_input_nesting_level = 64

 ; How many GET/POST/COOKIE input variables may be accepted
-; max_input_vars = 1000
+max_input_vars = 2000

 ; Maximum amount of memory a script may consume (128MB)
 ; http://php.net/memory-limit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この値を適当に2000にして、PHPを再起動したら保存できました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;systemctl restart php-fpm.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>CloudWatchのlog insightでの調査例</title><link>https://blog.teraren.com/posts/cloudwatch-log-insight/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cloudwatch-log-insight/</guid><description>CloudWatchのlog insightでの調査例</description><pubDate>Thu, 30 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;アプリケーションのログがJSONで保存されているときの調査サンプル&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;filter @logStream like &apos;app/app/&apos;
| filter @message like /include/
| filter @message not like /exclude/
| filter duration &amp;gt; 100
 | fields @timestamp, @message, duration 
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>slackで最終営業日にリマインダーを設定する方法</title><link>https://blog.teraren.com/posts/slack-reminder-last-weekday/</link><guid isPermaLink="true">https://blog.teraren.com/posts/slack-reminder-last-weekday/</guid><description>slackで最終営業日にリマインダーを設定する方法</description><pubDate>Thu, 30 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;正確には日本の休日マスタを使わないと出せません。&lt;/p&gt;
&lt;p&gt;とりあえず簡易的には以下で設定できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/remind #channel or @your_username [メッセージ] at [時間] on the last weekday of the month
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/remind #general 今月の報告書を提出してください at 3pm on the last weekday of the month
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Automatically delete head branchesの宗教論争</title><link>https://blog.teraren.com/posts/post-15243/</link><guid isPermaLink="true">https://blog.teraren.com/posts/post-15243/</guid><description>GitHubの「Automatically delete head branches」をONにすべきかOFFにすべきかをChatGPTの見解と個人考察を交えて議論。古いブランチを定期削除するGitHub Actionsで折衷案も紹介。</description><pubDate>Tue, 28 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;githubのレポジトリ運用において「Automatically delete head branches」をonにするかoffにするか悩ましいところです。&lt;/p&gt;
&lt;p&gt;デフォルトはoffです。&lt;/p&gt;
&lt;h2&gt;GPTに聞いてみた&lt;/h2&gt;
&lt;p&gt;Q: githubのrepositoryの設定にある、 &quot;Automatically delete head branches&quot; をonにするかoffにするか悩んでます。どちらのほうが一般的でしょうか？&lt;/p&gt;
&lt;p&gt;A: 「Automatically delete head branches」の設定は、プルリクエストがマージされた後に、そのブランチを自動的に削除する機能です。この設定をオンにするかオフにするかは、チームやプロジェクトのワークフローと好みによって異なります。しかし、一般的な考え方をいくつか紹介します。&lt;/p&gt;
&lt;p&gt;オンにする利点:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;リポジトリがきれいに保たれる: 不要なブランチが自動的に削除されるため、リポジトリが整理されやすくなります。&lt;/li&gt;
&lt;li&gt;ブランチの管理が楽になる: 作業が完了したブランチを手動で削除する必要がなくなり、メンテナンスが容易になります。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;オフにする利点:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;履歴の追跡: ブランチが削除されないため、過去の変更履歴を容易に確認できます。&lt;/li&gt;
&lt;li&gt;再利用可能: 削除されないため、同じブランチを再利用して追加の変更ができます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一般的には、プルリクエストがマージされた後にブランチを自動的に削除してリポジトリを整理しやすくするため、この機能をオンにすることが多いです。しかし、過去の変更履歴を追跡したい場合や、ブランチを再利用する必要がある場合はオフにすることもあります。&lt;/p&gt;
&lt;p&gt;最終的には、チームやプロジェクトの要件に基づいて判断してください。機能を試してみて、適切な設定を見つけるのも良い方法です。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;まさに論点はGPTに聞いた内容といのですでに考えてました。&lt;/p&gt;
&lt;p&gt;インサイトとしては、&lt;strong&gt;onにしている方が多い&lt;/strong&gt;という情報です。&lt;/p&gt;
&lt;p&gt;そして、onとoffのいいとこ取りはできないかと思って探していたら見つけたのがこちら。古いブランチを削除するというGithub Actionsです。&lt;/p&gt;
&lt;p&gt;https://github.com/beatlabs/delete-old-branches-action&lt;/p&gt;
&lt;p&gt;これであれば参照頻度が低くて、再利用の可能性が低いブランチを積極的に消せます。&lt;/p&gt;
&lt;h2&gt;私の主張&lt;/h2&gt;
&lt;p&gt;ちなみに私は残しておく派。&lt;/p&gt;
&lt;p&gt;tigで見たときにブランチの目的が追いやすいから。&lt;/p&gt;
&lt;p&gt;そして、やっっぱりremoteにpushした情報って消しちゃいけないと思うんですよ。他の誰かがtrackingしているかもしれないのでブランチが消えると追いづらくなってしまいます。&lt;/p&gt;
&lt;p&gt;容量は食わないし、見づらくなるぐらいのデメリットぐらいしか無いので、どんどんstockしていくのが根本かなと思います。&lt;/p&gt;
&lt;p&gt;もし、ブランチ名を消す運用をしていて、再度同じブランチ名で別のfeature branchを作り出したときにURIの指す中身が違ってしまうというのもあるからブランチ名はレポジトリーに対してユニークになっていることも重要です。&lt;/p&gt;
</content:encoded></item><item><title>GPT-4を使って既存のRailsアプリケーションにヘルスチェック機能追加をしてみる</title><link>https://blog.teraren.com/posts/rails-with-gpt/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-with-gpt/</guid><description>最近、個人開発している サービスのコンテンツをCDNに乗せました。originの外形監視のためにヘルスチェック用のエンドポイントが必要になったのでその機能を実装してもらいましょう。</description><pubDate>Sat, 25 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;概要&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;GPT-4 の性能が良いので既存の Ruby on Rails で動いているアプリケーションに機能を追加して本番へリリースできるクオリティを目指します。&lt;/li&gt;
&lt;li&gt;GPT に指示出しをして PoC を作らせるのは簡単なので、今回はプロダクションレベルに出して良いレベルのコードを出力させて本番にデプロイします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;機能要求&lt;/h1&gt;
&lt;p&gt;最近、個人開発している &lt;a href=&quot;https://twitter.com/matsubokkuri/status/1634943638462685184&quot;&gt;サービスのコンテンツをCDN&lt;/a&gt;に乗せました。originの外形監視のためにヘルスチェック用のエンドポイントが必要になったのでその機能を実装してもらいましょう。&lt;/p&gt;
&lt;p&gt;実装の難易度はかなり低いですが、細かいところの評価ポイントがあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作る人によって Controller の名称が微妙ではないか？&lt;/li&gt;
&lt;li&gt;返却される JSON データのキーの名前が微妙ではないか？&lt;/li&gt;
&lt;li&gt;rspec を書いてくれるか？&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;実装&lt;/h1&gt;
&lt;p&gt;一発目は、とりあえずエンドポイント名だけを指定してコードを書いてもらいました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/2023-03-25-22-55-43.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;なかなか良いです！　しかしながら文字列で時間を返されてもちょっと扱いづらいので Unix タイムスタンプで返してもらおうと思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/2023-03-25-23-01-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;期待通りのコードができました。しかし、実装だけなら誰でもできる！
殆どのエンジニアが面倒だなと思うテストコードも書いてもらいましょう。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/2023-03-25-23-04-05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;まぁ、90 点ぐらいのできです。&lt;/p&gt;
&lt;p&gt;ちょっとこのコードでは 100％テストが通るとは限らないので修正してもらいます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/2023-03-25-23-19-39.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ヒントを与えすぎてしまったかもしれませんが、理想のコードになりました。&lt;/p&gt;
&lt;p&gt;なぜ今年の元旦の日付に固定したのかは不明です。べつに &lt;code&gt;Time.zone.now&lt;/code&gt; と書いたほうが良いです。コード量が削減できますし、マジックナンバーも減ります。まぁ、細かいことは気にしないで良いです。&lt;/p&gt;
&lt;p&gt;しかしながら惜しいです。細かいですが、rubocop で指摘されるような細かい指摘をしてみました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/2023-03-25-23-06-09.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;GPT に書かせて、&lt;code&gt;rubocop -a&lt;/code&gt; を使って自動に校正できるような内容なので全く問題無いです。&lt;/p&gt;
&lt;h1&gt;テスト&lt;/h1&gt;
&lt;p&gt;上記のコードをコピー&amp;amp;ペーストして、rspec を実行してみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose run --rm app bundle exec rspec spec/controllers/healthcheck_controller_spec.rb
[+] Running 2/0
 ⠿ Container train-chrome-1  Running                                                                                                    0.0s
 ⠿ Container train-db-1      Running                                                                                                    0.0s

Randomized with seed 11651

HealthcheckController
  GET #index
    returns http success
    returns current time in unix timestamp format

Top 2 slowest examples (0.05121 seconds, 94.6% of total time):
  HealthcheckController GET #index returns http success
    0.0462 seconds ./spec/controllers/healthcheck_controller_spec.rb:13
  HealthcheckController GET #index returns current time in unix timestamp format
    0.005 seconds ./spec/controllers/healthcheck_controller_spec.rb:18

Finished in 0.05413 seconds (files took 2.79 seconds to load)
2 examples, 0 failures

Randomized with seed 11651
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;素晴らしいです。1発で成功しました。&lt;/p&gt;
&lt;p&gt;つぎに、実際にHTTP経由で叩いてみましょう。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose up
% curl -s http://localhost:3001/healthcheck.json | jq
{
  &quot;time&quot;: 1679753425
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;成功しました！　完璧です。&lt;/p&gt;
&lt;p&gt;こうして作られた機能が以下のURLになります。
https://train.teraren.com/healthcheck.json&lt;/p&gt;
&lt;h2&gt;成果物&lt;/h2&gt;
&lt;p&gt;今回作ったコードをdiff形式で以下のURLにおいておきました。&lt;/p&gt;
&lt;p&gt;そのまま取り込めば同じ機能を自分のプロジェクトにそのまま使えると思います。&lt;/p&gt;
&lt;p&gt;https://gist.github.com/matsubo/ba0db8ba1386119ff0ffff1142a038ba&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cd &amp;lt;root of rails project&amp;gt;
% curl https://gist.githubusercontent.com/matsubo/ba0db8ba1386119ff0ffff1142a038ba/raw/1c5b63a98a366fb566aad998dba636f0d3900ba8/healthcheck.diff | patch -p1
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;そもそも&lt;/h2&gt;
&lt;p&gt;1 つ上位の視点で考えると、なんで Chat-GPT の結果を自分でコピー&amp;amp;ペーストして、他のプロジェクトに利用できるように diff を貼り付けているのだろう。
ここまでの流れをやらせれば良いのでは？　と思いました。&lt;/p&gt;
&lt;p&gt;試しに、Chat-GPT4 に diff を出させてみました。
&lt;img src=&quot;../../assets/uploads/2023/03/2023-03-26-14-22-02.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ちゃんと出力されています。&lt;/p&gt;
&lt;p&gt;ここまで、長々と GPT4 と対話して成果物を作製しましたが、以下のように司令を書けば 1 発で終わります。&lt;/p&gt;
&lt;p&gt;ここで言えることは、issue に書くようなフォーマットで実装を見越して要求定義をしっかり書けばコードを生成してくれます。
プロジェクトで共通の事項である rspec がインストール済みといったことは 1 回覚えさせてしまえば良いので省略できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/2023-03-26-14-27-54.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;まとめ&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;簡単な実装ならばコードを生成できそうです。&lt;/li&gt;
&lt;li&gt;当初、懸念していたキーワード選定の正しさや、テストコードの正しさはほぼ私のコーディングスタイルと一致しているので違和感は無いコードが出てきました。&lt;/li&gt;
&lt;li&gt;単純に要求を書いて、出されるようなコードは 100 点のコードは出てきません。事前条件の設定や、要件の設定でチューニングするのが良いです。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>HSTS (Http Strict Transport Security)を設定</title><link>https://blog.teraren.com/posts/hsts-http-strict-transport-security/</link><guid isPermaLink="true">https://blog.teraren.com/posts/hsts-http-strict-transport-security/</guid><description>NginxとApacheでHSTSヘッダを設定しpreloadリストへ登録する方法。includeSubdomains・1年以上の有効期限・preload指定の3条件と登録後の反映待ちについて解説。</description><pubDate>Sun, 12 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;HSTSについての説明はこちらに詳しく書かれています。&lt;/p&gt;
&lt;p&gt;https://zenn.dev/harusame0616/articles/b285a061e0c1f9&lt;/p&gt;
&lt;h2&gt;HSTSのpreloadに登録&lt;/h2&gt;
&lt;p&gt;HSTSのpreloadに登録するための設定は簡単です。&lt;/p&gt;
&lt;p&gt;ドメイン自体のAレコードのURLに対して、HTTPヘッダを1つ追加するだけです。&lt;/p&gt;
&lt;p&gt;HSTSのpreloadに登録するためには要件が厳しいです。以下の3つを満たす必要があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;includeSubdomainも付加&lt;/li&gt;
&lt;li&gt;有効期限は1年以上&lt;/li&gt;
&lt;li&gt;preloadの指定&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HSTSのpreloadのリストはグローバルで1つなのでリストの肥大化を防ぐためにもドメインレベルでしかも長期的に保持するような方針です。&lt;/p&gt;
&lt;p&gt;nginxの場合は以下の1行を適切なブロック(serverあたり)に足すだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
  add_header Strict-Transport-Security &apos;max-age=31536000; includeSubDomains; preload&apos;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apacheの場合は以下の1行を適切なディレクティブに足すだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Header add Strict-Transport-Security &quot;max-age=63072000; includeSubDomains; preload&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;対応ドメインの登録をする場合は以下のサイトでドメイン名を入力してSubmitします。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://hstspreload.org/&quot;&gt;https://hstspreload.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Submit後はすぐに登録されるわけではなく、保留されてから登録されるようなのでしばらく待ちます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ホストごとにHSTSを設定する場合&lt;/h2&gt;
&lt;p&gt;上記の場合はHSTSのドメインレベルでの登録、ドメインレベルでのHSTS preloadを登録しました。&lt;/p&gt;
&lt;p&gt;各ホストごとにもHSTSは設定できるので必要に応じて設定すれば良いと思います。&lt;/p&gt;
&lt;p&gt;例えば、以下のような感じで有効期限を指定するだけのようになります。(有効期限は1週間の例)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
  add_header Strict-Transport-Security &apos;max-age=604800&apos;;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>HHKB Proをオキシクリーンで掃除してルビング</title><link>https://blog.teraren.com/posts/happy-hacking-keyboard-pro-clean-up/</link><guid isPermaLink="true">https://blog.teraren.com/posts/happy-hacking-keyboard-pro-clean-up/</guid><description>2年間使い続けたHHKB Pro Hybrid Type-Sのキーキャップをオキシ漬けで洗浄し、スイッチにグリスを塗布して打鍵感を改善した実践レポート</description><pubDate>Sat, 11 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;2020年1月にHHKB Pro Hybrid Type-Sを買ってからほぼ毎日2年間ちょっと使ってきました。&lt;/p&gt;
&lt;p&gt;最近、&lt;a href=&quot;https://jun3010.me/amazon-gpl205g0-23270.html&quot;&gt;グリスアップが良い&lt;/a&gt;という記事を見たのでHHKBの掃除とグリスアップをしました。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B082TWFV9C&quot;}&lt;/p&gt;
&lt;h2&gt;掃除前&lt;/h2&gt;
&lt;p&gt;隙間に白いホコリが混入しています。ベースのほうにもゴミが溜まっているのが見えます。ブロアで頑張ってもなかなか落ちません。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2156-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2157-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;キープラーで抜いていきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2158-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0047MQJ4I&quot;}&lt;/p&gt;
&lt;p&gt;キートップを外したところ。汚いです。髪の毛も5本ぐらい溜まってます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2159-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;キーボードの汚れは油汚れだと思うのでぬるま湯でオキシ漬けします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2160-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B08T6WTVBG&quot;}&lt;/p&gt;
&lt;p&gt;キーボードのベース部分は分解するのが面倒なので、綿棒で掃除します。こちらも油汚れなので強アルカリ電解水の15倍濃縮液を使って汚れを拭き取ります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2161-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07874LQX1&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2162-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;綿棒は小さいのと普通サイズを用意しておくと細かいところを掃除できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2163-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;汚い。特に、スペースバーの左右にある部分に汚れが溜まりやすかったです。キーのセンサー内部にゴミが入りかけていました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2164-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;その間に、オキシクリーンしていたキートップのつけ置きの時間が終わりました。やばいものが出てくるかと思いましたが、普通です。油やホコリが浮いてきてます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2165-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;網ですくいます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2166-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;内部に水が溜まりやすいので全部綿棒である程度吸い取ります。キッチンペーパーの上でやると良いです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2167-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;無刻印なので、どこに戻すのかがわからなくなりました。&lt;/p&gt;
&lt;p&gt;HHKBは列ごとにキートップの形が違います。しかも、1つ1つキーの裏には型番が振られています。以下のような表がWeb上にいくつか合ったので参考にしようとしましたが存在しない型番が7割ぐらい。残り3割が存在する型番という状況でした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://sisidovski.hatenablog.com/entry/2017/11/25/124457&quot;&gt;https://sisidovski.hatenablog.com/entry/2017/11/25/124457&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ノギスで計測した結果、型番による違いは無さそうなのでアルファベットのキーは適当にはめました。&lt;/p&gt;
&lt;p&gt;このキートップたちは、大まかに4種類の形があります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2169-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;キートップをはめるときにグリスアップをしました。以前、5つのキーだけ試しにグリスアップをしてみたら静音化と潤滑性が確認できたのですべてのキートップに塗ります。&lt;/p&gt;
&lt;p&gt;グリスアップをして感じるのは、キーボードを購入した直後の滑らかな打鍵音がもとに戻った感じです。経年変化することで樹脂同士が触れ合ったときのかすかに「カサッ」となるノイズがなくなりました。&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/watch?v=EOSi1RKwuFs&lt;/p&gt;
&lt;p&gt;その反面、グリスはホコリを吸着してしまうというデメリットもありそうです。&lt;/p&gt;
&lt;p&gt;下の写真は塗り途中。軸の外周に塗ってベース部分と触れるところに塗りました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2170-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;使ったグリスはこちら。グリスの量の割には高いですが刷毛も付いていますし、これだけ買えばすぐに使えるので良しとします。205g0という種類が良いらしいです。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B09QQ8XCT4&quot;}&lt;/p&gt;
&lt;p&gt;205g0グリスの特性&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;完成図。型番による違いは無さそうで良かったです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/IMG_2171-Large.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;「キートップの型番によって表面の湾曲率が違う」みたいな書き込みがあって不安でしたが、大丈夫っぽいです。&lt;/p&gt;
&lt;p&gt;PCを使うデスクではなるべく食べ物を食べないように気をつけてはいましたが、ホコリの混入や髪の毛の混入は避けられません。それにプラスして樹脂部分が触れ合う構造なのでその部分をメンテナンスするべきだと思うので分解掃除は1年に一回ぐらいはしたほうが良いのかなと思います。&lt;/p&gt;
&lt;p&gt;キートップの着け外し自体にもキートップ自体に負担はかかるので頻繁にやりすぎるのも良くないかなと思います。&lt;/p&gt;
</content:encoded></item><item><title>Github Actionsでdocker composeのlayer cacheを使って実行時間を約3分短縮</title><link>https://blog.teraren.com/posts/2023-03-07-04d59908bc491d/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2023-03-07-04d59908bc491d/</guid><description>GitHub ActionsでDocker layer cacheを有効化し、CIのビルド時間を約3分短縮した設定方法とベンチマーク結果。</description><pubDate>Tue, 07 Mar 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;背景&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;GitHub Actions で CI を回しています。&lt;/li&gt;
&lt;li&gt;昔にセットアップしたプロジェクトで GitHub Actions の cache 機能が使われていませんでした。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;アプローチ&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://book.st-hakky.com/docs/github-actions-docker-cache/&quot;&gt;いろいろな設定方法&lt;/a&gt;がありますがコード量が多くてきれいじゃないです。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker compose&lt;/code&gt; を利用しているので Docker の build cache を流用できたら楽だなぁと思ってました。&lt;/li&gt;
&lt;li&gt;CircleCI では &lt;a href=&quot;https://circleci.com/docs/ja/docker-layer-caching/&quot;&gt;Docker レイヤーキャッシュ (DLC)&lt;/a&gt;によってbuild cache が保管されるのですが GitHub Actions ではこれに対応する機能がありません。&lt;/li&gt;
&lt;li&gt;今回見つけた actions では、GitHub Actions の Cache 機能を使って DLC をエミュレートしてくれるような動きをしてくれます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;設定&lt;/h1&gt;
&lt;p&gt;差分はこれだけです。
この追加した action の中でキャッシュストレージへの保存と読み込みをやってくれます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
jobs:
  rspec:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    env:
      TZ: Asia/Tokyo
      RAILS_ENV: test
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive
+      - uses: docker/setup-buildx-action@v2
+      - uses: docker/build-push-action@v4
+        with:
+          context: .
+          cache-from: type=gha
+          cache-to: type=gha,mode=max
      - name: Setup docker
        shell: bash
        run: |
          docker compose -f docker-compose.ci.yml build --progress=plain
          docker compose -f docker-compose.ci.yml pull -q
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記の設定を入れた上で、GitHub Actions で CI を回してみた結果です。&lt;/p&gt;
&lt;h1&gt;実行&lt;/h1&gt;
&lt;p&gt;Actions の Caches には以下のように保存されています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/gh-cache.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;CI 全体で 2 分 47 秒が短縮されました。
実行時間比率で言えば、19.8％短縮しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/ci-diff.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;実行時間の内訳&lt;/h2&gt;
&lt;p&gt;3 分 29 秒かかっていた build が 42 秒で終わるようになっています。&lt;/p&gt;
&lt;h3&gt;初回実行&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/gh-no-cache.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;cacheからロードして実行&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/gh-2nd.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h1&gt;考察&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Docker build にタグ付けしてロードしたりキャッシュしたりするようなロジックを書いているケースに対しても、今回紹介した設定に置き換えるだけで同等の効果があると思います。&lt;/li&gt;
&lt;li&gt;今までは、キャッシュの操作を手動で書いていたのが、Docker の中間キャッシュに完全に任せられるので楽になると思います。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.docker.com/build/cache/&quot;&gt;Dockerの中間キャッシュを使うロジック&lt;/a&gt;を理解した上で使う必要があります。&lt;/li&gt;
&lt;li&gt;今回は rspec 用のテストの紹介ですが、ECS に deploy するときの image を作る際にも使えると思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;まとめ&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;GitHub Actions の Cache を使って、Docker compose の build 時に使用する layer cache を有効利用するようにしました。&lt;/li&gt;
&lt;li&gt;実行時間が 3 分近く短縮しました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>NURO Wireless 5G注意報：レンタルモデムの不安定さを知っておこう！</title><link>https://blog.teraren.com/posts/nuro-wireless-5g/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nuro-wireless-5g/</guid><description>基地局20m圏内でNURO Wireless 5Gを実測。屋外と屋内での速度差や発熱・IPv6対応など、レンタルルーターの実態を詳しくレポートします。</description><pubDate>Mon, 27 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;NURO Wireless 5Gの基地局アンテナが直線距離20メートルに設置されたのでテストしてみます。&lt;/li&gt;
&lt;li&gt;理論値で4.1Gbps出るとのことなので期待したいです。&lt;/li&gt;
&lt;li&gt;7日間はキャンセル可能です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;レンタルルーター&lt;/h2&gt;
&lt;p&gt;5Gアンテナとルーター、WiFi APが1つに詰まったものになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;IEEE 802.11axに対応しているのでWiFi-6対応です。&lt;/p&gt;
&lt;h2&gt;所感&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;キャリアの電波周波数が5GHzということもあり、見通しで直接アンテナが見える状態に設置したときとしていないときの差が大きいです。&lt;/li&gt;
&lt;li&gt;特にアップロードの差が大きくて、屋外の直接見通せるところに設置すると、300Mbps, 部屋の中に設置すると40Mbps程度になります。&lt;/li&gt;
&lt;li&gt;IPv6アドレスが振られます。先頭の64bitも動的に振られます。&lt;/li&gt;
&lt;li&gt;ルーター本体は重いです。発熱もそこそこあります。ほんのり温かいです。冬に20度の室内で低負荷で稼働していて、表面温度が40度ぐらいです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;早速、測定してみます。&lt;/p&gt;
&lt;h3&gt;測定&lt;/h3&gt;
&lt;p&gt;屋外にルーターを置いて遮蔽物がない状態で計測してみます。無駄なCPU消費を抑えるために2GHz帯は無効化してあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WAN
&lt;ul&gt;
&lt;li&gt;屋外 見通し 20m&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LAN
&lt;ul&gt;
&lt;li&gt;WiFi IEEE802.11ax&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;WiFi&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://fast.com/&quot;&gt;Fast.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;補足:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://speed.cloudflare.com/&quot;&gt;Cloudflare&lt;/a&gt;のスピードテストの方は、fast.comより遅い結果となったのでnuro局内からcloudflareへの帯域が細そうです。&lt;/li&gt;
&lt;li&gt;WiFi6は実測値でも1.5Gbpsくらい出るのでWiFiがボトルネックにはなっていないはず。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題点&lt;/h2&gt;
&lt;p&gt;しばらく使っているとクリティカルな問題が発生しました。&lt;/p&gt;
&lt;h3&gt;事例1&lt;/h3&gt;
&lt;p&gt;24時間ほど運用していたところ、インターネットまたはWiFiの接続が不安定になりました。ルーターの電源を入れ直して復帰しました。&lt;/p&gt;
&lt;p&gt;WiFiにはたまに1台だけが接続されるという程度しか利用していません。というか、このWiFi APに接続していると、自然と接続が切れて既存の別のSSIDに勝手にフェイルオーバーされます。&lt;/p&gt;
&lt;p&gt;下のスクショは、WiFiにつながっているPCからCloudflare public DNSにpingを打ってみたところです。ほとんど繋がりません。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;事例2&lt;/h3&gt;
&lt;p&gt;事例1のあと4時間後にまた同じ問題が発生しました。&lt;/p&gt;
&lt;p&gt;今回も同様にインターネットまたはWiFiの接続が不安定になりました。&lt;/p&gt;
&lt;p&gt;しばらくpingの様子を見ていたら、調子が良くなりました。そして、また調子が悪くなったりします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;インターネット回線が調子悪いのか、WiFiが調子悪いのかを簡易的に判定するためにpingを打ち続けました。&lt;/p&gt;
&lt;p&gt;pingの送信先はcloudflareのDNSキャッシュサーバと、モデムのLAN側に付与されているIPアドレスです。&lt;/p&gt;
&lt;p&gt;LANのパケットがロスしていることから察するに、WiFiのアクセスポイントが調子悪そうです。&lt;/p&gt;
&lt;p&gt;ルーターのWiFi機能が不安定なのであれば、レンタルしているモデムには有線のポートが付いているので別途自分で用意したWiFiアクセスポイントを設置すれば解決できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-17.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;参考のために、別の固定回線の計測結果です。TTLにばらつきはありますがパケットロスは無いです。本来ならばこのぐらいの速度で安定して送信できるべきです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;事例3&lt;/h3&gt;
&lt;p&gt;10時間後、またレンタルしているモデムのWiFiアクセスポイントが不安定になった。&lt;/p&gt;
&lt;h3&gt;事例4&lt;/h3&gt;
&lt;p&gt;そのまた15時間後。レンタルモデムのWiFi APが不安定になった。ほとんど繋がらない。&lt;/p&gt;
&lt;p&gt;左がCloudflare public DNSに対してのping結果。右がルーターのNICへのping結果。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;不安定になるたびに、レンタルモデムの本体を再起動してますがしばらく時間が経過すると不安定になります。&lt;/p&gt;
&lt;h3&gt;RTTが遅い&lt;/h3&gt;
&lt;p&gt;既存の固定回線+WiFi APの平均RTTは27.295ms&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;--- 1.1.1.1 ping statistics ---
3233 packets transmitted, 3196 packets received, 1.1% packet loss
round-trip min/avg/max/stddev = 10.485/27.295/3520.858/105.505 ms&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;NURO Wireless 5G (内蔵WiFi AP)の平均RTTは76.733ms。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;--- 1.1.1.1 ping statistics ---
225 packets transmitted, 225 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 14.292/76.733/1602.545/205.341 ms&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;遅すぎます。テレカンするには若干テンポが遅れるし、ゲームをする人にとっては耐えられないと思います。&lt;/p&gt;
&lt;p&gt;一応、有線LANでpingを測定して見た結果。&lt;/p&gt;
&lt;p&gt;有線LANでpingを送信した結果。&lt;/p&gt;
&lt;p&gt;左側がルータのNICへ。右側はCloudflareのpublic DNSへ。右側はaverage 19.818msでした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;参考のために、既存の回線でも計測してみました。&lt;/p&gt;
&lt;p&gt;有線LANによる接続で、左側がCloudflare public DNSへのping, 右側がLANのルーターへのpingです。Cloudflare public DNSへはaverage 7.189msでした。&lt;/p&gt;
&lt;p&gt;nuro 5G Wirelessのほうが3倍近くTTLが遅いです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Latencyのまとめ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-23.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;参考までに、google meetでは300ms以下であれば問題ない数値と定義している様子。このグラフは固定回線＋無線LANのとき。片道だから10ms台。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/03/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;静的NATができない&lt;/h3&gt;
&lt;p&gt;自宅サーバや、マインクラフトのサーバを立ち上げるときに普通に静的IPマスカレード、静的NATを行うだけでは公開できないです。&lt;/p&gt;
&lt;p&gt;外部にサービスを公開したい場合はCloudflareといったtunnellingサービスを使う必要があります。とはいっても、安全性の面ではCloudflareを通したほうが良いのでこの点はどっちが良いとも言い切れない。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developers.cyberagent.co.jp/blog/archives/39259/&quot;&gt;Cloudflare zero trust&lt;/a&gt;などを使って回避はできます。自宅サーバからCloudflareにtunnelを貼って、private networkを作成して、接続する人はCloudflareのprivate networkに接続してもらう流れです。接続の際には、予め登録してあるメールアドレスなどの認証情報を元に接続します。&lt;/p&gt;
&lt;p&gt;初心者にはかなりハードルは高いと思います。&lt;/p&gt;
&lt;h2&gt;ルーターの交換を申し出てみる&lt;/h2&gt;
&lt;p&gt;現状のWiFiが不安定に鳴る問題を共有し、（無駄なトラブルシューティングの）問答を20分ほど受けて、ルーターの交換をやっと受け付けてもらいました。&lt;/p&gt;
&lt;p&gt;しかし、7日間のお試し期間の延長は不可能と言われました。&lt;/p&gt;
&lt;p&gt;自分の持っている安定したWiFi APを接続して運用しても良いかなと思いましたが、1ヶ月分の課金をして、再度検証するのは手間がかかるし、回線のlatencyが76msは致命的に遅いので&lt;/p&gt;
&lt;p&gt;その場で解約を申し出て、解約しました。&lt;/p&gt;
&lt;p&gt;ちなみに、レンタルした機材を返却しない場合は、機器損害金（税込61,500円）が請求されるとのことでした。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;nuro wireless 5Gのlatencyが76msもかかり遅いです。&lt;/li&gt;
&lt;li&gt;貸与されたルーターのWiFi AP機能が不安定すぎて使えない。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>ZennのPublication機能を利用している組織一覧</title><link>https://blog.teraren.com/posts/zenn_publications/</link><guid isPermaLink="true">https://blog.teraren.com/posts/zenn_publications/</guid><description>逆に、Zenn でテックブログを運用するときに欲しいなぁ思った機能</description><pubDate>Fri, 17 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;背景&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://corporate.minedia.com/&quot;&gt;株式会社マインディア&lt;/a&gt;のテックブログをどこで書こうか考えてました。&lt;/li&gt;
&lt;li&gt;ちょうど、Zenn で &lt;a href=&quot;https://zenn.dev/zenn/articles/how-to-use-publication&quot;&gt;Publication&lt;/a&gt;機能がベータリリースされているので使ってみたいと思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;なぜZennか？&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;執筆側
&lt;ul&gt;
&lt;li&gt;記事の管理を GitHub 連携できるのは便利で、linter をワークフローに入れられるので記事チェックするときに最低限のチェックを CI で回せるのは大きなアドバンテージとなるかなと思います。&lt;/li&gt;
&lt;li&gt;PR によるレビューができる。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zenn.dev/catnose99/articles/cb72a73368a547756862&quot;&gt;RSS&lt;/a&gt;のまとめによる運用ではSEOやまとめなどの機能がちょっと弱い。(まぁ、拡張すれば解決しますが。)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zenn.dev/catnose99&quot;&gt;catnose99&lt;/a&gt;さんの価値観に共感するところが大きいから応援したい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;オーディエンス側
&lt;ul&gt;
&lt;li&gt;読者は主にエンジニア。&lt;/li&gt;
&lt;li&gt;記事の横移動の導線はある。&lt;/li&gt;
&lt;li&gt;SEO はさほど強い印象がない。
&lt;ul&gt;
&lt;li&gt;Qiita のほうが強い印象。&lt;/li&gt;
&lt;li&gt;中期的には Zenn が上がってくるはず（というか頑張って上げていきたい）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;逆に、Zenn でテックブログを運用するときに欲しいなぁ思った機能&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;掲載、非掲載の承認機能
&lt;ul&gt;
&lt;li&gt;事後チェックという運用で回避&lt;/li&gt;
&lt;li&gt;publish しないで、URL への直接アクセスでチェックするという運用で回避&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hatena.blog/dev&quot;&gt;企業技術ブログ&lt;/a&gt;みたいなFeedまとめは欲しい。
&lt;ul&gt;
&lt;li&gt;はてブとの相乗効果が強いかもしれませんが。&lt;/li&gt;
&lt;li&gt;最近、テックブログが分散していてアグリゲートしてくれるサービスがあると嬉しいので。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;まとめ機能
&lt;ul&gt;
&lt;li&gt;note でいうマガジン的なもの。&lt;/li&gt;
&lt;li&gt;feature 記事機能。&lt;/li&gt;
&lt;li&gt;記事のスコープやオーディエンスに応じて publication 内で綺麗に整理して見せたい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Publicationsの利用者&lt;/h1&gt;
&lt;p&gt;Publications がどのような感じで運用されているかを見てみたいのですが、Publications の一覧ページは存在しませんでした。&lt;/p&gt;
&lt;p&gt;まぁ、このようなちゃんとしたサイトは XML Sitemap を出しているのでそこからたどってみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -s https://zenn.dev/sitemaps/_index.xml | xq -x &apos;//loc&apos; | grep publication | xargs curl -s --output - | zcat | xq -x &apos;//loc&apos;
https://zenn.dev/p/monicle
https://zenn.dev/p/aidemy
https://zenn.dev/p/shelfy
https://zenn.dev/p/varygoodkun
https://zenn.dev/p/team_zenn
https://zenn.dev/p/churadata
https://zenn.dev/p/yumemi_inc
https://zenn.dev/p/vim_jp
https://zenn.dev/p/mixi
https://zenn.dev/p/cybozu_ept
https://zenn.dev/p/heartrails
https://zenn.dev/p/shiguredo
https://zenn.dev/p/sonicgarden
https://zenn.dev/p/moneyforward
https://zenn.dev/p/leaner_dev
https://zenn.dev/p/cybozu_frontend
https://zenn.dev/p/bascule_tech
https://zenn.dev/p/cybozu_neco
https://zenn.dev/p/homura_tech
https://zenn.dev/p/_adakoda
https://zenn.dev/p/chatwork
https://zenn.dev/p/labbase
https://zenn.dev/p/chot
https://zenn.dev/p/nanamusic
https://zenn.dev/p/videotouch
https://zenn.dev/p/manalink_dev
https://zenn.dev/p/spacemarket
https://zenn.dev/p/deepflow_tech
https://zenn.dev/p/rext
https://zenn.dev/p/babel
https://zenn.dev/p/lincwell_inc
https://zenn.dev/p/google_cloud_jp
https://zenn.dev/p/ricora
https://zenn.dev/p/peraichi_blog
https://zenn.dev/p/mutex_inc
https://zenn.dev/p/sre_holdings
https://zenn.dev/p/buyselltech
https://zenn.dev/p/solxyz_bso
https://zenn.dev/p/sharefull_blog
https://zenn.dev/p/tokium_dev
https://zenn.dev/p/spicato_blog
https://zenn.dev/p/funteractiveinc
https://zenn.dev/p/pepabo
https://zenn.dev/p/bluage_techblog
https://zenn.dev/p/morning_night
https://zenn.dev/p/tam_tam
https://zenn.dev/p/babyjob
https://zenn.dev/p/takeyuwebinc
https://zenn.dev/p/tailoor
https://zenn.dev/p/vallis
https://zenn.dev/p/ivry
https://zenn.dev/p/mirrativ_blog
https://zenn.dev/p/zozotech
https://zenn.dev/p/axelmark_tech
https://zenn.dev/p/noplan_inc
https://zenn.dev/p/innoscouter
https://zenn.dev/p/mofmof_inc
https://zenn.dev/p/iwakenlab_book
https://zenn.dev/p/ienter_blog
https://zenn.dev/p/hataluck
https://zenn.dev/p/microsoft
https://zenn.dev/p/beeworks_web
https://zenn.dev/p/altiveinc
https://zenn.dev/p/altura_x
https://zenn.dev/p/lmw
https://zenn.dev/p/paiza
https://zenn.dev/p/avita_blog
https://zenn.dev/p/makery
https://zenn.dev/p/medicalforce
https://zenn.dev/p/karabiner_inc
https://zenn.dev/p/siiibo_tech
https://zenn.dev/p/wasd_inc
https://zenn.dev/p/tellernovel_inc
https://zenn.dev/p/mierune
https://zenn.dev/p/techtrain_blog
https://zenn.dev/p/longrun_jp
https://zenn.dev/p/wwwave
https://zenn.dev/p/necscat
https://zenn.dev/p/ubie_dev
https://zenn.dev/p/thinkingsinc
https://zenn.dev/p/minedia
https://zenn.dev/p/singularity
https://zenn.dev/p/lclco
https://zenn.dev/p/eraman
https://zenn.dev/p/rescuenow
https://zenn.dev/p/cynekastam
https://zenn.dev/p/eishin_blog
https://zenn.dev/p/noxas
https://zenn.dev/p/loglass
https://zenn.dev/p/mapbox_japan
https://zenn.dev/p/naccare
https://zenn.dev/p/catallaxy_dev
https://zenn.dev/p/ncdc
https://zenn.dev/p/hackermeshi
https://zenn.dev/p/any_dev
https://zenn.dev/p/readyfor_blog
https://zenn.dev/p/overflow_offers
https://zenn.dev/p/praha
https://zenn.dev/p/fivot
https://zenn.dev/p/junni
https://zenn.dev/p/sucotech
https://zenn.dev/p/general_link
https://zenn.dev/p/cloudbase
https://zenn.dev/p/gaudiy_blog
https://zenn.dev/p/sarah
https://zenn.dev/p/folio_sec
https://zenn.dev/p/gemcook
https://zenn.dev/p/dena
https://zenn.dev/p/sakazuki_xyz
https://zenn.dev/p/ourly_tech_blog
https://zenn.dev/p/stafes_blog
https://zenn.dev/p/u2tech
https://zenn.dev/p/smartslide
https://zenn.dev/p/xbit
https://zenn.dev/p/aldagram_tech
https://zenn.dev/p/mybest_dev
https://zenn.dev/p/youngeek
https://zenn.dev/p/morisawa
https://zenn.dev/p/techtalk
https://zenn.dev/p/egstock_inc
https://zenn.dev/p/liquitous
https://zenn.dev/p/kthrlab_blog
https://zenn.dev/p/pakepu
https://zenn.dev/p/a11y_blog
https://zenn.dev/p/gumijp
https://zenn.dev/p/bohkai
https://zenn.dev/p/timetree
https://zenn.dev/p/commew
https://zenn.dev/p/sun_asterisk
https://zenn.dev/p/gu3
https://zenn.dev/p/pyspa
https://zenn.dev/p/no4_dev
https://zenn.dev/p/openly
https://zenn.dev/p/guildex
https://zenn.dev/p/less
https://zenn.dev/p/hirooict
https://zenn.dev/p/socialdog
https://zenn.dev/p/sharediary_app
https://zenn.dev/p/optfit_tech
https://zenn.dev/p/algoage
https://zenn.dev/p/toridori
https://zenn.dev/p/studio
https://zenn.dev/p/protooutstudio
https://zenn.dev/p/flutteruniv_dev
https://zenn.dev/p/microverse_dev
https://zenn.dev/p/airx_inc
https://zenn.dev/p/localworks_dev
https://zenn.dev/p/hacobell_dev
https://zenn.dev/p/miraistudio
https://zenn.dev/p/nocoinc
https://zenn.dev/p/beenos_tech
https://zenn.dev/p/gibjapan
https://zenn.dev/p/insight
https://zenn.dev/p/zoome
https://zenn.dev/p/third_tech
https://zenn.dev/p/devcamp
https://zenn.dev/p/team_soda
https://zenn.dev/p/qin
https://zenn.dev/p/fusic
https://zenn.dev/p/gamewith
https://zenn.dev/p/akinai_tech
https://zenn.dev/p/smartshopping
https://zenn.dev/p/thecreator
https://zenn.dev/p/ochakumi
https://zenn.dev/p/route06
https://zenn.dev/p/bi_knowledge
https://zenn.dev/p/stak
https://zenn.dev/p/dbttokyo
https://zenn.dev/p/bad_company
https://zenn.dev/p/purpom
https://zenn.dev/p/micin
https://zenn.dev/p/sbisecsol
https://zenn.dev/p/stmn_inc
https://zenn.dev/p/kwc_cpaas
https://zenn.dev/p/nkc_ug
https://zenn.dev/p/dataheroes
https://zenn.dev/p/lecto
https://zenn.dev/p/midra_lab
https://zenn.dev/p/gtn
https://zenn.dev/p/algorithms
https://zenn.dev/p/arklet
https://zenn.dev/p/sendo_tech
https://zenn.dev/p/she_techblog
https://zenn.dev/p/activecore
https://zenn.dev/p/hajimari
https://zenn.dev/p/voicelunchjp
https://zenn.dev/p/laiblitz_tech
https://zenn.dev/p/castingone_dev
https://zenn.dev/p/peco4ever_blog
https://zenn.dev/p/fraim
https://zenn.dev/p/carenet
https://zenn.dev/p/turing_motors
https://zenn.dev/p/todoker_blog
https://zenn.dev/p/salescore
https://zenn.dev/p/buzzkuri_tech
https://zenn.dev/p/team_delta
https://zenn.dev/p/sai_dev_blog
https://zenn.dev/p/red_frasco
https://zenn.dev/p/sweeep_blog
https://zenn.dev/p/devrel
https://zenn.dev/p/visasq
https://zenn.dev/p/docs_and_markup
https://zenn.dev/p/jawsug_bgnr
https://zenn.dev/p/line_dc
https://zenn.dev/p/mento_techblog
https://zenn.dev/p/voicy
https://zenn.dev/p/happy_elements
https://zenn.dev/p/azookey
https://zenn.dev/p/gohan_dao
https://zenn.dev/p/karadanote_tech
https://zenn.dev/p/synschismo_inc
https://zenn.dev/p/dotdtech_blog
https://zenn.dev/p/jotaifriends
https://zenn.dev/p/vs_blog
https://zenn.dev/p/urstudx_blog
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;件数&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -s https://zenn.dev/sitemaps/_index.xml | xq -x &apos;//loc&apos; | grep publication | xargs curl -s --output - | zcat | xq -x &apos;//loc&apos; | wc -l
215
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;運用していそうな知っている組織を目視でピックアップ&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://zenn.dev/p/google_cloud_jp&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/mixi&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/shiguredo&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/microsoft&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/visasq&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/line_dc&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/dena&lt;/li&gt;
&lt;li&gt;https://zenn.dev/offers&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/turing_motors&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/spacemarket&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/cybozu_ept&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/cybozu_frontend&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/cybozu_neco&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ほかにも多数。&lt;/p&gt;
&lt;p&gt;運用していないけど知っている組織&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://zenn.dev/p/buyselltech&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/voicy&lt;/li&gt;
&lt;li&gt;https://zenn.dev/p/mirrativ_blog&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;弊社（宣伝）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://zenn.dev/p/minedia&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;まとめ&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;tech blog をどこで構築しようか考えてましたが、Zenn で構築している会社や組織はそこそこあるので、Zenn でよさそう。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Ruby on Railsプロジェクトのrubocop.ymlテンプレ</title><link>https://blog.teraren.com/posts/a88546e4efa1f3/</link><guid isPermaLink="true">https://blog.teraren.com/posts/a88546e4efa1f3/</guid><description>私が育てたプロジェクトの `rubocop.yml` を置いておきます。</description><pubDate>Wed, 15 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;最近、&lt;a href=&quot;https://github.com/rubocop/rubocop-rspec&quot;&gt;rubocop-rspec&lt;/a&gt;というrubocopのrspec用プラグインを見つけました。&lt;/li&gt;
&lt;li&gt;数年前から存在しているようです。早速導入してみたところ、盛大に修正点を上げてくれて、ベストプラクティスを享受できたので感動しました。&lt;/li&gt;
&lt;li&gt;このプラグインはあまり知られていないのかもしれないので記事にしておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;私が育てたプロジェクトの &lt;code&gt;rubocop.yml&lt;/code&gt; を置いておきます。&lt;/p&gt;
&lt;p&gt;最近の rubocop はデフォルトではルールが厳しすぎるので、コードのみやすさやパフォーマンスに影響が少ないところは無効化しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  gem &apos;rubocop&apos;, require: false
  gem &apos;rubocop-performance&apos;, require: false
  gem &apos;rubocop-rails&apos;, require: false
  gem &apos;rubocop-rspec&apos;, require: false
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;inherit_from: .rubocop_todo.yml

## This configuration was generated by
## `rubocop --auto-gen-config`
## on 2017-11-25 11:44:56 +0000 using RuboCop version 0.51.0.
## The point is for the user to remove these configuration records
## one by one as the offenses are removed from the code base.
## Note that changes in the inspected code, or installation of new
## versions of RuboCop, may require this file to be generated again.

## Offense count: 15
## Cop supports --auto-correct.
## Configuration parameters: Include, TreatCommentsAsGroupSeparators.
## Include: **/Gemfile, **/gems.rb
require:
  - rubocop-rails
  - rubocop-performance
  - rubocop-rspec

AllCops:
  TargetRubyVersion: 3.1
  Exclude:
    - &apos;vendor/**/*&apos;
    - &apos;db/**/*&apos;
    - &apos;lib/tasks/**/*&apos;
    - &quot;db/schema.rb&quot;
    - &apos;bin/*&apos;
    - &apos;test/*&apos;
    - &apos;node_modules/**/*&apos;
    - &apos;config/initializers/**/*&apos;
    - &apos;public/**/*&apos;
    - &apos;storage/**/*&apos;
    - &apos;log/**/*&apos;
    - &apos;tmp/**/*&apos;
    - &apos;terraform/**/*&apos;
    - &apos;openapi/**/*&apos;
  NewCops: enable

## sider&apos;s rubocop stops during this file
Rails/HttpStatus:
  Exclude:
    - &apos;app/controllers/application_controller.rb&apos;

Rails/SkipsModelValidations:
  AllowedMethods:
    - &apos;touch&apos;
    - &apos;upsert_all&apos;

Layout/LineLength:
  Max: 200
  Exclude:
    - &apos;spec/**/*&apos;
    - &apos;config/**/*&apos;

Layout/ParameterAlignment:
  Enabled: false

Layout/EmptyLineBetweenDefs:
  Enabled: false

Layout/EmptyLines:
  Enabled: false

Layout/EmptyLinesAroundAccessModifier:
  Enabled: false

Layout/EmptyLinesAroundBlockBody:
  Enabled: false

Layout/EmptyLinesAroundClassBody:
  Enabled: false

Layout/EmptyLinesAroundMethodBody:
  Enabled: false

Layout/ExtraSpacing:
  Enabled: false

Layout/IndentationConsistency:
  Enabled: false

Layout/SpaceBeforeBlockBraces:
  Enabled: false

Layout/SpaceInsideHashLiteralBraces:
  Enabled: false

Layout/EmptyLinesAroundAttributeAccessor:
  Enabled: true

Layout/SpaceAroundMethodCallOperator:
  Enabled: true

Lint/DeprecatedOpenSSLConstant:
  Enabled: true

Lint/DuplicateElsifCondition:
  Enabled: true

Lint/MixedRegexpCaptureTypes:
  Enabled: true

Lint/RaiseException:
  Enabled: true

Lint/StructNewOverride:
  Enabled: true

Style/AsciiComments:
  Enabled: false

Style/ClassAndModuleChildren:
  Enabled: false

Style/Documentation:
  Enabled: false

Style/EmptyMethod:
  Enabled: false

Style/FrozenStringLiteralComment:
  Enabled: false

Style/GuardClause:
  Enabled: false

## Configuration parameters: Whitelist.
## Whitelist: be, be_a, be_an, be_between, be_falsey, be_kind_of, be_instance_of, be_truthy, be_within, eq, eql, end_with, include, match, raise_error, respond_to, start_with
Style/NumericPredicate:
  Enabled: false

## Readability is more important
Style/RedundantReturn:
  Enabled: false

Style/NumericLiterals:
  Enabled: false

Style/AccessorGrouping:
  Enabled: false

Style/ArrayCoercion:
  Enabled: true

Style/BisectedAttrAccessor:
  Enabled: true

Style/CaseLikeIf:
  Enabled: true

Style/ExponentialNotation:
  Enabled: true

Style/HashAsLastArrayItem:
  Enabled: false

Style/HashEachMethods:
  Enabled: true

Style/HashLikeCase:
  Enabled: true

Style/HashTransformKeys:
  Enabled: true

Style/HashTransformValues:
  Enabled: true

Style/RedundantAssignment:
  Enabled: true

Style/RedundantFetchBlock:
  Enabled: true

Style/RedundantFileExtensionInRequire:
  Enabled: true

Style/RedundantRegexpCharacterClass:
  Enabled: true

Style/RedundantRegexpEscape:
  Enabled: true

Style/SlicingWithRange:
  Enabled: true

Style/TrailingCommaInHashLiteral:
  Enabled: false

## Configuration parameters: EnforcedStyle, SupportedStyles.
## SupportedStyles: all_comparison_operators, equality_operators_only
Style/YodaCondition:
  # Readability is more important
  Enabled: false

Style/FormatStringToken:
  EnforcedStyle: template

Performance/TimesMap:
  Exclude:
    - &apos;spec/**/*&apos;

Metrics/BlockLength:
  Exclude:
    - &apos;spec/**/*&apos;
    - &apos;config/**/*&apos;
    - &apos;app/views/api/v1/**/*&apos;
    - &apos;app/models/order_product.rb&apos; # aasm

Metrics/AbcSize:
  Enabled: false

Metrics/MethodLength:
  Enabled: false

Style/SymbolArray:
  Enabled: false

Style/RescueModifier:
  Enabled: false

Metrics/ClassLength:
  Enabled: false

Metrics/ParameterLists:
  Enabled: false

RSpec/NestedGroups:
  Enabled: false

Capybara/CurrentPathExpectation:
  Enabled: false

RSpec/MultipleMemoizedHelpers:
  Enabled: false

RSpec/ExampleLength:
  Enabled: false

RSpec/ContextWording:
  Enabled: false

RSpec/MultipleExpectations:
  Enabled: false

RSpec/LetSetup:
  Enabled: false

RSpec/Capybara/FeatureMethods:
  Enabled: false

RSpec/ChangeByZero:
  Enabled: false

Naming/VariableNumber:
  Enabled: false
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最新版はこちらに置いておきます。
https://gist.github.com/matsubo/ec5b6cbf0a7207075e2b081f394863e6&lt;/p&gt;
&lt;h2&gt;CIでの実行おススメ&lt;/h2&gt;
&lt;p&gt;もちろんCI上でもrubocopを実行しているのですが、rubocopをオプション無しで実行するとフォーマットの準拠を1つでもしていないとfailします。&lt;/p&gt;
&lt;p&gt;せっかくCIを回したのに、テストがfailしてしまうのはあまりよろしくないです。開発効率を上げるためにCIを入れているのに逆に悪くなってしまいます。&lt;/p&gt;
&lt;p&gt;なので、プログラムの動作に影響しないようなstylingの準拠は無視するようにしています。そのためのオプションがこちら。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% rubocop --fail-level W
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WARNIG 以上の問題だったら終了コードに 0 以外を返却して CI を fail させます。これによってわざわざコードのスタイルを準拠するために commit と push を行わなくて良くなるので気が楽になります。&lt;/p&gt;
</content:encoded></item><item><title>Dockerを使ってHTTP3対応のnginxでホスティングしてみる手順</title><link>https://blog.teraren.com/posts/nginx-http3/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nginx-http3/</guid><description>DockerでHTTP3（QUIC）対応のnginxを動かし、Let&apos;s Encrypt証明書とUDP443ポートを使った実際の設定ファイルや動作確認方法をステップごとに紹介します。</description><pubDate>Sun, 12 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;HTTP3に対応したサイトが全世界の&lt;a href=&quot;https://w3techs.com/technologies/details/ce-http3&quot;&gt;ウェブサイトの中で25％ある&lt;/a&gt;らしいです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;nginxのroadmap上では、3年前からHTTP3が入っているのに2023年2月11日現在ではまだ&lt;a href=&quot;https://trac.nginx.org/nginx/roadmap&quot;&gt;stableでのリリースは行われていません&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;HTTP3を簡単に試してみるツール類は揃ってきているので今回は、HTTP3対応のnginxを使ってどんな感じの運用になるかをテストしてみます。&lt;/p&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;h3&gt;前提&lt;/h3&gt;
&lt;p&gt;nginxをリバースプロクシとして動かし、バックエンドとしてlocalhostの3005番ポートでRuby on Railsサービスが動いているという前提です。&lt;/p&gt;
&lt;p&gt;nginxにはlet&apos;s encryptで取得したTLS証明書を使ってhttpsで接続しています。&lt;/p&gt;
&lt;p&gt;今回の対象サイト: &lt;a href=&quot;https://train.teraren.com/&quot;&gt;https://train.teraren.com/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;サーバサイドの設定&lt;/h3&gt;
&lt;p&gt;HTTP3のデフォルトでは、UDP443ポートを使います。デフォルトなだけで、任意のポートも利用できます。&lt;/p&gt;
&lt;p&gt;とりあえず、以下のようなコマンドを打ち込んでみてUDPの443ポートが使われていないことを確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% netstat -ln | grep 443 | grep udp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、以下のような設定ファイルを作成します。&lt;/p&gt;
&lt;p&gt;設定ファイルの内容は適宜変更してください。TLS証明書のファイルの場所、ドキュメントrootの場所　を適宜変更します。&lt;/p&gt;
&lt;p&gt;proxy_passに指定するバックエンドのサービスのホスト名は、docker container内から参照できるIPアドレスまたはホスト名にする必要があります。ここで、localhostと指定してもコンテナ自体のホストを指すことになってしまいますので注意してください。&lt;/p&gt;
&lt;p&gt;そして、docker composeで立ち上げればOKです。let&apos;s encryptのファイルの読み込みにはroot権限が必要になりますが、docker自体がroot権限で実行されるようなので一般ユーザで起動してもちゃんと読み込めてます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これで立ち上がります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;これで、1つのバックエンドサービスに対して2つのWebサーバが立ち上がっている状態になります。1つは元から動いているnginx、2つ目は今回立ち上げたHTTP3対応nginxです。&lt;/p&gt;
&lt;p&gt;最後に、外部から接続できるようにfirewallやパケットフィルタの設定などでUDP 443への接続を許可します。&lt;/p&gt;
&lt;h3&gt;接続テスト&lt;/h3&gt;
&lt;p&gt;ブラウザ上ではhttp2もhttp3も同じURLになります。後述するalt-svcヘッダを出力する設定を元のnginx側で出力するようにする設定が必要になります（後述）&lt;/p&gt;
&lt;p&gt;よって、まずはCLIを使ってテストしてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker run -it --rm ghcr.io/unasuke/curl-http3:quiche-latest curl -IL https://train.teraren.com/ --http3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;正常な結果&lt;/p&gt;
&lt;p&gt;もし、HTTP3のnginxの設定が間違っていた場合は500系のエラーが返ってきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;500系のエラー&lt;/p&gt;
&lt;p&gt;HTTP3のnginxを立ち上げたdocker composeの標準出力にアクセスログやエラーが表示されるのでその内容をチェックすれば良いと思います。&lt;/p&gt;
&lt;h3&gt;HTTP3に対応していることをブラウザへ　告知&lt;/h3&gt;
&lt;p&gt;現時点でブラウザは、httpsスキーマが指定されたらTCP 443番に対してTLSを使って接続し、HTTP 2.0などのアプリケーションプロトコルを使って接続を試みます。&lt;/p&gt;
&lt;p&gt;この状態では、ウェブサイトがHTTP3に対応しているかどうかわかりません。なので、このTCPで接続した際にHTTP3に対応していることをHTTPヘッダのレスポンスで返します。&lt;/p&gt;
&lt;p&gt;以下の設定をTCPで運用している元のnginxに追加します。これにより、ブラウザはHTTP3でのサービス提供が行われているサイトということを認識できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;add_header alt-svc &apos;h3=&quot;:443&quot;; ma=3600&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;外部のチェッカー&lt;/h3&gt;
&lt;p&gt;何故かエラーになる。。。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://http3check.net/?host=https%3A%2F%2Ftrain.teraren.com%2F&quot;&gt;https://http3check.net/?host=https%3A%2F%2Ftrain.teraren.com%2F&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;余談&lt;/h3&gt;
&lt;p&gt;自分の使っているブラウザがHTTP3に対応しているかどうかは以下のサイトなどでチェックできます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://cloudflare-quic.com/&quot;&gt;https://cloudflare-quic.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;手元のBraveブラウザではなぜかHTTP3での接続が行われない状態でした。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HTTP3用nginxを立ち上げると、同じような設定を2箇所で管理しないといけないので面倒です。早くstableでHTTP3を対応してほしいです。&lt;/li&gt;
&lt;li&gt;すでにlet&apos;s encryptで証明書を取得している場合は簡単にHTTP3を試せます。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Minecraft Server(統合版)をUbuntu上で起動する</title><link>https://blog.teraren.com/posts/post-14986/</link><guid isPermaLink="true">https://blog.teraren.com/posts/post-14986/</guid><description>Ubuntu 22でMinecraft Bedrock版（統合版）サーバを無料で立ち上げる手順を解説。ダウンロードから起動、外部公開のためのポート設定まで3分でセットアップできます。</description><pubDate>Mon, 06 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu 22でMinecraftのBedrock(統合版)サーバを動かすための方法を記載します。(Bedrock版と、Java版が存在します。Java版を使っていない場合はBedrockを使えばOKです)&lt;/li&gt;
&lt;li&gt;Minecraftのサーバは無料です。Linuxの操作に慣れていれば3分ぐらいでセットアップが完了します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;手順&lt;/h2&gt;
&lt;p&gt;Bedrockのサーバは以下のURLで公開されています。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.minecraft.net/ja-jp/download/server/bedrock&quot;&gt;https://www.minecraft.net/ja-jp/download/server/bedrock&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下に、現時点での最新のサーバをダウンロードして解凍する手順を記載します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% mkdir bedrock
% cd bedrock
% wget https://minecraft.azureedge.net/bin-linux/bedrock-server-1.19.52.01.zip
% unzip bedrock-server-1.19.52.01.zip
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;起動方法&lt;/h2&gt;
&lt;p&gt;以下のコマンドを打てば立ち上がります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% LD_LIBRARY_PATH=. ./bedrock_server
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;サーバを停止するためにはCtrl−Cを押せばサーバを終了できます。&lt;/p&gt;
&lt;h2&gt;ポート開放&lt;/h2&gt;
&lt;p&gt;サーバ自体にfirewallが設定されている場合は、以下の内容でポートを開放して外部から接続できるようにします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IPv4で接続する場合は、UDPの19132を開放します。&lt;/li&gt;
&lt;li&gt;IPv6で接続する場合は、UDPの19133を開放します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;サーバが自宅などのNAT内に置かれている場合は、ルータ上でパケットフィルタの解除と静的NATの設定（＝静的ポートフォワーディング）を変更してください。&lt;/p&gt;
&lt;p&gt;このあとに、Minecraftから立ち上げたサーバのアドレスを指定してログインできれば成功です。&lt;/p&gt;
&lt;h2&gt;接続権限の設定&lt;/h2&gt;
&lt;p&gt;普通にサーバを立ち上げただけでは、全世界から誰でもアクセスが可能で、しかもメンバー権限で接続できてしまうので勝手に遊ばれてしまいます。&lt;/p&gt;
&lt;p&gt;それを防ぐために、特定のユーザだけが接続して遊べるように設定をします。&lt;/p&gt;
&lt;p&gt;server.propertiesをテキストエディタで開いて以下のように設定をしました。&lt;/p&gt;
&lt;p&gt;1つ目のallow-cheatsはチートを禁止するようにする設定をしています。&lt;/p&gt;
&lt;p&gt;2つ目はdefault-player-permission-levelでデフォルトの権限を設定します。他人が接続してきたときの権限を設定しておきます。最低の権限がvisitorしか無いのでvisitorを設定します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff  server.properties.default server.properties
23c23
&amp;lt; allow-cheats=true
---
&amp;gt; allow-cheats=false
79c79
&amp;lt; default-player-permission-level=visitor
---
&amp;gt; default-player-permission-level=member
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、permission.jsonを編集して以下のようなフォーマットで遊べるユーザのIDを記載します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cat ~/bedrock/permissions.json
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[
  {
    &quot;permission&quot;: &quot;operator&quot;,
    &quot;xuid&quot;: &quot;2535406840148511&quot;
  },
  {
    &quot;permission&quot;: &quot;operator&quot;,
    &quot;xuid&quot;: &quot;2535471542624633&quot;
  }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記の設定例では、2人のユーザを接続可能にしています。&lt;/p&gt;
&lt;p&gt;xuidのIDは、Minecraftのアプリからサーバに接続するとログに出力されるので、その値をコピペします。&lt;/p&gt;
&lt;h2&gt;自動起動設定&lt;/h2&gt;
&lt;p&gt;自動起動の設定をしておかないと、サーバが途中で停止したときに自動で再起動されないので遊べなくなってしまいます。だいたい数日ぐらい遊ぶと勝手にサーバが落ちてしまいます。&lt;/p&gt;
&lt;p&gt;自動起動の設定は別の記事に書きました。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/minecraft-bedrock-server-setup/&lt;/p&gt;
</content:encoded></item><item><title>Minecraft Server (統合版) をsystemdによる自動起動設定</title><link>https://blog.teraren.com/posts/minecraft-bedrock-server-setup/</link><guid isPermaLink="true">https://blog.teraren.com/posts/minecraft-bedrock-server-setup/</guid><description>Minecraft Server (統合版) をsystemdによる自動起動設定</description><pubDate>Sun, 05 Feb 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Minecraft BedrockサーバをLinux上で起動させてSystemd配下でサービスを管理する設定。&lt;/li&gt;
&lt;li&gt;Minecraft bedrockサーバはしばらく立ち上げておくとメモリを食いすぎて勝手に落ちてしまいます。勝手に落ちたら手動で起動をするのが面倒なので systemd配下で管理して勝手に再起動をするように設定します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定内容&lt;/h2&gt;
&lt;p&gt;以下のREADMEに書いてあるコマンドの流れで設定します。&lt;/p&gt;
&lt;p&gt;bedrock.serviceファイルのUserやbedrockサーバの実行バイナリが置いてある場所は各自の内容に置き換えてください。&lt;/p&gt;
&lt;h2&gt;備考&lt;/h2&gt;
&lt;p&gt;以下のサイトに紹介されている方法は余計なことが色々書いてあり、あまり使いたくなかったため自分で書きました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://minecraft.server-memo.net/bedrock_server_install_centos8/&quot;&gt;https://minecraft.server-memo.net/bedrock_server_install_centos8/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/gatopeich/36ed7fab3850367bbcd8e6f40becd4e5&quot;&gt;https://gist.github.com/gatopeich/36ed7fab3850367bbcd8e6f40becd4e5&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>和暦や休日情報をREST APIで提供するサービスを公開</title><link>https://blog.teraren.com/posts/seireki-wareki-api/</link><guid isPermaLink="true">https://blog.teraren.com/posts/seireki-wareki-api/</guid><description>西暦↔和暦変換・年齢計算・日本の祝日一覧をJSON形式で取得できるREST APIサービスの公開を発表し、curlを使った具体的な利用例を紹介します。</description><pubDate>Mon, 09 Jan 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;以下の情報の取得や変換を行えるサービスを公開しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;和暦→西暦変換&lt;/li&gt;
&lt;li&gt;西暦→和暦&lt;/li&gt;
&lt;li&gt;休日一覧&lt;/li&gt;
&lt;li&gt;年齢&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://seireki.teraren.com/&quot;&gt;https://seireki.teraren.com/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;APIの利用例&lt;/h2&gt;
&lt;h3&gt;和暦を取得&lt;/h3&gt;
&lt;p&gt;今年に関する情報を取得。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -s https://seireki.teraren.com/seireki/2023.json | jq
{
  &quot;seireki&quot;: &quot;2023年&quot;,
  &quot;wareki&quot;: &quot;令和5年&quot;,
  &quot;eto&quot;: &quot;卯&quot;,
  &quot;age&quot;: 0,
  &quot;url&quot;: &quot;https://seireki.teraren.com/seireki/2023.json&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1950年生まれの人の年齢を取得&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% curl -s https://seireki.teraren.com/seireki/1950.json | jq &apos;.age&apos;
73
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2023年の休日一覧を取得&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% curl -s https://seireki.teraren.com/holiday/2023.json | jq
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[
  {
    &quot;date&quot;: &quot;2023-01-01&quot;,
    &quot;name&quot;: &quot;元日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-01-02&quot;,
    &quot;name&quot;: &quot;振替休日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-01-09&quot;,
    &quot;name&quot;: &quot;成人の日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-02-11&quot;,
    &quot;name&quot;: &quot;建国記念の日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-02-23&quot;,
    &quot;name&quot;: &quot;天皇誕生日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-03-21&quot;,
    &quot;name&quot;: &quot;春分の日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-04-29&quot;,
    &quot;name&quot;: &quot;昭和の日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-05-03&quot;,
    &quot;name&quot;: &quot;憲法記念日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-05-04&quot;,
    &quot;name&quot;: &quot;みどりの日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-05-05&quot;,
    &quot;name&quot;: &quot;こどもの日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-07-17&quot;,
    &quot;name&quot;: &quot;海の日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-08-11&quot;,
    &quot;name&quot;: &quot;山の日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-09-18&quot;,
    &quot;name&quot;: &quot;敬老の日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-09-23&quot;,
    &quot;name&quot;: &quot;秋分の日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-10-09&quot;,
    &quot;name&quot;: &quot;スポーツの日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-11-03&quot;,
    &quot;name&quot;: &quot;文化の日&quot;
  },
  {
    &quot;date&quot;: &quot;2023-11-23&quot;,
    &quot;name&quot;: &quot;勤労感謝の日&quot;
  }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Google SpreadsheetやExcelから利用する方法&lt;/h3&gt;
&lt;p&gt;Google Spreadsheetでは和暦を表示できません。Google App Scriptで西暦から和暦への変換プログラムを書いてよいのですが、なかなか複雑なので今回使ったサービスを使って和暦を表示してみたいと思います。&lt;/p&gt;
&lt;p&gt;また、自分でロジックを書くと新たな和暦が登場したときにメンテナンスが必要になるという問題も発生します。&lt;/p&gt;
&lt;p&gt;Google SpreadsheetではGoogle App Scriptを使うとREST APIの呼び出しと、JSONのパースができるようになります。&lt;/p&gt;
&lt;p&gt;出力例とサンプルファイルのURL↓&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/12/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.google.com/spreadsheets/d/1DiEUrZNH3Y7jJNrryQmRn04eMQO4zpoSHzKJg05Km38/edit?usp=sharing&quot;&gt;https://docs.google.com/spreadsheets/d/1DiEUrZNH3Y7jJNrryQmRn04eMQO4zpoSHzKJg05Km38/edit?usp=sharing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Google App ScriptでREST APIを呼び出します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getWarekiFromSeireki(year) {

  const url = &apos;https://seireki.teraren.com/seireki/&apos; + year  + &apos;.json&apos;;

  try {
    ContactsApp response = UrlFetchApp.fetch(url, {&apos;muteHttpExceptions&apos;: true});
    response_object = JSON.parse(response);
    return response_object[&apos;wareki&apos;];
  }catch(e){
    Logger.log(e);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;その他&lt;/h2&gt;
&lt;p&gt;機能要望や不具合要望はDiscordの方へご連絡願います。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://discord.com/channels/725542623594545233/1032168402925662229&quot;&gt;https://discord.com/channels/725542623594545233/1032168402925662229&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>AWS Organizationを導入した後にAWS IDを作る手順</title><link>https://blog.teraren.com/posts/aws-organization-account-creation/</link><guid isPermaLink="true">https://blog.teraren.com/posts/aws-organization-account-creation/</guid><description>AWS Organizationを導入した後にAWS IDを作る手順</description><pubDate>Fri, 16 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;備忘録。マニュアルは長ったらしいし、ベストプラクティスがよくわからないので、以下のような感じで運用していきます。&lt;/p&gt;
&lt;h2&gt;手順&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;上位OUのアカウントにログイン&lt;/li&gt;
&lt;li&gt;AWS OrganizationsのページからAccountを作成（ここで言うAccountとはAWS IDのことを意味しています）
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://console.aws.amazon.com/organizations/home?region=ap-northeast-1&quot;&gt;https://console.aws.amazon.com/organizations/home?region=ap-northeast-1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;利用するメールアドレスはエイリアス使ったほうが良いです。1メールアドレスに対して1つのAWS IDのrootアカウントしか紐付けられません。例: foo.bar+product-development@example.com&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://console.aws.amazon.com/&quot;&gt;https://console.aws.amazon.com/&lt;/a&gt; へ行って、rootアカウントでログインをするリンクをクリックして、パスワードリマインダを送る。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://console.aws.amazon.com/iam/home#/home&quot;&gt;https://console.aws.amazon.com/iam/home?#/home&lt;/a&gt; に行って、IAMのログイン用URLを作成する。&lt;/li&gt;
&lt;li&gt;(任意) AdministratorAccessのIAMアカウントを作る。&lt;/li&gt;
&lt;li&gt;AWS Organizationの上位OUにログインして、SwitchRoleでログインできるかを確認。&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>CloudFrontにてCORSを利用する際の設定方法</title><link>https://blog.teraren.com/posts/cloudfront-cors-s3/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cloudfront-cors-s3/</guid><description>CloudFrontとS3でCORSリクエストが成功したり失敗したりする原因と、Originヘッダのキャッシュ設定を正しく行う具体的な解決方法</description><pubDate>Wed, 14 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;久しぶりにハマったので備忘録を残しておきます&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;CloudFrondを使っている環境において、CORS (Cross-Origin Resource Sharing) に該当するリクエストが成功したり失敗したりしました。&lt;/p&gt;
&lt;h2&gt;前提の共有&lt;/h2&gt;
&lt;p&gt;サーバサイドにおけるCORSの挙動は2種類あります。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;どんなリクエストに対してもCORSの設定を含んだHTTPレスポンスを返却する&lt;/li&gt;
&lt;li&gt;HTTPリクエストにOriginヘッダがあった場合に、CORSの設定を含んだHTTPレスポンスを返す。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;nginxとかrailsのアプリケーションで適当に設定してしまう場合は面倒なので1番めになります。AWS S3で設定する場合は2番の設定になります。&lt;/p&gt;
&lt;p&gt;そのため、2番の設定を検証するためにはリクエストにOriginヘッダを含めて検証する必要があります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -i &apos;https://postcode.teraren.com/postcodes.json&apos; -H &apos;Origin: http://example.com&apos; 2&amp;gt;&amp;amp;1|grep -i access
access-control-allow-origin: *
access-control-allow-methods: GET, HEAD
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;また、1の場合はCDNにおいて一律クライアントに返却する場合と、CDNのorigin側でレスポンスを返すという2パターンのデプロイ方法が存在します。&lt;/p&gt;
&lt;p&gt;このあたりのポリシーを決めた上で、設定していく必要があります。この設計によってトラブルシューティングする場所が大幅に変わってきます。&lt;/p&gt;
&lt;h2&gt;問題が起きるケース&lt;/h2&gt;
&lt;p&gt;2時間ぐらいトラブルシュートして、やっと問題がわかりました。CloudFrontをほぼデフォルトで設定した場合に起きる、以下のようなケースのときです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTTPクライアントがOriginヘッダを付けないでCloudFrontにリクエスト&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CloudFrontにhttpレスポンスヘッダも含めてキャッシュされる。（CORSのレスポンスが入らないキャッシュができる）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTTPクライアントがOriginヘッダを付けてCloudFrontにリクエスト&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CDNがキャッシュ済みのオブジェクトを返却。（これにはCORSが入っていない）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;対処方法&lt;/h2&gt;
&lt;p&gt;CloudFrontのBehaviorsの設定において、CDN上のキャッシュのキーにHTTPリクエストの&quot;Origin&quot;ヘッダを含めるようにする。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/12/Pasted_Image_2022_12_15_17_54.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Elemental-MediaPackage&lt;/h3&gt;
&lt;p&gt;Managedポリシーの中で唯一Originヘッダをキーとして使うルールです。他にも細かい設定が入っているのですが、面倒なのでこれを使います。&lt;/p&gt;
&lt;h3&gt;CORS-S3Origin&lt;/h3&gt;
&lt;p&gt;HTTPクライアントから送られてきたリクエストをOriginに送るヘッダです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;origin&lt;/li&gt;
&lt;li&gt;access-control-request-headers&lt;/li&gt;
&lt;li&gt;access-control-request-method&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;PoC&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;// This would succeed if CORS setting is correct.
fetch(&quot;https://postcode.teraren.com/favicon.ico&quot;)
  .then((res) =&amp;gt; res.blob())
  .then((blob) =&amp;gt; {
    let image = new Image();
    image.src = URL.createObjectURL(blob);
    image.width = 200;
    image.height = 200;
    document.getElementById(&quot;cf&quot;).appendChild(image);
  })
  .catch((error) =&amp;gt; {
    console.error(&quot;通信に失敗しました&quot;, error);
  });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;https://codepen.io/matsubokkuri/pen/wvXLbzo&lt;/p&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;p&gt;https://zenn.dev/bun913/articles/cloudfront-cors-policies&lt;/p&gt;
&lt;h2&gt;余談1&lt;/h2&gt;
&lt;p&gt;BraveやChromeのDeveloper Consoleでトラブルシュートをしているときに、Networkタブにて確認しているとがOriginヘッダ無しのリクエストを出したり、Originヘッダ付きのリクエストを出したりしていました。&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-successive-word &lt;em&gt;/}
よくよく確認してみると、Javascriptからの呼び出しは1回なのに、リクエストが2回飛んでいました。
{/&lt;/em&gt; textlint-enable ja-technical-writing/ja-no-successive-word */}1つは、意図した通りのリクエスト、もう1つは単にブラウザがGETしているだけのリクエスト。後者を呼び出すようなコードを書いていないので意味不明だった。&lt;/p&gt;
&lt;p&gt;トラブルシューティングをする際に、上記の2種類のリクエストのどちらをチェックするかによって変わってくるのでそこをしっかり確認しておく必要があります。&lt;/p&gt;
&lt;p&gt;→原因判明。上記のPoCのコードを&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;image.src = &quot;http://postcode.teraren.com/favicon.ico&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;と書くと、CORSを考慮しない普通のGETリクエストが走ることになり、fetchとは別のリクエストが飛びます。しかしながら、ブラウザのキャッシュのメカニズムが、URLをキーとしたキャッシュになるのでCORS無しのリクエスト、レスポンスがキャッシュから呼ばれてしまうときがあります。&lt;/p&gt;
&lt;p&gt;よって、1ページ内で外部リソースを読むときに、CORS付きでリクエストをするコードと、CORS無しでリクエストをするコードが存在する場合、予期しない挙動になります。&lt;/p&gt;
&lt;p&gt;自分でスクラッチから書いていれば問題ないと思いますが、ライブラリレベルで外部リソースの呼び出し方が異なる場合はかなり面倒なことになります。どちらかのライブラリを使わないようにする解決方法しか無いのかなと思います。&lt;/p&gt;
&lt;h2&gt;余談2&lt;/h2&gt;
&lt;p&gt;かつて、メルカリがCDNの設定をミスって情報漏洩をしたこともあります。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://engineering.mercari.com/blog/entry/2017-06-22-204500/&quot;&gt;https://engineering.mercari.com/blog/entry/2017-06-22-204500/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;CDNの設定は、アプリケーションごとにいろいろなユースケースを考えてテストをしないといけないので、なかなか難しいです。&lt;/p&gt;
</content:encoded></item><item><title>Rail7の推奨になったimportmap+ dartsassを使ってサービスを構築してみました</title><link>https://blog.teraren.com/posts/rail7-importmap-service/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rail7-importmap-service/</guid><description>Rails 7で標準採用されたimportmapとdart-sassを使い、西暦和暦変換サービス「元号くん」を実際に開発して公開した経験をもとに、importmapの仕組みと実践的な使い方を解説します。</description><pubDate>Wed, 14 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://qiita.com/advent-calendar/2022/ruby-on-rails&quot;&gt;Ruby on Rails Advent Calendar 2022&lt;/a&gt;の17日目の記事です。&lt;/li&gt;
&lt;li&gt;Ruby on Rails 7.0からアセット管理にimport mapsが使われるようになりました。Rails6のときに使われていたwebpackerとは大きく仕組みが異なります。&lt;/li&gt;
&lt;li&gt;import mapsの学習のためにrails newから始めて、1つサービスを構築して公開してみました。&lt;/li&gt;
&lt;li&gt;個人的には日本や世界のDXをに役立ったり、生活を便利にするサービスを作ることを片手間におこなっています。今回もその一環です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;今回作ったサイト&lt;/h3&gt;
&lt;p&gt;「元号くん」という名称で、西暦から和暦を表示したり、和暦から西暦を表示できます。また、各年ごとの祝日の情報を表示しています。&lt;/p&gt;
&lt;p&gt;ただ表示するだけではRailsを使う意味があまりないのでREST APIでも同様の変換を提供できるようにしました。&lt;/p&gt;
&lt;p&gt;サイトのURLは以下になります。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://seireki.teraren.com/&quot;&gt;https://seireki.teraren.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;トップページのスクリーンショットは以下です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/12/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;importmapとは&lt;/h3&gt;
&lt;p&gt;すでに解説記事が多数あるのでそちらを参照するのが良いです。こちらの記事がとても理解しやすかったです。&lt;/p&gt;
&lt;p&gt;JSのmoduleをimportするときに、今まではブラウザ上では相対パスでしか指定できなかったけど、importするmoduleとしてnode_moduleやURLなど色々指定できるようにする機能というかんじです。なるほど。&lt;/p&gt;
&lt;p&gt;https://blog.mizukami.sh/entry/2022/05/23/importmap&lt;/p&gt;
&lt;h3&gt;importmapの対応ブラウザ&lt;/h3&gt;
&lt;p&gt;2022年12月14日時点でグローバルで72.9%です。古めのsafariだと対応してい無さそうです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/12/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://caniuse.com/import-maps&quot;&gt;https://caniuse.com/import-maps&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;サービス構築&lt;/h2&gt;
&lt;h3&gt;要件定義&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;importmapを使う。&lt;/li&gt;
&lt;li&gt;REST APIからも利用できるようにする。&lt;/li&gt;
&lt;li&gt;すでに動いている自宅サーバで公開できるようにすることでサーバ費用はほぼ0円で運用する。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;外部設計&lt;/h3&gt;
&lt;p&gt;大したサービスではないのでページ階層を書いておきます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;トップページ
&lt;ul&gt;
&lt;li&gt;西暦→和暦 一覧
&lt;ul&gt;
&lt;li&gt;各西暦のページ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;和暦→西暦 一覧
&lt;ul&gt;
&lt;li&gt;和暦のページ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;年ごとの休日一覧
&lt;ul&gt;
&lt;li&gt;年ごとのページ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;内部設計&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;西暦と和暦を変換するgemである&lt;a href=&quot;https://github.com/sugi/wareki&quot;&gt;wareki&lt;/a&gt;を使えばかんたんに実装できそうです。&lt;/li&gt;
&lt;li&gt;休日のマスタは&lt;a href=&quot;https://github.com/holiday-jp/holiday_jp-ruby&quot;&gt;holiday_jp&lt;/a&gt;を使えばかんたんに実装できそうです。&lt;/li&gt;
&lt;li&gt;RDBなどのストレージは使わないで運用できそうなのでストレージの設計は無いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;実装&lt;/h3&gt;
&lt;p&gt;まずはじめに開発サーバを作ります。dockerによるコンテナ上で開発をするので開発環境を準備します。&lt;/p&gt;
&lt;p&gt;以下のファイルを準備します。&lt;/p&gt;
&lt;p&gt;上記ファイルを準備した上で以下のコマンドを実行して、railsの実行にgemをインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose run --rm app bundle install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、railsの新規プロジェクトを作成します。なんら特殊なオプションを指定しないでrailsの推奨するテンプレで作っていきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose run --rm app bundle exec rails new . -C sqlite3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成されたGemfileを覗いてみます。アセットに関連するgemは以下のものが指定されていました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gem &quot;sprockets-rails&quot;
gem &quot;importmap-rails&quot;
gem &quot;turbo-rails&quot;
gem &quot;stimulus-rails&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ここで、config/importmap.rb の初期設定を見てみます。ここに、ロードする可能性のあるJSの場所を一元管理しておくこととなります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pin &quot;application&quot;, preload: true
pin &quot;@hotwired/turbo-rails&quot;, to: &quot;turbo.min.js&quot;, preload: true
pin &quot;@hotwired/stimulus&quot;, to: &quot;stimulus.min.js&quot;, preload: true
pin &quot;@hotwired/stimulus-loading&quot;, to: &quot;stimulus-loading.js&quot;, preload: true
pin_all_from &quot;app/javascript/controllers&quot;, under: &quot;controllers&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;1行目で書かれているapplication.jsにはstimulusの初期化が書かれています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// cat ./app/javascript/controllers/application.js
import { Application } from &quot;@hotwired/stimulus&quot;

const application = Application.start()

// Configure Stimulus development experience
application.debug = false
window.Stimulus   = application

export { application }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2〜4行目にあるhotwiredの部分では、turbo, stimulusのモジュール定義が入っています。&lt;/p&gt;
&lt;p&gt;最後の行は、pin_all_fromと書かれており、controllers以下のファイルを自動的に展開してキーとして指定できるような定義が書かれています。&lt;/p&gt;
&lt;p&gt;controllers以下のJSの中身は以下のようになっています。stimulusで書かれたJSのテンプレが入っています。stimulusを使わなければごそっと消しても良いかと思います。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ==&amp;gt; ./app/javascript/controllers/application.js &amp;lt;==
import { Application } from &quot;@hotwired/stimulus&quot;

const application = Application.start()

// Configure Stimulus development experience
application.debug = false
window.Stimulus   = application

export { application }

// ==&amp;gt; ./app/javascript/controllers/hello_controller.js &amp;lt;==
import { Controller } from &quot;@hotwired/stimulus&quot;

export default class extends Controller {
  connect() {
    this.element.textContent = &quot;Hello World!&quot;
  }
}

// ==&amp;gt; ./app/javascript/controllers/index.js &amp;lt;==
// Import and register all your controllers from the importmap under controllers/*

import { application } from &quot;controllers/application&quot;

// Eager load all controllers defined in the import map under controllers/**/*_controller
import { eagerLoadControllersFrom } from &quot;@hotwired/stimulus-loading&quot;
eagerLoadControllersFrom(&quot;controllers&quot;, application)

// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
// import { lazyLoadControllersFrom } from &quot;@hotwired/stimulus-loading&quot;
// lazyLoadControllersFrom(&quot;controllers&quot;, application)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;BootstrapのJSとCSSの追加&lt;/h4&gt;
&lt;p&gt;デザインはTwitter bootstrapを使うので追加していきます。&lt;/p&gt;
&lt;p&gt;まずは、今回のメインであるimportmapを使ったJSのロード部分です。まずは、キーを追加します。今回デフォルトで指定されているファイルをそのまま使います。minifyされたファイルのURLが指定されています。&lt;/p&gt;
&lt;p&gt;また、bootstrapが依存しているpopperjsも自動的に追加されました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose run -- app bin/importmap pin bootstrap
Pinning &quot;bootstrap&quot; to https://ga.jspm.io/npm:bootstrap@5.2.3/dist/js/bootstrap.esm.js
Pinning &quot;@popperjs/core&quot; to https://ga.jspm.io/npm:@popperjs/core@2.11.6/lib/index.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;実行後のconfig/importmap.rbがこちら。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pin &quot;application&quot;, preload: true
pin &quot;@hotwired/turbo-rails&quot;, to: &quot;turbo.min.js&quot;, preload: true
pin &quot;@hotwired/stimulus&quot;, to: &quot;stimulus.min.js&quot;, preload: true
pin &quot;@hotwired/stimulus-loading&quot;, to: &quot;stimulus-loading.js&quot;, preload: true
pin_all_from &quot;app/javascript/controllers&quot;, under: &quot;controllers&quot;
pin &quot;bootstrap&quot;, to: &quot;https://ga.jspm.io/npm:bootstrap@5.2.3/dist/js/bootstrap.esm.js&quot;
pin &quot;@popperjs/core&quot;, to: &quot;https://ga.jspm.io/npm:@popperjs/core@2.11.6/lib/index.js&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、上記の定義をもとに app/javascript/application.js で読み込みます。最後の2行を追加します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import &quot;@hotwired/turbo-rails&quot;
import &quot;controllers&quot;

import * as Popper from &quot;@popperjs/core&quot;
import * as Bootstrap from &quot;bootstrap&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、stylesheetです。railsの推奨はdartsassなので、dartsass-railsをインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose run --rm app bundle add dartsass-rails
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
Fetching gem metadata from https://rubygems.org/..........
Resolving dependencies...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;snip&amp;gt;&lt;/code&gt;
Fetching dartsass-rails 0.4.0
&lt;code&gt;&amp;lt;snip&amp;gt;&lt;/code&gt;
Installing dartsass-rails 0.4.0&lt;/p&gt;
&lt;p&gt;そしてインストールを実行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker compose run --rm app bundle exec rails dartsass:install
Build into app/assets/builds
      create  app/assets/builds
      create  app/assets/builds/.keep
      append  app/assets/config/manifest.js
Stop linking stylesheets automatically
        gsub  app/assets/config/manifest.js
      append  .gitignore
Add default app/assets/stylesheets/application.scss
      create  app/assets/stylesheets/application.scss
Add default Procfile.dev
      create  Procfile.dev
Ensure foreman is installed
         run  gem install foreman from &quot;.&quot;
Fetching foreman-0.87.2.gem
Successfully installed foreman-0.87.2
1 gem installed
Add bin/dev to start foreman
      create  bin/dev
Compile initial Dart Sass build
         run  rails dartsass:build from &quot;.&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;+ /usr/local/bundle/gems/dartsass-rails-0.4.0/exe/aarch64-linux/sass --style=compressed --no-source-map --load-path /app/app/assets/stylesheets --load-path /app/app/assets/builds --load-path /app/app/assets/config --load-path /app/app/assets/images --load-path /app/app/assets/stylesheets --load-path /usr/local/bundle/gems/stimulus-rails-1.2.1/app/assets/javascripts --load-path /usr/local/bundle/gems/turbo-rails-1.3.2/app/assets/javascripts --load-path /usr/local/bundle/gems/importmap-rails-1.1.5/app/assets/javascripts --load-path /usr/local/bundle/gems/actiontext-7.0.4/app/assets/javascripts --load-path /usr/local/bundle/gems/actiontext-7.0.4/app/assets/stylesheets --load-path /usr/local/bundle/gems/activestorage-7.0.4/app/assets/javascripts --load-path /usr/local/bundle/gems/actionview-7.0.4/lib/assets/compiled --load-path /app/app/javascript --load-path /app/vendor/javascript /app/app/assets/stylesheets/application.scss:/app/app/assets/builds/application.css
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、CSSのファイルを管理するためにnpm経由でcssを取得します。今までなら、npmによってJSとCSSを同時に取得していましたが、管理が別々になっちゃいます。&lt;/p&gt;
&lt;p&gt;dartsass自体はnodeJS無しで実行できますが、sassファイルの管理自体はnpm経由が私は楽だと思うので結局はnodeJSを使ってしまっています。&lt;/p&gt;
&lt;p&gt;npm-check-updatesによってパッケージの更新がわかるので楽です。&lt;/p&gt;
&lt;p&gt;package.json&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;dependencies&quot;: {
    &quot;bootstrap&quot;: &quot;^5.2.3&quot;,
    &quot;bootstrap-icons&quot;: &quot;^1.10.2&quot;,
    &quot;bootswatch&quot;: &quot;^5.2.2&quot;
  },
  &quot;devDependencies&quot;: {
    &quot;npm-check-updates&quot;: &quot;^16.4.3&quot;
  },
  &quot;license&quot;: &quot;UNLICENSED&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;app/assets/stylesheets/application.scssにファイルを読み込むように書きます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@import &quot;../../../node_modules/bootswatch/dist/flatly/variables&quot;;
@import &quot;../../../node_modules/bootstrap/scss/bootstrap.scss&quot;;
@import &quot;../../../node_modules/bootswatch/dist/flatly/bootswatch&quot;;
@import &quot;../../../node_modules/bootstrap-icons/font/bootstrap-icons&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これでJSの読み込みができつつ、デザインが反映されるようになります。&lt;/p&gt;
&lt;p&gt;その後は、&lt;a href=&quot;https://techracho.bpsinc.jp/hachi8833/2022_11_14/122975&quot;&gt;dartsassによるファイル変更監視などを設定&lt;/a&gt;して、いつもどおりrailsアプリ開発と同じです。&lt;/p&gt;
&lt;h3&gt;テスト&lt;/h3&gt;
&lt;p&gt;個人サービスだし、変更はほとんど行わないので省略。&lt;/p&gt;
&lt;h3&gt;考察&lt;/h3&gt;
&lt;h4&gt;lighthouseで高スコア&lt;/h4&gt;
&lt;p&gt;95点です。ユーザ体験も大きく向上できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/12/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;popperのファイル読み込みが多数出るようになった&lt;/h4&gt;
&lt;p&gt;importmapの前提としては、HTTP2の利用があるので大した問題ではないかもしれませんが、細かく分割されたファイルが読み込まれるようになりました。全部popper関連です。流石に分割され過ぎのような気もしますが、キャッシュ効率を考えるとこれが良いのでしょう。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/12/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;Google Spreadsheetで和暦表示が可能になります&lt;/h4&gt;
&lt;p&gt;Google Spreadsheetでは和暦を表示できません。Google App Scriptで西暦から和暦への変換プログラムを書いてよいのですが、なかなか複雑なので今回使ったサービスを使って和暦を表示してみたいと思います。&lt;/p&gt;
&lt;p&gt;また、自分でロジックを書くと新たな和暦が登場したときにメンテナンスが必要になるという問題も発生します。&lt;/p&gt;
&lt;p&gt;Google SpreadsheetではGoogle App Scriptを使うとREST APIの呼び出しと、JSONのパースができるようになります。&lt;/p&gt;
&lt;p&gt;出力例とサンプルファイルのURL↓&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/12/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.google.com/spreadsheets/d/1DiEUrZNH3Y7jJNrryQmRn04eMQO4zpoSHzKJg05Km38/edit?usp=sharing&quot;&gt;https://docs.google.com/spreadsheets/d/1DiEUrZNH3Y7jJNrryQmRn04eMQO4zpoSHzKJg05Km38/edit?usp=sharing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Google App ScriptでREST APIを呼び出します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getWarekiFromSeireki(year) {

  const url = &apos;https://seireki.teraren.com/seireki/&apos; + year  + &apos;.json&apos;;

  try {
    ContactsApp response = UrlFetchApp.fetch(url, {&apos;muteHttpExceptions&apos;: true});
    response_object = JSON.parse(response);
    return response_object[&apos;wareki&apos;];
  }catch(e){
    Logger.log(e);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;日付から、西暦を出力してあげたほうが親切かなと思いました。&lt;/p&gt;
&lt;h3&gt;その他&lt;/h3&gt;
&lt;p&gt;Webサービスの公開に際して以下のことも行っています&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://seireki.teraren.com/shared/sitemap.xml.gz&quot;&gt;XML Sitemapの出力&lt;/a&gt;とGoogle search consoleへの登録&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kzkn/gretel&quot;&gt;gretel&lt;/a&gt;を利用してパンくずリストの表示と、&lt;a href=&quot;https://developers.google.com/search/docs/appearance/structured-data/breadcrumb?hl=ja&quot;&gt;ld+json&lt;/a&gt;を利用したマークアップ。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://seireki.teraren.com/robots.txt&quot;&gt;robots.txt&lt;/a&gt;の設置&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rcs/google-tag-manager-rails&quot;&gt;google-tag-manager-rails&lt;/a&gt;を入れてGTMを設定&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;rails7 + importmap-rails + dartsass-railsを使って最新の推奨組み合わせを使ってサイトを構築してみました。&lt;/li&gt;
&lt;li&gt;かかった時間は8時間ぐらいです。この記事を書くのに2時間ぐらいです。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>node 18 upgrade error</title><link>https://blog.teraren.com/posts/node-18-upgrade-error/</link><guid isPermaLink="true">https://blog.teraren.com/posts/node-18-upgrade-error/</guid><description>Node.js v18へのアップグレード時に発生するERR_OSSL_EVP_UNSUPPORTEDエラーの原因と、NODE_OPTIONSで回避する方法を解説</description><pubDate>Tue, 06 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Node.js v16からNode.js v18にアップグレードしたらエラーが出ました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;node:internal/crypto/hash:71
  this[kHandle] = new _Hash(algorithm, xofLen);
                  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:71:19)
    at Object.createHash (node:crypto:133:10)
    at module.exports (/app/node_modules/webpack/lib/util/createHash.js:135:53)
    at NormalModule._initBuildHash (/app/node_modules/webpack/lib/NormalModule.js:417:16)
    at /app/node_modules/webpack/lib/NormalModule.js:452:10
    at /app/node_modules/webpack/lib/NormalModule.js:323:13
    at /app/node_modules/loader-runner/lib/LoaderRunner.js:367:11
    at /app/node_modules/loader-runner/lib/LoaderRunner.js:233:18
    at context.callback (/app/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
    at /app/node_modules/babel-loader/lib/index.js:59:103 {
  opensslErrorStack: [ &apos;error:03000086:digital envelope routines::initialization error&apos; ],
  library: &apos;digital envelope routines&apos;,
  reason: &apos;unsupported&apos;,
  code: &apos;ERR_OSSL_EVP_UNSUPPORTED&apos;
}

Node.js v18.12.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://qiita.com/kamada_math/items/4df6f153bb2d0159a4ff&quot;&gt;Node.js v17に入った問題&lt;/a&gt;ようです。以下の環境変数をセットすれば回避できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;NODE_OPTIONS=--openssl-legacy-provider
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;docker-composeでnodeやwebpackを使っている場合は以下の設定をdocker-compose.ymlへ追加すれば回避できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    environment:
      NODE_OPTIONS: --openssl-legacy-provider
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;原因&lt;/h2&gt;
&lt;p&gt;webpackがbabelを使っていて、babelが参照しているライブラリ内でOpenSSL 3.0の今はサポートされていないアルゴリズムかキーサイズのオプションを利用しようとした場合に出るようです。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;はやく、webpackerとbabelから脱却しないとですな。。。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Webpacker has been retired&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/rails/webpacker&quot;&gt;https://github.com/rails/webpacker&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>githubのissueやpull requestをCSVで出力するスクリプトを書きました</title><link>https://blog.teraren.com/posts/github-issues-prs-csv-export/</link><guid isPermaLink="true">https://blog.teraren.com/posts/github-issues-prs-csv-export/</guid><description>githubのissueやpull requestをCSVで出力するスクリプトを書きました</description><pubDate>Thu, 01 Dec 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;特定の検索条件で、githubのissueやpull requestをCSVに出力する必要があったのでスクリプトを書きました。&lt;/p&gt;
&lt;p&gt;APIでの呼び出しはpagingがあるのでちょっとスクリプトを書かないと一覧を取得できないので面倒です。&lt;/p&gt;
&lt;p&gt;https://github.com/matsubo/github-issue-export-script&lt;/p&gt;
&lt;p&gt;oktakitを使えばページ送りを自動でやってくれるので楽です。しかしながら、oktakitのAPIドキュメントが充実していないのでgithubのREST APIと、oktakitのソースコードを照らし合わせながら調べる必要があって時間がかかりました。&lt;/p&gt;
&lt;p&gt;Webで検索しても単純にissueの一覧を出す程度にとどまっていますが、今回やりたかったのはフィルタ条件をいくつかのフィールドに対して設定してCSVで出力したかったのでそのようなコードが見つかりませんでした。&lt;/p&gt;
&lt;p&gt;使い方は&lt;a href=&quot;https://github.com/matsubo/github-issue-export-script/blob/main/README.md&quot;&gt;README&lt;/a&gt;に記載しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/12/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Google SpreadsheetのGOOGLEFINANCE関数で為替レート・株価を取得する方法</title><link>https://blog.teraren.com/posts/google-spreadsheet-fx/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-spreadsheet-fx/</guid><description>Google SpreadsheetのGOOGLEFINANCE関数を使って、特定の日のドル円為替レートや株価を1セルで取得する方法。INDEX関数と組み合わせるテクニックも紹介。</description><pubDate>Mon, 28 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;やりたいこと&lt;/h2&gt;
&lt;p&gt;確定申告や投資記録で「特定の日の為替レート」や「特定の日の株価」をスプレッドシートに記録したいことがある。Google SpreadsheetにはGOOGLEFINANCE関数が用意されていて、外部データソースなしで為替・株価を取得できる。&lt;/p&gt;
&lt;h2&gt;GOOGLEFINANCE関数の基本&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;GOOGLEFINANCE&lt;/code&gt;関数の書式は以下の通り。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=GOOGLEFINANCE(銘柄コード, 属性, 開始日, [終了日], [間隔])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;為替レートの場合、銘柄コードは &lt;code&gt;&quot;CURRENCY:USDJPY&quot;&lt;/code&gt; のように &lt;code&gt;CURRENCY:&lt;/code&gt; プレフィックスを付ける。株価の場合はティッカーシンボルをそのまま指定する（例: &lt;code&gt;&quot;AAPL&quot;&lt;/code&gt;, &lt;code&gt;&quot;ZM&quot;&lt;/code&gt;）。&lt;/p&gt;
&lt;h2&gt;為替レートを取得する&lt;/h2&gt;
&lt;h3&gt;テーブル形式で取得&lt;/h3&gt;
&lt;p&gt;日付を指定すると、ヘッダー行を含む2行のテーブルが自動で生成される。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/image-8.png&quot; alt=&quot;GOOGLEFINANCE関数の結果がテーブルで表示される&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=GOOGLEFINANCE(&quot;CURRENCY:USDJPY&quot;,&quot;price&quot;,&quot;2022/1/1&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この方法だとセルが2行×2列に展開されてしまうため、他のデータと混在するシートでは使いにくい。&lt;/p&gt;
&lt;h3&gt;1つのセルで値だけ取得&lt;/h3&gt;
&lt;p&gt;INDEX関数で2行目2列目を指定すれば、レート値だけを1セルに収められる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/image-7.png&quot; alt=&quot;1セルに為替レートが表示される&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=INDEX(GOOGLEFINANCE(&quot;CURRENCY:USDJPY&quot;,&quot;price&quot;,&quot;2022/1/1&quot;),2,2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;INDEX(...,2,2)&lt;/code&gt; はGOOGLEFINANCE関数が返すテーブルの2行目（データ行）・2列目（価格列）を取り出している。1行目はヘッダー（&quot;Date&quot;, &quot;Close&quot;）なのでスキップする。&lt;/p&gt;
&lt;h3&gt;日付をセル参照にする&lt;/h3&gt;
&lt;p&gt;日付部分をセル参照にすれば、日付リストから一括で為替レートを取得できる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=INDEX(GOOGLEFINANCE(&quot;CURRENCY:USDJPY&quot;,&quot;price&quot;,A2),2,2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A2セルに &lt;code&gt;2022/1/1&lt;/code&gt; のような日付を入れておけば、行をコピーするだけで複数日分のレートが取得できる。&lt;/p&gt;
&lt;h2&gt;株価を取得する&lt;/h2&gt;
&lt;p&gt;為替レートと同じ要領で、ティッカーシンボルを指定すれば株価も取得できる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/image-9.png&quot; alt=&quot;株価を1セルで取得&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=INDEX(GOOGLEFINANCE(&quot;ZM&quot;,&quot;price&quot;,&quot;2022/1/1&quot;),2,2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;日本株の場合は &lt;code&gt;&quot;TYO:7203&quot;&lt;/code&gt;（トヨタ）のように東証のプレフィックスを付ける。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;=INDEX(GOOGLEFINANCE(&quot;TYO:7203&quot;,&quot;price&quot;,&quot;2022/1/1&quot;),2,2)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;注意点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GOOGLEFINANCE関数はリアルタイムではなく、最大20分程度の遅延がある&lt;/li&gt;
&lt;li&gt;過去のデータは取得できるが、あまりに古い日付だとデータがない場合がある&lt;/li&gt;
&lt;li&gt;土日祝日を指定すると直近の営業日のデータが返される&lt;/li&gt;
&lt;li&gt;1スプレッドシートあたりのGOOGLEFINANCE関数の呼び出し回数には上限があるため、大量に使うと&lt;code&gt;#N/A&lt;/code&gt;エラーになることがある&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Google WorkspaceからOffice 365へのユーザ同期が年1回ぐらい止まる問題の対処方法</title><link>https://blog.teraren.com/posts/google-workspace-office-365/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-workspace-office-365/</guid><description>Google WorkspaceのユーザをAzure ADへ自動同期する設定が定期的に止まる問題の対処法。トークン期限切れや証明書失効など3つの障害事例と再認証手順を解説。</description><pubDate>Tue, 08 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;コーポレートSEのお話。（おそらく日本に数人しか必要としないようなユースケースのネタかと思いますが）&lt;/p&gt;
&lt;p&gt;弊社（&lt;a href=&quot;https://corporate.minedia.com/&quot;&gt;マインディア&lt;/a&gt;）ではGoogle Workspaceのユーザ情報をマスタとしています。所属する部署に応じてMicrosoft Office (Office 365)のライセンスを自動付与するような運用をしています。&lt;/p&gt;
&lt;p&gt;3年前ぐらいに以下の記事にあるような超絶面倒な設定をして、Google Workspace側のユーザマスタをMicrosoft Azure AD側に同期する設定をしました。&lt;/p&gt;
&lt;p&gt;https://zenn.dev/cestquigucci/articles/59175c03342c66&lt;/p&gt;
&lt;p&gt;3年前はこれよりもっと面倒なことをしなければならなかったです。設定手順が煩雑すぎてブログの記事にしようと思ってましたが忙しくて頓挫しました。&lt;/p&gt;
&lt;h2&gt;トラブルシュート&lt;/h2&gt;
&lt;h3&gt;事例1&lt;/h3&gt;
&lt;p&gt;定期的に同期が止まるみたいです。&lt;/p&gt;
&lt;p&gt;2021年5月ごろに取得したスクショです。Azure ADにユーザが同期されなくなったのでGoogle Workspace側に登録してある&quot;Microsoft Office 365&quot;のアプリ設定画面を開いたらエラー出ていました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ログをダウンロードしたら以下のようなメッセージが書いてありました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair &lt;em&gt;/}
“Syncing active” と書いてあるのに、失敗するのは謎です。とりあえずエラーの内容がtoken周りなので認証がおかしくなっているのかなと思って”REAUTHORIZE”を押したら直りました。
{/&lt;/em&gt; textlint-enable */}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;事例2&lt;/h3&gt;
&lt;p&gt;1.5年後、またユーザの同期が止まりました。&lt;/p&gt;
&lt;p&gt;今度はAutoprovisioningがinactiveになってました。これをactiveにして、10分ほど待ったら同期されました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;このあたり、変化が激しいので管理画面も変わっちゃっていたりします。&lt;/p&gt;
&lt;h3&gt;事例3&lt;/h3&gt;
&lt;p&gt;2022年2月。また止まりました。事例1と同じエラーです。謎です。&lt;/p&gt;
&lt;p&gt;Error code  Error Details 17013  Generating access token for the SP failed&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;アプリの方の一覧には、別のwarningも出ていたので要注意です。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Certificate expires on Mar 16, 2023 Autoprovisioning ON&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/02/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;対処としては、事例1と同じように再接続しました。3分後ぐらいにMicrosoft 365に同期されました。&lt;br /&gt;
（一応、ユーザ情報の更新をしてトリガーも踏んでおきました）&lt;/p&gt;
</content:encoded></item><item><title>カジノのルーレットシミュレータを書いてみました</title><link>https://blog.teraren.com/posts/roulett-strategy-simulator/</link><guid isPermaLink="true">https://blog.teraren.com/posts/roulett-strategy-simulator/</guid><description>ダズンベット法やマーチンゲール法を組み合わせたルーレット戦略をRubyでシミュレーターとして実装し、本当に勝てるのかを統計的に検証した記事</description><pubDate>Sun, 06 Nov 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ダズンベット法を使うと勝ちやすい&lt;/strong&gt;とか書いてあるので実際にプログラムを書いて検証してみました。&lt;/p&gt;
&lt;p&gt;「勝率が高いベッティング方法と&lt;a href=&quot;https://casinoschool.co.jp/casino_glossary/martingale-system/#:~:text=%E5%8B%9D%E7%8E%875%E5%89%B2%E3%81%BB%E3%81%A9%E3%81%AE,%E3%82%92%E5%8F%96%E3%82%8A%E8%BF%94%E3%81%9D%E3%81%86%E3%81%A8%E3%81%99%E3%82%8B%E4%BD%9C%E6%88%A6%E3%80%82&quot;&gt;マーチンゲール法&lt;/a&gt;による資金管理を組み合わせれば最強じゃね？」と思ってプログラムを書いて検証してみました。&lt;/p&gt;
&lt;p&gt;世の中にあるカジノのシミュレータは、ベッティング方法単体、資金管理方法単体でのシミュレーターはあるのですが両方を一気に実行できるプログラムがなかったので書きました。&lt;/p&gt;
&lt;p&gt;https://github.com/matsubo/roulett-strategy-simulator&lt;/p&gt;
&lt;p&gt;単純な計算で出せないので、ちゃんとオブジェクト指向でアクターとエンティティを整理して書かないときれいに書けないなと感じたので、ちゃんと設計して書くのが面倒でした。&lt;/p&gt;
&lt;p&gt;クラス図を書く必要があるギリギリの難易度くらいでした。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;勝率の高いベッティング方法は過去の履歴を参考にして出やすい目を予測することです。&lt;/p&gt;
&lt;p&gt;確率で考えると赤か黒が10回連続で出る確率は、&lt;/p&gt;
&lt;p&gt;(18^10)/(37^10)=0.00074252=0.074252%&lt;/p&gt;
&lt;p&gt;となるので10回目に同じ色が出る確率は非常に少ないことになります。これを元に10回目は別の色に賭けるということによって勝率をあげようと言うことです。逆張りアプローチです。&lt;/p&gt;
&lt;p&gt;単純な計算で出せないので、ちゃんとオブジェクト指向でアクターとエンティティを整理して書かないときれいに書けないなと感じたので、ちゃんと設計して書くのが面倒でした。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;しかしながら、全然思ったとおりに勝てないことがわかりました。&lt;/p&gt;
&lt;h3&gt;シミュレーションの結果&lt;/h3&gt;
&lt;p&gt;シミュレーションの結局、期待した結果にはなりませんでした。&lt;/p&gt;
&lt;p&gt;9回連続同じ色が出た後に、10回目に同じもの色が出る確率は約1/2です。&lt;/p&gt;
&lt;p&gt;以下のサイトにある通りでした。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;このサイトでは再三言っていますが、カジノにおけるルーレットは過去の事象の歴史と次回の事象には関連性がない独立した事象であるという事です。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.a-taichi.com/casinogamenavi/roulette/roulette9884.html&quot;&gt;https://www.a-taichi.com/casinogamenavi/roulette/roulette9884.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;例&lt;/h3&gt;
&lt;p&gt;基本ルール&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;開始は200クレジット&lt;/li&gt;
&lt;li&gt;戦略を実行するためのベットができなくなった時点で中止&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;毎回1クレジットをランダムに黒か赤に賭ける&lt;/h4&gt;
&lt;p&gt;360プレイ x 100日分実行した結果&lt;/p&gt;
&lt;p&gt;この360プレイというのは、1回のルーレットの実施に2分かかると仮定して、12時間プレイすると仮定した値です。ようするに丸1日中ルーレットをした場合のプレイ数です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/result-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;ずっと黒に賭ける&lt;/h4&gt;
&lt;p&gt;そもそも赤も黒も期待値は同じなので、ずっと黒にかけてみても同じになるはずなので検証。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/result-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; % bundle exec ruby main.rb |grep Won | awk &apos;{ print $2}&apos; | awk  &apos;BEGIN {total=0} {total += $1} END {print total/NR}&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;48.5666
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;48.5666%となるので、ほぼ理論値通り。&lt;/p&gt;
&lt;p&gt;確率は、18/37=0.48648649&lt;/p&gt;
&lt;p&gt;36万回実行してます。&lt;/p&gt;
&lt;h4&gt;5回連続同じ色が出たら逆張り戦略&lt;/h4&gt;
&lt;p&gt;本気で勝ちにいきたいので、ベットする金額はマーチンゲール法を用いてみます。&lt;/p&gt;
&lt;p&gt;マーチンゲール法では、負けた分を取り返すような掛け方になるので1, 2, 4, 8, 16というふうに指数的に増えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/result-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ほとんどのサンプルは資産が微増するようになってます。しかしながら気になるのは、下にスパイクしたときのサンプルです。&lt;/p&gt;
&lt;p&gt;その際に、最後の統計値を見るのが重要です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Test suite result ----------------------
Bankrupt: 6
Bankrupt rate: 6.0%
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;6％が資産不十分になってしまってマーチンゲール法を続けられなくなってます。&lt;/p&gt;
&lt;p&gt;実世界に置き換えると、まる1日カジノに居て、16日に1回は破産します。15回は10％程度の微増です。&lt;/p&gt;
&lt;h4&gt;逆張りをしたときの勝率&lt;/h4&gt;
&lt;p&gt;36万回実行してみた結果、47.926%でした。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Won(%): 47.926 %&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;1回あたりにおける当たる確率は、18/37-19/37 = 0.48648649なので、逆張りをしても意味が無いです。&lt;/p&gt;
&lt;p&gt;ちなみに、ゲームへの参加率は6.452778%でした。実際のゲームで実行するとなると空き時間が多いですね。&lt;/p&gt;
&lt;p&gt;5回連続同じ目が出たときに、当たるまで1単位を逆張りし続けたときの資金残高はこちら。残高が0になっても止まらないように変更して実行しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/result-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;簡単なコードの変更でルーレットの戦略、実行回数、を変更して実行結果をシミュレーションするプログラムを作りました。&lt;/p&gt;
&lt;p&gt;グラフでの出力により視覚的にわかりやすくして、シミュレーションに必要な各種指標を出力するようにしました。&lt;/p&gt;
&lt;p&gt;昔、FXの自動取引プログラムを開発していたときの知識が役に立ちました。&lt;/p&gt;
&lt;p&gt;https://diary.teraren.com/posts/2008-01-20-metatrader-agent/&lt;/p&gt;
</content:encoded></item><item><title>LIXILナビッシュをDIY取り付け（意外と簡単）</title><link>https://blog.teraren.com/posts/2022-10-20-nah461sy-nabish/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2022-10-20-nah461sy-nabish/</guid><description>LIXILナビッシュのDIY取り付け手順。既存混合水栓の取り外しから電源確保、浄水カートリッジの選び方まで、実際の施工写真付きで解説。</description><pubDate>Fri, 21 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;家で料理をすることが多くなってきたし、簡単な手洗いもするので出したり止めたりを繰り返すことが多いです。あと、なんだかんだいって東京都心の水道水はそのまま飲むと臭いので浄水器を付けたいという思いがありました。&lt;/p&gt;
&lt;p&gt;そこで、10万円はしますが、&lt;a href=&quot;https://www.lixil.co.jp/lineup/faucet/navish/&quot;&gt;LIXILのナビッシュ&lt;/a&gt;という商品がまさに要求にぴったりということで買って取り付けをしました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/image-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;このナビッシュは細かいバリエーションが多数あります。&lt;/p&gt;
&lt;p&gt;今回取り付けたのは一番高いものです。「浄水器付き」「電源あり」です。電源はコンセントが必要になります。近くにあればよいですが、ない場合は分岐して持ってくる必要があります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/image-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;交換前の状態&lt;/h2&gt;
&lt;p&gt;混合水栓がついています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/IMG_0439-scaled.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;キッチンの下。お湯の官は食洗機へ伸びています。それにしてもアングルが厳しい感じに設置されている。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/IMG_0440-scaled.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ナビッシュを取り付け&lt;/h2&gt;
&lt;p&gt;まずは古い混合水栓を取り外す必要があります。24mmのロングソケットが必要だったので別途買いました。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B003YUGAHU&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/image-20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ボルトを1つ外すと取れます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/IMG_0442-scaled.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;このボルトを外さないといけない。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/IMG_0443-scaled.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;説明書どおりに接続して、こんな感じにラフに設置してみました。100V ACは食洗機の電源から分岐してきました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/IMG_0445-scaled.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/IMG_0441-scaled.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;後日、コンセントをちゃんと設置してケーブルの取り回しを整理しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/IMG_0494-scaled.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;電磁弁のコントローラ&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/IMG_0495-scaled.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;新設したコンセント。見えないから適当に。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/IMG_0496-scaled.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;夜は光っていてかっこいいです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/IMG_0446-scaled.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;取り付けは簡単に行えました。&lt;/p&gt;
&lt;p&gt;初心者でも可能かと思います。電気の取り回しができない場合は乾電池式を買うのが良いと思います。停電でも使えるのも利点と考えられます。&lt;/p&gt;
&lt;p&gt;毎年1万円ぐらいの浄水器カートリッジを交換する必要があります。高額ではありますが、交換直後は水の匂いが全くなくなって美味しく感じるので1年で交換は必要です。&lt;/p&gt;
&lt;p&gt;食器を手洗いするときに、いちいち水を止めるのが面倒だから出しっぱなしにすることが多かったのですが、自動吐出があると必要なときに&lt;strong&gt;水を出せるから節約&lt;/strong&gt;できます。また、&lt;strong&gt;両手が塞がっているときや手が汚れているときに水を出せるのは非常に快適です。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;カートリッジの型番はJF-45Nです。偽物のカートリッジが多いのでご注意ください。Amazonで本物を見分けるのは困難なので、オフィシャルサイトから買うようにしました。。。高いけど体に入るものなので。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00E59R5LO&quot; kw=&quot;JF-43N&quot;}&lt;/p&gt;
</content:encoded></item><item><title>Rails7 + importmap + dartsass-rails</title><link>https://blog.teraren.com/posts/rails7-importmap-dartsass-rails/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails7-importmap-dartsass-rails/</guid><description>Rails 7のrails newで生成されるimportmap＋dartsass-railsのデフォルト構成を調査。Docker Compose対応サンプルと西暦・和暦変換サービスを用いた実装例を公開。</description><pubDate>Sun, 16 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;Rails7のデフォルトでのアセットの管理がどの様になっているか知りたかったので rails newをしてみました。&lt;/p&gt;
&lt;p&gt;既存プロジェクトを移行したときの差分はこちらです。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/removing-webpacker/&lt;/p&gt;
&lt;p&gt;既存のソースコードの流用などがあるので変更を最小限にしたかったという思いもあってcssbundle-rails + jsbundling-rails + propshaftの構成にしましたが、やはり最新のrails newをしたときの推奨構成を知っておきたくなったため今回はrails newをしました。&lt;/p&gt;
&lt;h2&gt;サンプルのソースコード&lt;/h2&gt;
&lt;p&gt;特徴&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;docker-composeで動くようになっています。&lt;/li&gt;
&lt;li&gt;行った操作ごとにコミットを分けています。&lt;/li&gt;
&lt;li&gt;boostrapベースの良い感じのデザインテンプレである&lt;a href=&quot;https://bootswatch.com/&quot;&gt;bootswatch&lt;/a&gt;を導入してあります。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/rails7_importmap_bootswatch/commit/588e3841a13cb4ff773078946df1f0ba9c05ecd0&quot;&gt;rails new . -C -d sqlite3&lt;/a&gt; で初期化してあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://github.com/matsubo/rails7_importmap_bootswatch&lt;/p&gt;
&lt;h2&gt;作ったサービス&lt;/h2&gt;
&lt;p&gt;西暦と和暦を一覧で表示するサービスを作ってみました。&lt;/p&gt;
&lt;p&gt;アセットの内容などを確認できます。&lt;/p&gt;
&lt;p&gt;https://seireki.teraren.com/&lt;/p&gt;
</content:encoded></item><item><title>ExcelやGoogle Spreadsheetで郵便番号から住所を補完</title><link>https://blog.teraren.com/posts/postcode-auto-fill/</link><guid isPermaLink="true">https://blog.teraren.com/posts/postcode-auto-fill/</guid><description>郵便番号を入力するだけで住所を自動補完できるAPIを自作。Google SpreadsheetやExcelのIMPORTDATA関数から呼び出せ、都道府県・市区町村・町域などパート指定での部分取得にも対応。</description><pubDate>Sun, 09 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;Google SpreadsheetやExcelにて、郵便番号から住所を自動入力するAPIを作成しました。地域の郵便番号だけではなく、事業所に割り振られている郵便番号も対応しています。&lt;/p&gt;
&lt;p&gt;以下のスクリーンショットのように、一番のA列に郵便番号を入力すると任意のフォーマットで住所を入力できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;使い方&lt;/h2&gt;
&lt;p&gt;Google Spreadsheetで以下のような関数を入力するだけです。1600022は取得したい郵便番号を指定します。&lt;/p&gt;
&lt;p&gt;WindowsのExcel 2003以降のバージョンでは、WEBSERVICE関数でGoogle Spreadsheetと同じように使えます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;= IMPORTDATA(&quot;https://postcode.teraren.com/postcodes/1600022.txt&quot;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;郵便番号を別のセルから参照するためには以下のように郵便番号の部分に変数を使います。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;= IMPORTDATA(&quot;https://postcode.teraren.com/postcodes/&quot;&amp;amp;A2&amp;amp;&quot;.txt&quot;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;住所の全体ではなく、一部だけを取得したい場合は&lt;code&gt;part&lt;/code&gt;パラメータを付与します。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;= IMPORTDATA(&quot;https://postcode.teraren.com/postcodes/1600022.txt?part=1&quot;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;partパラメータの説明は以下です。&lt;/p&gt;
&lt;p&gt;1: 都道府県&lt;br /&gt;
2: 市町村区&lt;br /&gt;
3: 町域&lt;br /&gt;
4: 番地&lt;br /&gt;
5: 名称&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.google.com/spreadsheets/d/1KessddjJIEudW7v9VbP85dan4BwxvOzg03HaGUQ5guQ/edit?usp=sharing&quot;&gt;サンプルのファイル&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;API仕様&lt;/h2&gt;
&lt;p&gt;郵便番号をパラメータとしたURLを呼び出すと、住所の文字情報が返却されるAPIです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ curl https://postcode.teraren.com/postcodes/1600022.txt
東京都新宿区新宿
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のページにAPIの詳細を掲載してあります。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://postcode.teraren.com/doc/redoc#tag/Postcode/operation/getPostcodeText&quot;&gt;https://postcode.teraren.com/doc/redoc#tag/Postcode/operation/getPostcodeText&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>webpackerを削除してcssbundling-rails+jsbundling-rails+propshaftに移行</title><link>https://blog.teraren.com/posts/removing-webpacker/</link><guid isPermaLink="true">https://blog.teraren.com/posts/removing-webpacker/</guid><description>Rails 7でwebpackerを廃止し、cssbundling-rails・jsbundling-rails・propshaftへ移行する手順をGemfileやpackage.jsonの差分を交えて詳しく解説します。</description><pubDate>Sun, 09 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;importmap-railsに移行したかったのですが、手元のブラウザではちゃんと動かなかったので諦めてJavascriptはtranspileすることにしました。&lt;/p&gt;
&lt;p&gt;webpackerから移行した際の手順をまとめておきます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;https://postcode.teraren.com/&lt;/a&gt; こちらのサービスで実施した内容になります。&lt;/p&gt;
&lt;h2&gt;移行手順&lt;/h2&gt;
&lt;p&gt;できるだけわかりやすいように、差分を多く掲載します。&lt;/p&gt;
&lt;p&gt;Gemfileを書き換えます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/Gemfile b/Gemfile
index 312e40b..4c2a986 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,13 +1,31 @@
 source &apos;https://rubygems.org&apos;

 gem &quot;rails&quot;, &apos;~&amp;gt;7.0&apos;
-gem &apos;webpacker&apos;

 gem &apos;jbuilder&apos;

 gem &apos;puma&apos;

+# gem &quot;sprockets-rails&quot;
+
+#gem &quot;importmap-rails&quot;
+gem &apos;cssbundling-rails&apos;
+gem &apos;propshaft&apos;
+
+gem &quot;jsbundling-rails&quot;
+
+#gem &quot;turbo-rails&quot;
+
+#gem &quot;stimulus-rails&quot;
+
+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;package.jsonを一新します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ついでにjQueryに依存したコードも削除下のでjqueryも消しています。&lt;/li&gt;
&lt;li&gt;bootstrapのバージョンも最新にしています。&lt;/li&gt;
&lt;li&gt;webpack関連のnpmは削除しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/package.json b/package.json
index 5ec1857..18b62d6 100644
--- a/package.json
+++ b/package.json
@@ -1,18 +1,19 @@
 {
-  &quot;packageManager&quot;: &quot;yarn@1.22.15&quot;,
-  &quot;private&quot;: true,
+  &quot;name&quot;: &quot;app&quot;,
+  &quot;private&quot;: &quot;true&quot;,
   &quot;dependencies&quot;: {
-    &quot;@fortawesome/fontawesome-free&quot;: &quot;^5&quot;,
-    &quot;@popperjs/core&quot;: &quot;^2&quot;,
-    &quot;@rails/activestorage&quot;: &quot;^7.0&quot;,
-    &quot;@rails/ujs&quot;: &quot;^7.0&quot;,
-    &quot;@rails/webpacker&quot;: &quot;5.4&quot;,
-    &quot;bootstrap&quot;: &quot;^5.1&quot;,
-    &quot;bootswatch&quot;: &quot;^5.1&quot;,
-    &quot;jquery&quot;: &quot;^3.6&quot;,
-    &quot;webpack-cli&quot;: &quot;^4&quot;
+    &quot;@fortawesome/fontawesome-free&quot;: &quot;^6.2.0&quot;,
+    &quot;@popperjs/core&quot;: &quot;^2.11.6&quot;,
+    &quot;@rails/ujs&quot;: &quot;^7.0.4&quot;,
+    &quot;bootstrap&quot;: &quot;^5.2.2&quot;,
+    &quot;bootswatch&quot;: &quot;^5.2.1&quot;
+  },
+  &quot;scripts&quot;: {
+    &quot;build&quot;: &quot;esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets&quot;,
+    &quot;build:css&quot;: &quot;sass ./app/assets/stylesheets/application.sass.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules&quot;
   },
   &quot;devDependencies&quot;: {
-    &quot;webpack-dev-server&quot;: &quot;^4&quot;
+    &quot;esbuild&quot;: &quot;^0.15.10&quot;,
+    &quot;sass&quot;: &quot;^1.55.0&quot;
   }
 }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;設定ファイルを自動作成します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./bin/rails css:install:sass
./bin/rails javascript:install:esbuild
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;JS周りの設定ファイルを書き換えます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/app/assets/builds/.keep b/app/assets/builds/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/app/assets/config/manifest.js b/app/assets/config/manifest.js
index 20b4c66..cf7a2a5 100644
--- a/app/assets/config/manifest.js
+++ b/app/assets/config/manifest.js
@@ -1,3 +1,11 @@
-//= link graphiql/rails/application.css
-//= link graphiql/rails/application.js
+// app/assets/config/manifest.js
+
+//= link_tree ../images
+
+//= link application.js
+//= link controllers/application.js
+//= link controllers/home.js
+//= link controllers/index.js
+
+//= link application.css
+//= link_tree ../builds
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CSS周りの設定ファイルを書き換えます。gitにファイルの置き場所が変わっているので新規作成として認識されてます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/app/assets/stylesheets/application.sass.scss b/app/assets/stylesheets/application.sass.scss
new file mode 100644
index 0000000..7f0faab
--- /dev/null
+++ b/app/assets/stylesheets/application.sass.scss
@@ -0,0 +1,8 @@
+// bootswatch
+@import &quot;bootswatch/dist/simplex/variables&quot;;
+@import &quot;bootstrap/scss/bootstrap&quot;;
+@import &quot;bootswatch/dist/simplex/bootswatch&quot;;
+
+// fontawesome
+@import &apos;@fortawesome/fontawesome-free/scss/fontawesome&apos;;
+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;JS、CSS、画像の置き場所を全体的に変更します。&lt;/p&gt;
&lt;p&gt;JS: app/javascript/pack =&amp;gt; app/javascript&lt;/p&gt;
&lt;p&gt;CSS: app/javascript/stylesheets =&amp;gt; app/assets/stylesheets&lt;/p&gt;
&lt;p&gt;画像: app/javasript/images =&amp;gt; app/assets/images&lt;/p&gt;
&lt;p&gt;アセットの呼び出し方法を変更します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 9290dda..75a118d 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -20,7 +20,7 @@ description.strip!
   &amp;lt;meta property=&quot;og:type&quot; content=&quot;website&quot; /&amp;gt;
   &amp;lt;meta property=&quot;og:title&quot; content=&quot;&amp;lt;%= title %&amp;gt;&quot; /&amp;gt;
   &amp;lt;meta property=&quot;og:url&quot; content=&quot;&amp;lt;%= request.url %&amp;gt;&quot; /&amp;gt;
-  &amp;lt;meta property=&quot;og:image&quot; content=&quot;&amp;lt;%= asset_pack_path &apos;media/images/apple-touch-icon-144x144-precomposed.png&apos; %&amp;gt;&quot; /&amp;gt;
+  &amp;lt;meta property=&quot;og:image&quot; content=&quot;&amp;lt;%= asset_path &apos;apple-touch-icon-144x144-precomposed.png&apos; %&amp;gt;&quot; /&amp;gt;

   &amp;lt;meta name=&quot;theme-color&quot; content=&quot;#d97368&quot;&amp;gt;

@@ -43,32 +43,31 @@ description.strip!
   &amp;lt;%= csp_meta_tag %&amp;gt;

-  &amp;lt;%= stylesheet_pack_tag &quot;application&quot; %&amp;gt;
-  &amp;lt;%= javascript_pack_tag &quot;application&quot;, defer: true %&amp;gt;
-
-
   &amp;lt;!-- For third-generation iPad with high-resolution Retina display: --&amp;gt;
   &amp;lt;!-- Size should be 144 x 144 pixels --&amp;gt;
-  &amp;lt;%= favicon_link_tag (asset_pack_path(&apos;media/images/apple-touch-icon-144x144-precomposed.png&apos;)), :rel =&amp;gt; &apos;apple-touch-icon-precomposed&apos;, :type =&amp;gt; &apos;image/png&apos;, :sizes =&amp;gt; &apos;144x144&apos;, skip_pipeline: true  %&amp;gt;
+  &amp;lt;%= favicon_link_tag (asset_path(&apos;apple-touch-icon-144x144-precomposed.png&apos;)), :rel =&amp;gt; &apos;apple-touch-icon-precomposed&apos;, :type =&amp;gt; &apos;image/png&apos;, :sizes =&amp;gt; &apos;144x144&apos;, skip_pipeline: true  %&amp;gt;

   &amp;lt;!-- For iPhone with high-resolution Retina display: --&amp;gt;
   &amp;lt;!-- Size should be 114 x 114 pixels --&amp;gt;
-  &amp;lt;%= favicon_link_tag (asset_pack_path(&apos;media/images/apple-touch-icon-114x114-precomposed.png&apos;)), :rel =&amp;gt; &apos;apple-touch-icon-precomposed&apos;, :type =&amp;gt; &apos;image/png&apos;, :sizes =&amp;gt; &apos;114x114&apos; %&amp;gt;
+  &amp;lt;%= favicon_link_tag (asset_path(&apos;apple-touch-icon-114x114-precomposed.png&apos;)), :rel =&amp;gt; &apos;apple-touch-icon-precomposed&apos;, :type =&amp;gt; &apos;image/png&apos;, :sizes =&amp;gt; &apos;114x114&apos; %&amp;gt;

   &amp;lt;!-- For first- and second-generation iPad: --&amp;gt;
   &amp;lt;!-- Size should be 72 x 72 pixels --&amp;gt;
-  &amp;lt;%= favicon_link_tag (asset_pack_path(&apos;media/images/apple-touch-icon-72x72-precomposed.png&apos;)), :rel =&amp;gt; &apos;apple-touch-icon-precomposed&apos;, :type =&amp;gt; &apos;image/png&apos;, :sizes =&amp;gt; &apos;72x72&apos; %&amp;gt;
+  &amp;lt;%= favicon_link_tag (asset_path(&apos;apple-touch-icon-72x72-precomposed.png&apos;)), :rel =&amp;gt; &apos;apple-touch-icon-precomposed&apos;, :type =&amp;gt; &apos;image/png&apos;, :sizes =&amp;gt; &apos;72x72&apos; %&amp;gt;

   &amp;lt;!-- For non-Retina iPhone, iPod Touch, and Android 2.1+ devices: --&amp;gt;
   &amp;lt;!-- Size should be 57 x 57 pixels --&amp;gt;
-  &amp;lt;%= favicon_link_tag (asset_pack_path(&apos;media/images/apple-touch-icon-precomposed.png&apos;)), :rel =&amp;gt; &apos;apple-touch-icon-precomposed&apos;, :type =&amp;gt; &apos;image/png&apos; %&amp;gt;
+  &amp;lt;%= favicon_link_tag (asset_path(&apos;apple-touch-icon-precomposed.png&apos;)), :rel =&amp;gt; &apos;apple-touch-icon-precomposed&apos;, :type =&amp;gt; &apos;image/png&apos; %&amp;gt;

   &amp;lt;!-- For all other devices --&amp;gt;
   &amp;lt;!-- Size should be 32 x 32 pixels --&amp;gt;
-  &amp;lt;%= favicon_link_tag (asset_pack_path(&apos;media/images/favicon.ico&apos;)), :rel =&amp;gt; &apos;shortcut icon&apos; %&amp;gt;
+  &amp;lt;%= favicon_link_tag (asset_path(&apos;favicon.ico&apos;)), :rel =&amp;gt; &apos;shortcut icon&apos; %&amp;gt;

   &amp;lt;%= google_tag_manager_script_tag(:default) %&amp;gt;

+    &amp;lt;%= stylesheet_link_tag &quot;application&quot; %&amp;gt;
+    &amp;lt;%= javascript_include_tag &quot;application&quot;, &quot;data-turbo-track&quot;: &quot;reload&quot;, defer: true %&amp;gt;
+
   &amp;lt;/head&amp;gt;
   &amp;lt;body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;開発サーバのスタート方法を変更します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/start.sh b/start.sh
index 1df6187..e986393 100755
--- a/start.sh
+++ b/start.sh
@@ -7,5 +7,6 @@ bundle exec rails db:migrate

 rm -f /app/tmp/pids/server.pid
-bundle exec rails server -b &apos;0.0.0.0&apos;
+
+bin/dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;webpack関連のファイルを削除します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;config/webpacker.yml
config/webpack/*
bin/webpack
bin/webpack-dev-server
postcss.config.js
.browserslistrc
babel.config.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;docker-compose.ymlからwebpack-dev-serverを削除&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/docker-compose.yml b/docker-compose.yml
index e9a41fd..6027e93 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,7 +3,6 @@ services:
   app:
     build: .
     environment:
-      WEBPACKER_DEV_SERVER_HOST: webpack
       BUNDLE_JOBS: 4
     volumes:
       - .:/app
@@ -12,20 +11,6 @@ services:
     command: ./start.sh
     ports:
       - &quot;3000:3000&quot;
-    depends_on:
-      - webpack
-
-  webpack:
-    build: .
-    volumes:
-      - .:/app
-      - bundle_app2:/usr/local/bundle:cached
-    ports:
-      - &quot;3035:3035&quot;
-    command: bin/webpack-dev-server
-    environment:
-      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
-      WEBPACKER_DEV_SERVER_HOT: 1
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;差分&lt;/h2&gt;
&lt;p&gt;変更したファイルやファイルの量はこんな感じです。yarn.lockがかなり減りました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; git diff ee5315a51ea69c1573f5434fb0e1761bb675fcdf --stat
 .browserslistrc                                                            |    1 -
 .gitignore                                                                 |    3 +
 Dockerfile                                                                 |    1 +
 Gemfile                                                                    |   21 +-
 Gemfile.lock                                                               |   21 +-
 Procfile.dev                                                               |    3 +
 app/assets/builds/.keep                                                    |    0
 app/assets/config/manifest.js                                              |   12 +-
 app/{javascript =&amp;gt; assets}/images/apple-touch-icon-114x114-precomposed.png |  Bin
 app/{javascript =&amp;gt; assets}/images/apple-touch-icon-144x144-precomposed.png |  Bin
 app/{javascript =&amp;gt; assets}/images/apple-touch-icon-72x72-precomposed.png   |  Bin
 app/{javascript =&amp;gt; assets}/images/apple-touch-icon-precomposed.png         |  Bin
 app/{javascript =&amp;gt; assets}/images/discord.png                              |  Bin
 app/{javascript =&amp;gt; assets}/images/favicon.ico                              |  Bin
 app/{javascript =&amp;gt; assets}/images/graphql_query.png                        |  Bin
 app/{javascript =&amp;gt; assets}/images/ss.png                                   |  Bin
 app/assets/stylesheets/application.sass.scss                               |    8 +
 app/controllers/postcodes_controller.rb                                    |   14 +-
 app/javascript/{packs =&amp;gt; }/application.js                                  |   20 +-
 app/javascript/controllers/application.js                                  |   10 +
 app/javascript/controllers/home.js                                         |   25 +
 app/javascript/controllers/index.js                                        |   12 +
 app/javascript/packs/home.js                                               |   36 -
 app/javascript/stylesheet/bootstrap_variables.scss                         |    3 -
 app/javascript/stylesheet/style.scss                                       |    4 +-
 app/views/layouts/application.html.erb                                     |   19 +-
 babel.config.js                                                            |   65 -
 bin/dev                                                                    |    9 +
 bin/webpack                                                                |   18 -
 bin/webpack-dev-server                                                     |   18 -
 config/environments/production.rb                                          |   17 +
 config/initializers/assets.rb                                              |   13 +
 config/routes.rb                                                           |    4 +-
 config/webpack/development.js                                              |    9 -
 config/webpack/environment.js                                              |   12 -
 config/webpack/production.js                                               |    5 -
 config/webpack/test.js                                                     |    5 -
 config/webpacker.yml                                                       |   92 --
 docker-compose.production.yml                                              |    4 +-
 docker-compose.yml                                                         |   15 -
 package.json                                                               |   25 +-
 postcss.config.js                                                          |   12 -
 start.sh                                                                   |    3 +-
 yarn.lock                                                                  | 7422 +++------------------------------------------------------------------------------------------
 51 files changed, 492 insertions(+), 7540 deletions(-)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;開発時のコンパイルが高速になったのでとても快適です。&lt;/li&gt;
&lt;li&gt;資料が少ないし、いまいち構造がよくわからないので半日ぐらいかかりました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>RailsのアクターがN:Mのシステムを作るときの権限モデル</title><link>https://blog.teraren.com/posts/rails-permission-metrics/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-permission-metrics/</guid><description>RailsのアクターがN:Mのシステムを作るときの権限モデル</description><pubDate>Sat, 08 Oct 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;手元で作っているRailsのサービスの要求が肥大化してきたので、権限モデルをちょっと整理してみました。&lt;/p&gt;
&lt;p&gt;権限が複雑になる原因は、メトリックが多くなること。要件レベルでどれだけメトリックを減らせるかが重要。&lt;/p&gt;
&lt;p&gt;ビジネスで利用するサービスの場合、細かい権限設定が要求されるのでメトリックが増えやすい。&lt;/p&gt;
&lt;p&gt;今回扱わなければいけないメトリックは以下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アクター&lt;/li&gt;
&lt;li&gt;ロール&lt;/li&gt;
&lt;li&gt;マスタデータのステータス遷移&lt;/li&gt;
&lt;li&gt;Web経由の操作 or API経由の操作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;メトリックが3つ以上になった時点で直交表が作成できなくなってしまう。&lt;/p&gt;
&lt;p&gt;メトリックが3つであれば、直交表を複数作ればギリギリ対応できるが、4つになると表現が厳しい。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;クリーンアーキテクチャのレイヤと比較して、このような感じで考える。これ以上メトリックが増える場合は、独自にビジネスロジックのレイヤーを追加するなりして対応する必要がある。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/10/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;メトリックが4つになった時点で、権限をわかりやすくまとめろと言われても不可能に近い。&lt;/p&gt;
</content:encoded></item><item><title>Appleで買ったSIMフリー端末が「SIMロックあり」になったので解除した話</title><link>https://blog.teraren.com/posts/apple-sim-free-locked/</link><guid isPermaLink="true">https://blog.teraren.com/posts/apple-sim-free-locked/</guid><description>Apple公式で購入したSIMフリーiPhone XSに「SIMロックあり」表示が出た原因を調査し、Appleサポートと連携して解除した手順を解説</description><pubDate>Wed, 20 Jul 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;日本のApple公式サイトからiPhone XS 256GBを買いました。Apple公式サイトから購入すればSIMフリーのはずなのですが、「SIMロックあり」という表示が出るようになってしまいました。&lt;/li&gt;
&lt;li&gt;楽天モバイルのSIMを挿していて使える状態でした。&lt;a href=&quot;https://k-tai.watch.impress.co.jp/docs/column/minna/1284123.html&quot;&gt;Webの書き込み&lt;/a&gt;を見てみると、表示はSIMロックと書くかれていますが、実際にはされていないという書き込みを見たので、AhamoのSIMを挿してみたところ、「SIMロックあり」の表示はそのままですが、AhamoのSIMが使えたので実質はSIMフリーのようです。&lt;/li&gt;
&lt;li&gt;どっちにしろ、この端末を売却したいので「SIMロックあり」という表示は消したいので、その方法を書いておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/07/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;時系列の整理&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2018年9月: iPhone XS 256GBをAppleストアで購入&lt;/li&gt;
&lt;li&gt;2019年8月: Face IDが使えなくなったので、保証期限内のため、Appleのサポートへ送付したら交換ということになって新品のiPhone XS 256GBが送られてきた。&lt;/li&gt;
&lt;li&gt;2019年9月: DoCoMoの物理SIMを入れて利用開始&lt;/li&gt;
&lt;li&gt;2021年x月: 楽天モバイルにMNPして楽天モバイルの物理SIMを入れて利用開始&lt;/li&gt;
&lt;li&gt;2022年6月: 「SIMロックあり」という表示が出ていることに気づいた。しかし、実際にSIMロックされているかを検証したところSIMロックはされていない状態であり、表示だけがSIMロックありとなっている。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kobonemi.com/entry/SIM%E3%83%95%E3%83%AA%E3%83%BCiPhone%E3%81%8CSIM%E3%83%AD%E3%83%83%E3%82%AF&quot;&gt;こちらの記事&lt;/a&gt;によると、Appleにしか解除できないという記述があります。
&lt;ul&gt;
&lt;li&gt;上記記事の端末は、表示もSIMロックとあり、本当にSIMロックが掛かっていますが、私の端末はSIMロックという表示だけですが実際にはSIMロックはかかっていません。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://k-tai.watch.impress.co.jp/docs/column/minna/1284123.html&quot;&gt;こちらの記事&lt;/a&gt;では、SIMロックありという表示は嘘で、実際はSIMフリー。iOSの不具合で新しいiOSのリリースを待つ必要があるという結論です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;私はこのiPhone XS 256GBを売りたいので、SIMロックという表示があると値段が低くなってしまうので、なんとしても「SIMロックあり」の表示を外したいのです。&lt;/p&gt;
&lt;h2&gt;やったこと&lt;/h2&gt;
&lt;h3&gt;Appleへの問い合わせ&lt;/h3&gt;
&lt;p&gt;Appleのサポートと電話で話した結果はこちら↓&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;「SIMロック」はキャリアがかけるものだからAppleではどうしようもできない。&lt;/p&gt;
&lt;p&gt;関連する記事はこちらだから、こちらを見て1つ前のキャリアである楽天モバイルにSIMロックを解除を依頼して！&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://support.apple.com/ja-jp/HT201328&quot;&gt;https://support.apple.com/ja-jp/HT201328&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;という感じでした。&lt;/p&gt;
&lt;p&gt;1つ目の記事にある内容とは異なる回答が返ってきました。&lt;/p&gt;
&lt;p&gt;反論しようにも、反論する材料が上記のWebサイトしか無いので、とりあえずAppleのサポートの言う通りにしてみます。&lt;/p&gt;
&lt;h3&gt;楽天モバイルへの問い合わせ&lt;/h3&gt;
&lt;p&gt;1時間20分にも及ぶ、長いチャットの結果、DoCoMoへリダイレクトされました。。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/07/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ここに至るまでに、たくさんの見当違いの質問をされて、反論したい気持ちを抑えながら回答を淡々と繰り返していたのに、この結果です。&lt;/p&gt;
&lt;p&gt;SIMロック解除に必要であろう、IMEIも聞かれることはなかったです。たぶん、楽天モバイルの担当者は全く仕組みを理解していないことが想定されます。そもそも楽天モバイルはSIMロックが総務省に寄って禁止される頃に登場した事業者なのでSIMロックを行うユースケース自体が存在していない可能性があります。&lt;/p&gt;
&lt;p&gt;もし、この後にドコモへ問い合わせて解決できなかったらたらい回し状態になってしまい、何が真実なのかわからないし、問い合わせ先もよくわからなくなってしまいます。&lt;/p&gt;
&lt;p&gt;楽天モバイルのサポートとチャットをしながら、同時に裏でググっていたらドコモはWebからSIMロックの解除申請を行えるという記載を見つけました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/07/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.docomo.ne.jp/support/unlock_simcard/&quot;&gt;https://www.docomo.ne.jp/support/unlock_simcard/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;DoCoMoでSIMロック解除申請&lt;/h3&gt;
&lt;p&gt;dアカウントが必要になるので、自分のdアカウントでログインして申請してみました。&lt;/p&gt;
&lt;p&gt;IMEIを入力するだけで申請できました。しかも、確認画面で端末の情報が表示されてます。DoCoMoに提供した覚えはない情報なのでどううやってドコモが知り得たのか謎です。IMEIからハードウェアを特定する手法があるのかなと思います。（関連付けされた機種のストレージ容量は間違ってますが。。。）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/07/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;すんなりと申請は完了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/07/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;この状態では、まだ申請だけしか行っていないです。&lt;/p&gt;
&lt;p&gt;iPhoneの場合は「メッセージR」というものが送られてくるのでそれが来たら完了するらしいです。（メッセージRはtypoで、SMSのことだと思います）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;SIMロック解除を実施するためには、他社のSIMカードなどの挿入や設定をした上で、お手続き完了画面に表示されるSIMロック解除コードを入力してください。また、一部端末においては、SIMロック解除コードの入力は不要です。&lt;/p&gt;
&lt;p&gt;【iPhone/iPadのみ】メッセージＲの配信設定の有無に限らず、解除準備完了後に準備完了をお知らせする旨のメッセージRを送信いたします。メッセージＲ受信後にお客さまご自身で解除処理(端末へ他社SIMを挿入)をお願いいたします。メッセージRが届かない場合、お客さまから再度お申し出の必要があります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ちなみに、Ahamoでも同じようにSIMロック解除の説明ページがありますがリンク先はDoCoMoのSIMロック解除ページに飛びます。&lt;/p&gt;
&lt;h4&gt;IMEIに関して&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://www.imei.info/&quot;&gt;imei.info&lt;/a&gt;というサイトでIMEIを入力したらハードウェアの情報が表示されたので、IMEIとハードウェア情報の関連付けは公開情報のようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/07/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;DoCoMoでSIMロックを解除申請その後&lt;/h3&gt;
&lt;p&gt;結局、DoCoMoのサイト上でSIMロック解除申請をしても、結果を受け取れる手段が無いから結果がわかりません。&lt;/p&gt;
&lt;p&gt;1週間後に、試しに端末を初期化してみましたが相変わらず「SIMロックあり」の表示で解決していません。&lt;/p&gt;
&lt;p&gt;なので、DoCoMoへ問い合わせてみたら、「機器を販売したAppleに問い合わせてね」という回答。振り出しに戻った。&lt;/p&gt;
&lt;p&gt;どの会社も明確なSIMロックの構造を理解していない。こちらの時間をかなり消費する。ほんとムカつく。しかし、まだ問題が誰にあるのかがわからないので根本的に誰が間違ったことを言っているのかがわからない。&lt;/p&gt;
&lt;h3&gt;Appleサポートへ2回目の問い合わせをしてみました。&lt;/h3&gt;
&lt;p&gt;1回目は、軽く鼻で笑われたような対応をされました（しかも結果として不適切な回答だったのでダブルでムカつく）が、今回対応してくれた人はちゃんと対応してくれている印象です。&lt;/p&gt;
&lt;p&gt;ここで、普通のサポート窓口ではなく別の&lt;strong&gt;上位部署&lt;/strong&gt;にエスカレされました。&lt;/p&gt;
&lt;p&gt;その結果、以下のページに有るようにMacosにiPhoneをつないでリカバリーモードで初期化を試してほしいとのことでした。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://ahamo.com/support/procedure/other/unlock-sim/index.html&quot;&gt;https://ahamo.com/support/procedure/other/unlock-sim/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;その場で言われた手順を実行してトラブルシュートをしたかったのですが、サポートとの電話を開始してからすでに40分程度経っていて、別件のミーティングが始まるので私の持ち帰りの宿題として、電話を切りました。&lt;/p&gt;
&lt;p&gt;そして、上記のリカバリーモードを試してみましたが状況は変わらず、「SIMロックあり」でした。&lt;/p&gt;
&lt;h3&gt;Appleサポートへの問い合わせ3回目&lt;/h3&gt;
&lt;p&gt;2回めに対応してくれた人とは別の人です。引き継ぎもされているはずなのですが、あんまり引き継がれていない模様です。&lt;/p&gt;
&lt;p&gt;今まで試したことを確認されたり、販売経路を確認されたりと今までも何度も言ってきたことをすべて再確認されました。。。。&lt;/p&gt;
&lt;p&gt;「なぜ楽天モバイルに問い合わせたのか？楽天モバイルで買った端末じゃないから、問い合わせても意味が無いのに。」と言われ、「Appleに言われたから。。。（怒）」という感じの問答を何回か繰り返しました。&lt;/p&gt;
&lt;p&gt;そして、Apple社内でもこの問題に対して、ステップバイステップで対応マニュアルがあるらしくて、最終ステップがこのリカバリーモードでのリカバリーを行うことだったとのことでした。&lt;/p&gt;
&lt;p&gt;これを行っても状況が変わらないとなると、Apple側で再度社内調整をした上で再度、状況ややったことの手順をヒアリングする電話を後日行うとのことで電話を切られました。&lt;/p&gt;
&lt;p&gt;やっと前に進んだ感じはあります。&lt;/p&gt;
&lt;p&gt;30分ほど使いました。&lt;/p&gt;
&lt;h3&gt;Appleサポートとの会話 4回目&lt;/h3&gt;
&lt;p&gt;1日後に電話が来ました。&lt;/p&gt;
&lt;p&gt;なんか、サポートの人の説明が分かりづらかったです。Apple社内で「SIMロックを解除するための申請」をしたとのことで、その結果が出るのに1〜2日かかるとのことでした。&lt;/p&gt;
&lt;p&gt;終わったら連絡が来るとのことでした。&lt;/p&gt;
&lt;p&gt;10分使いました。&lt;/p&gt;
&lt;h3&gt;Appleサポートとの会話 5回目&lt;/h3&gt;
&lt;p&gt;2日後に電話が来ました。&lt;/p&gt;
&lt;p&gt;担当者が休みを取っていたようで、2日後の連絡となってしまったようです。&lt;/p&gt;
&lt;p&gt;そして、「Appleの別部署にて、&quot;申請&quot;の確認が取れたので、申請をしたその日のうちにSIMロック解除の設定をした」との連絡が来ました。&lt;/p&gt;
&lt;p&gt;確かに、「SIMロックあり」という表示がなくなりました。これにて一件落着です。&lt;/p&gt;
&lt;p&gt;後学のためにいくつかAppleのサポートの人に質問をしてみました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Q: WiFiに接続しているだけ（＝キャリアのSIMを使わない状態）で、「SIMロックあり」の表示が「SIMロックなし」になった。SIMロックの情報を端末に反映するにはキャリアのネットワークは不要という理解で正しいか？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A: 正しい。WiFiでもSIMロックに関する情報は伝搬される。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Q: そもそも、なんでAppleがSIMロックの解除とかそういうのを管理しているの？&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A: 普通はAppleで管理しない。SIMロックはAppleとは別の所で管理されている。今回のような何が原因かよくわからない状態でSIMロックになってしまった場合は、Apple社内でいろいろな承認を得るとSIMロック解除を行えるようになっている。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Web上には様々な状況や解決策がありましたが、結局は&lt;a href=&quot;https://www.kobonemi.com/entry/SIM%E3%83%95%E3%83%AA%E3%83%BCiPhone%E3%81%8CSIM%E3%83%AD%E3%83%83%E3%82%AF&quot;&gt;こちらの方&lt;/a&gt;と同じ解決策でした。&lt;/li&gt;
&lt;li&gt;最終的には無事に「SIMロックあり」の表示が消えたので良かったです。調査などを含めると8時間近く消費しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B0B1V5P27W&quot;}&lt;/p&gt;
</content:encoded></item><item><title>MegaRAIDの節電機能</title><link>https://blog.teraren.com/posts/megaraid-eco/</link><guid isPermaLink="true">https://blog.teraren.com/posts/megaraid-eco/</guid><description>自宅サーバのHDD4台をstorcli経由でスピンダウンして節電を試みたが、MegaRAIDカードがPower savings非対応だった実験記録</description><pubDate>Thu, 30 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;サーバの平均消費電力が80Wぐらいです。金額にすると約2000円/月。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;主に電力を食うのはCPUかディスク。CPUはさほど使われていないのでおそらくハードディスクが電力を食っているような気がします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/07/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HDDを4台搭載したファイルサーバなのでほとんどディスクは稼働していないので、ディスクをスピンダウンして節電しようと考えました。&lt;/li&gt;
&lt;li&gt;strocli経由で節電モードを操作で来そうなのでやってみます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;現状の設定を確認&lt;/h2&gt;
&lt;p&gt;なんと、ハードウェアが未対応。。。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo /opt/MegaRAID/storcli/storcli64 /c0 show ds
Controller = 0
Status = Failure
Description = None

Detailed Status :
===============

--------------------------------------------------
Ctrl_Prop Value
--------------------------------------------------
DS        Adapter does not support Power savings.
--------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ちなみに、dsとはDimmer Switchの略で、節電モードのことです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/06/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;有効化してみる&lt;/h2&gt;
&lt;p&gt;まぁ、エラーになるのですが一応試してみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo /opt/MegaRAID/storcli/storcli64 /c0 set ds=off type=4
Controller = 0
Status = Failure
Description = does not support PowerState
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ホットスタンバイのHDDが2台無駄に動いているのが悲しいですな。&lt;/p&gt;
</content:encoded></item><item><title>過去に立ち上げたサービスのまとめ</title><link>https://blog.teraren.com/posts/built-services/</link><guid isPermaLink="true">https://blog.teraren.com/posts/built-services/</guid><description>駅・路線API、銀行コードAPI、郵便番号APIなど、個人で開発・公開してきたREST APIサービスの一覧と現在の稼働状況をまとめた記事</description><pubDate>Tue, 07 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;過去に立ち上げたサービスを紹介します。&lt;/p&gt;
&lt;h2&gt;稼働中&lt;/h2&gt;
&lt;h3&gt;駅・路線 REST API&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/ekidata-api/&lt;/p&gt;
&lt;h3&gt;銀行コード、支店コードAPI&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/japanese-bank-code-branch-code-api/&lt;/p&gt;
&lt;h3&gt;郵便番号API&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/postcode-api/&lt;/p&gt;
&lt;p&gt;利用者はいないと思いますが、GraphQLにも対応しています。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/api-graphql-postcode/&lt;/p&gt;
&lt;h3&gt;covid-19新規陽性者の都道府県ごとグラフ&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/covid19-japan-graph-feed/&lt;/p&gt;
&lt;h3&gt;AKB勝手にランキング&lt;/h3&gt;
&lt;p&gt;https://matsu.teraren.com/ranking/&lt;/p&gt;
&lt;h3&gt;確認くん&lt;/h3&gt;
&lt;p&gt;IPv4、IPv6対応の自分のグローバルIPを表示するサービス。curlでアクセスするとIPアドレスだけ返ってきます。&lt;/p&gt;
&lt;p&gt;https://kakunin.teraren.com/&lt;/p&gt;
&lt;h2&gt;サービス停止・更新停止&lt;/h2&gt;
&lt;h3&gt;Facebook pageのlike数をトラッキング&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/facebook-page-like-tracking/&lt;/p&gt;
&lt;h3&gt;CSSで絵文字を表現&lt;/h3&gt;
&lt;p&gt;https://github.com/matsubo/emoji-sprite&lt;/p&gt;
&lt;h3&gt;mixi2rss&lt;/h3&gt;
&lt;p&gt;https://diary.teraren.com/posts/2009-07-22-mixi-diary-feed/&lt;/p&gt;
</content:encoded></item><item><title>読み物系記事のおすすめ15本ピックアップ</title><link>https://blog.teraren.com/posts/popular-story-article/</link><guid isPermaLink="true">https://blog.teraren.com/posts/popular-story-article/</guid><description>開設から19年で埋もれた人気記事をセレクト。技術・ビジネス・ガジェット・ライフスタイルにまたがるおすすめ15本を紹介</description><pubDate>Tue, 07 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;このブログは開設から約19年経過しました。良い記事が埋もれてしまっていてもったいないので、個人的に過去に人気があったおすすめ記事を5ページ紹介します。&lt;/p&gt;
&lt;h2&gt;1位 日本のインターネットの父。慶応大学最終講義。&lt;/h2&gt;
&lt;p&gt;事あることに、読み返しています。インターネットに関わる仕事をしている方はインターネットの成り立ちと理想を鑑みられる質疑応答です。はてなブックマークで1175件ブックマークされてます。ホットエントリーにも掲載されました。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/mj-last-class-text/&lt;/p&gt;
&lt;h2&gt;2位 tmux-powerlineでおされにする&lt;/h2&gt;
&lt;p&gt;tmux powerlineは今でもこの設定に近いです。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/moteru-tmux-powerline/&lt;/p&gt;
&lt;h2&gt;3位 価値観的なもの&lt;/h2&gt;
&lt;p&gt;スタートアップをやろうとしている方へ向けての1つの考え方をまとめました。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/before-the-startup/&lt;/p&gt;
&lt;p&gt;こちらも合わせてどうぞ。上記をリバイズしたバージョンです。&lt;/p&gt;
&lt;p&gt;https://note.com/yuki_matsukura/n/n08e53fdfd84d&lt;/p&gt;
&lt;h2&gt;4位 3rd party cookie周辺の内容&lt;/h2&gt;
&lt;p&gt;調査してみた内容のまとめです。世界のプライバシー保護への温度感がつかめます。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/ad-accuracy-and-3rd-party-cookie/&lt;/p&gt;
&lt;h2&gt;5位 写真や動画を安全に長期間保存する&lt;/h2&gt;
&lt;p&gt;「機密性」「完全性」「可用性」を程よく満たして写真や動画などの大容量データを安全に保管する方法。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/photo-backup/&lt;/p&gt;
&lt;h2&gt;6位 Singletonは嫌いです&lt;/h2&gt;
&lt;p&gt;最近はOOP (オブジェクト指向プログラミング) の知識レベルの底上げがあり、見ることは少なくなりましたが、10年前はSingletonが多く見られました。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/evil-singleton/&lt;/p&gt;
&lt;h2&gt;7位 中小企業共通EDI&lt;/h2&gt;
&lt;p&gt;商取引に関わるシステムのときのモデルや、ビジネスの一般慣習を学べます。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/edi/&lt;/p&gt;
&lt;h2&gt;8位 クレカの頭6桁の仕様&lt;/h2&gt;
&lt;p&gt;クレジットカードのBINコード&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/credit-card-bin-code/&lt;/p&gt;
&lt;h2&gt;9位 転職プラットフォームの価値を考察&lt;/h2&gt;
&lt;p&gt;https://blog.teraren.com/posts/job-change-platform/&lt;/p&gt;
&lt;h2&gt;10位 ミル挽きコーヒーメーカー&lt;/h2&gt;
&lt;p&gt;https://blog.teraren.com/posts/office-coffee/&lt;/p&gt;
&lt;h2&gt;11位 私が考える要求定義の流れとアウトプット&lt;/h2&gt;
&lt;p&gt;https://blog.teraren.com/posts/request-definition/&lt;/p&gt;
&lt;h2&gt;12位 英語勉強の浅いノウハウ&lt;/h2&gt;
&lt;p&gt;https://blog.teraren.com/posts/english-learning/&lt;/p&gt;
&lt;h2&gt;13位 コストコで買うものルーチーン&lt;/h2&gt;
&lt;p&gt;https://blog.teraren.com/posts/costco/&lt;/p&gt;
&lt;h2&gt;14位 一応、私はエストニアの電子国民です。&lt;/h2&gt;
&lt;p&gt;https://blog.teraren.com/posts/e-residency/&lt;/p&gt;
&lt;h2&gt;15位 LINE詐欺をやってる人のIPアドレスを暴いてみた&lt;/h2&gt;
&lt;p&gt;ネタ的なかんじ&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/line-fraud/&lt;/p&gt;
</content:encoded></item><item><title>おすすめの技術記事15本ピックアップ</title><link>https://blog.teraren.com/posts/popular-tech-article/</link><guid isPermaLink="true">https://blog.teraren.com/posts/popular-tech-article/</guid><description>ネットワーク設計・データベース・タイムゾーン処理・CI/CDなど、エンジニアが知っておくべき実践的な技術記事を15本厳選して紹介</description><pubDate>Tue, 07 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;エンジニアとして知っておくべき知識や便利な設定を紹介します。&lt;/p&gt;
&lt;h3&gt;小規模オフィスのネットワーク構築&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/building-small-office-network/&lt;/p&gt;
&lt;h3&gt;航空会社のマイルを管理するシステム&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/point-system-design-rdb/&lt;/p&gt;
&lt;h3&gt;MySQLにおけるデータの境界値&lt;/h3&gt;
&lt;p&gt;意図した値が出てこない可能性があるので知って置かなければまずいこと。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/sql-between-boundary/&lt;/p&gt;
&lt;h3&gt;Githubの通知を便利にする&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/github-mention-slack/&lt;/p&gt;
&lt;h3&gt;周りに迷惑をかけないようにするファイル転送方法&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/rsync-bwlimit/&lt;/p&gt;
&lt;h3&gt;RailsのTimezoneの扱い&lt;/h3&gt;
&lt;p&gt;Railsに限らず、i18nをするときには知らないといけないこと。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/rails-timezone/&lt;/p&gt;
&lt;h3&gt;Railsのエラーページをかっこよくする&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/make-rails-404-page-fancy/&lt;/p&gt;
&lt;h3&gt;並列処理で速度が出ない場合&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/xargs-concurrent-execution/&lt;/p&gt;
&lt;p&gt;上記の応用。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/2010/12/09/%e5%86%8d%e5%b8%b0%e7%bd%ae%e6%8f%9b%e3%81%99%e3%82%8b%e3%82%b7%e3%82%a7%e3%83%ab%e3%82%b9%e3%82%af%e3%83%aa%e3%83%97%e3%83%88-%e3%83%95%e3%82%a1%e3%82%a4%e3%83%ab%e5%90%8d-%e3%81%a8-%e4%b8%ad/
https://blog.teraren.com/posts/mogrify-imagemagick-recursive/&lt;/p&gt;
&lt;h3&gt;エンジニアならすぐに知る必要があること&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/external-ip-address/&lt;/p&gt;
&lt;h3&gt;業務用ルータを家庭で使う&lt;/h3&gt;
&lt;p&gt;とても安定しますし、速度も出ます。しかも中古なら安い。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/rtx1200-deployment/&lt;/p&gt;
&lt;h3&gt;CLIで集合演算&lt;/h3&gt;
&lt;p&gt;年に数回使います。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/element-calculation/&lt;/p&gt;
&lt;h3&gt;Intelとarm(M1,M2)向け設定共通化&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/arm-intel-docker-compose-in-the-same-file/
https://blog.teraren.com/posts/chromedriver-on-arm/&lt;/p&gt;
&lt;h3&gt;コーポレートSEネタ&lt;/h3&gt;
&lt;p&gt;GoogleのCloud Identityで会社のPCやスマホを管理する方法とか設定例。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/google-cloud-identity/&lt;/p&gt;
&lt;h3&gt;自分の居場所を自動でアイコン表示&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/show-current-location-icon/&lt;/p&gt;
&lt;h3&gt;PCが調子悪いと言われたときのトラブルシューティング&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/cpu-high-load-caused-by-heat-issue/&lt;/p&gt;
&lt;h3&gt;ActiveRecordのTransaction例外処理&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/activerecord-transaction-nest/&lt;/p&gt;
&lt;h3&gt;zoomの脆弱性を見つけた時の話&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/zoom-vulnerability/&lt;/p&gt;
&lt;h3&gt;回線が遅いなと思ったら調査すること&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/speedtest-benchmark-mackerel/&lt;/p&gt;
&lt;h3&gt;AWSでサイトメンテナンス表示&lt;/h3&gt;
&lt;p&gt;https://blog.teraren.com/posts/nginx-site-maintenance-setting/&lt;/p&gt;
</content:encoded></item><item><title>現在位置情報から最寄り駅の一覧を取得する</title><link>https://blog.teraren.com/posts/qiita-20220607-cc3f69aa42a61ab654f2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20220607-cc3f69aa42a61ab654f2/</guid><description>駅情報・路線情報 REST APIを利用します。</description><pubDate>Tue, 07 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;経度緯度から、最寄り駅の一覧を取得します。&lt;/li&gt;
&lt;li&gt;ブラウザから経度緯度情報は Javscript で取得できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;利用するAPI&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://train.teraren.com/&quot;&gt;駅情報・路線情報 REST API&lt;/a&gt;を利用します。&lt;/p&gt;
&lt;p&gt;REST API のサンプル。東京タワーからの最寄り駅一覧を出力してみます。distance の単位は km です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl &apos;https://train.teraren.com/stations/near_by_stations.json?lon=139.7454316&amp;amp;lat=35.658584&apos; | jq &apos;limit(5; .[])&apos;
{
  &quot;station_cd&quot;: 9930122,
  &quot;station_name&quot;: &quot;赤羽橋&quot;,
  &quot;station_g_cd&quot;: 9930122,
  &quot;distance&quot;: 0.4293522820451477
}
{
  &quot;station_cd&quot;: 2800317,
  &quot;station_name&quot;: &quot;神谷町&quot;,
  &quot;station_g_cd&quot;: 2800317,
  &quot;distance&quot;: 0.48968747581839894
}
{
  &quot;station_cd&quot;: 9930306,
  &quot;station_name&quot;: &quot;御成門&quot;,
  &quot;station_g_cd&quot;: 9930306,
  &quot;distance&quot;: 0.6242133516473801
}
{
  &quot;station_cd&quot;: 9930305,
  &quot;station_name&quot;: &quot;芝公園&quot;,
  &quot;station_g_cd&quot;: 9930305,
  &quot;distance&quot;: 0.639515764707121
}
{
  &quot;station_cd&quot;: 9930209,
  &quot;station_name&quot;: &quot;大門&quot;,
  &quot;station_g_cd&quot;: 9930121,
  &quot;distance&quot;: 0.8574239732003268
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Webから利用する場合のサンプルコード&lt;/h2&gt;
&lt;h3&gt;スクリーンショット&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/06/73007b56-6ade-63ec-41c3-e2e99c82dda8.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stimulus.hotwired.dev/&quot;&gt;Stimulus&lt;/a&gt;によるサンプルコード。ブラウザから位置情報を取得して、駅の一覧を表示するだけのスクリプトです。
サーバのCORSの設定はGETをどこのサイトからでもできるようにしてあるのでご自由に利用ください。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Controller } from &apos;stimulus&apos;;

export default class extends Controller {
  static targets = [&apos;lon&apos;, &apos;lat&apos;, &apos;output&apos;];

  getLocation() {
    if (!(&apos;geolocation&apos; in navigator)) {
      alert(&apos;Allow browser to acquire location.&apos;);
    }

    navigator.geolocation.getCurrentPosition((position) =&amp;gt; {
      this.latTarget.value = position.coords.latitude;
      this.lonTarget.value = position.coords.longitude;
    }, (error) =&amp;gt; {
      alert(error.message);
    });
  }

  search() {
    const url = `https://train.teraren.com/stations/near_by_stations.json?lon=${this.lonTarget.value}&amp;amp;lat=${this.latTarget.value}&amp;amp;limit=5`;
    fetch(url)
      .then((response) =&amp;gt; response.json())
      .then((json) =&amp;gt; JSON.stringify(json, null, 2))
      .then((json_string) =&amp;gt; { this.outputTarget.textContent = json_string });
  }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>広告配信精度とプライバシー保護に関する法律と技術のまとめ</title><link>https://blog.teraren.com/posts/ad-accuracy-and-3rd-party-cookie/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ad-accuracy-and-3rd-party-cookie/</guid><description>GDPR・改正個人情報保護法などプライバシー規制の動向と、3rd party cookieに代わるFLoCなど広告ターゲティング技術の変遷を解説します。</description><pubDate>Fri, 03 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2022年5月に社内でLTした内容をまとめておきます。きっかけは&lt;a href=&quot;https://developers-jp.googleblog.com/2021/04/floc.html&quot;&gt;GoogleのFLoC&lt;/a&gt;を調べていたら、FLoCを取り巻く歴史などの情報がまとまっていなかったのでまとめていました。&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;プライバシーを守るための法律が制定されつつあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EU
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gdpr-info.eu/&quot;&gt;GDPR&lt;/a&gt; (General Data Protection Regulation)&lt;/li&gt;
&lt;li&gt;2018年5月25日から適用開始&lt;/li&gt;
&lt;li&gt;Webサイトを見ていると「Cookie取得の同意」のポップアップ表示を見かけると思います。それはGDPRに準拠するためという目的がほとんどです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;US
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.consumerprivacyact.com/federal/&quot;&gt;COPRA&lt;/a&gt; (Consumer Online Privacy Rights Act)&lt;/li&gt;
&lt;li&gt;大統領の署名待ち。署名後180日で施行&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;日本
&lt;ul&gt;
&lt;li&gt;改正個人情報保護法&lt;/li&gt;
&lt;li&gt;3年毎に更新。2022年4月に更新&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;インターネット上の広告業界にとって、ユーザの個人情報の取得が困難になるので、ディスプレイ広告のターゲティング精度が落ちます。&lt;/p&gt;
&lt;p&gt;ユーザにとってはプライバシーが重視される一方、ターゲティングの精度が落ちることになるので関連度の低い広告が表示されるようになります。&lt;/p&gt;
&lt;p&gt;根底としては以下の相反する要求があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;広告ターゲティング精度 VS プライバシー&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;背景技術の説明&lt;/h2&gt;
&lt;p&gt;この広告業者がユーザの情報を集めるために使っている技術が3rd party cookieという仕組みです。&lt;/p&gt;
&lt;p&gt;1st partyは自分、2nd partyは閲覧しているウェブサイト、3rd partyとは広告配信業者に当たります。&lt;/p&gt;
&lt;p&gt;昨今のChromeやEdgeでデフォルトである3rd party cookieが有効になっていると、ユーザはウェブサイトを閲覧しているだけで、ユーザが意図しないところで広告配信業者に情報を共有されてしまっている状態になります。&lt;/p&gt;
&lt;h3&gt;3rd party cookieによって広告配信業者に情報が渡る流れ&lt;/h3&gt;
&lt;p&gt;図にすると以下のような流れになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ユーザが広告のJavascriptコードが付いている健康器具のウェブサイトを閲覧する。&lt;/li&gt;
&lt;li&gt;ブラウザがそのコードを実行して広告配信業者にアクセスし、広告配信業者はcookieを送信する。&lt;/li&gt;
&lt;li&gt;広告配信業者から指示されたcookieをブラウザが保存する。&lt;/li&gt;
&lt;li&gt;別のサイトをユーザが表示する。&lt;/li&gt;
&lt;li&gt;同じ広告配信業者の広告のJavascriptコードが付いているウェブサイトを閲覧する。&lt;/li&gt;
&lt;li&gt;別のサイトにアクセスしている情報と共に広告配信業者へ送信される。&lt;/li&gt;
&lt;li&gt;広告配信業者はユーザがアクセスしたページのアクセス履歴を保存し、そこからユーザに適した広告を配信する。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;3rd party cookieが禁止されるとできなくなること&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;広告配信業者がユーザのアクセス履歴を取れなくなります。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;広告配信側
&lt;ul&gt;
&lt;li&gt;アクセスしている人のアクセス履歴などの情報を取得できなくなる&lt;/li&gt;
&lt;li&gt;ターゲティングできなくなる&lt;/li&gt;
&lt;li&gt;リタゲできなくなる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;エンドユーザ
&lt;ul&gt;
&lt;li&gt;第三者に自分のアクセスログに近いものが保存されなくなる&lt;/li&gt;
&lt;li&gt;関連度の低い広告が表示される。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3rd party cookieに対しての各ブラウザの方針&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;3rd party cookieを無効
&lt;ul&gt;
&lt;li&gt;safari&lt;/li&gt;
&lt;li&gt;Edge&lt;/li&gt;
&lt;li&gt;Brave&lt;/li&gt;
&lt;li&gt;Firefox&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3rd party cookieが有効
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Google Chrome&lt;/strong&gt; (2023年末に終了すると発表)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Googleが全方面で強い&lt;/h3&gt;
&lt;p&gt;では、なぜGoogle Chromeだけが3rd party cookieを無効にしていないかというと、Googleは広告配信を行っているので3rd party cookieが無効化されると広告収益が落ちるからです。&lt;/p&gt;
&lt;p&gt;Google Chrome以外は広告収益への関連が無いのですぐに3rd party cookieを無効に動きました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Googleは1st party cookieを埋め込めるようなソリューションや、自分自身のメディアを持っています。&lt;/p&gt;
&lt;p&gt;また、Google Analyticsはウェブサイトに1st party cookieを埋め込んで居るのでGoogle Analyticsが裏側で値を突合していたら同じことが物理的には実現できてしまいますができないでしょう。Gmailも同様です。Google社の内部統制を信じるしか無いようなユーザにとっては危うい状態です。&lt;/p&gt;
&lt;p&gt;まさに、この危うい状態になるのを防ぐための法律が最初に挙げた法律なのかなとも思います。&lt;/p&gt;
&lt;p&gt;YouTubeに関しては、バーティカルなメディアなので自サイトで個人情報を集め、広告配信に利用できます。他社からの広告は期待できませんが、自社のアドネットワークだけで十分収益を得られるのでビジネスへの影響は無いでしょう。&lt;/p&gt;
&lt;h3&gt;Googleだけが3rd party cookieはいきなり廃止できない&lt;/h3&gt;
&lt;p&gt;広告配信業者がほぼGoogle一強になっているため、3rd party cookieが問題になります。&lt;/p&gt;
&lt;p&gt;もし、広告配信業者が数万社とか存在していたら、個人情報が一箇所に集まるような構図にならないので3rd party cookieを禁止するというところまで行かなかったかもしれません。&lt;/p&gt;
&lt;p&gt;よって、Googleは3rd party cookieの廃止には超絶反対の立場ですが、流石に世論はプライバシー保護の流れになっているので対応する必要が出てきます。&lt;/p&gt;
&lt;p&gt;3rd party cookieが無くなったらどんな技術を使ってユーザに最適な広告を提供するか？がまさに現在進行系で問題になっていて、3rd party cookieとは別に&lt;strong&gt;プライバシーに考慮したターゲティング技術を作る&lt;/strong&gt;ことを行っています。&lt;/p&gt;
&lt;h2&gt;Googleが取ったアプローチ&lt;/h2&gt;
&lt;p&gt;Googleが新たに考えた技術がFLoCとTopicsの2つになります。タイムライン的には以下のような流れになります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;2021/3/30&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google ChromeでFLoC(Federated Learning of Cohorts) を試験運用開始と&lt;a href=&quot;https://web.dev/floc/&quot;&gt;発表&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2022/1/25&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FLoCの開発を中止し、Topicsの技術テストを年内に行うと&lt;a href=&quot;https://www.itmedia.co.jp/news/articles/2201/26/news064.html&quot;&gt;発表&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;次に、FLoCとTopicsの概要を説明します。&lt;/p&gt;
&lt;h2&gt;FLoC(Federated Learning of Cohorts)&lt;/h2&gt;
&lt;p&gt;FLoCの最初の部分である、&quot;Federated Learning&quot; の説明をします。&lt;/p&gt;
&lt;h3&gt;Federated Learningの説明&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;呼び方: フェデレイテッド・ラーニング、連合学習&lt;/li&gt;
&lt;li&gt;抽象度高めの概念&lt;/li&gt;
&lt;li&gt;流れ
&lt;ul&gt;
&lt;li&gt;青丸: 初期モデル構築&lt;/li&gt;
&lt;li&gt;多数のエンドクライアントに配布&lt;/li&gt;
&lt;li&gt;エンドクライアントがモデルを修正&lt;/li&gt;
&lt;li&gt;エンドクライアントで作ったモデルを集めて集計して初期モデルを再構築&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ユースケース例: 日本語IMEの予測変換モデル&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://ai.googleblog.com/2017/04/federated-learning-collaborative.html&quot;&gt;https://ai.googleblog.com/2017/04/federated-learning-collaborative.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Cohortの説明&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;コーホートとは、共通した因子を持ち、観察対象となる&lt;strong&gt;集団&lt;/strong&gt;のこと。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%9B%E3%83%BC%E3%83%88&quot;&gt;Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;文脈としてはコホート法のほうが近い。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;FLoC(Federated Learning of Cohorts) の説明&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;コホートのフェデレイテッド・ラーニング
&lt;ul&gt;
&lt;li&gt;訳: 集団ごとにフェデレイテッド・ラーニングを適用する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wicg.github.io/floc/&quot;&gt;https://wicg.github.io/floc/&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;W3Cの仕様はworking draftの状態.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コホート（集団）は興味ごとに生成される。
&lt;ul&gt;
&lt;li&gt;=&amp;gt; 自分でコホートのIDとバージョンを取得できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;W3Cに掲載されている、サンプルコードはこちら。ユーザのコホートのIDを取得するコード。この取得したIDを広告配信業者に送信して、広告配信業者はそれに対して最適な広告を配信する。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lh6.googleusercontent.com/C1LgFvrvZ_7SdhtuSQJ_ivjdZz_R9T2r_kAPxYZheKtf1nuzd_ci0g6mDc-rBrIFK2RhuGCt7L0Rdxespu_cAVmGOKgxVgCloPyIau8Hq2tDlC6VhB7KIcu1sChWJOql-YZu7QvF1n1BDJLqTaDjxQ&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;FLoCの動作の流れ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://lh3.googleusercontent.com/hAYj74vtshpjRnarLefDVvTzhiA5jfo_in79dZXq7oRJDGqamb_Fhts1bUc4gMmEF7sSM2x1Inye-dqeIESRAVkqsCj6vdTZnesSRSDg1P3C5XqnImJte7rzP8lG16mTSkYHdbSgToLqhRH9Nd-7jw&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;FLoCの問題&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;FLoCのデータが個人を特定できる情報と紐付けられる可能性
&lt;ul&gt;
&lt;li&gt;=フィンガープリンティングリスク&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;トライアル中に&lt;a href=&quot;https://digiday.jp/platforms/wtf-is-googles-topics/&quot;&gt;3万グループ&lt;/a&gt;が作られたことにより、特徴的な行動をする場合は個人が特定されてしまうぐらいになる。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ユーザのプライバシー保護ができそうな手法だったにも関わらず、実証実験をしてみたら意外とプライバシーが守られなかった手法となってしまいました。&lt;/p&gt;
&lt;p&gt;個人的には、Cohortの粒度を調整することでプライバシーの調整できるので技術的には問題は無いと思います。&lt;/p&gt;
&lt;p&gt;それより、根底にはCohortを管理しているGoogleのコンプライアンスを信じるしか無い状態になっていることが問題になるのかと思います。&lt;/p&gt;
&lt;h2&gt;Topicsの説明&lt;/h2&gt;
&lt;p&gt;FLoCと比較して、Topicsは非常にシンプルです。&lt;/p&gt;
&lt;h3&gt;Topicsの概要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ユーザーの過去3週間の閲覧履歴に基づき、ユーザーが関心を持つ3つのトピックを広告主へ送信
&lt;ul&gt;
&lt;li&gt;ユーザは送信した内容は確認可能&lt;/li&gt;
&lt;li&gt;ユーザは送信する内容を変更可能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Googleが発表しているプロトタイプのスクリーンショット。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lh6.googleusercontent.com/9E40-Z_r6smFx3ja3QVrYdtS9J1f6sCefQjJusishnxe4ng0REoZFEWnXNkg4XihS8vS53daU180ZGsbrzli-oTvF8IKOzkwurwqrFov1pEh7Y47pkujPcb7VoTAK_4aStN2oga2EJhekIe6krAsVw&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Topicの考察&lt;/h3&gt;
&lt;p&gt;かなりユーザのプライバシー保護に寄った手法です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;広告配信側
&lt;ul&gt;
&lt;li&gt;ターゲティング精度がかなり低くなる&lt;/li&gt;
&lt;li&gt;デモグラなどのターゲティングも不可能&lt;/li&gt;
&lt;li&gt;「ユーザの情報ではなく、表示する場所に関連した広告が増える」と思う&lt;/li&gt;
&lt;li&gt;「DMPが消えることになるのと同義」かなと思う&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ユーザ側
&lt;ul&gt;
&lt;li&gt;開示する情報を完全にコントロールできるので安心&lt;/li&gt;
&lt;li&gt;興味のない広告が表示されることが多くなる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;他の事例&lt;/h2&gt;
&lt;p&gt;では、プライバシーに考慮したブラウザという謳い文句のBraveはどうやってユーザのプライバシーを保護しながら効率的に広告を配信しているのか疑問に思ったので調べてみました。&lt;/p&gt;
&lt;h3&gt;An Introduction to Brave’s In-Browser Ads&lt;/h3&gt;
&lt;p&gt;流れは以下のような図です。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://brave.com/intro-to-brave-ads/&quot;&gt;https://brave.com/intro-to-brave-ads/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lh4.googleusercontent.com/WhJvA6rDWV3-SKotDKAsLC4y7BpusQGgd5CSuZOzdp7XVHSWGFMKn815m5vgK-KKjaIPOHArGJNL3c_HatqTWIeciqjfCa_-pwVYU1ssdpulcC-IP8OdTrvXp6W_GfsgftIF8-QM5wHhFk-Th6Tb-w&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;広告をBraveの広告配信サーバに登録する&lt;/li&gt;
&lt;li&gt;Braveブラウザは全部の広告をダウンロードする&lt;/li&gt;
&lt;li&gt;Braveはユーザの興味モデルをブラウザ内で生成する&lt;/li&gt;
&lt;li&gt;ユーザが閲覧しているサイトをトリガーとして、ブラウザ内で最適なタイミングと最適な広告を計算して表示する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;広告の量が増えたらどうなるんだろうという疑問はありますが自分の情報が外に出ないので安全です。広告の配信に関しては非効率ですし即時性も無いのでちょっと微妙な感じはあります。&lt;/p&gt;
&lt;p&gt;やはり両立は難しいです。&lt;/p&gt;
&lt;p&gt;余談ですが、私はGoogle ChromeからBraveに半年ほど前に移行しました。&lt;/p&gt;
&lt;h3&gt;異業種ペルソナマーケティングAI推進協議会&lt;/h3&gt;
&lt;p&gt;アカデミック分野でもGoogleと同じように研究が進められています。&lt;/p&gt;
&lt;p&gt;https://ai-persona.jp/ （サービス終了）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://lh5.googleusercontent.com/xOxd7UyK_wVQDGl7IfZCRhroFg-DgLByELObQBYOmzoquQVCnlgYXTQr-AdScBH8Yq9yiyde7fba2o9N3dyO2jMrxacX_wZJuUEEzTh74v3uFVt-u2rsxNJYhqmaJ_5K0haoWpIhCW24Y2ZeHPZYVw&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;この場合、1st partyのサイトがユーザモデルを作ってそれを共有することでプライバシーに配慮しつつターゲティングの精度をあげようという試みかと思います。&lt;/p&gt;
&lt;p&gt;完全に余談ではありますが、私が&lt;a href=&quot;https://sfc.teraren.com/documents/g-pro/pdf/200502_thesis.pdf&quot;&gt;卒論&lt;/a&gt;（18年ほど前）で書いた「ユーザの行動を行動モデルに抽象化して利用する」というアプローチと同じです。&lt;/p&gt;
&lt;h2&gt;総括&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;アカデミック&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;普通は研究の世界では世の中の数年〜10年先を行くのが普通だが、プライバシーの分野では現在進行系の社会課題を研究対象としている。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1st party dataを3rd partyがかなり使いづらくなる&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;例:自社で広告案件を獲得して配信&lt;/li&gt;
&lt;li&gt;例:外部には具体的な情報を渡しづらくなるので、マクロなデータを渡す。&lt;/li&gt;
&lt;li&gt;バーティカルなサービスが重宝されそう。1st party dataを持っている会社が広告配信を行う。YouTubeやTikTokみたいなメディアが強くなりそう。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Web3の流れ&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GAFAMが情報を持ちすぎることで力を持ちすぎる問題に対処するためにも、情報の管理をより個人に持ってくる動きが強まると予想。個人情報を集めて収益化してきたGoogle, Facebookは広告ビジネスが辛い事になりそう。だから、VRに力を入れたり、別のソリューションに力を入れたりしている。&lt;/li&gt;
&lt;li&gt;個人情報はローカルまたは暗号化された状態でクラウドに持ち、物理的に自分がコントロールできる状態になるだろう。
&lt;ul&gt;
&lt;li&gt;メールで言えば、Gmail =&amp;gt; &lt;a href=&quot;https://protonmail.com/jp/&quot;&gt;Proton mail&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>FakerやGimeiのseedをrspecのseedと一致させる</title><link>https://blog.teraren.com/posts/rspec-seed-unstable-result/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rspec-seed-unstable-result/</guid><description>RSpecの--seedを指定してもFakerやGimeiが不安定になる原因と、乱数生成器を統一して再現性を確保する設定方法</description><pubDate>Thu, 02 Jun 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;rspecにおいて、単体テストの順番や使うデータをランダム化してテストパターンを増やすために &lt;code&gt;config.order = :random&lt;/code&gt;を有効化するのは普通かと思います。&lt;/li&gt;
&lt;li&gt;テストが失敗したときに、rspecコマンドの--seedオプションでランダム生成器のseedを固定してデバッグするときがあると思います。今回は、seedを固定してもテストが失敗したり成功したりして不安定でした。&lt;/li&gt;
&lt;li&gt;そしたら、乱数生成のseedはFakerやGimeiは各ライブラリ内で乱数発生器のインスタンスを作っているのでランダムに生成された値に依存したテストがユニークになりませんでした。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題が起きたテスト&lt;/h2&gt;
&lt;p&gt;FactoryBotで以下のようにエンティティを生成したうえで、このエンティティのページングをテストするコードでした。&lt;/p&gt;
&lt;p&gt;ページングする際には、codeカラムでsortされているので生成される値がランダムになるとテストのときに検証する値が予期しないものとなってしまいます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FactoryBot.define do
  factory :product do
    code { Faker::Alphanumeric.unique.alpha(number: 20)  }
    name { Gimei.prefecture.kanji  }
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;rspecコマンドに--seedを渡してもFakerやGimeiで生成した値が固定されないことが問題でした。&lt;/p&gt;
&lt;p&gt;実際にはこの問題を見つけるのに2時間ぐらいかかりました。結果だけ書くのは簡単ですが、見つけるのは結構大変です。&lt;/p&gt;
&lt;p&gt;実装が正しいのか、テストが正しいのかわからない状況で検証を進めるのは結構大変なものです。しかも、seedオプションを渡しても検証したいコードの結果が変わったりするので辛かったです。&lt;/p&gt;
&lt;p&gt;（そもそも、そんなカラムでソートしている実装なんて知らなかったし。natural orderで帰ってきていると思っていたという思い込みもあり。）&lt;/p&gt;
&lt;h2&gt;解決策&lt;/h2&gt;
&lt;h3&gt;差分&lt;/h3&gt;
&lt;p&gt;GimeiやFakerにrspecで使っている乱数生成器を渡してあげれば良いです。GimeiやFakerを使っている場合は必ず入れるべき設定です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -91,5 +91,11 @@ RSpec.configure do |config|
   #   # Setting this allows you to use `--seed` to deterministically reproduce
   #   # test failures related to randomization by passing the same `--seed` value
   #   # as the one that triggered the failure.
+  Kernel.srand config.seed
+
+  require &apos;faker&apos;
+  Faker::Config.random = Random.new(Random.seed)
+
+  require &apos;gimei&apos;
+  Gimei.config.rng = Random.new(Random.seed)
 end
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;結果&lt;/h3&gt;
&lt;p&gt;spec/spec_helper.rbはこんな感じになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  #   # Run specs in random order to surface order dependencies. If you find an
  #   # order dependency and want to debug it, you can fix the order by providing
  #   # the seed, which is printed after each run.
  #   #     --seed 1234
  config.order = :random
  #
  #   # Seed global randomization in this process using the `--seed` CLI option.
  #   # Setting this allows you to use `--seed` to deterministically reproduce
  #   # test failures related to randomization by passing the same `--seed` value
  #   # as the one that triggered the failure.
  Kernel.srand config.seed

  require &apos;faker&apos;
  Faker::Config.random = Random.new(Random.seed)

  require &apos;gimei&apos;
  Gimei.config.rng = Random.new(Random.seed)
end
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;テストコードの書き換え&lt;/h3&gt;
&lt;p&gt;値に依存しないようなテストコードに書き換えます。&lt;/p&gt;
&lt;p&gt;今回は、返り値となるデータの中身の検証が必要だったので、FactoryBotのcreate時に定数を渡すことで対処しました。&lt;/p&gt;
</content:encoded></item><item><title>Railsでsessionを無効化する方法</title><link>https://blog.teraren.com/posts/disable-session-on-rails/</link><guid isPermaLink="true">https://blog.teraren.com/posts/disable-session-on-rails/</guid><description>Railsでsessionを無効化する方法</description><pubDate>Sat, 28 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;config/initializers/session_store.rb&lt;/code&gt;に&lt;code&gt;Rails.application.config.session_store :disabled&lt;/code&gt;を書き込んでアプリケーションサーバを再起動。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;Rails.application.config.session_store :disabled&quot; &amp;gt; config/initializers/session_store.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;検証&lt;/h2&gt;
&lt;p&gt;Ruby on Rails 7.0で検証。Rails 3からこの方法でできるっぽい。&lt;/p&gt;
&lt;h3&gt;before&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% curl -v http://localhost:3001/ 2&amp;gt;&amp;amp;1 |grep -i cookie
&amp;lt; Set-Cookie: _train_session=9zmzzmUN5C%2FawwJc1xfMyQCNdWwVgoyQ4HeSgjCvK3tFdYR47cYGiKusOjIIL1goxvO3vhUazqJYtwUcQcWUGXjueOQLOyy89TOJ%2BpPgZOwcr1iFNsEXXxg4Mvt%2Be8IaCWilq7EmBn3q3r2DiK4TcfaS%2FKw9Qs3qNe6GftE%2BlYprxg3r9esCOkyVPva3OLw08IZOtgtvzcyyC6zbtTlBZ7lX9OV0E3ngUU8a5XdcFJ2bBzmKk4W6DAvIGrqOvza%2Bb7eUgWv60YdOJb5LWUkc9B3gmFz1AA%3D%3D--Zqf%2B2sbFYn7PYeMM--LPCwaBZ27oJWCKVb4lpuQA%3D%3D; path=/; HttpOnly; SameSite=Lax
%
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;after&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% curl -v http://localhost:3001/ 2&amp;gt;&amp;amp;1 |grep -i cookie
%
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Error response from daemon: network xxxxxxxx not foundエラーが出たけど解決</title><link>https://blog.teraren.com/posts/error-response-from-daemon-network-not-found/</link><guid isPermaLink="true">https://blog.teraren.com/posts/error-response-from-daemon-network-not-found/</guid><description>docker-compose.ymlからサービスを削除した後にnetwork not foundエラーが発生する原因と、設定を戻してdownしてから再起動する解決方法</description><pubDate>Sat, 28 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;コンテナを起動しようとしたら以下のような感じのエラーが出ました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker-compose run --rm app bash
[+] Running 2/2
 ⠿ Container train-chrome-1  Created                                                                                                                                                                                    0.0s
 ⠿ Container train-db-1      Recreated                                                                                                                                                                                  1.2s
[+] Running 1/2
 ⠹ Container train-chrome-1  Starting                                                                                                                                                                                   0.2s
 ⠿ Container train-db-1      Started                                                                                                                                                                                    0.2s
Error response from daemon: network 44b6d50a789537858cbdfe53a498bd50d288214b673c8c393ffc450ee942ac06 not found
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;試したこと&lt;/h2&gt;
&lt;p&gt;以下のようにお掃除すれば直るとかいてありますが、直りませんでした。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;docker-compose up --force-recreate&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/53347951/docker-network-not-found&quot;&gt;https://stackoverflow.com/questions/53347951/docker-network-not-found&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一通り、以下のことを試しましたが、解決しませんでした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker-compose down&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker-compose build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker-compose up --force-recreate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker network prune&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;docker network inspect &amp;lt;id&amp;gt;&lt;/code&gt; で調査したけど、not foundと言われる。。。&lt;/li&gt;
&lt;li&gt;docker engineの再起動&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;解決方法&lt;/h2&gt;
&lt;p&gt;結局は、docker-compose upしたときにdocker-compose.ymlから削除したサービスがあったのですが、それを起動しようとしているようなメッセージを見つけました。&lt;/p&gt;
&lt;p&gt;docker-compose.ymlを変更前に戻して、docker-compose downを実行した上で、docker-compose upをしたら正常に起動できました。&lt;/p&gt;
&lt;p&gt;エラーメッセージからはかなりわかりづらくて困りました。。。&lt;/p&gt;
</content:encoded></item><item><title>路線・駅データのAPIサービスをRuby on Rails 7 + Tailwind CSSで構築しました</title><link>https://blog.teraren.com/posts/d935e37a33c5c2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/d935e37a33c5c2/</guid><description>駅データのCSVを活用し、Rails 7 + Tailwind CSSで無料の路線・駅情報REST APIサービスを構築した記録。</description><pubDate>Thu, 26 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ruby on Rails 7 から Tailwind CSS がサポートされました。&lt;/li&gt;
&lt;li&gt;Rails が公式でサポートするからにはさぞかし良いものだろうと思うので使ってみたいと思い、ゴールデンウィークの 1 日を使って構築してみました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://train.teraren.com/&quot;&gt;路線・駅データのAPI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;スクリーンショット&lt;/h2&gt;
&lt;p&gt;まずは成果物の紹介です。&lt;/p&gt;
&lt;h3&gt;トップページ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/de390ab86035-20220527.png&quot; alt=&quot;train.teraren.com&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;APIドキュメント&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/42d0f2ccf3cf-20220527.png&quot; alt=&quot;駅情報 REST API&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;リクエストサンプル&lt;/h3&gt;
&lt;p&gt;山手線の駅名と緯度経度を取得する例。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -s  https://train.teraren.com/lines/11302/stations.json | jq -r &apos;.[] | [.station_name, .lat, .lon]&apos;
[
  &quot;大崎&quot;,
  &quot;35.619772&quot;,
  &quot;139.728439&quot;
]
[
  &quot;五反田&quot;,
  &quot;35.625974&quot;,
  &quot;139.723822&quot;
]
[
  &quot;目黒&quot;,
  &quot;35.633923&quot;,
  &quot;139.715775&quot;
]
[
  &quot;恵比寿&quot;,
  &quot;35.646685&quot;,
  &quot;139.71007&quot;
]
[
  &quot;渋谷&quot;,
  &quot;35.658871&quot;,
  &quot;139.701238&quot;
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;なぜ駅・路線のAPIサービスを作ったのか？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ekidata.jp/&quot;&gt;駅データ&lt;/a&gt;のサイトにて10年以上前から路線と駅のマスタデータがCSVファイルで公開されていました。&lt;/li&gt;
&lt;li&gt;上記のサイトにてAPIからデータを取得できるようになっていたようですが、サービスが停止されていました。&lt;/li&gt;
&lt;li&gt;類似サービスは様々な会社が提供していますが、無料でユーザ登録なしに簡単に利用できるAPIがありませんでした。&lt;/li&gt;
&lt;li&gt;駅データのマスタ情報は、運営元の方がオープンなライセンスを適用してくださっているので、それを有効活用したかった。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;作業の流れと使った時間&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ekidataのマスタ情報の学習: 1h&lt;/li&gt;
&lt;li&gt;Tailwind CSSのチュートリアル: 1h&lt;/li&gt;
&lt;li&gt;開発環境構築: 2h
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rails new . -c tailwind&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;docker-compose設定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;プログラム開発: 6h
&lt;ul&gt;
&lt;li&gt;model作成&lt;/li&gt;
&lt;li&gt;migrations作成&lt;/li&gt;
&lt;li&gt;i18n&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://daisyui.com/&quot;&gt;daisyUIの学習&lt;/a&gt;: 1h&lt;/li&gt;
&lt;li&gt;UIコーディング: 4h&lt;/li&gt;
&lt;li&gt;Lighthouse用チューニング: 1h&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://swagger.io/specification/&quot;&gt;OpenAPI Specification 3&lt;/a&gt;形式でのAPIドキュメント作成: 1h&lt;/li&gt;
&lt;li&gt;サーバ設定: 1h&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Railsの主な設定&lt;/h2&gt;
&lt;h3&gt;追加したgem&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;gem &apos;rails-i18n&apos;, &apos;~&amp;gt; 7.0.0&apos;
gem &apos;kaminari&apos;
gem &apos;sitemap_generator&apos;
gem &quot;meta-tags&quot;
gem &quot;rack-cors&quot;
gem &quot;google-tag-manager-rails&quot;, &quot;~&amp;gt; 0.1.3&quot;
gem &quot;gretel&quot;, &quot;~&amp;gt; 4.4&quot;
gem &quot;geocoder&quot;, &quot;~&amp;gt; 1.8&quot;

## for dev and test
gem &apos;rubocop&apos;, &apos;~&amp;gt; 1.28&apos;
gem &apos;openapi3_parser&apos;
gem &apos;openapi_parser&apos;
gem &apos;annotate&apos;

gem &apos;rspec-rails&apos;
gem &apos;capybara-screenshot&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;tailwindの設定&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;diff --git a/config/tailwind.config.js b/config/tailwind.config.js&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;index 34c0c84..01f8719 100644
--- a/config/tailwind.config.js
+++ b/config/tailwind.config.js
@@ -17,5 +17,16 @@ module.exports = {
     require(&apos;@tailwindcss/forms&apos;),
     require(&apos;@tailwindcss/aspect-ratio&apos;),
     require(&apos;@tailwindcss/typography&apos;),
-  ]
+    require(&apos;daisyui&apos;),
+  ]
 }

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;工夫した点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Lighthouse のスコアがほとんどチューニングしないで 95 点も出せました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/58429e477edc-20220527.png&quot; alt=&quot;lighthouse&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Tailwind CSS だけではプリミティブな UI ライブラリ集なので、Tailwind CSS だけを使ってページを作るのはかなり大変です。&lt;/li&gt;
&lt;li&gt;UI の部品であるコンポーネントは &lt;a href=&quot;https://daisyui.com/&quot;&gt;daisyUI&lt;/a&gt;を使いました。
&lt;ul&gt;
&lt;li&gt;Twitter Bootstrap は Tailwind CSS + デフォルトでそこそこ見栄えの良いアセットが提供されているのに対して Tailwind ではマークアップのライブラリとそれを使った UI のアセットは綺麗に分割されています。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tailwind だけだと、左のように書かないといけないのですが右のように書けます。daisyUI はこのように Tailwind の 1 段階上位で提供されている UI のアセット集という位置づけです。その結果、Twitter Bootstrap と同じような DSL で UI をマークアップできます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/4ff9c8e11a84-20220527.png&quot; alt=&quot;daisyUI&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tailwind が node に依存していないということもあり、全体的にコンパイルが速くて良いです。&lt;/li&gt;
&lt;li&gt;ページ内で使っているスタイルしかコンパイルされないので、必要最低限の CSS がコンパイルされるのでファイル容量が少なくて良いです。&lt;/li&gt;
&lt;li&gt;DSL (Domain-Specific Language) が 1 つ増えるのは辛いところではありますが、daisyUI のおかげで覚える項目はほとんど無いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;UI ができないエンジニアでも良い感じの UI を作れました。&lt;/li&gt;
&lt;li&gt;今は基本的な API しか作っていませんが、もっと便利なユースケースの API を増やしていきます。&lt;/li&gt;
&lt;li&gt;そのうちテクニカル編を書きたいと思います。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>路線情報・駅情報のREST APIサービスを作りました</title><link>https://blog.teraren.com/posts/ekidata-api/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ekidata-api/</guid><description>Ruby on Rails 7とTailwindを使って日本全国の路線・駅情報をJSONやCSVで取得できるREST APIサービスを自作した際の概要とAPI呼び出し例を紹介します。</description><pubDate>Sat, 21 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://train.teraren.com/&quot;&gt;https://train.teraren.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://rubyonrails.org/&quot;&gt;Ruby on Rails 7&lt;/a&gt; + &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt; + &lt;a href=&quot;https://daisyui.com/&quot;&gt;daisyui&lt;/a&gt; で作りました。&lt;/p&gt;
&lt;p&gt;まだ、エンティティの一覧と取得しかできませんが、これから機能拡充をしていきます。ほしいAPIがあったら教えて下さい。&lt;/p&gt;
&lt;h4&gt;例&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ある駅の周辺駅を近い順に表示&lt;/li&gt;
&lt;li&gt;GraphQL対応&lt;/li&gt;
&lt;li&gt;駅の距離&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;API呼び出し例&lt;/h2&gt;
&lt;p&gt;駅の名前と位置情報の一覧をCSVで取得する例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -s https://train.teraren.com/stations.json| json_pp | jq &apos;.[] | [.station_name, .lon, .lat] | @csv&apos;
&quot;\&quot;函館\&quot;,\&quot;140.726413\&quot;,\&quot;41.773709\&quot;&quot;
&quot;\&quot;五稜郭\&quot;,\&quot;140.733539\&quot;,\&quot;41.803557\&quot;&quot;
&quot;\&quot;桔梗\&quot;,\&quot;140.722952\&quot;,\&quot;41.846457\&quot;&quot;
&quot;\&quot;大中山\&quot;,\&quot;140.71358\&quot;,\&quot;41.864641\&quot;&quot;
&quot;\&quot;七飯\&quot;,\&quot;140.688556\&quot;,\&quot;41.886971\&quot;&quot;
&quot;\&quot;新函館北斗\&quot;,\&quot;140.646525\&quot;,\&quot;41.9054\&quot;&quot;
&quot;\&quot;仁山\&quot;,\&quot;140.635183\&quot;,\&quot;41.930011\&quot;&quot;
&quot;\&quot;大沼\&quot;,\&quot;140.669347\&quot;,\&quot;41.971954\&quot;&quot;
&quot;\&quot;大沼公園\&quot;,\&quot;140.669758\&quot;,\&quot;41.980958\&quot;&quot;
&quot;\&quot;赤井川\&quot;,\&quot;140.642678\&quot;,\&quot;42.003267\&quot;&quot;
&quot;\&quot;駒ケ岳\&quot;,\&quot;140.610476\&quot;,\&quot;42.038809\&quot;&quot;
&quot;\&quot;東山\&quot;,\&quot;140.605222\&quot;,\&quot;42.06172\&quot;&quot;
&quot;\&quot;姫川\&quot;,\&quot;140.591632\&quot;,\&quot;42.081312\&quot;&quot;
&quot;\&quot;池田園\&quot;,\&quot;140.700333\&quot;,\&quot;41.990692\&quot;&quot;
&quot;\&quot;流山温泉\&quot;,\&quot;140.716358\&quot;,\&quot;42.003483\&quot;&quot;
&quot;\&quot;銚子口\&quot;,\&quot;140.720656\&quot;,\&quot;42.015471\&quot;&quot;
&quot;\&quot;鹿部\&quot;,\&quot;140.771393\&quot;,\&quot;42.06439\&quot;&quot;
&quot;\&quot;渡島沼尻\&quot;,\&quot;140.747596\&quot;,\&quot;42.10706\&quot;&quot;
&quot;\&quot;渡島砂原\&quot;,\&quot;140.689451\&quot;,\&quot;42.12164\&quot;&quot;
&quot;\&quot;掛澗\&quot;,\&quot;140.64598\&quot;,\&quot;42.119205\&quot;&quot;
&quot;\&quot;尾白内\&quot;,\&quot;140.613449\&quot;,\&quot;42.111232\&quot;&quot;
&quot;\&quot;東森\&quot;,\&quot;140.59353\&quot;,\&quot;42.106823\&quot;&quot;
&quot;\&quot;森\&quot;,\&quot;140.573846\&quot;,\&quot;42.108917\&quot;&quot;
&quot;\&quot;桂川\&quot;,\&quot;140.5427876\&quot;,\&quot;42.1156004\&quot;&quot;
&quot;\&quot;石谷\&quot;,\&quot;140.506525\&quot;,\&quot;42.135519\&quot;&quot;
&quot;\&quot;本石倉\&quot;,\&quot;140.471957\&quot;,\&quot;42.159668\&quot;&quot;
&quot;\&quot;石倉\&quot;,\&quot;140.458436\&quot;,\&quot;42.17285\&quot;&quot;
&quot;\&quot;落部\&quot;,\&quot;140.420755\&quot;,\&quot;42.187617\&quot;&quot;
&quot;\&quot;野田生\&quot;,\&quot;140.37586\&quot;,\&quot;42.217104\&quot;&quot;
&quot;\&quot;山越\&quot;,\&quot;140.326593\&quot;,\&quot;42.231172\&quot;&quot;
&quot;\&quot;八雲\&quot;,\&quot;140.273342\&quot;,\&quot;42.253391\&quot;&quot;
&quot;\&quot;鷲ノ巣\&quot;,\&quot;140.269919\&quot;,\&quot;42.278389\&quot;&quot;
&quot;\&quot;山崎\&quot;,\&quot;140.2746\&quot;,\&quot;42.314635\&quot;&quot;
&quot;\&quot;黒岩\&quot;,\&quot;140.288173\&quot;,\&quot;42.368296\&quot;&quot;
&quot;\&quot;北豊津\&quot;,\&quot;140.297868\&quot;,\&quot;42.400969\&quot;&quot;
&quot;\&quot;国縫\&quot;,\&quot;140.320885\&quot;,\&quot;42.439319\&quot;&quot;
&quot;\&quot;中ノ沢\&quot;,\&quot;140.346077\&quot;,\&quot;42.477928\&quot;&quot;
&quot;\&quot;長万部\&quot;,\&quot;140.37507\&quot;,\&quot;42.512477\&quot;&quot;
&quot;\&quot;長万部\&quot;,\&quot;140.37507\&quot;,\&quot;42.512477\&quot;&quot;
&quot;\&quot;二股\&quot;,\&quot;140.320821\&quot;,\&quot;42.575869\&quot;&quot;
&quot;\&quot;蕨岱\&quot;,\&quot;140.313353\&quot;,\&quot;42.626353\&quot;&quot;
&quot;\&quot;黒松内\&quot;,\&quot;140.305704\&quot;,\&quot;42.669608\&quot;&quot;
&quot;\&quot;熱郛\&quot;,\&quot;140.375084\&quot;,\&quot;42.675653\&quot;&quot;
&quot;\&quot;目名\&quot;,\&quot;140.465742\&quot;,\&quot;42.761432\&quot;&quot;
&quot;\&quot;蘭越\&quot;,\&quot;140.52894\&quot;,\&quot;42.804542\&quot;&quot;
&quot;\&quot;昆布\&quot;,\&quot;140.596107\&quot;,\&quot;42.797984\&quot;&quot;
&quot;\&quot;ニセコ\&quot;,\&quot;140.684588\&quot;,\&quot;42.808746\&quot;&quot;
&quot;\&quot;比羅夫\&quot;,\&quot;140.722615\&quot;,\&quot;42.84856\&quot;&quot;
&quot;\&quot;倶知安\&quot;,\&quot;140.745471\&quot;,\&quot;42.90164\&quot;&quot;
&quot;\&quot;小沢\&quot;,\&quot;140.677657\&quot;,\&quot;42.97185\&quot;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Tailwind良い&lt;/h2&gt;
&lt;p&gt;最近、lighthouseでのベンチマークをしているとCSSやJSが重すぎるというアラートが出ています。&lt;/p&gt;
&lt;p&gt;assetをprecompileすると一部のスタイルしか使わないのに全部を読み込まないといけなかったのが必要最低限の読み込みだけで済むようになりました。&lt;/p&gt;
&lt;p&gt;おかげで、lighthouseのスコアがめちゃめちゃ高い！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;しかしながら、TailwindはOSSでは無いので、今後長期的にコミュニティが乗っかってくるのかは不明です。&lt;/p&gt;
&lt;p&gt;しかも&lt;a href=&quot;https://tailwindui.com/license&quot;&gt;ライセンス&lt;/a&gt;の制約が厳しくて、コンポーネントの配布が制限されています。Twitter Bootstrapの場合はテーマがたくさん作られたことによって導入のハードルをかなり下げましたが、Tailwindはそのようなコンポーネントが制限されているようです。&lt;/p&gt;
&lt;p&gt;じゃあ、このnpmは良いのか？って感じがします。。。&lt;/p&gt;
&lt;p&gt;https://daisyui.com/&lt;/p&gt;
</content:encoded></item><item><title>Rails 6.1.5でdb:migrationのときにreference周りでエラー</title><link>https://blog.teraren.com/posts/rails-6-1-5-reference-error/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-6-1-5-reference-error/</guid><description>Rails 6.1.5でdb:migrate時に外部キーのbigint型不一致エラーが発生する問題。6.1.6にアップグレードで解消するが原因は不明という調査記録。</description><pubDate>Thu, 19 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;rails db:migrateをしたときに、以下のようなエラーが出るようになってしまった。&lt;/p&gt;
&lt;p&gt;親のキーがbigintで作られていないから、外部キーが貼れないというエラー。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Column `parent_id` on table `children` does not match column `id` on `parents`, which has type `bigint`. To resolve this issue, change the type of the `parent_id` column on `parents` to be :bigint. (For example `t.bigint :parent_id`).
Original message: Mysql2::Error: Referencing column &apos;parent_id&apos; and referenced column &apos;id&apos; in foreign key constraint &apos;fk_rails_0525da88a4&apos; are incompatible.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;調査&lt;/h2&gt;
&lt;p&gt;しかしながら、&lt;code&gt;show create table parents&lt;/code&gt;; してみたら、親のカラムはbigintで作られている。。。&lt;/p&gt;
&lt;p&gt;rails 6.1.6に上げたら発生しなくなりました。rails 6.1.5に戻したら再現性あります。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/rails/rails/releases/tag/v6.1.6&quot;&gt;rails 6.1.6のchangelog&lt;/a&gt;を見てもそれらしき記述はなかったです。謎です。&lt;/p&gt;
&lt;p&gt;migrationのファイルはすべて6.0以降です。&lt;/p&gt;
&lt;p&gt;以下の結果は何も無いことを確認。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git grep ActiveRecord::Migration db |grep -v 6.0|grep -v 6.1
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;面倒なので原因は深追いしてない。。。&lt;/p&gt;
</content:encoded></item><item><title>chromedriverのインストールをarmとintelのDockerfileで共通化</title><link>https://blog.teraren.com/posts/chromedriver-on-arm/</link><guid isPermaLink="true">https://blog.teraren.com/posts/chromedriver-on-arm/</guid><description>chromedriverのインストールをarmとintelのDockerfileで共通化</description><pubDate>Wed, 11 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;E2Eテストをするためのchromedriverは、Linuxのディストリビューションごとにパッケージで提供されていないので、おそらく直接ダウンロードしているケースがほとんどかと思います。&lt;/p&gt;
&lt;p&gt;Dockerfile上で、アーキテクチャごとにダウンロードするファイルを振り分けるのが理想ですが、Dockerfileではそのようなことはできず、shellscriptを書いて判定する必要があります。&lt;/p&gt;
&lt;p&gt;Dockerfileにif文を書くとエスケープ文字や改行で見づらくなるので別途スクリプトを用意してアーキテクチャごとにダウンロードするファイルを変更するのが良いです。&lt;/p&gt;
&lt;h2&gt;スクリプト&lt;/h2&gt;
&lt;p&gt;https://gist.github.com/matsubo/ed900c43f9d00c1bc9e24c3873f9efeb&lt;/p&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;む。後日確認したら、chromedriver_mac64_m1.zipが動かなそうだ。。。&lt;/p&gt;
</content:encoded></item><item><title>第二種電気工事士の受験記録</title><link>https://blog.teraren.com/posts/2022-05-05-denki-koujishi/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2022-05-05-denki-koujishi/</guid><description>第二種電気工事士の受験記録。筆記・実技それぞれの勉強方法、使用した教材・工具、費用、試験当日の流れまで実体験をもとに詳しくまとめた。</description><pubDate>Thu, 05 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;家のリフォームをするに当たって、低圧電気の配線を工事するためには国家資格である第二種電気工事士が必要になるので取りました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;第二種電気工事士に合格したのでその時の記録を書いておきます。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;タイムライン&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;2020年3月31日 申し込み&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;9,593円（事務手数料　293円込み）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;筆記試験が2020年5月31日に実施予定でしたが、新型コロナウィルスにより延期されました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2020年10月4日 筆記試験&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;2020年12月12日 実技試験&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;筆記試験へ向けての勉強&lt;/h2&gt;
&lt;p&gt;以下の参考書と問題集がセットになっているものを買って勉強しました。試験の1ヶ月前から、週末に数時間勉強していたのでだいたい20時間ぐらいやったかと思います。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;4907394705&quot;}&lt;/p&gt;
&lt;p&gt;私の勉強の仕方としては、オーソドックスですが以下のような感じです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;教科書部分をサラッと読む。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;問題集をやる。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;できなかったところを復習してできるようにする。&lt;br /&gt;
（その後は2と3の繰り返し）&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;また、予備としてホーザンのYouTubeを寝る前に見ながら寝てました。&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/playlist?list=PLsb6Jp0PqtFzL6fcQnF4KZLaMy-K_MKL7&lt;/p&gt;
&lt;p&gt;合格基準点は60点以上なので不得意な分野はバッサリ切って、簡単なところだけを押さえるだけで十分です。&lt;/p&gt;
&lt;p&gt;資格偏差値は44なので低いです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;試験の1週間前には、この過去問サイトを3つ分行いました。適当にやって合格点はクリアできることを確認しました。&lt;/p&gt;
&lt;p&gt;会員登録して、途中からでも再開できるのでスキマ時間で実施できました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kakomonn.com/2shudenkikoujishi/&quot;&gt;https://kakomonn.com/2shudenkikoujishi/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;こんな感じでスコアのスクショを保存していきました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/BDE61E01-0C77-496B-809D-46A018B75744_1_201_a.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;筆記試験&lt;/h2&gt;
&lt;p&gt;筆記試験は、片道1時間半近くかかって、多磨駅（漢字はこれが正しい）にある東京外語大学のキャンパスへ。&lt;/p&gt;
&lt;p&gt;早く付きすぎて、室内に入れないので、キャンパスのベンチで復習しておきました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/IMG_5180-scaled.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;問題は持ち帰れるので、すぐに発表される速報で自己採点で8割以上取れていたので良しとします。&lt;/p&gt;
&lt;h2&gt;実技試験へ向けて&lt;/h2&gt;
&lt;p&gt;実技のためには、資材を加工するための道具と実技試験を練習するための資材を買う必要がありました。&lt;/p&gt;
&lt;p&gt;カッターとかペンチはすでに持っていたので、特殊な工具などを追加で買いました。&lt;/p&gt;
&lt;h3&gt;買ったもの&lt;/h3&gt;
&lt;p&gt;教科書と問題集がセットになったもの。必須です。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;4907394748&quot;}&lt;/p&gt;
&lt;p&gt;資材。高いですけど、必須です。私はこのキットのように1回分あれば十分でした。使い終わったら、9000円ぐらいでは売れます。流用したければ、実際に使っても良いですし。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B079JG1MD1&quot;}&lt;/p&gt;
&lt;p&gt;必須です。ワイヤーのカット、ストリップ、圧着を1本でできます。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00FO0IS5A&quot;}&lt;/p&gt;
&lt;p&gt;これは、実際いらないような気もしますが安いので買っておきます。家の蛇口の工事のときにも使えます。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00FB92WQ0&quot;}&lt;/p&gt;
&lt;p&gt;勉強の進め方は、教科書を頭の方から、1問ずつ進めました。問題と解説を軽くさらって、実際に作ってみました。&lt;/p&gt;
&lt;p&gt;作った結果は以下のように全部画像に保存しつつ、時間を記録していきました。また、不良部分は画像にメモしておきました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最終的には問題集を1周回して全部作って、あとは苦手だった問題を何個か作りました。&lt;/p&gt;
&lt;p&gt;この頃には、複線図を書かないでもいきなり作り始められるようになっていました。&lt;/p&gt;
&lt;h2&gt;実技試験&lt;/h2&gt;
&lt;p&gt;東京ビックサイトの南ホールです。新型コロナウィルスが流行っていたのと、電車だと行きづらいところなので車で行きました。&lt;/p&gt;
&lt;p&gt;帰りは駐車場を出るのにすごい渋滞してました。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/E69BB27C-A206-45DF-8EDA-E7EAF82F6533_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;試験の自体は、複線図を書くことは無く、すぐに制作に取り掛かって完成したので10分ぐらいで終わってしまいました。&lt;/p&gt;
&lt;p&gt;残り時間が暇だったので、すごい綺麗に整形してました。&lt;/p&gt;
&lt;h2&gt;その後&lt;/h2&gt;
&lt;p&gt;実技試験の練習のために使った資材に関しては、できるだけもとに戻してヤフオクで売りました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;練習して使用済みの電線は、市区町村のリサイクル回収ボックスがあったので全部そこへ持っていきました。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;自分で天井にWiFi アクセスポイントを付けたりできるようになりました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>armとintelのdocker-compose共通化へ向けて(mysql編)</title><link>https://blog.teraren.com/posts/arm-intel-docker-compose-in-the-same-file/</link><guid isPermaLink="true">https://blog.teraren.com/posts/arm-intel-docker-compose-in-the-same-file/</guid><description>Apple M1(ARM)とIntelで同じdocker-compose.ymlを使いMySQLを動かす方法。mysql/mysql-serverイメージを使ったマルチアーキテクチャ対応の設定手順を解説。</description><pubDate>Mon, 02 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;Officialの方でもarm64に対応していたのでオフィシャルをそのまま使えそうです。&lt;/p&gt;
&lt;p&gt;この記事を書いた時点ではまだリリースされていませんでした。&lt;/p&gt;
&lt;p&gt;https://x.com/matsubokkuri/status/1696078129100660767&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;m1(arm)のmacで既存プロジェクトのdocker-compose upをすると以下のようなエラーが出ます。
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Host &apos;172.21.0.4&apos; is not allowed to connect to this MySQL server&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;理由は&lt;a href=&quot;https://toyo.hatenablog.jp/entry/2022/03/02/234159&quot;&gt;こちらの記事&lt;/a&gt;がよくまとまっています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;あちこちで使われている、Docker公式イメージである、&apos;mysql&apos; はamd用しか提供されていません。arm用は、&lt;a href=&quot;https://hub.docker.com/r/arm64v8/mysql/&quot;&gt;別のイメージ名&lt;/a&gt;で提供されているようです。&lt;/p&gt;
&lt;p&gt;しかしながら、Docker HubにあるMySQLが提供している、mysql/mysql-server イメージはintel用とarm用を提供しています。設定ファイルを共通化したいのでimage名が同じマルチアーキテクチャビルドしてあるmysql/mysql-serverを使います。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;MySQL Server 8.0, the latest GA, for both x86 and AArch64(ARM64) architectures (tag: &lt;a href=&quot;https://github.com/mysql/mysql-docker/blob/mysql-server/8.0/Dockerfile&quot;&gt;&lt;code&gt;8.0&lt;/code&gt;, &lt;code&gt;latest&lt;/code&gt;&lt;/a&gt;) (&lt;a href=&quot;https://github.com/mysql/mysql-docker/blob/mysql-server/8.0/Dockerfile&quot;&gt;mysql-server/8.0/Dockerfile&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://hub.docker.com/r/mysql/mysql-server&quot;&gt;https://hub.docker.com/r/mysql/mysql-server&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;なので、mysql/mysql-server を指定することで設定を共通化できます。&lt;/p&gt;
&lt;p&gt;https://gist.github.com/matsubo/94666cf045af3ad8f91fada59116a1dd&lt;/p&gt;
&lt;p&gt;しかしながら、Docker Hubのイメージと、MySQLが出しているイメージは初期化スクリプトがちょっと違うようなので設定を追加で行う必要がありました。(上記の差分を参照)&lt;/p&gt;
&lt;h3&gt;初期&lt;/h3&gt;
&lt;p&gt;mysqlの/entrypoint.shの中で、MYSQL_ROOT_HOSTが参照されるのはmysqlのdataディレクトリが未作成の時だけです。&lt;/p&gt;
&lt;p&gt;データディレクトリが存在しないか、消した状態で上記の設定を動かせば特に気にする必要はありません。&lt;/p&gt;
&lt;h3&gt;MYSQL_ROOT_HOSTオプション無しで作成済みの場合&lt;/h3&gt;
&lt;h4&gt;ファイルのownerを設定&lt;/h4&gt;
&lt;p&gt;volumeを永続化している場合は、以下のようなコマンドを打ってownerを再設定する必要があります。imageによってuser idが変わっているためです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker-compose run --rm db chown -R mysql.mysql /var/lib/mysql /run/mysqld/
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;接続元許可&lt;/h4&gt;
&lt;p&gt;作成済みの場合は、権限を変えてあげる必要があります。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker-compose run db bash&lt;/code&gt;とかして、&lt;code&gt;mysql -u root&lt;/code&gt;とかして、DBに特権でログインします。&lt;/p&gt;
&lt;p&gt;以下のようなクエリーを打って、権限情報を変更します。変数部分は手元の環境に合わせて置き換えてください。&lt;/p&gt;
&lt;p&gt;MYSQL_ROOT_HOSTは、%にします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;${MYSQL_ROOT_PASSWORD}&apos;;
CREATE USER &apos;root&apos;@&apos;${MYSQL_ROOT_HOST}&apos; IDENTIFIED BY &apos;${MYSQL_ROOT_PASSWORD}&apos;;
GRANT ALL ON *.* TO &apos;root&apos;@&apos;${MYSQL_ROOT_HOST}&apos; WITH GRANT OPTION ;
GRANT PROXY ON &apos;&apos;@&apos;&apos; TO &apos;root&apos;@&apos;${MYSQL_ROOT_HOST}&apos; WITH GRANT OPTION ;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ちょっと前までは、Dockerfile自体を分ける必要がありましたが、今はDockerfileとdocker-compose.ymlを別にする必要はなさそうです。&lt;/li&gt;
&lt;li&gt;armでの開発環境構築がかなりスムーズになりそう。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Toonesの利用料を取得するスクリプト</title><link>https://blog.teraren.com/posts/toones-usage-automation/</link><guid isPermaLink="true">https://blog.teraren.com/posts/toones-usage-automation/</guid><description>Toonesの利用料を取得するスクリプト</description><pubDate>Mon, 02 May 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Toonesのサービス利用料を集計するためにはWebの画面にログインしてCSVファイルをダウンロードする方法しか無く、APIで取得ができません。&lt;/li&gt;
&lt;li&gt;手元で毎月集計したいので簡単なスクリプトを作ってみました。&lt;/li&gt;
&lt;li&gt;とりあえず作っただけなのでハードコードが多いです。HTTPクライアントは&lt;a href=&quot;https://github.com/sparklemotion/mechanize&quot;&gt;Mechanize&lt;/a&gt;を使っています。&lt;/li&gt;
&lt;li&gt;後々、Google Driveに追記していくようなスクリプトにします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ソースコード&lt;/h2&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ドハマリしたポイントは、ダウンロードしたCSVファイルに改行コードが、CRとCRLFの2つが混じっていたことです。rubyのCSVライブラリが文字コードやCSVparse周りでエラーを出すけど原因がわからずに問題を見つけるのが大変でした。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Amazon Linux 2にtigをインストール</title><link>https://blog.teraren.com/posts/amazon-linux-2-tig/</link><guid isPermaLink="true">https://blog.teraren.com/posts/amazon-linux-2-tig/</guid><description>Amazon Linux 2にtigをインストール</description><pubDate>Wed, 27 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Extra Packages for Enterprise Linux (EPEL)に入っているので、EPELを有効化して、tigをインストールするだけ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo amazon-linux-extras install -y epel
% sudo yum -y install tig
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>armとintelのdocker-compose共通化へ向けて(Ruby on Rails編)</title><link>https://blog.teraren.com/posts/docker-m1-arm-glibc-error-on-nokogiri/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-m1-arm-glibc-error-on-nokogiri/</guid><description>M1 MacのDockerでnokogiriのGLIBC_2.29エラーが発生する原因と、ARM・Intel両対応のdocker-compose設定で解決する方法</description><pubDate>Tue, 26 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;M1macでDockerのrubyイメージを使おうとすると、nokogiriの部分でエラーが出ます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker run --rm -it ruby:3.0.3-buster bash
root@489921d6a766:/# gem i nokogiri
Fetching nokogiri-1.13.4-aarch64-linux.gem
Successfully installed nokogiri-1.13.4-aarch64-linux
1 gem installed
root@489921d6a766:/# irb
irb(main):001:0&amp;gt; require &apos;nokogiri&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;ERROR: It looks like you&apos;re trying to use Nokogiri as a precompiled native gem on a system with glibc &amp;lt; 2.17:

  /lib/aarch64-linux-gnu/libm.so.6: version `GLIBC_2.29&apos; not found (required by /usr/local/bundle/gems/nokogiri-1.13.4-aarch64-linux/lib/nokogiri/3.0/nokogiri.so) - /usr/local/bundle/gems/nokogiri-1.13.4-aarch64-linux/lib/nokogiri/3.0/nokogiri.so

  If that&apos;s the case, then please install Nokogiri via the `ruby` platform gem:
      gem install nokogiri --platform=ruby
  or:
      bundle config set force_ruby_platform true

  Please visit https://nokogiri.org/tutorials/installing_nokogiri.html for more help.

/usr/local/bundle/gems/nokogiri-1.13.4-aarch64-linux/lib/nokogiri/extension.rb:7:in `require_relative&apos;: /lib/aarch64-linux-gnu/libm.so.6: version `GLIBC_2.29&apos; not found (required by /usr/local/bundle/gems/nokogiri-1.13.4-aarch64-linux/lib/nokogiri/3.0/nokogiri.so) - /usr/local/bundle/gems/nokogiri-1.13.4-aarch64-linux/lib/nokogiri/3.0/nokogiri.so (LoadError)
	from /usr/local/bundle/gems/nokogiri-1.13.4-aarch64-linux/lib/nokogiri/extension.rb:7:in `&amp;lt;top (required)&amp;gt;&apos;
	from /usr/local/bundle/gems/nokogiri-1.13.4-aarch64-linux/lib/nokogiri.rb:10:in `require_relative&apos;
	from /usr/local/bundle/gems/nokogiri-1.13.4-aarch64-linux/lib/nokogiri.rb:10:in `&amp;lt;top (required)&amp;gt;&apos;
	from &amp;lt;internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb&amp;gt;:160:in `require&apos;
	from &amp;lt;internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb&amp;gt;:160:in `rescue in require&apos;
	from &amp;lt;internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb&amp;gt;:149:in `require&apos;
	from (irb):1:in `&amp;lt;main&amp;gt;&apos;
	from /usr/local/lib/ruby/gems/3.0.0/gems/irb-1.3.5/exe/irb:11:in `&amp;lt;top (required)&amp;gt;&apos;
	from /usr/local/bin/irb:23:in `load&apos;
	from /usr/local/bin/irb:23:in `&amp;lt;main&amp;gt;&apos;
&amp;lt;internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb&amp;gt;:85:in `require&apos;: cannot load such file -- nokogiri (LoadError)
	from &amp;lt;internal:/usr/local/lib/ruby/3.0.0/rubygems/core_ext/kernel_require.rb&amp;gt;:85:in `require&apos;
	from (irb):1:in `&amp;lt;main&amp;gt;&apos;
	from /usr/local/lib/ruby/gems/3.0.0/gems/irb-1.3.5/exe/irb:11:in `&amp;lt;top (required)&amp;gt;&apos;
	from /usr/local/bin/irb:23:in `load&apos;
	from /usr/local/bin/irb:23:in `&amp;lt;main&amp;gt;&apos;
irb(main):002:0&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;原因は、Nokogiriが1.11あたりからプリコンパイルされて配布されるようになりました。そのバイナリは、&lt;a href=&quot;https://nokogiri.org/tutorials/installing_nokogiri.html&quot;&gt;glibc 2.17でコンパイル&lt;/a&gt;されています。&lt;/p&gt;
&lt;p&gt;しかしながら、arm用にコンパイルされたnokogiriが参照している &lt;code&gt;/lib/aarch64-linux-gnu/libm.so.6&lt;/code&gt;が2.29を必要としているっぽくてエラーになります。&lt;/p&gt;
&lt;h2&gt;解決方法&lt;/h2&gt;
&lt;p&gt;静的リンクするか、独自でコンパイルするのが良さそうです。静的リンクはバイナリサイズがでかくなりそうなので独自でコンパイルします。&lt;/p&gt;
&lt;h3&gt;Bundlerを使っている場合&lt;/h3&gt;
&lt;p&gt;Bundler使っている場合は以下を打って自分でコンパイルするように設定します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# bundler 2.1以降
% bundle config set force_ruby_platform true
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# bundler 2.0以前
% bundle config force_ruby_platform true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そうすると、.bundle/configに以下が入ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
BUNDLE_FORCE_RUBY_PLATFORM: &quot;true&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;もし、.bundleディレクトリを.gitignoreで無視するような設定を書いていたり、ユーザ側で設定した.bundleディレクトリを使うようにしている場合はホームディレクトリの設定ファイルに書き込んであげるのがよいです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bundle config set --global force_ruby_platform true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;実行例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker run --rm -it ruby:3.0.3-buster bash
root@11a428c7e8da:/# bundle config set force_ruby_platform true
root@11a428c7e8da:/# bundle init
Writing new Gemfile to //Gemfile
root@11a428c7e8da:/# bundle add nokogiri
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Fetching gem metadata from https://rubygems.org/.......
Resolving dependencies...
Using bundler 2.2.32
Fetching racc 1.6.0
Fetching mini_portile2 2.8.0
Installing racc 1.6.0 with native extensions
Installing mini_portile2 2.8.0
Fetching nokogiri 1.13.4
Installing nokogiri 1.13.4 with native extensions
root@11a428c7e8da:/# bundle exec irb
irb(main):002:0&amp;gt; require &apos;nokogiri&apos;
=&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Bundlerを使っていない場合&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;--platform=ruby&lt;/code&gt; オプションをつけてインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@b4ca7905b3a5:~# gem install nokogiri --platform=ruby
Fetching nokogiri-1.13.4.gem
Building native extensions. This could take a while...
Successfully installed nokogiri-1.13.4
1 gem installed
root@b4ca7905b3a5:~# irb
irb(main):001:0&amp;gt; require &apos;nokogiri&apos;
=&amp;gt; true
root@b4ca7905b3a5:/# gem list|grep nokogiri
nokogiri (1.13.4)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;手元での変更&lt;/h2&gt;
&lt;p&gt;結果的に手元のプロジェクトでは以下のような変更をDockerfileに行いました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;+ RUN bundle config set --global force_ruby_platform true
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;p&gt;詳細はこちらのissueにかかれています。&lt;/p&gt;
&lt;p&gt;https://github.com/sparklemotion/nokogiri/issues/2075&lt;/p&gt;
&lt;h2&gt;不確実情報&lt;/h2&gt;
&lt;p&gt;環境によっては、arm用のbinaryがインストールされたりもするので、これが実現すればコンパイルの時間が取られなくて良いのでどういったときにこのような設定ができるのかを検証中です。&lt;/p&gt;
&lt;p&gt;https://gist.github.com/matsubo/94666cf045af3ad8f91fada59116a1dd/b45e953d224220676898b1b84e7622edde3c1efe&lt;/p&gt;
</content:encoded></item><item><title>AASMでステータス変更と同じクリティカルセクションで実行</title><link>https://blog.teraren.com/posts/aasm-execute-within-transaction/</link><guid isPermaLink="true">https://blog.teraren.com/posts/aasm-execute-within-transaction/</guid><description>RailsのAASMでステータス変更と別テーブルの更新を同一トランザクション内で行うには、after_commitではなくafterコールバックを使うべき理由と実装方法を解説。</description><pubDate>Wed, 20 Apr 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;主にActiveRecordと併用して使うステータス管理用のgemがあります。&lt;/li&gt;
&lt;li&gt;AASM（ステートマシーン）です。&lt;/li&gt;
&lt;li&gt;「ステータス変更と同時に別の処理を実行したい」という要求を満たすために排他制御（主にデータベースのトランザクション）を使う場面がありますが、どのコールバックを使うのかがAASMのドキュメント内で明示されていなかったので書いておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;よくAASMのサンプルコードで見つけるのが、&lt;code&gt;after_commit&lt;/code&gt;コールバックに処理をしたいメソッドを書く方法です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://qiita.com/satour/items/fe838dc21dc95df95c62&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;上記にあるコードでは、ステータスの変更が終わったら通知をするというような別に処理を行っても問題ない処理なのでコードは正しいです。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;要するに、after_commitはその名の通りAASMによって管理されているステータスが更新されたことをDBにコミットした後に実行されます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;しかしながら、AASMで管理するステータスと別のテーブルにあるステータスを&lt;strong&gt;同時&lt;/strong&gt;に更新する場合に&lt;code&gt;after_commit&lt;/code&gt;コールバックを使うだけでは不十分です。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;after&lt;/code&gt; コールバックを使います。&lt;/p&gt;
&lt;p&gt;afterコールバックを使うと、AASMで管理するステートと同じトランザクション内で実行されます。&lt;/p&gt;
&lt;p&gt;https://github.com/aasm/aasm/blob/master/lib/aasm/aasm.rb#L177&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/04/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;afterコールバックは、&lt;code&gt;event&lt;/code&gt;とtransitionに対して設定できます。&lt;/p&gt;
&lt;h3&gt;余談&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;requires_lock: true&lt;/code&gt;は付ける必要があります。&lt;/p&gt;
</content:encoded></item><item><title>Envoy(受付アプリ)のSlack通知が遅いので自作</title><link>https://blog.teraren.com/posts/envoy-slack-notification/</link><guid isPermaLink="true">https://blog.teraren.com/posts/envoy-slack-notification/</guid><description>オフィス受付アプリEnvoyのSlack連携が4〜5分遅延する問題を解消するため、webhookを直接受け取るPHPスクリプトを自作した実装例</description><pubDate>Thu, 24 Mar 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://envoy.com/&quot;&gt;Envoy&lt;/a&gt;というオフィスのエントランスで受付をするシステムがあります。&lt;/li&gt;
&lt;li&gt;理想のワークフローは、Envoyで訪問者が受付をした際に、担当者宛にSlackで通知を飛ばすこと。&lt;/li&gt;
&lt;li&gt;Envoyが提供しているSlackのIntegrationを使うと、通知が届くまで4〜5分かかるのでかなり問題。（どうやら、2回めの通知は早い。SlackのIntegrationの初回呼び出しが遅い感じ。）&lt;/li&gt;
&lt;li&gt;Envoyからのwebhookは即時で届くので、SlackのIntegrationを使うのではなく自作したプログラムを使います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設計&lt;/h2&gt;
&lt;p&gt;通信のフローは以下のようになります。&lt;/p&gt;
&lt;p&gt;Envoy =&amp;gt; (webhook) =&amp;gt; なんかしらのScript =&amp;gt; (webhook) =&amp;gt; Slack&lt;/p&gt;
&lt;p&gt;Scriptの部分を作って設置します。&lt;/p&gt;
&lt;p&gt;スクリプトは以下のような感じです。EnvoyからはPOSTでいろいろなデータが送られてくるので、必要なデータを抽出してSlackへ通知します。&lt;/p&gt;
&lt;p&gt;SlackのWebhookのURLはパラメータで受け取れるようにしておきます。&lt;/p&gt;
&lt;p&gt;https://gist.github.com/matsubo/a5f8eb01057dbf86cd3fc9cb2d116ebc&lt;/p&gt;
&lt;h3&gt;設定&lt;/h3&gt;
&lt;p&gt;予め、Slack側で通知を送りたいチャネルでwebhookのURLを発行しておきます。&lt;/p&gt;
&lt;p&gt;Envoyに管理者でログインして、上記のスクリプトのURLを登録します。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dashboard.envoy.com/integrations&quot;&gt;https://dashboard.envoy.com/integrations&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/03/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;設定するWebhookのURLには忘れずにurlパラメータでslackの通知先webhookを入力します。一応、urlencodeした値を入れておきます。&lt;/p&gt;
&lt;p&gt;URL例&lt;/p&gt;
&lt;p&gt;https://example.com/slack.php?url=https%3A%2F%2Fhooks.slack.com%2Fservices%2FT0000XXXX%2Fxxxxxxxxxxx%2Fxxxxxxxxxxxxxxxxxxxxxxxxx&lt;/p&gt;
&lt;h2&gt;通知のサンプル&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/03/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ほぼ即時に通知が来るようになりました。&lt;/li&gt;
&lt;li&gt;webhookを動かしているPHPのアプリケーションサーバが落ちると通知が来なくて辛い状態になります。&lt;/li&gt;
&lt;li&gt;mentionさせるためには、SlackとEnvoy間でユーザの紐付けをしないといけないので今回はやってません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;p&gt;EnvoyからWebhookで送られてくるサンプルデータはこちらです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Array
(
    [event] =&amp;gt; entry_sign_in
    [meta] =&amp;gt; Array
        (
            [location] =&amp;gt; Array
                (
                    [id] =&amp;gt; xxxx
                    [type] =&amp;gt; locations
                    [attributes] =&amp;gt; Array
                        (
                            [name] =&amp;gt; xx
                            [company-name-override] =&amp;gt;
                            [time-zone] =&amp;gt; Asia/Tokyo
                            [timezone] =&amp;gt; Asia/Tokyo
                            [locale] =&amp;gt; ja
                            [address] =&amp;gt; 〒xxx-xxxx xxxxxxxxxxx
                            [address-line-one] =&amp;gt; undefined
                            [address-line-two] =&amp;gt; 1F
                            [city] =&amp;gt; xxxx
                            [state] =&amp;gt; xxxx
                            [country] =&amp;gt; xx
                            [zip] =&amp;gt; xxx-xxxx
                            [longitude] =&amp;gt; xxxx.xxxxxx
                            [latitude] =&amp;gt; xx.xxxxxxxxx
                            [created-at] =&amp;gt; 20xx-04-11T08:18:24.829Z
                        )

                    [relationships] =&amp;gt; Array
                        (
                            [company] =&amp;gt; Array
                                (
                                    [data] =&amp;gt; Array
                                        (
                                            [id] =&amp;gt; xxxx
                                            [type] =&amp;gt; companies
                                        )

                                )

                        )

                )

            [company] =&amp;gt; Array
                (
                    [id] =&amp;gt; xxx
                    [type] =&amp;gt; companies
                    [attributes] =&amp;gt; Array
                        (
                            [name] =&amp;gt; xxxxxxxxx
                            [plan-intent] =&amp;gt; basic
                            [buy-intent] =&amp;gt;
                            [active] =&amp;gt; 1
                            [created-at] =&amp;gt; 20xx-04-11T08:18:24.795Z
                        )

                )

        )
    [payload] =&amp;gt; Array
        (
            [id] =&amp;gt; xxxxxxxxxxxxxxx
            [type] =&amp;gt; entries
            [attributes] =&amp;gt; Array
                (
                    [agreements-status] =&amp;gt; not_applicable
                    [full-name] =&amp;gt; xxxxxx
                    [email] =&amp;gt;
                    [employee-screening-flow] =&amp;gt;
                    [host] =&amp;gt; @here
                    [host-email] =&amp;gt; foo@example.com
                    [private-notes] =&amp;gt;
                    [signed-in-at] =&amp;gt; 20xx-03-24 02:21:53 UTC
                    [device-session-uuid] =&amp;gt;
                    [signed-in-via] =&amp;gt; xxxxx
                    [signed-in-by] =&amp;gt;
                    [signed-out-via] =&amp;gt; xxxxxx
                    [signed-out-by] =&amp;gt;
                    [signed-out-at] =&amp;gt; 20xx-03-24 02:21:53 UTC
                    [thumbnails] =&amp;gt; Array
                        (
                            [large] =&amp;gt;
                            [original] =&amp;gt;
                            [small] =&amp;gt;
                        )

                    [flow-name] =&amp;gt; Visitor
                    [original-nda-sign-date] =&amp;gt;
                    [group-name] =&amp;gt;
                    [id-check-status] =&amp;gt;
                    [is-delivery] =&amp;gt; 1
                    [agreement-refused] =&amp;gt;
                    [pov-key] =&amp;gt; Purpose of visit
                    [user-data] =&amp;gt; Array
                        (
                            [0] =&amp;gt; Array
                                (
                                    [field] =&amp;gt; Host
                                    [value] =&amp;gt; @here
                                )

                        )

                    [sms-status] =&amp;gt; not_sent
                    [approval-status] =&amp;gt;
                    [push-status] =&amp;gt; not_sent
                    [email-status] =&amp;gt; not_sent
                )
            [relationships] =&amp;gt; Array
                (
                    [location] =&amp;gt; Array
                        (
                            [data] =&amp;gt; Array
                                (
                                    [type] =&amp;gt; locations
                                    [id] =&amp;gt; xxxxx
                                )

                        )

                    [device] =&amp;gt; Array
                        (
                            [data] =&amp;gt; Array
                                (
                                    [type] =&amp;gt; devices
                                    [id] =&amp;gt; xxxxx
                                )

                        )

                    [employee] =&amp;gt; Array
                        (
                            [data] =&amp;gt; Array
                                (
                                    [type] =&amp;gt; employees
                                    [id] =&amp;gt; xxxxxx
                                )

                        )

                    [flow] =&amp;gt; Array
                        (
                            [data] =&amp;gt; Array
                                (
                                    [type] =&amp;gt; flows
                                    [id] =&amp;gt; xxxxxx
                                )

                        )

                    [previous-entries] =&amp;gt; Array
                        (
                            [links] =&amp;gt; Array
                                (
                                    [related] =&amp;gt; https://app.envoy.com/api/v3/entries/xxxxxxxxx/previous-entries
                                )

                        )

                    [platform-jobs] =&amp;gt; Array
                        (
                            [links] =&amp;gt; Array
                                (
                                    [related] =&amp;gt; https://app.envoy.com/api/v3/entries/xxxxxxxx/platform-jobs
                                )

                        )

                )

        )

)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Google Domainsのドメインでメール送信ができなくなったけど解決</title><link>https://blog.teraren.com/posts/google-domains-send-failure/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-domains-send-failure/</guid><description>Google Domainsのドメインでメール送信ができなくなったけど解決</description><pubDate>Mon, 07 Mar 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;独自ドメインの転送メールアドレスを無料で行えるように設定しました。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/google-domains-custom-domain-gmail/&lt;/p&gt;
&lt;p&gt;しかしながら、1週間ぐらい経過してからメールを送信したら、以下のようなエラーメールが返ってきてしまいました。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You no longer have access to foo@example.com. To send this email, choose a different &quot;from&quot; address and try again. Learn more at https://support.google.com/mail/answer/22370?hl=&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;解決方法&lt;/h2&gt;
&lt;p&gt;gmailのSMTPサーバから別ドメインのメールを送っているのでSPF関連の設定を入稿していないから起きているのかな？と思っていましたが、以下の書き込みでは外部メールアドレスの設定を一度削除して作り直せば使えるようになると書いてありました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.google.com/search?q=gmail+spf&amp;amp;oq=gmail+spf+&amp;amp;aqs=chrome..69i57.1471j0j1&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&quot;&gt;https://www.google.com/search?q=gmail+spf&amp;amp;oq=gmail+spf+&amp;amp;aqs=chrome..69i57.1471j0j1&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;そんなので直るのかと思っていましたが、実際に作り直したら送信できるようになりました。&lt;/p&gt;
&lt;p&gt;設定と確認に10分近くかかるので再発したら面倒だなと思います…。&lt;/p&gt;
&lt;h2&gt;招待コード&lt;/h2&gt;
&lt;p&gt;25%オフで利用できる招待コードが届いたのでどうぞ。&lt;/p&gt;
&lt;p&gt;Have a friend who hasn’t tried Google Domains yet? New users can enter code &lt;strong&gt;FRIENDSOFDOMAINS&lt;/strong&gt; at checkout for 25% off** a new domain or transfer-in.&lt;/p&gt;
</content:encoded></item><item><title>郵便番号から住所を補完するコード</title><link>https://blog.teraren.com/posts/qiita-20230213-30f724b296d1b0729503/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20230213-30f724b296d1b0729503/</guid><description>郵便番号から住所を呼び出すときには以下のような URL で呼び出すだけです。</description><pubDate>Sun, 13 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Web の申し込みフォームなどで郵便番号を入力すると住所が自動的に補完されるコードを書きます。&lt;/li&gt;
&lt;li&gt;無料の &lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;郵便番号API ポストくん&lt;/a&gt;を使いました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;調査&lt;/h3&gt;
&lt;p&gt;郵便番号から住所を呼び出すときには以下のような URL で呼び出すだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -s https://postcode.teraren.com/postcodes/1600023.json | jq
{
  &quot;postcode_type&quot;: &quot;area&quot;,
  &quot;jis&quot;: &quot;13104&quot;,
  &quot;old&quot;: &quot;160&quot;,
  &quot;new&quot;: &quot;1600023&quot;,
  &quot;prefecture_kana&quot;: &quot;トウキョウト&quot;,
  &quot;city_kana&quot;: &quot;シンジュクク&quot;,
  &quot;suburb_kana&quot;: &quot;ニシシンジュク&quot;,
  &quot;prefecture&quot;: &quot;東京都&quot;,
  &quot;city&quot;: &quot;新宿区&quot;,
  &quot;suburb&quot;: &quot;西新宿&quot;,
  &quot;street_address&quot;: null,
  &quot;office&quot;: null,
  &quot;office_kana&quot;: null,
  &quot;post_type&quot;: null,
  &quot;is_separated_suburb&quot;: 0,
  &quot;is_koaza&quot;: 0,
  &quot;is_chome&quot;: 1,
  &quot;is_include_area&quot;: 0,
  &quot;status&quot;: 0,
  &quot;reason&quot;: 0,
  &quot;created_at&quot;: &quot;2023-02-08T05:10:49.000Z&quot;,
  &quot;updated_at&quot;: &quot;2023-02-08T05:10:49.000Z&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;実装&lt;/h3&gt;
&lt;p&gt;上記を踏まえてコードを書きます。とても簡単です。&lt;/p&gt;
&lt;h4&gt;HTML&lt;/h4&gt;
&lt;p&gt;HTML側は郵便番号の入力フォームと、取得したデータを表示する部分を作っておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;form&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;h2&amp;gt;郵便番号入力&amp;lt;/h2&amp;gt;
  &amp;lt;input type=&quot;text&quot; id=&quot;postcode&quot; placeholder=&quot;1600023&quot; maxlength=&quot;7&quot; autofocus&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;h2&amp;gt;住所補完&amp;lt;/h2&amp;gt;
  &amp;lt;input type=&quot;text&quot; id=&quot;prefecture&quot; placeholder=&quot;東京都&quot; disabled&amp;gt;
  &amp;lt;input type=&quot;text&quot; id=&quot;city&quot; placeholder=&quot;新宿区&quot; disabled&amp;gt;
  &amp;lt;input type=&quot;text&quot; id=&quot;suburb&quot; placeholder=&quot;西新宿&quot; disabled&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;JavaScript(ES6)&lt;/h4&gt;
&lt;p&gt;キーボードの入力が行われて数字が7桁だったらAPIで問い合わせをしています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;document.addEventListener(&apos;keyup&apos;, (e) =&amp;gt; {
  // 0 - 9 の数字キーでない場合は処理を終了
  if (!(e.keyCode &amp;gt;= 48 &amp;amp;&amp;amp; e.keyCode &amp;lt;= 57)) return;

  const postcode = document.getElementById(&apos;postcode&apos;).value;

  // 郵便番号が7桁でない場合は処理を終了
  if (postcode.length !== 7) return;

  const url = `https://postcode.teraren.com/postcodes/${postcode}.json`;

  fetch(url)
    .then(response =&amp;gt; response.json())
    .then(json =&amp;gt; {
      document.getElementById(&apos;prefecture&apos;).value = json.prefecture;
      document.getElementById(&apos;city&apos;).value = json.city;
      document.getElementById(&apos;suburb&apos;).value = json.suburb;
    })
    .catch(error =&amp;gt; {
      document.getElementById(&apos;prefecture&apos;).value = &apos;&apos;;
      document.getElementById(&apos;city&apos;).value = &apos;&apos;;
      document.getElementById(&apos;suburb&apos;).value = &apos;&apos;;
    });
});

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;デモはこちら&lt;/h2&gt;
&lt;p&gt;https://codepen.io/matsubokkuri/pen/XWPrNNw&lt;/p&gt;
</content:encoded></item><item><title>Google Domainsへ移管して無料でカスタムドメインをGmailで使う</title><link>https://blog.teraren.com/posts/google-domains-custom-domain-gmail/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-domains-custom-domain-gmail/</guid><description>Google Domainsの無料メール転送機能を使い、カスタムドメインのメールをGmailで送受信する設定手順を解説</description><pubDate>Thu, 10 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Google Domainsでドメインを管理すれば、無料でGmailをカスタムドメインで利用できるようになるらしいので設定してみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://x.com/twk/status/1484885881760923654&lt;/p&gt;
&lt;p&gt;おそらく、これに当たるのかなと思います。custom domainでaliasが作れる感じかなと思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;料金&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;今までは、muumuuドメインで管理していました。.comドメインなので料金は以下。過去の履歴を見てみたら、5年前は950円/年でした。2倍近く値上がりしています。
&lt;ul&gt;
&lt;li&gt;1,728円/年&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Google Domains
&lt;ul&gt;
&lt;li&gt;1,400円/年&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;移管&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;移管はこちらの手順通りに行いました。特につまずくところはないと思います。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://support.google.com/domains/answer/3251236?hl=ja&amp;amp;ref_topic=9003137&amp;amp;visit_id=637799892079898736-1406187690&amp;amp;rd=1&quot;&gt;https://support.google.com/domains/answer/3251236?hl=ja&amp;amp;ref_topic=9003137&amp;amp;visit_id=637799892079898736-1406187690&amp;amp;rd=1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;muumuuの場合は以下のような画面でAUTH_CODEを取得できました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;移管時に、DNSレコードをGoogleで管理するか聞かれますが、これにはNoと回答する必要があります。設定をインポートすると書いてありますが、今はAWSで管理していてすべてをインポートできるわけではないからです。&lt;/li&gt;
&lt;li&gt;ドメインの移管が終わってから、後ほどDNSの設定は行いましょう。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;今の所、日本では法人しか対応していないようなメッセージが表示されました。（どうやってそれって確認するのか不明ですが。。。）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;課金が完了するとメールが来ます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;その後、しばらく待ちます。移管元の方のレジストラから連絡が来るはずです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;数十分待つと、以下のようなメールが移管元のレジストラから来ますので、承認手続きを進めます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;5分ぐらいすると、移管が完了したメールが移管先のGoogle Domainsから届きます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;移行前のレジストラにあった有効期限はそのまま引き継がれます。&lt;/p&gt;
&lt;h2&gt;メールのForwardの設定&lt;/h2&gt;
&lt;p&gt;このあたりを読んで設定します。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://support.google.com/domains/answer/3251241?hl=en#emailForwarding&quot;&gt;https://support.google.com/domains/answer/3251241?hl=en#emailForwarding&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;まずは、Google Domains側でAliasを設定します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そして、カスタムドメインのメアドにメールを出して、gmail側で受信できることを確認します。&lt;/p&gt;
&lt;p&gt;次に、送信側の設定です。送信側の設定は、普通にGmailからSMTPサーバを追加するだけで良いです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mail.google.com/mail/u/0/#settings/accounts&quot;&gt;https://mail.google.com/mail/u/0/#settings/accounts&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-17.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;受信したメールに対して返信してみたところ、うまく返信できました。 後日試してみたら、送信できなくなってました。謎。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Reporting機能を有効化&lt;/h2&gt;
&lt;p&gt;Google DomainsでReporting機能を有効化すると、約1日後からドメインに対する統計情報が閲覧できるようになります。&lt;/p&gt;
&lt;p&gt;この統計情報は、Google Search Consoleに新たに1つ特別なプロファイルが作られて、そこから閲覧できるようになります。今まではホスト名単位でプロファイルが切られていましたが、このプロファイルは特殊でドメイン単位の統計が見られます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Google Domainsの「無料メール転送機能」が使えることによって、無料のGmailでカスタムドメインのメールアドレスを送受信できるようになりました。&lt;/li&gt;
&lt;li&gt;カスタムドメインでGmailを使いたかったがために、Google Workspaceを契約していましたが解約できます。&lt;/li&gt;
&lt;li&gt;ついでにDNS zoneの移行なども行ったのでトータル3時間位かかりました。&lt;/li&gt;
&lt;li&gt;Google Domainsを使っているとGoogle Sitesでサイトを作ることをおすすめされますが、相変わらずテンプレが貧素なので時間を無駄にしました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>GoogleのCloud Identityでエンドポイント管理</title><link>https://blog.teraren.com/posts/google-cloud-identity/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-cloud-identity/</guid><description>Google Cloud Identity Premiumで社内端末を一元管理し、BYODや紛失端末のリモートワイプをGoogle Workspaceと連携して実現する方法</description><pubDate>Thu, 03 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://b.hatena.ne.jp/entry/s/www.publickey1.jp/blog/20/g_suitewindows_10g_suitewindows_10.html&quot;&gt;Googleが2020年1月16日にリリースした&lt;/a&gt;Cloud Identityによって社内端末を管理する設定をしました。&lt;/li&gt;
&lt;li&gt;事例がほとんど見つからないのでオフィシャルドキュメントを片っ端から読んで設定してみました。&lt;/li&gt;
&lt;li&gt;コーポレート関連の情報が全然出回らないので書いておきます。&lt;/li&gt;
&lt;li&gt;手順などをちゃんと書くと、文量が大量になるので要点だけまとめます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Cloud Identity特徴&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;無料と有料プランがあります
&lt;ul&gt;
&lt;li&gt;Google Cloud Identity Free Edition&lt;/li&gt;
&lt;li&gt;Google Cloud Identity Premium Edition&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/09/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Chrome Bookの端末管理をしたかったので今回はPremium Editionを使う必要があります。&lt;/li&gt;
&lt;li&gt;Google WorkspaceのEnterpriseプランだとCloud Identityのサービスが含有されているのですが、それ以外では個別に契約が必要っぽいです。&lt;/li&gt;
&lt;li&gt;料金
&lt;ul&gt;
&lt;li&gt;645円/ユーザ/月&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/09/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;セキュリティ要件例&lt;/h2&gt;
&lt;p&gt;このあたりのことをやれます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;端末の紛失、盗難
&lt;ul&gt;
&lt;li&gt;データの削除をリモートから行ったり、容易にログインできなくする。&lt;/li&gt;
&lt;li&gt;ディスクが暗号化された状態を担保する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;認証
&lt;ul&gt;
&lt;li&gt;ソーシャルエンジニアリング対策&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;BYO対策
&lt;ul&gt;
&lt;li&gt;個人端末で会社アカウントを使っている場合の管理。&lt;/li&gt;
&lt;li&gt;業務委託の端末管理。&lt;/li&gt;
&lt;li&gt;Google Workspaceのアカウントを使ってログインしている端末は、Google Device Policyというアプリを別途入れることを共用されます。このアプリ経由で端末を制御できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://support.google.com/a/answer/7582673&quot;&gt;https://support.google.com/a/answer/7582673&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/09/image-3-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こんな感じで有効化できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/09/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Windows端末の場合は、Google Credential Providerというアプリが用意されていて、Google WorkspaceのIDとPWでWindows端末にログインするように設定できます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://tools.google.com/dlpage/gcpw&quot;&gt;https://tools.google.com/dlpage/gcpw&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/09/image-3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;私の場合は、以下のようなPowerShellスクリプトを書いて、キッティング時に実行して設定してます。&lt;/p&gt;
&lt;p&gt;https://gist.github.com/matsubo/97e7d42c7bad1b5f76905c0351f71f87&lt;/p&gt;
&lt;h2&gt;運用&lt;/h2&gt;
&lt;p&gt;以下のスクショのような感じでログインしたユーザやデバイスが表示されます。対象のデバイスから強制ログアウトや、リモートから情報の削除を行えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/09/image-3-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;デバイスでフィルタをしたりできます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/09/image-3-3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;この設定によって、会社のデバイスやBYODの端末を管理できるようになりました。セキュリティをコントロールしづらいBYODに対してもリモートワイプできるようになりました。&lt;/li&gt;
&lt;li&gt;Google Workspacesを導入したスタートアップには良いと思います。Android, ios, Windows, macosにおける最低限の認証管理、設定管理は行なえます。&lt;/li&gt;
&lt;li&gt;もっと細かい制御をしたい場合は、&lt;a href=&quot;https://www.jamf.com/ja/&quot;&gt;JAMF&lt;/a&gt;や&lt;a href=&quot;https://www.microsoft.com/ja-jp/microsoft-365/enterprise-mobility-security/microsoft-intune&quot;&gt;Intune&lt;/a&gt;などを使って強化していけばよいかと思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ABM連携もできるようなので、今後トライしたいです。&lt;br /&gt;
&lt;a href=&quot;https://support.google.com/a/answer/9904735?hl=ja&quot;&gt;https://support.google.com/a/answer/9904735?hl=ja&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;4798063193&quot;}&lt;/p&gt;
</content:encoded></item><item><title>自宅サーバ環境</title><link>https://blog.teraren.com/posts/home-server/</link><guid isPermaLink="true">https://blog.teraren.com/posts/home-server/</guid><description>Dell PowerEdge T320を中古2.6万円で購入し、Xeon 8コア・16GB RAM・RAID1構成でDocker運用する自宅サーバ環境の詳細</description><pubDate>Thu, 03 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;ハードウェア&lt;/h2&gt;
&lt;p&gt;PowerEdge T320を2019年12月に中古で26,000円で買いました。製造日は2013年とか2014年かと思います。&lt;/p&gt;
&lt;p&gt;CPU: 8コア Xeon E5-2450 2.1GHz&lt;/p&gt;
&lt;p&gt;RAM: 16GB&lt;/p&gt;
&lt;p&gt;HDD: 2TB x 4&lt;/p&gt;
&lt;p&gt;(RAID1)&lt;/p&gt;
&lt;p&gt;SSD: 500GB x 2 (RAID1)&lt;/p&gt;
&lt;h2&gt;OS&lt;/h2&gt;
&lt;p&gt;Ubuntu 22.04（基本的に最新を入れていくようにしています）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;コアは16個あるので一人で利用する分には並列性は十分です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;アプリケーション&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Dockerを入れて様々なWebサービスを運用しています。&lt;/li&gt;
&lt;li&gt;ユーザが多いサービスは安定性を重視するためにAWS Lightsailの方へ移行しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/Pasted_Image_2022_02_03_18_15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;UPS&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;停電のときにRAIDコントローラーを保護したいという目的でUPSを導入しました。&lt;/li&gt;
&lt;li&gt;最悪、長期の停電になったときにUPSの電池から充電をできたりするという用途にもなります。&lt;/li&gt;
&lt;li&gt;あと、使っている電力がわかるので電気代算出の目安になります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B06XHZ3K5T&quot;}&lt;/p&gt;
</content:encoded></item><item><title>有効期限付きポイントシステムの要求定義と設計</title><link>https://blog.teraren.com/posts/point-system-design-rdb/</link><guid isPermaLink="true">https://blog.teraren.com/posts/point-system-design-rdb/</guid><description>航空会社マイルのような有効期限付きポイントの加算・消費・取り消しを正確に処理するRDBスキーマ設計とシステム要件の公開解説</description><pubDate>Thu, 03 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;15年前ぐらいに設計、実装したシステムの設計と実装を公開します。&lt;/li&gt;
&lt;li&gt;目的は、誰かに特許を取られてしまっても困るので。自分で特許を取るほどでもないので共有資産として残しておきます。特許というか、どちらかと言うと論文で発表するほうが向いていそうです。&lt;/li&gt;
&lt;li&gt;航空会社のマイルで使われているポイント管理機能の実現方法です。このようなポイントシステムの要求はビジネスサイドではよくありそうですが、設計内容が公開されている事例を見つけられませんでした。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;類似ポイントシステム&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;JALやANAのマイルシステム
&lt;ul&gt;
&lt;li&gt;まさにこれと同じ機能の実現方法です。&lt;/li&gt;
&lt;li&gt;設計と実装が比較的難しいので、当時はこの機能を実現しているサービスは見つけられませんでした。&lt;/li&gt;
&lt;li&gt;2022年の今となってはこのポイントの仕組みはメジャーになりつつあります。様々な大手ポイントサイトで使われています。設計と実装の難易度が高かかったり、ユースケースが限られていたりするので中小規模のところでは採用されていないです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ビックカメラやヨドバシカメラのポイントシステム
&lt;ul&gt;
&lt;li&gt;最終利用日から1年で有効期限が切れる。&lt;/li&gt;
&lt;li&gt;この仕組の実装は簡単なのであちこちで採用されています。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.capilano-fw.com/?p=9251&quot;&gt;「有効期限つき」ポイントシステムをつくる&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;この記事で紹介されている設計では、「ポイントの消費を取り消す」ユースケースを処理できません。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要求&lt;/h2&gt;
&lt;h3&gt;アクター&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ユーザ&lt;/li&gt;
&lt;li&gt;経理&lt;/li&gt;
&lt;li&gt;システム管理者&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;機能要求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;基本機能&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ユーザに対してポイントを加算、減算できるシステム。&lt;/li&gt;
&lt;li&gt;加算に対して、任意の&lt;strong&gt;有効期限をつける。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;有効期限が近いポイントから消費していく。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;運用&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;減算を取り消すときには、&lt;strong&gt;減算前のポイントの有効期限を復元&lt;/strong&gt;する。&lt;/li&gt;
&lt;li&gt;ある時点の残高を算出できる。&lt;/li&gt;
&lt;li&gt;ポイントの整合性をチェックできる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ユーザ向け機能&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有効期限ごとに残高を表示できる。&lt;/li&gt;
&lt;li&gt;現在の残高を取得できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;経理&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;できるだけオンラインで処理できるようにする&lt;/li&gt;
&lt;li&gt;特定時点のBS（バランスシート）の算出&lt;/li&gt;
&lt;li&gt;特定時点のPL（プロフィット/ロス）の算出&lt;/li&gt;
&lt;li&gt;BSとPLの一致&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;システム&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;長期間運用しても遅くならないクエリーで取り出せる。&lt;/li&gt;
&lt;li&gt;減算、加算の整合性を検算できる。（＝BSとPLを作っておいて、整合性を検証）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ユースケースの例&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;2022年6月まで有効の100ポイントを加算&lt;/li&gt;
&lt;li&gt;2022年7月まで有効の100ポイントを加算&lt;/li&gt;
&lt;li&gt;150ポイントを消費。（1から100ポイント、2から50ポイントを引く）&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;いくつか設計のアプローチがあるので整理します。どのような特徴に注目して設計するかによっていくつかのアプローチがあります。それぞれの設計とメリット、デメリットをまとめておきます。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;トランザクションモデル
&lt;ol&gt;
&lt;li&gt;入金と出金の処理のトリガーはPLなので、必要最低限のPLを保存する。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;会計的アプローチ
&lt;ol&gt;
&lt;li&gt;PLとBS (有効期限ごと)を分離して保存する。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;オブジェクト指向
&lt;ol&gt;
&lt;li&gt;入金、出金をオブジェクトとして考える。&lt;/li&gt;
&lt;li&gt;入金、出金、1つ1つがオブジェクトとなる。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;1. トランザクションモデル&lt;/h3&gt;
&lt;p&gt;方向性は、入金と出金の履歴は最低限取らなければいけないのでそれぞれの履歴をエンティティとして表現します。&lt;/p&gt;
&lt;p&gt;Userエンティティは、ユーザ情報のマスタです。&lt;/p&gt;
&lt;p&gt;DepositHistoryは入金の履歴を表現するエンティティです。amountにはポイントの額を入れます。used_amountはその入金に対して利用済みの金額を保存するためのカラムです。デフォルトは0になります。 expiration_dateはその入金の有効期限の日付を入力します。&lt;/p&gt;
&lt;p&gt;WithdrawHistoryは出金の履歴を表現するエンティティです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;入金と出金を1つのエンティティで表現しても良かったのですが、used_amountとexpiration_dateの2つのアトリビュートが出金には非従属なので正規化してエンティティで分けました。&lt;/p&gt;
&lt;p&gt;このアプローチの良い点は、テーブルが2つで済むのでシンプルです。悪い点は、出金と入金の紐付けが行えないので出金の取り消しができません。&lt;/p&gt;
&lt;h3&gt;2. 会計的アプローチ&lt;/h3&gt;
&lt;p&gt;PLとBS (有効期限ごと)を分離して保存する。ユーザや管理者が見たいのは主にPLかBLのどちらかです。なので、ユーザ側の要求に近い状態でデータ自体も保存してしまえば集計も楽というアプローチです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;良い点は集計が容易です。悪い点は、1つ目と同じように入金と出金の紐付けがないので出金の取り消しが行なえません。&lt;/p&gt;
&lt;h3&gt;3. オブジェクト指向&lt;/h3&gt;
&lt;p&gt;入金、出金を個別に扱います。入金に対しての出金を厳密に関連付けることで取り消しを行えるようにします。&lt;/p&gt;
&lt;p&gt;データとしてはPLを持ちます。BSはこのPLのデータを使って集計して出すか、参照頻度が高いのであれば別途BS用のテーブルを用意しても良いと思います。&lt;/p&gt;
&lt;p&gt;BS用のテーブルを用意すると、集計は行いやすいですがその反面、PLの更新があるたびにBSのテーブルの更新も行う必要が出てきます。システムのユースケース頻度やトラフィックの多さによって使い分けるのが良いと思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;この手法の良い点は、出金の取り消しも容易に行なえます。悪い点はテーブルが3つになるのでデータの管理が煩雑です。出金時のクエリーを複数回発行する必要があり、計算量が収束しないので処理が遅くなる可能性があります。&lt;/p&gt;
&lt;h3&gt;メリット・デメリット&lt;/h3&gt;
&lt;p&gt;Matrixで整理しておきます。&lt;/p&gt;
&lt;p&gt;アプローチ1&lt;/p&gt;
&lt;p&gt;アプローチ2&lt;/p&gt;
&lt;p&gt;アプローチ3&lt;/p&gt;
&lt;p&gt;有効残高算出&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;減算・加算の時系列一覧&lt;/p&gt;
&lt;p&gt;△ &lt;code&gt;O(2n)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;△ &lt;code&gt;O(2n)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;残高の計算量&lt;/p&gt;
&lt;p&gt;&lt;code&gt;O(n)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;O(1)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;O(n)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;とある時点のスナップショット計算量&lt;/p&gt;
&lt;p&gt;&lt;code&gt;O(n)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;O(n)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;O(log(n))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;BSとPLの検算&lt;/p&gt;
&lt;p&gt;x&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;減算の取り消し&lt;/p&gt;
&lt;p&gt;x&lt;/p&gt;
&lt;p&gt;x&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;時間を指定したBSの出力&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;期間を指定したPLの出力&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;o&lt;/p&gt;
&lt;p&gt;nはとあるユーザに対する関連するテーブルのレコード数&lt;/p&gt;
&lt;h3&gt;採用する手法&lt;/h3&gt;
&lt;p&gt;3番を採用します。&lt;/p&gt;
&lt;h2&gt;実装&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;実装の方向性
&lt;ul&gt;
&lt;li&gt;各エンティティにまたがった排他制御が必要なのでRDBMSで実装するのが一般的かと思います。&lt;/li&gt;
&lt;li&gt;行ロックはデッドロックを回避するために左側のエンティティから順番にかけていくように実装します。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;加算&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Depositにレコードを入れるだけ。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;残高の表示&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Depositから有効期限が未来のレコードを抽出し、DepoistWithdraw.amountのsum()を除算&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;減算&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;トランザクション
&lt;ul&gt;
&lt;li&gt;残高をチェック。&lt;/li&gt;
&lt;li&gt;Depositから有効期限に近い順にソート&lt;/li&gt;
&lt;li&gt;影響のあるDepositを排他ロック&lt;/li&gt;
&lt;li&gt;Withdrawへレコードの追加&lt;/li&gt;
&lt;li&gt;DepositWithdrawへレコードの追加&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;減算取り消し&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;トランザクション
&lt;ul&gt;
&lt;li&gt;関連するDepositWithdrawを排他ロック&lt;/li&gt;
&lt;li&gt;Withdrawの削除&lt;/li&gt;
&lt;li&gt;関連するDepositWithdrawの削除&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;一覧&lt;/h3&gt;
&lt;p&gt;加算と減算を別のテーブルで管理しているので加算と減算の一覧を時系列に出す処理が重くなってしまいます。計算量、メモリ使用量がO(n)です。&lt;/p&gt;
&lt;p&gt;このシステムの設計における一番大きなデメリットがこの点。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DepositとWithdrawをUNION ALLして時間でソートする。
&lt;ul&gt;
&lt;li&gt;上記の処理は重いのでユースケースレベルで加算と減算それぞれのページを用意する事によってパフォーマンスは担保できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ユーザの削除&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PLを簡単に出すために、退会したユーザに対しては減算処理をして残高を0にしておく必要がある。そうでないと、BSを出すときに退会ユーザを除外するのが難しくなる。現時点でのBSを出すのは簡単だが、過去のとある時点のBSを出す際にはクエリーが不可能ではないが困難になる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ポイントの失効&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;BSを計算する際に、expiration_dateを元に算出することになる。有効期限が切れたポイントに関連するPLを算出するのはクエリーが複雑になる。&lt;/li&gt;
&lt;li&gt;考察
&lt;ul&gt;
&lt;li&gt;PLを集計しやすいように、ポイントが失効したら減算するレコードを入れるバッチを作っても良いが、実行タイミングは失効と同時に行う必要があるので実行が困難。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;検算&lt;/h3&gt;
&lt;p&gt;BSのスナップショットは持っていないので、PLの整合性を検証するのみになります。PLを複数テーブルで管理しているのでその整合性を確認します。&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair */}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“OK” if sum(DepositWithdraw.amount) == sum(Withdraw.amount)&lt;/li&gt;
&lt;li&gt;“OK” if Deposit.amount =&amp;gt; sum(DepositWithdraw.amount)
{/* textlint-enable ja-technical-writing/no-unmatched-pair */}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;実装が正しく動いているか確認するための保険としてdailyで上記のバッチを実行しておくのが良いです。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;この設計で今までに2つのサービスを構築しましたが不整合無く稼働しています。&lt;/li&gt;
&lt;li&gt;運用を開始してから、ビジネスサイドやファイナンスサイドからの要求に対しても基本的には答えられています。&lt;/li&gt;
&lt;li&gt;監査、経理、マーケティング用途の集計要求にも答えられています。（設計が少し複雑なのでエンジニアかデータに詳しい人じゃないと複雑な抽出クエリーを書けないという問題はあります）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B07D25W3HF&quot;}&lt;/p&gt;
</content:encoded></item><item><title>slackのステータスアイコンを自動で更新（家かオフィスかをアイコンで表示）</title><link>https://blog.teraren.com/posts/show-current-location-icon/</link><guid isPermaLink="true">https://blog.teraren.com/posts/show-current-location-icon/</guid><description>WiFiのSSIDが変わるたびにSlackのステータスアイコンを自動更新し、在宅・オフィスを周囲に知らせるツールの設定方法</description><pubDate>Thu, 03 Feb 2022 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;以下のように、自分がどこにいるのかを自動的にSlackのアイコンに表示する方法を紹介します。&lt;/li&gt;
&lt;li&gt;2年前（2020年）ぐらいに設定した内容なのでちょっと古いところがあるかもです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/02/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;slack-wifi-status&lt;/h2&gt;
&lt;p&gt;じゃあ、どうやってステータスを変えるのかと言うと、以下のようなロジックです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;wifiのSSIDが変更されたときのイベントをhookする&lt;/li&gt;
&lt;li&gt;SSIDとアイコンの定義を予め用意しておいて、それを元にSlackのAPIを使ってアイコンを変更する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下のバイナリをダウンロードします。このバイナリファイルをデーモンとして稼働させてWiFi APの変更を検知してアイコンを変更することになります。&lt;/p&gt;
&lt;p&gt;https://github.com/polidog/slack-wifi-status&lt;/p&gt;
&lt;p&gt;設定ファイルを以下のような感じで書きます。slackのtokenの項目にはユーザトークンを入れます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat ~/.slack-wifi-status.toml
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[slack]
token = &quot;xoxp-xxxxx-xxxxx-xxxxxxx-xxxxxxxxxxxx&quot;

[wifi]
  [[wifi.list]]
  name = &quot;office-wifi-ap&quot;
  message = &quot;at office&quot;
  emoji = &quot;:office:&quot;

  [[wifi.list]]
  name = &quot;office-guest-wifi-ap&quot;
  message = &quot;at office&quot;
  emoji = &quot;:office:&quot;

  [[wifi.list]]
  name = &quot;my-home-ssid&quot;
  message = &quot;at home&quot;
  emoji = &quot;:house:&quot;

  [[wifi.list]]
  name = &quot;starbucks&quot;
  message = &quot;at starbucks&quot;
  emoji = &quot;:comet:&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;/Users/matsu/Documents/slack-wifi-status_darwin_amd64/&lt;/code&gt; にバイナリを保存した前提のplistファイル&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat Library/LaunchAgents/slack-wifi-status.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;
&amp;lt;plist version=&quot;1.0&quot;&amp;gt;
 &amp;lt;dict&amp;gt;
  &amp;lt;key&amp;gt;Label&amp;lt;/key&amp;gt;
  &amp;lt;string&amp;gt;com.slack.slack-wifi-status&amp;lt;/string&amp;gt;
  &amp;lt;key&amp;gt;ProgramArguments&amp;lt;/key&amp;gt;
  &amp;lt;array&amp;gt;
     &amp;lt;string&amp;gt;/Users/matsu/Documents/slack-wifi-status_darwin_amd64/slack-wifi-status&amp;lt;/string&amp;gt;
  &amp;lt;/array&amp;gt;
  &amp;lt;key&amp;gt;StandardOutPath&amp;lt;/key&amp;gt;
  &amp;lt;string&amp;gt;/var/tmp/slack-wifi-status.log&amp;lt;/string&amp;gt;
  &amp;lt;key&amp;gt;RunAtLoad&amp;lt;/key&amp;gt;
  &amp;lt;true/&amp;gt;
 &amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のコマンドで、デーモンとして登録します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cd Library/LaunchAgents
% launchctl load slack-wifi-status.plist
% launchctl start slack-wifi-status.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自分のためと言うより、一緒に働いている人に対して自分がどこにいるのかを自動的に表現できる仕組みです。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Toonesの残高をチェックして少なかったらSlackへアラート</title><link>https://blog.teraren.com/posts/toones-balance/</link><guid isPermaLink="true">https://blog.teraren.com/posts/toones-balance/</guid><description>Toonesの残高をチェックして少なかったらSlackへアラート</description><pubDate>Wed, 12 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;インターネットFAXの&lt;a href=&quot;https://my.toones.jp/&quot;&gt;Toones&lt;/a&gt;にある残高が減った時に検知する手段が無かったのでスクレイピングしてSlackに通知するようにしました。mechanize gemを使えば、結構簡単に書けます。&lt;/p&gt;
&lt;p&gt;ヘッドレスブラウザを使うと大げさすぎるし、http clientだと低機能すぎるのでmechanizeはちょうどよい具合でした。&lt;/p&gt;
&lt;p&gt;アラートの通知は以下のような感じです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/01/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ソースコード&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;スクレイピングでエラーが起きたときに、検知できないと辛いのでエラーが起きたらSlackに通知しています。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sparklemotion/mechanize&quot;&gt;Mechanize&lt;/a&gt;は便利です。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>RSA Encryption not supported - caching_sha2_password plugin was built with GnuTLS support がでたときの対処法</title><link>https://blog.teraren.com/posts/rsa-encryption-not-supported/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rsa-encryption-not-supported/</guid><description>MySQL 8のcaching_sha2_passwordに対応していないクライアントで発生するRSA Encryption not supportedエラーを2種類の方法で解決する手順</description><pubDate>Sat, 18 Dec 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;原因&lt;/h2&gt;
&lt;p&gt;MySQL5.7までの認証プラグインにはmysql_native_passwordがデフォルトで使用されていましたがMySQL8より新たに追加されたcacing_sha2_passwordがデフォルトに変更されましたがクライアント側が対応していないため。&lt;/p&gt;
&lt;h3&gt;解決法1&lt;/h3&gt;
&lt;p&gt;docker-compose.ymlに以下の行を追加すればOKです。すでに構築済みでも大丈夫です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;command: --default-authentication-plugin=mysql_native_password
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/05/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;解決法2&lt;/h3&gt;
&lt;p&gt;DBのレコードを書き換える方法です。DB内に入っている値を書き換えるので、一時的な解決方法です。&lt;/p&gt;
&lt;p&gt;以下の実行例はdocker-composeで立ち上げている場合&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker exec -it &amp;lt;repository_name&amp;gt;-db-1 bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;passwordの部分は任意の文字列に置き換えてください。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# mysql -u root -p
&amp;gt; ALTER USER &apos;root&apos;@&apos;%&apos; IDENTIFIED WITH mysql_native_password BY &apos;password&apos;;
&amp;gt; ALTER USER &apos;root&apos;@&apos;localhost&apos; IDENTIFIED WITH mysql_native_password BY &apos;password&apos;
&amp;gt; flush privileges;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;発生するタイミング&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;初期セットアップ時。&lt;/li&gt;
&lt;li&gt;MySQLのDocker Imageのバージョンを上げたり（あがってしまったり）するとDBのユーザデータが初期化される場合がある様子。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Ubuntu 20.04.2 LTSにWiFiドングルを設定</title><link>https://blog.teraren.com/posts/ubuntu-20-04-2-lts-tplink-wifi/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ubuntu-20-04-2-lts-tplink-wifi/</guid><description>Ubuntu 20.04にTP-Link製USBWifiドングル（Realtek RTL8812BU）を接続してドライバをビルド・インストールし、無線LANを使えるようにする手順</description><pubDate>Fri, 12 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;こちらを買いました。Linuxで使えるようにするための設定があまり書かれていなかったのでメモ書きを残しておきます。Ubuntu 21でも同様です。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07MXHJ6KB&quot;}&lt;/p&gt;
&lt;h2&gt;チップセットを調べる&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;matsu@lenovo:~/$ lspci |grep net
08:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller (rev 0e)
matsu@lenovo:~/$ sudo lshw -c network
  *-network
       description: Ethernet interface
       product: RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
       vendor: Realtek Semiconductor Co., Ltd.
       physical id: 0
       bus info: pci@0000:08:00.0
       logical name: eno1
       version: 0e
       serial: 1c:69:7a:4d:00:26
       size: 1Gbit/s
       capacity: 1Gbit/s
       width: 64 bits
       clock: 33MHz
       capabilities: pm msi pciexpress msix vpd bus_master cap_list ethernet physical tp mii 10bt 10bt-fd 100bt 100bt-fd 1000bt-fd autonegotiation
       configuration: autonegotiation=on broadcast=yes driver=r8169 duplex=full ip=192.168.1.27 latency=0 link=yes multicast=yes port=MII speed=1Gbit/s
       resources: irq:30 ioport:f000(size=256) memory:fcd04000-fcd04fff memory:fcd00000-fcd03fff
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ドライバをインストール&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% git clone https://github.com/aircrack-ng/rtl8812au.git
% cd rtl8812au/
% sudo apt install dkms
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;matsu@lenovo:~/rtl8812au$ sudo make dkms_install
mkdir -p /usr/src/8812au-5.6.4.2_35491.20191025
cp -r * /usr/src/8812au-5.6.4.2_35491.20191025
dkms add -m 8812au -v 5.6.4.2_35491.20191025

Creating symlink /var/lib/dkms/8812au/5.6.4.2_35491.20191025/source -&amp;gt;
                 /usr/src/8812au-5.6.4.2_35491.20191025

DKMS: add completed.
dkms build -m 8812au -v 5.6.4.2_35491.20191025

Kernel preparation unnecessary for this kernel.  Skipping...

Building module:
cleaning build area...
&apos;make&apos; -j8 KVER=5.4.0-90-generic KSRC=/lib/modules/5.4.0-90-generic/build.............
Signing module:
Generating a new Secure Boot signing key:
Can&apos;t load /var/lib/shim-signed/mok/.rnd into RNG
139750728316224:error:2406F079:random number generator:RAND_load_file:Cannot open file:../crypto/rand/randfile.c:98:Filename=/var/lib/shim-signed/mok/.rnd
Generating a RSA private key
.................+++++
......................+++++
writing new private key to &apos;/var/lib/shim-signed/mok/MOK.priv&apos;
-----
 - /var/lib/dkms/8812au/5.6.4.2_35491.20191025/5.4.0-90-generic/x86_64/module/88XXau.ko
Secure Boot not enabled on this system.
cleaning build area...

DKMS: build completed.
dkms install -m 8812au -v 5.6.4.2_35491.20191025

88XXau.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.4.0-90-generic/updates/dkms/

depmod.......

DKMS: install completed.
dkms status
8812au, 5.6.4.2_35491.20191025, 5.4.0-90-generic, x86_64: installed
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;dkmsで入れたドライバを確認&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@lenovo:/home/matsu/rtl8812au# dkms status
8812au, 5.6.4.2_35491.20191025, 5.4.0-90-generic, x86_64: installed
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;USBデバイスを抜いて、挿すとこんな感じのメッセージが出てwlan0に割当されました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% dmesg
[ 2098.449336] usb 1-3: USB disconnect, device number 5
[ 2101.243660] usb 1-3: new high-speed USB device number 6 using xhci_hcd
[ 2101.418090] usb 1-3: New USB device found, idVendor=2357, idProduct=011e, bcdDevice= 2.00
[ 2101.418095] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2101.418098] usb 1-3: Product: 802.11ac WLAN Adapter
[ 2101.418100] usb 1-3: Manufacturer: Realtek
[ 2101.418101] usb 1-3: SerialNumber: 00e04c000001
[ 2101.493015] 88XXau: loading out-of-tree module taints kernel.
[ 2101.493536] 88XXau: module verification failed: signature and/or required key missing - tainting kernel
[ 2105.586166] usb 1-3: 88XXau 10:27:f5:09:2e:f7 hw_info[107]
[ 2105.631758] usbcore: registered new interface driver rtl88XXau
[ 2105.671189] rtl88XXau 1-3:1.0 wlx1027f5092ef7: renamed from wlan0
[ 2113.636088] IPv6: ADDRCONF(NETDEV_CHANGE): wlx1027f5092ef7: link becomes ready
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;nmcliから見られるようになりました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@lenovo:/home/matsu/rtl8812au# nmcli
wlx1027f5092ef7: disconnected
        &quot;TP-Link Wi-Fi&quot;
        wifi (rtl88XXau), 10:27:F5:09:2E:F7, hw, mtu 2312
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;nmtuiなどで設定して、activateします&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/11/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ip a&lt;/code&gt;コマンドで見るとつながっていることがわかります&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;7: wlx1027f5092ef7: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 2312 qdisc mq state UP group default qlen 1000
    link/ether 10:27:f5:09:2e:f7 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.114/24 brd 192.168.1.255 scope global dynamic noprefixroute wlx1027f5092ef7
       valid_lft 3552sec preferred_lft 3552sec
    inet6 240f:78:8153:1::2/128 scope global dynamic noprefixroute
       valid_lft 3555sec preferred_lft 1755sec
    inet6 240f:78:8153:1:8f:8b35:3766:78df/64 scope global temporary dynamic
       valid_lft 288sec preferred_lft 288sec
    inet6 240f:78:8153:1:7c53:4137:36ac:2635/64 scope global dynamic mngtmpaddr noprefixroute
       valid_lft 288sec preferred_lft 288sec
    inet6 fe80::b191:e8c0:2c47:7f85/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Ubuntu 21.10で複数NICを1つのネットワークに繋げる設定</title><link>https://blog.teraren.com/posts/ubuntu-21-10-multiple-nic/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ubuntu-21-10-multiple-nic/</guid><description>Ubuntu 21.10で複数NICを1つのネットワークに繋げる設定</description><pubDate>Fri, 05 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ubuntu 20系よりroute周りの設定を細かく書かないとエラーになってしまうので以下のように修正。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;** (generate:289522): WARNING **: 01:36:28.530: `gateway4` has been deprecated, use default routes instead.
See the &apos;Default routes&apos; section of the documentation for more details.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;内容は&lt;code&gt;gateway4&lt;/code&gt;というセクションがDeprecatedになったので&lt;code&gt;routes&lt;/code&gt;に定義してね。と。&lt;/p&gt;
&lt;p&gt;今まではgateway4にデフォルトゲートウェイのアドレスを記載するだけでしたが、metricなどを記載する必要があります。まぁ、routeテーブルをより明確に書き換えるための詳細化です。&lt;/p&gt;
&lt;p&gt;ということで、以下のような感じで記載しました。metricは低いほうが高プライオリティ。&lt;/p&gt;
&lt;p&gt;それでもまだ、ちょっとネットワークを切断、接続したときのrouteテーブルの書き換えが変になる動作があるので運用には要注意という感じです。&lt;/p&gt;
&lt;p&gt;L2までが安定していて変化がなければ気にしないで良いと思います。&lt;/p&gt;
</content:encoded></item><item><title>Ubuntu 21.10にアップグレードしましたが2つ問題が発生</title><link>https://blog.teraren.com/posts/ubuntu-21-10-upgrade/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ubuntu-21-10-upgrade/</guid><description>Ubuntu 21.10へのアップグレード後にX Window systemが勝手に起動した問題とlvm2削除によるブート不能を順に解決した記録</description><pubDate>Wed, 27 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;処理自体は簡単です。今までと同じようにUbuntuの場合は以下のコマンドだけでアップグレードできます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo apt update
$ sudo apt upgrade
$ sudo do-release-upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/10/image.png&quot; alt=&quot;Ubuntu 21.10&quot; /&gt;&lt;/p&gt;
&lt;p&gt;アップグレードは正常に終了。&lt;/p&gt;
&lt;p&gt;この後は、rebootしてちゃんと起動することを確認すれば作業が終了します。&lt;/p&gt;
&lt;p&gt;しかしながら、問題はこのあと起きます。&lt;/p&gt;
&lt;h2&gt;問題1&lt;/h2&gt;
&lt;p&gt;なぜかrebootしたあとにはX-window systemが一通り入っていて、runlevelが上がってしまいました。サーバー用途のためCUIしか使っていないので不要です。。。謎すぎます。&lt;/p&gt;
&lt;p&gt;なので、runlevelを落とします。Ubuntuは以下のコマンドでCUIになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo systemctl set-default multi-user.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;それに伴って、X Window system関連のパッケージを削除します。以下のコマンドで削除できると書いてありますが、Gnome関連などのGUIアプリは依存関係がないらしくて消えません。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo apt-get remove xserver-xorg-core
$ sudo apt-get autoremove -y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;aptitudeをわざわざインストールしてそれっぽいパッケージを抜いていきます。そして、再起動しました。&lt;/p&gt;
&lt;h3&gt;追記&lt;/h3&gt;
&lt;p&gt;別のほとんど追加パッケージを入れていないUbuntu 20 ServerにてUbuntu21へのアップグレードを試したら、この問題は起きませんでした。おそらくなにかのパッケージの依存関係が変わってしまったのだろうと予想します。&lt;/p&gt;
&lt;p&gt;問題1が発生しなければ問題2も発生しないです。&lt;/p&gt;
&lt;h2&gt;問題2&lt;/h2&gt;
&lt;p&gt;今度は別の問題が発生しました。起動中に、ディスクが見つからないと言うエラーがでました。対処法はWeb上では様々な方法がでてきます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Gave up waiting for root device. Common problems:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kudzu.hatenablog.com/entry/20151102/1446416115&quot;&gt;https://kudzu.hatenablog.com/entry/20151102/1446416115&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;結局は、lvm2のパッケージが消えたことが原因でした。&lt;/p&gt;
&lt;p&gt;Grubの選択肢のときにeを押してブート方法を選ぶページに行って、1つ前に入れたkernelを選択して起動。（recovery modeではない）&lt;/p&gt;
&lt;p&gt;それでも同様に起動はしませんが、kernelは動くのでshellが動くのと/sbinなどには管理ツールが充実しています。&lt;/p&gt;
&lt;p&gt;いろいろ調べていると、lvmのパッケージが依存関係で消えてしまうことがあるらしいので、lvmのパッケージを入れ直せば運が良ければ起動するとのことだったのでインストールして対処します。&lt;/p&gt;
&lt;p&gt;確かに、lvm関連のコマンドが一切存在していませんでしたが、このインストール後には利用できるようになりました。どこの領域にインストールされているのか謎なのは依然として残りますが。。。lvmをマウントできていないから/sbinや/usr/sbinとかにアクセスできないはずなのに。。。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt update
# apt install lvm2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このあと、再起動をしたらちゃんと起動しました。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;/var/log/dpkg.log を漁ってみましたが、lvm2が消えたログが見当たりませんでした。&lt;/p&gt;
&lt;p&gt;色々謎は残りますが復帰できてよかったです。&lt;/p&gt;
</content:encoded></item><item><title>Rails + MySQL 8でngramを用いたfulltext index</title><link>https://blog.teraren.com/posts/rails-mysql-ngram-fulltext/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-mysql-ngram-fulltext/</guid><description>RailsのmigrationでMySQL 8のngramパーサを使った日本語全文検索インデックスを作成する方法とパフォーマンス測定結果</description><pubDate>Tue, 19 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Railsのmigrationで普通にfulltext indexを付ける場合には以下のようにすると思いますが、普通のfulltext indexではngramが使われないので日本語の全文検索をする場合には全然マッチしません。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class AddNormalFullText &amp;lt; ActiveRecord::Migration[6.1]
  def change
    add_index :corporations, :name, :type =&amp;gt; :fulltext
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ngramのindexをつけるためには以下のように手でmigrationの内容を書く感じです。&quot;ft_index&quot;は自分でつけるindexの名称なので適当に付けてOK。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class AddNgramFullText &amp;lt; ActiveRecord::Migration[6.1]
  def up
    execute &apos;CREATE FULLTEXT INDEX ft_index ON corporations  (name) WITH PARSER ngram&apos;
  end
  def down
    execute &apos;ALTER TABLE corporations DROP INDEX ft_index&apos;
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;show create tableをすれば、以下のようなindexが作られることが確認できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FULLTEXT KEY `ft_index` (`name`) /*!50100 WITH PARSER `ngram` */
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;MySQL 5.7系でも同じだと思います。&lt;/p&gt;
&lt;p&gt;パフォーマンスはなんか、いまいちです。平均約10文字のカラムに対して500万レコードを対象にindexを張りました。2件を抽出するために3秒位かかりました。&lt;/p&gt;
&lt;p&gt;別の語句で試したら0.5秒以内には返ってきたりします。&lt;/p&gt;
&lt;p&gt;ngram周りのパラメータはデフォルトです。&lt;/p&gt;
</content:encoded></item><item><title>ミラーサーバの取りやめの連絡</title><link>https://blog.teraren.com/posts/stop-mirrorring/</link><guid isPermaLink="true">https://blog.teraren.com/posts/stop-mirrorring/</guid><description>ミラーサーバの取りやめの連絡</description><pubDate>Tue, 05 Oct 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;以下の2サイトを停止致します。&lt;/p&gt;
&lt;p&gt;ミラー元のサービスが停止したことにより、テラレン！でのミラーリングを終了致します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mirrors.teraren.com&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;※ 元の「dotdebのミラーリングを開始」記事は削除済み&lt;/p&gt;
</content:encoded></item><item><title>SHARP ヘルシオ ホットクックがWi-Fiにつながらない問題を解決</title><link>https://blog.teraren.com/posts/2021-09-26-hot-cooki-wifi/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2021-09-26-hot-cooki-wifi/</guid><description>ヘルシオ ホットクックKN-HW24FがWi-Fiに接続できない問題の解決法。WiFiルーターの暗号化をWPA2からWPAに変更したら即接続できた。</description><pubDate>Sun, 26 Sep 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ホットクックの型番はKN-HW24F&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B08JYHRFR4&quot;}&lt;/p&gt;
&lt;p&gt;WPSボタン経由、COCORO HOMEアプリ経由でも何回頑張っても接続できなかったです。&lt;/p&gt;
&lt;p&gt;使っているWiFiアクセスポイントは、こちら。&lt;/p&gt;
&lt;p&gt;TP-Link WiFi ルーター WiFi6 PS5 対応 無線LAN 11ax AX5400 4804 Mbps (5 GHz) + 574 Mbps (2.4 GHz) OneMesh対応 メーカー保証３年 Archer AX73/A&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B08RDHHS6Z&quot;}&lt;/p&gt;
&lt;p&gt;ちなみにWebで書かれている以下の確認ポイントはもちろん全部クリア済み。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;2.4GHz帯 WPA2&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ホットクック側のWiFi設定削除&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;アプリの削除、インストール&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;WiFiアクセスポイントのもともとの設定はこちらです。セキュリティ重視の一番安全な設定です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/09/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ホットクックのような日本のメーカーが作るIoT機器は載っている計算リソースやハードウェアが最低限だろうから、対応しているWiFiの暗号化セットが古いものしか対応していないだろうという仮説のもと、WiFiアクセスポイントの対応暗号化のレベルを下げました。&lt;/p&gt;
&lt;p&gt;WiFiアクセスポイント上で以下のように暗号化設定を変更して、WPSボタンを使って接続をしたらあっさりと１回目で接続できました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/09/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WPA2系の暗号化の場合は接続できなく、WPA系の暗号化では接続できるようになりました。ホットクックはWPA2には非対応のようです。&lt;/p&gt;
&lt;h2&gt;その後&lt;/h2&gt;
&lt;p&gt;何度やってもWiFiが繋がらなかったので無線LANに接続しないで利用しようかとも考えていましたが、頑張ってWiFiを繋げてよかったです。&lt;/p&gt;
&lt;p&gt;COCOROアプリ上でレシピを検索して、そのレシピを使うためにアプリ上からボタン1発でホットクックへそのレシピに必要なメニューを追加できるようになるのが便利です。&lt;/p&gt;
&lt;p&gt;また、調理が完了したらアプリ上に通知が来るようになります。（これは別に不要だったのでオフにしました）&lt;/p&gt;
</content:encoded></item><item><title>このBlogのホスティングを自宅サーバからLightsailに移行しました</title><link>https://blog.teraren.com/posts/wordpess-lightsail-php8/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpess-lightsail-php8/</guid><description>RAIDカード故障を機に自宅サーバからAWS Lightsail（月5ドル）へWordPressブログを移行。PHP8対応とLet&apos;s Encryptの設定、実際の運用負荷とベンチマークも公開。</description><pubDate>Tue, 31 Aug 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宅サーバで運用していましたが、Raidカードが壊れてOSが起動できなくなってしまいました。&lt;/li&gt;
&lt;li&gt;調達にも時間がかかるので、取り急ぎデータをサルベージしてどこかで動かす必要がありました。&lt;/li&gt;
&lt;li&gt;Lightsailが安いのでこの際に移行してしまいます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;選んだインスタンス&lt;/h2&gt;
&lt;p&gt;Disk容量が足りなくて一番低い3.5USD/monthのインスタンスでは乗り切りませんでした。それでも月5ドルは安いです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aws.amazon.com/jp/lightsail/pricing/&quot;&gt;https://aws.amazon.com/jp/lightsail/pricing/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/08/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;理想は、ACMやらロードバランサを付けておきたいのですがそれらをつけるとコストが普通に高くなってしまうのでこのインスタンスだけでなんとか運用します。定期スナップショットも取れるし自宅よりインフラ面（電源、回線、ハードウェアなど）が安定しているので安全です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WordPressでできたBlogを10個ぐらい乗せる&lt;/strong&gt;のでOSはAmazon Linux 2を使ってゼロからセットアップします。（WordPressのインスタンスから作ると余計なものが色々入ってきてしまうので）&lt;/p&gt;
&lt;p&gt;コストがかからないことを最優先にするのでMySQLも同居させます。&lt;/p&gt;
&lt;p&gt;ついでに、&lt;strong&gt;PHP8にも移行&lt;/strong&gt;しました。WordPressのテーマやプラグインで最近の更新が止まっているものはエラーが出てしまっているので、綺麗サッパリ消して諦めました。主要なプラグインやテーマはPHP8に基本的に対応しています。&lt;/p&gt;
&lt;p&gt;もちろんIPv6対応です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/08/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;SSL/TLS対応はLet&apos;s Encryptを手動でセットアップしました。&lt;/p&gt;
&lt;h2&gt;1ヶ月ほど運用した結果&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/08/image-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WordPressで運用している記事数が数万件のサービスは乗せられそうにありませんでした。MySQLのDisk I/Oがボトルネックになりました。&lt;/p&gt;
&lt;p&gt;プロセスレベルのリソースはこんな感じ。WordPressの&lt;a href=&quot;https://ja.wordpress.org/plugins/comet-cache/&quot;&gt;Comet Cache&lt;/a&gt;を使っているので基本的にはスカスカです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/08/image-1-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;lightsailを運用する上で気をつけないといけないことは、burstを使い切ってしまうと超遅くなってしまうことです。現時点ではあんまり問題無さそうです。日中がちょっと負荷が上がっている時間がありますが、まだ気にしないで良いかなと思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/09/image-3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/09/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;なんか遅いけど。同じregionのlightsailインスタンスから行って居て、Average: 0.1203 secs。Comet cacheでは、0.00320secでserveしてるっぽいんだけどね。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/09/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;静的ファイルに対してのベンチマークでは、約100倍ほど速いAverage: 0.0018 secsでした。OSのリソースの使用状況を見ているとPHPとnginxのCPUオーバーヘッドが大きいような感じがしています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/09/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Comet Cacheが効いていないのかと思って、外してみたらAverage: 3.8090 secsとなりとても遅くなりました。Comet Cacheは効いているようです。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;EC2だと個人Blogを運用するにはコストがちょっと気になりますが、Lightsailだと月$5で運用できます。もっとトラフィックや容量が少なければ$3.5/月でも十分です。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;余談ですが、&lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;郵便番号検索サービス&lt;/a&gt;のほうもLightsailに移行しました。$3.5/monthで運用しています。記事は後日。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自宅サーバーはファイルサーバとしてメインで使い、ディスクIOや容量を使うサービスは自宅サーバで運用します。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Amazon Linux 2, Amazon Linux 2023のTimezone変更</title><link>https://blog.teraren.com/posts/qiita-20210730-f71e964da833812b1a56/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20210730-f71e964da833812b1a56/</guid><description>現在が UTC で表示されているかを確認します。</description><pubDate>Fri, 30 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Amazon Linux 2 で Timezone を変更する方法を記載しておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;現在が UTC で表示されているかを確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-10-0-0-141 ssm-user]# date
Fri Jul 29 15:18:56 UTC 2021
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;timedatedctlコマンド経由で変更します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-10-0-0-141 ssm-user]# timedatectl set-timezone Asia/Tokyo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;crondに対しても変更を反映するために再起動しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-10-0-0-141 ssm-user]# systemctl restart crond.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;JSTで表示されるかを確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-10-0-0-141 ssm-user]# date
Fri Jul 30 00:20:56 JST 2021
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;補足&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;/etc/sysconfig/clock&lt;/code&gt; ファイルは存在していないようです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-10-0-0-141 ssm-user]# cat /etc/sysconfig/clock
cat: /etc/sysconfig/clock: No such file or directory
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Amazon Linux 2のTimezone変更</title><link>https://blog.teraren.com/posts/amazon-linux2-timezone/</link><guid isPermaLink="true">https://blog.teraren.com/posts/amazon-linux2-timezone/</guid><description>現在が UTC で表示されているかを確認します。</description><pubDate>Thu, 29 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Amazon Linux 2 で Timezone を変更する方法を記載しておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;現在が UTC で表示されているかを確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-10-0-0-141 ssm-user]# date
Fri Jul 29 15:18:56 UTC 2021
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;timedatedctlコマンド経由で変更します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-10-0-0-141 ssm-user]# timedatectl set-timezone Asia/Tokyo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;crondに対しても変更を反映するために再起動しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-10-0-0-141 ssm-user]# systemctl restart crond.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;JSTで表示されるかを確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-10-0-0-141 ssm-user]# date
Fri Jul 30 00:20:56 JST 2021
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;補足&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;/etc/sysconfig/clock&lt;/code&gt; ファイルは存在していないようです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@ip-10-0-0-141 ssm-user]# cat /etc/sysconfig/clock
cat: /etc/sysconfig/clock: No such file or directory
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Embody Chairのキャスター交換で8,000円節約 | 汎用品で代替可能</title><link>https://blog.teraren.com/posts/2021-07-16-embody-chair-2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2021-07-16-embody-chair-2/</guid><description>Herman Miller Embody Chairのキャスターが破損。純正品は2,000円×5個で10,000円ですが、Amazonの汎用ゴムキャスターで8,000円削減。交換方法と選び方のポイントを解説。</description><pubDate>Fri, 16 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最近、椅子の近くにプラスチックの破片が落ちていたので、椅子のどこかが崩壊しているのかと思っていました。3日目にやっと破損箇所を発見しました。&lt;/p&gt;
&lt;p&gt;なんと、Embody Chair（Herman Miller製のエルゴノミクスチェア）のキャスター部分が崩壊してきています。&lt;/p&gt;
&lt;h2&gt;この記事について&lt;/h2&gt;
&lt;h3&gt;学べること&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Embody Chairのキャスター破損の状況と原因&lt;/li&gt;
&lt;li&gt;純正品と汎用品のコスト比較&lt;/li&gt;
&lt;li&gt;Amazonで購入できる代替キャスターの選び方&lt;/li&gt;
&lt;li&gt;キャスター交換の簡単な手順&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;想定読者&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Embody Chairのキャスターが破損して困っている方&lt;/li&gt;
&lt;li&gt;純正品より安価にキャスター交換したい方&lt;/li&gt;
&lt;li&gt;高級チェアのメンテナンスに興味がある方&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;前提条件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;特別な工具は不要（引き抜くだけで交換可能）&lt;/li&gt;
&lt;li&gt;推定所要時間: 5分&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題の発見&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/07/IMG_9437.jpeg&quot; alt=&quot;破損したキャスター&quot; /&gt;&lt;/p&gt;
&lt;p&gt;キャスターのプラスチック部分が経年劣化で崩壊してきています。&lt;/p&gt;
&lt;h2&gt;コスト比較&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://store.hermanmiller.co.jp/c/refurbishedservice/accessories_service_parts/category241670/241670&quot;&gt;Herman Miller公式サイト&lt;/a&gt;でキャスターの価格を確認したところ、1個あたり約2,000円です。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;選択肢&lt;/th&gt;
&lt;th&gt;価格&lt;/th&gt;
&lt;th&gt;メリット&lt;/th&gt;
&lt;th&gt;デメリット&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;純正キャスター&lt;/td&gt;
&lt;td&gt;10,000円（2,000円×5個）&lt;/td&gt;
&lt;td&gt;動作保証、色合い一致&lt;/td&gt;
&lt;td&gt;高価&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;汎用キャスター&lt;/td&gt;
&lt;td&gt;2,000円前後（5個セット）&lt;/td&gt;
&lt;td&gt;大幅なコスト削減&lt;/td&gt;
&lt;td&gt;色合い・サイズが若干異なる可能性&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;5個交換すると10,000円になってしまうため、汎用品で代替できないか検討します。また、10年後に再び壊れることを考えると、コストパフォーマンスの良い選択肢を探したいところです。&lt;/p&gt;
&lt;h2&gt;汎用キャスターの選定&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/07/image.jpg&quot; alt=&quot;純正キャスターの詳細&quot; /&gt;&lt;/p&gt;
&lt;p&gt;よく見ると、このキャスターは汎用品のようなので、Amazonで類似品を探すことにしました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;選定ポイント&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;フローリングで使用するため、傷つきにくいゴムタイプを選択&lt;/li&gt;
&lt;li&gt;差込式（11mm穴径）に対応していること&lt;/li&gt;
&lt;li&gt;車輪直径は純正品に近いサイズ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B08TCCNFWZ&quot;}&lt;/p&gt;
&lt;h2&gt;交換作業&lt;/h2&gt;
&lt;h3&gt;キャスター比較&lt;/h3&gt;
&lt;p&gt;翌日、購入したキャスターが届いたので、純正品と比較してみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/07/IMG_9444.jpeg&quot; alt=&quot;純正品（左）と汎用品（右）の比較&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;気づいた点&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;汎用品（右）は純正品より一回り大きい&lt;/li&gt;
&lt;li&gt;色合いが純正品（黒）に対して、汎用品はグレーで若干異なる&lt;/li&gt;
&lt;li&gt;ダブルホイール（2輪）タイプを選択&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;交換手順&lt;/h3&gt;
&lt;p&gt;キャスターの交換は非常に簡単です。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;椅子を横にして、古いキャスターを引き抜く&lt;/li&gt;
&lt;li&gt;新しいキャスターを差し込む&lt;/li&gt;
&lt;li&gt;5個すべて交換する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;所要時間&lt;/strong&gt;: 約5分&lt;/p&gt;
&lt;h3&gt;交換後の様子&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/07/IMG_9445.jpeg&quot; alt=&quot;交換完了後の椅子&quot; /&gt;&lt;/p&gt;
&lt;p&gt;全てのキャスターを交換しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/07/IMG_9446.jpeg&quot; alt=&quot;横から見た様子&quot; /&gt;&lt;/p&gt;
&lt;p&gt;色の違いは想定よりも目立ちます。真っ黒ではなく、グレーがかった色合いです。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;h3&gt;ダブルホイール vs シングルホイール&lt;/h3&gt;
&lt;p&gt;今回はダブルホイール（2輪）タイプを選びましたが、これにはいくつか理由があります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ダブルホイールを選んだ理由&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;体重が2つのタイヤに分散されるため、破損リスクが低い&lt;/li&gt;
&lt;li&gt;安定性が高い&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;シングルホイール（1輪）の選択肢&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;デザイン性の高い製品が多い&lt;/li&gt;
&lt;li&gt;より一般的で選択肢が豊富&lt;/li&gt;
&lt;li&gt;Embody Chairのスタイルには合うかもしれない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;どちらを選ぶかは、耐久性重視かデザイン重視かで判断すると良いでしょう。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;コスト削減&lt;/strong&gt;: 純正品10,000円 → 汎用品2,000円で&lt;strong&gt;8,000円の節約&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;所要時間&lt;/strong&gt;: 約5分（工具不要）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;動作&lt;/strong&gt;: 問題なく使用可能、静音性も良好&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注意点&lt;/strong&gt;: 色合いが純正品と異なる（気になる場合は純正品推奨）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;耐久性&lt;/strong&gt;: 今後の使用で検証予定&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;汎用品でも十分に代替可能です。コストパフォーマンスを重視する方にはおすすめの選択肢です。&lt;/p&gt;
</content:encoded></item><item><title>rsync over sshをAWS Session manager経由で使う設定方法</title><link>https://blog.teraren.com/posts/rsync-over-ssh-on-aws-session-manager/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rsync-over-ssh-on-aws-session-manager/</guid><description>パブリックIPなしのEC2にAWS Session Manager経由でrsyncを実行するためのIAMポリシーとSSH設定の手順を詳解</description><pubDate>Fri, 16 Jul 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;要件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager.html&quot;&gt;AWS Systems Manager Session Manager&lt;/a&gt; （以降AWS Session Manager）経由でEC2インスタンスにログインする。&lt;/li&gt;
&lt;li&gt;AWS Session Manager経由でログインするとssm-userでログインされてしまうが、IAMごとに別のユーザでログインする。&lt;/li&gt;
&lt;li&gt;rsync over sshできる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a href=&quot;https://gist.github.com/matsubo/37941e7ee8243c9440639c8b9f1f8168#%E5%89%8D%E6%8F%90&quot;&gt;&lt;/a&gt;前提となる環境&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;AWS Session Managerがセットアップ済み&lt;/li&gt;
&lt;li&gt;利用するregionにおいて、 &lt;code&gt;Enable Run As support for Linux instances&lt;/code&gt; にチェックが入っている
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ap-northeast-1.console.aws.amazon.com/systems-manager/session-manager/preferences?region=ap-northeast-1#&quot;&gt;https://ap-northeast-1.console.aws.amazon.com/systems-manager/session-manager/preferences&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/07/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;&lt;a href=&quot;https://gist.github.com/matsubo/37941e7ee8243c9440639c8b9f1f8168#aws%E4%B8%8A%E3%81%A7%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E8%BF%BD%E5%8A%A0&quot;&gt;&lt;/a&gt;AWS上でのIAM設定&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;policyを作成する。
&lt;ul&gt;
&lt;li&gt;policyレベルでユーザを指定したい場合は、TagsにSSMSessionRunAsを追加してValueにユーザ名を指定する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特定のインスタンスにSession Manager経由でログインできるようにする例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Sid&quot;: &quot;VisualEditor0&quot;,
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Action&quot;: &quot;ssm:StartSession&quot;,
            &quot;Resource&quot;: [
                &quot;arn:aws:ssm:*:*:document/AWS-StartSSHSession&quot;,
                &quot;arn:aws:ec2:ap-northeast-1:*:instance/i-xxxxxxxxxxxxxxxx&quot;
            ]
        },
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Action&quot;: [
                &quot;ssm:DescribeSessions&quot;,
                &quot;ssm:GetConnectionStatus&quot;,
                &quot;ssm:DescribeInstanceProperties&quot;,
                &quot;ssm:DescribeInstanceInformation&quot;,
                &quot;ec2:DescribeInstances&quot;
            ],
            &quot;Resource&quot;: &quot;*&quot;
        },
        {
            &quot;Sid&quot;: &quot;VisualEditor1&quot;,
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Action&quot;: &quot;ssm:TerminateSession&quot;,
            &quot;Resource&quot;: &quot;arn:aws:ssm:*:*:session/${aws:username}-*&quot;
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;個人のIAMアカウントを作成する
&lt;ul&gt;
&lt;li&gt;上で作ったpolicyをattachする。&lt;/li&gt;
&lt;li&gt;IAMユーザレベルでshellアカウントを指定する場合は&lt;code&gt;**SSMSessionRunAs**タグを設定して、値にログインさせたいsshアカウントを指定する&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ログイン先端末での設定&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;公開鍵をログインしたいホスト上のログインさせたいユーザのauthorized_keysに登録しておく。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ログイン元端末での設定&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;必須プログラム
&lt;ul&gt;
&lt;li&gt;aws-cli&lt;/li&gt;
&lt;li&gt;aws session manager plugin&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aws configure&lt;/code&gt; などを使ってcredentialを設定ファイルに記述しておく&lt;/li&gt;
&lt;li&gt;AWS Session managerを使ってi-xxxxxxxxxxxxxxxxにssh接続テストしてみる
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;aws ssm start-session --target i-xxxxxxxxxxxxxxxx&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;~/.ssh/config&lt;/code&gt; へ以下の設定を追加する
&lt;ul&gt;
&lt;li&gt;もし、複数のprofileを使っている場合は &lt;code&gt;AWS_PROFILE&lt;/code&gt; 環境変数に設定してsshコマンド経由でも同じawsのcredentialを使うように注意する必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;host i-* mi-*
    ProxyCommand sh -c &quot;aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters &apos;portNumber=%p&apos;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;sshコマンドで接続してみる
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ssh username@i-xxxxxxxxxxxxxxxx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;SSMSessionRunAsで設定したユーザ名を指定する必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;rsyncコマンド経由でファイルを転送してみる
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rsync -aruzv -e ssh &amp;lt;source&amp;gt; &amp;lt;username&amp;gt;@i-xxxxxxxxxxxxxxxxx:&amp;lt;destination&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;rsyncをする場合はAWS Session Managerの設定と、sshの設定の両方が必要になる。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>zipコマンドでmacosのDSStoreやIconファイルを除外して圧縮</title><link>https://blog.teraren.com/posts/zip-macos-dsstore-icon/</link><guid isPermaLink="true">https://blog.teraren.com/posts/zip-macos-dsstore-icon/</guid><description>zipコマンドでmacosのDSStoreやIconファイルを除外して圧縮</description><pubDate>Wed, 30 Jun 2021 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;zip -r output.zip  directory -x &apos;*/.DS_Store&apos; -x &apos;*Icon*&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Windowsの人が解凍すると「なにこれ？」と毎回聞かれるので。&lt;/p&gt;
</content:encoded></item><item><title>テレカンするとCPU利用率が高くなる→熱暴走の保護機能が発動している</title><link>https://blog.teraren.com/posts/cpu-high-load-caused-by-heat-issue/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cpu-high-load-caused-by-heat-issue/</guid><description>MacBook ProでテレカンのたびにCPU負荷が急上昇する原因を追究し、熱による保護機能の発動と冷却グリス劣化が原因と特定した調査記録</description><pubDate>Fri, 11 Jun 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;症状&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;最近、Google Hangoutなどでテレカンを始めると、CPU利用率が徐々に高まっていき、最終的にはUI操作のレスポンスがすごく遅くなります。&lt;/li&gt;
&lt;li&gt;しかも、USB-DACを経由して音声を出力していると、音割れがひどくなります。ヘッドフォンを使っていると問題無いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/06/image-1-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ちなみに、2.4 GHz 8-Core Intel Core i9のMacbook Proです。&lt;/p&gt;
&lt;h2&gt;考えられる問題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ChromeのWebRTCを使ったときに、処理がおかしくて、どんどん変なCPU処理が増えていく？
&lt;ul&gt;
&lt;li&gt;ブラウザを変更しても再現するし、ならないときはある。&lt;/li&gt;
&lt;li&gt;再起動すると直るような気はする。&lt;/li&gt;
&lt;li&gt;Chromeのメジャーバージョンが上がっても全然解決しない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;熱暴走？
&lt;ul&gt;
&lt;li&gt;CPUコアの温度表示は60度程度なのでそんなに熱くないと思う。&lt;/li&gt;
&lt;li&gt;コンパイルなどの重い処理をしているときには特に問題にならない。（結局はこれはテレカンに比べれば短時間だからそこまで発熱しない）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ホコリが溜まっている？
&lt;ul&gt;
&lt;li&gt;まだ買って1年しか経っていないし、エアーダスターで掃除したけど改善せず。&lt;/li&gt;
&lt;li&gt;さすがに、ファンが回りまくっているのでエアーダスターを使ったらホコリが結構出てきました。&lt;/li&gt;
&lt;li&gt;分解すれば色々わかるのでしょうが、保証が効かなくなるので今回は分解はしない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ハードウェア的におかしい？
&lt;ul&gt;
&lt;li&gt;SMCリセット、NVRAMリセットをしたけど解決しない。&lt;/li&gt;
&lt;li&gt;個人用macbook proでもこの現象は再現するので違う気がする。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;電源を左に挿しているから？
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://apple.stackexchange.com/questions/363337/how-to-find-cause-of-high-kernel-task-cpu-usage/363933#363933&quot;&gt;macbook pro 2019年モデルは、左にUSB-Cで給電すると発熱するという報告がある。。。&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;私の場合は、右に挿しても変化が感じられなかった。。。&lt;/li&gt;
&lt;li&gt;kernel_taskプロセスが食っている感じはしない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;外部モニタを使っていて、GPU起因？
&lt;ul&gt;
&lt;li&gt;単独で使用すれば多少改善した感じがするけど、外部モニタを使えないのは辛すぎるので、あまりちゃんとトラブルシュートするのは辛い。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;クラムシェルで使っているから？
&lt;ul&gt;
&lt;li&gt;クラムシェルじゃなくすれば、少しは緩和するような感じはしたけど、すぐにCPU使用率が高まる問題は発生する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;気になる数字を発見&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://bjango.com/mac/istatmenus/&quot;&gt;iStat Menu&lt;/a&gt;を使ってシステムモニタリングをしています。そこで気づいたのですが、なぜかCPU周波数が1GHz。。。。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CPU温度は低いのに周波数が低いことを見つけました&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/06/image.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;OSがハードウェアを熱暴走から保護する機能が働いているような挙動です。&lt;/p&gt;
&lt;p&gt;そこで、一応、&lt;strong&gt;扇風機でクーリングをした結果、CPUのクロック数が低くならなくなりました。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/06/Pasted_Image_2021_06_11_14_15.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;扇風機で冷やしている様子。見た目はダサいが、&lt;strong&gt;これで問題は解決された&lt;/strong&gt;。背に腹は代えられない。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/06/image-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ということで、こういうのを買えば解決する。&lt;/p&gt;
&lt;p&gt;プライムデー前に買うか考え中。→買ったけど、ほんの少し改善したかんじです。根本的に発熱が大きすぎます。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B089KCW43Q&quot;}&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;なかなかトラブルシューティングが大変でしたが、熱暴走ということがわかりました。&lt;/li&gt;
&lt;li&gt;iStats menuを使っていない場合は問題に気づけなかった気がします。これから夏にかけて温度が上がっていくのでクロック数は注意したほうが良いです。&lt;/li&gt;
&lt;li&gt;今後、問題に気づきやすいように重要数値を確認しやすくしました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/06/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ファンの回転の制御を自動だったのを手動にして最大にしてみました。（左右で最大回転数が違うんですね）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/06/image-1-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;テレカン中には、Chromeの負荷が高くなるのはもちろんのこと、&lt;a href=&quot;https://ref.krisp.ai/u/ud40cc5747&quot;&gt;krisp&lt;/a&gt;（ノイズキャンセリングをソフトウェアでやるやつ）もそこそこCPUを食うことがわかります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/06/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;追記：2021年7月6日&lt;/h2&gt;
&lt;p&gt;もう、熱問題の原因箇所がわからなすぎで困ってましたが、PCを20cmぐらいの高さから落としてしまったときにホコリの粉がファンの出口からドバっって出てきたからブロワーでは取り切れないホコリがありそうなことがわかりました。&lt;/p&gt;
&lt;p&gt;自分で分解するのは怖いのでGenius Barに行ってホコリを除去してもらいました。ホコリは堆積していたみたいですが冷却に影響するほどでは無かったそうです。SMC, PRAMとNVRAMのリセットが勝手に行われている感じはしました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Apple Storeの人にはクリーンインストールをおすすめされました。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;そして、ホコリを除去してもらった後のテレカン時のファン稼働はこちら。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/07/image-6.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ホコリを除去して貰う前と比較して変化はほとんどありませんでした。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;世界中で問題になっている&lt;/h2&gt;
&lt;p&gt;こちらのスレが一番情報がまとまっていますが、解決方法は無さそうです。。。。&lt;/p&gt;
&lt;p&gt;https://www.reddit.com/r/macbookpro/comments/ekh86o/macbook_pro_16_heat_issues_with_external_monitor/&lt;/p&gt;
&lt;h2&gt;追記: この問題の解決を諦めてM1を買いました&lt;/h2&gt;
&lt;p&gt;買ったのはこちらのMacBook Pro 14inch M1 Pro&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/04/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;M1では全然熱くなりません！&lt;/p&gt;
&lt;p&gt;ファンすら回りません。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/04/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/04/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Amazon Lightsailは初期立ち上げは楽だけど運用が辛い</title><link>https://blog.teraren.com/posts/amazon-lightsail-os-upgrade-failure/</link><guid isPermaLink="true">https://blog.teraren.com/posts/amazon-lightsail-os-upgrade-failure/</guid><description>Amazon LightsailのWordPress環境でdo-release-upgradeを実行後にSSH接続不能になった失敗談。bitnamiとOSの密結合が原因で、OSアップグレードは不可能と判断しインスタンス再構築で対処。</description><pubDate>Mon, 31 May 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2年前ぐらいに Lightsailで立ち上げたWordPressサイトがありました。&lt;/li&gt;
&lt;li&gt;アプリケーション、ミドルウェア、OSを一通り最新にしようとしましたが、無理だったのでインスタンスを作り直しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ふと確認すると、WordPress本体が最新は5.7.2なのに対して、5.4系でした。&lt;/li&gt;
&lt;li&gt;phpも7.2だったので3ヶ月前にサポートが切れてしまっていました。&lt;/li&gt;
&lt;li&gt;Ubuntu 16.02 LTS。最新は20なのでメジャーバージョンが2つ低い。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;行った手順&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WordPress本体、プラグイン、テーマはwpコマンド経由で更新できました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cyberciti.biz/faq/aws-lightsail-upgrade-ubuntu-16-04-lts-to-18-04-lts/&quot;&gt;このあたりの記事&lt;/a&gt;を参考に普通にdo-release-upgradeをして、&lt;strong&gt;&lt;a href=&quot;https://www.cyberciti.biz/faq/aws-lightsail-upgrade-ubuntu-16-04-lts-to-18-04-lts/&quot;&gt;再起動をかけたらsshで繋がらなくなりました&lt;/a&gt;&lt;/strong&gt;。もちろんWebのコンソールも以下のエラーメッセージが出て繋がりません。。。。万事休す。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;UPSTREAM_NOT_FOUND [519]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;調べてみると、回避手段は、スタートアップスクリプトで、&lt;a href=&quot;https://community.bitnami.com/t/ssh-not-working-post-upgrade-to-ubuntu-18-04-from-16-04-aws-lightsail/76827&quot;&gt;sshを停止して起動するというすごいワークアラウンドを実施する必要が有るらしいです。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;bitnamiのページに書いてあるので、bitnamiのアプリケーション周りが怪しい挙動をしているのだと思います。bitnami自体は、OSのバージョンと密接に関連づいているはずなのでこのような不可解な事象が起きるのかと思います。&lt;/p&gt;
&lt;p&gt;再度、スナップショットから復元してアップデートをかけるのはとても大変なので諦めて、最新のlightsail wordpressを立てて、wordpressのDB、themeファイル、htdocs以下のコピーを使って復元しました。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Lightsailの立ち上げは楽だし、運用は最低なら$3/monthなのでとても良いけど、長期運用をするには辛い。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OSやミドルウェアの最新追随は不可能と考え&lt;/strong&gt;て、1年か2年おきぐらいに&lt;strong&gt;インスタンスの載せ替え&lt;/strong&gt;をするような運用をする必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;余談&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;LightsailのDNSはトラフィックが少なければ無料です。大体、1.1request/secなら無料なので殆どの場合はこれでまかなえるような気がします。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q: Lightsail DNS 管理にかかるコストはどれくらいですか?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Lightsail 内での DNS 管理は無料です。最大 3 つの DNS ゾーンを作成でき、各ゾーンのレコード数は無制限です。また、全ゾーンで 1 か月あたり 300 万 DNS クエリを利用できます。1 か月のクエリ数が最初の 300 万を超えると、0.40 USD/100 万 DNS クエリの料金が適用されます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://aws.amazon.com/jp/lightsail/faq/&quot;&gt;https://aws.amazon.com/jp/lightsail/faq/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;LightsailのDNSは、動的にLightsailのインスタンスへ向けられるので、Lightsail + LightsailのDNSを使う組み合わせに留めるレベルのシステムなら最適なソリューションです。
&lt;ul&gt;
&lt;li&gt;ロードバランサ(18USD/month)を使っていくと値段が普通に高くなっていくのであまりLightsailの魅力が無くなってきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>郵便番号APIサイトのデータソースをzipcloudに変更</title><link>https://blog.teraren.com/posts/postcode-api-master-change/</link><guid isPermaLink="true">https://blog.teraren.com/posts/postcode-api-master-change/</guid><description>運営中の郵便番号検索APIで、郵便局公式データからzipcloudのデータソースへ切り替えた理由と差分比較。京都府の正規化や丁目表記の変更点をvimdiffで解説。</description><pubDate>Sun, 25 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;私が運営している&lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;郵便番号検索APIサイト&lt;/a&gt;にて、今までは、郵便局が提供していたデータを加工して利用していましたが、それでは追いつかないぐらい正規化されていない項目が多いため自分でメンテナンスするより他社がしっかりメンテナンスしているデータを使ったほうがユーザメリットが大きいと判断しました。&lt;/li&gt;
&lt;li&gt;このたび、&lt;a href=&quot;http://zipcloud.ibsnet.co.jp/&quot;&gt;zipcloud&lt;/a&gt;が提供するデータに差し替えました。&lt;/li&gt;
&lt;li&gt;左が郵便局が提供しているデータ、右がzipcloudが提供しているデータのvimdiffです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/04/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;変更点を見てみる&lt;/h2&gt;
&lt;p&gt;vimdiffで見ていって、目立った変更点をピックアップしてみます。&lt;/p&gt;
&lt;p&gt;まず、丁目の表記が消えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/04/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;1行に複数の住所が入っているレコードは、2行に分割されます。しかしながら、当方のサイトでは1つの郵便番号に対して一意の住所を返却したいので1行目の方だけを採用します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/04/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;京都府のマスタと呼べないような記述の部分はこのように正規化されます。&lt;/p&gt;
&lt;p&gt;もともと1郵便番号に対して複数行でしたが、2倍位の行数に増えています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/04/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://postcode.teraren.com/about&quot;&gt;不具合ありましたらご連絡願います。&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;差分は大きいですが、郵便番号から住所を求めるというユースケースにおいては&lt;strong&gt;zipcloudのデータのほうが綺麗なので問題無さそうです。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>分割されていない電話番号から市外局番と市内局番の求め方</title><link>https://blog.teraren.com/posts/split-area-code/</link><guid isPermaLink="true">https://blog.teraren.com/posts/split-area-code/</guid><description>分割されていない電話番号から市外局番と市内局番の求め方</description><pubDate>Thu, 15 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;分割されていない電話番号から、市内局番や市外局番を求めたい。
&lt;ul&gt;
&lt;li&gt;0292323011 =&amp;gt; 029-232-3011&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/daddyz/phonelib&quot;&gt;phonelib&lt;/a&gt;が良さそう。&lt;/li&gt;
&lt;li&gt;phonelibは&lt;a href=&quot;https://github.com/googlei18n/libphonenumber&quot;&gt;Google libphonenumber&lt;/a&gt;のデータをもとにしている。&lt;/li&gt;
&lt;li&gt;日本の市外局番マスタはPDFで提供されていて辛い。。。。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.soumu.go.jp/main_content/000141817.pdf&quot;&gt;https://www.soumu.go.jp/main_content/000141817.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google libphonenumberはこの内容もちゃんとアップデートされている模様。&lt;/li&gt;
&lt;li&gt;これの悲しいのは、桁数で明確に市内局番が別れていないことです。市内局番が例えば、137と1377が存在します。なので、最長一致でマッチングする必要があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/04/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;実装&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;irb&amp;gt; require &apos;phonelib&apos;
irb&amp;gt; Phonelib.default_country = &quot;JP&quot;
irb&amp;gt; Phonelib.parse(&apos;0292323011&apos;).national.split(&apos;-&apos;)
=&amp;gt; [&quot;029&quot;, &quot;232&quot;, &quot;3011&quot;]
irb&amp;gt; Phonelib.parse(&apos;0292323011&apos;).area_code
=&amp;gt; &quot;29&quot;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>tableau serverのホスト名が変わってしまったときの対処法</title><link>https://blog.teraren.com/posts/tableau-server-certificate-error/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tableau-server-certificate-error/</guid><description>AWS EC2でTableau Serverをサブネットをまたいでインスタンスをリプレースするとホスト名変更でSSL証明書エラーが発生する問題の回避策。hostnamectl set-hostnameで旧ホスト名を強制設定して解消。</description><pubDate>Wed, 14 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Tableau serverをAWS EC2で運用しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;インスタンスを落として、別のsubnetで起動したらtableau serverがちゃんと動かなくなってしまった。&lt;/li&gt;
&lt;li&gt;具体的には、Webからアクセスできない。tsmコマンドを打つとエラーになる。&lt;br /&gt;
&lt;code&gt;% tsm status   Unable to verify the server&apos;s HTTPS certificate.&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;以下のcertificate checkを無視するオプションを付けても変化なし。&lt;br /&gt;
&lt;code&gt;% tsm status --accepteula&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;大量にエラーが出力され続ける。&lt;br /&gt;
&lt;code&gt;sudo tail -f /var/opt/tableau/tableau_server/data/tabsvc/**/*&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;対処法&lt;/h2&gt;
&lt;p&gt;hostnamectl set-hostnameを使って古いインスタンスのホスト名を無理やり設定する。その後、インスタンスのリブートをします。&lt;/p&gt;
&lt;p&gt;以下がコマンド例。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo hostnamectl set-hostname ip-xxx-xxx-xxx-xxx.ap-northeast-1.compute.internal
sudo reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;本来のやり方&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;落とす前にtsmコマンド経由でbackupファイルを作成する&lt;/li&gt;
&lt;li&gt;新規ホストでtableau serverをクリーンインストール&lt;/li&gt;
&lt;li&gt;backupファイルを復元&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;h3&gt;tsm関連&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;tableauのtsmコマンドは、裏でhttpsで通信している&lt;/li&gt;
&lt;li&gt;https serverはself signedなSSL証明書を使っている&lt;/li&gt;
&lt;li&gt;tsmコマンドはself signedなSSL証明書だったら認証が通る。しかしながら、ホスト名が変わるとSSL証明書のホスト名と不一致になるので通らなくなる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;tableau server関連&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;内部でセットアップ時のホスト名を保持している様子。よってホスト名が変更されると正常に動かなくなる。&lt;/li&gt;
&lt;li&gt;今回は無理やり前回のホスト名に合わせることで対処&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>自宅LinuxサーバにUPS(無停電電源装置)導入</title><link>https://blog.teraren.com/posts/ups/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ups/</guid><description>APC RS 550をLinuxサーバに接続し、apcupsdデーモンで停電時の自動シャットダウンを設定するまでの物理・ソフトウェア両面のセットアップ手順</description><pubDate>Wed, 14 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;UPSが1万5000円ぐらいなのでこのblogが動いているLinuxサーバに導入してみました。&lt;/li&gt;
&lt;li&gt;UPSとは、「Uninterruptible Power Supply」の略で、日本語では「無停電電源装置」と訳します。&lt;/li&gt;
&lt;li&gt;APC RS 550 BR550S-JP Eを買いました。あまり商品リサーチはしてません。APCは老舗なのでまぁ、安心かなと。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B06XHZ3K5T&quot;}&lt;/p&gt;
&lt;h2&gt;物理的なセットアップ&lt;/h2&gt;
&lt;p&gt;まず最初に、UPSの蓋を開けてバッテリーのケーブルを接続します。&lt;strong&gt;初期状態ではケーブルが外れた状態&lt;/strong&gt;になっています。バイクのバッテリーみたいな電池が入ってました。&lt;/p&gt;
&lt;p&gt;そして、こんな感じに適当にケーブルを接続してセットアップ。&lt;/p&gt;
&lt;p&gt;残り時間は27分と出ています。&lt;/p&gt;
&lt;p&gt;サーバであんまり電力消費しないはずなのに想定より短い感じです。今回は常時70Wぐらい使われています。&lt;a href=&quot;/posts/ups-mac-mini-apc-rs-400/&quot;&gt;mac miniでは5wしか消費&lt;/a&gt;されていなかたのに全然違う。。。&lt;/p&gt;
&lt;p&gt;付属のUSBケーブルでUPSと接続しておきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/04/image.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ソフトウェア設定&lt;/h2&gt;
&lt;p&gt;apcupsdというデーモンで管理します。これによって、UPSの電池が切れそうになったらLinuxが自動的にシャットダウンされます。&lt;/p&gt;
&lt;p&gt;aptで入るのでインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; sudo apt install apcupsd
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  apcupsd-doc
Suggested packages:
  apcupsd-cgi
The following NEW packages will be installed:
  apcupsd apcupsd-doc
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 532 kB of archives.
After this operation, 1,743 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://ftp.riken.jp/Linux/ubuntu focal/universe amd64 apcupsd-doc all 3.14.14-3build1 [328 kB]
Get:2 http://ftp.riken.jp/Linux/ubuntu focal/universe amd64 apcupsd amd64 3.14.14-3build1 [204 kB]
Fetched 532 kB in 3s (212 kB/s)
Selecting previously unselected package apcupsd-doc.
(Reading database ... 256476 files and directories currently installed.)
Preparing to unpack .../apcupsd-doc_3.14.14-3build1_all.deb ...
Unpacking apcupsd-doc (3.14.14-3build1) ...
Selecting previously unselected package apcupsd.
Preparing to unpack .../apcupsd_3.14.14-3build1_amd64.deb ...
Unpacking apcupsd (3.14.14-3build1) ...
Setting up apcupsd (3.14.14-3build1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/apcupsd.service → /lib/systemd/system/apcupsd.service.
Setting up apcupsd-doc (3.14.14-3build1) ...
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for systemd (245.4-4ubuntu3.6) ...
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = &quot;en_US:en&quot;,
        LC_ALL = (unset),
        LC_CTYPE = &quot;UTF-8&quot;,
        LC_COLLATE = &quot;C&quot;,
        LC_TERMINAL = &quot;iTerm2&quot;,
        LANG = &quot;C&quot;
    are supported and installed on your system.
perl: warning: Falling back to the standard locale (&quot;C&quot;).
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = &quot;en_US:en&quot;,
        LC_ALL = (unset),
        LC_CTYPE = &quot;UTF-8&quot;,
        LC_COLLATE = &quot;C&quot;,
        LC_TERMINAL = &quot;iTerm2&quot;,
        LANG = &quot;C&quot;
    are supported and installed on your system.
perl: warning: Falling back to the standard locale (&quot;C&quot;).
 23 files changed, 816 insertions(+)
 create mode 100755 apcupsd/apccontrol
 create mode 100644 apcupsd/apcupsd.conf
 create mode 100755 apcupsd/changeme
 create mode 100755 apcupsd/commfailure
 create mode 100755 apcupsd/commok
 create mode 100644 apcupsd/hosts.conf
 create mode 100755 apcupsd/killpower
 create mode 100644 apcupsd/multimon.conf
 create mode 100755 apcupsd/offbattery
 create mode 100755 apcupsd/onbattery
 create mode 100755 apcupsd/ups-monitor
 create mode 100644 default/apcupsd
 create mode 100755 init.d/apcupsd
 create mode 120000 init.d/ups-monitor
 create mode 120000 rc0.d/K01apcupsd
 create mode 120000 rc1.d/K01apcupsd
 create mode 120000 rc2.d/S01apcupsd
 create mode 120000 rc3.d/S01apcupsd
 create mode 120000 rc4.d/S01apcupsd
 create mode 120000 rc5.d/S01apcupsd
 create mode 120000 rc6.d/K01apcupsd
 create mode 120000 systemd/system/multi-user.target.wants/apcupsd.service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;インストール直後は勝手にデーモンが立ち上がって稼働しだします。初期設定を1つもしていないのに。。。&lt;/p&gt;
&lt;p&gt;私の環境の場合、1つだけ追加で設定するだけで最低限の動作はします。DEVICEの行をコメントアウトするだけでした。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# DEVICE /dev/ttyS0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;その後は、デーモンの再起動をします。&lt;code&gt;sudo systemctl restart apcupsd&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;単独でAPCのUPSを使う場合はこれだけでよしなに動いてくれます。&lt;/p&gt;
&lt;h2&gt;設定されているパラメータを確認&lt;/h2&gt;
&lt;p&gt;apctestコマンドでステータスを表示できるかと思いきや、デーモンが立ち上がっている場合はこのコマンドは使えないよです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; sudo apctest
[sudo] password for matsu:
2021-04-13 18:08:20 apctest 3.14.14 (31 May 2016) debian
Checking configuration ...
sharenet.type = Network &amp;amp; ShareUPS Disabled
cable.type = USB Cable
mode.type = USB UPS Driver
apctest FATAL ERROR in apctest.c at line 311
Unable to create UPS lock file.
  If apcupsd or apctest is already running,
  please stop it and run this program again.
apctest error termination completed
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;代わりに、apcaccessというコマンドを利用します。これを使えばデーモン経由で情報を取得してくるみたいです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo apcaccess
APC      : 001,036,0850
DATE     : 2024-06-30 15:47:11 +0000
HOSTNAME : gmk
VERSION  : 3.14.14 (31 May 2016) debian
UPSNAME  : gmk
CABLE    : USB Cable
DRIVER   : USB UPS Driver
UPSMODE  : Stand Alone
STARTTIME: 2024-06-30 15:42:16 +0000
MODEL    : APC RS 550S
STATUS   : ONLINE
LINEV    : 105.0 Volts
LOADPCT  : 13.0 Percent
BCHARGE  : 96.0 Percent
TIMELEFT : 39.3 Minutes
MBATTCHG : 5 Percent
MINTIMEL : 3 Minutes
MAXTIME  : 0 Seconds
SENSE    : Medium
LOTRANS  : 82.0 Volts
HITRANS  : 123.0 Volts
ALARMDEL : No alarm
BATTV    : 13.5 Volts
LASTXFER : No transfers since turnon
NUMXFERS : 0
TONBATT  : 0 Seconds
CUMONBATT: 0 Seconds
XOFFBATT : N/A
SELFTEST : NO
STATFLAG : 0x05000008
SERIALNO : 4B2033P28395
BATTDATE : 2020-08-16
NOMINV   : 100 Volts
NOMBATTV : 12.0 Volts
NOMPOWER : 330 Watts
FIRMWARE : 941.c6 .A USB FW:c6
END APC  : 2024-06-30 15:47:24 +0000
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;設定ファイルの確認&lt;/h2&gt;
&lt;p&gt;設定ファイルのパラメータを覗いてみます。ファイルは /etc/apcupsd/apcupsd.conf にあります。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;UPSCABLE usb&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;UPSとの通信を何で行っているかです。USBなのでそのままでOK。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;BATTERYLEVEL 5&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;電池の残りが5%になったらshutdown -hを実行するということ。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;MINUTES 3&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;電池の残りが3分以下になったらshutdown -hを実行するということ。上記とor条件かなと思います。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ANNOY 300&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;シャットダウンの300秒前から、broadcastメッセージを出してユーザにログアウトを促す。&lt;/p&gt;
&lt;h2&gt;停電のテスト&lt;/h2&gt;
&lt;p&gt;商用電源を抜き差ししてみます。&lt;/p&gt;
&lt;p&gt;流石にシャットダウンされては困るので短時間抜き差ししてみます。&lt;/p&gt;
&lt;p&gt;抜いてみたときのログ。/var/log/syslog&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Apr 13 17:06:20 dell apcupsd[18732]: Power failure.
Apr 13 17:06:26 dell apcupsd[18732]: Running on UPS batteries.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同時にメールがrootに飛びます。&lt;/p&gt;
&lt;p&gt;商用電源を復帰させたときのログ&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Apr 13 17:06:55 dell apcupsd[18732]: Mains returned. No longer on UPS batteries.
Apr 13 17:06:55 dell apcupsd[18732]: Power is back. UPS running on mains.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Mackerelから各種指標を監視する&lt;/h2&gt;
&lt;p&gt;gistにコードを書いておきました。&lt;/p&gt;
&lt;p&gt;https://gist.github.com/matsubo/764666d00d25f2a53b505292c9a7c501&lt;/p&gt;
</content:encoded></item><item><title>CSVデータをActiveRecordにimportする際における各手法のベンチマーク</title><link>https://blog.teraren.com/posts/csv-activerecord-import/</link><guid isPermaLink="true">https://blog.teraren.com/posts/csv-activerecord-import/</guid><description>RailsでCSVをDBへインポートするActiveRecord・Hash・insert・bulk insertの4パターンを12万件の郵便番号データで速度比較し最適解を導出</description><pubDate>Sun, 21 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;RubyにおいてCSVデータをDBに挿入する際の手法による速度の違いをベンチマーク&lt;/li&gt;
&lt;li&gt;CSVデータのインポート処理は業務系のWebアプリケーションを構築する際にはほぼ必ず必要となる機能なので感覚地として掴んでおくことが目的です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ベンチマーク対象のアプリケーション&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;郵便番号のAPIを提供しているサービス&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;https://postcode.teraren.com/&lt;/a&gt; のデータ洗い替えの処理&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.post.japanpost.jp/zipcode/download.html&quot;&gt;郵便局のサイト&lt;/a&gt;から、郵便番号データと、事業所のデータをダウンロード&lt;/li&gt;
&lt;li&gt;importの処理流れ
&lt;ul&gt;
&lt;li&gt;郵便番号のデータで洗替&lt;/li&gt;
&lt;li&gt;郵便番号のデータを処理して、建物ごとに郵便番号をまとめて洗い替え&lt;/li&gt;
&lt;li&gt;事業所のデータを洗替&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;この処理を運用中のサービスでは月初に自動で行っています。&lt;/p&gt;
&lt;p&gt;Rails6でアプリケーションは書かれていますが、Rails5の場合も考慮してbulk insertには&lt;a href=&quot;https://github.com/zdennis/activerecord-import&quot;&gt;activerecord-import&lt;/a&gt;を使います。どちらを使ってもほぼ&lt;a href=&quot;https://simple-minds-think-alike.hatenablog.com/entry/rails_bulk_insert&quot;&gt;速度は変わらない&lt;/a&gt;ようです。&lt;/p&gt;
&lt;p&gt;データ量は、郵便番号のデータが124,568レコード、事業所のデータが22,371レコードです。&lt;/p&gt;
&lt;p&gt;Ruby 3.0.0 + Rails 6.1.3&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;データをインポートする際に、どの程度抽象的なプログラミングを行うかがキーになってきます。低レイヤーで書けば書くほど速度は早いけど、ビジネスロジック上で面倒を見ないといけないことが多くなります。&lt;/p&gt;
&lt;p&gt;主に悩む選択肢は以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ActiveRecordオブジェクトをつかつか、Hashを使うか？ (ActiveRecord VS Hash)&lt;/li&gt;
&lt;li&gt;bulk insertを使うかどうか？ (insert VS bulk insert)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;それぞれのパターンで計測してみます。&lt;/p&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;以下のパターンでとりました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hash VS ActiveRecord&lt;/li&gt;
&lt;li&gt;insert VS bulk insert&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一応、比較のためにRails6のinsert_allのベンチマークも取ってみましたが、importよりかなり速いです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;activerecord-importはデフォルトでvalidateがかかりますが、ActiveRecord 6のinsert_allはvalidateは走りらないことが速度の差かと思います。DBへのアクセスが発生するようなvalidationは行っていませんが塵も積もれば山となる感じかと思います。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ActiveRecord VS Hashの結果
&lt;ul&gt;
&lt;li&gt;Hashのほうが20秒ぐらい速い。＝約22％速い。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;insert VS bulk insert
&lt;ul&gt;
&lt;li&gt;bulk insertのほうが約220秒速い。＝約74％速い。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意：前処理の時間（約10秒）を含んだベンチマークなので、実装コード部分だけで考えれば、上記の表記よりずっと速い。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;CSVをインポートする際は以下の組み合わせが一番速い
&lt;ul&gt;
&lt;li&gt;Hashの配列を作る&lt;/li&gt;
&lt;li&gt;Rails6のinsert_allを使う&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;もともとは110秒かかっていた処理を76秒にしました。＝約30％高速化。
&lt;ul&gt;
&lt;li&gt;おもな変更点は2つ。ActiveRecordのインスタンスを作るのをやめて、import gemをinsert_allに変更。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>TOPPING D10 USB DACのチップをOPA627AUに交換</title><link>https://blog.teraren.com/posts/topping-d10-usb-dac-opa627au/</link><guid isPermaLink="true">https://blog.teraren.com/posts/topping-d10-usb-dac-opa627au/</guid><description>TOPPING D10 USB DACのデフォルトオペアンプOPA2134PAをBurr-Brown製OPA627AUに換装した手順と注意点。逆向き装着で発熱した失敗談も紹介。</description><pubDate>Mon, 15 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今持っている、TOPPING D10というUSB DACはもとから評価が高くて良い品なのに加えて、オペアンプのチップを交換できるというすぐれものなので交換してみたいと思います。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B079HRGN5B&quot;}&lt;/p&gt;
&lt;p&gt;買ったチップはこちら。そっくりそのまま入れ替えられます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://store.shopping.yahoo.co.jp/nfj/o479.html&quot;&gt;Burr-Brown社製 OPA627AU 2回路DIP化オペアンプ完成基板 実装品 2,980円&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;もともと搭載されているのは&lt;a href=&quot;https://eleshop.jp/shop/g/gV2113F/&quot;&gt;OPA2134PA&lt;/a&gt;です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/IMG_7348.jpeg&quot; alt=&quot;OPA627AU&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こちらが交換をするTOPPING D10です。32bit 384kHzに対応するDACです。こんな良質な音源は手元にないので完全に活かしきれませんが。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/IMG_7349.jpeg&quot; alt=&quot;TOPPING D10&quot; /&gt;&lt;/p&gt;
&lt;p&gt;蓋を開けたところ。筐体と基盤を接着するボンドの処理が汚い。。。。ついでにきれいに掃除しておきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/IMG_7350.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;載せ替えたところ。以下の写真が正解の向き。&lt;/p&gt;
&lt;p&gt;向きがよくわからなかったので、最初は逆向きにつけて電源を入れたら、チップがものすごく熱くなってしまった。。。再度差し直したら音が鳴ったので大丈夫だったのかなと思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/IMG_7352.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;チップを入れ替えた結果は、よくわからないですね。音源が悪いからだと思います。&lt;/p&gt;
&lt;p&gt;スピーカーは&lt;a href=&quot;https://jp.yamaha.com/products/proaudio/speakers/msp_studio_series/index.html#d284563&quot;&gt;YAMAHA MSP5 Studio&lt;/a&gt;です。&lt;/p&gt;
</content:encoded></item><item><title>CloudWatchにrubyアプリケーションからログを投げる</title><link>https://blog.teraren.com/posts/cloudwatch-ruby/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cloudwatch-ruby/</guid><description>CloudWatchにrubyアプリケーションからログを投げる</description><pubDate>Fri, 12 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;しかし、投げまくっていると以下のような例外が出るので、Throttlingされてしまったらsleepする必要があります。そうなると全体としての処理パフォーマンスのボトルネックになってしまうので要注意です。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Aws::CloudWatchLogs::Errors::ThrottlingException Rate exceeded&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;CloudWatchに投げておけば後々の統計処理が楽になるので。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;それにしても、ログを送るだけなのにコードをいっぱい書かないといけないなぁ。。。&lt;/p&gt;
</content:encoded></item><item><title>ワンライナーでJSONをCSVに変換</title><link>https://blog.teraren.com/posts/json-to-csv/</link><guid isPermaLink="true">https://blog.teraren.com/posts/json-to-csv/</guid><description>ワンライナーでJSONをCSVに変換</description><pubDate>Wed, 10 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;リモートに有る郵便番号の一覧をJSONで取得して、必要なカラムだけを抽出してCSVファイルを作る方法です。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stedolan.github.io/jq/manual/&quot;&gt;jqコマンド&lt;/a&gt;を使えば、いかに上げる例以外の&lt;/p&gt;
&lt;p&gt;色々な集約や、構造の変更ができます。&lt;/p&gt;
</content:encoded></item><item><title>17013	 Generating access token for the SP failed</title><link>https://blog.teraren.com/posts/17013-generating-access-token-for-the-sp-failed/</link><guid isPermaLink="true">https://blog.teraren.com/posts/17013-generating-access-token-for-the-sp-failed/</guid><description>17013	 Generating access token for the SP failed</description><pubDate>Thu, 04 Mar 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Google Workspace =&amp;gt; Microsoft 365へのユーザ同期が失敗していました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Download listを押して、エラーの内容を確認すると「17013 Generating access token for the SP failed」と記載されていました。ググっても解決方法は見つかりませんでした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&quot;Reauthorize&quot;をクリックしたら裏で勝手に再同期がかかったようでエラーが消えて、ユーザ情報がMicrosoft側に同期されました。解決しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/03/image-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>郵便番号検索APIサービスをGraphQL対応しました</title><link>https://blog.teraren.com/posts/api-graphql-postcode/</link><guid isPermaLink="true">https://blog.teraren.com/posts/api-graphql-postcode/</guid><description>郵便番号検索APIサービスをGraphQL対応しました</description><pubDate>Sun, 07 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;郵便番号検索APIサービス&lt;/a&gt;において、GraphQLに対応しました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rmosolgo/graphql-ruby&quot;&gt;graphql&lt;/a&gt;を使い、paginationには &lt;a href=&quot;https://github.com/RenoFi/graphql-pagination&quot;&gt;graphql-pagination&lt;/a&gt;, &lt;a href=&quot;https://github.com/kaminari/kaminari/tree/master/kaminari-activerecord&quot;&gt;kaminari-activerecord&lt;/a&gt;を使っています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GET系だけなので特にハマりどころは無く、オフィシャルドキュメントを軽く読んで、数時間で構築できました。&lt;/li&gt;
&lt;li&gt;Typeの定義（REST APIでいうエンティティ）にアノテーションを少しするだけでドキュメントが自動生成されるのでドキュメンテーションが楽です。&lt;/li&gt;
&lt;li&gt;paginationのmetadataがデフォルトでレスポンスに含まれるような記述がありましたが、実際には何も出力されなかったです。&lt;/li&gt;
&lt;li&gt;N+1が発生しやすいので、その際は&lt;a href=&quot;https://buildersbox.corp-sansan.com/entry/2020/07/17/110000&quot;&gt;このあたり&lt;/a&gt;を参考にする。&lt;a href=&quot;https://github.com/Shopify/graphql-batch&quot;&gt;graphql-batch&lt;/a&gt;を使って手動でpreloadするらしい。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>AWS session managerのクライアント設定</title><link>https://blog.teraren.com/posts/aws-session-manager/</link><guid isPermaLink="true">https://blog.teraren.com/posts/aws-session-manager/</guid><description>AWS Session Managerで踏み台サーバ不要のSSH接続を実現するクライアント設定手順。ssh-over-ssmとssm-toolを使い、EC2インスタンスIDをわかりやすい名前でアクセスできるように設定。</description><pubDate>Fri, 05 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager.html&quot;&gt;AWS Session Manager&lt;/a&gt;を使うと踏み台サーバが不要になるのでサーバサイドは設定しました。&lt;/li&gt;
&lt;li&gt;クライアント側でわざわざEC2のinstance IDを指定するのが大変なのでかんたんにssh接続できるように設定します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定手順&lt;/h2&gt;
&lt;p&gt;同じ作者のshell scriptである、&lt;a href=&quot;https://github.com/elpy1/ssh-over-ssm&quot;&gt;ssh-over-ssm&lt;/a&gt;と&lt;a href=&quot;https://github.com/elpy1/ssm-tool&quot;&gt;ssm-tool&lt;/a&gt;を使います。接続のたびに、裏で勝手にsshのキーペアを作成してログインできるようにしてくれます。また、EC2のinstance idを人間がわかりやすい名前でアクセスできるように設定してくれます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ghq get git@github.com:elpy1/ssh-over-ssm.git
% cp ~/ghq/github.com/elpy1/ssh-over-ssm/ssh-ssm.sh ~/bin/
% ghq get git@github.com:elpy1/ssm-tool.git
% cp ~/ghq/github.com/elpy1/ssm-tool/ssm-tool ~/bin/
% pip3 install --user -r ~/ghq/github.com/elpy1/ssm-tool/requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;~/bin/にはpathを通しておきます。&lt;/p&gt;
&lt;p&gt;~/.aws/configと~/aws/credentials にIAMのcredentialを設定しておきます。&lt;/p&gt;
&lt;p&gt;aws cliをインストールしておきます。それに追加して、&lt;a href=&quot;https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html&quot;&gt;session manager plugin&lt;/a&gt;をインストールします。&lt;/p&gt;
&lt;p&gt;Ubuntuの場合は以下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl &quot;https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb&quot; -o &quot;session-manager-plugin.deb&quot;
% sudo dpkg -i session-manager-plugin.deb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;instance idとの関連付け定義ファイルを生成します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ssm-tool --ssh-conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のような設定ファイルが生成されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-19.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;あとは、わかり易い名前を指定するだけでsshでは入れます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ホストの一覧ファイルを作るのにひと手間かかりますが、fishであればホスト名の補完ができるようになるので楽です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;session managerを使ってかんたんにログインできるようにするツールを導入しました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>cyta.jpサービス終了に先立ち魚拓</title><link>https://blog.teraren.com/posts/cyta-jp-gyotaku/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cyta-jp-gyotaku/</guid><description>2007年から開発に携わったC2C教育プラットフォームcyta.jpのサービス終了を前に、開発史と技術的チャレンジを振り返る記録</description><pubDate>Tue, 02 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2007年頃〜2011年ごろまで私がシステムを開発していたサービスが終わるとのことです。&lt;/li&gt;
&lt;li&gt;ちょっと当時のアチーブメントを軽く振り返ってみます。&lt;/li&gt;
&lt;li&gt;せっかくなので魚拓しておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;振り返り&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;最初のコミット。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-17.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;時系列&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;フィージビリティスタディ
&lt;ul&gt;
&lt;li&gt;2009年のフルタイムでジョインするまでの2年間ぐらいは&lt;strong&gt;土日や平日の夜&lt;/strong&gt;を使って技術スキル向上&amp;amp;暇つぶしのために開発していました。&lt;/li&gt;
&lt;li&gt;報酬は&lt;strong&gt;ほぼ無償&lt;/strong&gt;で開発をやっていました。今からだと考えられないですね。当時はエンジニアの希少性がまだ低いときです。&lt;/li&gt;
&lt;li&gt;cytaeは&lt;strong&gt;C2Cのプラットフォーム&lt;/strong&gt;という形を取っていますが、最初のうちはnucleusというPHPでできたCMSで先生ひとりひとりのブログを構築していました。blogを普通に1つ立ち上げるのは大変なので、&lt;strong&gt;コマンド1発でブログを構築できるようなスーパバイザサービス&lt;/strong&gt;を作っていました。&lt;/li&gt;
&lt;li&gt;ビジネスが回ることがわかると、人力でやっていた作業を自動化する予約管理、授業料決済、報酬支払、フィードバックの仕組み、メッセージやり取り、ブログ機能などを一元的に開発するシステムが必要になってきました。&lt;/li&gt;
&lt;li&gt;毎週少しずつ開発は進めていましたが、流石に機能が多くて、土日の作業では土曜日に先週やっていたところを思い出し、日曜にプラスアルファの開発をするというような日々が続いていてとても効率が悪くなっていました。&lt;/li&gt;
&lt;li&gt;効率が悪くなったので副業ではなくフルタイムで開発することになります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;フルタイムで開発
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;給料が少なかったので家賃は半額のところへ引っ越しました。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;1つのプロダクトを集中して開発できる状態は今思えばとても良かったです。&lt;/li&gt;
&lt;li&gt;国内ではgitをいち早く導入した記憶があります。日本語の文献がなかったのでgitのオライリー英語本で学習していました。&lt;/li&gt;
&lt;li&gt;ポイント管理は結構先進的だったと思います。入金ごとに有効期限を管理したという要求がありました。当時はANAのマイル管理ぐらいしかこの方法での管理をしていなかったと思います。なぜなら、設計と実装が難しいからです。普通のシステムは、最終ポイント利用から1年といったロジックで実装されています。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;その後
&lt;ul&gt;
&lt;li&gt;なんか自分の思ったようなサービスの成長がなかった&amp;amp;戦略が見えなかったので見切りをつけGREEへ。&lt;/li&gt;
&lt;li&gt;cookpadに買収され、crowdworksに買収され、サービス停止が決定しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;いま振り返ってみると
&lt;ul&gt;
&lt;li&gt;このサービスを当時は、&lt;strong&gt;私とバイト数名でDevOps&lt;/strong&gt;していたのは今から考えるとなかなかすごいかも。&lt;/li&gt;
&lt;li&gt;約10年前に書いたコードが現役で動き続けているのはすごい。&lt;/li&gt;
&lt;li&gt;deployはgit pullだけなので数秒で終わるし、サーバはVPSで運用していたので月に5,000円ぐらい。最強に安価だしライトウェイトな運用システムでした。&lt;/li&gt;
&lt;li&gt;講師は全員面接をしていたので、高品質でした。私自身もサービスを使い3人のコーチと出会いました。各コーチは自分の人生にとって重要な価値観や示唆を与えてくれました。今でも連絡を取り合っている人も居ます。&lt;/li&gt;
&lt;li&gt;そういえば、自分も講師としてシステムコンサルをしていました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;信用は重要&lt;/strong&gt;ということを学ぶ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;魚拓&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;感想&lt;/h2&gt;
&lt;p&gt;当時、お世話になったお二方のコーチに頂いたアドバイスはその後ずっと人生で生きています。この方々に出会わなければ多少なりとも価値観や生き方が変わっていたと思います。&lt;/p&gt;
&lt;p&gt;マンツーマンだからこそ、自分に最適なアドバイスをくれるし、自分もちゃんと受け入れると思います。金額がちょっと高いですが有意義なことに使えばすぐにペイするぐらいです。むしろ、教える人にとってちょっと割安すぎる感があるような感じなので。&lt;/p&gt;
&lt;p&gt;個人的には社会的意義のあるサービスだったなぁと思います。&lt;/p&gt;
</content:encoded></item><item><title>ActiveRecordでネストされたトランザクションのRollback方法</title><link>https://blog.teraren.com/posts/activerecord-transaction-nest/</link><guid isPermaLink="true">https://blog.teraren.com/posts/activerecord-transaction-nest/</guid><description>ActiveRecordでトランザクションをネストした際にRollbackが意図通りに動作しない原因と、requires_new オプションを使った正しい排他制御の実装方法を解説します。</description><pubDate>Mon, 01 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ActiveRecordでトランザクションを入れ子にするケースがあり、ActiveRecordのトランザクションの処理を追ってみるとなかなか興味深かったので文章にまとめておきます。&lt;/li&gt;
&lt;li&gt;おそらく、この内容を知っておかないと排他制御を考慮したクラス設計、実装ができないと思う。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;以下のようなコードがあったときに、1つ目のセンテンスである&apos;Kotori&apos;と&apos;Nemu&apos;が作られます。（一見、一切コミットされないように思えるかもしれませんが）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;User.transaction do
  User.create(username: &apos;Kotori&apos;)
  User.transaction(requires_new: true) do
    User.create(username: &apos;Nemu&apos;)
    raise ActiveRecord::Rollback
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;こんなコードは普通は書きませんが、クラスが別れていたり、実装するレイヤーが分かれている場合に不用意に発行されてしまう可能性があります。
&lt;ul&gt;
&lt;li&gt;例えば、振替というビジネスロジックに対して残高の加算や減算の処理。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;原因&lt;/h2&gt;
&lt;h3&gt;理由&lt;/h3&gt;
&lt;p&gt;ActiveRecordのtransactionはActiveRecord::Rollbackをraiseしないために起きます。&lt;/p&gt;
&lt;p&gt;該当のコードはこちら。（現時点のmainブランチの最新です。v6.1.1の半月ぐらい先くらいのコード）&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/rails/rails/blob/e9d997a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb#L313&quot;&gt;https://github.com/rails/rails/blob/e9d997a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb#L313&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;      def transaction(requires_new: nil, isolation: nil, joinable: true)
        if !requires_new &amp;amp;&amp;amp; current_transaction.joinable?
          if isolation
            raise ActiveRecord::TransactionIsolationError, &quot;cannot set isolation when joining a transaction&quot;
          end
          yield
        else
          transaction_manager.within_new_transaction(isolation: isolation, joinable: joinable) { yield }
        end
      rescue ActiveRecord::Rollback
        # rollbacks are silently swallowed
      end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;1回目のtransaction呼び出しは、transaction_manager.within_new_transactionが実行されますが、2回めのtransaction呼び出しは普通にyieldされるだけになります。（transaction開始時にオプションを指定していない場合）&lt;/p&gt;
&lt;p&gt;よって、beginが発行されません。また、そのyieldで発行されたRollbackは、rescue ActiveRecord::Rollbackによって捕捉されて中身は何もしていません。&lt;/p&gt;
&lt;p&gt;参考までに、within_new_transactionのコード。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/rails/rails/blob/e9d997a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb#L313&quot;&gt;https://github.com/rails/rails/blob/e9d997a/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb#L313&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;      def within_new_transaction(isolation: nil, joinable: true)
        @connection.lock.synchronize do
          transaction = begin_transaction(isolation: isolation, joinable: joinable)
          ret = yield
          completed = true
          ret
        rescue Exception =&amp;gt; error
          if transaction
            rollback_transaction
            after_failure_actions(transaction, error)
          end
          raise
        ensure
          if !error &amp;amp;&amp;amp; transaction
            if Thread.current.status == &quot;aborting&quot;
              rollback_transaction
            else
              if !completed &amp;amp;&amp;amp; transaction.written
                ActiveSupport::Deprecation.warn(&amp;lt;&amp;lt;~EOW)
                  Using `return`, `break` or `throw` to exit a transaction block is
                  deprecated without replacement. If the `throw` came from
                  `Timeout.timeout(duration)`, pass an exception class as a second
                  argument so it doesn&apos;t use `throw` to abort its block. This results
                  in the transaction being committed, but in the next release of Rails
                  it will rollback.
                EOW
              end
              begin
                commit_transaction
              rescue Exception
                rollback_transaction(transaction) unless transaction.state.completed?
                raise
              end
            end
          end
        end
      end
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ネストされたブロックだけロールバックしたい場合&lt;/h3&gt;
&lt;p&gt;まず、回答としてはできます。&lt;/p&gt;
&lt;p&gt;前提として&lt;strong&gt;殆どのデータベースはネストされたトランザクションをサポートしていません。&lt;a href=&quot;https://api.rubyonrails.org/v6.1.0/classes/ActiveRecord/Transactions/ClassMethods.html#module-ActiveRecord::Transactions::ClassMethods-label-Nested+transactions&quot;&gt;MS-SQLだけ&lt;/a&gt;のようです。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;**MySQLなどのRDBではsavepointを使ってエミュレートしています。**よって、細かい例外条件や細かい注意事項が出てきます。&lt;/p&gt;
&lt;p&gt;やり方は、savepointを使うためにネストされたtransaction呼び出し時に、requires_new: trueを追加します。これによって、savepointが発行されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;User.transaction do
  User.create(username: &apos;Kotori&apos;)
  User.transaction(requires_new: true) do
    User.create(username: &apos;Nemu&apos;)
    raise ActiveRecord::Rollback
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記のコードを実行すると、Kotoriだけが保存されます。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;h3&gt;1. requires_new: trueを全部に付ける&lt;/h3&gt;
&lt;p&gt;では、全部requires_new: trueをつければ、なんとなくプログラマーの意図通りに動いてくれるだろうからそれで良いのかもしれません。これはこれで、**1つの解ではあるかもしれません。しかしながら、RDBMSごとに実装が異なったり、savepointを使って、部分的にrollbackされたときのロック範囲について考えながらコードレビューするのは大変かと思います。**静的チェックもできないですし。&lt;/p&gt;
&lt;h3&gt;2. DB transactionを1つにまとめる&lt;/h3&gt;
&lt;p&gt;transactionブロックが分散してしまうのであれば、transactionを1箇所で管理するとtransactionのnestを発行させないようにできます。&lt;/p&gt;
&lt;p&gt;前提として、ビジネスロジックレイヤーを整理しておく必要があります。なぜなら、どのレイヤー（ビジネスロジック、ユーティリティクラス、ORMなど）でDBのtransactionを使うかを明確にする必要があり、けっこう大変かと思います。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class TransactionScript
  def self.process(&amp;amp;block)
    ActiveRecord::Base.transaction do
      yield
    mary.deposit(100)
  end
end

TransactionScript.process do
  subtract
  add
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この方法では、静的チェックも可能です。デメリットとしては、transactionを使うときには呼び出しコードをブロックで実行しなければいけないので、インデントが深くなるのとコード量が増えます。&lt;/p&gt;
&lt;h3&gt;3. raise ActiveRecord::Rollbackしない&lt;/h3&gt;
&lt;p&gt;一見、このルールを作ったらコーディングの自由度が減るから嫌うかと思いますが、現場では&lt;strong&gt;raise ActiveRecord::Rollbackを書く必要は無い&lt;/strong&gt;と思います。&lt;/p&gt;
&lt;p&gt;サンプルコードで、ネストされたブロックでraise ActiveRecord::Rollbackをしていますが、サンプルでしかありえない書き方かと思います。本来ならば独自の例外をraiseするはずなので全体が失敗するようなコードになります。&lt;/p&gt;
&lt;p&gt;例えば以下のようになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;User.transaction do
  User.create(username: &apos;Kotori&apos;)
  User.transaction do
    User.create(username: &apos;Nemu&apos;)
    raise MyOriginalError
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これならば全体で失敗しますし、外側のブロックから見たら全体で失敗すべきなので問題ないです。&lt;/p&gt;
&lt;p&gt;そもそも、raise ActiveRecord::Rollbackを発行する際というのは、そのtransactionブロックの中で何かしら問題が起きて、その問題を上位に伝搬せずに対処するという時にしか使わないはずです。そのようなケースが思いつかないです。&lt;/p&gt;
&lt;p&gt;このアプローチならば、コードの静的チェックも可能になり、運用しやすいです。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ActiveRecordのtransactionを使ったときのネストの挙動を追ってみました。&lt;/li&gt;
&lt;li&gt;3番めの運用法が良さそうです。&lt;/li&gt;
&lt;li&gt;その挙動とうまくやり合うために、クリアに持続可能な運用をするアプローチを提案しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://api.rubyonrails.org/v6.1.0/classes/ActiveRecord/Transactions/ClassMethods.html#module-ActiveRecord::Transactions::ClassMethods-label-Nested+transactions&quot;&gt;https://api.rubyonrails.org/v6.1.0/classes/ActiveRecord/Transactions/ClassMethods.html#module-ActiveRecord::Transactions::ClassMethods-label-Nested+transactions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rails/rails/blob/main/activerecord/lib/active_record/transactions.rb&quot;&gt;https://github.com/rails/rails/blob/main/activerecord/lib/active_record/transactions.rb&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://techracho.bpsinc.jp/hachi8833/2018_03_16/53811&quot;&gt;https://techracho.bpsinc.jp/hachi8833/2018_03_16/53811&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>PC版GREEの魚拓</title><link>https://blog.teraren.com/posts/pc-gree/</link><guid isPermaLink="true">https://blog.teraren.com/posts/pc-gree/</guid><description>PC版GREEの魚拓</description><pubDate>Mon, 01 Feb 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;https://x.com/4GamerNews/status/1356172192329818115&lt;/p&gt;
&lt;p&gt;魚拓撮っとく。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本番テストのためにたくさんガチャを引いたなぁ。。。&lt;/p&gt;
</content:encoded></item><item><title>EC2ホストのログをCloudWatch Logsに集約</title><link>https://blog.teraren.com/posts/ec2-cloudwatch-logs/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ec2-cloudwatch-logs/</guid><description>Amazon Linux 2とUbuntuのEC2インスタンスで、OSログやApacheログをCloudWatch Logsへ集約するawslogsの設定手順をまとめています。</description><pubDate>Sun, 31 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/var/log/messages&lt;/code&gt; などのOSのログ、&lt;code&gt;/var/log/httpd/access.log&lt;/code&gt; などのサーバ・ソフトウェアのログをCloudWatch Logsに集約します。設定はかんたんです。&lt;/li&gt;
&lt;li&gt;EC2インスタンスやContainerなどの計算資源は使い捨てですが、ログだけは監査などのために保管しておきたいため一通り設定しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;ssm-agentを使っていない場合は、ssm-agentを設定しておいたほうが良いです。（AWS Access keyでの認証もできますが、面倒だし少しセキュアではないので）&lt;/p&gt;
&lt;h3&gt;Amazon Linux 2の場合&lt;/h3&gt;
&lt;p&gt;設定は楽です。&lt;a href=&quot;https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/QuickStartEC2Instance.html&quot;&gt;こちらの公式ドキュメント&lt;/a&gt;を参考にインストールすればOKです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo yum install -y awslogs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;/etc/awslogs/awscli.conf&lt;/code&gt; を変更します。デフォルトだとusになっているので、&lt;code&gt;ap-northeast-1&lt;/code&gt;などに書き換えます。&lt;/p&gt;
&lt;p&gt;つぎに、&lt;code&gt;/etc/awslogs/awslogs.conf&lt;/code&gt; を開いて以下の設定を末尾の方に記述します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[/var/log/messages]
datetime_format = %b %d %H:%M:%S
file = /var/log/messages
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/messages

[/var/log/secure]
datetime_format = %b %d %H:%M:%S
file = /var/log/secure
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/secure
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;datetime_format&lt;/code&gt;は、読み込むログファイル内で、日付がどのようなフォーマットで表記されているかです。これをもとにtimestampを生成した上で、CloudWatchに送信されます。&lt;/p&gt;
&lt;p&gt;最後に、systemctlでサービスを有効にします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo systemctl start awslogsd
% sudo systemctl enable awslogsd.service
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Ubuntuの場合&lt;/h3&gt;
&lt;p&gt;Amazon Linux 2のようにパッケージは用意されていません。Pythonのセットアップスクリプトを実行することによって、&lt;code&gt;/var/awslogs&lt;/code&gt; に必要ファイルが展開されます。&lt;/p&gt;
&lt;p&gt;セットアップ方法は&lt;a href=&quot;https://medium.com/@agungdarmanto/how-to-send-nginx-logs-to-aws-cloudwatch-1be3dccd1a7&quot;&gt;こちら&lt;/a&gt;が一番綺麗に整理されているので参考にするのが良いです。&lt;/p&gt;
&lt;p&gt;途中で、regionのパラメータを設定する必要があるのでそちらは適宜置き換えます。以下は東京の例。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo python ./awslogs-agent-setup.py --region ap-northeast-1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;セットアップ中に、AWS access key IDとAWS secret access keyが聞かれますが、ssm-agentを使っているならば空白で飛ばしてOKです。&lt;/p&gt;
&lt;p&gt;インストールが完了すると、設定ファイルは&lt;code&gt;/var/awslogs/etc/awslogs.conf&lt;/code&gt;に置かれているので開きます。&lt;/p&gt;
&lt;p&gt;Ubuntu/Debianの場合は以下のような設定を追記します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[/var/log/syslog]
datetime_format = %b %d %H:%M:%S
file = /var/log/syslog
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/syslog

[/var/log/auth.log]
datetime_format = %b %d %H:%M:%S
file = /var/log/auth.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/auth.log

[/var/log/kern.log]
datetime_format = %b %d %H:%M:%S
file = /var/log/kern.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/kern.log

[/var/log/dpkg.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/dpkg.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/dpkg.log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最後にリスタートを忘れずに。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;%  sudo service awslogs restart
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;設定の確認&lt;/h2&gt;
&lt;p&gt;こんな感じでインスタンスIDごとにログストリームができます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/01/image-4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Logs Insightで横断的に検索できます。使い方は&lt;a href=&quot;https://qiita.com/sot528/items/8431317c26780e6a7e54&quot;&gt;こちらの記事&lt;/a&gt;を参照。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/01/image-4-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;このようにCloudWatch Logsに入ってしまえば、メッセージや流量をトリガーにSNS経由でアラートを発行できるようになります。&lt;/p&gt;
&lt;p&gt;とりあえずシステムのログはCloudWatchに入れてしまうのが良いと思います。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;システム系のログは流量が少ないので何も考えずにCloudWatch Logsに入れてしまって良いと思います。&lt;/li&gt;
&lt;li&gt;アプリケーション系は要望によって、要設計。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Amazonで2020年に購入した商品を軽く見てみる</title><link>https://blog.teraren.com/posts/2020-amazon-purchase/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2020-amazon-purchase/</guid><description>コロナ禍で在宅時間が増えた2020年のAmazon購入履歴を振り返り。モニターアーム・加湿器など良かったものと、未開封のランニングシューズなど失敗した買い物を公開。</description><pubDate>Sat, 30 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;家にいる時間が増えて、アマゾンでたくさん買い物をしたから振り返ってみようと思いました。購入内容の算出には&lt;a href=&quot;https://rs-techdev.com/archives/4340&quot;&gt;このスクリプト&lt;/a&gt;を利用しました。&lt;/li&gt;
&lt;li&gt;たくさん買い物をしたなぁと思っていたけれど、大したことなかったです。&lt;/li&gt;
&lt;li&gt;もっとたくさん消費して経済を回したほうが良いと思いました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/01/Screen-Shot-2021-01-29-at-22.54.01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;複数個買ったのは単価1つとして出てしまています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/01/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;買ったけど、殆ど使っていないものやハズレのものがたくさんありました。。。&lt;/li&gt;
&lt;li&gt;良かったもの
&lt;ul&gt;
&lt;li&gt;インターホンの子機：デスクで応答できるから楽。&lt;/li&gt;
&lt;li&gt;インパクトドライバー：穴あけ、ネジの締込み作業が格段に楽になりました。&lt;/li&gt;
&lt;li&gt;6Lぐらい入る加湿器：水を補充する手間が減った。&lt;/li&gt;
&lt;li&gt;モニターアーム：デスクが広くなる！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;買わなくてよかったもの
&lt;ul&gt;
&lt;li&gt;ランニングシューズ：やすかったからたくさん買ったけど、1つも箱を開けていない。&lt;/li&gt;
&lt;li&gt;WiFi中継機：あんまり意味なかった&lt;/li&gt;
&lt;li&gt;スピーカーインシュレーター：変化なし。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;おまけ&lt;/h2&gt;
&lt;p&gt;過去すべて&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/01/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>2021/1/29 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/2021-1-29-minedia-tech-talk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2021-1-29-minedia-tech-talk/</guid><description>2021/1/29 Minedia Tech Talk 今週のニュース</description><pubDate>Sat, 30 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;h2&gt;メイン&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itmedia.co.jp/news/articles/2101/29/news107.html&quot;&gt;三井住友銀行などのソースコードが流出 &quot;年収診断&quot;したさにGitHubに公開か&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;これはきつい。。。&lt;/li&gt;
&lt;li&gt;銀行、警察のソースコードも上げていた模様。Forkされたソースコードが見られる状態（リポジトリは法的措置により削除済み）。もう拡散は止められない。&lt;/li&gt;
&lt;li&gt;私もかつて、&lt;a href=&quot;https://x.com/matsubokkuri/status/765471854886686721&quot;&gt;外注先にソースコードをpublicにされて&lt;/a&gt;、大変でした。&lt;/li&gt;
&lt;li&gt;github連携から自動で年収判定をするサイトで、tensorflowのサンプルコードを10行ぐらい書けば、年収800万円ぐらいと表示されるらしい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;在宅ワークのお供
&lt;ul&gt;
&lt;li&gt;ホットクック＋ネットスーパー&lt;/li&gt;
&lt;li&gt;コスパ良い。もちろん、食洗機がある前提。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://magazine.cainz.com/article/30246&quot;&gt;ホットサンドメーカー&lt;/a&gt;良い。水分が飛ばないから美味しくできるし、火の通りが早い。油が飛び散らない。だけど、掃除が若干面倒。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;めちゃ綺麗。&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/watch?v=6yuZnQSDuBo&amp;amp;feature=emb_logo&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;マネオフォ給与のSSOは有効にできないの？
&lt;ul&gt;
&lt;li&gt;有料オプションっぽいかも。&lt;/li&gt;
&lt;li&gt;セキュリティを向上できるからお互いにとって良いはずなのに謎。利益追求かー。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www3.nhk.or.jp/news/html/20210129/k10012839841000.html&quot;&gt;東京の緊急事態宣言は延長っぽい。&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;都内に住む利点って薄いのでは？固定費の安い地方移住するのが良い気がする。&lt;/li&gt;
&lt;li&gt;しかし、もとに戻ったら不便すぎるし。&lt;/li&gt;
&lt;li&gt;移住するとなったら半年ぐらい準備に掛かりそうだし。その頃には少しは状況が良くなっているはずだし。&lt;/li&gt;
&lt;li&gt;地方移住するなら、海外移住を検討しても良いかもなー&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;おわりに&lt;/h2&gt;
</content:encoded></item><item><title>githubでmentionされたらslackへ通知する設定 (所要時間約10分）</title><link>https://blog.teraren.com/posts/github-mention-slack/</link><guid isPermaLink="true">https://blog.teraren.com/posts/github-mention-slack/</guid><description>GitHub Actionsの「github-mention-to-slack」を使い、GitHubでmentionされたらSlackへ即通知する設定方法。既読管理やリマインダーも活用できる快適な開発ワークフローを構築。</description><pubDate>Tue, 19 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;github上でmentionされても気づくのが難しい状態でした。メールはいろいろな通知が送られてくるし、githubのwebサイト上の通知欄は自分から見に行かないと行けないし、後ほどTODOとして未読に変更ができないので自分のタスク管理がしづらい状態でした。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/marketplace/actions/github-mention-to-slack&quot;&gt;github-mention-to-slack&lt;/a&gt;というGithub Actionがあったので設定してみたところ、かなり快適でした。&lt;/li&gt;
&lt;li&gt;紹介されている設定では、運用に不十分なところが多かったので、ほとんどコピペでできるような設定を&lt;a href=&quot;https://gist.github.com/matsubo/69f994a3a9830973c56fd8322798f60f&quot;&gt;gist&lt;/a&gt;に置いておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;githubのrepositoryまたはorganizationのSecretに&lt;code&gt;SLACK_WEBHOOK_URL_FOR_MENTION&lt;/code&gt;というキーでSlackのwebhook URLを登録します。&lt;/p&gt;
&lt;p&gt;（organizationに登録しておけば設定を使い回せるので楽です）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/01/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下を実行して、Github Actionsの設定ファイルを2つ作ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd path/to/repository
mkdir -p .github/workflows
curl https://gist.github.com/matsubo/69f994a3a9830973c56fd8322798f60f#file-mapping-mention-to-slack-yml &amp;gt; .github/mention-to-slack-yml
curl https://gist.githubusercontent.com/matsubo/69f994a3a9830973c56fd8322798f60f/raw/731171a269ad11befc9e15c4a47bf1059c6ef541/mention-to-slack.yml &amp;gt; .github/workflows/mention-to-slack-yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、githubのアカウントとSlackのアカウントのマッピングをgithub/mention-to-slack-ymlに書きます。&lt;/p&gt;
&lt;p&gt;サンプル&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# For Github User
# github_username: &quot;slack_member_id&quot;
# please_replace_me_11: U01G30S9LHW
# please_replace_me_4: U011F5DRG2V

# github_username_A: &quot;slack_member_id_A&quot;
# github_username_B: &quot;slack_member_id_B&quot;
# github_username_C: &quot;slack_member_id_C&quot;
# abeyuya: &quot;XXXXXXXXX&quot;

# For Github Team
# github_teamname: &quot;slack_member_id&quot;
# github_teamname_A: &quot;slack_member_id_D&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;slackのIDはその人のプロフィールをクリックして表示される英数字10桁ぐらいの文字です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/01/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;これで設定はおわりなので、commitしてpushしてメインとなるブランチにmergeされた状態にすればOKです。&lt;/p&gt;
&lt;p&gt;送られてくるメッセージこんな感じ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/01/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;これで、手元のslackで&lt;strong&gt;未読、既読の管理ができる&lt;/strong&gt;し、&lt;strong&gt;リマインダ&lt;/strong&gt;も設定できます。取りこぼしも激減しました。&lt;/p&gt;
&lt;p&gt;ちなみに、&lt;strong&gt;pull requestのassign&lt;/strong&gt;が行われたときにもその人へ通知が来ます。&lt;/p&gt;
&lt;p&gt;github上でコメントに後からmentionを追加した場合は通知は&lt;strong&gt;飛びません&lt;/strong&gt;。&lt;/p&gt;
</content:encoded></item><item><title>2021/1/15 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/2021-1-15-minedia-tech-talk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2021-1-15-minedia-tech-talk/</guid><description>Parlerデータ流出・電気代高騰・devise-two-factorによる2FA実装・AWSへのシステム移行など2021年1月のテックニュースと個人的な考察まとめ。</description><pubDate>Fri, 15 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;h2&gt;本題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cloud.watch.impress.co.jp/docs/news/1299886.html&quot;&gt;蔦屋書店が15のサービスをAWSへ移行、システム標準化や保守作業の削減に成功&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;はてブがついているから見たけど普通だった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://news.mynavi.jp/article/20200304-987014/&quot;&gt;Amazonの領収書をまとめて出力、確定申告の“神”ツール「アマゾン注文履歴フィルタ」&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;地味に便利&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pc.watch.impress.co.jp/docs/topic/feature/1299995.html&quot;&gt;数千円のWebカメラと照明で、ビデオ会議やゲーム配信ワイプの画質を高級カメラに近づける&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;証明でぜんぜん変わるのはわかるけど、ライトが眩しい！よほど気合の入ったカンファレンス的なイベントなら良いですけど普通のテレカンではオーバースペック感はありますね。&lt;/li&gt;
&lt;li&gt;テレカンのたびにライトを入れたり切ったりするのが大変です。&lt;/li&gt;
&lt;li&gt;なにか良い方法あればいいんですけどねぇ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://togetter.com/li/1652450&quot;&gt;みんなでエッチに見える方の画像を選ぶ『遺伝的アルゴリズムで最高にエッチな画像を作ろう！』→3500世代目にしておっぱいとお腹誕生へ&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;昔の状態がわからないからいまいち凄さがわからない。。。&lt;/li&gt;
&lt;li&gt;遺伝的アルゴリズムだと限界がありそう。&lt;/li&gt;
&lt;li&gt;しかもフィードバックが2つに1つだと時間がかかりそう。。。両方同じくらいというフィドバックも入れると局所解に陥らなさそうな気はする。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gizmodo.jp/2021/01/ompletely-save-parler-data.html&quot;&gt;Parlerの投稿がひどすぎて削除される前にハッカーが完全保存。メタタグで議事堂占拠犯がゴロゴロ逮捕&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;画像をstripしていなかったのか。。。初歩的な。。。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itmedia.co.jp/news/articles/2101/13/news084.html&quot;&gt;コンテンツ規制&lt;/a&gt;の境界って難しい。発言の自由が脅かされる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.nikkansports.com/general/nikkan/news/202101130000639.html&quot;&gt;電気代「市場連動型」４月まで高騰続く可能性／識者&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;辛い。。。&lt;/li&gt;
&lt;li&gt;一般家庭で市場連動を使っている人って稀なような気がするが。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://game.watch.impress.co.jp/docs/news/1299782.html&quot;&gt;これぞゲーミングマスク!? Razerが手掛けるマスク「Project Hazel」が登場&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;光ることが特徴？？&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tinfoil/devise-two-factor&quot;&gt;devise-two-factor&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;qrcode, smsなどの2FA対応できる。まぁ、認証ロジックにはそこそこ手を入れないといけなさそう。&lt;/li&gt;
&lt;li&gt;あんまりはてブついていないけど、 このご時世はかなり重要な気がする。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;あとがき&lt;/h2&gt;
</content:encoded></item><item><title>2021/1/8 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/2021-1-8-minedia-tech-talk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2021-1-8-minedia-tech-talk/</guid><description>2021/1/8 Minedia Tech Talk 今週のニュース</description><pubDate>Fri, 08 Jan 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;h2&gt;本題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://note.com/ebiebi_pg/n/nf3519b5041ee&quot;&gt;ベテランエンジニアがクラウドワークスで5,000円の案件を受けてみた｜ebiebi_pg｜note&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;逆に発注する側からするとお得にできるということですね。&lt;/li&gt;
&lt;li&gt;そう考えて、私が数年前に、難易度が低いRailsアプリケーションの管理画面に機能を追加するという案件を5個ほど普通の業務委託相場の8掛けの値段で出したら応募が殺到しました。頑張って発注する人を選定し、発注しましたが半分ぐらいの人しか完了しなかった。。。&lt;/li&gt;
&lt;li&gt;プロジェクト形式なのに「完了してないけど頑張ったから報酬をくれ」とか言われたりして交渉が大変だった。揉めたら悪い評価付けられるし。&lt;/li&gt;
&lt;li&gt;まれに優秀なコードを書く人は居たりもする。ちゃんとしたフルタイムでエンジニアをしている人が副業の受注先として使っていたりもする。（今回のnoteの作者のような人）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;年始だからか、ニュースが少ないなぁ。&lt;/li&gt;
&lt;li&gt;個人ネタですが、個人で運用しているサービスをruby 3に置き換えました。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://postcode.teraren.com/postcodes/&quot;&gt;https://postcode.teraren.com/postcodes/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/&quot;&gt;https://bank.teraren.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/covid19-daily-tweet&quot;&gt;https://github.com/matsubo/covid19-daily-tweet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;もう1こ、rails 6のサイトはpumaが上がらなくて時間切れで断念。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://scrapbox.io/neet/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%B9%E3%82%AF%E3%83%BC%E3%83%AB%E3%81%AB%E9%80%9A%E3%81%86%E3%81%8F%E3%82%89%E3%81%84%E3%81%AA%E3%82%89%E3%81%93%E3%81%AE%E6%9C%AC%E3%82%92%E8%AA%AD%E3%82%8110%E9%81%B8&quot;&gt;プログラミングスクールに通うくらいならこの本を読め10選 - ニート向けソフトウェアエンジニアリング塾&lt;/a&gt;
{/* textlint-disable no-unmatched-pair */}
&lt;ul&gt;
&lt;li&gt;うーん。1つも呼んだことがない（汗）
{/* textlint-enable */}&lt;/li&gt;
&lt;li&gt;リーダブルコードは流し読みしたけど、&lt;a href=&quot;https://www.amazon.co.jp/CODE-COMPLETE-%E7%AC%AC2%E7%89%88-%E4%B8%8A-%E5%AE%8C%E5%85%A8%E3%81%AA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%92%E7%9B%AE%E6%8C%87%E3%81%97%E3%81%A6/dp/489100455X&quot;&gt;Code complete&lt;/a&gt;に書いてある内容だったので。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://japan.cnet.com/article/35164761/&quot;&gt;バイデン次期政権、オープンソース開発者のリコードン氏を技術ディレクターに - CNET Japan&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;台湾のオードリー・タンに続いてアメリカも。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://xtech.nikkei.com/atcl/nxt/column/18/00138/010500702/&quot;&gt;「リモート初詣」で参拝客が130倍に、住職のこだわりと技術力に驚いた | 日経クロステック（xTECH）&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;環境に適合する人だけが生き残っていけるよね。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://speakerdeck.com/_kensh/serverless-testing&quot;&gt;Serverlessをテストしよう / Serverless Testing - Speaker Deck&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;半年前ぐらいにこのあたりを考えてみたけど、やっぱり大変ですよね。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;あとがき&lt;/h2&gt;
</content:encoded></item><item><title>2020/12/25 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/2020-12-25-minedia-tech-talk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2020-12-25-minedia-tech-talk/</guid><description>IQbuds2 MAX・作業環境リノベ事例・Smoozブラウザ終了・Ruby 3.0リリース（型システム・VM37%高速化）・HHKB Pro BT購入レポートなど2020年末のテックニュースまとめ。</description><pubDate>Fri, 25 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;h2&gt;本題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;IQbuds2 MAX良さそう。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://av.watch.impress.co.jp/docs/review/review/1296432.html&quot;&gt;https://av.watch.impress.co.jp/docs/review/review/1296432.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;RTINGS.comの結果次第かなと。定量的に音響機器を評価してくれる素晴らしいサイト。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rtings.com/headphones/tools/compare/bose-soundsport-free-vs-b-o-play-e8/560/566&quot;&gt;https://www.rtings.com/headphones/tools/compare/bose-soundsport-free-vs-b-o-play-e8/560/566&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;5万円か。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;作業環境リノベ。ガチだ。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.craftz.dog/a-solo-app-developers-dream-desk-setup-late-2020-bac70736e809&quot;&gt;https://blog.craftz.dog/a-solo-app-developers-dream-desk-setup-late-2020-bac70736e809&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;自己満足感が強いけど、家の仕事環境に投資しても良いですよねぇ。長引きそうなので。&lt;/li&gt;
&lt;li&gt;リフォーム業者は忙しいらしいです。&lt;/li&gt;
&lt;li&gt;Pro Display XDRはちょこちょこTwitter上で買っている人を見かけるけど、実売価格が知りたいなぁ。定価52万円。整備品で安く出たという話もある&lt;/li&gt;
&lt;li&gt;冬休みにやるのが丁度いいのでは？&lt;/li&gt;
&lt;li&gt;木の天板が欲しいー。ちょうどよい反発感。反発力が強いとあたっている手が痛くなる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Smooz終了
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://b.hatena.ne.jp/entry/s/reliphone.jp/post-16361/&quot;&gt;https://b.hatena.ne.jp/entry/s/reliphone.jp/post-16361/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;個人的には乗り切ってほしかったし、ポイントを稼ぎたいユーザも一定数居たと思うんだけどなぁ。倫理性はわからん。&lt;/li&gt;
&lt;li&gt;第三者機関の監査と、プライバシーポリシーが明確になっていて、ユーザの合意が取れれば良い気がするが。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;おすすめAlexaスキル
&lt;ul&gt;
&lt;li&gt;https://otona-life.com/2020/12/24/49287/ （リンク切れ）&lt;/li&gt;
&lt;li&gt;トータル5個飼ってます。あんまり有効活用していない。。。&lt;/li&gt;
&lt;li&gt;便利そうなので整備してみても良いかもなぁ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ruby 3.0.0 リリース
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ruby-lang.org/ja/news/2020/12/25/ruby-3-0-0-released/&quot;&gt;https://www.ruby-lang.org/ja/news/2020/12/25/ruby-3-0-0-released/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;特徴はズバリ型！！&lt;/li&gt;
&lt;li&gt;パフォーマンスはVMで37%ぐらい早くなっているっぽい。&lt;/li&gt;
&lt;li&gt;色々なサービスをはやく載せ替えてみたい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://x.com/nalsh/status/1342350629407092737&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/PFU-Hacking-Keyboard-Professional-PD-KB600B/dp/B01DVH7C0O&quot;&gt;HHKB Pro BT&lt;/a&gt;買いました。
&lt;ul&gt;
&lt;li&gt;apple keyboardに慣れていると、キーストロークが深くて指の可動域が広くなって辛い。&lt;/li&gt;
&lt;li&gt;macだと、functionキーの共存が難しい。&lt;/li&gt;
&lt;li&gt;1列まるっとキーが減っているので、なくなっているので代替方法が今の所よくわからない。&lt;/li&gt;
&lt;li&gt;USB接続しているのに、キーボードマップツールが何故か動かない。。キーボード自体の打鍵はできるのに。冬休みに考える。&lt;/li&gt;
&lt;li&gt;打鍵音は最高ですけどね。ちょっとうるさいかも。Type-Sなら打鍵音が静かで、キーストロークも0.2mmほど短いらしい。本物を試してみたいです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://x.com/matsubokkuri/status/1342006932576473088&lt;/p&gt;
&lt;h2&gt;おわりに&lt;/h2&gt;
</content:encoded></item><item><title>Minedia社の技術ブログを立ち上げました</title><link>https://blog.teraren.com/posts/creating-a-tech-blog/</link><guid isPermaLink="true">https://blog.teraren.com/posts/creating-a-tech-blog/</guid><description>Next.js SSGとOSSのblog hubをForkし、Vercelと独自ドメインで会社の技術ブログを10分で構築した手順を紹介</description><pubDate>Sat, 19 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;技術ブログを立ち上げる目的とか狙いとか、運用で困るといった考察は、&lt;a href=&quot;https://medium.com/@ichiroshoda/howtomanagetechblog-af451552192a&quot;&gt;TechBlog運用の難しさとHERPでの考えについて&lt;/a&gt;に書いてある内容と同じことを考えておりました。ただ、blog hubを立ち上げたくても立ち上げコストがかかるからプライオリティを下げてました。&lt;/li&gt;
&lt;li&gt;そんなところで、&lt;a href=&quot;https://x.com/catnose99&quot;&gt;@catnose99&lt;/a&gt;さんがblog hubを構築するOSSを&lt;a href=&quot;https://zenn.dev/catnose99/articles/cb72a73368a547756862&quot;&gt;公開してくれた&lt;/a&gt;のでforkして利用してみました。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/catnose99/team-blog-hub&quot;&gt;https://github.com/catnose99/team-blog-hub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Forkしたコードは公開しております
&lt;ul&gt;
&lt;li&gt;https://github.com/minedia/team-blog-hub （リポジトリ削除済み）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10分ぐらいで構築できると思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;主な設定&lt;/h2&gt;
&lt;p&gt;コードはNext.jsのSSG(Static Site Generators)で書かれています。ソースコードのコミットログを見てもらえればわかると思いますが、Forkした上で、主な設定はこれ。&lt;/p&gt;
&lt;p&gt;https://github.com/minedia/team-blog-hub/commit/640dc1cff76f3b4595045d3574f3b970a9a52f22 （リポジトリ削除済み）&lt;/p&gt;
&lt;p&gt;設定項目はきれいに外出しされていて超簡単です。&lt;/p&gt;
&lt;h2&gt;ホスティング&lt;/h2&gt;
&lt;p&gt;Vercelを使っています。github organizationと連携するので有料（$20/month）になりますが、最初の2週間は無料です。個人アカウントなら無料のようです。&lt;/p&gt;
&lt;p&gt;普通に設定すると &lt;code&gt;minedia-engineer-hub.vercel.app&lt;/code&gt; のようなホスト名でホスティングされます。自社ドメインで運用したいので独自ドメインの設定をします。&lt;/p&gt;
&lt;p&gt;Vercelの管理画面上で独自ドメイン + TSLの設定をすることになるわけですが、非常に簡単です。まずドメインを新たに追加します。&lt;/p&gt;
&lt;p&gt;そのうえで、オーナー確認をするためにDNSの設定を自分のドメインに追加します。初期状態ではドメインの所有者確認ができていないので &quot;Invalid Configuration&quot;と表示されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;CNAMEを1つ入れるだけです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;再度設定ページを表示すると、Valid configurationになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そしたら、独自ドメインで表示されるようになります。&lt;/p&gt;
&lt;p&gt;https://tech-blog.minedia.com/ =&amp;gt; zennへ移行しました。&lt;a href=&quot;https://zenn.dev/p/minedia&quot;&gt;https://zenn.dev/p/minedia&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;githubなので、社内のエンジニアだけでなくbizの人もpull requestを出すことで運用できます。&lt;/p&gt;
&lt;h3&gt;定期的なデプロイ&lt;/h3&gt;
&lt;p&gt;初期設定のままでは、静的なファイルなので誰かがコンテンツを書いてもHub側のページは更新されません。pingを送ることで更新するのが一番良いのですが、pingを送ることに対応していないblogが多いので定期的に自動更新をします。&lt;/p&gt;
&lt;p&gt;Vercelではcronに対応していないのでGithub Actionsからデプロイをトリガーします。&lt;/p&gt;
&lt;p&gt;設定ファイルはこちら。（この設定内容が世の中に出回っていないので貴重です）&lt;/p&gt;
&lt;p&gt;https://github.com/minedia/team-blog-hub/blob/master/.github/workflows/cron.yaml （リポジトリ削除済み）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name: Deploy production site
on:
  schedule:
    - cron: &apos;5 1 * * *&apos;
jobs:
  cron:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: amondnet/vercel-action@v20
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }} # Required
          github-token: ${{ secrets.GITHUB_TOKEN }} #Optional
          vercel-args: &apos;--prod&apos; #Optional
          vercel-org-id: ${{ secrets.ORG_ID}}  #Required
          vercel-project-id: ${{ secrets.PROJECT_ID}} #Required
          scope: ${{ secrets.VERCEL_SCOPE }}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;環境変数を設定するために、ローカルで &lt;code&gt;npx vercel&lt;/code&gt; を打って、セットアップします。&lt;/p&gt;
&lt;p&gt;その後、&lt;code&gt;.vercel/project.json&lt;/code&gt; の中に書かれた情報を使って環境変数を追加します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;githubのsecretsに追加&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;短時間で会社の技術ブログを立ち上げられました。&lt;/li&gt;
&lt;li&gt;自分の個人BlogのRSSを登録するということもあり、定期的に記事は書いているので、更新が止まった感じの寂れた感じは出ないはずです。&lt;/li&gt;
&lt;li&gt;会社で使っているや社内の雰囲気は&lt;a href=&quot;https://docs.google.com/presentation/d/1w3vXduRqsnAjq-_iRBYPNqDeWh9zKskrFjqv9WmIhjQ/edit&quot;&gt;こちらのスライド&lt;/a&gt;を御覧ください。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>2020/12/18 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/2020-12-18-minedia-tech-talk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2020-12-18-minedia-tech-talk/</guid><description>Docker Desktop 3リリース・M1向けDocker Tech Preview・ブラウザ拡張マルウェア300万人感染・Smoozのデータ送信問題など2020年12月のテックニュースまとめ。</description><pubDate>Fri, 18 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;h2&gt;本題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;明日渡航。&lt;a href=&quot;https://www.google.com/search?q=newyork+covid19&amp;amp;rlz=1C5CHFA_enJP888JP889&amp;amp;oq=newyork+covid19&amp;amp;aqs=chrome..69i57j0i30l5j0i8i10i30j0i8i30.3835j0j7&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8#wptab=s:H4sIAAAAAAAAAONgVuLVT9c3NMwySk6OL8zJecTYxMgt8PLHPWGpyklrTl5jLOYS901NyUzOzEt1ySxOTSxO9clPTizJzM8T0uNic80rySypFFLhEpRCNUeDQYqfC1VISIOLA65XhotXilM_V9_AKN7IwgyompsLweXZxcTtkZqYU5IRXJJYUryI1eHZtA1P53U_btr8uHnt4-aux03LHjctedy8-nHTToXHjeueb934YkXHs-bWpws2KugqPG7ufty89HHznsfNK0Bk03oAVELB3egAAAA&quot;&gt;New Yorkの新規陽性者多い&lt;/a&gt;。
&lt;ul&gt;
&lt;li&gt;New Yorkは日本からの渡航後は自主隔離。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tom Cruiseが非常に意識高くてびっくり。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rollingstone.com/movies/movie-news/tom-cruise-covid-19-rant-1104720/&quot;&gt;マスクをしていないスタッフをガチギレで注意&lt;/a&gt;。その理由が、プロフェッショナルな意識によるもの。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.docker.com/blog/docker-desktop-3-0-0-smaller-faster-releases/&quot;&gt;Docker 3リリース&lt;/a&gt;。メジャーバージョンアップですがそこまで大きなものはなさそう。&lt;/li&gt;
&lt;li&gt;ARM対応のDocker Desktopが&lt;a href=&quot;https://www.docker.com/blog/download-and-try-the-tech-preview-of-docker-desktop-for-m1/&quot;&gt;Tech Review版をリリース&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pc.watch.impress.co.jp/docs/news/1295872.html&quot;&gt;ChromeやEdgeの拡張機能複数にマルウェア実装。すでに300万人がダウンロード&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;上記サイトに怪しいプラグインの一覧が掲載されている。&lt;/li&gt;
&lt;li&gt;マーケットプレイスという仕組み上しょうがないような。。。&lt;/li&gt;
&lt;li&gt;とある日までまともに動いていたけど、ある日からいきなりマルウェアになるパターンも存在する。（開発者が身売りするケースがある）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://techblog.kayac.com/10-taboo-phrases-to-engineers&quot;&gt;たった一言でエンジニアを怒らせる方法 10 おまけ付き&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;ついつい言ってしまう言葉があります。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://reliphone.jp/post-16247/&quot;&gt;Smoozのデータ送信の件&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;ユーザにコンセンサスは取っている様子。&lt;/li&gt;
&lt;li&gt;オフィシャルからコメントが出ていて、バグによってログアウトしていても情報を送信しているから直すとのこと。会社の対応が誠実。&lt;/li&gt;
&lt;li&gt;元記事の中でもちょっと釣り的なタイトル。&lt;/li&gt;
&lt;li&gt;高木浩光先生はノーコメントっぽい。Retweetだけしている。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;情報収集に&lt;a href=&quot;https://techfeed.co.jp/&quot;&gt;TechFeed&lt;/a&gt;おすすめです。
&lt;ul&gt;
&lt;li&gt;パーソナライズ化されたTech系ニュースが配信される。&lt;/li&gt;
&lt;li&gt;プロがキュレーションしている様子。まとめ記事とかじゃなくて1次情報源の記事が多いのが良い。&lt;/li&gt;
&lt;li&gt;海外のソースも豊富。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;お知らせ&lt;/h2&gt;
</content:encoded></item><item><title>超低リスクに自社プロダクトのスタートアップを立ち上げるために大事な5つのこと</title><link>https://blog.teraren.com/posts/before-the-startup/</link><guid isPermaLink="true">https://blog.teraren.com/posts/before-the-startup/</guid><description>会社員エンジニアとして働きながら自社プロダクトのスタートアップを立ち上げた実体験をもとに、リスクを最小化して起業するための5つのポイントを紹介します。</description><pubDate>Mon, 14 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://adventar.org/calendars/5573&quot;&gt;CTOA Advent Calendar&lt;/a&gt; 14日目の記事です。&lt;br /&gt;
CTOの役割や業務については他の素晴らしいCTOが書いてくださっているので、この記事では&lt;strong&gt;会社員エンジニアとして働きながら&lt;/strong&gt;事業アイデアを仮説検証し、自社プロダクトのスタートアップを立ち上げるまでの話をしたいと思います。&lt;/p&gt;
&lt;p&gt;一般的にスタートアップを立ち上げるのはハイリスクと思われているかもしれませんが、しっかりとリスクヘッジをすれば超低リスクにスタートアップを立ち上げることができると、実体験ベースで思いました。今回はリスクヘッジの要点を5つに絞ってそのコツをお伝えできればと思います。&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;私の人生の目標のうち、一部を抜粋します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;0からサービスとビジネスを作る。&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;世の中を効率的、便利、公平にする。&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;そのためには、スタートアップをやろうと20年前からの目標です。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;そのためにはITを使ったスタートアップを立ち上げるというアプローチが最適でした。今はその実現途中であり、株式会社マインディアのCTO 3年目です。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/minedia-logo-wb-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;経歴&lt;/h2&gt;
&lt;p&gt;経歴だけだとつまらないので、一言コメント付き。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2005年 慶應義塾大学 環境情報学部 卒業
&lt;ul&gt;
&lt;li&gt;(研究室に寝泊まりの日々)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2006年 UCLA Extension ALC high intermediate 修了
&lt;ul&gt;
&lt;li&gt;(IT業界で生きていくには英語が必須だと思い、とりあえず海外へ。)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2007年 - 2009年 某社にて自社ECサイト開発
&lt;ul&gt;
&lt;li&gt;(知り合いの会社に呼ばれたので、帰国してシステム開発、サービス立ち上げ。)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2009年-2011年 コーチ・ユナイテッド株式会社 にてcyta.jpを0からのサービス開発・運用
&lt;ul&gt;
&lt;li&gt;(前職のときに土日で手伝っていたサービスが大きくなってきたのでフルタイムへ)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2011年 - 2013年 グリー株式会社 にてソシャゲDevOps、海外展開、2ndゲーム運用、チームマネジメント
&lt;ul&gt;
&lt;li&gt;(大規模トラフィックを扱いたくて)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2014年 - 2018年 株式会社メタップス にてSPIKE決済サービスを0から開発・運用
&lt;ul&gt;
&lt;li&gt;(手数料ゼロの決済サービスを使いたい！と思って話を聞いたら、流れで開発する側になっていた)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2019年 - 株式会社マインディア にてCo-founder CTO
&lt;ul&gt;
&lt;li&gt;マーケティングにおける調査を効率的にして、ITを活用したインサイトを生むために！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;重要な5点&lt;/h2&gt;
&lt;p&gt;起業までに必要な重要な点を時系列で整理しました。&lt;/p&gt;
&lt;h3&gt;1．自分自身の価値観を整理し準備する&lt;/h3&gt;
&lt;p&gt;スタートアップは辛いことが多いので、&lt;strong&gt;自分の得意なこと、性格、ゴールなどは明確にしておきます。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;なぜなら、一緒に組むメンバーを探す時やサービスを考えるときに、目標や価値観が違っていては議論の土台が変わってしまうためです。3年後の売上を年1億円目指すのか年100億円を目指すかによってパートナーやアプローチが変わってくるためです。&lt;/p&gt;
&lt;p&gt;また、自分自身の強みを客観的にも把握しておくことをおすすめします。自分では気づけなかった強みを見つけられると思います。&lt;/p&gt;
&lt;p&gt;例えば、CliftonStrengthsをやってみるなど。CliftonStrengthsの思想は、苦手分野を克服するより得意分野を伸ばしたほうがパフォーマンスが上がるので得意分野を知って継続的に研鑽するという考え方です。（統計的裏付けもあるみたい）。その得意分野は下記に記載のとおり34項目あるそうです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.gallup.com/cliftonstrengths/ja/253634/%E3%83%9B%E3%83%BC%E3%83%A0.aspx&quot;&gt;引用元&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;私の2018年ごろの&lt;a href=&quot;https://diary.teraren.com/posts/2018-03-15-strength-finder/&quot;&gt;結果&lt;/a&gt;は以下です。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;未来志向&lt;/li&gt;
&lt;li&gt;目標志向&lt;/li&gt;
&lt;li&gt;戦略性&lt;/li&gt;
&lt;li&gt;親密性&lt;/li&gt;
&lt;li&gt;個別化&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2. 信頼できる人とやる&lt;/h3&gt;
&lt;p&gt;基本的にエンジニアはエンジニアリングに集中するのが得策かと思っております。経営、マーケティング、ファイナンスのプロと話すとわかりますが簡単に習得できるような職種じゃないと感じました。&lt;/p&gt;
&lt;p&gt;そのような分野は専門家に任せたほうが良いので、スタートアップをやるときには誰か組むのが一般的かと思います。&lt;/p&gt;
&lt;p&gt;そのときに一番根底にあるのは&lt;strong&gt;信用&lt;/strong&gt;・&lt;strong&gt;信頼です&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;私は過去に騙された経験がありますが、騙された場合はその事業に掛けた数年間の時間やお金を失うことになります。最悪お金はなんとかなりますが、時間が奪われると取り返せません。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://4.bp.blogspot.com/-2HtNpopd8j4/WcB5u7qYQMI/AAAAAAABG14/S1HuOpthvscS6jSr1PRCfxThHwX0DFJCwCLcBGAs/s400/sagishi_man.png&quot; alt=&quot;詐欺師のイラスト&quot; /&gt;&lt;/p&gt;
&lt;p&gt;信頼を少しでも担保するためには一緒に働いたことがある人や、友人、リファレンスチェックができるような人と組みましょう。&lt;/p&gt;
&lt;p&gt;私が、出会った信頼できない人の行動例&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;超ケチ
&lt;ul&gt;
&lt;li&gt;自分の懐だけ潤して、社員や関係会社の利益はあまり考えない。&lt;/li&gt;
&lt;li&gt;一緒に儲けようというチームプレイができない。周りの人がチームプレイをしているつもりでも騙されている場合がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;女性関係が派手、社内の人と真剣ではない交際をする
&lt;ul&gt;
&lt;li&gt;色々と面倒なことを引き起こすリスクがあります。&lt;/li&gt;
&lt;li&gt;ビジネスとプライベートの区別がつかない。経営の意思決定がブレる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;口だけで実績が伴っていないまたは、実績が客観的に判断不能
&lt;ul&gt;
&lt;li&gt;喋りやポートフォリオがとてもきれいに見えるけど、実際に働いてみたらパフォーマンスが上がらないような人は多い。その人が行った実績を別の手段で評価しましょう。&lt;/li&gt;
&lt;li&gt;その本人の実績がよくわからない状態ということは、殆どの場合でその人が実績を上げていないからです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;例外があり、死ぬほど頭の良い人とは組んだほうが良い&lt;/strong&gt;という反省はあります。死ぬほど頭の良い人は、他人にもちゃんと利益を与えることを軽視しないし、ビジネス自体の成功確度が高いです。&lt;/p&gt;
&lt;p&gt;また、ファイナンスや経営の知識を自分で習得して会社経営を全般的に自分でハンドリングできるならばあまり重視する必要はないです。しかしながらエンジニアリングとは違う領域なのでハードルは高いです。&lt;/p&gt;
&lt;h3&gt;3. どこのフィールドで活動するかを計画する&lt;/h3&gt;
&lt;p&gt;この選択はロールプレイングゲームに言い換えると、&lt;strong&gt;その後の難易度がイージーモードかハードモードかが変わってくる&lt;/strong&gt;非常に重要なポイントになります。&lt;/p&gt;
&lt;p&gt;シンプルですが、以下のようなフレームワークを使って、作ろうとするサービスやビジネスの仮説を検証します。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;マーケティング環境分析と市場機会の発見&lt;/li&gt;
&lt;li&gt;セグメンテーション（市場細分化）&lt;/li&gt;
&lt;li&gt;ターゲティング（市場の絞り込み）&lt;/li&gt;
&lt;li&gt;ポジショニング&lt;/li&gt;
&lt;li&gt;マーケティング・ミックス（4P）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;まだこの段階ではリサーチ段階なのでいくらでも立ち戻れます。&lt;strong&gt;起業は手段なので焦って起業しない&lt;/strong&gt;ようにしましょう。&lt;/p&gt;
&lt;p&gt;私の場合は、代表の鈴木と定期的に電話などでビジネスのディスカッションをしていました。その中で、上記のフィルタリングをくぐり抜けたのが&lt;strong&gt;オンラインでの定性調査サービス&lt;/strong&gt;でした。&lt;/p&gt;
&lt;p&gt;この仮説検証の段階で1つ気になったことがあった。それは、「オンラインでのインタビューがほとんど行われていないこと」。オンラインで定性調査するサービスを作っても、実はすでに提供している会社がありましたというオチになるのではないか？とずっと思っていた。&lt;/p&gt;
&lt;p&gt;よって、他のプレイヤーが立ち上がったらやめようというくらいのノリでした。しかしながら競合プレイヤーはなかなか現れませんでした。&lt;strong&gt;自分の中では当たり前でも、他業種では当たり前ではないことが多数あることを体感しました。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-11-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こんな感じで貸会議室とかでいろいろな側面から計画&lt;/p&gt;
&lt;p&gt;実際のところ、「言うは易し行うは難し」という言葉そのもので、実装してみると色々と大変だった。既存業務のリプレイスは要求が多くて大変。&lt;/p&gt;
&lt;h3&gt;4．プロダクトは自分の手で作る&lt;/h3&gt;
&lt;p&gt;私の場合は、平日は忙しいので毎週土曜日をこのプロジェクトに使うというスコープで時間を投資していたため、実装を自分でやっているとプロトタイプの完成が遅くなると考えていた。&lt;/p&gt;
&lt;p&gt;そこで、設計の重要なところだけを自分で行い、実装は外部に任せるというアプローチをとることにしました。&lt;/p&gt;
&lt;p&gt;しかし、いま振り返るとこの意思決定は間違っていました。&lt;br /&gt;
会社で開発するのと個人で開発を外注するのは大きな違いがあります。それは予算です。&lt;/p&gt;
&lt;p&gt;普通に考えると実装で最低でも300万円ぐらい掛かりそうな内容でしたが、この段階ではこの金額をかけて作り込むほどビジネスプランが作れていないので300万円をかける意思決定はできません。そこで、安く請けてくれる海外のオフショアへ発注することにしました。要件定義、外部設計、内部設計まで私の方で行って実装を依頼しました。&lt;/p&gt;
&lt;p&gt;設計書の一例&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-10.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Cacooで外部設計を書いていた&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;MySQL Workbenchの内部設計&lt;/p&gt;
&lt;p&gt;しかし、最終的に上がってきた成果物は意図したとおりに動かず、動作させるために自分でコードを修正してました。&lt;/p&gt;
&lt;p&gt;結局はほとんどのコードを書き直しました。&lt;strong&gt;振り返ると、自分でゼロから書いたほうが早かったです。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;時間がかかるけど、お金をかけないでやるためにはしょうがないです。自分で書きましょう。biz側にも納得してもらいましょう。納得してくれなければ優秀な人を雇うお金をポケットマネーで出してもらいましょう。時間をお金で買うかどうかという視点で、資金調達をするかどうかの議論が行われました。&lt;/p&gt;
&lt;p&gt;記念すべき最初のコミットログを貼り付けておきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;5．仮説・検証を回しまくる&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Thread.new { `一緒にやる仲間を探す` }
while (お金を払っても使いたい会社数 &amp;lt; 5)
  `無料で使ってもらう。`
  `フィードバックをもらう。`
  `修正する`
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://www.amazon.co.jp/dp/B00F3UTIQY?tag=matsubo0e-22&quot;&gt;リーン・スタートアップ&lt;/a&gt;のBuild-Measure-Learnにあたるところです。期間は半年ぐらいやりました。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00F3UTIQY&quot;}&lt;/p&gt;
&lt;p&gt;余談ですが、プロダクトを開発し始めた2015年ごろのWebRTCは対応ブラウザが少なく、実装がかなり不安定でした。つらすぎてFlashに変更するか？と何度か考えましたが、結果的にはWebRTCを使い続けて本当によかった。。。今となってはWebRTCを利用しない日は無いくらいに普及しました。&lt;/p&gt;
&lt;p&gt;ここでの粘りが、後々の貯金を作ります。運用や会社が走り出したら収支を気にしながら行かなければいけないので、収支を無視してこだわりの実装やリファクタリングをやるならこのタイミングでとことんやっておきます。&lt;/p&gt;
&lt;h3&gt;そして会社設立へ！&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://1.bp.blogspot.com/-2DQN0Sie5QY/XKGKvx2H60I/AAAAAAABSH0/tEBYM1iGEaQ1ewywqxKD4xPFjrC1ahAIQCLcBGAs/s800/gengou_document_reiwa.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;テスト利用をしてもらっていたら、有償で利用してくださる会社が現れました。有償で使ってもらうためには機密保持契約や基本契約書を交わす必要があります。大きめの企業だったので個人では取引のための契約が締結できないので、このときに法人が必要になりました。自社プロダクトのサービス提供を行う場合、実は法人設立は必要になったタイミングぐらいでも良いのです。&lt;/p&gt;
&lt;p&gt;脱サラをする際には信用が必要なものは行使しておいたほうが良いと聞きました。会社員でなくなると、銀行が評価する与信枠が減ります。住宅ローンを組む際の金利が優遇されなくなったり、クレジットカードの審査が通りにくくなるとのこと。&lt;br /&gt;
特に上場企業勤務×勤続年数が長い場合は、与信枠が多い状態だったりするため、どのタイミングでそのカードを切るかは自分のライフプランも考慮したほうが良いかと思います。&lt;/p&gt;
&lt;p&gt;ちなみに、物理オフィスはこの時点では不要だったりします。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;おっさんエンジニアが若手にアドバイスできることは穴に落ちない方法を伝えることぐらいかと思うので参考にしていただければと思います。&lt;/li&gt;
&lt;li&gt;起業後にも今までやったことがないような立ち回りが色々と必要になりますが、嫌でも身に付けさせられるので大丈夫かと思います。&lt;/li&gt;
&lt;li&gt;**Minediaでは事業拡大のためエンジニアを募集しています。**まだ数名規模のエンジニア組織のためチャレンジ要素しかありません。一緒に働いてみたい方はこちらをご覧ください。&lt;/li&gt;
&lt;li&gt;（サムネは最近お気に入りの&lt;a href=&quot;https://zenn.dev/&quot;&gt;zenn.dev&lt;/a&gt;のOGP画像を参考にしました。）&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>2020/12/11 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/2020-12-11-minedia-tech-talk-weekly-news/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2020-12-11-minedia-tech-talk-weekly-news/</guid><description>2020/12/11 Minedia Tech Talk 今週のニュース</description><pubDate>Fri, 11 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.willnet.in/entry/2020/12/11/100000&quot;&gt;APIに制限をかける方法&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;GCRAはpublicなサービスに良さそう。sidekiq enterpriseが必要かぁ。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;postcode.teraren.com&lt;/a&gt;を運用していますが、今は完全にフリー。負荷も問題ないけど何かしら、アプリケーションキーを発行して誰がどのくらい使っているのかは把握したいところではあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gigazine.net/news/20201211-centos-red-hat-enterprise-linux/&quot;&gt;CentOS終了&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;むかしから、RedHatの実験的存在のCentOSが無くなるとのこと。&lt;/li&gt;
&lt;li&gt;昔はもっとDistributionの統廃合が早かったなぁ。長く持ったほうだと思うし。文句言うならメンテナンスするかお金を集めないと。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://devblog.thebase.in/entry/2020/12/11/113000&quot;&gt;Slackで問い合わせ対応&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;こういうことやりたいですね。サンプルコードが長い。大変そうです。工数どんぐらいかかったんだろう。&lt;/li&gt;
&lt;li&gt;Slackアプリ化してほしい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://offers.jp/media/sidejob/workstyle/a_1938&quot;&gt;Write code everyday&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;すごい。&lt;/li&gt;
&lt;li&gt;githubが全てではないけど、こんな感じ。土日はサボってるのがバレる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itmedia.co.jp/pcuser/articles/2012/11/news079_4.html&quot;&gt;微妙に気になるPCの電気代&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;ノートPCなら1カ月使っても数十円レベル&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;安い。。。ありがとう電気。ブロックチェーンのマイニングをしていたときは電気代がすごい高かったけど。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;おわりに&lt;/h2&gt;
</content:encoded></item><item><title>2020/12/4 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/2020-12-4-minedia-tech-talk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2020-12-4-minedia-tech-talk/</guid><description>ahamoサービス開始・iPhone 12の5G制限、Apple M1でのDocker動作、Kubernetes 1.20のcontainerd移行、PHP8の互換性変更、AWS re:Invent 2020まとめ。</description><pubDate>Fri, 04 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;はじめに&lt;/h2&gt;
&lt;h2&gt;5G通信&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://ahamo.com/&quot;&gt;ahamo&lt;/a&gt;が爆誕。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;aha mobileの略。MVNOの会社が危機に陥るような。。。&lt;/li&gt;
&lt;li&gt;先行エントリーをしておけばdポイントを3000ポイントもらえるので、とりあえず登録してみるのが良いです。&lt;/li&gt;
&lt;li&gt;2021年3月頃からサービス開始予定。&lt;/li&gt;
&lt;li&gt;Work From Homeなのでキャリア課金は最低で良いよね。3GBにしてしまった。キャリアを変えるのってMVNOで簡単にはなったけど、手間がかかるのは事実、なかなかスイッチする気にはならない。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/mineo-to-yahoo/&quot;&gt;mineoは遅い&lt;/a&gt;。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;iPhone 12はDual SIMモードで5Gを両方サポートできない。&lt;a href=&quot;https://www.theverge.com/2020/10/19/21523718/apple-iphone-12-5g-dual-sim-mode-launch-issue-update&quot;&gt;片方は4Gになってしまう。&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;そして、5Gは低遅延になると言われているけど実際のところどうなるのかが技術的に解説されている記事が話題でした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://highemerly.hatenadiary.jp/entry/real-5g-urllc&quot;&gt;https://highemerly.hatenadiary.jp/entry/real-5g-urllc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;5Gの真価が発揮できるのはまだまだ先なのでは・・・？&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MVNOで5Gが使える業者は楽天モバイル（正確に言うと自社になるかもしれませんが）くらいしかないので安くて5Gが使えるのは良いかも。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;それにしても5Gの1基地局のカバー範囲はかなり狭そう。参考資料で、auの2020年末までの範囲。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;インフラ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Apple M1プロセッサでDockerが動いたという話。Dockerの中の人がビルドしています。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.softantenna.com/wp/software/apple-silicon-docker/&quot;&gt;https://www.softantenna.com/wp/software/apple-silicon-docker/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Kubernetes 1.20からDockerが非推奨になって、containerdが推奨になるっぽい。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.inductor.me/entry/2020/12/03/061329&quot;&gt;https://blog.inductor.me/entry/2020/12/03/061329&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Docker内部ではcontainerdが使われていたりするので、よくわからないけど。&lt;/li&gt;
&lt;li&gt;以下の図がわかりやすい。k8sは赤枠だけしか使っていないとのこと。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/12/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP8が下位互換性をなくす変更が多数入っているのですんなり移管できなさそう。WordPressも次期リリースの5.6からサポートする様子。その上のプラグインやテーマはその後に対応することになるのだろうな。。。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.php.net/manual/en/migration80.incompatible.php&quot;&gt;https://www.php.net/manual/en/migration80.incompatible.php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;大きな変更は、評価式の評価方法が変わる。。。。&lt;/li&gt;
&lt;li&gt;create_functionが無くなるなど。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;AWS re:Invent 20&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;まとめ
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.classmethod.jp/referencecat/aws-reinvent-2020/&quot;&gt;https://dev.classmethod.jp/referencecat/aws-reinvent-2020/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.classmethod.jp/articles/ebs-gp3/&quot;&gt;EBSでgp3が登場&lt;/a&gt;。gp2よりコスパ良いので普通にmigrateしちゃえば良さそう。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.classmethod.jp/articles/aurora-serverless-v2/&quot;&gt;Aurora Serverless v2&lt;/a&gt;ができたとのことだけど、Aurora Serverlessの存在自体を知らなかった。。。計算やIOに課金しているとのことなので稼働率が低い開発環境や突発的にアクセスが来るサイトには良い！&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.classmethod.jp/articles/breaking-sagemaker-data-wrangler/&quot;&gt;SageMaker良さそう&lt;/a&gt;。機能がかなり増えた。Python＋DSLっぽい。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/jp/codeguru/&quot;&gt;CodeGuru&lt;/a&gt;使いたい。。。Profilerですね。まずは&lt;a href=&quot;https://github.com/reviewdog/reviewdog&quot;&gt;Reviewdog&lt;/a&gt;を入れたい。。。。時間が。。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;監視ツール&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;サービス監視。フロントエンドからインフラまでワンストップで監視するなら&lt;a href=&quot;https://www.datadoghq.com/ja/&quot;&gt;Datadog&lt;/a&gt; か &lt;a href=&quot;https://newrelic.co.jp/platform&quot;&gt;Newrelic&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Datadogはログの保存が高い！一部だけ保存するようにするなどしないとお金がかかりまくる。&lt;/li&gt;
&lt;li&gt;DatadogのPHP APMは不安定らしい。&lt;/li&gt;
&lt;li&gt;そして、オーバーヘッドはだいたい10%ぐらい増加するっぽい。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://newrelic.co.jp/platform&quot;&gt;Newrelic One&lt;/a&gt;という新しいサービスは安くて良さそう。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;お知らせ&lt;/h2&gt;
</content:encoded></item><item><title>2020/11/27 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/2020-11-27-minedia-tech-talk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2020-11-27-minedia-tech-talk/</guid><description>2020年11月のテックニュースまとめ。PHP8リリース、Apple M1プロセッサへのLinus氏の反応、AWS Graviton2のコスパ、weworkのコワーキング動向などを紹介。</description><pubDate>Fri, 27 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;アドベントカレンダー&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;アドベントカレンダーの季節がやってまいりました。&lt;/li&gt;
&lt;li&gt;プレゼント付きアドベントカレンダーがあるので、ニッチな分野では当選しやすいと思います。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://qiita.com/advent-calendar/2020/categories/sponsor&quot;&gt;https://qiita.com/advent-calendar/2020/categories/sponsor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;スポンサーのプレゼント付きアドベントカレンダー自体は、スポンサー付きハッカソンに似てますね。&lt;/li&gt;
&lt;li&gt;P&amp;amp;Gでは数日かけてハッカソンを開催しています。大規模すごい。ガチハッカソンです。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://prtimes.jp/main/html/rd/p/000000042.000031986.html&quot;&gt;https://prtimes.jp/main/html/rd/p/000000042.000031986.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;おすすめ本&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;生々しい。ベンチャーマインドが垣間見られる。&lt;/li&gt;
&lt;li&gt;Box, Stripe, AirBnBなど有名ベンチャーがYcomから輩出されている。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://www.amazon.co.jp/Y%E3%82%B3%E3%83%B3%E3%83%93%E3%83%8D%E3%83%BC%E3%82%BF%E3%83%BC-%E3%82%B7%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%90%E3%83%AC%E3%83%BC%E6%9C%80%E5%BC%B7%E3%81%AE%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E9%A4%8A%E6%88%90%E3%82%B9%E3%82%AF%E3%83%BC%E3%83%AB-%E3%83%A9%E3%83%B3%E3%83%80%E3%83%AB%E3%83%BB%E3%82%B9%E3%83%88%E3%83%AD%E3%82%B9/dp/4822249468&lt;/p&gt;
&lt;h2&gt;コワーキングスペース&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;名古屋では供給が少ない。東京は逆に供給過多っぽいです。&lt;/li&gt;
&lt;li&gt;weworkでは月額39000円で、日本のすべての拠点が使えるキャンペーンをやってます。
&lt;ul&gt;
&lt;li&gt;https://www.wework.com/ja-JP/solutions/wework-all-access&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;拠点が結構増えましたね。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/11/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://signal.diamond.jp/articles/-/404&quot;&gt;tonari&lt;/a&gt;という環境側埋め込みのテレカンシステムが低遅延で良さそう。
&lt;ul&gt;
&lt;li&gt;独自プロトコルです。低遅延といっても数百ミリ秒はあるので中途半端な感じはしますが。&lt;/li&gt;
&lt;li&gt;ネットワークだけなら十数msぐらいのはずなので、テレカンの遅延の原因は、エンコード・デコード処理かなと思うので攻めるところは正しいかもしれないが。イグジットはM&amp;amp;Aか？&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Apple M1プロセッサ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Linus「もしLinuxが動くなら、絶対に欲しいです」と発言w&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.realworldtech.com/forum/?threadid=196533&amp;amp;curpostid=196570&quot;&gt;I&apos;d absolutely love to have one, if it just ran Linux&lt;/a&gt;..&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://gigazine.net/news/20201124-linus-torvalds-linux-m1-mac/&quot;&gt;https://gigazine.net/news/20201124-linus-torvalds-linux-m1-mac/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AWSでも同じような流れがある。&lt;a href=&quot;https://aws.amazon.com/jp/ec2/graviton/&quot;&gt;AWS Graviton2&lt;/a&gt;がリリースされて4倍ぐらいコスパが良くなった模様。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cyberagent.co.jp/blog/archives/27782/&quot;&gt;https://developers.cyberagent.co.jp/blog/archives/27782/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;アーキテクチャがx86からarmになるため、既存のx86インスタンスには適用できません。後はサーバソフトの動作確認が取れれば導入していっても良さそうです。完全に置き換えるまでは長い道のりになりそうです。&lt;/li&gt;
&lt;li&gt;t4gのprefixのインスタンスです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;PHP8リリース&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PHPのメジャーバージョンリリース。あんまり周辺ではバズってませんが。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.php.net/releases/8.0/en.php&quot;&gt;https://www.php.net/releases/8.0/en.php&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;slackのバックエンドはPHPらしい。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://slack.engineering/taking-php-seriously/&quot;&gt;https://slack.engineering/taking-php-seriously/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;engineeringっていうTLDがあるんですね。かっこいい。&lt;/li&gt;
&lt;li&gt;https://minedia.enginerring/ とか。&lt;/li&gt;
&lt;li&gt;ちょっとお高め&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/11/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;今後&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ゲストを招いてできればと思っているので、ご興味ある方は Twitter で &lt;a href=&quot;https://x.com/matsubokkuri&quot;&gt;@matsubokkuri&lt;/a&gt; へフォロー &amp;amp; mentionをお願いします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;お知らせ&lt;/h2&gt;
</content:encoded></item><item><title>2020/11/20 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/tech-news/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tech-news/</guid><description>2020/11/20 Minedia Tech Talk 今週のニュース</description><pubDate>Fri, 20 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前置き&lt;/h2&gt;
&lt;h2&gt;ニュース&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://jp.quora.com/Ruby-jQuery%E3%81%AA%E3%81%A9%E3%81%AE%E5%BB%83%E3%82%8C%E3%81%A6%E3%81%84%E3%81%8FOSS%E3%82%92%E9%96%8B%E7%99%BA%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E4%BA%BA%E9%81%94%E3%81%AF%E3%81%A9%E3%81%86%E3%81%84%E3%81%86&quot;&gt;Ruby、jQueryなどの廃れていくOSSを開発している人達はどういう気持ちで日々それらを開発しているんですか？回答するフォロー·9回答依頼&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Rubyオワコン発言にmatzが反応してます。&lt;/li&gt;
&lt;li&gt;まぁ、「廃れていく」という主観的な表現をする場合は背景や意図をしっかり書かないと。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://togetter.com/li/1625195&quot;&gt;中小企業なのにインターン育成に力を入れて大手企業に就職させてしまう会社、一体どうして？と思ったら数年後に秘密があった&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;長期スパンでの人材育成の視点です。&lt;/li&gt;
&lt;li&gt;インターン卒業生がインフルエンサーになる！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kobonemi.com/entry/2020/11/19/Apple-M1-MacBook-Air-8GB-RAM-Reviews&quot;&gt;8GBメモリのM1版MacBook Airの限界に挑戦！16GBはほとんどの人には必要ないことを検証&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Macbook Pro M1 手元では起動直後に8GBぐらい使われているけど足りるかな。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://b.hatena.ne.jp/entry/s/www.itmedia.co.jp/news/articles/2011/20/news061.html&quot;&gt;Apple、iPhone 12 miniの「ロック画面問題」をOSアップデートで解消&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;iOS 14.2.1 Releaseされました。主にmini対応なのでスルーでもOK。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://scrumguide-ja.kdmsnr.com/&quot;&gt;スクラムガイド 日本語版&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;スクラムガイドの日本語版がHTMLで出ました！助かります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wacul.co.jp/lab/google-analytics-important-10-points/&quot;&gt;成果を出す人がGoogleアナリティクスで使う機能は10個だけ。アクセス解析の実態調査&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Google Analytics内の機能の人気投票結果です。&lt;/li&gt;
&lt;li&gt;最近、GAが高機能化してメトリックスが多いので重要度が説明されているのは助かります。自分の視点と周りの視点を比較しできます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;今後&lt;/h2&gt;
</content:encoded></item><item><title>手元のMacBook Pro 16inchでGeekBench5してみた結果</title><link>https://blog.teraren.com/posts/macbook-pro-16inch-geekbench5/</link><guid isPermaLink="true">https://blog.teraren.com/posts/macbook-pro-16inch-geekbench5/</guid><description>手元のMacBook Pro 16inchでGeekBench5してみた結果</description><pubDate>Wed, 18 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;1年前に約30万円で買ったモデルで試してみます。&lt;a href=&quot;https://www.gizmodo.jp/2020/11/m1-benchmark-mac.html&quot;&gt;M1のベンチマーク&lt;/a&gt;と比較してどの程度家を見てみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/11/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ベンチマーク結果&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://browser.geekbench.com/v5/cpu/4803081&quot;&gt;https://browser.geekbench.com/v5/cpu/4803081&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/11/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/11/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;CPUの稼働状況&lt;/p&gt;
&lt;h2&gt;比較&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;M1のMacbook airの結果が1741，7656なので、負けてますね。&lt;/li&gt;
&lt;li&gt;1年前に、個人PCをMacBook Proに買い換えなくてよかったです。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>新型コロナウィルス陽性者グラフのFeed</title><link>https://blog.teraren.com/posts/covid19-japan-graph-feed/</link><guid isPermaLink="true">https://blog.teraren.com/posts/covid19-japan-graph-feed/</guid><description>新型コロナウィルス陽性者グラフのFeed</description><pubDate>Tue, 17 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;以前、&lt;a href=&quot;/posts/tokyo-covid19-graph/&quot;&gt;毎日の新型コロナウィルス陽性者数のグラフを投稿するTwitter Bot&lt;/a&gt;を作ったのですが、神奈川県以外すべてTwitterにBanされました。&lt;/li&gt;
&lt;li&gt;プラットフォームに依存するとBanされたときに困るので1次情報源は自分のサイトで運営すべきだと感じたのでWordPressに投稿するようにしました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;今回作ったサイト&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://covid19.teraren.com/&quot;&gt;https://covid19.teraren.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/11/image-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;FeedlyでRSS購読した例&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/11/image-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;都道府県をカテゴリ名としています。購読したいカテゴリのatom feedを購読してもらえればと思います。&lt;/li&gt;
&lt;li&gt;東京のRSS例：&lt;a href=&quot;https://covid19.teraren.com/category/tokyo/feed/&quot;&gt;https://covid19.teraren.com/category/tokyo/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ソースコードはこちら
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/covid19-daily-tweet/pull/49&quot;&gt;https://github.com/matsubo/covid19-daily-tweet/pull/49&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>2020/11/13 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/news/</link><guid isPermaLink="true">https://blog.teraren.com/posts/news/</guid><description>2020/11/13 Minedia Tech Talk 今週のニュース</description><pubDate>Fri, 13 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前置き&lt;/h2&gt;
&lt;h2&gt;ニュース&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;macOSのメジャーアップデートが降ってきた！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;容量は12GBです。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://pc.watch.impress.co.jp/docs/news/1288866.html&quot;&gt;https://pc.watch.impress.co.jp/docs/news/1288866.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;M1チップのベンチマークが出てきた&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gigazine.net/news/20201112-apple-silicon-m1-benchmark-score/&quot;&gt;https://gigazine.net/news/20201112-apple-silicon-m1-benchmark-score/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;エンジニアは最低でも32GB無いと厳しいので、もう少し待ちかも。MBP 16inchが出てくるはず。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;mac miniでも16GB。メモリがチップに内蔵されているから増設とか無理なのね。(unified memory architectureと呼ぶらしい)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://pc.watch.impress.co.jp/docs/news/1288311.html&quot;&gt;https://pc.watch.impress.co.jp/docs/news/1288311.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;iMacも新しいのが出たらしい。こちらはIntel&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.apple.com/jp/imac/&quot;&gt;https://www.apple.com/jp/imac/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mac製品買い時がわかるサイト&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://appledays.santalab.me/&quot;&gt;https://appledays.santalab.me/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gitコマンドノウハウ。ほとんど既知だけど一部は参考になる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zenn.dev/takuya/articles/7550d21ddd17f121602e&quot;&gt;https://zenn.dev/takuya/articles/7550d21ddd17f121602e&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;こういう、結構プロっぽい人の操作動画や録画は非常に参考になる。あんまり出回らないので。そして、shellの見た目が私と酷似しているので親近感ある。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Firebase summitまとめ&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nabettu.com/9359dcae953248e0b001046b0b49459c&quot;&gt;https://nabettu.com/9359dcae953248e0b001046b0b49459c&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HomePod miniが良い音だし、音場の制御が賢そう。スモールオフィスに1つ欲しい。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://japanese.engadget.com/homepodmini-140005690.html&quot;&gt;https://japanese.engadget.com/homepodmini-140005690.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;google chromeにゼロデイ脆弱性&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gizmodo.jp/2020/11/google-chrome-update-now.html&quot;&gt;https://www.gizmodo.jp/2020/11/google-chrome-update-now.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;今後&lt;/h2&gt;
</content:encoded></item><item><title>Ferdiで「Grrr! A pop-up blocker may be preventing...」エラーが出る場合の対処法</title><link>https://blog.teraren.com/posts/ferdi-popup-blocker-error/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ferdi-popup-blocker-error/</guid><description>FerdiでGmailを開くと「A pop-up blocker may be preventing the application from opening the page」エラーが出る場合の修正方法。User-Agentの変更で解決。</description><pubDate>Wed, 11 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;症状&lt;/h2&gt;
&lt;p&gt;Ferdi（メッセージングアプリのアグリゲーター）でGmailを開こうとすると、以下のエラーが表示されてログインできない。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Grrr! A pop-up blocker may be preventing the application from opening the page. If you have a pop-up blocker, try disabling it to open the window.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ポップアップブロッカーの問題のように見えるが、実際にはポップアップとは無関係。&lt;/p&gt;
&lt;h2&gt;原因&lt;/h2&gt;
&lt;p&gt;FerdiがGmailにアクセスする際に送信するUser-Agent文字列が古く、Googleがそのブラウザバージョンをブロックしている。1年近く前からGitHubに報告されている既知の不具合（&lt;a href=&quot;https://github.com/ferdium/ferdium-app&quot;&gt;ferdium/ferdium-app&lt;/a&gt;、旧getferdi/ferdi#321）。&lt;/p&gt;
&lt;h2&gt;対処法&lt;/h2&gt;
&lt;p&gt;Gmailのレシピファイル内のUser-Agent文字列を新しいバージョンに更新する。&lt;/p&gt;
&lt;h3&gt;1. 設定ファイルを開く&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;open ~/Library/Application\ Support/Ferdi/recipes/gmail/index.js
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. User-Agent文字列を変更&lt;/h3&gt;
&lt;p&gt;9行目あたりにあるUser-Agent文字列を、現在のChromeのバージョンに合わせて更新する。&lt;/p&gt;
&lt;p&gt;変更後のファイルはこちら: https://gist.github.com/matsubo/3d4bb8c7292f7b7b2daf53d5a818c956&lt;/p&gt;
&lt;h3&gt;3. Ferdiを再起動&lt;/h3&gt;
&lt;p&gt;設定ファイルを保存してFerdiを再起動すると、Gmailが正常に表示される。&lt;/p&gt;
</content:encoded></item><item><title>2020/11/16 Minedia Tech Talk 今週のニュース</title><link>https://blog.teraren.com/posts/news-of-week/</link><guid isPermaLink="true">https://blog.teraren.com/posts/news-of-week/</guid><description>2020/11/16 Minedia Tech Talk 今週のニュース</description><pubDate>Fri, 06 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前置き&lt;/h2&gt;
&lt;h2&gt;ニュース&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;5Gエリアが極小。1本のアンテナで半径150m程度っぽい。これは敷設が大変そう。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www13.info-mapping.com/au/map/index.aspx?maptype=5g&amp;amp;l=35.6939457%2c139.7011918&amp;amp;z=6&quot;&gt;http://www13.info-mapping.com/au/map/index.aspx?maptype=5g&amp;amp;l=35.6939457%2c139.7011918&amp;amp;z=6&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;moment.jsがメンテナンスモード。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://devblog.thebase.in/entry/2020/11/05/110000&quot;&gt;https://devblog.thebase.in/entry/2020/11/05/110000&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TLS証明書の期限が短くなる。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ssl.sakura.ad.jp/column/shortened-ssl/&quot;&gt;https://ssl.sakura.ad.jp/column/shortened-ssl/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;iOS 14.2 released
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://iphone-mania.jp/news-327009/&quot;&gt;https://iphone-mania.jp/news-327009/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;標識フォントすごい。。。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://kokagem.sakura.ne.jp/font/michishirube/&quot;&gt;http://kokagem.sakura.ne.jp/font/michishirube/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;WSL2すごい。WindowsでもMacと同じ用に開発できるね。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://speakerdeck.com/noriyukitakei/wslvscodedocker?slide=98&quot;&gt;https://speakerdeck.com/noriyukitakei/wslvscodedocker?slide=98&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11/11 apple 新アーキテクチャ発表
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://k-tai.watch.impress.co.jp/docs/news/1286724.html&quot;&gt;https://k-tai.watch.impress.co.jp/docs/news/1286724.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.apple.com/apple-events/&quot;&gt;https://www.apple.com/apple-events/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SSG: Static Site Generators
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://jamstack.org/generators/&quot;&gt;NextとGatsbyが主流&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Netlify使ってみたい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;zenn.devはNext.js
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zenn.dev/catnose99/articles/zenn-dev-stack&quot;&gt;https://zenn.dev/catnose99/articles/zenn-dev-stack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;すぐ動くことは動く。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nextjs.org/learn&quot;&gt;https://nextjs.org/learn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;今後&lt;/h2&gt;
</content:encoded></item><item><title>LVMのファイルシステムをいきなりlvreduceして壊しかけた</title><link>https://blog.teraren.com/posts/lvm-lvreduce/</link><guid isPermaLink="true">https://blog.teraren.com/posts/lvm-lvreduce/</guid><description>マウント中のLVMボリュームをlvreduceしてファイルシステムを破損させた失敗談と、umount→resize2fs→lvreduceの正しい縮小手順を解説します。</description><pubDate>Fri, 30 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;online(mount中)のlogical volumeのサイズをいきなり変更したら、ファイルシステムがバグってしまってOSがおかしくなって起動しなくなりました。&lt;/li&gt;
&lt;li&gt;そもそもumountしろという感じですが、EC2のEBSはオンラインで容量が拡張できるから逆に縮小もできると思い、実行してみたけど順番が違かった。。。&lt;/li&gt;
&lt;li&gt;raidのディスク構成を変更したかったので、830GB位あるlogical volumeを300GBに変更したかったのです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題のコマンドはこちら&lt;/h2&gt;
&lt;p&gt;↓&lt;strong&gt;オンライン中に実行してはいけません。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/matsu# lvreduce -L 300G /dev/mapper/dell--vg-root
  WARNING: Reducing active and open logical volume to 300.00 GiB.
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce dell-vg/root? [y/n]: y
  Size of logical volume dell-vg/root changed from 834.44 GiB (213617 extents) to 300.00 GiB (76800 extents).
  /etc/lvm/backup/dell-vg.tmp: fsync failed: Input/output error
  /etc/lvm/backup/dell-vg.tmp: fclose failed: Read-only file system
  Backup of volume group dell-vg metadata failed.
  Logical volume dell-vg/root successfully resized.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;THIS MAY DESTROY YOUR DATA (filesystem etc.) って書いてあるし。。。。コマンド実行中にもIOエラーが表示されちゃってますね。やばいです。&lt;/p&gt;
&lt;p&gt;lvmの構成情報は/etc/lvm/backup以下にバックアップされるのですが、/etc/にすでに書き込めなくなっちゃっているようです。その後はshellがおかしくなり、コマンドが徐々に打てなくなってきたのでrebootしました。&lt;/p&gt;
&lt;p&gt;もちろん、rebootしても正常に起動できないのでinitramfsが起動します。fsckを実行しても訂正されることはありません。fsckでチェックする領域は別のようです。&lt;/p&gt;
&lt;h2&gt;本来の手順&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://serverfault.com/questions/433275/lvm-logical-volume-partition-corrupted-after-lvreduce&quot;&gt;こちら&lt;/a&gt;の書き込みでは、以下のように説明されています。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;unmount&lt;/strong&gt;するか、&lt;strong&gt;オンラインでやるなら最初にresize2fs&lt;/strong&gt;（使っているファイルシステムによってコマンドは異なる）などで&lt;strong&gt;ファイルシステムのサイズを変更する&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;logical volumeを縮小する&lt;/li&gt;
&lt;li&gt;phisical volumeを縮小する&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;上記の記事から、認知していないといけないレイヤーの整理をいかに記載します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ファイルシステム&lt;/li&gt;
&lt;li&gt;Logical Volume&lt;/li&gt;
&lt;li&gt;Volume Group&lt;/li&gt;
&lt;li&gt;Phisical Volume&lt;/li&gt;
&lt;li&gt;Partition&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今回は、ファイルシステム上では変更前の800GBですが、Logical Volumeがいきなり300GBになったのでおかしくなりました。&lt;/p&gt;
&lt;h2&gt;復旧へ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntuのboot diskをUSBメモリに焼いて起動します。&lt;/li&gt;
&lt;li&gt;端末を立ち上げて、コマンドを打ちます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということで、Logical Volumeを、空き領域に対して全部使うように変更します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@ubuntu:/home/ubuntu# lvscan
  ACTIVE            &apos;/dev/data-vg/data&apos; [&amp;lt;3.64 TiB] inherit
  ACTIVE            &apos;/dev/dell-vg/root&apos; [534.45 GiB] inherit
  ACTIVE            &apos;/dev/dell-vg/swap_1&apos; [976.00 MiB] inherit
root@ubuntu:/home/ubuntu# lvresize -l +100%FREE /dev/mapper/dell--vg-root
  Size of logical volume dell-vg/root changed from 534.45 GiB (136820 extents) to 834.45 GiB (213620 extents).
  Logical volume dell-vg/root successfully resized.
root@ubuntu:/home/ubuntu# lvs
  LV     VG      Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  data   data-vg -wi-a-----  &amp;lt;3.64t
  root   dell-vg -wi-a----- 834.45g
  swap_1 dell-vg -wi-a----- 976.00m
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;fsckしてrebootします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@ubuntu:/home/ubuntu# fsck /dev/mapper/dell--vg-root
fsck from util-linux 2.34
e2fsck 1.45.5 (07-Jan-2020)
Clearing orphaned iノード 46935860 (uid=1000, gid=1000, mode=0100644, size=400721)
Clearing orphaned iノード 46932279 (uid=1000, gid=1000, mode=0100644, size=400542)
Clearing orphaned iノード 51380233 (uid=115, gid=125, mode=0100600, size=0)
Clearing orphaned iノード 51381297 (uid=115, gid=125, mode=0100600, size=0)
Clearing orphaned iノード 51381296 (uid=115, gid=125, mode=0100600, size=0)
Clearing orphaned iノード 51380238 (uid=115, gid=125, mode=0100600, size=4563)
Clearing orphaned iノード 17703601 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 17703596 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 17703594 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 17703593 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 17312060 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 17312056 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 17312055 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 17312054 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 15213286 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 15213285 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 15213284 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 15213283 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 12459447 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 12459443 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 12459439 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 12459438 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 18095575 (uid=0, gid=0, mode=0100644, size=776264)
Clearing orphaned iノード 12194905 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 12194904 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 12194903 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 12194895 (uid=999, gid=999, mode=0100600, size=0)
Clearing orphaned iノード 2883690 (uid=104, gid=4, mode=0100640, size=1642249)
Clearing orphaned iノード 2884265 (uid=0, gid=0, mode=0100644, size=339)
Clearing orphaned iノード 51380226 (uid=0, gid=0, mode=0100666, size=0)
Setting free iノードs count to 52970465 (was 53008249)
Setting free blocks count to 172967006 (was 173674078)
/dev/mapper/dell--vg-root: clean, 1719327/54689792 files, 45776802/218743808 blocks
root@ubuntu:/home/ubuntu# reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;エラーがたくさんありますが、だいたい良い感じに直ったようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/IMG_5497.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;lvresizeでもとに戻して、ちゃんと起動しました。よかった。。。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>storcliでraid5からraid6にmigrateできない</title><link>https://blog.teraren.com/posts/storcli-raid5-raid6-migrate/</link><guid isPermaLink="true">https://blog.teraren.com/posts/storcli-raid5-raid6-migrate/</guid><description>MegaRAIDコントローラーでstorcliを使いRAID5からRAID6へのオンラインマイグレーションを試みた際に発生したエラーの内容と対処記録をログとともに公開します。</description><pubDate>Thu, 29 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ログを書いておきます&lt;/p&gt;
&lt;h3&gt;physical disk&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/matsu# /opt/MegaRAID/storcli/storcli64 /c0/d0 show
Controller = 0
Status = Success
Description = Show Diskgroup Succeeded

TOPOLOGY :
========

--------------------------------------------------------------------------
DG Arr Row EID:Slot DID Type  State BT       Size PDC  PI SED DS3  FSpace
--------------------------------------------------------------------------
 0 -   -   -        -   RAID5 Optl  N  836.625 GB dsbl N  N   none N
 0 0   -   -        -   RAID5 Optl  N  836.625 GB dsbl N  N   none N
 0 0   0   252:0    6   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   1   252:1    5   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   2   252:2    7   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   3   252:3    4   DRIVE Onln  N  278.875 GB dsbl N  N   none -
--------------------------------------------------------------------------

DG=Disk Group Index|Arr=Array Index|Row=Row Index|EID=Enclosure Device ID
DID=Device ID|Type=Drive Type|Onln=Online|Rbld=Rebuild|Dgrd=Degraded
Pdgd=Partially degraded|Offln=Offline|BT=Background Task Active
PDC=PD Cache|PI=Protection Info|SED=Self Encrypting Drive|Frgn=Foreign
DS3=Dimmer Switch 3|dflt=Default|Msng=Missing|FSpace=Free Space Present
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;volume group&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/matsu# /opt/MegaRAID/storcli/storcli64 /c0/v0 show
Controller = 0
Status = Success
Description = None

Virtual Drives :
==============

-----------------------------------------------------------
DG/VD TYPE  State Access Consist Cache sCC       Size Name
-----------------------------------------------------------
0/0   RAID5 Optl  RW     Yes     RWTC  -   836.625 GB
-----------------------------------------------------------

Cac=CacheCade|Rec=Recovery|OfLn=OffLine|Pdgd=Partially Degraded|dgrd=Degraded
Optl=Optimal|RO=Read Only|RW=Read Write|HD=Hidden|B=Blocked|Consist=Consistent|
R=Read Ahead Always|NR=No Read Ahead|WB=WriteBack|
AWB=Always WriteBack|WT=WriteThrough|C=Cached IO|D=Direct IO|sCC=Scheduled
Check Consistency
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;raid5からraid6に変更したいけどできない&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/matsu# /opt/MegaRAID/storcli/storcli64 /c0/v0 start migrate type=raid6
Controller = 0
Status = Failure
Description = None

Detailed Status :
===============

---------------------------------------------
VD Operation Status ErrCd ErrMsg
---------------------------------------------
 0 MIGRATE   Failed     3 invalid arguments
---------------------------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;command help&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/matsu# /opt/MegaRAID/storcli/storcli64 /c0/v0 start migrate help
     Storage Command Line Tool  Ver 1.15.05 Jan 22, 2015

     (c)Copyright 2015, AVAGO Corporation, All Rights Reserved.

NAME: Start Migration

SYNTAX: storcli /cx/vx start migrate type=raidx [option=add|remove drives=[e:]s|[e:]s-x|[e:]s-x,y] [Force]

DESCRIPTION: Starts Migration on the specified virtual drive to a specified
                raid level

OPTIONS:
raidx - Raid level to which migration needs to be done.
        where x specifies the raid level value.
option -
        add - adds the specified PD to the migrated raid level.
        remove - removes the specified PD from the migrated raid level.
Drives - Specifies the list PD&apos;s which needs to be added or removed.
Force - If specified, then Migration will start even if any drive in the DG
        is secured by FDE
CONVENTION:
/cx - specifies the controller where X is the controller index
/vx - specifies the virtualdrive where X is the vd ID
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>小規模（5〜20人）オフィスのネットワーク構築例</title><link>https://blog.teraren.com/posts/8cdda8c874e3795225bc/</link><guid isPermaLink="true">https://blog.teraren.com/posts/8cdda8c874e3795225bc/</guid><description>それでは、2019年当時の構築記録をご覧ください!</description><pubDate>Mon, 26 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;⚠️ 2025年現在の読者の方へ&lt;/h2&gt;
&lt;p&gt;**この記事は2019年に書かれた内容です。**以下の点に注意してください:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RTX1200は2021年5月に保守終了しました&lt;/strong&gt; → 現在は使用を推奨しません&lt;/li&gt;
&lt;li&gt;新規構築の場合は &lt;a href=&quot;https://amzn.to/3JxsnFL&quot;&gt;RTX1300&lt;/a&gt; や &lt;a href=&quot;https://amzn.to/47CwauE&quot;&gt;RTX1220&lt;/a&gt; をご検討ください&lt;/li&gt;
&lt;li&gt;Wi-Fi 6E/7対応のアクセスポイントが主流になってきています&lt;/li&gt;
&lt;li&gt;IPv6対応は必須の時代になりました&lt;/li&gt;
&lt;li&gt;セキュリティ対策として、ゼロトラストネットワークの考え方が重要になってきています&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;それでは、2019年当時の構築記録をご覧ください!&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;株式会社マインディア CTO の &lt;a href=&quot;https://twitter.com/matsubokkuri&quot;&gt;@matsubokkuri&lt;/a&gt;です。&lt;/li&gt;
&lt;li&gt;事業規模の拡大に伴いオフィスの移転がありました。それに伴い社内ネットワークインフラの構築しました。オンサイトで働く人は約 10 名。エンジニアは私 1 名なのでインフラ整備を自分でやるか外注するかという選択でしたが、外注するためには RFP 作るのが面倒だし費用がかかるので DIY しました。&lt;/li&gt;
&lt;li&gt;中小企業のネットワーク構築の記事は 5 年前の &lt;a href=&quot;https://wadap.hatenablog.com/entry/2013/12/26/094008&quot;&gt;@wadap&lt;/a&gt;さんの記事が詳しいです。その記事以降、まとまった社内LAN構築の良い感じのノウハウ記事を見つけられませんでした。その5年の差分を埋めるためにも記録を書いておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要求定義&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ゲスト用ネットワークの分離（インターネット回線、LAN 回線）
&lt;ul&gt;
&lt;li&gt;将来のシステム監査で指摘されるであろうことなので。&lt;/li&gt;
&lt;li&gt;トラフィックの QoS 制御のため。&lt;/li&gt;
&lt;li&gt;インターネット上のホストにおいてグローバル IP アドレスによるアクセス制限がかかっている場合があるため。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;役割（部署）毎に LAN の分離
&lt;ul&gt;
&lt;li&gt;コンピュータウィルスなどのインシデントが発生した際、被害を限定的にするため。&lt;/li&gt;
&lt;li&gt;QoS 制御のため。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;安定
&lt;ul&gt;
&lt;li&gt;ストリーミングを扱う自社プロダクトを構築しているので安定性を高める。&lt;/li&gt;
&lt;li&gt;特に普段遣いをする Wi-Fi は安定してほしい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Wi-Fi と有線を用意して L1 レイヤの冗長性を確保しておく。&lt;/li&gt;
&lt;li&gt;有線 LAN の低遅延と安定性は素晴らしいです。
&lt;ul&gt;
&lt;li&gt;ルーターへの ping において、RTT が Wi-Fi では数 ms かかるのに対して有線では 1ms 以内です。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;グローバルネットワーク、LAN において低レイテンシー&lt;/li&gt;
&lt;li&gt;初期費用、固定費は安く。&lt;/li&gt;
&lt;li&gt;20 人ぐらいの同時利用ユーザに対応できる。
&lt;ul&gt;
&lt;li&gt;平均 3 台/人と想定して 60 端末同時接続&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ISP は 2 アカウント用意する。社員用の固定 IP とゲスト用。&lt;/li&gt;
&lt;li&gt;物理ネットワークの自由度を持たすために VLAN を使う。&lt;/li&gt;
&lt;li&gt;Wi-Fi が安定していること。&lt;/li&gt;
&lt;li&gt;オフィス外からネットワークに入れる。&lt;/li&gt;
&lt;li&gt;各席に有線。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設計&lt;/h2&gt;
&lt;p&gt;どんな機材を買ってどこに設置するのかを考えるためにネットワークの設計します。&lt;/p&gt;
&lt;p&gt;タグ VLAN が絡むと設計書を書くのが難しかったです。物理レイヤ(L1)と論理レイヤ(L2)を同時に考えて 1 つの図にする必要が有りました。これが結構難しかったです。&lt;/p&gt;
&lt;p&gt;論理レイヤで考えて、それを物理レイヤに落として。その逆を行ったりと。L1、L2、L3 を行ったり来たりして考えていました。vlan 使わなければ L1 だけ考えれば済むので超楽だなぁと思いました。&lt;/p&gt;
&lt;p&gt;VLAN を使わなければ、L1 と L2 は完全に分離して考えられるので非常に簡単ですが、VLAN が絡み出すと難易度がかなり上がります。本来は、論理と物理を分けて考えられて便利にするための VLAN なのに。&lt;/p&gt;
&lt;p&gt;一部に VLAN 非対応機器が存在したり、tag, untag を同一ネットワークに混在して設置できてしまうため、論理と物理が混ざってしまう原因でした。&lt;/p&gt;
&lt;p&gt;このあたり、想定した動作と各ベンダーの実装が若干違うので検証が大変でした。
例えば、ルーターは vlan の設定しかしていないのに、vlan ではないパケットも vlan1 として扱われてしまいます。
そうしないと vlan を設定した途端 untag のパケットが到達出来なくなったりするのを回避するためなのかと思います。&lt;/p&gt;
&lt;p&gt;どのツールで設計書を書くのが良いのかよくわからないのでとりあえず &lt;a href=&quot;https://cacoo.com/ja/&quot;&gt;cacoo&lt;/a&gt;で設計しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/sktqwygvfwrp8mnmch9hrvmcw12r&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;次に、図にある各エンティティについて詳細を書きます。&lt;/p&gt;
&lt;h3&gt;キャリア&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;フレッツ光ネクストで最高速 1Gbps のプランを使っています。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;余談&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最近評判が良いと聞く &lt;a href=&quot;https://www.nuro.jp/campaign/rmd/?recomndNo=dfs84206&quot;&gt;NURO 光&lt;/a&gt;を検討しましたが導入をやめました。&lt;/li&gt;
&lt;li&gt;NURO 光は個人と法人(Nuro Biz)で内容が全然違います。根本的なところで運営している会社自体が違います。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.nuro.jp/campaign/rmd/?recomndNo=dfs84206&quot;&gt;NURO光の個人&lt;/a&gt;の利用料は6,000円ぐらい（大人気らしく敷設に2ヶ月待ちとのことで、タイムラインが間に合わず断念）&lt;/li&gt;
&lt;li&gt;NURO 光の法人(NURO biz)の利用料は月額 20,000 円ぐらい。サポート充実。固定 IP あり。2 個 +6,000 円とかで予算感が合わずに断念。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ISP&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Web の管理画面にアクセス制限をつけるために、アクセス元のネットワークによってアクセス制限をしたいというユースケースがあります。それを代替できるアプローチが今のところないので、IPv4 の固定 IP アドレスが必要です。
&lt;ul&gt;
&lt;li&gt;サーバサイドからの視点では、やはり IP アドレス制限を入れる事でリスクを L3 以下は気にしないで良くなる利点は大きい&lt;/li&gt;
&lt;li&gt;IPv6 の固定レンジでの割り当てをする ISP はほぼ無い&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;固定 IP アドレスを提供する ISP は安いしいままで大きな問題が無かった GMO BB を引き続き使います。1,100 円/月（夜 20 時以降は少し遅い感じがします → &lt;a href=&quot;https://blog.teraren.com/2020/01/08/gmobb-to-sonet/&quot;&gt;遅いので解約して、so-netの固定IPオプションにしました&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;ゲスト用のネットワークは適当な ISP で良いので、キャリアと ISP の申し込みを同時にすると安いので適当に選びました。とりあえず IPv6 に対応している so-net にしました。&lt;a href=&quot;https://blog.teraren.com/2018/03/27/%e3%82%a4%e3%83%b3%e3%82%bf%e3%83%bc%e3%83%8d%e3%83%83%e3%83%88%e5%9b%9e%e7%b7%9a%e6%96%b0%e8%a6%8f%e5%a5%91%e7%b4%84%e2%86%92/&quot;&gt;家で使っていたとき&lt;/a&gt;は下りで400Mbps出ていたので。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ルーター&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;安く済ますために &lt;a href=&quot;https://network.yamaha.com/products/routers/rtx1200/index&quot;&gt;YAMAHA RTX1200&lt;/a&gt;です。10年近く前の機種ですが、1Gbps対応、L2TP対応、SNMP対応など十分な機能です。&lt;/li&gt;
&lt;li&gt;定価 125,000 円ですが、保守終わりの中古機材が &lt;a href=&quot;https://amzn.to/3TT49s8&quot;&gt;7,000円ぐらいで大量に流通&lt;/a&gt;しています。保証はないですが、壊れたら買えば良いのです。自宅でも使っていますが2年以上全く落ちませんでした。スループットも1Gbps近くまでは出ます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IPv6の複数の接続方式に対応するため&lt;/strong&gt;、新しいモデルである &lt;a href=&quot;https://amzn.to/3LRFmgx&quot;&gt;RTX1210&lt;/a&gt;をおすすめします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;スイッチ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;全部 YAMAHA で揃えて一元管理したいのが理想ですが、いかんせん VLAN 対応の YAMAHA のインテリジェントスイッチは高いです。中古でも出回ってないです。&lt;/li&gt;
&lt;li&gt;安い VLAN 対応のスイッチを選択。&lt;a href=&quot;https://amzn.to/48ymAqz&quot;&gt;Netgear GS108e&lt;/a&gt;を2台。約5,000円/台&lt;/li&gt;
&lt;li&gt;参考のために、8 ポートの YAMAHA SWX2200-8G は&lt;strong&gt;実売で約23,000円&lt;/strong&gt;。Netgear の 4 倍！&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Wi-Fi AP（アクセスポイント）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://network.yamaha.com/products/wireless_lan/wlx313/index&quot;&gt;YAMAHA WLX313&lt;/a&gt;で。実売約6万円。定価69,800円(税抜)。Wi-Fi AP だけはケチらずに買います。WLC（Wireless LAN Controller）と VLAN にも対応しております。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WLX313 はかなりいろんな機能があって良いのですが、&lt;strong&gt;自動制御が不安定です&lt;/strong&gt;。残念なのですが便利な機能は OFF にしまくってシンプルな設定にして運用する必要がありました。自動チャネル選択、自動出力変更などの便利そうな機能を一通り OFF にしました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PoE 対応なので、PoE スイッチに接続して使おうしたのですが普通の PoE スイッチでは&lt;strong&gt;電源容量が足りなくて&lt;/strong&gt;動きませんでした。Wi-Fi AP は消費電力が大きいので対応した PoE スイッチを選択する必要があります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;余談&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;市販の家庭用アクセスポイントはよく壊れます。&lt;/li&gt;
&lt;li&gt;コンシューマ向けの Wi-Fi アクセスポイントはすぐに詰まったり、電波飛ばなかったり、不安定な動作が多いです。&lt;/li&gt;
&lt;li&gt;自宅の AP は 1〜2 年おきに買い換えています。電波は目に見えなくてトラブルシューティングしづらいのでここはケチらず良い物を買いましょう。&lt;/li&gt;
&lt;li&gt;Cisco の meraki も見たのですが、小規模ビジネスでの実績がよくわからないし見た感じ安定性が心配だったので外しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;LANケーブル&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;今回は小規模だしケチりたいので自前で行います。自前で圧着するとなったら &lt;a href=&quot;https://amzn.to/3vtftBg&quot;&gt;テスタや圧着器など一式&lt;/a&gt;が必要になりますが、今後も使えるので買っておいて良いかなと。いつでも好きなときに好きな長さのLANケーブルを作れるようになります。&lt;/li&gt;
&lt;li&gt;楽天などにて 200 円/本で 0.5m から 5m のいろいろな長さの cat6 ケーブルが売っています。自分で圧着する時間を考えると買った方が安います。しかしながら、安い楽天にて買った LAN ケーブルは品質が悪くて断線が頻繁に起きました。&lt;/li&gt;
&lt;li&gt;かといって市販のケーブルは 500 円/m とかするので、10 本買うと 5,000 円ぐらいかかったりする。また、長い距離になると 5m 単位や 10m 単位のロットしかなくて配線の余りが出てきてしまいます。なので、自作します。&lt;/li&gt;
&lt;li&gt;今回買った &lt;a href=&quot;https://amzn.to/3RWsYRi&quot;&gt;エレコムのLANケーブル&lt;/a&gt;は安いのでケーブルの被覆と芯線がとても硬くて扱いづらいです。&lt;a href=&quot;https://amzn.to/3RWZNhf&quot;&gt;ローダー付きのRJ45&lt;/a&gt;じゃないとコネクタへのケーブルの挿入の難易度高すぎて無理でした。最初はローダー無しのRJ45を買ったのですが、穴に通らなくてローダー付きを書い直しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実装&lt;/h2&gt;
&lt;h3&gt;L1&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;どこに何を通すか設計します。業者からもらった室内の設計図では不十分なので、結局は現況を見てからちゃんと作りました。意外と図面は抽象的なので要注意です。&lt;/li&gt;
&lt;li&gt;現場では、図面に載っていない配線があったりしました。天井裏の配線は謎で、ケーブル通しを使って業者と 2 人がかりで捜索し、現場の作業員を勝手にお借りしてケーブル通しを手伝ってもらいました。頭数が 2 人は最低必要な状況でした。&lt;/li&gt;
&lt;li&gt;ケーブリングが終わったら、引き継ぎやすいように As-Is を残しておきます。モザイクばかりでよくわかりませんが。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/w8fia22k4djzmnzmxwxwuhdi31j8&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;機材の設定は、事前に一通り行って動作テストを行っておくことを強く推奨します。理由は以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;初期不良を検出する。&lt;/li&gt;
&lt;li&gt;現地はトラブルシュートをするための機材が少ないので、事前に資材や機材の環境が整ったところでトラブルシュートをする。&lt;/li&gt;
&lt;li&gt;現地ではインターネットにつながらない場合もあるため。&lt;/li&gt;
&lt;li&gt;特に VLAN とパケットフィルタの動作テストには時間がかかります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;動作テストのために 50cm のケーブルをたくさん作る事になって辛かったです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/rhtlgdgw4nhj9pmfq3sgmpoxuyv9&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;フリーアクセスなのでカーペットを剥がして床を見て見ると結構堅い締め付けでネジが締められていて、外すのが大変でした。インパクトドライバーが無いと堅くて緩まないので取りに帰りました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/4fwvlwbjrl10gs4xlv7dejcp8vai&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;インパクトドライバーでやっと開けられた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/ekn4k6ev9sezi15lzq6876r3fjph&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;仮に敷設。ケーブルが堅い。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/uvmmn0jvdz2ks86tw1ozfhm9tgwd&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;テーブルの上に置けるように、端っこは長めに残しておきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/l733wwx20rfpft5xvgpgcsqb66hh&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;床を元通りにして L1 は完了（床を剥がさないで線を通す方法、道具を教えてほしいです。&lt;a href=&quot;https://amzn.to/3MOvWDI&quot;&gt;通線&lt;/a&gt;で真っ直ぐを引っ張れるのでしょうか？）&lt;/p&gt;
&lt;p&gt;L1 の敷設は大変だけど、一般人にはわかってもらえなくて悲しいです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/nsfbyuvv6jpivc08v6ds4n5p4lju&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Wi-Fi Sanner で帯域をチェック。これを見て利用するチャネルを決めます。2GHz 帯は外から回り込んでくるのか、他社のが入ってきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/871thxpr4hzwnj7u5ne3aifnlhc6&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;電波が届きにくいところや、外への漏れ具合を確認するときには、&lt;a href=&quot;https://apps.apple.com/jp/app/wi-fi%E3%83%9F%E3%83%AC%E3%83%AB/id1132440751&quot;&gt;WiFiミレル&lt;/a&gt;を使ってチェックします。PCを持ち歩いてうろうろしないで良いので楽です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/njpeu82o0jx4tdpq42s74tyfg2u2&quot; alt=&quot;WiFiミレル&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ルーターの設定&lt;/h3&gt;
&lt;p&gt;RTX1200 の設定の要点をいくつか書いておきます。&lt;/p&gt;
&lt;p&gt;4 つの vlan を作ります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;社内リソース用&lt;/li&gt;
&lt;li&gt;エンジニア用&lt;/li&gt;
&lt;li&gt;biz 用&lt;/li&gt;
&lt;li&gt;ゲスト用&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;vlan lan1/4 802.1q vid=4
vlan lan1/5 802.1q vid=5
vlan lan1/6 802.1q vid=6
vlan lan1/7 802.1q vid=7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、どこからどこに何を通したいかを設定します。ネットワーク間は全てデフォルトではpassなので、一旦全てrejectした上で必要なパケットをpassさせていきます。&lt;/p&gt;
&lt;p&gt;ルール自体はとても複雑なので、使うか使わないかは別にしてルールは一旦全部作って起きます。その後、このルールをip pp secure filterで適用していきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip filter 600000 reject 192.168.4.0/24 192.168.5.0/24
ip filter 600001 reject 192.168.4.0/24 192.168.6.0/24
ip filter 600002 reject 192.168.4.0/24 192.168.7.0/24
ip filter 600011 reject 192.168.5.0/24 192.168.4.0/24
ip filter 600012 reject 192.168.5.0/24 192.168.6.0/24
ip filter 600013 reject 192.168.5.0/24 192.168.7.0/24
ip filter 600021 reject 192.168.6.0/24 192.168.4.0/24
ip filter 600022 reject 192.168.6.0/24 192.168.5.0/24
ip filter 600023 reject 192.168.6.0/24 192.168.7.0/24
ip filter 600031 reject 192.168.7.0/24 192.168.4.0/24
ip filter 600032 reject 192.168.7.0/24 192.168.5.0/24
ip filter 600033 reject 192.168.7.0/24 192.168.6.0/24
ip filter 600045 reject 192.168.4.0/24 192.168.5.0/24
ip filter 600046 reject 192.168.4.0/24 192.168.6.0/24
ip filter 600047 reject 192.168.4.0/24 192.168.7.0/24
ip filter 600054 reject 192.168.5.0/24 192.168.4.0/24
ip filter 600056 reject 192.168.5.0/24 192.168.6.0/24
ip filter 600057 reject 192.168.5.0/24 192.168.7.0/24
ip filter 600064 reject 192.168.6.0/24 192.168.4.0/24
ip filter 600065 reject 192.168.6.0/24 192.168.5.0/24
ip filter 600067 reject 192.168.6.0/24 192.168.7.0/24
ip filter 600074 reject 192.168.7.0/24 192.168.4.0/24
ip filter 600075 reject 192.168.7.0/24 192.168.5.0/24
ip filter 600076 reject 192.168.7.0/24 192.168.6.0/24
ip filter 600145 pass 192.168.4.0/24 192.168.5.0/24 icmp
ip filter 600146 pass 192.168.4.0/24 192.168.6.0/24 icmp
ip filter 600147 pass 192.168.4.0/24 192.168.7.0/24 icmp
ip filter 600154 pass 192.168.5.0/24 192.168.4.0/24 icmp
ip filter 600156 pass 192.168.5.0/24 192.168.6.0/24 icmp
ip filter 600157 pass 192.168.5.0/24 192.168.7.0/24 icmp
ip filter 600164 pass 192.168.6.0/24 192.168.4.0/24 icmp
ip filter 600165 pass 192.168.6.0/24 192.168.5.0/24 icmp
ip filter 600167 pass 192.168.6.0/24 192.168.7.0/24 icmp
ip filter 600174 pass 192.168.7.0/24 192.168.4.0/24 icmp
ip filter 600175 pass 192.168.7.0/24 192.168.5.0/24 icmp
ip filter 600176 pass 192.168.7.0/24 192.168.6.0/24 icmp
ip filter 600245 pass 192.168.4.0/24 192.168.5.0/24 * 631
ip filter 600246 pass 192.168.4.0/24 192.168.6.0/24 * 631
ip filter 600247 pass 192.168.4.0/24 192.168.7.0/24 * 631
ip filter 600254 pass 192.168.5.0/24 192.168.4.0/24 * 631
ip filter 600256 pass 192.168.5.0/24 192.168.6.0/24 * 631
ip filter 600257 pass 192.168.5.0/24 192.168.7.0/24 * 631
ip filter 600264 pass 192.168.6.0/24 192.168.4.0/24 * 631
ip filter 600265 pass 192.168.6.0/24 192.168.5.0/24 * 631
ip filter 600267 pass 192.168.6.0/24 192.168.7.0/24 * 631
ip filter 600274 pass 192.168.7.0/24 192.168.4.0/24 * 631
ip filter 600275 pass 192.168.7.0/24 192.168.5.0/24 * 631
ip filter 600276 pass 192.168.7.0/24 192.168.6.0/24 * 631
ip filter 610047 pass 192.168.4.0/24 192.168.7.0/24 icmp
ip filter 610048 pass 192.168.7.0/24 192.168.4.0/24 icmp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ipv6の設定。社員用はIPv4のアクセス制限があるので、IPv6の利用はゲストネットワークのみにします。lan1/6がゲストネットワークのvlanです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ipv6 prefix 1 ra-prefix@lan2::/64
ipv6 lan1/6 address ra-prefix@lan2::1/64
ipv6 lan1/6 rtadv send 1 o_flag=on
ipv6 lan1/6 dhcp service server
ipv6 lan2 secure filter in 200030 200031 200038 200039
ipv6 lan2 secure filter out 200099 dynamic 200080 200081 200082 200083 200084 200085 200086 200098 200099
ipv6 lan2 dhcp service client ir=on
ipv6 filter 200030 pass * * icmp6 * *
ipv6 filter 200031 pass * * 4
ipv6 filter 200038 pass * * udp * 546
ipv6 filter 200039 reject * *
ipv6 filter 200099 pass * * * * *
ipv6 filter dynamic 200080 * * ftp
ipv6 filter dynamic 200081 * * domain
ipv6 filter dynamic 200082 * * www
ipv6 filter dynamic 200083 * * smtp
ipv6 filter dynamic 200084 * * pop3
ipv6 filter dynamic 200085 * * submission
ipv6 filter dynamic 200086 * * https
ipv6 filter dynamic 200098 * * tcp
ipv6 filter dynamic 200099 * * udp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ゲストネットワークのQoSを最初は設定していましたが、ユーザが少ないので撤廃しました。&lt;/p&gt;
&lt;p&gt;ゲストネットワークには帯域を100MBpsまでしか割り当てない設定例。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;queue lan1 type shaping
queue lan1 class filter list 1 2
queue lan1 class property 1 bandwidth=100M
queue class filter 1 1 ip 192.168.6.0/24 * * * *
queue class filter 2 1 ip * 192.168.6.0/24 * * *
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;うるさいログをoffにしたり。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip filter dynamic 200080 * * ftp syslog=off
ip filter dynamic 200081 * * domain syslog=off
ip filter dynamic 200082 * * www syslog=off
ip filter dynamic 200083 * * smtp syslog=off
ip filter dynamic 200084 * * pop3 syslog=off
ip filter dynamic 200085 * * submission syslog=off
ip filter dynamic 200098 * * tcp syslog=off
ip filter dynamic 200099 * * udp syslog=off
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;とある日のトラフィックはこんな感じです。
&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/6ttb8aatylv78tm5u9peyvuw43sf&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/5j0w2ylpxwq8eshbkbtfxa6z5jwa&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;スイッチの設定&lt;/h3&gt;
&lt;p&gt;ブラウザ上で vlan の設定をポチポチとやります。&lt;/p&gt;
&lt;p&gt;設定値は以下のような感じです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/yfb9d897zfyhdy1u65oma9fczqzc&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;安い VLAN 対応スイッチですが簡単な統計は出ます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/chju60450w7ino9bielk2v4aa0gk&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Wi-Fi APの設定&lt;/h3&gt;
&lt;p&gt;周波数と SSID が分離されていて設定しやすいです。このご時世、2.4GHz をオフにしていてもクレームは出ませんでした。&lt;/p&gt;
&lt;p&gt;AP の設定は以下のような感じです。VLAN に対応してアクセスポイント名を設定しています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/t64yb5kd1w4hxibybmxogyy97xs3&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;L1 の敷設です。Wi-Fi AP は上の方に設置して降らせる感じで電波を飛ばすのが良いみたいなので上部に設置します。&lt;/p&gt;
&lt;p&gt;壁に穴を開けて、Wi-Fi を設置したところです。ケーブルが露出していて汚いのでモールでカバーをします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/lze6l26syr5q2rnvbxrf53mcm9r5&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Viva ホームで買ってきたモールです。マルチカッターで切ります。2 秒位でカットできます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/o8m8g4uqh1fy0m55v48k5uejoim5&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;完了した状態です（アンテナの向き地面に対して垂直が正しく、写真の状態は間違い）。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/7kcyv9v9omoyr2lkjl18dqkalqow&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Chromecastを設置&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;会議室のテレビには &lt;a href=&quot;https://amzn.to/3Hdvb5R&quot;&gt;Chromecast&lt;/a&gt;を設置しました。ゲストネットワークに参加させておきます。&lt;/li&gt;
&lt;li&gt;来訪者が Wi-Fi に繋げれば、Windows と macOS からも会議室のテレビをワイヤレスで投影できるので便利です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/og7tgghlmyjv9x6h5q1tilmxhjwe&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;設定管理&lt;/h3&gt;
&lt;p&gt;API で制御は出来ないので、Infrastructure as Code の理想に近づけるためにも設定ファイルをダンプして GitHub で管理。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/34e8y9eu05wjfglf5ye8hi52gts7&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;初期コスト: &lt;strong&gt;約11万円&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/o6tg8lkxd6fuxymms32ee6q5trav&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ランニングコスト: &lt;strong&gt;1万円未満/月&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;Wi-Fi でのベンチマーク
&lt;img src=&quot;../../assets/uploads/2020/10/2023-12-05-10-53-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;有線でのベンチマーク
&lt;img src=&quot;../../assets/uploads/2020/10/2023-12-05-10-56-24.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;IPv6 の設定テスト結果
&lt;img src=&quot;https://storage.googleapis.com/zenn-user-upload/p2c9mle2ta57roo2u9gozw55ewq7&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2019 年 4 月〜2023 年 10 月の 4 年半が経過した現在、問題は 1 度も起きておりません。&lt;/li&gt;
&lt;li&gt;1 年に 1 回程度、ファームウェアの更新しているので再起動しています。&lt;/li&gt;
&lt;li&gt;Wi-Fi だけで事足りてしまうようで、有線 LAN はほぼ使われていないです。OS のアップデートなどで数百 GB のダウンロードをする際には周りの Wi-Fi ユーザに迷惑をかけないという意味でも有線を使うのが良いです。早く終わるし。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;オフィスの引っ越しに伴いネットワークを構築しました。&lt;/li&gt;
&lt;li&gt;工数は 10 人日ぐらい使いました（キャリア選定、機器選定、L1,L2 設計、施工、設定、テスト、ケーブル作成など）&lt;/li&gt;
&lt;li&gt;もし、在宅環境を整備するなら：&lt;a href=&quot;https://amzn.to/3PLkjzh&quot;&gt;YAMAHA RTX830&lt;/a&gt; + &lt;a href=&quot;https://amzn.to/41Y6vb9&quot;&gt;WLX212&lt;/a&gt; or &lt;a href=&quot;https://network.yamaha.com/products/wireless_lan/wlx313/index&quot;&gt;WLX313&lt;/a&gt;を入れておけば完璧かなと。WiFi6はまだ理論値をちゃんと出せるハードウェアが無いので気にしなくて良いかと思います。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>docker-compose経由でMySQLのデータをバックアップとリストア</title><link>https://blog.teraren.com/posts/docker-compose-mysql-backup-and-restore/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-compose-mysql-backup-and-restore/</guid><description>docker-compose経由でMySQLのデータをバックアップとリストア</description><pubDate>Thu, 15 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Backup&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;docker-compose run --rm app bash -c &apos;mysqldump -u root --password=${MYSQL_ROOT_PASSWORD} -h ${MYSQL_HOSTNAME} --all-databases &amp;gt; dump.sql&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Restore&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;docker-compose run --rm app bash -c &apos;mysql -u root --password=${MYSQL_ROOT_PASSWORD} -h ${MYSQL_HOSTNAME} &amp;gt; dump.sql&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Docker for macosを2.4.0にあげて、デフォルトの&lt;a href=&quot;https://stackoverflow.com/questions/62442611/innodb-initialization-warnings&quot;&gt;gRPCがonの状態だとエラー&lt;/a&gt;になる。&lt;/li&gt;
&lt;li&gt;DBを作り直せば解決される。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[Server] Different lower_case_table_names settings for server (&apos;2&apos;) and data dictionary (&apos;0&apos;).
[Server] Data Dictionary initialization failed.
[Server] Aborting
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Ubuntu 20のサーバにWiFi6導入→なぜか遅い</title><link>https://blog.teraren.com/posts/linux-wifi6/</link><guid isPermaLink="true">https://blog.teraren.com/posts/linux-wifi6/</guid><description>Ubuntu 20.04サーバにIntel製WiFi6アダプター（Archer TX3000e）をPCIe増設した際の設定手順と、速度が期待値に達しなかった原因の調査記録</description><pubDate>Tue, 13 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/ubuntu-19-04-rtl88x2bu/&quot;&gt;Ubuntu 19.04でrtl88x2buをインストール&lt;/a&gt;の続編です。&lt;/li&gt;
&lt;li&gt;以前に買ったWiFiアダプターの謳い文句に「1200Mbps出る」と書いてありますが実際は全然速度が出ません。そこで今回はWiFi6対応のArcher TX3000eを買いました。&lt;/li&gt;
&lt;li&gt;しかしながら、ドライバか何かの影響で速度が出ません。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B07Y4Z89MR&quot;}&lt;/p&gt;
&lt;h2&gt;取り付け&lt;/h2&gt;
&lt;p&gt;PCIeに刺すだけ。サーバの筐体たとステー部分のネジも不要なので簡単に取り付けられて良い。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/image-5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;環境&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% lsb_release  -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.1 LTS
Release:        20.04
Codename:       focal
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ドライバのインストールは不要でした。さすがIntelのチップが載っているだけある。&lt;/p&gt;
&lt;p&gt;iwconfigを打って出てくるこのwlp9s0デバイスが新しく追加したものかと思う。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% lspci|grep AX
09:00.0 Network controller: Intel Corporation Wi-Fi 6 AX200 (rev 1a)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;% ifconfig
wlp9s0    IEEE 802.11  ESSID:off/any
          Mode:Managed  Access Point: Not-Associated   Tx-Power=22 dBm
          Retry short limit:7   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:on
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;nmcliコマンドで設定を打って終わり。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo nmcli device wifi connect &apos;xxxxxxxx&apos; password &apos;xxxxxxxx&apos; ifname wlp9s0
% ifconfig
wlp9s0: flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt;  mtu 1500
        inet 192.168.1.18  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 240f:78:af46:1:db6e:285e:7642:f9d1  prefixlen 64  scopeid 0x0&amp;lt;global&amp;gt;
        inet6 240f:78:af46:1:7594:3204:f393:98e6  prefixlen 64  scopeid 0x0&amp;lt;global&amp;gt;
        inet6 fe80::d72:face:dbc7:89b2  prefixlen 64  scopeid 0x20&amp;lt;link&amp;gt;
        ether a8:7e:ea:cb:04:f3  txqueuelen 1000  (Ethernet)
        RX packets 748331  bytes 339021359 (339.0 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 43668  bytes 1272545886 (1.2 GB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかし、なぜか遅い！！270Mbpsという表示が出る。。。&lt;/p&gt;
&lt;p&gt;WiFi6のAP側は問題ないことはiPhone11との接続で確認しているのでこのデバイスの設定に問題があるのだろうが。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;最新ドライバのインストール&lt;/h3&gt;
&lt;p&gt;以下のサイトを参考に、最新のドライバを入れてみる。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://asobod11138.com/2020/01/07/ubuntu18-04-3%E3%82%92%E3%83%8E%E3%83%BC%E3%83%88pc%E3%81%AB%E5%85%A5%E3%82%8C%E3%81%9F%E3%82%89wi-fi%E3%81%8C%E7%B9%8B%E3%81%8C%E3%82%89%E3%81%AA%E3%81%8F%E3%81%A6%E5%9B%B0%E3%81%A3%E3%81%9F/&quot;&gt;https://asobod11138.com/2020/01/07/ubuntu18-04-3%E3%82%92%E3%83%8E%E3%83%BC%E3%83%88pc%E3%81%AB%E5%85%A5%E3%82%8C%E3%81%9F%E3%82%89wi-fi%E3%81%8C%E7%B9%8B%E3%81%8C%E3%82%89%E3%81%AA%E3%81%8F%E3%81%A6%E5%9B%B0%E3%81%A3%E3%81%9F/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://unix.stackexchange.com/questions/518571/locating-drivers-for-intel-ax200-wireless-on-5-1-kernel&quot;&gt;https://unix.stackexchange.com/questions/518571/locating-drivers-for-intel-ax200-wireless-on-5-1-kernel&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;modprobe -rをすると、稼働中のWiFiが落ちるので注意。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget https://wireless.wiki.kernel.org/_media/en/users/drivers/iwlwifi/iwlwifi-cc-46.3cfab8da.0.tgz
% tar xf iwlwifi-cc-46.3cfab8da.0.tgz
% cd iwlwifi-cc-46.3cfab8da.0/
% sudo cp iwlwifi-cc-a0-46.ucode /lib/firmware
% sudo modprobe -r iwlwifi &amp;amp;&amp;amp;  sudo modprobe iwlwifi
% nmcli dev wifi list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかし、相変わらずの270 Mbit/sという表示。&lt;/p&gt;
&lt;p&gt;wavemonを入れてみてみると、RXが1000Mbpsの表示。何が正しいのかわからないです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ベンチマークも非常に遅い。。。 &amp;gt; 52.3 Mbits/sec&lt;/p&gt;
&lt;p&gt;引き続き調査。&lt;/p&gt;
&lt;h2&gt;追加設定&lt;/h2&gt;
&lt;p&gt;省電力モードをオフにしておく。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /etc (master) [128]# git diff NetworkManager/conf.d/default-wifi-powersave-on.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/NetworkManager/conf.d/default-wifi-powersave-on.conf b/NetworkManager/conf.d/default-wifi-powersave-on.conf
index 23a6889..111af0b 100644
--- a/NetworkManager/conf.d/default-wifi-powersave-on.conf
+++ b/NetworkManager/conf.d/default-wifi-powersave-on.conf
@@ -1,2 +1,2 @@
 [connection]
-wifi.powersave = 3
+wifi.powersave = 2
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>KDDIが利用を強要するホームゲートウェイ(NEC製)の機能がショボすぎるのでAU光を契約する際は要注意</title><link>https://blog.teraren.com/posts/kddi-aterm-875ae1/</link><guid isPermaLink="true">https://blog.teraren.com/posts/kddi-aterm-875ae1/</guid><description>KDDI au光で強制使用されるNEC製ATERM-875AE1の問題点。DHCP最大64台制限、発熱、NAT不具合など実際の運用で発覚した欠陥を詳細にレポート。</description><pubDate>Thu, 08 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;NEC製 ATERM-875AE1。外箱はおしゃれだけど、中身は低機能。&lt;/p&gt;
&lt;p&gt;DHCPサーバのIPv4割当アドレスの数が最大&lt;strong&gt;64&lt;/strong&gt;だけしかありません！65と指定すると「入力範囲外」と表示されて設定できません。大量のノードを運用されている方は、ネットワークを分割するなどの対策が必要になります。&lt;/p&gt;
&lt;p&gt;DHCP関連のパラメータはほとんど&lt;strong&gt;調整できません&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;パケットフィルタや静的NATの設定もとてもやりづらい。。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/image-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そして、機器自体の発熱が多い！&lt;/p&gt;
&lt;p&gt;説明書には、前後左右に排熱用にマージンを開けろと書いてあったので、怪しいなぁと思っていました。&lt;/p&gt;
&lt;p&gt;運用しだしたら、案の定、トラフィックが殆どないのにほんのり温かくなります。人肌より温かいので40度は超えています。夏が心配です。&lt;/p&gt;
&lt;p&gt;ハードウェアはこれかな。&lt;a href=&quot;https://www.au.com/support/service/internet/guide/modem/gateway-05/&quot;&gt;https://www.au.com/support/service/internet/guide/modem/gateway-05/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ATERM-875AE1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;隣接して壁などの遮蔽物と接しないように、台座が大きく取られています。しかも、スロープが付いているので重ねることも難しいといういやらしい設計です。&lt;/p&gt;
&lt;h2&gt;追記：IPv4のルーティングが変&lt;/h2&gt;
&lt;p&gt;LANで公開しているサーバにアクセスしたら、TSLの証明書エラーが出ました。&quot;kantan.setuzoku.example.com&quot;というホスト名に対して発行された証明書が返答された模様。&lt;/p&gt;
&lt;p&gt;一度、携帯キャリアの回線でテザリングをして、再度LANに接続したら正常に戻りました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/Screen-Shot-2020-10-11-at-21.10.19.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;表示されるページ&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/11/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;404 Not Found File not found.&lt;/p&gt;
&lt;p&gt;Tweet元のアカウントが凍結されているけど、同じ報告を発見&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/Screen-Shot-2020-10-11-at-21.14.59.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;おそらく、ルーターのNAT周りの実装が変になっている様子。。。&lt;/p&gt;
&lt;p&gt;NECルーターは&lt;a href=&quot;/posts/nec-router-auto-reboot/&quot;&gt;10年前にも一定時間でハングアップするという問題&lt;/a&gt;があってとてもストレスたまりました。&lt;/p&gt;
&lt;h2&gt;追記 2020年11月25日&lt;/h2&gt;
&lt;p&gt;上記のNATの問題に対して、サポートに「このルーターの利用を強要されている身としてはどうしようもないから無料で解約させて」と申し出たら、冷たい反応。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;大変恐縮ではございますが、契約期間内でのご解約の場合、&lt;/p&gt;
&lt;p&gt;契約解除料7,700円（税込）が発生いたします。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ローカルでDNSサーバ立てるしか無いのか。。。。面倒。DNSサーバを立てたとしてもDHCPのパラメータがいじれないから手動でDNSサーバを設定しないといけない。&lt;/p&gt;
&lt;p&gt;それを避けるためにはネットワークをLANで1つ切って、DHCPサーバによるDNSサーバのアドレスを指定できるルーターを使う必要がある。&lt;/p&gt;
&lt;h2&gt;追記：2021年1月28日&lt;/h2&gt;
&lt;p&gt;IPv6アドレスならばNATされないので正常にアクセスできます。&lt;/p&gt;
&lt;p&gt;IPv6を優先しつつ、自宅サーバはIPv6のアドレスも振れば運用上はカバーできます。&lt;/p&gt;
&lt;p&gt;普通のPC起動直後や、IPv6アドレスが振られる前の状態でIPv4しか使えない状態だと失敗するので少し待ったり、WiFiをon/offしたりしてIPv6が優先されるまで待ちましょう。&lt;/p&gt;
</content:encoded></item><item><title>MegaRAIDのパフォーマンスチューニング</title><link>https://blog.teraren.com/posts/megaraid-parameter-set/</link><guid isPermaLink="true">https://blog.teraren.com/posts/megaraid-parameter-set/</guid><description>DellサーバのMegaRAID SASコントローラーでWriteBackキャッシュやRead Aheadを設定し、MySQL起因のディスクI/Oノイズを軽減したチューニング手順</description><pubDate>Tue, 06 Oct 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;以前買ったDellのサーバにディスクIOが断続的に発生しています。そのたびにSASへのdisk writeが発生してSASのディスクアクセスの音がうるさいです。iotopを見てみると、mysqldの書き込みが多いです。&lt;/li&gt;
&lt;li&gt;そもそもSASには重要なデータは保存されていなく、速度優先のデータしか入っていないので安全性を犠牲にして、ディスクアクセスを効率的に行うように設定します。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/symbios-logic-megaraid-sas-2108-ubuntu/&quot;&gt;MegaRAID&lt;/a&gt;の値を調整します。コマンドの&lt;a href=&quot;https://fibrevillage.com/storage/710-storcli-virtual-drive-command-examples&quot;&gt;資料&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定の現状確認&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/m/.ssh# /opt/MegaRAID/storcli/storcli64 /c0/v0 show
Controller = 0
Status = Success
Description = None

Virtual Drives :
==============

-----------------------------------------------------------
DG/VD TYPE  State Access Consist Cache sCC       Size Name
-----------------------------------------------------------
0/0   RAID5 Optl  RW     Yes     NRWTD -   836.625 GB
-----------------------------------------------------------

Cac=CacheCade|Rec=Recovery|OfLn=OffLine|Pdgd=Partially Degraded|dgrd=Degraded
Optl=Optimal|RO=Read Only|RW=Read Write|HD=Hidden|B=Blocked|Consist=Consistent|
R=Read Ahead Always|NR=No Read Ahead|WB=WriteBack|
AWB=Always WriteBack|WT=WriteThrough|C=Cached IO|D=Direct IO|sCC=Scheduled
Check Consistency
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;NRWTDと書かれているので、No Write Ahead, Write Through, Directのフラグが立っています。&lt;/p&gt;
&lt;p&gt;読み書きを効率的に行うために、Write AheadとWrite Back、Cached IOに変更します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/opt/MegaRAID/storcli/storcli64 /c0/v0 set rdcache=ra
/opt/MegaRAID/storcli/storcli64 /c0/v0 set wrcache=WT
/opt/MegaRAID/storcli/storcli64 /c0/v0 set iopolicy=cached
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;その結果、RWTDになりました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/m/.ssh# /opt/MegaRAID/storcli/storcli64 /c0/v0 show
Controller = 0
Status = Success
Description = None

Virtual Drives :
==============

-----------------------------------------------------------
DG/VD TYPE  State Access Consist Cache sCC       Size Name
-----------------------------------------------------------
0/0   RAID5 Optl  RW     Yes     RWTC  -   836.625 GB
-----------------------------------------------------------

Cac=CacheCade|Rec=Recovery|OfLn=OffLine|Pdgd=Partially Degraded|dgrd=Degraded
Optl=Optimal|RO=Read Only|RW=Read Write|HD=Hidden|B=Blocked|Consist=Consistent|
R=Read Ahead Always|NR=No Read Ahead|WB=WriteBack|
AWB=Always WriteBack|WT=WriteThrough|C=Cached IO|D=Direct IO|sCC=Scheduled
Check Consistency
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;その結果、&lt;strong&gt;Read Ahead Always&lt;/strong&gt;、&lt;strong&gt;WriteBack&lt;/strong&gt;、&lt;strong&gt;Cached IO&lt;/strong&gt;になりました。&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ディスクアクセスが効率的になりました。&lt;/li&gt;
&lt;li&gt;グラフはwriteです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/d7685149e884f1e33c38a3653d025a7f.png&quot; alt=&quot;mackerel disk i/o&quot; /&gt;&lt;/p&gt;
&lt;p&gt;データ保存用のディスクアレイは継続して安全な方向で運用中。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/m/.ssh# /opt/MegaRAID/storcli/storcli64 /c0/v1 show
Controller = 0
Status = Success
Description = None

Virtual Drives :
==============

----------------------------------------------------------
DG/VD TYPE   State Access Consist Cache sCC     Size Name
----------------------------------------------------------
1/1   RAID10 Optl  RW     Yes     NRWTD -   3.637 TB
----------------------------------------------------------

Cac=CacheCade|Rec=Recovery|OfLn=OffLine|Pdgd=Partially Degraded|dgrd=Degraded
Optl=Optimal|RO=Read Only|RW=Read Write|HD=Hidden|B=Blocked|Consist=Consistent|
R=Read Ahead Always|NR=No Read Ahead|WB=WriteBack|
AWB=Always WriteBack|WT=WriteThrough|C=Cached IO|D=Direct IO|sCC=Scheduled
Check Consistency
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;そもそも、定常的に書き込みが多すぎる。。。iotopではプロセス名しかでなくてどのコンテナのプロセスかがわからない。。。&lt;/p&gt;
&lt;p&gt;docker statsでみてみるととあるプロセスのBLOCK I/Oが多いので、書き込みをなくすようにプログラム側を変更して対処して更に一段とディスクIOを減らしました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/image.jpg&quot; alt=&quot;docker stats&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/image-1.png&quot; alt=&quot;mackerel disk i/o&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>スクリーンキャプチャ動画を適当にgifアニにするコマンド</title><link>https://blog.teraren.com/posts/mov-to-gif-animation/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mov-to-gif-animation/</guid><description>スクリーンキャプチャ動画を適当にgifアニにするコマンド</description><pubDate>Mon, 07 Sep 2020 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;ffmpeg -i input.mov  -filter_complex &quot;[0:v] fps=10,scale=640:-1,split [a][b];[a] palettegen [p];[b][p] paletteuse&quot; output.gif
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;githubは10MBまでしかアップロードできないので、サイズを減らすためにはfpsやscaleを適当にへらして対応するのが良いです。&lt;/p&gt;
&lt;h2&gt;サンプルファイル&lt;/h2&gt;
&lt;p&gt;文字を大きくするか、オプションの画像サイズを大きくするなどの調整は必要そう。&lt;/p&gt;
&lt;p&gt;ファイルサイズ：11MB&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/09/out.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Instance Schedulerを使ってEC2, RDSの定期停止</title><link>https://blog.teraren.com/posts/aws-instance-scheduler/</link><guid isPermaLink="true">https://blog.teraren.com/posts/aws-instance-scheduler/</guid><description>AWSのInstance SchedulerをCloudFormationでデプロイし、EC2・RDSを平日昼間のみ稼働させてコストを削減する設定手順を詳しく解説。</description><pubDate>Thu, 27 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;平日昼間&lt;/strong&gt;しか稼働しないお値段高めのインスタンスがあるので&lt;strong&gt;節約&lt;/strong&gt;します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CloudWatchやLambdaで簡易的に実装されている例がありますが、ステート管理や設定の柔軟さに欠けます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;こちらの設定が良さげです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.aws.amazon.com/solutions/latest/instance-scheduler-on-aws/&quot;&gt;https://docs.aws.amazon.com/solutions/latest/instance-scheduler-on-aws/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CloudFormationで管理されているのでデプロイが楽&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;曜日、時間、タイムゾーン、リージョンなどの条件を指定して定期的にスタート、停止&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;停止やスタートのステートを保管しているので効率的な実行&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;こちらの設定が十分細かいのでこちらの設定どおりにやる
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/solutions/latest/instance-scheduler-on-aws/&quot;&gt;https://docs.aws.amazon.com/solutions/latest/instance-scheduler-on-aws/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;今回は、sleep-night-and-weekend-ec2 という名前でデプロイしました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;テンプレートの内容&lt;/p&gt;
&lt;p&gt;デフォルトではいくつか設定が入っているのでDynamoDBのテーブルを見てみるのが良いと思います。どのようなロジックなのかがなんとなくわかると思います。typeがscheduleになっているレコードが実行される設定です。crontabの行のようなものです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;CloudFormationでのデプロイ後&lt;/p&gt;
&lt;p&gt;デフォルトで入稿されている&lt;strong&gt;オフィスアワー&lt;/strong&gt;の設定を更新します。fish用設定&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set stack sleep-night-and-weekend-ec2
set aws_profile default
set name office-hours
set region ap-northeast-1
scheduler-cli update-period --name $name --begintime 09:00 --endtime 23:00 --weekdays mon-fri --stack $stack --profile-name $aws_profile --region $region
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;日本時間での計画停止の設定を入稿します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set periods office-hours
set schedule jp-office-hours
set description &quot;Office hours in Japan&quot;
set stack sleep-night-and-weekend-ec2
set aws_profile default
set region ap-northeast-1
scheduler-cli create-schedule --stack $stack --name $schedule --periods $periods --description &quot;$description&quot; --timezone Asia/Tokyo --profile-name $aws_profile --region $region
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のレコードが追加されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;あとは規定のTagをEC2に打てば終わり。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set instance_id &apos;i-0d13c9eb8xxxxxxxxxx&apos;
aws ec2 create-tags \
    --resources $instance_id \
    --tags Key=Schedule,Value=jp-office-hours
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CloudWatchLogsを確認。デフォルトは5分ごとにこのスタックが実行されるので5分以内にはas-isになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>ALB+WAF配下でredashのクエリーが実行できない問題を解決</title><link>https://blog.teraren.com/posts/alb-waf-redash/</link><guid isPermaLink="true">https://blog.teraren.com/posts/alb-waf-redash/</guid><description>AWS WAFのFortinet OWASPルールがRedashのAPIリクエストを403ブロックする問題を、特定パスのallow設定で解決した方法</description><pubDate>Thu, 20 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;redashにおいて、一部のクエリーが実行できなかったり、保存できなかったりして困っていました。&lt;/li&gt;
&lt;li&gt;調べていると、AWSのWAFでブロックされていることがわかりました。&lt;/li&gt;
&lt;li&gt;fortinetのOWASP top 10のルールにブロックするようになっていました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;現象&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;UI上では、クエリーが実行中のように見えますが、通信はサーバサイドから403が返されているので実際には動いていません。&lt;/li&gt;
&lt;li&gt;redashのアプリケーションサーバのログレベルをDEBUGにしてもアクセスが来ていなかったので気づきました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/Screen_Shot_2020-08-20_at_19_10_57.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WAFのブロックされた数字を見てみると、ブロックしているアクセスが有ることがわかります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image-4-1.jpg&quot; alt=&quot;AWS WAF blocks api access to the redash.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Fortinet#all_rules#SQL-injection-02というルールにブロックされている&lt;/p&gt;
&lt;h2&gt;対処&lt;/h2&gt;
&lt;p&gt;できるだけ、狭く絞って、以下のようなルールをWAFに追加して対処。プライオリティはブロックされるフィルタより先に実行されるようにしておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;Name&quot;: &quot;allow-redash-api-access&quot;,
  &quot;Priority&quot;: 0,
  &quot;Action&quot;: {
    &quot;Allow&quot;: {}
  },
  &quot;VisibilityConfig&quot;: {
    &quot;SampledRequestsEnabled&quot;: true,
    &quot;CloudWatchMetricsEnabled&quot;: true,
    &quot;MetricName&quot;: &quot;allow-redash-api-access&quot;
  },
  &quot;Statement&quot;: {
    &quot;AndStatement&quot;: {
      &quot;Statements&quot;: [
        {
          &quot;ByteMatchStatement&quot;: {
            &quot;FieldToMatch&quot;: {
              &quot;SingleHeader&quot;: {
                &quot;Name&quot;: &quot;host&quot;
              }
            },
            &quot;PositionalConstraint&quot;: &quot;CONTAINS&quot;,
            &quot;SearchString&quot;: &quot;xxxxxxx.xxxxxx.com&quot;,
            &quot;TextTransformations&quot;: [
              {
                &quot;Type&quot;: &quot;LOWERCASE&quot;,
                &quot;Priority&quot;: 0
              }
            ]
          }
        },
        {
          &quot;ByteMatchStatement&quot;: {
            &quot;FieldToMatch&quot;: {
              &quot;UriPath&quot;: {}
            },
            &quot;PositionalConstraint&quot;: &quot;STARTS_WITH&quot;,
            &quot;SearchString&quot;: &quot;/api&quot;,
            &quot;TextTransformations&quot;: [
              {
                &quot;Type&quot;: &quot;LOWERCASE&quot;,
                &quot;Priority&quot;: 0
              },
              {
                &quot;Type&quot;: &quot;COMPRESS_WHITE_SPACE&quot;,
                &quot;Priority&quot;: 1
              }
            ]
          }
        }
      ]
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>東京都のCOVID-19新規陽性者をTweetするBot</title><link>https://blog.teraren.com/posts/tokyo-covid19-graph/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tokyo-covid19-graph/</guid><description>東京都のCOVID-19新規陽性者をTweetするBot</description><pubDate>Thu, 20 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;東京都のCOVID-19新規感染者をTweetするBotを作りました。フォローしてね！&lt;br /&gt;
→@covid19tokyoが垢バンくらったので、&lt;a href=&quot;https://x.com/covid19kanagawa&quot;&gt;神奈川県&lt;/a&gt;のみ生きてます。&lt;/p&gt;
&lt;p&gt;https://x.com/covid19kanagawa&lt;/p&gt;
&lt;h2&gt;仕様&lt;/h2&gt;
&lt;p&gt;毎日東京都の新規感染者を調べてチェックするのが面倒なので、プログラムで新規感染者数を集計してTweetするようにしました。&lt;br /&gt;
データソースは東京都が公開しているオープンデータです。当日の20時〜23時ごろに更新されます。30分に1回更新を確認しています。&lt;/p&gt;
&lt;h2&gt;Open Sourceにしました&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/matsubo/covid19-daily-tweet/&quot;&gt;https://github.com/matsubo/covid19-daily-tweet/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/Screen-Shot-2020-08-20-at-23.00.51.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>macosでsshfs</title><link>https://blog.teraren.com/posts/macos-sshfs/</link><guid isPermaLink="true">https://blog.teraren.com/posts/macos-sshfs/</guid><description>macosでsshfs</description><pubDate>Sun, 16 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PC間のファイルの同期に&lt;a href=&quot;https://app.box.com/login&quot;&gt;Box&lt;/a&gt;をずっと使っていますが、ここ数年間CPUを結構消費する感じだったので問題視していました。&lt;/li&gt;
&lt;li&gt;過去には、勝手にファイルが削除されたりしてしまってかなり不満でした。Boxの前はDropboxを使っていましたが、そちらも同様の問題があります。&lt;/li&gt;
&lt;li&gt;なので、もう面倒ですがファイルサーバをsshでマウントしちゃいます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ brew tap homebrew/cask
$ brew cask install osxfuse
$ brew install sshfs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;マウント&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sshfs -o reconnect remote:/home/remote_directory /home/local_mount_point
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Createdの日時が保管されない。rsyncで同期してもダメそう。&lt;a href=&quot;https://github.com/osxfuse/osxfuse/issues/623&quot;&gt;このあたり&lt;/a&gt;でも議論されているけど直っていない。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>ダイキンのエアコンの効きが悪い問題を設定で解決</title><link>https://blog.teraren.com/posts/2020-08-14-daikin-cooler-issue/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2020-08-14-daikin-cooler-issue/</guid><description>ダイキンエアコンAN71VRP-Wの冷房が30分で効かなくなる原因は「留守エコ」等の自動節電機能。室温を実測して検証し、機能をOFFにして解決した。</description><pubDate>Fri, 14 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://diary.teraren.com/posts/2019-07-17-buying-time/&quot;&gt;1年前に買った20万円ぐらいするエアコン&lt;/a&gt;の効きが悪い問題がありました。効きが悪いというと語弊があります。なぜなら、最初はすぐに冷風が出て部屋が涼しくなって快適になりますが、30分ぐらい経つと体感が不快なぐらい暑くなるという問題です。&lt;/li&gt;
&lt;li&gt;機種はDAIKINの&lt;a href=&quot;https://kakaku.com/item/K0001005213/&quot;&gt;AN71VRP-W&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;これ1台をつけていればマンションの1区分全体が涼しくなるくらいのパワーを持っているので性能が低いとうことは無いはずです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実験&lt;/h2&gt;
&lt;p&gt;クーラーをつけてしばらくすると、体感で暑くなっているのは感じますが、それは主観なので、客観的に本当に室温が高くなっているのかを検証するために部屋の温度を計測しました。&lt;/p&gt;
&lt;p&gt;測定した結果を以下に貼ります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;設定を変更する前は、涼しい時間が短時間しかありません。エアコンの温度設定を下げてもそれが有効になっている感じがしませんでした。&lt;/p&gt;
&lt;p&gt;しかし、設定後は涼しいところで室温が安定するようになりました。&lt;/p&gt;
&lt;h2&gt;設定内容&lt;/h2&gt;
&lt;p&gt;エアコン自体はすぐに涼しくなるので、おそらくハードウェアはちゃんと動いていると思ったのでエアコンの設定を見直してみて、色々試してみたら原因がわかりました。&lt;/p&gt;
&lt;p&gt;諸悪の根源はこの&lt;strong&gt;留守エコ&lt;/strong&gt;機能などの自動節電機能群。これを「&lt;strong&gt;切&lt;/strong&gt;」にします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上記以外の「便利な機能」にあたる、&lt;strong&gt;自動なんちゃらと書かれている機能はすべてOFFにしました&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;そうしたら、室温が設定した温度で安定しました。&lt;/p&gt;
&lt;p&gt;去年の夏や冬も同じような問題がありましたが、在宅時間が短かったということもあってあまり気にしていませんでしたが、リモートワークする時間が長くなり、不快に感じることが多くなったのでちゃんと問題を解決しました。&lt;/p&gt;
&lt;h2&gt;類似書き込み&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://bbs.kakaku.com/bbs/K0001102797/SortID=22904225/&quot;&gt;https://bbs.kakaku.com/bbs/K0001102797/SortID=22904225/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://review.kakaku.com/review/K0000913724/ReviewCD=1160602/&quot;&gt;https://review.kakaku.com/review/K0000913724/ReviewCD=1160602/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;エアコン自体はいいのですが、ソフトウェア面とかオマケ機能がついているせいで本来の機能を使い切れなくて非常に残念な感じに仕上がっております。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;kakaku.comにはエアコンがちゃんと効かないという書き込みが多数見受けられますが、問題はこの便利機能がデフォルトでONになっていることが起因していると思います。&lt;/p&gt;
</content:encoded></item><item><title>プロダクト開発のEngagement Model</title><link>https://blog.teraren.com/posts/post-12638/</link><guid isPermaLink="true">https://blog.teraren.com/posts/post-12638/</guid><description>プロダクト開発のEngagement Model</description><pubDate>Thu, 13 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://emerline.com/blog/engagement-models&quot;&gt;https://emerline.com/blog/engagement-models&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;What Engagement Model is Right for You?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;How to choose the most efficient engagement model to lay a solid foundation for the successful project delivery?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Emerline will tell you about the available options, highlight which one works best for each particular case, and share the team’s approach to technological partnership and other engagement scenarios.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>present in INFORMATION_SCHEMA&apos;s INNODB_SYS_TABLES table but missing from TABLES table</title><link>https://blog.teraren.com/posts/rds-mysql8-upgrade/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rds-mysql8-upgrade/</guid><description>RDSをMySQL 8.0にアップグレードする際に発生するInnoDB一時テーブル残留エラーの解決方法。innodb_sys_tablesに残った孤立テーブルをDROPする手順を解説。</description><pubDate>Wed, 12 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;RDSをmysql 8.0にアップグレードしようとしたらエラー&lt;/p&gt;
&lt;p&gt;PrePatchCompatibility.logに以下のようなエラーが出ました。(xxxxxxxはデータベース名)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;17) Schema inconsistencies resulting from file removal or corruption
	Following tables show signs that either table datadir directory or frm file was removed/corrupted. Please check server logs, examine datadir to detect the issue and fix it before upgrade
	xxxxxxx - present in INFORMATION_SCHEMA&apos;s INNODB_SYS_TABLES table but missing from TABLES table
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;スキーマ変更中にinterruptしてしまった&lt;/strong&gt;ときにtemporary tableが残る様子。&lt;/p&gt;
&lt;p&gt;要らないので消してしまいます。&lt;/p&gt;
&lt;h2&gt;解決法&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://serverfault.com/a/1002705/556236&quot;&gt;https://serverfault.com/a/1002705/556236&lt;/a&gt; を参考に。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; use xxxxxxx;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql&amp;gt; drop table `#mysql50##sql-105e_bcd3`;
Query OK, 0 rows affected (0.41 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;#mysql50#&lt;/code&gt; の部分は、ファイルシステムを参照する特殊な表記。sql-105e_bcd3の部分は以下のクエリーを実行して出力された値です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select * from information_schema.innodb_sys_tables where name like &apos;%#%&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;無くなったかを確認&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select * from information_schema.innodb_sys_tables where name like &apos;%#%&apos;;
Empty set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;余談&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;アップグレード自体は15分ぐらい。DBの容量は約100GB。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; show variables where Variable_name = &apos;Version&apos;;
+---------------+--------+
| Variable_name | Value  |
+---------------+--------+
| version       | 8.0.17 |
+---------------+--------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>OWASP TOP 10のトップ3を解説</title><link>https://blog.teraren.com/posts/owasp-top10/</link><guid isPermaLink="true">https://blog.teraren.com/posts/owasp-top10/</guid><description>OWASP Top 10のうちInjection・Broken Authentication・Sensitive Data Exposureの3大脆弱性を具体的なコード例と対策付きで解説</description><pubDate>Thu, 06 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://owasp.org/www-project-top-ten/#&quot;&gt;OWASP&lt;/a&gt;が発表している最新のWeb攻撃手法のことです。2017年時点の内容ですが、2020年時点でもこれらの攻撃手法は現役です。&lt;/li&gt;
&lt;li&gt;&quot;Top 10 Web Application Security Risks&quot;。通称は &lt;strong&gt;OWASP Top 10&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Web SecurityなのでOSI参照レイヤーではレ&lt;strong&gt;イヤー5から7&lt;/strong&gt;の話題です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.infraexpert.com/study/tcpip.html&quot;&gt;https://www.infraexpert.com/study/tcpip.html&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;OWASP Top 10 一覧&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Injection&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Broken Authentication&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sensitive Data Exposure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;XML External Entities (XXE)&lt;/li&gt;
&lt;li&gt;Broken Access Control&lt;/li&gt;
&lt;li&gt;Security Misconfiguration&lt;/li&gt;
&lt;li&gt;Cross-Site Scripting XSS.&lt;/li&gt;
&lt;li&gt;Insecure Deserialization&lt;/li&gt;
&lt;li&gt;Using Components with Known Vulnerabilities.&lt;/li&gt;
&lt;li&gt;Insufficient Logging &amp;amp; Monitoring.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;各項目の説明&lt;/h2&gt;
&lt;h3&gt;1. &lt;strong&gt;&lt;a href=&quot;https://owasp.org/www-project-top-ten/OWASP_Top_Ten_2017/Top_10-2017_A1-Injection&quot;&gt;Injection&lt;/a&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Injection flaws, such as SQL, NoSQL, OS, and LDAP injection, occur when untrusted data is sent to an interpreter as part of a command or query. The attacker’s hostile data can trick the interpreter into executing unintended commands or accessing data without proper authorization.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;訳：SQL、NoSQL、OS、LDAP インジェクションなどの欠陥は、信頼できないデータがコマンドやクエリの一部としてインタープリタに送信された場合に発生します。攻撃者が送信する不正なデータは、インタープリタを騙して&lt;strong&gt;意図しないコマンドを実行したり、適切な権限を持たずにデータにアクセス&lt;/strong&gt;したりします。&lt;/p&gt;
&lt;p&gt;原因は、Webのフォームやパラメーターの&lt;strong&gt;ユーザからの入力データを適切に処理していない&lt;/strong&gt;ときに発生。&lt;/p&gt;
&lt;p&gt;脆弱性を含むコードの例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;odbc.execute(&apos;SELECT id FROM users WHERE email = {email} AND password = {password}&apos;, email: params[&quot;email&quot;], password: params[&quot;password&quot;])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;emailに&lt;code&gt;&quot;&quot; OR 1 OR&lt;/code&gt;というパラメータが入っていたらすべての認証が通る。以下に例。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT id FROM users WHERE email = &quot;&quot; OR 1 OR 1 AND password = &quot;&quot;&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;防ぎ方：静的コード解析(Code sniffer)、コードレビュー、WAF、IDS/IPS&lt;/p&gt;
&lt;p&gt;漏洩事例：&lt;a href=&quot;https://cybersecurity-jp.com/news/29506&quot;&gt;SQLインジェクション攻撃で個人情報約6万4千件が流出、株式会社釣りビジョン&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;2. &lt;strong&gt;&lt;a href=&quot;https://owasp.org/www-project-top-ten/OWASP_Top_Ten_2017/Top_10-2017_A2-Broken_Authentication&quot;&gt;Broken Authentication&lt;/a&gt;&lt;/strong&gt;.&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Application functions related to authentication and session management are often implemented incorrectly, allowing attackers to compromise passwords, keys, or session tokens, or to exploit other implementation flaws to assume other users’ identities temporarily or permanently.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;訳：認証とセッション管理に関連したアプリケーション機能は、しばしば誤った実装をされており、攻撃者はパスワード、キー、セッショントークンを漏洩させたり、他の実装の欠陥を悪用して、&lt;strong&gt;一時的または恒久的に他のユーザの認証を不正に入手&lt;/strong&gt;できます。&lt;/p&gt;
&lt;p&gt;原因は、経路が暗号化されていなかったり、URLに認証に使っているセッションIDを露出してしまったりして&lt;strong&gt;第三者が認証に使っているキーを手に入れてしまう&lt;/strong&gt;場合に発生します。&lt;/p&gt;
&lt;p&gt;容易にあるケースは、暗号化されていないWiFiアクセスポイントやWEP（脆弱な暗号アルゴリズム）で暗号化されているアクセスポイントでTLSで暗号化されていないサイトにログインする場合。&lt;strong&gt;信頼できないVPNやProxyサーバ&lt;/strong&gt;を通したときに漏洩します。&lt;/p&gt;
&lt;p&gt;例：とあるサイトでの認証キー&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;認証されたキーの例&lt;/p&gt;
&lt;p&gt;防ぎ方：ペネトレーションテスト、コードレビュー、WAF、IDS/IPS。&lt;/p&gt;
&lt;h3&gt;3. &lt;a href=&quot;https://owasp.org/www-project-top-ten/OWASP_Top_Ten_2017/Top_10-2017_A3-Sensitive_Data_Exposure&quot;&gt;Sensitive Data Exposure&lt;/a&gt;.&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Many web applications and APIs do not properly protect sensitive data, such as financial, healthcare, and PII. Attackers may steal or modify such weakly protected data to conduct credit card fraud, identity theft, or other crimes. Sensitive data may be compromised without extra protection, such as encryption at rest or in transit, and requires special precautions when exchanged with the browser.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;訳：多くのWebアプリケーションやAPIは、金融、医療、PII(Personally Identifiable Information)などの機密データを適切に保護していません。攻撃者は、このような弱く保護されたデータを盗んだり、変更したりして、クレジットカード詐欺や個人情報の窃盗、その他の犯罪を行う可能性があります。機密性の高いデータは、永続データや転送中の暗号化など、より踏み込んだ保護がなければ危険にさらされる可能性があり、ブラウザとのやり取りの際には特別な注意が必要となります。&lt;/p&gt;
&lt;p&gt;原因は、適切に転送するデータや保存するデータの暗号化を行っていないことです。&lt;/p&gt;
&lt;p&gt;漏洩を防ぐためには、適切な隠蔽が必要になります。&lt;strong&gt;クレカ情報を生データで保存することはPCI DSSで禁止&lt;/strong&gt;されており暗号化が必須です。&lt;strong&gt;パスワードの保存に関しては不可逆のハッシュ&lt;/strong&gt;で保存したり、&lt;strong&gt;salt&lt;/strong&gt;という文字列を混ぜることで復元を困難にします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/08/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;防ぎ方：設計レビュー、ログ解析、コードレビュー、WAF、IDS/IPS&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ちゃんと書き出したらキリが無いのでトップ3だけにします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;対処方法が似たりよったり&lt;/strong&gt;ということに気づいたと思います。Web Securityに関しては、100%絶対防げるという手法が存在しません。なぜならレイヤーが高めなので機械では正常なのか異常なのかが区別が付きづらいケースがあるためです。&lt;/li&gt;
&lt;li&gt;脆弱性が起きる勘所を押さえて、できるだけ低レイヤーな部分からセキュアなコーディングをしていくのが良いです。&lt;/li&gt;
&lt;li&gt;OWASP Top10はコードレビュアーやシステムの設計者をする人は最低限知らなければいけない内容です。セキュリティを知らなくても正常系は動いてしまうので軽視しがちです。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>転職プラットフォームの理想を思考してみる</title><link>https://blog.teraren.com/posts/job-change-platform/</link><guid isPermaLink="true">https://blog.teraren.com/posts/job-change-platform/</guid><description>乱立する50以上のエンジニア転職サイトに対する問題提起。採用する側・される側双方の視点からプラットフォームの理想モデルとゲーミフィケーション活用の可能性を考察。</description><pubDate>Mon, 27 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;最近はエンジニア転職サイト&lt;strong&gt;多すぎ&lt;/strong&gt;です。&lt;strong&gt;50サイト&lt;/strong&gt;ぐらいあるらしいです。&lt;/p&gt;
&lt;p&gt;採用する側、採用される側の考えは「&lt;strong&gt;全サイトがまとまって1つになってほしい&lt;/strong&gt;。」&lt;/p&gt;
&lt;p&gt;転職メディアがこんなにも乱立していたら、**採用する側も採用される側も手間が増えてしょうがない！**短期的に儲かる市場にプレイヤーが増えるのは必然ですが、過剰供給な感じです。&lt;/p&gt;
&lt;p&gt;そもそも理想の採用や転職のモデルってなんだろう？と思ったので考えを整理してみます。&lt;/p&gt;
&lt;h2&gt;システムを使った単純な採用ユースケース&lt;/h2&gt;
&lt;p&gt;すごい単純にユースケースを書くとこんな感じです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;システムを使った採用ユースケース&lt;/h2&gt;
&lt;p&gt;もうすこしユースケースをブレイクダウンしてみます。&lt;/p&gt;
&lt;p&gt;昔からある採用メディアはこんな感じです。このシステムが世の中に1個または3個ぐらいしか存在しない世界では両サイドの人はハッピーな状態です。&lt;/p&gt;
&lt;p&gt;プラットフォームは乱立することでプラットフォームの価値が減ります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image-8.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;重要な採用はシステム外で起きている&lt;/h2&gt;
&lt;p&gt;別の議論にはなりますが、&lt;strong&gt;立ち上げ初期のコアメンバー獲得、チーム作成、過去に一緒に仕事がしたことがあってマッチングがぴったりな人を採用&lt;/strong&gt;するといった&lt;strong&gt;重要な採用はシステム外で起きている&lt;/strong&gt;割合のほうが多い気がします。&lt;/p&gt;
&lt;p&gt;システムは登場しないです。デジタル上に情報が上がってこないから顕在化しないというデメリットがあります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;もちろん、それをオンラインに載せた紹介プラットフォームも1つの転職サイトとして存在しています。しかしながら、「紹介する」のトリガーがオンライン上では存在しないのであまり活発ではありません。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;オフラインなどで行われているコミュニケーションがトリガーとなって紹介は発生している気がします。それに、トリガーを握っている紹介する人にとっては、&lt;strong&gt;オフラインで紹介出来るのにオンラインでやる必要は無い&lt;/strong&gt;のでワークしません。&lt;/p&gt;
&lt;h2&gt;次に来るモデル&lt;/h2&gt;
&lt;p&gt;色々なモデルが試されていて、結構行き詰まっている感はあります。広告、プラットフォーム、pull型、push型、紹介など。&lt;/p&gt;
&lt;p&gt;今までにないのは、&lt;strong&gt;ゲーミフィケーション&lt;/strong&gt;ぐらいかなと思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;と思ったら、ありました。テクスカ。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://scout.techcareer.jp/&quot;&gt;https://scout.techcareer.jp/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;スカウトメールを見るとお金をもらえる、知り合いを紹介するとお金をもらえる。面接するとお金をもらえる&lt;/strong&gt;。プラットフォームとしてはコスト計算が非常に難しいし、集客は大変ですけどもともとアービトラージがあるマーケットなので自走できるようなエコシステムを作ったらワークする可能性があります。&lt;/p&gt;
&lt;p&gt;まぁ、すごい冷静に見るとスカウトメールを読む事自体にも時間をとってるし、会社説明を聞くだけでも時間を撮っているのでまっとうかと思います。それがワークするのは 採用される側＞採用する側というパワーバランスの時かなと。&lt;/p&gt;
&lt;p&gt;マッチングの精度が上がれば、採用される側＝採用する側となるはずなので是正されるかな。でも、あまりPDCAが回りづらいところではあるので難しいかも。&lt;/p&gt;
&lt;p&gt;お金の流れは違いますが、使っている技術や機能などはマッチングアプリが類似しているなぁと感じました。Tinderみたいな感じのサイトが登場するのかもしれません。&lt;/p&gt;
&lt;p&gt;海外ではLinkedInがメジャーな採用プラットフォームとして稼働しているので日本のような問題は起きないのかなと思います。このような状態は日本マーケットだけなのかな。。。？&lt;/p&gt;
</content:encoded></item><item><title>楽天モバイルはメイン携帯にもおすすめ（でした）</title><link>https://blog.teraren.com/posts/rakuten-mobile/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rakuten-mobile/</guid><description>楽天モバイルUnlimitをサブ回線で1年試用した結果レポート。自社アンテナエリアでのパケット使い放題・ピーク時の速度実測値・IPv6対応など利点を詳しく紹介。</description><pubDate>Thu, 23 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/%E6%A5%BD%E5%A4%A9%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB-%E3%82%A8%E3%83%B3%E3%83%88%E3%83%AA%E3%83%BC%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8-SIM%E3%82%AB%E3%83%BC%E3%83%89%EF%BC%88%E4%BA%8B%E5%8B%99%E6%89%8B%E6%95%B0%E6%96%99%E7%84%A1%E6%96%99%EF%BC%89-%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD-%E6%A8%99%E6%BA%96SIM%E5%AF%BE%E5%BF%9C-iPhone-Android%E5%85%B1%E9%80%9A/dp/B01MR9JGKY?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=255c681090f0cdd51fd2c24d11c18022&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;楽天モバイルのunlimit&lt;/a&gt;が良いという噂を聞いたので申し込んでみました。&lt;/li&gt;
&lt;li&gt;クオリティが低かったら困るのでサブのスマホ(Google Pixel4)用に買いました。&lt;/li&gt;
&lt;li&gt;その結果、&lt;strong&gt;予想以上に良いですのでおすすめです！&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B01MR9JGKY&quot;}&lt;/p&gt;
&lt;h2&gt;楽天モバイルの概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;既存のMVNO業者とは違い、自社でアンテナを立てている！自社でカバーできないところはMVNOするというハイブリッドな方式。&lt;/li&gt;
&lt;li&gt;IPv6に対応！（これ、楽天モバイルだけじゃないかなと思います）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;料金表&lt;/h2&gt;
&lt;p&gt;非常にわかりやすいプラン。これだけ見れば、すごいプランということがわかります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;広尾の屋外で、Netflixのベンチマークで計測した結果です。充分早いですね。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image-3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;申込みは&lt;a href=&quot;https://www.amazon.co.jp/%E6%A5%BD%E5%A4%A9%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB-%E3%82%A8%E3%83%B3%E3%83%88%E3%83%AA%E3%83%BC%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8-SIM%E3%82%AB%E3%83%BC%E3%83%89%EF%BC%88%E4%BA%8B%E5%8B%99%E6%89%8B%E6%95%B0%E6%96%99%E7%84%A1%E6%96%99%EF%BC%89-%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD-%E6%A8%99%E6%BA%96SIM%E5%AF%BE%E5%BF%9C-iPhone-Android%E5%85%B1%E9%80%9A/dp/B01MR9JGKY?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=f454ecd996280a5c994b3f63bc6fc608&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;こちら&lt;/a&gt;から。300万人対象なのですぐにはなくなりませんが、早めに申し込んだほうがよいと思います。&lt;/li&gt;
&lt;li&gt;12時から13時の混む時間や、夕方などの混む時間にも今の所快適です。上記のベンチマークが12時半というピークタイムに取得したにもかかわらず高速通信ができています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;使い方&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;なんと言っても楽天の自社アンテナが立っている場所では&lt;strong&gt;パケット通信が使い放題です&lt;/strong&gt;！**＝テザリングし放題！**基本的には都内であれば入ります。&lt;/li&gt;
&lt;li&gt;カフェでの作業やアプリのダウンロードは全部この端末で行っています。素晴らしいです。&lt;strong&gt;パケ死を気にしながら生活にさようなら。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;解約手数料は無料なので、もし自分の使い方に合わなかった場合でも問題なし。金銭的なリスクは無いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B01MR9JGKY&quot;}&lt;/p&gt;
&lt;h2&gt;追記 2021/4/14&lt;/h2&gt;
&lt;p&gt;1年、サブ携帯で使いました。その結果、本当にずっと0円でした。また、最近は新しい料金プランが出ておりまして、利用データが1GB以下なら0円らしいです。サブ携帯に嬉しい値段設定です。&lt;/p&gt;
&lt;p&gt;他の月額最低料金が500円ぐらいのSIMに乗り換えようと思っていましたが、しばらく楽天モバイルを使っておきます。&lt;/p&gt;
&lt;h2&gt;追記 2022/6/1&lt;/h2&gt;
&lt;p&gt;固定費が0円ではなくなったのでおすすめではない。&lt;/p&gt;
&lt;p&gt;auのローミングが減って都市部でもつながらないケースが多数。&lt;/p&gt;
</content:encoded></item><item><title>Benchmarking ActiveRecord and mysql2</title><link>https://blog.teraren.com/posts/benchmarking-activerecord-and-mysql2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/benchmarking-activerecord-and-mysql2/</guid><description>RubyのActiveRecordとmysql2ドライバの速度を実測比較。1万回のクエリでActiveRecordは6.6秒、mysql2直接使用は3.5秒と約2倍の差を計測。</description><pubDate>Mon, 06 Jul 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;RubyActiveRecordを使う場合と使わない場合におけるベンチマークがWebを探しても無かったので測ってみました。&lt;/li&gt;
&lt;li&gt;純粋な比較は難しいので、あくまでも参考値として見ていただければと思います。&lt;/li&gt;
&lt;li&gt;比較&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;activerecord (5.2.4.3)&lt;/li&gt;
&lt;li&gt;mysql2 (0.5.3)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実験&lt;/h2&gt;
&lt;h3&gt;測定方法&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;純粋な比較が難しいので、とりあえず1行だけプライマリーキーで1行取得して変数に入れます。&lt;/li&gt;
&lt;li&gt;usersテーブルは67カラムあります。&lt;/li&gt;
&lt;li&gt;レコードのデータは、文字列に変換すると576バイトです。&lt;/li&gt;
&lt;li&gt;実行環境: ruby 2.6.6p146, MySQL: 5.7.29&lt;/li&gt;
&lt;li&gt;on Docker on macos.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Activerecordの結果&lt;/h3&gt;
&lt;p&gt;6.6秒&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pry(main)&amp;gt; puts Benchmark.measure { 10000.times { User.find(1) } }
  3.223594   0.814001   4.037595 (  6.624353)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;mysql2の結果&lt;/h3&gt;
&lt;p&gt;3.5秒&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pry(main)&amp;gt; puts Benchmark.measure { 10000.times { client.query(&apos;select * from users where id = 1&apos;).first } }
  1.157955   0.410513   1.568468 (  3.569280)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;mysqlコマンドの結果&lt;/h3&gt;
&lt;p&gt;事前に1万行のクエリーを書いておいたファイルを実行してみました。&lt;/p&gt;
&lt;p&gt;2.9秒&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% time (cat select.sql | mysql -u root --password=$MYSQL_ROOT_PASSWORD test_database  -h db  &amp;gt; /dev/null)
real	0m2.935s
user	0m0.340s
sys	0m0.529s
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Google OSSのTsunamiを試してみた</title><link>https://blog.teraren.com/posts/google-oss-tsunami/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-oss-tsunami/</guid><description>Google OSSのTsunamiを試してみた</description><pubDate>Mon, 29 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Googleが出した脆弱性チェックツール「&lt;a href=&quot;https://github.com/google/tsunami-security-scanner&quot;&gt;Tsunami&lt;/a&gt;」を試してみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://x.com/GoogleOSS/status/1273647816242540545&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;スキャンに15分ぐらいかかります。ターゲットのホストにディクショナリーアタックをかけたり、ポートスキャンをかけたりしています。&lt;/li&gt;
&lt;li&gt;セットアップは5分ぐらいで終わります。スキャンには15分ぐらいかかりました。結果のjsonファイルを見ると発見された脆弱性が記載されています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://youtu.be/JtVgiPH2TAY&lt;/p&gt;
&lt;p&gt;Tsunamiに関する文字の説明は&lt;a href=&quot;https://qiita.com/satto_sann/items/69deb12ed3f11155a284&quot;&gt;こちら&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;余談&lt;/h2&gt;
&lt;p&gt;Googleのページが消えてます。。。。やはり名前が問題になったのだろうか。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-39.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2020/7/1 追記&lt;/h3&gt;
&lt;p&gt;Tsunami Early Warning Systemという意図だったようなのです。名前はそのまま続行しそうです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.publickey1.jp/blog/20/tsunamiissue.html&quot;&gt;https://www.publickey1.jp/blog/20/tsunamiissue.html&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>I found a vulnerability related to the potential of Zoom Bomb</title><link>https://blog.teraren.com/posts/security-vulnerability-related-to-the-potential-of-zoom-bomb/</link><guid isPermaLink="true">https://blog.teraren.com/posts/security-vulnerability-related-to-the-potential-of-zoom-bomb/</guid><description>A security vulnerability discovered in Zoom where password authentication is case-insensitive despite appearing case-sensitive, reducing cryptographic strength by 10^30 times. CVSS score 6.5.</description><pubDate>Mon, 29 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Abstract&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;I found a security issue related to the strength of password authentication.&lt;/li&gt;
&lt;li&gt;This can be attacked from a remote host and threaten confidentiality and availability of Zoom service.&lt;/li&gt;
&lt;li&gt;CVSS score would be 6.5.
&lt;ul&gt;
&lt;li&gt;CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L/E:H/RL:O/RC:R&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;When you create a meeting room in Zoom, a new room ID and password will be generated for you.&lt;/li&gt;
&lt;li&gt;It will also generate a URL that contains the room&apos;s ID and password information.&lt;/li&gt;
&lt;li&gt;By accessing this URL, you will be able to access your meeting room in Zoom . (Example below. URL were valid in past times)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://zoom.us/j/98459262939?pwd=K1J6VjdFd2NpTWpaenJ6WE0zWml0QT09&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The 11 digits represents room ID and the &lt;code&gt;pwd&lt;/code&gt; parameter in the query string represents password.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;98459262939&lt;/code&gt; part is the room ID. It looks like it&apos;s probably issued by a sequential number.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;K1J6VjdFd2NpTWpaenJ6WE0zWml0QT09&lt;/code&gt; in the pwd parameter of this URL represents the password.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Issue&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;This password is made up of a combination of upper and lower case letters and numbers.&lt;/li&gt;
&lt;li&gt;The length of the character is 32 characters. Trailing two digits seems fixed.&lt;/li&gt;
&lt;li&gt;Therefore, the pattern is (26+26+10)^30. (a-z, A-Z, 0-9)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;However, Zoom&apos;s server-side processing doesn&apos;t make this case sensitive, so there are actually only (26+10)^30 combinations.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It was intended case &lt;strong&gt;sensitive&lt;/strong&gt; but authentication program evaluate case &lt;strong&gt;insensitive&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Therefore, it&apos;s probably 10^30 times weaker than the cryptographic strength Zoom is assuming.&lt;/p&gt;
&lt;h2&gt;Recording of the procedure&lt;/h2&gt;
&lt;p&gt;The procedure in the video&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to the correct URL&lt;/li&gt;
&lt;li&gt;Access the pwd parameter with all the letters capitalized. It should be denied, but the password is accepted.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://www.youtube.com/watch?v=JPA5hxmEonE&amp;amp;feature=youtu.be&lt;/p&gt;
&lt;h2&gt;My thought&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;I sent an email to Zoom&apos;s security insident contact, but the contact person didn&apos;t understand it, so I wrote it on this blog.&lt;/li&gt;
&lt;li&gt;It&apos;s a common mistake in implementations. The storage engine (e.g. database) has this password and I believe the string is stored and evaluated by matching the pwd parameter in the URL. However, since the storage engine is not case sensitive, the authentication passes. This is a common mistake at the implementation level.&lt;/li&gt;
&lt;li&gt;Even if the cryptographic strength is weakened by a factor of 10^30, it is still strong enough, so this is not a big deal for the security in the most cases.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2020/7/2&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;This issue has been fixed by zoom &lt;strong&gt;after I submitted this report to Zoom&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;There is no response from Zoom.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Zoomのパスワード強度に関する脆弱性を見つけた</title><link>https://blog.teraren.com/posts/zoom-vulnerability/</link><guid isPermaLink="true">https://blog.teraren.com/posts/zoom-vulnerability/</guid><description>ZoomのミーティングURLに含まれるパスワードがサーバ側で大文字小文字を区別せず認証される脆弱性を発見。想定の暗号強度より10^30倍弱くなる問題を動画付きで実証報告。</description><pubDate>Mon, 29 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zoom.us/&quot;&gt;Zoom&lt;/a&gt;においてパスワード認証に関連する脆弱性を見つけました。&lt;/li&gt;
&lt;li&gt;特徴はリモートから、Zoomのサービスを利用しているユーザに対して、秘匿性に影響する内容です。&lt;/li&gt;
&lt;li&gt;自己診断したCVSSスコアは6.5です。
&lt;ul&gt;
&lt;li&gt;CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L/E:H/RL:O/RC:R&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;前提となる知識を説明します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Zoomにおいてミーティングの部屋を作成すると、新しい部屋のIDとパスワードが生成されます。&lt;/li&gt;
&lt;li&gt;また、その部屋のIDとパスワードの情報が含まれたURLも生成されます。&lt;/li&gt;
&lt;li&gt;このURLにアクセスすることによってZoomのミーティング部屋にアクセス可能になります。（以下に例。過去の時間に有効だったURLです）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;https://zoom.us/j/98459262939?pwd=K1J6VjdFd2NpTWpaenJ6WE0zWml0QT09
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;98459262939&lt;/code&gt;の部分は部屋のIDです。おそらく連番で発行されている感じです。&lt;/li&gt;
&lt;li&gt;このURLの後半にある &lt;code&gt;pwd&lt;/code&gt; パラメータにある&lt;code&gt;K1J6VjdFd2NpTWpaenJ6WE0zWml0QT09&lt;/code&gt;はパスワードを意味しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;このパスワードは、アルファベット大文字小文字と数字の組み合わせによっていできています。&lt;/li&gt;
&lt;li&gt;文字の長さは32文字です。最後の2桁は固定されている様子。&lt;/li&gt;
&lt;li&gt;よって、パターンは(26+26+10)^30個となります。（内訳：a-z, A-Z, 0-9）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;しかしながら、Zoomのサーバサイドの処理において、この大文字と小文字の区別をしていないので、実際には(26+10)^30個の組み合わせしか無いです。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;よって、おそらくですがZoom社が想定している暗号強度の&lt;strong&gt;10^30倍&lt;/strong&gt;弱い状態になってしまっています。&lt;/p&gt;
&lt;h2&gt;再現したときの動画&lt;/h2&gt;
&lt;p&gt;動画内の手順&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;正規のURLにアクセスします&lt;/li&gt;
&lt;li&gt;pwdパラメータの文字をすべて大文字にしてアクセスします。&lt;strong&gt;本来は入れないはずですが入れてしまいます。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://www.youtube.com/watch?v=JPA5hxmEonE&lt;/p&gt;
&lt;h2&gt;感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Zoom社のsecurity insident窓口にメールを送ったのですが、窓口の担当者が理解してくれなかったので書いてみました。&lt;/li&gt;
&lt;li&gt;実装ではよくある間違いで、ストレージエンジン（データベースなど）にこのパスワードとなる文字列が保存されており、URLにあるpwdパラメータと一致するかで評価していると思います。しかしながら、ストレージエンジンが大文字と小文字を区別しないので認証が通ってしまっていると考えます。実装レベルではよくある間違いです。&lt;/li&gt;
&lt;li&gt;暗号強度が10^30倍弱くなったとしてもまだ充分に強度はあるので実質問題は無いと思います。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>fail2banを運用するにあたっての設定</title><link>https://blog.teraren.com/posts/fail2ban-operation/</link><guid isPermaLink="true">https://blog.teraren.com/posts/fail2ban-operation/</guid><description>SSHの踏み台サーバでfail2banを運用し、24時間8998件のBANを記録。bantime1年に設定してMackerelでグラフ化する運用ノウハウ</description><pubDate>Fri, 26 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;fail2ban運用方法&lt;/h2&gt;
&lt;p&gt;どこからでもsshができるような、踏み台ホストを運用しています。&lt;/p&gt;
&lt;p&gt;fail2banを入れているのですが、ほんとアタックが多くて困りますねぇ。24時間で8,998件もBanしています。Banのルールは4回の認証失敗です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-36.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;fail2ban件数&lt;/p&gt;
&lt;p&gt;次に、現時点のiptablesでのDROPに入っているIPアドレスは114個です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;fail2banによりiptablesで拒否されている件数&lt;/p&gt;
&lt;p&gt;無駄なアタックを容認していると、こちらのCPUリソースやネットワークリソースを食うので、止む終えない理由で22番ポートを開放している場合はfail2banのインストールは必須かと思います。&lt;/p&gt;
&lt;h2&gt;どのくらいアタックが来ているか？&lt;/h2&gt;
&lt;p&gt;banされたら、メールが来るような設定をしていると、こんぐらいの頻度でアタックが来ています。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-38.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;fail2banのブロックしているホスト数をmackerelでグラフ化&lt;/h2&gt;
&lt;p&gt;メールの通知がたくさんくるので、1回ブロックしても再度アタックしてくるホストがたくさん居ることがわかります。&lt;/p&gt;
&lt;p&gt;ということで、パスワードはミスらないように注意するという運用と引き換えに、1回banをしたら1年間は解除しないように設定しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bantime = 31536000 ; 1 year
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mackerelのカスタムメトリックでグラフ化するときの設定はこちら。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image.png&quot; alt=&quot;fail2ban drop  and reject mackerel graph&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>回線速度を定期的にベンチマーク</title><link>https://blog.teraren.com/posts/speedtest-benchmark-mackerel/</link><guid isPermaLink="true">https://blog.teraren.com/posts/speedtest-benchmark-mackerel/</guid><description>OOKLAの公式speedtestコマンドをcronで定期実行し、Mackerelのカスタムメトリクスとして上り下りの回線速度をグラフ化する手順</description><pubDate>Wed, 17 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;インターネット回線速度が時間によってどの程度になっているのかを測定し、mackerelでグラフ化します。&lt;/li&gt;
&lt;li&gt;回線速度を測定するスクリプトはこちらに置きました。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/speedtest-for-mackerel&quot;&gt;https://github.com/matsubo/speedtest-for-mackerel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;speedtestコマンドは&lt;a href=&quot;https://www.speedtest.net/ja/apps/cli&quot;&gt;OOKLAが&lt;strong&gt;公式&lt;/strong&gt;に出しているコマンド&lt;/a&gt;です。aptにデフォルトで入っているspeedtestではないです。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/env ruby

require &apos;json&apos;

# command
# % speedtest --server-id=15047 -f json --progress=no
#
# output
# {&quot;type&quot;:&quot;result&quot;,&quot;timestamp&quot;:&quot;2020-06-16T01:07:49Z&quot;,&quot;ping&quot;:{&quot;jitter&quot;:120.10299999999999,&quot;latency&quot;:27.356000000000002},&quot;download&quot;:{&quot;bandwidth&quot;:878001,&quot;bytes&quot;:10077578,&quot;elapsed&quot;:13815},&quot;upload&quot;:{&quot;bandwidth&quot;:4004130,&quot;bytes&quot;:35680876,&quot;elapsed&quot;:9131},&quot;packetLoss&quot;:0,&quot;isp&quot;:&quot;So-net&quot;,&quot;interface&quot;:{&quot;internalIp&quot;:&quot;192.168.1.18&quot;,&quot;name&quot;:&quot;wlx0013eff32167&quot;,&quot;macAddr&quot;:&quot;00:13:EF:F3:21:67&quot;,&quot;isVpn&quot;:false,&quot;externalIp&quot;:&quot;223.132.34.53&quot;},&quot;server&quot;:{&quot;id&quot;:15047,&quot;name&quot;:&quot;OPEN Project (via 20G SINET)&quot;,&quot;location&quot;:&quot;Tokyo&quot;,&quot;country&quot;:&quot;Japan&quot;,&quot;host&quot;:&quot;speed.open.ad.jp&quot;,&quot;port&quot;:8080,&quot;ip&quot;:&quot;202.222.12.78&quot;},&quot;result&quot;:{&quot;id&quot;:&quot;3aca24d3-cde5-44cb-95e8-6c94bed68b93&quot;,&quot;url&quot;:&quot;https://www.speedtest.net/result/c/3aca24d3-cde5-44cb-95e8-6c94bed68b93&quot;}}

output=`speedtest --server-id=15047 -f json --progress=no`

json = JSON.parse(output)

time = Time.now.to_i
puts sprintf(&quot;speed.bandwidth.download\t%d\t%d&quot;, json[&quot;download&quot;][&quot;bandwidth&quot;], time)
puts sprintf(&quot;speed.bandwidth.upload\t%d\t%d&quot;, json[&quot;upload&quot;][&quot;bandwidth&quot;], time)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;/etc/mackerel-agent/mackerel-agent.conf に以下を追加します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[plugin.metrics.speedtest]
command = &quot;sudo -u matsu ruby /home/matsu/speedtest-for-mackerel/test.rb&quot;
interval = 15
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;まる1日動かしたときのグラフです。表示はByte/secondです。8倍すればbits/secondです。&lt;/p&gt;
&lt;p&gt;IPv4でしか計測できないのが難点です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-29.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;応用&lt;/h2&gt;
&lt;p&gt;回線のlatencyとjitterを計測したグラフ&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-30.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;回線のpacket loss数をカウントしたグラフ。IPv6 tunnelにしてからはとても安定しています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-31.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2020/7/16&lt;/p&gt;
&lt;p&gt;mackerelだと粒度が粗いのでGrafanaに移行した。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image-3.png&quot; alt=&quot;grafana&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>室内外の温度温度の変化を記録</title><link>https://blog.teraren.com/posts/raspberry-pi-thumostat-humid-sensor/</link><guid isPermaLink="true">https://blog.teraren.com/posts/raspberry-pi-thumostat-humid-sensor/</guid><description>Raspberry Pi 4とDHT11センサを使い、室内外の温度・湿度を定期取得してMackerelでグラフ可視化するIoT環境モニタリングシステムの構築手順を紹介します。</description><pubDate>Mon, 15 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;最近、&lt;strong&gt;外は涼しいのに&lt;/strong&gt;、マンションの&lt;strong&gt;部屋の中が暑い&lt;/strong&gt;と感じるときが多いです。&lt;/li&gt;
&lt;li&gt;「暑い」というのは主観的な指標でしか無いので、定量的かつ客観的な数字を取得してみることにします。&lt;/li&gt;
&lt;li&gt;「屋外と屋内」に「温度センサと湿度センサ」を設置してみます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;準備&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;以前に買った Raspberry Pi 4を使いまわします。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Raspberry Pi 4&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;温度湿度センサは&lt;a href=&quot;https://www.amazon.co.jp/HiLetgo-DHT11%E6%B8%A9%E5%BA%A6%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC-%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E6%B9%BF%E5%BA%A6%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-%E3%83%87%E3%83%A5%E3%83%9D%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%A8%E4%BB%98%E5%B1%9E-Arduino%E3%81%A8%E4%BA%92%E6%8F%9B/dp/B010GXAH4E?pd_rd_i=B010GXAH4E&amp;amp;psc=1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=fa126091cef8482fb1b448ad7cd8a562&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;DHT11&lt;/a&gt;を買います。精度が10倍高い&lt;a href=&quot;https://www.amazon.co.jp/HiLetgo-%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E6%B8%A9%E5%BA%A6%E6%B9%BF%E5%BA%A6%E3%82%BB%E3%83%B3%E3%82%B5%E3%83%BC%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-DHT22-AM2302-%E4%B8%A6%E8%A1%8C%E8%BC%B8%E5%85%A5%E5%93%81/dp/B010GXBBIU?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=7360663381e19f4c9dd47b424d796fd0&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;DHT22&lt;/a&gt;はお値段が3倍するためお遊びに2個も高めのセンサを買うのはやめました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B010GXAH4E&quot;}&lt;/p&gt;
&lt;h2&gt;実装&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ハードウェア系の道具は揃っていないので家に有る適当な品物で代用しますので全体的に見た目は良くないです。&lt;/li&gt;
&lt;li&gt;まず、&lt;a href=&quot;https://www.amazon.co.jp/%E3%83%A9%E3%82%BA%E3%83%99%E3%83%AA%E3%83%BC%E3%83%91%E3%82%A44-%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%83%BC%E3%83%A2%E3%83%87%E3%83%ABB-Raspberry-Computer-Model/dp/B07WR5W2D6?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=19e8f321e498f6f05c46fc028d557501&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;Raspberry Pi 4&lt;/a&gt;のピン仕様を調べます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/GPIO-Pinout-Diagram-2.png&quot; alt=&quot;Raspberry PI 4 GPIO&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2番ピンの5Vから電源を取ります。3Vでも稼働するらしいですが推奨は5Vとの記述があったので。接地は6番です。&lt;/p&gt;
&lt;p&gt;データは7番（IDは4）と8番（IDは14）を利用します。若い順に使ってみます。GPIO4に室内用のセンサ、GPIO14に室外用のセンサを取り付けます。&lt;/p&gt;
&lt;p&gt;配線したところはこんな感じです。2つ目のセンサは5mぐらいのVVFケーブルを流用しています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/IMG_3752.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/IMG_3751.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;こちらの&lt;a href=&quot;https://github.com/szazo/DHT11_Python&quot;&gt;DHT11用のPythonライブラリ&lt;/a&gt;を使って、データを取得、表示します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;その次に、mackerelの&lt;a href=&quot;https://mackerel.io/ja/docs/entry/advanced/custom-metrics&quot;&gt;カスタムメトリック&lt;/a&gt;に流し込めるように、仕様通りの表示形式にします。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;タブ区切り&lt;/li&gt;
&lt;li&gt;1カラム目はメトリックスの名称&lt;/li&gt;
&lt;li&gt;2カラム目は数値&lt;/li&gt;
&lt;li&gt;3カラム目はUNIXタイムスタンプ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/Screen-Shot-2020-06-10-at-13.16.38.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mackerel-agent.confに設定を追記します。&lt;/li&gt;
&lt;li&gt;そうすると、以下のようにmackerelで表示できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-14.png&quot; alt=&quot;温度のグラフをmackerelで表示&quot; /&gt;&lt;/p&gt;
&lt;p&gt;温度 on mackerel&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-13.png&quot; alt=&quot;湿度のグラフをmackerelで表示&quot; /&gt;&lt;/p&gt;
&lt;p&gt;湿度 on mackerel&lt;/p&gt;
&lt;p&gt;センサの精度が低いらしいですが、同じ場所に設置してみたところ、上記のグラフになったので2つの相対的なズレは大きく無さそうです。&lt;/p&gt;
&lt;p&gt;（湿度の方のグラフに差が大きいのは、試しに1m下にセンサを設置した見たからです。下のほうが10%ほど湿度が高いことがわかりました。）&lt;/p&gt;
&lt;h3&gt;テスト&lt;/h3&gt;
&lt;p&gt;不快指数もグラフに表示するようにしました。不快指数を求める計算式は以下です。&lt;/p&gt;
&lt;p&gt;不快指数DI　（Tは乾球気温℃、Hは湿度％）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DI=0.81T+0.01Hx(0.99T−14.3)+46.3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ついでに設置したCO2濃度のグラフはこちらです。冷房を付けると二酸化炭素濃度が上がります。&lt;/li&gt;
&lt;li&gt;使った&lt;a href=&quot;https://www.amazon.co.jp/%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0-CUSTOM-CO2-mini-CO2%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC/dp/B00I3XJ9LM?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=CO2%E3%81%AE%E3%82%BB%E3%83%B3%E3%82%B5&amp;amp;qid=1618339103&amp;amp;s=industrial&amp;amp;sr=1-17&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=750036c743a304b37c6484c98ae4b7ce&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;CO2のセンサ&lt;/a&gt;はこちら。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B00I3XJ9LM&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-17.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;晴れた日のグラフ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;湿度は、室内はほぼ一定。外より少し遅れてゆっくりと変化してきている感じです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;温度変化については、室内はほぼ一定、室外は24度から31度へ変化&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-24.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不快指数は外も中もほぼ一定です。&lt;/li&gt;
&lt;li&gt;この日は、部屋の中は別に暑いと感じる気はしませんでした。不快指数は78前後です。&lt;/li&gt;
&lt;li&gt;不快に感じる時は別の要因があるっぽいです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;雨が降った日のグラフ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;湿度は外のほうが20%ぐらい高いです&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-19.png&quot; alt=&quot;湿度のグラフ&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;温度は4度ぐらい室内のほうが高いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-20.png&quot; alt=&quot;温度のグラフ&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不快指数のグラフ&lt;/li&gt;
&lt;li&gt;5ポイントほど室内のほうが高いです。部屋の中は特に不快ではありませんが、少し湿度が高いという印象ぐらいでした。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-22.png&quot; alt=&quot;不快指数のグラフ&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;晴れのときは、部屋の&lt;strong&gt;湿度&lt;/strong&gt;が高くて不快&lt;/li&gt;
&lt;li&gt;雨のときは、室内の&lt;strong&gt;温度&lt;/strong&gt;が高くてやや不快&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ということがわかりました&lt;/p&gt;
</content:encoded></item><item><title>Google SpreadsheetからGoogle Calendarへ一括登録</title><link>https://blog.teraren.com/posts/google-spreadsheet-to-google-calendar/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-spreadsheet-to-google-calendar/</guid><description>Google Apps Scriptを使ってスプレッドシートの予定一覧をGoogle Calendarへ一括インポートする方法。テンプレートとスクリプト例付きで手順を解説。</description><pubDate>Tue, 09 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Google Spreadsheetにある予定の一覧をGoogle Calendarへ一括登録する方法です。&lt;/li&gt;
&lt;li&gt;イベントなどの予定をスプレッドシートで一括で作成したうえで、その予定をGoogle Calendarへexportするスクリプトです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;準備&lt;/h2&gt;
&lt;p&gt;予定の一覧が掲載されるSpreadsheetを準備します。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.google.com/spreadsheets/d/1dEvh2lWZ_4N92c0tui5L9pfOCqgFXdE3Unctl1B_ubg/edit?usp=sharing&quot;&gt;テンプレをこちらに置いた&lt;/a&gt;のでコピーを作成するのが良いと思います。スクリプト内では、行やセルの参照はこのテンプレを基準に書いてあるためです。（テンプレ内のURLやパスワードはデタラメです）&lt;/p&gt;
&lt;p&gt;Google SpreadsheetからGoogle Calendarに登録できるようにします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Google App Scriptをちょろっと書きます&lt;/p&gt;
&lt;p&gt;上記のApps ScriptをGoogle Spreadsheetで実行します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;追加されました！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://triathlon.teraren.com/wp-content/uploads/2020/04/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;予定の詳細。10分前にリマインダを設定しています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://triathlon.teraren.com/wp-content/uploads/2020/04/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cloud.google.com/blog/products/g-suite/g-suite-pro-tip-how-to-automatically-add-a-schedule-from-google-sheets-into-calendar&quot;&gt;G Suite Pro Tips: how to automatically add a schedule from Google Sheets into Calendar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>RTX830のNAPTテーブル、ARPテーブル、DHCPの使用状況をコマンドで取得</title><link>https://blog.teraren.com/posts/rtx830-napt-arp-dhcp/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rtx830-napt-arp-dhcp/</guid><description>RTX830のNAPTテーブル、ARPテーブル、DHCPの使用状況をコマンドで取得</description><pubDate>Mon, 08 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;YAMHA RTX830はSNMPで取得できない値があるので別途コマンドで取得する&lt;/p&gt;
&lt;h2&gt;グラフにした結果&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-32.png&quot; alt=&quot;YAMAH RTX 830  ARP table&quot; /&gt;&lt;/p&gt;
&lt;p&gt;arp&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-33.png&quot; alt=&quot;YAMAH RTX 830  DHCP client&quot; /&gt;&lt;/p&gt;
&lt;p&gt;dhcp&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-34.png&quot; alt=&quot;YAMAH RTX 830  NAT tabl&quot; /&gt;&lt;/p&gt;
&lt;p&gt;NAT&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-35.png&quot; alt=&quot;YAMAH RTX 830 session&quot; /&gt;&lt;/p&gt;
&lt;p&gt;session&lt;/p&gt;
&lt;p&gt;Mackerelではなく、Grafanaに入れて表示した図&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/07/image-10.png&quot; alt=&quot;grafana rtx830&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>RTX830でv6プラスを設定 (IPoE MAP-E)</title><link>https://blog.teraren.com/posts/rtx830-v6-plus-mape/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rtx830-v6-plus-mape/</guid><description>YAMAHA RTX830にIPoE MAP-E（v6プラス）を設定してPPPoEからの乗り換えでレイテンシーを20ms→10ms以下に改善した手順と速度比較</description><pubDate>Mon, 08 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;環境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;建物がVDSLなので100Mbpsまでしかでない。。。&lt;/li&gt;
&lt;li&gt;PPPoEだとレイテンシーが遅かったり、ピークタイムでは10Mbps程度しか出ませんでした。&lt;/li&gt;
&lt;li&gt;v6プラスに対応するためにはIPoEしかも、MAP-Eに対応した機材が必要だったので比較的新しくて、しかも一部の機種にしか付いていない機能なので以前と同じRTX1200に似たように設定したいので&lt;a href=&quot;https://www.amazon.co.jp/%E3%83%A4%E3%83%9E%E3%83%8F-RTX830-%E3%82%AE%E3%82%AC%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9VPN%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC/dp/B075YVK9QF?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=83375e51ecafde141c8c27dea43f842c&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;YAMAHA RTX830&lt;/a&gt;を買いました。&lt;/li&gt;
&lt;li&gt;ひかり電話は未契約&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B075YVK9QF&quot;}&lt;/p&gt;
&lt;h2&gt;IPoE設定前&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;IPv4は普通のPPPoEです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://kiriwake.jpne.co.jp/v/&quot;&gt;http://kiriwake.jpne.co.jp/v/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/Screen-Shot-2020-06-08-at-1.38.42.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.speedtest.net/&quot;&gt;https://www.speedtest.net/&lt;/a&gt; 深夜に測ったので速度は速いです。しかし帯域は若干不安定な感じのグラフがでています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/Screen-Shot-2020-06-08-at-1.40.04-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Googleのpublic DNSへのpingはだいたいaverage 20ms程度。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;IPoE設定後&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/Screen-Shot-2020-06-08-at-1.17.48.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;IPアドレスはプロバイダではなく、&lt;a href=&quot;https://www.jpne.co.jp/&quot;&gt;ネットワークイネイブラー&lt;/a&gt;のIPアドレスになっています。このIPアドレスはNAPTされていて、複数の人によって使い回されています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/Screen-Shot-2020-06-08-at-1.17.44.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;帯域のグラフがとても安定しています。速度もPPPoEより少し速いです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/Screen-Shot-2020-06-08-at-1.16.27.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Googleのpublic DNSへのpingが10ms以下に収まっていてWebの閲覧をしている時の反応が良い感じになりました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-10.png&quot; alt=&quot;RTX830のMAP-E設定後の画面&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;番外編&lt;/h2&gt;
&lt;p&gt;IPv6では100Mbpsきっちり出ることもあります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/Screen-Shot-2020-06-08-at-1.17.57.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;また、自宅サーバを運用する場合はMAP-EされたIPv4のアドレスは使えません。（他の人によって共有されているNAPTのホストなので）。よって、残念ですが自宅サーバはPPPoEのIPv4アドレスを使います。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://ipq.jp/plan/ipoe2/&quot;&gt;IPoEで固定IPアドレスを振ってくれるサービス&lt;/a&gt;がありますが、月に3000円ぐらいするので。。。&lt;/p&gt;
&lt;h3&gt;自宅の回線をIPv6対応するときに必要になる基礎知識がちゃんと書かれた本&lt;/h3&gt;
&lt;p&gt;https://x.com/_nhayato/status/1268948054872174594&lt;/p&gt;
&lt;h3&gt;zabbixでトラフィックを監視&lt;/h3&gt;
&lt;p&gt;最近思うことは、帯域よりlatencyのほうが重要な感じです。&lt;/p&gt;
&lt;p&gt;昨今のアプリケーションはリアルタイム性が求められるユースケースが増えてきました。例えばテレカン、SSH、ゲーム。&lt;/p&gt;
&lt;p&gt;動画や音楽はキューイングされるので体感的にはあまり重要ではない気がします。&lt;/p&gt;
&lt;p&gt;一般的には帯域が出るってことは、latencyも低いので一緒に扱われてしまいそうです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-9.png&quot; alt=&quot;RTX830 zabbix&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B075YVK9QF&quot;}&lt;/p&gt;
</content:encoded></item><item><title>UbuntuにてIPv6のtemporary addressを使わないようにする。サーバ運用なので。</title><link>https://blog.teraren.com/posts/disable-temporary-address-of-ipv6-on-ubuntu/</link><guid isPermaLink="true">https://blog.teraren.com/posts/disable-temporary-address-of-ipv6-on-ubuntu/</guid><description>RFC3041のIPv6プライバシー拡張による一時アドレス自動変更の仕組みを解説し、サーバ運用向けにUbuntuで固定アドレスのみ使用する設定手順を紹介します。</description><pubDate>Sat, 06 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/route-53-dynamic-dns/&quot;&gt;自宅サーバをipv6対応&lt;/a&gt;しました。&lt;/li&gt;
&lt;li&gt;Ubuntu Linuxを普通に使っていると、ipv6のアドレスは7日で変わってしまう。セキュリティ的な理由で。詳細は：&lt;a href=&quot;http://www5d.biglobe.ne.jp/stssk/rfc/rfc3041j.html&quot;&gt;RFC3041&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;最近、&lt;a href=&quot;https://qiita.com/notoken3331/items/ca228e2ac28ac7ea4879&quot;&gt;Web上で話題になっていた&lt;/a&gt;、ipv6のパケットフィルタリングルールに関する話題にも関連しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;仕様の調査&lt;/h2&gt;
&lt;p&gt;IPv6の仕様の一つに、&lt;a href=&quot;http://www5d.biglobe.ne.jp/stssk/rfc/rfc3041j.html&quot;&gt;Privacy Extensions for Stateless Address Autoconfiguration in IPv6&lt;/a&gt; (IPv6ステートレスアドレス自動設定のプライバシー拡張)があります。&lt;/p&gt;
&lt;p&gt;要するに、IPv6はNATが基本的に存在しなく、グローバルアドレスが直接ノードに振られてしまう事によってサーバサイドから追跡可能になってしまう可能性があるからそれを防ぐために定期的に使うアドレスを変更する技術です。&lt;/p&gt;
&lt;p&gt;逆に、勝手にIPv6アドレスが変わってしまっても困るので固定のアドレスと、一時アドレスの2つをNICにアサインして基本的には一時アドレスを使いましょうという方針です。&lt;/p&gt;
&lt;p&gt;例えば、macosでは以下のようなIPv6アドレスの表示があり、片方が一時アドレスになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/Pasted_Image_2020_06_06_13_10-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ipv6 最初の状態&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/Pasted_Image_2020_06_06_13_17.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;NICをoffにしてonにするとipv6の片方が入れ替わる （下）&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://ipv6-test.com/&quot;&gt;https://ipv6-test.com/&lt;/a&gt; にGoogle Chromeでアクセスすると、この変更されたipv6のアドレスが表示されます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;では、このRFC3041をOSではどのように実装しているかというと、Linuxの場合は以下のパラメータで調整します。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt&quot;&gt;https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;use_tempaddr - INTEGER
	Preference for Privacy Extensions (RFC3041).
	  &amp;lt;= 0 : disable Privacy Extensions
	  == 1 : enable Privacy Extensions, but prefer public
	         addresses over temporary addresses.
	  &amp;gt;  1 : enable Privacy Extensions and prefer temporary
	         addresses over public addresses.
	Default:  0 (for most devices)
		 -1 (for point-to-point devices and loopback devices)

temp_valid_lft - INTEGER
	valid lifetime (in seconds) for temporary addresses.
	Default: 604800 (7 days)

temp_prefered_lft - INTEGER
	Preferred lifetime (in seconds) for temporary addresses.
	Default: 86400 (1 day)
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;use_tempaddr :一時アドレスを使うかどうか制御。&lt;strong&gt;0なら無効、1なら一時アドレスを有効化しますが、パブリックアドレスを優先して使う。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;temp_valid_lft: 有効期限（&lt;strong&gt;デフォルトは7日&lt;/strong&gt;）&lt;/li&gt;
&lt;li&gt;temp_prefered_lft: 推奨される有効期間 （&lt;strong&gt;デフォルトは1日&lt;/strong&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;手元のUbuntu 20で確認してみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; sudo sysctl -a|grep -e temp_valid_lft -e  temp_prefered_lft -e use_tempaddr|grep wlx
net.ipv6.conf.wlx0013eff32167.temp_prefered_lft = 86400
net.ipv6.conf.wlx0013eff32167.temp_valid_lft = 604800
net.ipv6.conf.wlx0013eff32167.use_tempaddr = 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;use_tempaddrが2になっています。デスクトップ向けの設定という感じです。サーバならばこれが0か1になるべきです。&lt;/p&gt;
&lt;p&gt;では、AWS EC2ではどのように設定されているかを見てみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo sysctl -a|grep -e temp_valid_lft -e temp_prefered_lft -e use_tempaddr|grep ens
net.ipv6.conf.ens5.temp_prefered_lft = 86400
net.ipv6.conf.ens5.temp_valid_lft = 604800
net.ipv6.conf.ens5.use_tempaddr = 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;0になっています。&lt;/p&gt;
&lt;p&gt;まぁ、自宅サーバなのでuse_tempaddrは1に設定しておこうかと思います。&lt;/p&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; sudo sysctl  net.ipv6.conf.wlx0013eff32167.use_tempaddr
net.ipv6.conf.wlx0013eff32167.use_tempaddr = 2
matsu@dell ~&amp;gt; curl https://v6.ident.me/
240b:10:2120:f400:edc1:bcf0:567b:785d

matsu@dell ~&amp;gt; sudo sysctl -w net.ipv6.conf.wlx0013eff32167.use_tempaddr=1
net.ipv6.conf.wlx0013eff32167.use_tempaddr = 1
matsu@dell ~&amp;gt; curl https://v6.ident.me/
240b:10:2120:f400:f93f:c66f:26ff:46e3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;設定の永続化をするために以下を/etc/sysctl.confへ追記&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;net.ipv6.conf.wlx0013eff32167.use_tempaddr=1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一応、ddns-route53の動作確認をします。今までは一時アドレスを使って、これからはpublic addressを使うようになっているかを確認しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /v/log# grep ddns syslog|grep IPv6|tail -n 10
Jun  6 13:00:02 dell ddns-route53[110094]: #033[90mSat, 06 Jun 2020 04:00:02 UTC#033[0m #033[32mINF#033[0m Current WAN IPv6: 240b:10:2120:f400:edc1:bcf0:567b:785d
Jun  6 13:00:02 dell ddns-route53[110094]: #033[90mSat, 06 Jun 2020 04:00:02 UTC#033[0m #033[32mINF#033[0m WAN IPv4/IPv6 addresses have not changed since last update. Skipping...
Jun  6 13:00:02 dell ddns-route53[1588297]: #033[90mSat, 06 Jun 2020 04:00:02 UTC#033[0m #033[32mINF#033[0m Current WAN IPv6: 240b:10:2120:f400:edc1:bcf0:567b:785d
Jun  6 13:00:02 dell ddns-route53[1588297]: #033[90mSat, 06 Jun 2020 04:00:02 UTC#033[0m #033[32mINF#033[0m WAN IPv4/IPv6 addresses have not changed since last update. Skipping...
Jun  6 13:30:02 dell ddns-route53[1588297]: #033[90mSat, 06 Jun 2020 04:30:02 UTC#033[0m #033[32mINF#033[0m Current WAN IPv6: 240b:10:2120:f400:edc1:bcf0:567b:785d
Jun  6 13:30:02 dell ddns-route53[1588297]: #033[90mSat, 06 Jun 2020 04:30:02 UTC#033[0m #033[32mINF#033[0m WAN IPv4/IPv6 addresses have not changed since last update. Skipping...
Jun  6 13:30:02 dell ddns-route53[110094]: #033[90mSat, 06 Jun 2020 04:30:02 UTC#033[0m #033[32mINF#033[0m Current WAN IPv6: 240b:10:2120:f400:edc1:bcf0:567b:785d
Jun  6 13:30:02 dell ddns-route53[110094]: #033[90mSat, 06 Jun 2020 04:30:02 UTC#033[0m #033[32mINF#033[0m WAN IPv4/IPv6 addresses have not changed since last update. Skipping...
Jun  6 14:00:02 dell ddns-route53[1588297]: #033[90mSat, 06 Jun 2020 05:00:02 UTC#033[0m #033[32mINF#033[0m Current WAN IPv6: 240b:10:2120:f400:f93f:c66f:26ff:46e3
Jun  6 14:00:03 dell ddns-route53[110094]: #033[90mSat, 06 Jun 2020 05:00:03 UTC#033[0m #033[32mINF#033[0m Current WAN IPv6: 240b:10:2120:f400:f93f:c66f:26ff:46e3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ddns-route53もtemporary addressを使っていたようなので、今回の設定によってpublic addressを使うようになりました。&lt;/p&gt;
&lt;p&gt;あと、IPv6のフィルタリングが気になったのでポートスキャンしてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ nmap -6 240b:10:2120:f400:f93f:c66f:26ff:46e3
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-06 05:09 UTC
Nmap scan report for 240b:10:2120:f400:f93f:c66f:26ff:46e3
Host is up (0.012s latency).
Not shown: 992 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
139/tcp  open  netbios-ssn
443/tcp  open  https
445/tcp  open  microsoft-ds
3000/tcp open  ppp
3001/tcp open  nessus
3003/tcp open  cgms
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;む。ipv6のフィルタ設定が漏れていたので、ちゃんとfilterをしました。世の中にサンプルとして公開されているYAMAHA RTX系ルータの設定って危険ですね。。。。再テストします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ nmap -6 240b:10:2120:f400:f93f:c66f:26ff:46e3
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-06 06:16 UTC
Nmap scan report for 240b:10:2120:f400:f93f:c66f:26ff:46e3
Host is up (0.013s latency).
Not shown: 997 filtered ports
PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Nmap done: 1 IP address (1 host up) scanned in 4.79 seconds
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宅サーバのIPv6アドレスが、長期間変更されないようになりました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;p&gt;上記の解説をもとにして、こちらの記事を見てみると、&lt;a href=&quot;https://qiita.com/notoken3331/items/ca228e2ac28ac7ea4879&quot;&gt;この記事&lt;/a&gt;内で指摘しているセキュリティリスクを理解できると思います。ブルートフォースで端末のIPv6アドレスを探すのは非常に困難です。&lt;/p&gt;
&lt;p&gt;しかしながら、サーバサイドに悪意のあるサーバや途中経路に悪意のあるノードがいる場合は、接続元のIPv6アドレスを知れるのでそこに対してアタックを仕掛けるのは容易になるというリスクがあります。&lt;/p&gt;
</content:encoded></item><item><title>docker-composeでzabbixを立ち上げ</title><link>https://blog.teraren.com/posts/docker-compose-zabbix/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-compose-zabbix/</guid><description>docker-composeを使ってZabbixを9コンテナ構成で立ち上げ、自宅のYAMAHA RTXルーターのリソースをSNMP経由で監視する設定手順。公式テンプレートを使った初期設定方法を解説。</description><pubDate>Sat, 06 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宅のYAMAHA RTXルーターのリソースをSNMP経由で取得して集計したりしようかなと思います。&lt;/li&gt;
&lt;li&gt;とりあえず、今もZabbixがメジャーっぽいのでZabbixにします。&lt;/li&gt;
&lt;li&gt;dockerのイメージがあるので利用して立ち上げます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;初期設定&lt;/h2&gt;
&lt;p&gt;docker-compose.ymlの&lt;a href=&quot;https://github.com/zabbix/zabbix-docker&quot;&gt;テンプレ&lt;/a&gt;が用意されているので利用します。簡単にコピペでできるような感じで作られていないので少し設定をしていきます。&lt;/p&gt;
&lt;p&gt;普通に作ると、以下の9コンテナが立ち上がります。使わないサービスを落としてもよいのですが依存関係が設定されていて外すのが面倒なのでこのまま立ち上げます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;zabbix-docker-compose_zabbix-web-apache-mysql
zabbix-docker-compose_zabbix-proxy-mysql
zabbix-docker-compose_zabbix-proxy-sqlite3
zabbix-docker-compose_zabbix-agent
zabbix-docker-compose_zabbix-web-nginx-mysql
zabbix-docker-compose_zabbix-server
zabbix-docker-compose_zabbix-snmptraps
zabbix-docker-compose_mysql-server
zabbix-docker-compose_zabbix-java-gateway
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;環境変数を定義したファイルをたくさん用意して、upすれば起動します。&lt;/p&gt;
&lt;p&gt;ファイルが沢山あるので以下に置いておきます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/matsubo/zabbix-docker-compose&quot;&gt;https://github.com/matsubo/zabbix-docker-compose&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;起動したら、8081番ポートで立ち上がっているWebインターフェイスにアクセスします。&lt;/p&gt;
&lt;p&gt;ログインページが表示されたら、デフォルトのアカウントを使ってログインします&lt;/p&gt;
&lt;p&gt;ユーザー名: &lt;strong&gt;Admin&lt;/strong&gt;、パスワード:&lt;strong&gt;zabbix&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;起動後の初期設定は以下のURLを参考にして、serverのアドレスやproxyなどを登録しました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://hawksnowlog.blogspot.com/2019/06/zabbix42-on-docker.html&quot;&gt;https://hawksnowlog.blogspot.com/2019/06/zabbix42-on-docker.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こんな感じでRTX830の統計を表示&lt;/p&gt;
&lt;p&gt;zabbix自体がCPUとDiskをそこそこ使う感じ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>GitHub ActionsからS3へデプロイ</title><link>https://blog.teraren.com/posts/github-actions-deploy-to-s3/</link><guid isPermaLink="true">https://blog.teraren.com/posts/github-actions-deploy-to-s3/</guid><description>GitHub ActionsからS3へデプロイ</description><pubDate>Thu, 04 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;デザイナーやディレクターが管理する静的ファイルを自動でGitHubからS3へデプロイする設定をする必要が出てきました。&lt;/li&gt;
&lt;li&gt;今まではCircleCIでdeployを頑張っていましたが、GitHub Actionsの&lt;a href=&quot;https://github.com/marketplace?type=actions&quot;&gt;アセット&lt;/a&gt;が揃ってきたので非常に簡単にできるようになっています。&lt;/li&gt;
&lt;li&gt;GitHub + CircleCIより、GitHubだけでできるという、ワンストップは設定が集約できて良いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;最終的に行った設定は、2点だけ。&lt;/p&gt;
&lt;p&gt;.github/workflows/main.yml に以下の内容を保存。&lt;/p&gt;
&lt;p&gt;レポジトリの、Secretsに環境変数としてAWSの認証情報を入稿します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;実行履歴&lt;/p&gt;
&lt;h2&gt;注意点&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;出力ログ&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;レポジトリには、1つディレクトリを作ってその下に公開するファイルを置くのが楽です。&lt;/li&gt;
&lt;li&gt;レポジトリ全体を転送するとなると.gitファイルやREADMEをexcludeする必要が出てきて面倒です。excludeするとなったら、argsに個別設定をする必要があります。&lt;/li&gt;
&lt;li&gt;s3-sync-actionは裏で&lt;a href=&quot;https://github.com/jakejarvis/s3-sync-action/blob/master/entrypoint.sh#L42&quot;&gt;aws s3 syncを使ってはいる&lt;/a&gt;ものの、差分が無いファイルもアップロードされているようなログが出ているので謎です。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Wi-Fi6を導入してみたら590Mbpsしか出ない</title><link>https://blog.teraren.com/posts/wifi6/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wifi6/</guid><description>TP-LinkのWi-Fi 6アクセスポイントを導入しiPhone 11でiperf3ベンチマーク実施。上り246Mbps・下り492Mbpsの実測値と有線LAN・5GHz Wi-Fiとの速度比較結果を公開。</description><pubDate>Thu, 21 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WiFi6 (IEEE 802.11ax) 対応端末が登場してきたので試してみました。&lt;/li&gt;
&lt;li&gt;そもそもWiFi6に対応している端末は、iPhone 11しか持っていないので、あんまり意味は無いですが今後のためということで。&lt;/li&gt;
&lt;li&gt;Linux上でのネットワークパフォーマンスを測定するためには&lt;a href=&quot;https://iperf.fr/iperf-download.php&quot;&gt;iperf3&lt;/a&gt;が良さそうです。iperfのバージョン2もありますが、3だとuplinkとdownlinkを勝手に測定してくれます。&lt;/li&gt;
&lt;li&gt;スピード的には大したこと無いような気がします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Wi-Fi6のアクセスポイント設定&lt;/h2&gt;
&lt;p&gt;買った機材はこちら。安いし、最近コスパが良いから買いまくっているTP-LINKです。悲しいのは、MAP-Eに対応していないこと。。。。ルーターとしてはあと1歩頑張ってほしい。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0813GJVYK&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こんな感じでかんたんな統計情報も出ます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/jp/app/wifi-explorer-lite/id1408727408?mt=12&quot;&gt;WiFi Explorer Lite&lt;/a&gt;で見てみた感じはこちら。設定は基本的にデフォルトです。帯域をかなり占領しております。家の周辺にはWi-Fi 6に対応したアクセスポイントは見当たりません！一番乗り。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-23.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;テスト&lt;/h2&gt;
&lt;p&gt;まず、ベンチマーク先であるノードへの有線LANがボトルネックにならないかを確認します。一応理論上WiFi6は現時点で1200Mbps出るらしいので。&lt;/p&gt;
&lt;p&gt;Wired Ethernet (1000Mbps)のベンチマーク。実測943Mbpsぐらいです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-24.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;参考までに、macbook pro 2019から5GHzのWiFi経由でアクセスした場合は、スループットは上下約165Mbps程度です。（これはこれで。なんか遅いです。L1は混雑している感じはしないので、業務用のちゃんとしたWiFiアクセスポイントじゃないとだめなのか？）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;遮蔽物がある、10mぐらい離れた場所では70Mbpsぐらいになってしまいます。&lt;/p&gt;
&lt;h2&gt;お待ちかねのWiFi6ベンチマーク&lt;/h2&gt;
&lt;p&gt;では、WiFi6対応のiPhone 11で試してみます。iperf3プロトコルに対応した&lt;a href=&quot;https://apps.apple.com/jp/app/iperf-3-wifi-speed-test/id1462260546&quot;&gt;iPerf&lt;/a&gt;というアプリを使ってベンチマークをします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/0ABEF20A-3C96-40A2-A895-32A52430D598_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WiFi6 上り&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/F4A1C2E5-5C28-4880-B553-4D44BD9C3818_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;WiFi6 下り&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;結果は、&lt;strong&gt;上り246Mbps&lt;/strong&gt;、&lt;strong&gt;下り492Mbps&lt;/strong&gt;とのこと。測定環境は、アクセスポイントから30cmぐらい離れたところで数回行い、速度が安定していることを確認しました。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WiFiがボトルネックとなるような環境では、導入しても良いかと思います。&lt;/li&gt;
&lt;li&gt;最近では、インターネット回線が200Mbps以上出るのでWiFiがボトルネックとなる場合が多くなりそうです。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Route 53を使ってDynamic DNS設定（ipv4, ipv6対応）</title><link>https://blog.teraren.com/posts/route-53-dynamic-dns/</link><guid isPermaLink="true">https://blog.teraren.com/posts/route-53-dynamic-dns/</guid><description>自宅サーバのIPv4/IPv6アドレスをAWS Route 53で自動更新するDynamic DNSをddns-route53ツールで構築する手順をIAM設定から解説</description><pubDate>Wed, 20 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宅サーバをIPv6対応するためにはDynamic DNSを設定しないといけないです。&lt;/li&gt;
&lt;li&gt;zoneサーバはAWS Route 53で運用されているのでCLIで書き換えるスクリプトを書くのが面倒だったので長らく放置していました。&lt;/li&gt;
&lt;li&gt;ちょっと探してみると、AWS APIをラップしているスクリプトがあったので設定してみました。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/crazy-max/ddns-route53/&quot;&gt;https://github.com/crazy-max/ddns-route53/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Route53の設定&lt;/p&gt;
&lt;h2&gt;理想の手順&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://crazymax.dev/ddns-route53/usage/prerequisites/&quot;&gt;こちら&lt;/a&gt;のドキュメントを参考にIAMユーザと、Policyを作成します。&lt;/p&gt;
&lt;p&gt;設定ファイルを&lt;code&gt;ddns-route53.yml&lt;/code&gt;という名前で作成します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;credentials:
  access_key_id: &quot;YOUR ACCESS KEY&quot;
  secret_access_key: &quot;YOUR SECRET ACCESS KEY&quot;

route53:
  hosted_zone_id: &quot;YOUR ZONE ID XXXXXXXX&quot;
  records_set:
    - name: &quot;teraren.com.&quot;
      type: &quot;A&quot;
      ttl: 300
    - name: &quot;teraren.com.&quot;
      type: &quot;AAAA&quot;
      ttl: 300
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;docker-composeのサンプルスクリプトがあるので、&lt;code&gt;docker-compose.yml&lt;/code&gt;というファイル名で作成します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;version: &quot;3.2&quot;

services:
  ddns-route53:
    image: crazymax/ddns-route53:latest
    container_name: ddns-route53
    volumes:
      - &quot;./ddns-route53.yml:/ddns-route53.yml:ro&quot;
    environment:
      - &quot;TZ=Asia/Tokyo&quot;
      - &quot;SCHEDULE=*/30 * * * *&quot;
      - &quot;MAX_RETRIES=3&quot;
      - &quot;LOG_LEVEL=info&quot;
      - &quot;LOG_JSON=false&quot;
      - &quot;LOG_CALLER=false&quot;
    restart: always
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そのうえで、&lt;code&gt;docker-compose up&lt;/code&gt;を叩けば動きます。&lt;/p&gt;
&lt;p&gt;しかしながら、ipv6のアドレスを取得する際にエラーができます。DockerがIPv6に対応していない感じのエラーです。軽くトラブルシュートしてみましたが、ちょっと面倒そうなので諦めました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; docker-compose up
Starting ddns-route53 ... done
Attaching to ddns-route53
ddns-route53    | Wed, 20 May 2020 09:00:12 JST INF Starting ddns-route53 1.9.1
ddns-route53    | Wed, 20 May 2020 09:00:13 JST INF Current WAN IPv4: 222.230.108.57
ddns-route53    | Wed, 20 May 2020 09:00:13 JST ERR Cannot retrieve WAN IPv6 address error=&quot;request failed: Get https://v6.ident.me/: dial tcp [2a01:7e00::f03c:91ff:fe70:xxxx]:443: connect: cannot assign requested address&quot;
ddns-route53    | Wed, 20 May 2020 09:00:13 JST ERR No WAN IPv6 address available to update teraren.com. record
ddns-route53    | Wed, 20 May 2020 09:00:13 JST ERR No WAN IPv6 address available to update *.teraren.com. record
ddns-route53    | Wed, 20 May 2020 09:00:14 JST ERR Cannot update records set error=&quot;InvalidInput: Invalid XML ; cvc-complex-type.2.4.b: The content of element &apos;Change&apos; is not complete. One of &apos;{\\&quot;https://route53.amazonaws.com/doc/2013-04-01/\\&quot;:Action, \\&quot;https://route53.amazonaws.com/doc/2013-04-01/\\&quot;:ResourceRecordSet}&apos; is expected.\\n\\tstatus code: 400, request id: 6a21c50f-4f3e-4a0b-b588-62ddb890ed66&quot;
ddns-route53    | Wed, 20 May 2020 09:00:14 JST INF 6 records set updated changes={&quot;ChangeInfo&quot;:null}
ddns-route53    | Wed, 20 May 2020 09:00:14 JST INF Cron initialized with schedule */30 * * * *
ddns-route53    | Wed, 20 May 2020 09:00:14 JST INF Next run in 29 minutes (2020-05-20 09:30:00 +0900 JST)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかたがないので、ddns-route53をbinaryでインストールして、daemonとして設定しました。&lt;/p&gt;
&lt;h4&gt;※オプション&lt;/h4&gt;
&lt;p&gt;daemonとして稼働させるよりcrontabのほうが楽かなと思いました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*/30 * * * * /usr/local/bin/ddns-route53 --config /path/to/ddns-route53.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;外部からテスト&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; host matsu.teraren.com
matsu.teraren.com is an alias for vectant.teraren.com.
vectant.teraren.com has address 121.3.155.147
vectant.teraren.com has IPv6 address 240b:10:2120:f400:4167:4cee:9d38:6125
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Work From Homeのこのご時世、IPv6対応してないと遅くて辛いですね。&lt;/p&gt;
&lt;h2&gt;IPアドレスが更新されて、非定期的に更新したいとき&lt;/h2&gt;
&lt;p&gt;デーモンで動いているので、デーモンを再起動すればOK&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo systemctl restart  ddns-route53
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Ubiquiti Networks Edgerouter ER-X設定</title><link>https://blog.teraren.com/posts/ubiquiti-networks-edgerouter/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ubiquiti-networks-edgerouter/</guid><description>Ubiquiti Networks Edgerouter ER-X設定</description><pubDate>Tue, 12 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;とりま、最初に入っていたファームウェアが古すぎなので、最新を入れるところからやります。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.ui.com/download/edgemax/default/default/edgerouter-er-xer-x-sfpep-r6er-10x-firmware-v208-hotfix1&quot;&gt;https://www.ui.com/download/edgemax/default/default/edgerouter-er-xer-x-sfpep-r6er-10x-firmware-v208-hotfix1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/04/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そして、MAP-Eに対応していないことが判明したので設定を中止しました。良い製品なのに惜しい。現在利用中のルーターがRTX1200なので速度や機能は同程度なのでEdgerouterの設定は見送り。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B010MZFH5A&quot;}&lt;/p&gt;
</content:encoded></item><item><title>テレカン環境のセルフチェックポイント</title><link>https://blog.teraren.com/posts/self-check-online-meeting/</link><guid isPermaLink="true">https://blog.teraren.com/posts/self-check-online-meeting/</guid><description>ZoomやTeamsなどのテレビ会議で映像・音声を高品質に届けるためのPC性能・マイク・カメラ・照明・背景のセルフチェック項目集</description><pubDate>Mon, 11 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自分の動画と音声が相手に高品質に届く状態にあるかどうかをセルフチェックするための項目です。&lt;/li&gt;
&lt;li&gt;zoom, whereby, Skype, Google Hangout, Teamsなどで汎用的に使えるスキルです。&lt;/li&gt;
&lt;li&gt;macOS前提での解説ですが、同じような設定がWindowsにもあります。&lt;/li&gt;
&lt;li&gt;(社内LT用の記事)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;評価する指標&lt;/h2&gt;
&lt;h3&gt;PC&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CPU処理速度&lt;/li&gt;
&lt;li&gt;物理メモリ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;wherebyやGoogle HangoutはWebRTCを使っており、今の所ハードウェアエンコーディングを使えないので、エンコードとでコードの処理にGPUではなくCPUを使ってしまう。&lt;/p&gt;
&lt;p&gt;アクティビティモニタで、CPUの使用率の変化をグラフで観察します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;どのくらいCPUを使うかというと、320 x 240の動画、音声ストリームを8つを開いたときの状態です。（2.4 GHz 8-Core Intel Core i9という速いCPU）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;マイク&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ピンきりです。100円〜5万円&lt;/li&gt;
&lt;li&gt;Youtuberやpodcastが流行ったので、「&lt;a href=&quot;https://www.google.com/search?q=youtube+live%E3%82%AA%E3%82%B9%E3%82%B9%E3%83%A1%E3%83%9E%E3%82%A4%E3%82%AF&amp;amp;rlz=1C5CHFA_enJP888JP889&amp;amp;oq=youtube+live%E3%82%AA%E3%82%B9%E3%82%B9%E3%83%A1%E3%83%9E%E3%82%A4%E3%82%AF&amp;amp;aqs=chrome..69i57j69i64.105j0j7&amp;amp;sourceid=chrome&amp;amp;ie=UTF-8&quot;&gt;youtube liveオススメマイク&lt;/a&gt;」とかで検索するとたくさん出てきます。&lt;/li&gt;
&lt;li&gt;Youtubeにレビューが&lt;a href=&quot;https://www.youtube.com/results?search_query=%E3%83%9E%E3%82%A4%E3%82%AF+%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC&quot;&gt;沢山掲載&lt;/a&gt;されています。コロナ前なので紹介されていても入手が困難です。&lt;/li&gt;
&lt;li&gt;USB2.0とUSB3.0では、周波数特性の違いから&lt;a href=&quot;http://sloppy-games.com/%E3%83%9E%E3%82%A4%E3%82%AF%E3%81%AE%E9%9F%B3%E3%81%8C%E3%80%8C%E3%82%B5%E3%83%BC%E3%80%8D%E3%81%A8%E9%B3%B4%E3%81%A3%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86%E3%81%AE%E3%82%92%E8%A7%A3%E6%B1%BA%E3%81%97/&quot;&gt;ノイズが乗る&lt;/a&gt;ことがあるらしいので、USB2.0は2.0で接続する必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;EarPodsのマイクはなにげに優秀。&lt;br /&gt;
&lt;a href=&quot;https://www.apple.com/jp/shop/product/MNHF2FE/A/earpods-with-35-mm-headphone-plug&quot;&gt;https://www.apple.com/jp/shop/product/MNHF2FE/A/earpods-with-35-mm-headphone-plug&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;サンプリングレートを見るのは重要！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://web.liveon.ne.jp/glossary/sampling_rate/&quot;&gt;https://web.liveon.ne.jp/glossary/sampling_rate/&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;純粋にマイクや録音環境をテストするためには、自分で録音してみます。&lt;/li&gt;
&lt;li&gt;ホワイトノイズの乗り方、音量の大きさが確認できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bluetoothのヘッドフォンの場合、マイクの品質を重視していない場合が多いのでとてもサンプリングレートが低い場合がある。8kHzとか。&lt;/li&gt;
&lt;li&gt;Bose QC35 bluetoothヘッドフォンの場合は、16kHzに固定されている。
&lt;ul&gt;
&lt;li&gt;CD: 44.1kHz, 電話: 8kHz&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ソフトウェアでノイズキャンセリングをできます。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ref.krisp.ai/u/ud40cc5747?utm_source=refprogram&amp;amp;utm_campaign=219011&amp;amp;locale=en-JP&quot;&gt;https://ref.krisp.ai/u/ud40cc5747?utm_source=refprogram&amp;amp;utm_campaign=219011&amp;amp;locale=en-JP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;krisp、まじすごいです。キーボードの打鍵音とか環境音が一切消えます。普通、救急車とかが通ると絶対拾ってしまうのですがそのような音を綺麗に消してくれます。&lt;/li&gt;
&lt;li&gt;一度使ったら手放せません。というか、相手に不快な音を届けないためのエチケットと考えてます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-17.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;スピーカー・ヘッドフォン&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ハウリングを防ぐために、ベストはヘッドフォンの組み合わせです。&lt;/li&gt;
&lt;li&gt;指向性マイクを使っていたり、マイクとスピーカーが遠かったり、ハウリング防止ロジックが効いていれば近くても良いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;カメラ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;FPS
&lt;ul&gt;
&lt;li&gt;1秒間に何コマ撮影できるか&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;解像度
&lt;ul&gt;
&lt;li&gt;どこまで細かく映像を撮れるか&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ホワイトバランス&lt;/li&gt;
&lt;li&gt;露出&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;回線の品質&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;回線の品質
&lt;ul&gt;
&lt;li&gt;latency&lt;/li&gt;
&lt;li&gt;bandwidth&lt;/li&gt;
&lt;li&gt;IPのversion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://www.speedtest.net/&quot;&gt;https://www.speedtest.net/&lt;/a&gt; はIPv6に非対応なのでおすすめしません。お勧めはNetflixが運営しているfast.comかCloudflareです。&lt;/p&gt;
&lt;h4&gt;fast.com&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://fast.com/&quot;&gt;https://fast.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://fast.com/&quot;&gt;Fast.com&lt;/a&gt;ならば、IPv6, IPv4に対応しています。&lt;a href=&quot;https://speed.cloudflare.com/&quot;&gt;CloudFlare&lt;/a&gt;のベンチマークもIPv6, IPv4対応でいろいろな指標が出て良いのですが、遅いです。&lt;/p&gt;
&lt;h4&gt;Cloudflare&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://speed.cloudflare.com/&quot;&gt;https://speed.cloudflare.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ページを開いて、しばらく放置すると色々な計測が行われます。回線の帯域に対してスロースタートで始まっていくので、完了まで時間がかかります。&lt;/p&gt;
&lt;p&gt;一通り完了したら、真ん中辺にある「Network Quality Score」の部分を見てもらうとサマリーが掲載されています。最高の場合は、Greatと表示されるはずです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-45.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ベンチマークでは一時的な情報しかわかりません。テレカンをしているときに、テレカンが不安定になった場合は逐次、自分の状態を知る必要があります。&lt;/p&gt;
&lt;p&gt;そのときに、いちいちアクティビティモニターを開いていては時間がかかったり、粒度が荒かったりするので原因分析をすぐに行うことが難しいです。なので、私はiStat Menusを使っています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bjango.com/mac/istatmenus/&quot;&gt;iStat Menus&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ネットワーク帯域&lt;/p&gt;
&lt;h2&gt;より高品質を求めて&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;テレカン映えを狙って。&lt;/li&gt;
&lt;li&gt;ライティング
&lt;ul&gt;
&lt;li&gt;ダイナミックレンジ&lt;/li&gt;
&lt;li&gt;光源&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://rocketnews24.com/2020/04/09/1356841/
https://www.instagram.com/p/B-tnyXAJrjB/?utm_source=ig_web_copy_link&lt;/p&gt;
&lt;p&gt;その他の参考資料&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Netflixが説明する吹き替え環境の説明書
&lt;ul&gt;
&lt;li&gt;よくまとまっています。&lt;/li&gt;
&lt;li&gt;さすがプロクオリティを目指しているだけあって、推奨する機材が高価です。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>iPhoneの高画質カメラをWebカメラとして使う(無料)</title><link>https://blog.teraren.com/posts/iphone-web-camera/</link><guid isPermaLink="true">https://blog.teraren.com/posts/iphone-web-camera/</guid><description>NDIツールを使いiPhone 11 Proの高解像度カメラをMacのWebカメラ入力として無料で活用する設定とZoom・OBSへの適用方法</description><pubDate>Sun, 10 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;リモートワークが増えてWebカメラやPCの内蔵カメラを使う機会が増えました。しかしながら、Macbook Proの内蔵カメラの解像度は1024 x 720ピクセルなので解像度が低いです。（まぁ、テレカンには問題無いかと思いますがちょっと解像度が高いテレカンシステムの場合は見劣りします）&lt;/li&gt;
&lt;li&gt;以下にサンプル画像。FaceTimeで表示して拡大した画像です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;それに比べ、iPhone 11 Proのカメラは、2,436 x 1,125なので解像度は4倍になります。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ndi.tv/tools/#download-tools&quot;&gt;NDI&lt;/a&gt;が公開しているソフトを使うとiPhoneのカメラをPCの入力として扱えるようになり、カメラの入力として使えるようになります。&lt;/li&gt;
&lt;li&gt;以下、サンプル。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/Pasted_Image_2020_05_10_4_24.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Amazonや家電量販店ではWebカメラが売り切れたり、高騰しているのでiPhoneを流用できるととても良いです。しかも無料。&lt;/p&gt;
&lt;h2&gt;NDIとは？&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;NDI(ネットワーク・デバイス・インターフェイス)は、インターネットプロトコル経由による映像伝送(ビデオオーバーIP)テクノロジーのひとつとして、NewTek社が開発し提唱しているテクノロジーです。NDIを利用することにより、SDIなどの映像ケーブルを使用せずに、一般的なギガビットイーサネット環境においても、映像、音声、メタデータをNewTek社製品TriCasterやIPシリーズなどのシステム間のみならず、NDI互換のさまざまな他社製システム、デバイス、PC間においても、高品質、かつ超低遅延で、複数のピデオストリームの相互伝送を可能とします。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.brains-system.co.jp/pdf/D-storm/NDI.pdf&quot;&gt;https://rental.pandastudio.tv/blog/ndi/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;使ってみた感じ、本当に低遅延でmDNSで名前解決もしてくれるし、使い勝手が良いです。プロトコル自体が汎用なので様々なアプリケーションの登場が期待されます。&lt;/p&gt;
&lt;p&gt;応用をするとプラグイン（&lt;a href=&quot;https://github.com/Palakis/obs-ndi/releases&quot;&gt;obs-ndi&lt;/a&gt;）を入れることで&lt;a href=&quot;https://obsproject.com/ja&quot;&gt;OBS Studio&lt;/a&gt;の入力ストリームの1つとして扱えたりもします。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;NDI was developed by NewTek, and is available to anyone with a royalty-free license. NewTek has an SDK available for Windows, Linux and macOS.[1] NDI has also been ported to iOS, tvOS[2], Android, Raspberry Pi, and FPGA.[3][4]NDI is designed to run over existing Gigabit networks,[5] with the NDI codec[6] expected to deliver 1080i HD video at VBR data rates typically around 100 Mbit/s.[7]&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Network_Device_Interface&quot;&gt;https://en.wikipedia.org/wiki/Network_Device_Interface&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;やりかた&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Windowsの場合は&lt;a href=&quot;https://note.com/sumasa/n/n17c02f598229&quot;&gt;こちら&lt;/a&gt;が参考になると思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;インストール&lt;/h3&gt;
&lt;p&gt;iPhone側&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;iPhoneのカメラをPCのカメラ入力として使う場合&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NDI®|HX Camera&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/us/app/ndi-hx-camera/id1477266080?ls=1&quot;&gt;https://apps.apple.com/us/app/ndi-hx-camera/id1477266080?ls=1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;iPhoneの画面をPCのカメラ入力として使う場合&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;NDI HX Capture 4+&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/us/app/ndi-hx-capture/id1501247823&quot;&gt;https://apps.apple.com/us/app/ndi-hx-capture/id1501247823&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ただし、2020/5/10 時点ではうまくビデオ入力として動かないです。映像のモニタリングはできるのでmacos側のドライバの問題な感じがします。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;PC側&lt;/p&gt;
&lt;p&gt;NDI® Tools for Macをダウンロードします。ダウンロードの際にメアドが求められます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://ndi.tv/tools/#download-tools&quot;&gt;https://ndi.tv/tools/#download-tools&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ファイルを展開して、Driverをインストールします。再起動が求められるので再起動します。&lt;/p&gt;
&lt;p&gt;そうすると、NDI Videoとうカメラ入力と、NDI Audioという仮想の入力デバイスが追加されます。&lt;/p&gt;
&lt;p&gt;手軽に試すためには&lt;a href=&quot;https://whereby.com/hogehoge&quot;&gt;Whereby&lt;/a&gt;とかを立ち上げて、ビデオの入力を選択してみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/05/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;スマホを立てるための三脚はこちらがおすすめです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;三脚&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B00GUNBNOS&quot;}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;スマホホルダー&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B0169SORDW&quot;}
https://www.facebook.com/ittriathlon/posts/1561806380644613&lt;/p&gt;
&lt;p&gt;OBSでpicture in pictureをしてみるとこんな感じで写ります。カメラの撮影位置の自由度が上がって良いですね。&lt;/p&gt;
&lt;p&gt;https://youtu.be/8YTBbmtJE3c&lt;/p&gt;
</content:encoded></item><item><title>Vonage (TokBox)のドキュメントに載っていないこと</title><link>https://blog.teraren.com/posts/vonage-tokbox/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vonage-tokbox/</guid><description>Vonage (TokBox)のドキュメントに載っていないこと</description><pubDate>Wed, 06 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;2020/5/6&lt;/h2&gt;
&lt;h3&gt;Session inspectorとArchive inspectorはそのセッションの20日後に見られなくなる。Advanced Insights ($500/month)を契約しても同じ制限。&lt;/h3&gt;
&lt;p&gt;Q: It seems I can see the data on the session inspector and archive inspector within a month after the events are happening. Is that correct? When does the information expire on the inspectors?&lt;/p&gt;
&lt;p&gt;Ans: Data on session inspector can be found only till 20 days from day session has been conducted i.e. it expire after 20 days.&lt;/p&gt;
&lt;p&gt;Q: If we use Advanced Insights ($500/month), the data never expires?&lt;/p&gt;
&lt;p&gt;Ans- No, on session inspector it still show data for that particular session, till 20 days from the day session is conducted.&lt;/p&gt;
&lt;h3&gt;Web上の時間表記はすべて現地時間に統一されている&lt;/h3&gt;
&lt;p&gt;Ans: Yes, Tokbox uses local time in all it&apos;s tools.&lt;/p&gt;
</content:encoded></item><item><title>Sentryでreleaseと紐付けたエラートラッキング</title><link>https://blog.teraren.com/posts/sentry-release-circleci/</link><guid isPermaLink="true">https://blog.teraren.com/posts/sentry-release-circleci/</guid><description>CircleCIのWorkflowでデプロイ完了後にSentryへリリース情報を自動通知し、エラーとデプロイバージョンを紐付けて追跡できるよう設定する方法</description><pubDate>Sat, 18 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2019年末ごろに、Sentry上のエラーとリリースを関連付けられる機能が付いていました。&lt;/li&gt;
&lt;li&gt;これにより、エラーとリリースの関連付けができるようになります。&lt;/li&gt;
&lt;li&gt;基本的に&lt;a href=&quot;https://blog.sentry.io/2020/01/21/automating-sentry-releases-with-circleci/&quot;&gt;このページ&lt;/a&gt;の内容を踏襲してCircleCIにてdeployが終わった後にSentryに通知するように設定してみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;コード&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;.circleci/config.ymlの抜粋です。&lt;/li&gt;
&lt;li&gt;CircleCIのWorkflowを使っている場合はサンプルコードをそのまま使えないので、色々変更しています。&lt;/li&gt;
&lt;li&gt;SENTRY_AUTH_TOKENをCircleCIの環境変数に設定しておく必要があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;version: 2.1
commands:
# &amp;lt;snip&amp;gt;
  sentry_setup_create_release:
    steps:
      - run: |
          curl -sL https://sentry.io/get-cli/ | bash
          export SENTRY_RELEASE=$(sentry-cli releases propose-version)
          sentry-cli releases new -p $SENTRY_PROJECT $SENTRY_RELEASE
          sentry-cli releases set-commits --auto $SENTRY_RELEASE
          sentry-cli releases finalize $SENTRY_RELEASE

jobs:
  create-sentry-production-release:
    docker:
      - image: circleci/node:latest
        environment:
          SENTRY_ORG: &amp;lt;YOUR_ORGANIZATION&amp;gt;
          SENTRY_PROJECT: &amp;lt;YOUR_PROJECT_NAME&amp;gt;
          SENTRY_AUTH_TOKEN: ${SENTRY_AUTH_TOKEN}
    steps:
      - checkout
      - sentry_setup_create_release

  create-sentry-development-release:
    docker:
      - image: circleci/node:latest
        environment:
          SENTRY_ORG: &amp;lt;YOUR_ORGANIZATION&amp;gt;
          SENTRY_PROJECT: &amp;lt;YOUR_PROJECT_NAME&amp;gt;
          SENTRY_AUTH_TOKEN: ${SENTRY_AUTH_TOKEN}
    steps:
      - checkout
      - sentry_setup_create_release

workflows:
  version: 2
  build-deploy:
    jobs:
    # &amp;lt;snip&amp;gt;
      - create-sentry-production-release:
          requires:
            - deploy-production
          filters:
            branches:
              only: master
    # &amp;lt;snip&amp;gt;
      - create-sentry-development-release:
          requires:
            - deploy-development
          filters:
            branches:
              only: develop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CircleCI上でbuildが成功すれば以下のような表示になります。実行時間は16秒。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/04/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Sentry上での表示は以下のような感じになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/04/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;エラーが無いからわかりませんがリリース後に出たエラーはここに表示されるようです。便利！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/04/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;関連ページ&lt;/h3&gt;
&lt;p&gt;CircleCIのorbがあって使えそうなのですが、なんか使えなかったので今回は自前でstepを書いています。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://circleci.com/orbs/registry/orb/adhawk/sentry-release&quot;&gt;https://circleci.com/orbs/registry/orb/adhawk/sentry-release&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://circleci.com/orbs/registry/orb/mcquaig/sentry-release&quot;&gt;https://circleci.com/orbs/registry/orb/mcquaig/sentry-release&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Next step&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;このあたりをやって、JavascriptのSDKからもバージョンを送る必要があるっぽい？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.sentry.io/product/releases/&quot;&gt;https://docs.sentry.io/product/releases/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>CloudWatchからSNS経由でSlackへ通知</title><link>https://blog.teraren.com/posts/cloudwatch-to-slack/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cloudwatch-to-slack/</guid><description>CloudWatchからSNS経由でSlackへ通知</description><pubDate>Fri, 17 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;CloudWatchのアラームをSlackへ通知します。&lt;/li&gt;
&lt;li&gt;CloudWatch =&amp;gt; SNS =&amp;gt; Lambda (with KMS) =&amp;gt; Slack webhook という流れ。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/04/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Blueprint通りに設定すればほぼ動きますが、一部ちょっと変更が必要だったのでメモっておきます。&lt;/p&gt;
&lt;p&gt;Blueprintはこちら。&lt;code&gt;cloudwatch-alarm-to-slack-python&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/04/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;AWS lambdaのコード&lt;/h2&gt;
&lt;p&gt;変更後&lt;/p&gt;
&lt;p&gt;Blueprintからの差分&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/matsubo/43cd5d1604bf49a71127402d2c93ba9e/revisions#diff-a545a08261d6fdc75c70060cdd64f452&quot;&gt;https://gist.github.com/matsubo/43cd5d1604bf49a71127402d2c93ba9e/revisions#diff-a545a08261d6fdc75c70060cdd64f452&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;テストのために、CloudWatchのイベントテンプレがあるのですが、そちらとの整合性も取れていません。CloudWatchのイベントを少し変更します。変更後のファイルはこちら。&lt;/p&gt;
</content:encoded></item><item><title>AMIのredashでPythonをデータソースとして追加する</title><link>https://blog.teraren.com/posts/redash-python-datasouce/</link><guid isPermaLink="true">https://blog.teraren.com/posts/redash-python-datasouce/</guid><description>AMIのredashでPythonをデータソースとして追加する</description><pubDate>Thu, 19 Mar 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://corporate.minedia.com/&quot;&gt;弊社&lt;/a&gt;のスーパーインターンのご所望により。&lt;/p&gt;
&lt;p&gt;設定方法は以下。（&lt;a href=&quot;https://qiita.com/axm-aoki/items/4982cf8999aebc46b3d4&quot;&gt;このあたり&lt;/a&gt;を参考にしました）&lt;/p&gt;
&lt;p&gt;コピペで行けるはずなのですが、一応1行1行実行するのが安全です。redashのバージョンは最新のv8.0.0です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo -s
cd /opt/redash
echo &apos;REDASH_ADDITIONAL_QUERY_RUNNERS=redash.query_runner.python&apos; &amp;gt;&amp;gt; env
docker-compose restart
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記の設定後、Data Sourceとして追加します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/03/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pythonのバージョンは&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% docker exec -it redash_server_1 bash
redash@b7b972738c0f:/app$ python --version
Python 2.7.16
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>4万枚400GBの写真を自動で安全にバックアップ。AWS Glacierで6ドル/年</title><link>https://blog.teraren.com/posts/photo-backup/</link><guid isPermaLink="true">https://blog.teraren.com/posts/photo-backup/</guid><description>NASに保存した4万枚400GBの写真をrcloneとAWS Glacierを使い年間6ドルで自動バックアップする仕組みを、ワークフローと設定手順を交えて解説します。</description><pubDate>Tue, 17 Mar 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;写真のバックアップを&lt;strong&gt;安価で安全に保存したいと&lt;/strong&gt;10年ぐらい前からぼんやりと考えていました。&lt;/li&gt;
&lt;li&gt;この記事では、&lt;strong&gt;やっと満足の行くバックアップ方法&lt;/strong&gt;を実現したので共有します。&lt;/li&gt;
&lt;li&gt;ファイルサーバをLinuxにしたことで柔軟なワークフローを構築できました。&lt;/li&gt;
&lt;li&gt;プロ写真家の場合は、この記事に書いてあるバックアップの期間の単位を1段階粒度を細かくして設定するとより頻度を高められて安全になると思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;私の写真ファイル保存ワークフロー&lt;/h2&gt;
&lt;p&gt;私の写真の使い方をまとめておきます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;月に1回ぐらい、デジタル一眼レフカメラでRaw画像で撮影。データはカメラに挿入しているXDカードに保存。&lt;/li&gt;
&lt;li&gt;XDカードからLightroom経由でローカルPCに転送し、レタッチ、現像。
&lt;ul&gt;
&lt;li&gt;良さそうな写真は現像してGoogle Photo, Facebook, iCloudなどにアップロードして共有。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lightroomからファイルサーバのディレクトリをsmbまたはsshfsでマウントして、Rawファイルをファイルサーバに移動&lt;/li&gt;
&lt;li&gt;過去の写真が見たくなったら、ファイルサーバをマウントしてLightroomから参照する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;このワークフローで問題になるのは、ファイルサーバ自体がリスクヘッジされていないのでサーバ自体の&lt;strong&gt;物理セキュリティ&lt;/strong&gt;（火事や地震など）が確保されていないことです。このファイルを地理的に遠い場所に安全に保管しておきたいです。&lt;/p&gt;
&lt;h3&gt;現状のファイルの傾向分析&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~/d/lightroom&amp;gt; find . |wc -l
41176
matsu@dell ~/d/lightroom&amp;gt; du -hs
413G    .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;4万1,176枚、413GB&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;ストレージ料金比較&lt;/h3&gt;
&lt;p&gt;オンラインストレージにてファイルを400GBを保存する場合で試算してみます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Google One
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;¥13,000 / year&lt;/strong&gt;かかります&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AWS S3
&lt;ul&gt;
&lt;li&gt;S3にstandardで保存すると$10/monthほどです。&lt;strong&gt;年に$120&lt;/strong&gt;, 10年で$1200ドル。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AWS S3 Glacier Deep Archive
&lt;ul&gt;
&lt;li&gt;400GBだと$0.5/monthぐらい、&lt;strong&gt;年に$6&lt;/strong&gt;、月に$0.5、10年で$60。&lt;/li&gt;
&lt;li&gt;保管と復元がAPIやCLI経由。&lt;/li&gt;
&lt;li&gt;復元に時間を要する。（だから安い）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/photos&quot;&gt;Prime Photo&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Raw画像の保管が容量制限&lt;strong&gt;無料&lt;/strong&gt;で利用できるので良いです。CLIからもファイルを転送できるのでいい感じなのですが、いかんせん復元の際に&lt;strong&gt;ディレクトリ構造を維持できなかったり&lt;/strong&gt;して復元したときが面倒そう。&lt;/li&gt;
&lt;li&gt;API、CLIでアクセスできなさそうなので、1つ別のストレージアグリゲーションサービスを経由しての利用になるので面倒。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;選定先のストレージは**2nd tierのバックアップストレージなので、Availabilityを犠牲にしても安さと利便性が重要です。**なので、GlacierのDeep Archiveが良さそうです。&lt;/p&gt;
&lt;p&gt;注意しないといけないのは、Glacierへの&lt;strong&gt;PutやGetのオペレーションごとに課金&lt;/strong&gt;される点です。また、バックアップの際はS3のインターフェイスと同じで簡単に行なえますが、取り出すときにはファイルごとにアーカイブの取り出しをいわなければ行けないので、やや面倒なコマンドを打っていかなければ行けないです。例えば40,000ファイルを復元したければ、40,000回オペレーションが必要になります。$0.05 per 1,000 requestsなので$2かかります。なので、ある程度の&lt;strong&gt;塊にして置いたほうが取り出すときに楽そう&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;S3のリージョンは、地理的リスクをヘッジするために海外を選びます。今回は、N. Virginiaにしました。&lt;/p&gt;
&lt;p&gt;Lightroomのファイルを管理するディレクトリは年、月、日の階層でファイルを保存してくれているので固めやすいです。&lt;/p&gt;
&lt;h3&gt;上記を踏まえての構成図&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/03/Photo-backup-deployment.png&quot; alt=&quot;my photo workflow plan&quot; /&gt;&lt;/p&gt;
&lt;p&gt;my photo workflow plan&lt;/p&gt;
&lt;h3&gt;運用案&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;1年分の写真を固めて、1ファイルにしてGlacier Deep Archiveに入れる。&lt;/li&gt;
&lt;li&gt;しかし、当年分はアーカイブとして固められないので、当年は、月に1回s3にRaw画像のファイルを同期（sync）する。&lt;/li&gt;
&lt;li&gt;年が明けたら、去年分の全ファイルを固めてGlacier Deep Archiveに入れる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実装&lt;/h2&gt;
&lt;p&gt;まず、過去分の写真を1年ごとに固めて、Glacierに入れます。S3のPUTは無料なので容量に気にせずに気軽にPUTできます。&lt;/p&gt;
&lt;p&gt;rawファイルを含んでいるので、ただのtarではなく、圧縮をかける必要があります。本来なら解凍する事は無いはずなので圧縮率を最高にしても良いですが、保管コストは安いのでbzip2をデフォルトで使います。&lt;/p&gt;
&lt;p&gt;普通にbzip2を使うとシングルコアしか使われず、CPUがボトルネックになります。そこで、&lt;a href=&quot;https://launchpad.net/pbzip2/&quot;&gt;pbzip2&lt;/a&gt;を使ってマルチコアで圧縮します。bzip2で圧縮しても10%弱しか容量は減らないので、tarで固めるだけで良かった気がします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/03/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;pbzip2で圧縮中&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

set -eu

cd &amp;lt;data directory&amp;gt;

for YEAR in `seq 2003 2018`; do
  tar -I pbzip2 -vcf $YEAR.tar.bz2 $YEAR
  aws s3 mv  --storage-class DEEP_ARCHIVE $YEAR.tar.bz2  s3://&amp;lt;bucket name&amp;gt;/lightroom/
done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/03/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;転送中&lt;/p&gt;
&lt;h3&gt;毎月実行&lt;/h3&gt;
&lt;p&gt;crontab例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 5 1 * *  bash /path/to/backup_monthly.sh &amp;gt;&amp;gt; /var/tmp/backup.log
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

set +eu

cd &amp;lt;data directory&amp;gt;

YEAR=`date +%Y`
echo aws s3 sync ${YEAR}/  s3://&amp;lt;bucket name&amp;gt;/lightroom/${YEAR}/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;毎年実行&lt;/h3&gt;
&lt;p&gt;年が明けて、早めの段階で去年の写真をまるごと固めてGlacierに入れます。そして、去年のs3 syncで毎月とっていたバックアップファイルを消します。&lt;/p&gt;
&lt;p&gt;crontab 例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;0 6 1 2 *  bash /path/to/backup_yearly.sh &amp;gt;&amp;gt; /var/tmp/backup.log
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

set +eu

cd &amp;lt;data directory&amp;gt;

LAST_YEAR=`date --date=last\ year +%Y`

# archive last year
tar -I pbzip2 -vcf $LAST_YEAR.tar.bz2 $LAST_YEAR
aws s3 mv  --storage-class DEEP_ARCHIVE $LAST_YEAR.tar.bz2  s3://&amp;lt;bucket name&amp;gt;/lightroom/

# delete last year
aws s3 rm s3://&amp;lt;bucket name&amp;gt;/lightroom/${LAST_YEAR} --recursive
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;気になるお値段&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;バックアップ
&lt;ul&gt;
&lt;li&gt;S3への転送は無料。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;運用
&lt;ul&gt;
&lt;li&gt;$6/400GB/年&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;取り出し
&lt;ul&gt;
&lt;li&gt;取り出し料が標準(数時間)で$4ドル/400GB&lt;/li&gt;
&lt;li&gt;転送量が$8/400GB。&lt;/li&gt;
&lt;li&gt;（のはず。課金体系が結構変わるのでもしかしたら間違っているかも。）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;大事なファイルは固めてGlacier DeepArchiveにぶち込むのが安くて良いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1年運用してみた実績&lt;/h2&gt;
&lt;p&gt;2021年1月の利用料です。64 cents/monthとなり、年間は840円ほどになります。大体予想通りです。&lt;/p&gt;
&lt;p&gt;データ容量は450GBに増えました。1年で50GBぐらい増えた計算です。&lt;/p&gt;
&lt;p&gt;S3 Glacierには長期保存用の写真、S3のstandardには、Glacierへ保存する前のデータです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>このサイトをTLS1.3に対応しました</title><link>https://blog.teraren.com/posts/tls-13/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tls-13/</guid><description>nginxのssl_protocolsにTLSv1.3を追加してHSTSも設定、QualysのSSL Labsでスコアを確認するまでの手順を解説</description><pubDate>Thu, 12 Mar 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;いつからか、&lt;a href=&quot;http://blog.teraren.com&quot;&gt;blog.teraren.com&lt;/a&gt;のTLS設定において、TLS1.3に対応していなかったので対応しました。&lt;/li&gt;
&lt;li&gt;TLS1.3は、1.2から大きくハンドシェイクシーケンスが変わっていたり、ちょっと古めの暗号化アルゴリズムが排除されていたりします。リビジョンが1つ上がっただけですが、裏の仕組みは大きな違いがあります。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://products.nvc.co.jp/array/blog/tls1-3-corporate-strategy&quot;&gt;https://products.nvc.co.jp/array/blog/tls1-3-corporate-strategy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;変更&lt;/h2&gt;
&lt;p&gt;以下、nginxでの変更箇所です。&lt;/p&gt;
&lt;p&gt;（ついでに、&lt;a href=&quot;https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Strict-Transport-Security&quot;&gt;HSTS&lt;/a&gt;にも対応しました。）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/nginx/global/ssl.conf b/nginx/global/ssl.conf
index 9cd7f49..d74c2ed 100644
--- a/nginx/global/ssl.conf
+++ b/nginx/global/ssl.conf
@@ -2,7 +2,7 @@
 # (デフォルト) ssl_ciphers  HIGH:!aNULL:!MD5;
 ssl_prefer_server_ciphers on;

-ssl_protocols TLSv1.2;
+ssl_protocols TLSv1.2 TLSv1.3;
 ssl_ciphers HIGH:!aNULL:!MD5;

 # 2. Logjam攻撃対策
@@ -12,3 +12,6 @@ ssl_stapling on;
 ssl_stapling_verify on;
 resolver 8.8.4.4 8.8.8.8 valid=300s;
 resolver_timeout 10s;
+
+add_header Strict-Transport-Security &apos;max-age=31536000; includeSubDomains; preload&apos;;
+
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://www.ssllabs.com/ssltest/analyze.html?d=matsu.teraren.com&quot;&gt;Qualys&lt;/a&gt;でチェック。A+になりました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/03/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/03/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ちなみに、AWSはTLS1.3に未だ対応していないみたいです。&lt;/p&gt;
&lt;h2&gt;2020/6/14 定期チェック&lt;/h2&gt;
&lt;p&gt;まだA+なので大丈夫そうです。完了するまでに5分かかりました。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;追記：2021/2/1&lt;/h2&gt;
&lt;p&gt;グレードがAに落ちてしまっていたので原因をチェック。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;まず、HSTSが短すぎるアラートが出たので変更。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-add_header Strict-Transport-Security &apos;max-age=86400; preload&apos;;
+add_header Strict-Transport-Security &apos;max-age=15552000; preload&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A+に戻った。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;また、対応する暗号アルゴリズムを変更しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- ssl_ciphers HIGH:!aNULL:!MD5;
+ssl_ciphers &apos;HIGH !aNULL !eNULL !kECDH !DSS !MD5 !EXP !PSK !SRP !CAMELLIA !SEED !RSA !AES128 !ARIA128 !SHA1 !SHA256 !SHA384&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;暗号のパラメータに関しては&lt;a href=&quot;https://qiita.com/ooxif/items/431c5d6db68cc46db60d&quot;&gt;こちらの記事&lt;/a&gt;を参考にしました。&lt;/p&gt;
&lt;p&gt;その結果&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/02/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;追記 2023/6/22&lt;/h2&gt;
&lt;p&gt;TLS terminationをCloudflareで行うようにしたのでサーバの方でTLSの設定をする必要がなくなりました。HSTSの設定もCloudflareで行っています。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/web-service-on-cloudflare/&lt;/p&gt;
&lt;p&gt;その結果、A+を簡単に出すことができました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/06/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Ruby on RailsでER図をモデルから生成</title><link>https://blog.teraren.com/posts/rails-app-erd/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-app-erd/</guid><description>Ruby on RailsでER図をモデルから生成</description><pubDate>Fri, 06 Mar 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Railsの最新のER図をリバースエンジニアリングでスキーマから生成しましょう。&lt;a href=&quot;https://github.com/voormedia/rails-erd&quot;&gt;rails-erd&lt;/a&gt;を使います。&lt;/p&gt;
&lt;p&gt;docker container内でコピペでできるようにコマンドを列挙しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt update
apt-get install graphviz -y
gem i rails-erd
erd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/03/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;たくさん出すぎて困る場合は、モデルを指定してフィルタできます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;erd --only=&quot;Foo,Bar,FooBar&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/03/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>コスパよくPCのHi-Res環境を整える</title><link>https://blog.teraren.com/posts/macos-audio-speaker/</link><guid isPermaLink="true">https://blog.teraren.com/posts/macos-audio-speaker/</guid><description>USB-DACとGENELEC 8020スピーカーを組み合わせてPCデスクトップにHi-Res対応ニアフィールド環境を構築するまでの1年間の試行錯誤と最終的なおすすめ構成</description><pubDate>Sun, 09 Feb 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在宅ワークがはじまり、自宅で作業するときは、&lt;a href=&quot;https://www.amazon.co.jp/SoundLink-Bluetooth-II-%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%96%E3%83%AB%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%AC%E3%82%B9%E3%82%B9%E3%83%94%E3%83%BC%E3%82%AB%E3%83%BC-%E3%82%B9%E3%83%9A%E3%82%B7%E3%83%A3%E3%83%AB%E3%82%A8%E3%83%87%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3/dp/B07YXSFBJB?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=soundlink+mini&amp;amp;qid=1620697580&amp;amp;s=electronics&amp;amp;sr=1-4&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=d87ae67385b3a8f2dd48d9cd363d8b50&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;SoundLink Mini&lt;/a&gt;で音楽を聞いていました。しかし、長時間音楽を流しているとなぜか耳が疲れてくるのでリスニング環境を見直しました。SoundLink Miniは音楽鑑賞用じゃないのでモノラルというのも音の立体感がゼロなので悲しいです。どうせなら、&lt;strong&gt;Hi-Res対応&lt;/strong&gt;しておきたいという気持ちが芽生えたのがことの発端です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image.png&quot; alt=&quot;BOSE SoundLink Mini&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1年間に渡り、4回ぐらいスピーカーを買い直しながら試行錯誤した過程を書いてあります。&lt;/li&gt;
&lt;li&gt;**結論：PCデスクトップのリスニング環境（ニアフィールド）には、GENELECの8020シリーズが超おすすめ！**下の方の「まとめ」の部分におすすめ機材を一覧で記載してあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;フェーズ1：PC音響を整備するために必要そうな機材を揃えてみる&lt;/h2&gt;
&lt;p&gt;基本的にmacos上でYouTubeやApple Musicの音源を再生するのでそもそもの音源の質が良くないのでそこそこ良い音が出れば良いという前提です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;USBDAC&lt;/li&gt;
&lt;li&gt;スピーカー&lt;/li&gt;
&lt;li&gt;インシュレーター&lt;/li&gt;
&lt;li&gt;スピーカースタンド&lt;/li&gt;
&lt;li&gt;スピーカーを接続するケーブル&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;USBDAC&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.amazon.co.jp/gp/product/B07B46KQVP?ie=UTF8&amp;amp;psc=1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=330681ddd86c9fa6699ef186d09cd0da&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;TOPPING D10 MINI USB DAC CSS XMOS XU208 ES9018K2M OPA2134オーディオアンプ・デコーダ(黒色)&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1万円未満でPCM384kHz / 32bitとDSD256に対応するのが良い。&lt;/li&gt;
&lt;li&gt;Web上で評判が良いです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;USBケーブル&lt;/strong&gt;の品質も影響するとか書いてあって、よくわからんです。デジタルデータの訂正符号無しのデータが流れているのであれば重要になるか。。。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://hitbit2009.blog68.fc2.com/blog-entry-762.html&quot;&gt;http://hitbit2009.blog68.fc2.com/blog-entry-762.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/IMG_2624.jpeg&quot; alt=&quot;TOPPING D10&quot; /&gt;&lt;/p&gt;
&lt;p&gt;TOPPING D10&lt;/p&gt;
&lt;p&gt;1点、MIDIの設定画面(Audio MIDI Setupアプリ)で転送ビットレートの設定をしておかないと本領を発揮できません。デフォルトは48kHzになってしまっています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/04/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/Pasted_Image_2020_02_09_3_35.png&quot; alt=&quot;TOPPING D10 MIDI setting&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;スピーカー配置も変えられるようですが、ステレオでは何も変えられない感じです。左右のスピーカーテストを一応行う程度のもの&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ついでに、Mac本体のアナログ出力の&lt;strong&gt;サンプリングレートも変更&lt;/strong&gt;しておきます。デフォルトでは低いです。これを設定しないと音の解像度が低いです。&lt;/p&gt;
&lt;h3&gt;スピーカー&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/YAMAHA-%E3%83%A4%E3%83%9E%E3%83%8F-%E3%83%91%E3%83%AF%E3%83%BC%E3%83%89%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC%E3%82%B9%E3%83%94%E3%83%BC%E3%82%AB%E3%83%BC-MSP3-%E3%83%9A%E3%82%A2/dp/B003J7WU22?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=msp3&amp;amp;qid=1620697623&amp;amp;s=electronics&amp;amp;sr=1-1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=6314fc2503b8870893c01294b56d41a0&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;YAMAHA MSP3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ヤフオクなどで2本セットで1万5千円ぐらいです。&lt;/li&gt;
&lt;li&gt;MSP5を視聴した時に感動したのですが、部屋が狭いので1サイズ小さい物を選びました。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;YAMAHAの定番中の定番であるモニタースピーカーで有名ですね。&lt;br /&gt;
サイズは小さいながらもながら20Wの出力で自宅などのDTM環境では十分なパワーが出せる能力を持っています。&lt;br /&gt;
コストパフォーマンスが非常に高いモニタースピーカーで多くの人が利用していることから最初に選ぶモニタースピーカーとしては十分すぎるでしょう。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://otokake.com/matome/Nftiug?page=4&quot;&gt;https://otokake.com/matome/Nftiug?page=4&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-2.png&quot; alt=&quot;YAMAHA MSP3&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;インシュレーター&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/gp/product/B00008B5UY?ie=UTF8&amp;amp;psc=1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=b7045cec69a77aea4e00c4f9b3b69b57&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;audio-technica ハイブリツドインシユレーター AT6098&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;効果があるのかはよくわかりませんが、デスクへの振動を抑制するために買ってみます。&lt;/li&gt;
&lt;li&gt;＝＞変化はわかりませんでした。軽量スピーカーに対しては硬すぎるのかもしれません。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;スピーカースタンド&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;耳の高さにスピーカーを持ってくるためにちょっと高いけど買います。&lt;/li&gt;
&lt;li&gt;スタンドにスピーカーを乗せると、机への振動がなくなるので音にこもりがなくなります。デスクへの振動もなくなるという副次的効果もあってよかったです。インシューレーターでは変化はわかりませんでしたが、これでははっきりと分かりました。素材がMDF（成形板）なので柔らかくてショックを吸収しやすいのかと思います。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/gp/product/B01N7RQV4L?ie=UTF8&amp;amp;psc=1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=069dc3f565af38026abe61a958043a3c&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;ハヤミ工産【TIMEZ】NXシリーズ 小型スピーカースタンド [2台1組] NX-B300S&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;スピーカーケーブル&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;適当なRCAケーブル。評価が高いです。上を見るときりがないので適当なやつ。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/gp/product/B01D5H8P0G?ie=UTF8&amp;amp;psc=1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=f9dc13c63858722ef52cb0ea9dc538a5&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;Amazonベーシック RCAオーディオケーブル 1.2m (2RCAオス - 2RCAオス)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;フェーズ1まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;音響関係って、実際に聞いてみないとよくわからないから難しいです。そして、調べれば調べるほど奥が深いです。&lt;/li&gt;
&lt;li&gt;スピーカーまでHi-Res対応のリスニング環境はできました。&lt;/li&gt;
&lt;li&gt;ノイズは無し。全音域できれいに出ています。音量を大きくしても音割れやこもりは無いです。打ち込み系の音楽をメインに聞いていたら、&lt;strong&gt;低音が物足りない&lt;/strong&gt;感じです。オーケストラ系の音はとても綺麗に聞こえます。&lt;/li&gt;
&lt;li&gt;定位もしっかりしていて、明確に特定の場所から音が発せられていることを感じられます。&lt;/li&gt;
&lt;li&gt;やっぱりもっと低音がほしいから大きめのMSP5でもよかったかも。しばらく耳をMSP3になれさせてから考える。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.pastimedesignworks.com/2014/03/yamaha-hs7-msp5-msp3-adam-audio-a5x.html&quot;&gt;https://www.pastimedesignworks.com/2014/03/yamaha-hs7-msp5-msp3-adam-audio-a5x.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;余談&lt;/h2&gt;
&lt;p&gt;じゃあ、MSP3とMSP5でどのくらい特性が違うのかというのがわかる周波数特性。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;YAMAHA MSP5 Frequency Response&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;YAMAHA MSP3 Frequency Response&lt;/p&gt;
&lt;p&gt;30から40Hzあたりが抜けてしまっているのと、角度が同じなので全体的に重低音が低く出てしまう感じ。でも、このためにスピーカーの値段を2倍にする必要も無いかなと思います。&lt;/p&gt;
&lt;p&gt;ということで、この周波数特性見た上で、低音の弱さを補うためにiTunesのエコライザーは以下のように調整しました。まぁ、他の再生ソフトを使ったときには意味がなくなりますが。。。OSレベルでエコライザーがあれば嬉しいのですがお手軽なソフトは無さそうです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;フェーズ2&lt;/h2&gt;
&lt;p&gt;やはり、MSP3だと低音が物足りなく感じてしまったので&lt;a href=&quot;https://www.amazon.co.jp/%E3%83%A4%E3%83%9E%E3%83%8F-Yamaha-YAMAHA-MSP5-Studio/dp/B003J7WU36?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=YAMAHA+MSP5&amp;amp;qid=1620806034&amp;amp;sr=8-1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=4a18648ebc70374132afcdc46e53e341&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;YAMAHA MSP5&lt;/a&gt;を買いました。やっぱりこのぐらい大きくないと低音は出ないですね。&lt;/p&gt;
&lt;p&gt;MSP3だとサブウーファーが必要な感じでしたが、MSP5だと単体で十分な低音が出ます。結構あちこちのサイトではMSP3がお勧めされていますが、私はMSP3はお勧めしません。&lt;strong&gt;買うなら断然MSP5が良いです。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;音質に拘ったため、デスク上のスペースをかなり占拠してます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/05/image-7.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;フェーズ3&lt;/h2&gt;
&lt;p&gt;2020年3月24日　追記&lt;/p&gt;
&lt;p&gt;YAMAHA MSP5 Studioを10ヶ月使ってみたので感想を書いておきます。とりあえず、MSP5 Studioは最高です。低音から高音まできれいに出ます。&lt;/p&gt;
&lt;p&gt;裏にスイッチが有り、簡易的なエコライザも付いていて良いです。&lt;/p&gt;
&lt;p&gt;しかし、リスニング環境によっては本領を発揮できないスピーカーなので要注意です。私はデスクトップスピーカーとして使っていますが、&lt;strong&gt;スピーカーと耳の距離が1.5m以上離れていないと重低音が聞こえてきません。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;音の周波数の関係だとは思いますが、スピーカーから1.5m以上離れないと重低音がきれいに聞こえてきません。なのでPCスピーカーとして使うには耳との距離がある程度取れないと厳しいです。&lt;/p&gt;
&lt;p&gt;というのも、デスクの置き場所を変えて部屋のレイアウト変更を行いました。左右に壁が合ったときにはこのような問題は起きませんでした。おそらく反響して1.5mぐらい取れていたのだと思います。&lt;/p&gt;
&lt;p&gt;こちらに詳しい方のコメントがありました。まさにこの通りだと思います。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;いや、MSP3とMSP5は、音の傾向は近いですけど、実際鳴らせば、誰が聞いても（特に耳の良い人でなくたって）わかるくらいに、MSP5の方が音質感は良いですよ。 確かに、音質感が違う大きな点は、口径とパワーが大きいMSP5の方が、中低域以下の再現性がよいからで、高音域はあんまりかわらんと言われるとそのとおり…という面はありますが、とにかくトータルの音質感はMSP5の方が実力的にずっと上です。&lt;/p&gt;
&lt;p&gt;だから、質問者の知人の方がMSP5を推すということは、非常によくわかります。 ただ、問題は…質問者もお気づきの通りで &amp;gt;部屋は結構狭いです。防音対策もされていません。スピーカーを置く場合自分との距離は１ｍもないです。 となってくると、MSP3の方が妥当です。&lt;/p&gt;
&lt;p&gt;上記の、MSP5の「強み」を活かそうと思ったら、ある程度は音量を上げないと、かえってちょっとショボ目の音になってしまいます。 そうなると、普通はリスニング位置から最低1m後半～2m程度の距離は欲しいところ。 1m未満で、MSP5の性能が活きる音量にすると、かなりやかましいです。 防音室なら、あえてその音量も有りですが（難聴になるほどの大音量ではないので）、私もそうですけど一般家屋ではツライ物がある。&lt;/p&gt;
&lt;p&gt;私の自宅作業場も、１m弱しか確保できないので… その距離では、MSP5が十分に活きないので、MSP3の方がセッティングがずっと楽で確実です。 MSP3は、重低音域は十分に出ませんので、そこだけは妥協です。 MSP3～5～7は、環境の広さによって使い分けるモデル設定だと思ったらよろしいです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11108516796&quot;&gt;https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11108516796&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;MSP3だと低音が不十分。MSP5だと距離が取れない。。。。なので&lt;strong&gt;MSP3＋サブウーファー&lt;/strong&gt;を使うか、他のラインナップを選ぶことになるかなと思います。&lt;/p&gt;
&lt;p&gt;そこで、サブウーファーを追加するか、サブウーファー付きのシステムをテストしてみることにします。サブウーファーを追加する場合は、しっかりした音を出すためには大きめのものになるので場所を結構取ることになってしまうのでMSP5+サブウーファーは場所的に辛い感じになります。&lt;/p&gt;
&lt;p&gt;なので、デスクトップは小さめのスピーカーでサブウーファーモジュールを床置きにするパターンが理想です。それに合致したメジャーなシステムは以下の2つぐらいになります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/Bose-Companion-II-system-PC%E3%82%B9%E3%83%94%E3%83%BC%E3%82%AB%E3%83%BC/dp/B000QY478Q?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=BOSE+COMPANION+3+SERIES+2&amp;amp;qid=1620806718&amp;amp;sr=8-3&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=9f82ea1a73d7eb1efabf46136f47be92&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;BOSE COMPANION 3 SERIES 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/Companion-multimedia-speaker-system-PC%E3%82%B9%E3%83%94%E3%83%BC%E3%82%AB%E3%83%BC/dp/B000KJTPK2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=BOSE+COMPANION+5&amp;amp;qid=1620806761&amp;amp;sr=8-1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=5555c9bf269dd3c424775b1eee82c252&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;Bose Companion 5 multimedia speaker system&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;どちらも最新のラインアップは無く、中古を買うことになりました。&lt;/p&gt;
&lt;p&gt;BOSE COMPANION 3 SERIES 2の方は、デスクトップのスピーカーが小さいせいで、高音しかなりません。なお、あたりまえですがウーファーは低音しか鳴りません。とりあえず、聞いていてかなり不快でした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/05/image-5.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Bose Companion 5のほうは、companion 3より改良されてデスクトップのスピーカーが大きくなったので中音も出るようになりました。しかしながら、低音と中高音のクロスオーバーがいまいちなせいで、中低音が不自然な感じだったのでいまいちでした。慣れれば問題ないのかもしれませんが。あと、なぜだか低音に遅延があるのでそれが気になります。サブウーファーのコーンのレスポンスが悪いのかと思います。&lt;/p&gt;
&lt;p&gt;MSP5を使ってしまうと見劣りしてしまいます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/05/image-4.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ということで、boseの2つのシステムを試してみましたけど、MSP5のほうが断然良いです。&lt;/p&gt;
&lt;p&gt;どこかの音響マニアのサイトで見つけましたが、&lt;strong&gt;ニアフィールドでは2wayスピーカーが最適&lt;/strong&gt;と書かれていましたが、それは正しいなと感じました。&lt;/p&gt;
&lt;h2&gt;フェーズ4&lt;/h2&gt;
&lt;p&gt;2020年4月15日　追記&lt;/p&gt;
&lt;p&gt;やはり、Yamaha MSP5をしばらく使ってみましたが、ニアフィールドで重低音が聞こえないのが難点なので別の似たようなスピーカーでは特性が違うのか、それとも環境が悪いのかを検証するために似たような2wayスピーカーを試してみます。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B087CPPHBB&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/05/image.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;USのAmazonでカテゴリ1位&lt;/strong&gt;を取っているらしいです。値段もとても安いです。&lt;strong&gt;低音、高音のエコライザが付いて&lt;/strong&gt;いるので設置環境に応じて音を調整しやすいというのもあります。&lt;/p&gt;
&lt;p&gt;USのデスクトップを晒している人の写真を見ているとちょこちょこ見かけます。&lt;/p&gt;
&lt;p&gt;こんな感じで設置して使っていました。MSP5と比べて遜色ない音色です。コスパがかなり良いです。しかしながらコーンのサイズはMSP5と同等なので特性は似ています。これもMSP5と同様にスピーカーから50cm居ないでは重低音が聞こえづらいです。機材というより、この大きさのコーンと設置場所による環境要因のようですね。。。&lt;/p&gt;
&lt;p&gt;かと言ってコーンの大きさを小さくすると、YAMAHA MSP3のように低音が出なくなるので悩ましいです。。。。MSP3+サブウーファーといった組み合わせの選択肢がないのかなぁ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/05/image-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ちゃんと比較するためにも、同じ環境で聞いたりもしました。特定周波数にレスポンスの違いはありましたが両方とも近い音でした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/05/image-3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ということで、ちょっと次にどうするのが良いかというのがよくわからなくなりました。&lt;/p&gt;
&lt;p&gt;諦めて、世の中でランキングが高いBose Companion 2 Series III multimedia speaker systemを買ってしまうというのも選択肢に浮上してきました。とりあえず、これなら店舗で視聴できるので視聴してみたくなりました。&lt;/p&gt;
&lt;p&gt;ついでに、自分の中でオーディオ関連に詳しい店員が居ると認知している有楽町のビックカメラへ行きました。まず、Bose Companion 2 Series IIIを視聴させてもらいましたが、やはり小さいので音圧が低くて重低音の伸びもいまいちでした。&lt;/p&gt;
&lt;p&gt;そこで、店員さんに今までの経緯や要求定義を共有した結果、GENELECをおすすめされました。&lt;/p&gt;
&lt;p&gt;https://x.com/matsubokkuri/status/1376110155348111362&lt;/p&gt;
&lt;p&gt;ネックはお値段。。。ちょっと高いので失敗したら悲しすぎます。&lt;/p&gt;
&lt;h2&gt;フェーズ5&lt;/h2&gt;
&lt;p&gt;2020年5月11日　追記&lt;/p&gt;
&lt;p&gt;やはりニアフィールドの低音をどうにかしたくなり、&lt;a href=&quot;https://x.com/matsubokkuri/status/1376110155348111362&quot;&gt;bic camera&lt;/a&gt;の店員がおすすめしてくれた&lt;a href=&quot;https://www.amazon.co.jp/GENELEC-%E3%83%A2%E3%83%8B%E3%82%BF%E3%83%BC%E3%82%B9%E3%83%94%E3%83%BC%E3%82%AB%E3%83%BC-8020DPM-%E3%80%90%E3%83%9A%E3%82%A2%E3%80%91/dp/B06XTBPZNZ?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=genelec+8020&amp;amp;qid=1620698081&amp;amp;s=electronics&amp;amp;sr=1-1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=1be8ad3b51d5fc160bc20c9de9d34d6c&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;GENELEC 8020シリーズ&lt;/a&gt;を買いました。&lt;/p&gt;
&lt;p&gt;見た目は丸っこくてダサいのですが、&lt;strong&gt;この形にも意味があってディストーションを削減&lt;/strong&gt;するみたいです。レビューを見ていると低音の出方に関しては問題無さそうなので買ってみました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/05/image-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;結果としては、GENELEC 8020は素晴らしいです。この大きさで重低音がしっかり出ますし、スピーカーの近くでも重低音がしっかり聞こえます。&lt;strong&gt;バスレフポートが裏にあるのが影響&lt;/strong&gt;しているのかもしれません。バスレフポートを塞いでも低音は出るので、トータルとしてスピーカーの設計が優れているっぽいです。&lt;/p&gt;
&lt;p&gt;**この形状のおかげか、スピーカーの近くで聞いても、横の方で聞いても、離れて聞いても聞こえ方が同じです！**これは今までのスピーカーにはなかった特性です。すごい！おすすめ！2本セットが中古で6万〜8万円ぐらいです。&lt;/p&gt;
&lt;p&gt;ちなみに、筐体が金属でできているので結構重いです。&lt;/p&gt;
&lt;p&gt;手っ取り早くテストで使う音源はこちら。重低音から高音まで一通り入っている感じなので。&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/embed/ycBBygx299Q?start=29&lt;/p&gt;
&lt;h2&gt;フェーズ6&lt;/h2&gt;
&lt;p&gt;Topping D10はオペアンプのチップを簡単に交換できるようになっていて、もとから乗っているチップはさほど良くないらしいので、高いチップに交換するのがオーディオ会の主流のようです。&lt;/p&gt;
&lt;p&gt;日本で買うと_2500円_ほどでハイグレードなチップを買えます。ちなみに、Ali Expressでは数百円で買えます。Amazon評価を読んでいると組み付け方によって違いが出るらしいのですが、単純な回路なのでそんなことはないかなぁという印象です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OPA627AU
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/%E9%AB%98%E7%B2%BE%E5%BA%A6%E9%AB%98%E9%80%9F%E3%83%87%E3%83%A5%E3%82%A2%E3%83%AB%E3%81%AB%E3%82%AA%E3%83%9A%E3%82%A2%E3%83%B3%E3%83%97%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB-OPA627AU-%E4%BA%A4%E6%8F%9B-NE5532-%E3%83%88%E3%83%83%E3%83%97/dp/B07X1NLSNF?pd_rd_w=GK82K&amp;amp;pf_rd_p=e0138d67-9e5b-487b-a2c3-be9ff3010069&amp;amp;pf_rd_r=JTB8C1F8TQNNT7DEYPM3&amp;amp;pd_rd_r=00517837-76d4-4572-ba98-b48e4202209b&amp;amp;pd_rd_wg=RKWVO&amp;amp;pd_rd_i=B07X1NLSNF&amp;amp;psc=1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=edc3e257626c4b6e43bd5a7d47c8d87b&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;高精度高速デュアルにオペアンプモジュール OPA627AU 交換 NE5532 トップ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;入れ替えた結果としては、&lt;strong&gt;全く変化が感じられませんでした&lt;/strong&gt;。。。&lt;/p&gt;
&lt;h2&gt;フェーズ7&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/TOPPING-D10-XMOS%EF%BC%88XU208%EF%BC%89-ES9018K2M-OPA2134%E3%82%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%82%AA%E3%83%BB%E3%83%87%E3%82%B3%E3%83%BC%E3%83%80/dp/B079HRGN5B?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=9ecc6f5492d9156b9d0655d895abe265&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;TOPPING D10 USB DAC XMOS（XU208）&lt;/a&gt;はそこそこ良いUSB-DACで気に入ってはいるのですが、せっかくスピーカーが良いのでもう少し良いUSB-DACがあればもっと良い音で聞けるのではないかと思ってTopping E30を買ってみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B0868J7NRV&quot;}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;買ってから気づいたのですが、E30はAmazon上では評価が高かったのですが、一部のハイアマチュアが&lt;a href=&quot;https://audiof.zouri.jp/pcaudio/e30.html&quot;&gt;イマイチという評価&lt;/a&gt;を書いていました。。。。私自身が視聴した感じでは、D10と比べほぼ同じ印象でした。まぁ、音源がさほど良いわけではないというのもありますが。&lt;/li&gt;
&lt;li&gt;それより、PCがスタンバイになってからE30は自動で復帰してくれないので毎回リモコンか本体のボタンで電源を入れる必要があって煩わしかったです。なので、説明と違っていたので返品しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Topping D10に戻したいなぁと気持ちになっていましたがすでにメルカリで売ってしまったので不可能です。再度書い直すのもアホらしいので再度USB-DACについてリサーチしました。&lt;/p&gt;
&lt;p&gt;値段帯を1万円台までで絞ると、MKII AK4493が良さそうでした。AK4493チップを採用しています。最初は、&lt;a href=&quot;https://amzn.to/3zfeIZH&quot;&gt;ZEN-DAC&lt;/a&gt;を買おうとしていましたが、それと同じチップが乗っていて、5000円ほど安いです。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B085TF124M&quot;}&lt;/p&gt;
&lt;p&gt;そして、買ってみた結果は正解でした。全体的な音の明瞭度が上がって聞こえなかった音が聞こえるようになりました。重低音も全体的に強調されたっぽいです。音の定位もより安定しました。低レイテンシーのチップを使っているせいかなと思います。&lt;/p&gt;
&lt;p&gt;本当はTEACなどの5万円くらいのものがほしいのですが、デスクに設置する必要があるので小さいものである必要があります。そうなると、これは意外と小さくて高さは6cm程度しかありませんでした。&lt;/p&gt;
&lt;h2&gt;フェーズ8&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;S.M.S.L Sanskrit 10th MKII AK4493&lt;/strong&gt;の動作が不安定になってきました。雑音が入ったり、急激にアンプの最大音量で雑音が鳴り出したりしてめちゃくちゃビックリさせられることが20回ぐらいありました。&lt;/p&gt;
&lt;p&gt;耐えられません。。。&lt;/p&gt;
&lt;p&gt;もう、USB-DACはすぐ壊れてしまうので評価が高くて安定しているものを買おうと思います。今までは対応するビットレートが高いものを選定していましたが、どうせ音源のビットレートが低いので優先度を下げます。&lt;/p&gt;
&lt;p&gt;こちらの商品はスペックは低めの192kHz/24bit対応です。簡易エコライザもついているので便利です。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07VDQQY95&quot;}&lt;/p&gt;
&lt;h2&gt;まとめ：現在のパソコン周りの音響環境&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2021/05/IMG_8600.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;スピーカーはGENELECが最高に良かった。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://amzn.to/2TihlJR&quot;&gt;GENELEC 8020&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;スピーカーは大きければ大きいほど良いというものではない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;導入したスピーカーの主観的な総合ランキング&lt;/h2&gt;
&lt;p&gt;5段階評価&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;GENELEC 8020: ★★★★★&lt;/li&gt;
&lt;li&gt;Edifier R1280DBs: ★★★★&lt;/li&gt;
&lt;li&gt;YAMAHA MSP 5: ★★★★&lt;/li&gt;
&lt;li&gt;Bose Companion 5 multimedia speaker system: ★★★&lt;/li&gt;
&lt;li&gt;YAMAHA MSP 3: ★★★&lt;/li&gt;
&lt;li&gt;BOSE COMPANION 3 SERIES 2: ★★&lt;/li&gt;
&lt;li&gt;BOSE SoundLink mini: ★★&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>村井純教授の1月16日最終講義全文書き起こし</title><link>https://blog.teraren.com/posts/mj-last-class-text/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mj-last-class-text/</guid><description>「日本のインターネットの父」慶応大・村井純教授の定年退官最終講義を人力で全文書き起こし。インターネットと国境・自由・SFCの未来への提言を収録。</description><pubDate>Sat, 25 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;{/* textlint-disable */}&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;「日本のインターネットの父」と呼ばれる&lt;a href=&quot;http://www.asahi.com/topics/word/%E6%85%B6%E5%BF%9C%E5%A4%A7%E5%AD%A6.html&quot;&gt;慶応大&lt;/a&gt;環境情報学部教授の村井純さん（64）が定年を迎え、16日、最終講義があった。村井さんは「インターネットに国境はない。国や政府が分断したり規制しようとしたりする試みは続くだろうが、若い人たちで守ってほしい」と呼びかけた。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://newspicks.com/news/4547652/&quot;&gt;朝日新聞デジタル&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://gc.sfc.keio.ac.jp/cgi/video_gc/view_video_gc.cgi?yc=2019_25312&amp;amp;lecture_id=14&amp;amp;slide_id=1&quot;&gt;村井先生の最終講義&lt;/a&gt;。16年ぶりに村井先生の講義を聞いて懐かしくなりました。せっかく良いことをたくさんおっしゃっていたので人力で書き起こしをしました。（&lt;a href=&quot;https://www.amazon.co.jp/hz/wishlist/ls/1Y9PUK3OZYI5M/ref=nav_wishlist_lists_1?_encoding=UTF8&amp;amp;type=wishlist&quot;&gt;Amazonウィッシュリスト&lt;/a&gt;）&lt;/p&gt;
&lt;h2&gt;講義全文&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;共同授業担当 佐藤特任准教授(以下教員)：&lt;/strong&gt; そろそろ始めましょうか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; はい。それでは皆さん、こんにちは。インターネットの、2019年秋学期の最終回ということで集まっていただきましてありがとうございました。学生は、履修者があふれるはずだけど来てない。ハハハ。その代わり、なんか変な普段見慣れない人も来ているということで、どうもありがとうございました。OBやそういう人たちも来てくれているようで、皆さんへのメッセージも一応用意してありますけれども。&lt;/p&gt;
&lt;p&gt;ただ、今日はずっとアナウンスするようにみんな期待して来ている人もいるんだけど、でかいクラスなのでなかなか学生とインタラクションができないから、質問をまとめてもらってそれを最後にまとめて答えるというのが最終回の使命なので。それを1時間くらいやって、そのあとでSFCとインターネットっていうまとめを少し最後に話すことにしますんで、よろしくお願いします。&lt;/p&gt;
&lt;p&gt;まずは皆さんに書いてもらった質問を聞きますんで。なんか変な質問がないことを祈るが。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; はい。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 個人的な質問はすんなよ。俺の生活を聞くな、みたいな。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; そうですね、個人的な質問は結構有りますね(笑)&lt;/p&gt;
&lt;p&gt;それで、講義に関するお願いはいつもと同じです。ハッシュタグ「&lt;a href=&quot;https://x.com/search?q=%EF%BC%83inet19F&amp;amp;src=typed_query&quot;&gt;#inet19F&lt;/a&gt;」で、内容に関しての感想とか、あるいはこれ聞きたいとかいうことがあれば。もし拾うことができればそれも考えていこうと思いますので、ご活用いただければと思います。&lt;/p&gt;
&lt;p&gt;まず前半は村井先生への質問ということで、最終課題ですね。これがまた550ぐらい(質問が)来てしまって、全部読むのもめちゃくちゃ大変だったんですけども、非常にたくさんのいろんな意見がきましたので、TA/SAにも手伝ってもらって、似たようなものというのはなるべくまとめる形で整理しました。なので、個人というよりは皆さんの総意のものも結構多いかなと思います。それで、時間の許す限り…。&lt;/p&gt;
&lt;p&gt;村井さん、&lt;strong&gt;Twitterの中ではMJ&lt;/strong&gt;と呼ばれてますね。「MJ、ファンサは楽しいですか？」みたいな質問もあって…。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; え？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; (ファンサとは)ファンサービスですね。村井先生が学生の所に行ってマイクを傾けるやつを、今の学生はファンサービスって言うんですよ。新しいですね。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; まず、JMじゃなくてMJなのね、もちろんね。それもあるし、昨日のTwitterはびっくりしたよな。なんかキャンパスで、「&lt;strong&gt;野生の村井純を見た&lt;/strong&gt;」って。ちょっと待って、ポケモンか俺は、みたいな(笑)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 恐らくハイパーボールじゃないと捕まえられないと思いますけど、はい(笑)&lt;/p&gt;
&lt;p&gt;いろんな質問が学生から寄せられていますのでいろいろあるんですが、まずはこの授業はインターネットということなので、インターネットについての質問から入りたいと思います。&lt;/p&gt;
&lt;p&gt;1個目は、インターネットが今当たり前の世界になりましたが、これからはどんな世界になると思いますか、という質問です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; いきなり難しくない？　最初にしては(笑)&lt;/p&gt;
&lt;p&gt;まず、&lt;strong&gt;当たり前の世界になったってすごいこと&lt;/strong&gt;だと思うんだよね。それで、この授業では今回歴史の話をしたけど、90年からこのキャンパスをやって、このキャンパスは当たり前であったけど、世の中は当たり前じゃ無かった。それで、井庭ちゃんが今スライド持ってて俺も持ってるんだけど、95年にSFCのキャンパスの統計を取って、学生のインタビューを取って、それでアンケートを取ってそれを井下先生っていう先生がまとめた調査結果があって。その中に、電子メールやインターネットで恋をした人とか、泣いた人とかそういうのが書いてあって、それがすごく多いんだよね。95年でインターネット誰も知らないので、世の中、その統計の論文に彼(井下先生)書いてたんだよね。それで、その論文の結果を俺がスライドにして、世界中で講演するわけ。そうすると日本は特に「気持ち悪い」とか言うわけ。メール見て泣いたとか笑った、とか言って。そうするとそれをすごく反応するんで。だけど、SFCじゃ当たり前で、SFC以外じゃ当たり前じゃないっていうときがあったと。それで、そうこうしているうちにインターネットは当たり前になって。&lt;/p&gt;
&lt;p&gt;いろんなことを言う人がいるんだけど、みんなはどう思うかわからないんだけど、ここまで当たり前になると「知らない」って言うんだよね。これがインターネットだって分かってなくて、「LINEは使うけどインターネットは知らない」とか、「私はPayPay使ってますけどインターネットは使ったことがありません」とか、そういう人が出てきちゃうんじゃないの？　っていう声があって。&lt;/p&gt;
&lt;p&gt;それで、これからどういう世界になるかなんて分かんないだけど、(これからはどんな世界に)なると思うか？　っていうそういう誰か任せみたいな考え方は持ってないんだよ。どういう世界にしたいかっていうことなら、かなりチャレンジングなことがあるなとは思うけど。最後にも言うけど、インターネットは人類が初めて地球上で、人間が同じようにデジタルデータを共有してコミュニケーションができる、こういう環境を創った。それが当たり前になった、つまり有るのが当たり前である。その上で、いろいろなことがわれわれの社会には起こるけれども、良いこと悪いこと、それからナショナリズム、戦争、サイバーセキュリティのイシュー、いろいろ起こるんだけど、じゃあこれからそれがすごく悪くなるのか良くなるのかっていうことを考えたときに、それだけ答えておくとね、ほとんどのSF映画の未来像みたいなの見るじゃん。そうすると大抵すさんでるね。大体、テクノロジーが発展しすぎてロボットにやられてターミネーター、みたいな。なんかそういう話がすごく多いんだよね。それで、なんであんな悲観的になるかなとは思うんだけど、でもそれは持っていきようだと思うので。&lt;/p&gt;
&lt;p&gt;やっぱりここまでこういう世界をつくってきて、いろんなときに俺は、&lt;strong&gt;「世の中悪くなったのはインターネットを創ったおまえのせいだ」っていろんな人に言われてた&lt;/strong&gt;けど、「はいはい」って言いながらもそこからそれをなんとか、そう(世の中が悪く)ならないようにするための技術の開発ももちろんしてきたわけだけど。でもやっぱり人間が何したいっていうことのプラットフォームを創ってるわけだから、そうすると人間は何したいっていうのは、結構良いことをしたいんじゃないかと思うんだよ。またこういうことを言うとナショナリズムって言われるけど、特にこの国はね。だからそういう意味で、インターネットの基盤ってどんどん良くなるんだけど、良くなるといろんなことがやりやすくなるから悪いこともやりやすくなるんだけど、良いことがやりやすくなるといろんな問題を解いたり、人のためになることをしようとか自分のためになることをしようとか、そういうことがどんどん発展するんで、これからはそういう問題を解決するためのコストが小さくて、そうするとやっぱりいろんな問題を解決しながら発展的に前へ進む世界になると僕は思ってます。だから、&lt;strong&gt;超オプティミスティック&lt;/strong&gt;なの。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; なるほど。もう、1個目の質問から非常にファンサービスがうっとりで、このままいくと3時間ぐらいかかっちゃうかもしれないのでいこうと思いますけど(笑)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;次が、インターネット時代の情報の取捨選択の方法についてです。たくさん情報があふれてるときに、どういう情報を選べば良いですかっていうことがあれば、という質問が何個か来ております。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 良いポイントで、もうちょっと待ってください。俺が今からやるのはこの話かもしれないなって思っていて。&lt;/p&gt;
&lt;p&gt;今、「国境なきジャーナリスト」っていうグループがあって、パリやヨーロッパ中心に活動している。そこからのアプローチがあって、いわば「フェイクニュース」だとか「新しいジャーナリズム」とか「広告のビジネスモデル」とか、そういう問題をどうやったら解決できるだろうって。ジャーナリストの人はシリアスだよね、すごく。そもそも新聞のメディアとかテレビとか、そういうもののメディアの広告のビジネス的な力が弱まってるから、メディアとして。代わりにいろんなメディアが出てくるけど、そこにはコンシューマー・ジェネレーションのメディアで動いている。そうすると、本当に質の高いジャーナリズムっていうのはどうやってつくれるんだろう、ということを考えているんだと思うんだよ。それで、そのグループの人から今アプローチがあって、その問題、まあ俺の場合は技術のプラットフォームを創ることだけど、その人たちがトラストをつくりながらグローバルな空間で新しいジャーナリズムの活動ができるような環境はどうすれば良いですかっていう研究課題を持ってきたんだよ。これ、答えは無いよ？&lt;/p&gt;
&lt;p&gt;それでそうなってくると、そこが狙ってるのは取捨選択の方法、例えばIDのトラストっていうのがあるんだけど、授業で何度か言ったけどアノニマスのIDは必ずしも危ないもんじゃないんだよ。TwitterのIDってなんでも付けられるけど、でも世の中が人間とものすごくタイトになるIDを持っているのは、リアル ドナルド・トランプさん。この人は本当に、Twitter見ると本物がちゃんとしゃべってる。このことのパスポートとの裏付けも無いけど、もうあまりに歴史が流れて彼だったことが分かるんだよ。&lt;/p&gt;
&lt;p&gt;というわけで、IDを政府発行のものに結びつければ信用ができるっていう単純な話じゃなくて、そして誰が何を発信しているのかってことが分かってくれば、今度はみんなのレピュテーションやコミュニティーとして、この人は信用できるとかこの人は本物だとか、この人の言うことを聞いてるとこうなるとか、そういうことをわれわれは日常で考えて、今まで何何新聞なら信用できるだろうとか何何新聞はどっちに寄ってるだろうとかそんな話があったのと同じように、個人の情報のエンティティでそういうものを取捨選択ができるような方法が徐々に出来てくるだろうなというふうに思ってるのね。だけど、今無いとは言ってないんだよ。だからリアル ドナルド・トランプは、本人がフェイクニュースって言うからどっちがフェイクニュースだかよく分かんないんだけど、だけどこの人が言っているこういうメッセージだっていうことは分かりながら、今のところ世の中は推移するようになってて、もう既にそこに俺たちの取捨選択の方法はだんだんアダプティブに確立してると。　それでアドバイスは、どうすれば良いのかなって考えてるとそれを実現するのは良いことなので自分一人でもできるんだよ。これ面白いよって言って人に伝えるってことができれば、そういうコミュニティーとしての取捨選択の方法のクオリティーはある方向に上がるから、そういうことはもうみんなやってんだよ。というわけで、まあ大丈夫だよ、うまくいくよ。ハハ。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; では、ちょっともしかしたらかぶってるかもしれませんけど、もう1つあった質問として、議論の場としてのインターネット空間について。&lt;/p&gt;
&lt;p&gt;今やインターネットの上で行われているさまざまなコミュニケーションについて、どういうふうな意見を持っていますか、というような質問ですね。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; まあ、これの方が嫌だね。嫌だねっていうのは、なんか炎上するじゃん、すぐ。だからそれを恐れてみんな言えなくなってると思って。でもすごく勇気のある人がいて、俺個人的によく知ってる人で、炎上覚悟でスパンって言うみたいな人がいるよね。それでもう、炎上しても全然気にしないでいて。まあきちんと答える人もいるし。だからいろんなことができるようになってきたなと思う。それで、完全にオープンな場で議論するとノイズが入るから嫌だっていう人も、例えばSFCの学生とはこういう議論をしたいとか、この教室でこのクラスを履修してるやつとはこういう話をしたいとかいろんなことができるので、インターネット空間は、例えばジオグラフィカルなロケーションに依存しないとか所属に依存しないとか、そういう議論ができる場所というためにはめちゃくちゃ自由になったんじゃないかな。&lt;/p&gt;
&lt;p&gt;タダ、タダだからね、テレビ会議タダだからね。世界中に散っててテレビ会議でずっと話してて誰もお金払わないって。まあタダっていう言い方も、サブスク、ISPには金払ってるぜってのはあるんだけどさ。だけどすごいね、みんな本当知らないと思うけどさ、国際電話ってお金取ってたときがあるんだぜっていう。電話で金取ってた人たちいたんだぜ、みたいな。今の学生知らない？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; みんなもしかしたら通話もタダだと思ってるかもしれません(笑)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;あといくつか寄せられてる質問で、これからのインターネットに限らずっていうところですけれども、人とコンピュータの関わり方、インターフェースっていうのはこれからどういうふうに変わっていくと思いますか、という質問もいくつかありました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; どうやって変わっていくと思いますか。&lt;/p&gt;
&lt;p&gt;(学生に向かってマイクを傾ける)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;学生A：&lt;/strong&gt; うーん、難しいですけれど、どこまでコンピュータが人の生活に入ってくるのか、人間がどこまで受け入れるのかがそうなのかな、と思いますけど、そんなに入ってきてほしくはないです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; (入ってきて)ほしくはないけどね。&lt;/p&gt;
&lt;p&gt;どう思う？　人間とコンピュータのインターフェース、界面、どこから先がコンピュータやインターネットの世界になる？　今ここだよな、この辺のパソコンとかな。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;学生B：&lt;/strong&gt; 一定の距離は。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 一定の距離は保ちたい、あんまり入ってきてほしくないな。一定の距離は保ちたいなと2人の人は言いました。それで、インターフェースって意味がいろいろあるんだけどさ、めちゃくちゃ変わると思うんだよ、俺は。&lt;/p&gt;
&lt;p&gt;例えば車を運転して行きたい場所があるよね。そして、どのレストランに行きなさいって言うよね。それで、レストランの名前を騒ぐという以外の運転の仕方をする人は1人もいないよね、1人も。「自宅に帰る」とか言うと自宅に帰れるよね、どこにいても。今のカーナビはね。カーナビで自宅に帰るっていうと自宅まで案内してくれる。そうすると、もう音声のインターフェースはカーナビではかなり早くから手が塞がってるから、俺もスマホでメッセージとか打つのに、増井さんには悪いけどフリック入力っていうのが苦手でつい間違えるね。でも、増井に「&lt;strong&gt;フリック入力使えねーじゃねーか&lt;/strong&gt;」とか言うとすっげー怒られるから、喧嘩になるから。一応知らない人には言っておくけど、増井さんっていうのがフリック入力っていうのを作ったファカルティでここにいるんだけどさ。とにかくみんな早いんだよね、若い奴はね。&lt;/p&gt;
&lt;p&gt;おまえ、早い？　フリック入力？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; あ、携帯、入力。それは増井さんに言えないね。でもエラーが多いので、俺1人で周り気にしないときはやっぱりしゃべっちゃうんだよね。だんだん音声の認識の質が上がってきているから。今、このキャンパスでは修士の中間発表がポスターになったんだよ。それで、ポスターに行って説明を学生から聞いて、コメントを入れなさいってコメントの欄がうわーってあって、それを打つのか、みたいな。しかもポスターって歩いてるから、スマホしか持ってないんだよ。もうしょうがが無いから全部しゃべって入れてるんだよ。そうするとだんだん流行ってきて、みんな他のファカルティも「あれ？　しゃべって入るんだ」ってクオリティーがいつの間にか上がってて気が付いていない人がいる。そうするとだんだん味を占めて、俺は原稿を書くとかそういうのも、ただただスマホにしゃべってるっていうので書いちゃうっていうのはあって。&lt;/p&gt;
&lt;p&gt;それで、だんだん変わってきてるね。俺自身も変わってきてる。みんなもそうだと思う。それからさっきの「あんまり入られたくないな」っていうのがあって、俺は結構ね、家の絶対嫌だという面がある。家の鏡の裏側に高解像度のカメラを付けて、ずっと鏡に向かう度に…鏡に向かうでしょ、毎日？　向かう？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;学生C：&lt;/strong&gt; (首をかしげる)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 俺も向かわない。俺、向かうのは女だけだと思ってたんだよ、長い間。ハハハ。まあ、俺は鏡見ない。とにかく毎日同じところで見ると、このデータをずっと毎日取っていると、健康状態が分かるんだよ。それで、もちろんトイレからっていうのも健康状態が分かる。スマートハウスってこうしていろんなことが分かるので、健康のことだけ考えるなら取られても良いデータだと思うんだよ。それで、それ以外には使われない。気持ち悪いと思うかもしれないけど、最初は。でも「自分の健康の見方、それ以外では絶対使われないデータだ」、こういうふうになったら絶対に素晴らしいインターフェースになる。&lt;/p&gt;
&lt;p&gt;というわけで、スマートハウスってそういうふうになると思います。なぜなら、人間の健康は人間が生きてくためにもっとも重要な基本のことだから。そういう意味で、このインターフェースっていうのは変化をしていくし、トラスティドなコンピュータとの接点でわれわれの人間のデータが、特に健康のため、あるいは災害のときの命を救うため、こういうために使われるようになると思うので、すげー変化すると思う。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 次の質問を見越して回答しているんじゃないかと思ってあれですけども、補足でいくつかあった質問は、これから先もどんどん新しい技術が出てくるとしたときに、そういう新しい技術、今だとAIとか自動運転とか例がありましたけど、そういうものが出てきたときの向き合い方で何かアドバイスがあれば、っていう質問です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 俺12月に追突されたんだよ、東名(高速道路)でまた。それでその前は、話したと思うけど俺が足をけがしてたときに運転しててもらった運転手が脳梗塞になって、東名で。それで、レーン出そうになるけどウインカー出してないから戻ってきて、みたいな。それで俺は命を救われたんだよ。それが2年前でしょ。それで12月にまた東名の横浜で追突ガツンってされて、後ろの車はぺっちゃんこ廃車。それで俺の車は後ろから追突される直前に、シートベルトをギューって締めてタイヤをロックするっていう追突のためのメカニズムが付いてたの。というわけで、僕はなんかダメージ受けたのかもしれないけど気が付いてないみたいな。ハハハ。次の日から痛くもなく動いてる、みたいな。やっぱり人間の体を守る方向にいくんじゃないですか、自動運転って。他になんかあんのかな。&lt;/p&gt;
&lt;p&gt;あ、俺ね、結構しゃべるのうまいんだよ、カーナビに。「自宅に帰る」とか「ホテルニューオータニ行く」とかいうと、大体俺のミスリードしない喋り方とかできる。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 素晴らしい。僕、「SFCに」って言ったら長万部に連れて行かれそうになったことありますよ、ハハハ。それは上手ですね、さすが。インターフェースが進んでいると。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;あといくつかあるんですが、ちょっとなるべくたくさんのものをと思いますのでアドバイス編ですね。&lt;/p&gt;
&lt;p&gt;大学の授業は役に立つと思いますか。あと、大学のうちに何かこれだけはやっておけってことがあれば教えてください、っていう質問です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 俺に聞く、これ？　ハハハ。&lt;/p&gt;
&lt;p&gt;まず、俺の大学の時代には授業受けてないよ。つまんないもん。大丈夫か、これ？　俺、学部長のときは言えなかったんだよ、これ。もう最後の授業だから全部バラすけど、俺は大学6年間かかって。日吉が4年間か。日吉4年間かかるって何かっていうと、一般教養だからなんだよ。一般教養って経済の基礎とか哲学とかそういうの勉強するんだよ。それで、これずっと勉強してると「なんで俺経済学が必要なんだっけ」「なんで俺哲学が必要なんだっけ」「なんで俺美術だっけ」みたいなのがあって、そう思って受けてるとつまんないんだよ。だから成績悪くて、その他の理由もあるけど留年してたわけ。それでSFC作るときに、「止めよう、それ」って思ったの。&lt;strong&gt;押しつけられて受けるとつまんない&lt;/strong&gt;んだよ。&lt;/p&gt;
&lt;p&gt;ところが、「あ、経済学って何だっけ」って、俺ちょっと知っとかなきゃなっていって受けるとめちゃくちゃ面白いんだよ。当たり前だよね、すごい先生が教えてるんだから。というわけで、&lt;strong&gt;SFCはその順番こだわるの止めよう&lt;/strong&gt;と言って、面白いことをやって必要だと思ったら、その授業や立派な授業があるようにカリキュラム作ればいいじゃん、というふうに作ってあるわけ。だから日吉と一緒にできないんだよ。それで、それはSFCのいわば成功の秘密だとも言えるんだよ。&lt;/p&gt;
&lt;p&gt;だから、1年からいきなり研究活動やって、&lt;strong&gt;必要だと思ったものは一生懸命勉強しようと思うとまず効率が良い&lt;/strong&gt;んだよね。そういう意味で大学の授業は、「役に立たないもんは言ってくれよ、止めさせるから」っていうのは学部長時代は思ってたけど。だから、役に立つものと立たないものがあると思うんだけど、基本的に(役に)立つと思うんだよ。SFCの授業はグループワークが多いので、その授業は役に立つかって言われると結局(役に)立つんだよ。皆さんが作る授業だから。&lt;/p&gt;
&lt;p&gt;次、2行目の質問は全然違う質問だけど、大学生のうちにやっておいた方が良いことは何か。もう俺にこれを聞いたら答えが1個しかないのに分かってて聞くなよ、っていう。もう**絶対にやっておいた方がいいのは好きなことだね。好きなことを思い切りやる。**これ、できないから、大学生以外。っていうか最後だから。もう就職したら好きなこと思い切りできないんだよ？　万一サラリーマンになったら、週5日とか朝から晩まで行くんだよ。言われたことやるんだよ。今なら好きなことできるじゃん。というわけで、絶対に好きなことを夢中になってやるべきだ。&lt;/p&gt;
&lt;p&gt;もう1個、&lt;strong&gt;いい友達を作れ&lt;/strong&gt;。はい、終わり。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 自分が本当に好きなものはどうやって見つければ良いですか、という質問も来ています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 分からないか、これ？　好きなことない人手挙げて、見つからない人手挙げて、もっとたくさん好きなこと見つけたいなと思う人手挙げて。あー、そうだよね。SFCを30年間見てて、本当は見つからないやつがいっぱいいて、それが一番の悩みで、SFCのようなスタイルのキャンパスを運営してると、みんな好きなことがあってきらきらしてんだけど、あたしはどうすればいいんだろうっていう悩みはすごく多いんだよね。だからこの質問はよく分かる。&lt;/p&gt;
&lt;p&gt;それで、俺のわずかな30年の経験で青春の学生と付き合ってて、「あー、見つかった」っていうのは友達を通じてだよね、先生を通じてとかね。例えば、俺が何が好きだかわかるだろ、もう。そうすると、授業を通じて俺から分かるってこともあるよ。それから、全然関係ない友達、研究室とは関係ない友達。例えばサークルだとかどっかでばったり出会ったとか。そういう友達と話してると、全然違うことに夢中になってる人とかと出会うことがある。そうすると「あ、これって面白いかもしれない」っていうことに気が付くので、このSFCのデザインでできるだけ気を付けてたのは、研究室入っちゃうと研究室にズポーンと行って出てこないとか、サークル行ったらサークル以外に出てこないっていうのは、それもそれでいいんだけどさ、好きなことやってるから。&lt;/p&gt;
&lt;p&gt;だけど、なんかそういうんじゃない出会いができるようになんないかなって言って、例えば今体育のクラスとかすごく大事な役割を果たしてると思うんだよ、全然知らない人と一緒のことをやらなきゃいけないっていうのは。それで、履修するっていっても全然関係ない人と一緒に履修をして、それで友達になって、そこを知ると「なんかこいつのやってること良い、面白そうだよね」っていうのが見つかるから、こうやってやっぱり人を通じて見つかるんじゃないかなとは思うけど。&lt;strong&gt;素敵に夢中になってる人から学べるんじゃない？&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; これはさっきもう回答があったので飛ばしますけども、次が、修士もそうなんですが、博士課程の進学、あるいは大学院の進学ってどうですか、とか先生はおすすめされますか、っていう質問も何個か寄せられています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; ちょっとヤスニャンこっち来て。お前は今何年だ？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員(豊田)：&lt;/strong&gt; 僕、今修士2年です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; どうすんの、来年？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員(豊田)：&lt;/strong&gt; 博士課程に行きます。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; ほら。というわけです。&lt;/p&gt;
&lt;p&gt;（会場拍手）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; あくまで個人の感想です、みたいな。ハハハ。違います？　大丈夫ですね。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; いや、あのね、ヤスニャンもそうとう悩んだんだよな、いろいろ。俺もね、いろんなことをやったんだけど、博士行きたくないやつ、まあヤスニャンもそうなんだけどね、俺今修士見るじゃん。修士見ててね、もう結構さぼってぎりぎりまであんま見てないんだけどさ、もう提出しちゃったよとかいう修士見てるんだよ、今。それでそうすると、大学で(修士)見てて、「なんだこいつ。おい、こいつ今いるか？」って言ったら、「いや、なんか発表の準備で机の下で寝てます」って。それで行ったら机の下で寝てて、蹴飛ばして「おい起きろよ、起きろよ。お前さ、これからどうすんの？」って言ったら「いや、何とか会社に就職します」って言うから「&lt;strong&gt;あ、そう。じゃあ俺今電話して断ってやるからさ、博士課程行けよ&lt;/strong&gt;」って言ったことあるんだよね、本当にね。来てるかどうか知らないけど。そういうやついるんだよね。そういうことやると、今だったらパワハラとかアカハラとか言って殺されそうですけど、今日で終わりだからいいや。ハハハ。でもちゃんとすごい立派にドクターになった人ばっかりですから、ヤスニャン心配すんなよ。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 良いコメントですね、良かった。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;あと、村井先生の原動力みたいなものに対してですね。すごい質問ですね、どうしてインターネットを作ろう、もしくはインターネットを研究しようと思ったのですか、という質問です。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; これについて授業でも言ったんだよね。高校大学の最初の頃にコンピュータ大嫌いで。それでその頃のコンピュータはメインフレームで、偉そうに真ん中に鎮座してて、なんか行列してカードとか持っていって、ガーって読ませると2日後に結果が出るみたいな。計算機ってそういうもんだから。弾道計算とか軌道計算とか、そういうすごい難しい物理学の式が解けて嬉しいな、みたいなそういうのが、俺たちが高校大学の最初のころのコンピュータのモデルで、メインフレームはでかい、高い。慶應にもあったけど、高校も大学のコンピュータ借りて行列作って、まあラーメン二郎の行列みたいな。それで、「コンピュータ様、計算してください」みたいな行列がある。偉そうだよね、コンピュータが。俺の頭の中のイメージは、コンピュータが偉くて、その周りに計算してもらいたい人が群がってる、そんな計算機中心みたいな。なんかそういうの大嫌いで。&lt;/p&gt;
&lt;p&gt;俺、ずっとキャンプのカウンセラーをやってたんだよ。野外教育をずっとやってたんだよ。なんとなく人間のことが好きで、人間が中心じゃ無いと気が済まない。だから、コンピュータをやるやつも嫌いだったし、コンピュータの授業も避けて。そのころ、必修じゃなかったから避けて通れたんだよ。それで俺は数学なんだけど、数学はコンピュータ無くたって当時解けた。数学科にはコンピュータの先生がいて、仕方ないからそこの課題があってやると。あ、矢上(キャンパス)で専門になってからね。ついに幸せだった日吉の4年間を越えて、晴れて矢上の数理工学科ってところに専門で入って。そうすると、コンピュータのアセンブラの必修の科目があってそれをやったわけ。そうしたら先生が来て、お前は面白いって肩たたかれて、「一緒に研究の手伝いしない？」って言われたんだよ。中西正和先生ってLISPの先生で、亡くなりましたけど。俺とか冨田勝の先生なんだけど。&lt;/p&gt;
&lt;p&gt;それで、なんと言っても衝撃の事件だったんですよ、大学5年目、初めて大学の先生と話したの。すごいだろ。大学ってところに俺は来たけど、大学の先生が話し掛けてきて、しかもお前は面白いって言ってくれた。この衝撃に俺は5年かかったね。だからみんな4年で卒業したいなんて思わない方がいいよ、本当に。そしてそれはなんで面白いかっていうと、やりたいことをやるような課題の根拠、今はゲーム作るんだけど、それがなんか面白い。そうするとだんだんその頃から、例えばワープロとか出てきて、ワープロってコンピュータで出来てるけど人間の道具だよね。人間がいて、それを支えるための道具化してきてるコンピュータがちらほら見えてきてる。&lt;/p&gt;
&lt;p&gt;元の俺のコンピュータのイメージは、コンピュータが真ん中にあって人間が群がってるみたいなイメージだったのに、人間が真ん中にあって道具が散らばってて、それが人間を支えるみたいなそんなイメージがついに持てるようになってきたので、その絵を描いたの、学部のときにいきなり。始めはコンピュータが真ん中、周りに人間がいる。もう1枚の絵は、&lt;strong&gt;人間が真ん中、周りにコンピュータがある&lt;/strong&gt;。それで考えたわけ、このコンピュータと人間が話してると、命令してると、なんか面倒くさい。それで、例えば秘書が3人いて、通訳が3人いて、それぞれ秘書なりに全部話しながらお願いしてたら時間が3倍かかっちゃう。だけど、秘書の代表みたいなのがいて、その人が他の秘書と連携してくれていれば、自分を助ける秘書のモデルってそういうので出来るんだろうなって思ったわけ。&lt;/p&gt;
&lt;p&gt;それで、じゃあ人間の周りにあるコンピュータってのが手をつないで、真ん中の人間のことを支えるようになんなきゃいけないよなってそのとき思って、そういうことができないかなと思ったの。それでできなかったね、そのときのコンピュータは。だから俺はインターネットを作ろうと思ったというよりは、コンピュータが人間を支える仕組みを作りたい、そのためにコンピュータはコンピュータ同士で話さなきゃいけない。それがコンピュータネットワークの研究をしたきっかけ。分かった？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 分かりました。僕が分かってもしょうがないか。ハハ。大丈夫ですかね、質問した人、何人かいると思います。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;あと2つあるんですけど、1つはインターネットを作ってきて後悔したことを聞かせてください、というものと、インターネットを作ってきた中で楽しかったことはあったのでしょうかって、全部つらいと思ってるのかなって気もするんですけども。つらかったことと楽しかったことがあればっていう質問も来ています。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 最初何？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 後悔したこと。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; &lt;strong&gt;無いね。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 無い！かっこいいですね。じゃあ、楽しかったことはなんでしょう。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; &lt;strong&gt;全部楽しかったね。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 素晴らしい。ハハハ。&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; あとここから少し、村井さんの個人への質問みたいなものもいくつかあるんですけども。&lt;/p&gt;
&lt;p&gt;最初の質問、結構(たくさん)来ましたね。どうしてSFCで定年まで勤められたのか、あるいはSFCにずっといたのか。海外に行く機会もあったと思うんですけど、行かなかったのはなぜですか、っていうような質問も来ていました。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 鋭い質問だね、この質問。っていうかこの話したことないね、俺。&lt;/p&gt;
&lt;p&gt;やっぱり(海外に)行きたかったし行くべきだと思ってて、実はポジションもオファーしてもらったことあるんだよ。それで、給料も見て目が飛び出て、どうして日本よりこんなに高いんだろうって思って。特に大学のときは、本当に用意して「来て下さい！」みたいなところもあったけれど、それからドクターのときも、東工大、東大と行ってここへ来てからも、でも一度も行っていないんですよ。開発のときに、相当バークレーに入り浸ってたことはあるし、徳田さんがCMU(カーネギー・メロン大学)行ったときに、何日も行ったことがあるけど、勤めたのは東工大と東大と慶應だけなんですね。それで、一応オファーが確かにあったんだよね、負け惜しみで言ってんじゃなくて本当にあったんだけどさ。&lt;/p&gt;
&lt;p&gt;なんで行かなかったかって言うとね、これ言うと修辺りに怒られるんだけどさ、あの後ろの方に座ってる奴らに怒られるんだけどさ。今俺がこの国を離れたら、日本のネットワークが止まるなってやっぱ思ったんだよね。ダウンするな、と。もうちょっと経ってからじゃないと駄目かなとかっていうふうに僕は思ってたわけ、勝手に。きっと俺がいなくなれば、残ってたやつらがうまくやってそんなことは無いんだよな、普通は。だけど、俺はそう思ってたの。だから、海外に行かなかったのはなぜですかっていうのを正直に答えると、&lt;strong&gt;今俺がいなくなると、やっぱ(日本のネットワークは)止まっちゃうんじゃないかな&lt;/strong&gt;って若い頃思ってたんだよね。でもそれはうぬぼれであって、多分そうじゃなかったんだと思う。なんか、俺が留守にすると動かなくなるんじゃないかなっていう心配があったから。&lt;/p&gt;
&lt;p&gt;それで、ひどいんだよなー、俺の定年。慶應義塾の定年ってひどいんだよ。65歳が定年だから、65歳が終わるときにクビにすりゃいいじゃん。でも、65歳になったら4月1日を迎えちゃいけないっていうのがルールなの。俺の誕生日3月29日なんだよ。それでさ、3日？　みたいな。始めにエントリーで得してないから、早生まれって大体いいことあったんだけどこれだけは納得いかないけど。でもまあ65歳で3日勤めますんで。本当に勤めるのかな？でも卒業式行くよ、今年。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 非常に良い話の次に聞くのもなんですが…。ここから一問一答形式ですね。村井さんの一番好きなお金の使い方はなんですか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; これはね、&lt;strong&gt;学生にうまいもん食わせること&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; これが嬉しいんだよ。なぜかって言うとね、大人にうまいもん食わせても喜ばないね。だって自分で食えるじゃん、みたいに思うじゃん。やっぱ楽しみだね、これね。「お前食ったことないだろ、これ」みたいな。ハハハ。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; あとは、村井先生の尊敬する人は誰ですか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 尊敬する人…。いっぱいい過ぎてあれだけど、やっぱ俺が最も持ってない力を持っている音楽家かな。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 音楽家(笑)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 絶対俺にはできない、ずるいって思うね。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; なるほど。&lt;/p&gt;
&lt;p&gt;生まれ変わったら何になりたいですか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 音楽家だね。&lt;/p&gt;
&lt;p&gt;(会場笑い)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; あ、ねえ、定年後何をやるんですかっていう質問は…？　あるんですね。まあ、いいや。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;生まれ変わったら…、バナナかな…。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; バナナ？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; …どうぞ、次行ってください。&lt;/p&gt;
&lt;p&gt;(会場笑い)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; すごい会場がザワザワしてますけど、大丈夫ですか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; なんで今そう言ってみたかっていうとね、長女が生まれて、ユミコっていうんだけど、「ユミちゃん、大人になったら何になりたいの？」って聞いたら、「バナナ」って言ったんだよ。だから一応それを尊重して、彼女はバナナになりたかったらしいんだよね、大きくなったら。だから俺もバナナになってみようかなっていう気に、今。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 次が、温泉掘削計画の進捗をお聞きしたいです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 止まってて申し訳ないんだけど、このプロジェクトは知らない人もいると思うんだけど、SFCに温泉を掘ろうと思っていて。この理由は、掘るの高いんだけど、あるところでSFCのすごいサポーターで、大分の温泉を掘るっていうのに投資してた人がいるんだよ。それで、この人まだSFCのサポーターだから止まってないんだよ。まだ終わった話じゃないんだけど、そしたらそのプロジェクトが頓挫しちゃったわけ。従って投資したお金は戻ってきたんだよね、やらなかったから。そうするとこれ、温泉に使った金だから、温泉を掘る夢のために投資した金なんだよ。この人が「これで温泉を掘るところないかな」って言うから、「SFCに掘ろう」って言ったの。それで、温泉課ってのがあるんだよ、神奈川県に。温泉っていうのは泉脈があって、泉脈の沿線に他の商業温泉があったりすると難しいとかそういういろいろな事情があるんだけど、それを一応調べてもらったら、良いんだよ。掘って良いの。そこまで分かったわけ。そのあと、ちょっと名前が分かっちゃうとまずいんだけど、その人がいろんなところ誘ってくるんだよ。どっか遊びに行きましょうとか、アフリカ遊びに行きましょうとか、お金持ちだから。そういうのについて行くと、じゃあ次の瞬間温泉掘るっていう感じになるかなと思ったけど、なかなか時間が取れないからオファーを振るわけ。ずっと振り続けてるから、だんだん良い感じ持ってないかもしれないねって、俺に。ハハ。それで一生懸命彼と遊んでると、きっと良くなる。今度リタイアして授業無くなると、少しアフリカとかそういうところに遊びに行けるから、そうすると温泉は戻ってくるかもしれない。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 一問一答でって言ったのに、こんなに&lt;strong&gt;温泉の話をインターネットの授業で聞くとは思いませんでしたけど&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;あと、明日死ぬとしたら今日何をしますか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 何だよそれー(笑)&lt;strong&gt;うまいもん食うよ&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; うまいもの、はい。&lt;/p&gt;
&lt;p&gt;あとこれは結構僕は衝撃でしたね。村井さんはこれまでに何か音楽をされていたのでしょうかという質問が来る！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; いやもう俺は自分では聴くのだけで。小学校のとき縦笛とかやったかな…。嘘だ、今の。僕、大学のときは、2年を4回やったうちに「東京大学ブルース研究会」っていうバンドやってて。東大って五月祭(ごがつさい)っていうのと、女子校は五月祭(さつきさい)っていうんだけど、東大の五月祭は駒場でやるの。それから本郷でやるのを駒場祭と五月祭っていうのかな。それで、本郷と駒場で春と秋に文化祭があるんだよ。これ全部出たから、4年間、2年のとき。つまり8回出て、ブルースばっかりやってて。そのとき隣の教室でやってて、「エレキの音はうるさい」とか言われたのは中島みゆきさん、昔の話です。それで、僕たちのMCやってくれた人は、夏目雅子さんという、女学館の2年生の。そのあと大女優になりましたね。一緒にずっと舞台の上でMCやってくれて。それで、そういうことはやってましたけど…やってたよ。だから俺は…まあいいや。言いたいことあるんだけど、あとで出てくるんだよな。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 分かりました。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;あといくつかですね、例えばSFCについての質問というところで、先に読み上げちゃいますね。社会にとってこのSFCという大学、あるいは学部は成功だったと思いますか、とか、村井先生がいなくなった後のSFCがどうなるのかの予想を教えて下さい、とか、SFCはどんな大学になっていってほしいですか、あるいはSFCの学生に期待することは何ですか、みたいな、SFCがこれからどういう風な、もしくは村井さんがSFCのことどう思ってるのかっていう質問もかなり多かった…。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; ちょっと待って。何でそんなすらすら言っちゃうわけ、これ。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; え、どれですか？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; いや、この質問。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; SFCの学生に期待すること…。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 違う違う、その前も。なんで飛ばしちゃったわけ？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 最後にまとめて返事をしますっていう…。それとも一問一答で行きますか？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; あっ、そう言ったっけ…。プレゼンにそんなこと書いてないよ。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; じゃあ、1個ずついきますか。ただ、お時間もありますので(笑)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 時間ってまだあるんじゃないの？　2時半までじゃないの？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 最後、村井先生のスライドも結構ありますよ？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; あー。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; でも時間の許す限りいきましょうか。&lt;/p&gt;
&lt;p&gt;社会にとって、SFCという大学は成功だったと思いますか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 思うよ、&lt;strong&gt;大成功だよ&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; あ、次で良いんだ。ハハハ。&lt;/p&gt;
&lt;p&gt;(会場爆笑)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 温泉よりも今の話に尺を取るべきだったんじゃないかと思いますが、まあまあ。ハハハ。&lt;/p&gt;
&lt;p&gt;村井先生がいなくなった後のSFCはどうなると思いますか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; もう&lt;strong&gt;どんどん良くなるよ&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;(会場爆笑)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; SFCはどんな大学になっていってほしいですか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; もう&lt;strong&gt;最高の大学になってほしいよ&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;(会場爆笑)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; SFCの学生に期待することは何ですか。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; 3つぐらいあるんだよ。&lt;/p&gt;
&lt;p&gt;**好きなことをやれ。自分を好きになれ。自信を持て。友達と仲良くしろ。**終わり。&lt;/p&gt;
&lt;p&gt;(会場笑い)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; さすがですね。落ちがちゃんと付いてる。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;最後の質問です。結構哲学的な質問もいくつかあって、なかなかこの授業をやっていてこの質問来るのもすごいなと思ったんですけど。「インターネットって何ですか」、これは僕、逆に深いなと思ったんですけど。これは最後スライドで？　それとも今一言お返事しますか？&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; あとで言う。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; あともう1つ。「この講義で一番伝えてきた、伝えたかったことは何ですか」っていうような質問も来ていますので。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; はい、それでは。今回はこのインターネットの授業は歴史みたいな話をしていたので、その延長なんだけど、これも30年やってきた最後の授業だから、オーバーラップするのは初めて来てる人は勘弁してもらって…。&lt;/p&gt;
&lt;p&gt;SFCとインターネットの話をしてみますね。俺は長い間、環境情報学部長をやってたんだよね。それで俺の完璧な考え方は、環境情報学部と総合政策学部の区別は無い。これがずっと俺が思ってたことなんだよ。区別があるって言うことを言うやつもいるんだけどさ、今の土屋総合政策学部長みたいに。いるんだよ、いつでも。言いたいやつは環境情報でもいたんだよ。名前言えないけど冨田勝っていうのが、「もう環境情報は違うんだよ」みたいな、そういうことをあいつが学部長だったときは言っていて。そして元はね、相磯先生。faculty of environmental informationっていう名前を、1990年になる前に俺たち集まって、環境情報はこういう英語にしようって。それで、相磯さんの言ってた環境情報は「人間が情報との関係を持つ、その全てが環境なんだよ」っていう。それを環境って言うんだよって。だから環境情報っていうのは、例えばエコロジーとかそういう環境学じゃないんだよね、本当のenvironmentじゃなくて。最初、相磯さんの考えてたのはその意味だったの。それでenvironmentって言っちゃうと環境学になっちゃうから、environmental informationって言って、informationが主でenvironmentが修飾語だっていうふうにして、英語でやろうって言ったわけ。そしたら、そうこうしているうちに、清水先生みたいな本当の環境からの先生が来ちゃって、だんだんエリーカとか電気自動車とか言って、「結構環境やるじゃん」っていう先生が増えてきて。まあ今で言うと蟹江みたいな。それで、「やっぱ環境って言っとくか」みたいな話になって。冨田が学部長だったときだと思うんだよな、environment and information。2つあるからstudiesって付けようって言って英語名だけ書いたの、それで環境情報学部ってなって。だから割合、ファカルティの中では環境の先生が今、すごく強くなってるの。だけど俺は知ったこっちゃなくて。&lt;/p&gt;
&lt;p&gt;SFCっていうのは、俺はいつも言ってたんだけど、「混浴風呂」。入ったことある？　混浴、混浴温泉、はやったよね。一応、入り口は男、女って書いてあるんだよ。それで、着替えるときは男、女。だけど中に入ると同じ風呂なんだよ。それがSFCなんだよ。だからどっちで入ってもいいんだよ。どういうことかっていうと、俺はずっと学部長のときこう言ってたの。「環境情報学部は人と地球だけ考えろ」って。人間がいて地球がある、これだけ考えていけばいい。これは、俺がインターネットを作ってるときも同じで、地球全体に1つの空間しかないのがインターネットだから合ってる。&lt;/p&gt;
&lt;p&gt;だから、俺が書いてる環境情報学部のディスクリプションってみんなまだ残ってるんだよ。なぜ残ってるかっていうと、俺のあとになった環境学部長2人目なんだけど、ああいうのは事務から「これどうしますか、直しますか？」って言われて「いや、面倒くさいから前のままでいいよ」っていうのがあるから、俺の書いたのがだいぶ残ってる。それで俺は全部書き換えてあるので、俺の前のやつが残ってることはない。だから、環境情報学部はこういう言葉がまだ残ってるんだよね。&lt;/p&gt;
&lt;p&gt;じゃあ総合政策学部はなんだっていうと、俺は&lt;strong&gt;総合政策学部じゃないんで残り全部&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;(会場爆笑)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; そうすると、SFC全体では全部のことが考えられる。これが俺のSFC観なんだよね。それでこれは何度も言ってるんだけど、インターネット文明って、俺たちはもうインターネットは道具から始まって文明になった、社会全体がっていうのはこれは何度も使っているんで。だからこの文明は、道具使って恐ろしいことやるんだけど、でも1つしか無いんだよな、インターネットは。&lt;strong&gt;元の文明ってのは世界にたくさんあるんだけど、でもインターネット文明っていうのは1個しかない、インターネットは地球に1個しかない&lt;/strong&gt;から。ここが一番伝えたいことで、俺たちは国と国との間でこの地球を生きてるけど、インターネットは1個しかない。これが一番のバリューだと思う。&lt;strong&gt;人類は、インターネットの前には地球全体を1つの空間だと思って人間が生きる空間を持ってなかった&lt;/strong&gt;。だが、インターネットでそれが出来た。&lt;/p&gt;
&lt;p&gt;でも、それと同時に国際空間も持ってる、戦争も起こる、経済制裁も起こるので、この2つを空間として同時に持ってて、それが当たり前だと思うのがインターネットネイティブ、インターネット文明時代の皆さん。俺たちはそれを作ってきたので。これを前提に1つの空間を作ってきたから、その間にいろんなコンフリクトもあったし、それからもっと重要なことは気が付かなかったね。&lt;strong&gt;みんな、もしインターネットが今日のようになるなら、あらかじめぶっ潰しておけば良かったって思うやつがきっといたと思うんだよ。だけど、そいつらが気が付く前に作っちゃった&lt;/strong&gt;、従って出来たというところがあるので、これからどうなるかっていうと、潰しにかかってくるやつが絶対いるから。それで、これをどうするかをみんなに委ねたいね。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;守れよー&lt;/strong&gt;、地球で人類が初めて1つの空間を作ったんだから、これを1つ1つの国の権利で分断したり、ぶっ壊したり、バラけさせたりさせるなよ。頼むぞ、ここまでやってきたんだから。それで、それが両方で生きてることがとても大事だと。これがインターネットのこの授業で一番伝えたかったことだし、みんなにお願いしたいことでもある。&lt;/p&gt;
&lt;p&gt;SFCは慶應義塾が本当に期待を持って作ったキャンパスなんだけど、福沢諭吉が『西洋事情』の中で、1866年だよ、「4つの海は一家。5つの族は兄弟。人類はみんな兄弟だ、ファミリーだ」、それで、左側にはそこが作ったもの。蒸気、経済、電気、電信、そしてそういった人間の道具たち。これが文明につながってくるっていう福沢先生の考えだったの。でも次の絵を見てください、恐ろしいでしょ。&lt;strong&gt;地球は1つで電信柱でつながってて、飛脚がそこを走ってるんだよ。インターネットだよ&lt;/strong&gt;。それで、1866年にこの人(福沢諭吉)はそのコンセプトを持ってんだよ。鎖国してたばかりで飛び出た明治維新より前、このときにこの感覚を持ってるね。でもついに出来たんだよ。それで、&lt;strong&gt;福沢先生のこの思いはSFCが作った&lt;/strong&gt;んだよ、すごいね。&lt;/p&gt;
&lt;p&gt;このSFCは、石川塾長という塾長のアイデアから出来てる。石川先生ってこういう顔してんだよ、あんまり知らなかったかもしれないけど。戦後最長の4期16年務めた塾長、すごいね。文化勲章だとか、勲章いっぱいもらってるね。慶應の塾長でこんなに勲章もらってる人はかなり少ない。この彼のスピーチ、SFCを作ったスピーチ。&lt;/p&gt;
&lt;p&gt;(会場全体に音源が流れる)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;音源中のナレーション：&lt;/strong&gt; 西暦1983年5月15日、日吉記念館で開かれた慶應義塾創立125年記念式典で、石川塾長は旧来の大学教育の不備を指摘し、新しい大学の在り方を熱く語った。後にこれは、湘南藤沢キャンパスの誕生のきっかけとなる名演説として、人々の間に記憶されることになる。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;音源中の石川塾長 (石川忠雄)：&lt;/strong&gt; 教育の面におきましても、現在のような複雑で流動的で不確定な時代というのは、われわれが過去に経験しなかった新しい現象があとからあとから起こってくる時代であります。従ってその教育の問題も、ただ単に広く物を知るということではなくて、自分の頭で物を考える力、これをどういうふうに作っていくかということが、極めて大切になりつつあります。新しい現象に対して自分の頭で物を分析し、推理し、判断し構成する力、ここに教育の重点が移されてこなければならない。さらに、かつてわれわれが対象としなかった領域の研究というものも、ますます重大になりつつあります。しかも、学問分野との間の交渉領域の研究も極めて重大になってきております。こういうような学問の在り方の変化というものに対応していくために、これまでのような大学の体制だけでは決して十分ではないというふうに考えられるのであります。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; というわけでこれが1983年で、7年間の準備を経てSFCを作ったわけです。かなりのことがここで言い尽くされているんじゃないか？　SFCがどういうことであるべきかとか、今までのことにとらわれないとか。SFCができて30年経つと、その間に同じ名前の学部が全国で出来てる。それで、&lt;strong&gt;SFCのAO入試はみんなコピーされている&lt;/strong&gt;よね。そりゃそうだよ、SFCうまくいったから。だけど、そこでまた新しい問題がどんどん出てきて新しい力が必要になり、そしてそのことにずっとサステイナブルに対応できる仕組みをSFCの中に作らなきゃいけない。いろんな苦労してきたけど、この間5年間、俺たちがいなくなる分のファカルティの補充っていうのを5年分まとめてやろうって言って採ったんだよ。そのときの教員を採るための基準になんて書いてあるか知ってる？　どうやって募集したか知ってる、教員を？　普通の大学は、経済学の教員が1つ足りないから1つ穴を埋めるぞ、とかそういうふうに聞くんだよ。コンピュータサイエンスな教員がいるって。そのとき、SFCはどういう教員を公募したんだろう。&lt;/p&gt;
&lt;p&gt;(壇上から降りて学生席に行き、藤井進也准教授にマイクを傾ける)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;藤井：&lt;/strong&gt; ハハハ、僕ですか。いろいろカテゴリがありましたね。1番から30番、領域があるんですけど、0番っていうのがありましたね。**0番は、「これまでのSFCに無い研究領域」**でした。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; というわけで、俺はこれまでのSFCに無い研究領域、普通そういうの最後に書くんだよね。俺はそこから採ろうと思ってそれを0番っていうのにして、そしたら藤井が来たんだよ。それでこのときに来ている教員は、全部が藤井だったら困るんだけどさ、やっぱり今までにない人がいつでも入ってきて新しい力を作っていくっていうのは、とても大事なんじゃないかなと思ってやってみた。まあ画期的だったよ。大学の教員公募で「うちに無いやつ」っていう教員公募をする大学は絶対無かったと思うけど、そこで入ってきた人が必ず新しい力を作っていく。というわけで、成長し続けると思うよ。&lt;/p&gt;
&lt;p&gt;このキャンパスはカトカンっていう人と、相磯秀夫先生っていう環境情報学部長で、カトカンは慶應大学の加藤寛先生です。政府税制調査会会長って書いてある。これが初めての消費税の導入をやったんだよ。初めての消費税導入をやったとき、SFC1期生しかいないんだよ。それで授業で相談してるんだよね、学生と。**「何パーセントにしようか」「消費税どうする？」みたいな。**次の日新聞見ると、「税制調査会会長、3パーセントの消費税に決定」って書いてあるんだよ。学生たち、みんななんて思ったか知ってる？　「あ、俺が決めた」って。そういうところがSFCの面白いところだよ。&lt;/p&gt;
&lt;p&gt;次は相磯先生ね。相磯先生は僕らの先生なんですけど、そもそも**「相磯研究室からは、村井純、徳田英幸や坂村健をはじめとするコンピュータ関連分野の多くの研究者を輩出した」**って、相磯先生の良いこともっと書けよっていう。ハハハ。まあとにかく、この2人の学部長がこのキャンパスの顔で、俺実は秘密をこの間聞いたんだよ。井関先生っていう本当に作ってる人たちっていうのがいるんだよ。それが、この2人を学部長にするっていうストーリーの件をこの間初めて井関先生から聞いたんだよ。井関先生と高橋潤二郎っていう2人の先生が、このキャンパスの企みをずっと作っていたんだよ。本当の哲学者って石川先生から言われて。それであるとき、石川先生に陳情に行ったっていうんだよ。井関先生から聞いたんだよ？　フェイクニュースかもしれないよ、とか言って。ハハハ。でも井関先生は当時の副学部長だから。それで、プロデューサーが高橋潤二郎と井関さんなの。それで準備してて、「これだ、これだ」って言って大体の骨格ができて、俺なんかも東大から呼んで準備室とか入れて、インターネットをどうするかとか。&lt;/p&gt;
&lt;p&gt;そしてある時期に、実は俺は行ったんだよ、石川さんのところに。それでこう言ったんだよ。「僕も高橋潤二郎先生も相磯先生も、ものすごくきちんとできるけど、やっぱり世の中にこれだけ違うことをやるっていうシンボリックな看板がいるんだ。だから経済学部から加藤をよこせ」って。一方加藤さんは「喜んで行くよ」って言ったらしいんだけどさ。それで加藤さんも三田では相当はみ出し者っていう感じだったからさ。もうあまりに外で活躍して有名だから、普通のアカデミズムから言うと、大体そういうのはちょっといろめがねで見られちゃう、まあSFCってそういう先生多いんだよね。&lt;/p&gt;
&lt;p&gt;というわけで、SFCにいる人っていうのはなんとなく激しい人多いでしょ？　「イラクとアメリカがどうした」なんて言っても結局、「田中と中山しか出てこないじゃん、テレビ見ても」みたいなそういうところあって、まあSFCはそういう先生多いんだよ。昔も中国のことが出てくると小島先生が出てきてっていう。とにかくそういうことで加藤先生を呼んだんだって。そうするとこれも見事に成功したんだよ、やっぱり。SFCの1つのキャラクターをこの2人で作って、総合政策学部と環境情報学部なんて一緒だよって言ったんだけど、この2つの強い芯、総合政策と、ある意味のコンピュータサイエンスを中心とする環境情報学部の強い力っていうのを、シンボリックにこの2人は表してたかなと思います。&lt;/p&gt;
&lt;p&gt;それで、そのときの環境情報学部側のブレインが斎藤信男先生で、僕や中村修さんの智将ですね、理工学部にいたね。彼がOSの専門家だったから、僕らはOSの勉強をするために筑波大学から移ってきた斎藤先生と一緒になりました。あとはもう時間が無いので飛ばします。歴史はこの授業でいろいろ話したので。&lt;/p&gt;
&lt;p&gt;(スライドを見ながら)インターネットができました。インターネットはUNIXとパケット交換のARPANET。これ(ケン・トンプソン、デニス・リッチー)が両方の親で、それがバークレーで一緒になった。&lt;/p&gt;
&lt;p&gt;(次のスライドに移って)これが俺が言わないとなかなか忘れられちゃう、1982年にこの男、Bill Joyはバークレー・ソフトウェア・ディストリビューション、BSDというUNIXを作ったときにTCP/IPを入れて、世界中にオープンソースで配ったの。これが重要なので、このレッスンは大学が世の中を変えるってことなの。インターネットは、大学ができたのはBillがバークレーで頑張ったから。&lt;/p&gt;
&lt;p&gt;(次のスライドに移って)そしてPostelのことは、オペレーションだね、やっぱり。動かし続ける技術っていうのを、そう派手なことじゃないけど彼はきちんと動くためにどうすれば良いかってことをずっと考えられる人で、彼がいたからインターネットは動いたっていう話をするときに、ドメイン名とかね。俺も彼から「日本は頼むぞ、純」って言われて。&lt;/p&gt;
&lt;p&gt;Postelがインターネットを動かすときに、どうしようって言って必ず俺を呼ぶんだよ。「太平洋の向こう側に1人、ちゃんとしたのがいる」って言って。そういう意味では彼は僕の大変重要な指導者であったと。&lt;/p&gt;
&lt;p&gt;(次のスライドに移って)次、この人(Stephen Wolff)は恐ろしい人なんですよ。俺33歳とかだからね、インターネットつないでたとき。インターネットっていう、つまりそれまでは電話と電話をつなぐみたいな話は、国と国がトップ・トップでやるような話で、それを33歳の若者が勝手にアメリカとつないじゃったんだよな、世界と。こんなもの、政府が関与しないでそんなことやって国際問題になったらどうするのよ、みたいな心配をみんなしていて。それでそのときに俺がアメリカ行って、こいつのオフィスのところで「つなぐぞー」っていうのをやっていたけど、「ところでさ、これつながって上手くいっても日本の奴みんな心配してて、東大助手の若造が世界をつなぐみたいなことやってて、こんなこと許されるわけないってみんな言うんだよね」って言ったら、こいつが3分いなくなって、National Science Foundationのレターヘッドでこのメール書いてきたの。&lt;/p&gt;
&lt;p&gt;「Dear Dr. Murai,　In light of our discussion this afternoon, on behalf of NSF it is a pleasure to grant internet access to the Japanese IP community. Sincerely,　Stephen S. Wolf　Division Director」&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; これを3分で書いてきて、「Jun. Does it help?」。このスピーディーな…。額に飾ってあるよ、今。これを持って帰って東大に戻ってきて、「分かるこれ？　分かる？　National Science Foundation、アメリカの政府の正式なグラントだよ？」みたいな。どうして権威に頼るんだよっていうことも、でも権威にも簡単に突破できるんじゃない？　みたいなところも、しかもフェイクじゃないからね、これ。まあ、そんなんで。&lt;/p&gt;
&lt;p&gt;(次のスライドに移って)ウェブはSFCから生まれたってことは言ったよね。Ted NelsonはSFCにいた教員。それが元になってハイパーテキストっていうんで、ワールド・ワイド・ウェブのTim Berners-Leeがウェブを作った。そういう意味ではSFCはインターネットをいっぱい生み出してるんだね。&lt;/p&gt;
&lt;p&gt;最後に、2000年にこういう人口分布があったんだよな。それで、アジアっていうのはほとんど日本なんだよ、それで頭にきて。なぜ頭にきたかっていうと、アメリカ人と日本人がほとんど同じ人数なんだよ。2000年だろ？　1990年の後半に、インターネット・バブルが起こって、バークレーのやつらがみんなビジネス始まったんだよ。だから、研究開発してるのは俺たちだけなんだよ。そうすると、これがめちゃくちゃ日本が強かったんだよ。日本の研究開発で作ってたのがIPv6っていう、今お前らが使ってるバージョンの前の、バージョン4っていうんだけど、この開発を刈込っていうこのキャンパスでやっていて、それが世界の開発をずっとこのとき牛耳ってて、しかもSFCで。そこへ同僚のとんでもないやつが来て、「&lt;strong&gt;日本のインターネットは、どうしてこんなにぼろいの？&lt;/strong&gt;」って言ったんだよ。俺はすごい頭にきて。そのときはもう超天狗で、俺たちが世界で一番先端のインターネットを作ってるんだ、って思ってたときに、平気な顔をして「日本のインターネットはどうしてこんなぼろいの」って。「何のことを言ってんだ、お前は」って言ったら、「役所で使ってない。経済で使われていない。だから、日本の経済はアメリカに後れを取るんだ」って言われて。だから「なんだ、このアメリカかぶれ」って思った。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;それを言ったのがこいつ(竹中平蔵)&lt;/strong&gt;、同僚、名前言えない同僚。それですごいよね、経済学者の視点と俺たちが作ってきた世界一だと思ってた話とが全く違うんだよね。でもよく考えてみるとそうなんだよ。政府で使われてないし、金融で使われてないし、だから経済にダメージを与えられているんだよ。なんでだよ、って思ったら1つ。こういう経済学者とかビジネスの人っていうのは、そういう言い方するんだよ。それで、「どうすれば良いですか」って言われると、「掛かった」みたいな、そういう金融コンサルタントってみんな大体そういう論法で話すわけ。「もうこうしなきゃだめですよ」って竹中さんが言うと、「どうすれば良いかな、どうすれば良い？」って俺も言っちゃったんだよね。そうしたら「総理のところへ行きましょう」って言われて。&lt;/p&gt;
&lt;p&gt;それで、そのときに作ったスライドを持ってきたんだけど。これ、2000年に総理のところに行きましょうって言うから、総理用に作ったスライドなんだよね。それで、「総理、今までは電話のインフラと放送のインフラがあるんですけど、いろんなインフラがありますよね、我が国には。それでインターネットっていうのは、電話のインフラの上に乗せてデジタル通信をやってみたら、経済とか教育とか結構うまくいき始めたんですよね。もうちょっと頑張ると、あらゆることにインターネットは貢献できると思うんですけど、多分電話の(インフラの)上に乗ってると高い。だからネイティブのインフラを作ろうよ。」って言って。(スライドを指しながら)放送と電話は国の物だから弄ると怒られるので、他の分野で貢献するとか言ってるんですよね。それでもう1枚(スライドを)入れて、そうすると(スライド上の電話インフラと放送インフラの図の面積が)なんとなく細くなってる。「あれ？いつの間にかちょっと、ちょっとインターネットが(笑)」なんて。それで、「いや、これ気が付かないよね」みたいな。だから、ネイティブのインフラが要るんだよねって言いながら、悪乗りしてもう1枚(スライドを)作ったの。&lt;/p&gt;
&lt;p&gt;(電話インフラと放送インフラの図のみ消されたスライドが表示され、会場爆笑)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; そしたらこれが上手く取り入れられて、あるとき総理が所信表明をするって言ったら、ここに夜中の2時頃、「明日総理が所信表明をするんですけど、キーワードが無い」って言われて。俺関係ねえなあ…そんなの、って思ったけど、この文章は始めは入ってて、「先端インターネットの技術の開発などの研究開発によるグローバルインターネットの課題解決へ積極参加する」。この文章は俺が入れたのね。そしたら各省庁を回らなきゃいけないんだよ、本当は。だけど、引っ掛かるワードが無いってわけ。だから「IPv6などにって、総理言ったらどうですか」って言ったら「それ良いね、入れよう」ってことになって。誰も知らないの、誰も。日本中誰も知らないの。IPv6って何、みたいな。そしたら所信表明の次の日、さすがに全ての新聞が囲みで「IPv6とは」って付けてたの。「やったー！」っていう、ハハハ。&lt;/p&gt;
&lt;p&gt;(会場笑い。拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; こういうやんちゃなことができるのは、SFCだよね。これは俺が技術者として生きてたら、こんなことは絶対起こらなかった。というわけで、SFCは素晴らしいところだなっていうので。&lt;/p&gt;
&lt;p&gt;じゃあ、俺のスライド、まだ？ああ、もういいや、911話したわ授業で。&lt;/p&gt;
&lt;p&gt;じゃあもう時間無いから。時間が来たのでこれで良いですか?他の質問とか。もう時間無いもんね。じゃあ、サユさん、マイク持っていただいて良いですか。&lt;/p&gt;
&lt;p&gt;これが最後の皆さんへのメッセージです。僕は喋れなくなるかもしれないから書いてあるんです。バックアップのスピーカーがちゃんとありますんで、僕の言葉だと思ってください、どうぞ。&lt;/p&gt;
&lt;p&gt;(スライドを見ながら)念のために書いておきました。まずは皆さん、今年のインターネットを最後まで履修してくれてどうもありがとう。&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; それから30年、SFCでつながってくれた全ての人たち、昔の人も今日は来てくれて本当に感謝いたします。どうもありがとう。&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; それからさっき、「みんなに任せたぞ」って言ったけど、俺は30年、50年、この世界を作ってきた、みんなと一緒に。でもこれから30年、50年、そして100年、ここを目指したことはみんなに任せます。頑張ってください。もう安心しています、みんながこれをやってくれると信じています。あの、SFCで…&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(&lt;strong&gt;涙ぐみながら__TA&lt;/strong&gt;：須田に続きの代読を頼むジェスチャー&lt;/em&gt;_)_&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TA(須田)：&lt;/strong&gt; &lt;strong&gt;SFCで働けて良かった！とても楽しかった！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TA(須田)：&lt;/strong&gt; &lt;strong&gt;SFCにきてよかった！とても楽しかった！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; &lt;strong&gt;SFCの学生と卒業生は、みなさんは！私の誇りです！本当に。どうもありがとう。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; &lt;strong&gt;30年間どうもありがとう！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; どうもありがとうございました。&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 先生、先生そのままで。&lt;/p&gt;
&lt;p&gt;(花束贈呈)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; ありがとう。(ハグをする)&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; ああ、よく来てくれた…。ありがとう。(ハグをする)&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 先生、せっかくなので履修者の方たちと一緒に写真を撮りたいなと思うのですが、大変申し訳ないんですけどステージから降りていただいて、そこで上からなるべく広角で撮りたいと思います、すみません。お花も持っていただいて。&lt;/p&gt;
&lt;p&gt;大丈夫ですか。じゃあ、あとで2ショットを撮る権利を与えよう！&lt;/p&gt;
&lt;p&gt;(写真撮影)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; ありがとうございました。じゃあみなさん一回戻っていただいて。&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;村井：&lt;/strong&gt; どうもありがとう、どうもありがとう。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;教員：&lt;/strong&gt; 今期の授業も本当にありがとうございました。みなさんのご協力のお陰で、時間もおさずに何とか終われましたので本当にありがとうございました。&lt;/p&gt;
&lt;p&gt;(会場拍手)&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;20年前に、WWW、インターネットを知りその凄さに感動し、どこに行けばちゃんと学べるかを探して、村井先生の居るSFCを見つけて進学しました。&lt;/li&gt;
&lt;li&gt;久しぶりに村井先生の講義を拝聴し、学生時代に聞いていた講義を懐かしく思うとともに、あの話し方は独特でとても惹きつけるし印象に残ります。&lt;/li&gt;
&lt;li&gt;日本のインターネットインフラが安価で高速で安定していて、検閲のない自由なインターネットができているのは村井先生のおかげです。&lt;/li&gt;
&lt;li&gt;卒業して16年後の私は共同創業者 取締役CTOをしてます。一緒にインターネットを楽しくする仲間を募集中！&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;余談・サポート&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;当初、&lt;a href=&quot;https://aws.amazon.com/jp/transcribe/&quot;&gt;AWS Transcribe&lt;/a&gt;を使って文字起こしをしてみました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;しかし、精度が低すぎたので人力で行いました。&lt;/li&gt;
&lt;li&gt;2020年の音声認識の精度の記録として&lt;a href=&quot;https://gist.github.com/matsubo/099d4b643bf14b341ca83bf97df9dd37&quot;&gt;処理結果のJSONファイル&lt;/a&gt;を一応アーカイブ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.amazon.co.jp/hz/wishlist/ls/1Y9PUK3OZYI5M/ref=nav_wishlist_lists_1?_encoding=UTF8&amp;amp;type=wishlist&quot;&gt;Amazon欲しい物リスト&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.buymeacoffee.com/matsubokkuri&quot;&gt;Buy me a coffee&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;頂いた品物&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Y.O様 — ありがとうございます！しっかり勉強します！=&amp;gt; 無事合格しました！&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://x.com/castanea&quot;&gt;@castanea&lt;/a&gt; — ありがとうございます！3杯も！&lt;/li&gt;
&lt;li&gt;N様 — ありがとうございます！Intel経営を学びたいと思います。&lt;/li&gt;
&lt;li&gt;R.O様（2021/12/6）— Amazon Wishlist経由のギフトをありがとうございます！年末の掃除と、夜間のランニングが安全に行なえます！&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;{/* textlint-enable */}&lt;/p&gt;
</content:encoded></item><item><title>git&apos;s weekly number of commits graph</title><link>https://blog.teraren.com/posts/gits-weekly-number-of-commits-graph/</link><guid isPermaLink="true">https://blog.teraren.com/posts/gits-weekly-number-of-commits-graph/</guid><description>git&apos;s weekly number of commits graph</description><pubDate>Thu, 23 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;https://x.com/matsubokkuri/status/1219951077442777090&lt;/p&gt;
&lt;p&gt;stat.rbを少し変更すれば、月ごとや年ごとの期間の調整ができます。また、git logコマンドのオプションにて、--authorなどを指定すれば集計したいコミットの絞り込みが行なえます。&lt;/p&gt;
</content:encoded></item><item><title>Redashでログインしてしまったユーザを削除</title><link>https://blog.teraren.com/posts/redash-delete-user/</link><guid isPermaLink="true">https://blog.teraren.com/posts/redash-delete-user/</guid><description>Redashで一度ログイン済みのユーザを管理画面から削除できない場合に、PostgreSQLに直接アクセスして外部キー制約を考慮しながら物理削除する手順</description><pubDate>Tue, 21 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Redashのユーザを作って、そのユーザでログインしてしまった後にそのユーザを物理削除する方法の紹介です。&lt;/li&gt;
&lt;li&gt;管理画面からEnable/Disableはできますが、削除はできません。SSOでユーザを作ってしまったらメアドの変更ができないので退避もできません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Redashのバージョン8.0.0.b32245&lt;/li&gt;
&lt;li&gt;AWS AMIで構築しているので、docker-compose管理下です。ubuntuユーザでSSHして、sudo -sでrootになります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;削除方法&lt;/h2&gt;
&lt;p&gt;削除したいユーザを見つけます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@ip-172-31-28-245:/opt/redash# docker exec -it redash_server_1 ./manage.py users list
&amp;lt;省略&amp;gt;
--------------------
Id: 5
Name: Yuki Matsukura
Email: xxxxxxxxxx@xxxxxxxx.com
Organization: Minedia, Inc.
Active: False
Groups: default
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;消そうとしても、外部キー制約にひっかかって消せません。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@ip-172-31-28-245:/opt/redash# docker exec -it redash_server_1 ./manage.py users delete xxxxxxxxxx@xxxxxxxx.com
Traceback (most recent call last):
  File &quot;./manage.py&quot;, line 9, in &amp;lt;module&amp;gt;
    manager()
  File &quot;/usr/local/lib/python2.7/site-packages/click/core.py&quot;, line 716, in __call__
    return self.main(*args, **kwargs)
  File &quot;/usr/local/lib/python2.7/site-packages/flask/cli.py&quot;, line 380, in main
    return AppGroup.main(self, *args, **kwargs)
  File &quot;/usr/local/lib/python2.7/site-packages/click/core.py&quot;, line 696, in main
    rv = self.invoke(ctx)
  File &quot;/usr/local/lib/python2.7/site-packages/click/core.py&quot;, line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File &quot;/usr/local/lib/python2.7/site-packages/click/core.py&quot;, line 1060, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File &quot;/usr/local/lib/python2.7/site-packages/click/core.py&quot;, line 889, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File &quot;/usr/local/lib/python2.7/site-packages/click/core.py&quot;, line 534, in invoke
    return callback(*args, **kwargs)
  File &quot;/usr/local/lib/python2.7/site-packages/click/decorators.py&quot;, line 17, in new_func
    return f(get_current_context(), *args, **kwargs)
  File &quot;/usr/local/lib/python2.7/site-packages/flask/cli.py&quot;, line 257, in decorator
    return __ctx.invoke(f, *args, **kwargs)
  File &quot;/usr/local/lib/python2.7/site-packages/click/core.py&quot;, line 534, in invoke
    return callback(*args, **kwargs)
  File &quot;/app/redash/cli/users.py&quot;, line 165, in delete
    synchronize_session=False)
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/query.py&quot;, line 3353, in delete
    delete_op.exec_()
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py&quot;, line 1329, in exec_
    self._do_exec()
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py&quot;, line 1521, in _do_exec
    self._execute_stmt(delete_stmt)
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/persistence.py&quot;, line 1336, in _execute_stmt
    mapper=self.mapper)
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/session.py&quot;, line 1176, in execute
    bind, close_with_result=True).execute(clause, params or {})
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py&quot;, line 948, in execute
    return meth(self, multiparams, params)
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/sql/elements.py&quot;, line 269, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py&quot;, line 1060, in _execute_clauseelement
    compiled_sql, distilled_params
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py&quot;, line 1200, in _execute_context
    context)
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py&quot;, line 1413, in _handle_dbapi_exception
    exc_info
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/util/compat.py&quot;, line 265, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py&quot;, line 1193, in _execute_context
    context)
  File &quot;/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py&quot;, line 509, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError) update or delete on table &quot;users&quot; violates foreign key constraint &quot;events_user_id_fkey&quot; on table &quot;events&quot;
DETAIL:  Key (id)=(5) is still referenced from table &quot;events&quot;.
 [SQL: &apos;DELETE FROM users WHERE users.email = lower(%(lower_1)s)&apos;] [parameters: {&apos;lower_1&apos;: u&apos;xxxxxxxxxx@xxxxxxxx.com&apos;}] (Background on this error at: http://sqlalche.me/e/gkpj)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;外部キー制約のある子供を物理的に消しに行きます。まず、postgresのコンソールに入ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@ip-172-31-28-245:/opt/redash# docker exec -it redash_postgres_1 bash
bash-5.0# su postgres
/ $ psql
psql (9.6.15)
Type &quot;help&quot; for help.

postgres=# \d
                        List of relations
 Schema |               Name               |   Type   |  Owner
--------+----------------------------------+----------+----------
 public | access_permissions               | table    | postgres
 public | access_permissions_id_seq        | sequence | postgres
 public | alembic_version                  | table    | postgres
 public | alert_subscriptions              | table    | postgres
 public | alert_subscriptions_id_seq       | sequence | postgres
 public | alerts                           | table    | postgres
 public | alerts_id_seq                    | sequence | postgres
 public | api_keys                         | table    | postgres
 public | api_keys_id_seq                  | sequence | postgres
 public | changes                          | table    | postgres
 public | changes_id_seq                   | sequence | postgres
 public | dashboards                       | table    | postgres
 public | dashboards_id_seq                | sequence | postgres
 public | data_source_groups               | table    | postgres
 public | data_source_groups_id_seq        | sequence | postgres
 public | data_sources                     | table    | postgres
 public | data_sources_id_seq              | sequence | postgres
 public | events                           | table    | postgres
 public | events_id_seq                    | sequence | postgres
 public | favorites                        | table    | postgres
 public | favorites_id_seq                 | sequence | postgres
 public | groups                           | table    | postgres
 public | groups_id_seq                    | sequence | postgres
 public | notification_destinations        | table    | postgres
 public | notification_destinations_id_seq | sequence | postgres
 public | organizations                    | table    | postgres
 public | organizations_id_seq             | sequence | postgres
 public | queries                          | table    | postgres
 public | queries_id_seq                   | sequence | postgres
 public | query_results                    | table    | postgres
 public | query_results_id_seq             | sequence | postgres
 public | query_snippets                   | table    | postgres
 public | query_snippets_id_seq            | sequence | postgres
 public | users                            | table    | postgres
 public | users_id_seq                     | sequence | postgres
 public | visualizations                   | table    | postgres
 public | visualizations_id_seq            | sequence | postgres
 public | widgets                          | table    | postgres
 public | widgets_id_seq                   | sequence | postgres
(39 rows)
postgres=# \d events
                                         Table &quot;public.events&quot;
        Column         |           Type           |                      Modifiers
-----------------------+--------------------------+-----------------------------------------------------
 id                    | integer                  | not null default nextval(&apos;events_id_seq&apos;::regclass)
 org_id                | integer                  | not null
 user_id               | integer                  |
 action                | character varying(255)   | not null
 object_type           | character varying(255)   | not null
 object_id             | character varying(255)   |
 additional_properties | text                     |
 created_at            | timestamp with time zone | not null
Indexes:
    &quot;events_pkey&quot; PRIMARY KEY, btree (id)
Foreign-key constraints:
    &quot;events_org_id_fkey&quot; FOREIGN KEY (org_id) REFERENCES organizations(id)
    &quot;events_user_id_fkey&quot; FOREIGN KEY (user_id) REFERENCES users(id)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;見つけて、レコードを消します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;postgres=# select * from events where user_id = 5;
  id   | org_id | user_id |     action     | object_type |     object_id     |                                                                                                             additional_properties                                                                                                              |         created_at
-------+--------+---------+----------------+-------------+-------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------
 17041 |      1 |       5 | login          | redash      |                   | {&quot;ip&quot;: &quot;172.31.28.17&quot;, &quot;user_agent&quot;: &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36&quot;}                                                                              | 2020-01-21 02:33:38+00
 17042 |      1 |       5 | load_favorites | query       |                   | {&quot;ip&quot;: &quot;172.31.28.17&quot;, &quot;params&quot;: {&quot;q&quot;: null, &quot;page&quot;: 1, &quot;tags&quot;: []}, &quot;user_agent&quot;: &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36&quot;, &quot;user_name&quot;: &quot;Yuki Matsukura&quot;} | 2020-01-21 02:33:39+00
 17043 |      1 |       5 | load_favorites | dashboard   |                   | {&quot;ip&quot;: &quot;172.31.28.17&quot;, &quot;params&quot;: {&quot;q&quot;: null, &quot;page&quot;: 1, &quot;tags&quot;: []}, &quot;user_agent&quot;: &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36&quot;, &quot;user_name&quot;: &quot;Yuki Matsukura&quot;} | 2020-01-21 02:33:39+00
 17044 |      1 |       5 | load_favorites | query       |                   | {&quot;ip&quot;: &quot;172.31.28.17&quot;, &quot;params&quot;: {&quot;q&quot;: null, &quot;page&quot;: 1, &quot;tags&quot;: []}, &quot;user_agent&quot;: &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36&quot;, &quot;user_name&quot;: &quot;Yuki Matsukura&quot;} | 2020-01-21 02:33:39+00
 17045 |      1 |       5 | load_favorites | dashboard   |                   | {&quot;ip&quot;: &quot;172.31.28.17&quot;, &quot;params&quot;: {&quot;q&quot;: null, &quot;page&quot;: 1, &quot;tags&quot;: []}, &quot;user_agent&quot;: &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36&quot;, &quot;user_name&quot;: &quot;Yuki Matsukura&quot;} | 2020-01-21 02:33:39+00
 17046 |      1 |       5 | view           | page        | personal_homepage | {&quot;screen_resolution&quot;: &quot;1920x1200&quot;, &quot;ip&quot;: &quot;172.31.28.17&quot;, &quot;user_name&quot;: &quot;Yuki Matsukura&quot;, &quot;user_agent&quot;: &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36&quot;}             | 2020-01-21 02:33:39.859+00
 17047 |      1 |       5 | view           | user        | 5                 | {&quot;ip&quot;: &quot;172.31.28.17&quot;, &quot;user_name&quot;: &quot;Yuki Matsukura&quot;, &quot;user_agent&quot;: &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36&quot;}                                               | 2020-01-21 02:33:44+00
 17048 |      1 |       5 | list           | group       | groups            | {&quot;ip&quot;: &quot;172.31.28.17&quot;, &quot;user_name&quot;: &quot;Yuki Matsukura&quot;, &quot;user_agent&quot;: &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36&quot;}                                               | 2020-01-21 02:33:44+00
(8 rows)

postgres=# delete from events where user_id = 5;
DELETE 8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そして、削除&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@ip-172-31-28-245:/opt/redash# docker exec -it redash_server_1 ./manage.py users delete xxxxxxxxxx@xxxxxxxx.com
Deleted 1 users.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-successive-word &lt;em&gt;/}
めでたしめでたし
{/&lt;/em&gt; textlint-enable */}&lt;/p&gt;
</content:encoded></item><item><title>RedashとG SuiteのSAML設定</title><link>https://blog.teraren.com/posts/redash-gsuite-saml/</link><guid isPermaLink="true">https://blog.teraren.com/posts/redash-gsuite-saml/</guid><description>Google WorkspaceとRedashをSAML連携させてSSO環境を構築するための詳細手順と、8時間かけて調べた設定値のポイントを解説</description><pubDate>Tue, 21 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;なかなか記事が見つからなかったので書いておきます。&lt;/li&gt;
&lt;li&gt;8時間ぐらい時間を使ったorz&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;手順&lt;/h2&gt;
&lt;h3&gt;G Suite側の設定&lt;/h3&gt;
&lt;p&gt;G Suiteの管理権限が必要になると思います。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://admin.google.com/AdminHome?hl=en#AppsList:serviceType=SAML_APPS&quot;&gt;https://admin.google.com/AdminHome?hl=en#AppsList:serviceType=SAML_APPS&lt;/a&gt; にアクセスして、SAMLのアプリを追加します。&lt;/p&gt;
&lt;p&gt;URLが変更された様子: &lt;a href=&quot;https://admin.google.com/ac/apps/unified&quot;&gt;https://admin.google.com/ac/apps/unified&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/01/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;RedashはIDpメタデータによる連携に対応しているので、このファイルをダウンロードしてRedashからアクセスできるURLに保存しておきます。&lt;/p&gt;
&lt;p&gt;私は、&lt;a href=&quot;https://gist.github.com/&quot;&gt;gist&lt;/a&gt;のsecretにしました。*1 （間違って、このURLのgistを削除してしまったり、github.comがダウンしているときにはどうしようという疑問は残ります）&lt;/p&gt;
&lt;p&gt;あと、Entity IDのURLをメモしておきます。（ダウンロードしたIDp metadataのXMLファイル内にも記載があるのでメモらなくてもOKですが）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/01/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;このあたりは適当に入力して、Nextへ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/01/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ACSのURLは、Redashを設置しているサイトのトップページURLに、&lt;code&gt;/saml/callback?org_slug=default&lt;/code&gt; をappendしたURLです。&lt;/p&gt;
&lt;p&gt;Entity IDは、*1のEntity IDを入れれば良いっぽいです。（本当は違うんだろうけど、Redash側のエンドポイントがわからないし、同じEntityの名前なようなのでこれで行けるんだと思います）&lt;/p&gt;
&lt;p&gt;Entity IDはGoogle Workspaceに登録されたApps内でユニークになる必要があります。なので、Service Providerを一意に識別できる文字列を入れておけば良さそうです。例えば、Service ProviderのURL。&lt;/p&gt;
&lt;p&gt;Start URLは適当にRedashのトップページを入れておきます。その他はデフォルトで良いです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/01/image-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Attributeのマッピングを以下のように設定します。後ほど設定もできます。（これを設定しないとRedash側でエラーが起きてSSOができません）&lt;/p&gt;
&lt;p&gt;Finishを押して設定を完了します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/01/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;作成直後はこのアプリ自体が無効になっているので有効にするのをお忘れなく。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/01/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Redash側の設定&lt;/h3&gt;
&lt;p&gt;設定の変更にはRedashのadmin権限が必要です。&lt;/p&gt;
&lt;p&gt;SAML Metadata URLには、G Suite側で作成したIDP MetadataのURLを記載します。*1 で取得したファイルへの参照です。&lt;/p&gt;
&lt;p&gt;SAML Entity IDも*1に含まれているか、途中で表示されたEntity IDのURLを記入します。&lt;/p&gt;
&lt;p&gt;SAML NameID Formatには、&lt;code&gt;urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress&lt;/code&gt;を入力します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/01/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最後に保存を押してテストをすればOKです。&lt;/p&gt;
&lt;p&gt;Redash側のSAML関連のコードはこのあたりでしたので、コードを読んで設定値を探してました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/getredash/redash/blob/a682265e1396cf46b7baf8cc593239b6129c5662/redash/authentication/saml_auth.py#L59&quot;&gt;https://github.com/getredash/redash/blob/a682265e1396cf46b7baf8cc593239b6129c5662/redash/authentication/saml_auth.py#L59&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;テスト時の注意&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;既存のメアドがredashにある状態で、SAMLでSSOしても&lt;strong&gt;問題ありません&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;新規ユーザでのテストのために、自分のメアドを一時的に置き換えてSAMLでSSOしてしまうと後々ユーザを消すのが大変なので**&lt;a href=&quot;/posts/redash-delete-user/&quot;&gt;やめたほうが良いです&lt;/a&gt;。**&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>GMOBBが遅いのでSo-netの固定IPアドレスへ変更</title><link>https://blog.teraren.com/posts/gmobb-to-sonet/</link><guid isPermaLink="true">https://blog.teraren.com/posts/gmobb-to-sonet/</guid><description>GMOBBの夜間平均350kbpsという劣悪な速度をspeedtest-cliで可視化し、So-net固定IPへ変更後に150Mbpsに改善した比較レポート</description><pubDate>Wed, 08 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ISPにGMOBBの固定IPアドレスを使っていたのですが、夜になると速度が超遅くて使い物になりませんでした。&lt;/p&gt;
&lt;p&gt;とはいっても、遅いと思った時に自分で計測していたら面倒です。定期的に自動的に回線速度を計測して、いつどの程度の速度が出ているかを計測してみます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/sivel/speedtest-cli&quot;&gt;speedtest&lt;/a&gt;コマンドがあるので、それを利用しました。結果のデータをjson形式で出力してくれるので加工も楽です。&lt;/p&gt;
&lt;p&gt;speedtestコマンドはUploadの数値は正しく計測できないようです。普段の生活ではDownloadのほうが重要なので無視します。&lt;/p&gt;
&lt;p&gt;使ったコマンド↓&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% speedtest --json | jq -r &apos;[.timestamp,.download,.upload] | @csv&apos; | tee -a `dirname $0`/result.csv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これを15分に1回実行して、回線速度を計測します。&lt;/p&gt;
&lt;p&gt;speedtestコマンドはIPv4にしか対応していないのでIPv4の計測のみになります。&lt;/p&gt;
&lt;h3&gt;Before&lt;/h3&gt;
&lt;p&gt;GMOBBの回線を数日間ベンチマークして。時間ごとに平均値をグラフ化した結果がこちら。時間表記はUTCです。日本時間で、夜9時から12時にかけてかなり遅くなっています。Webサーフィンをしていて体感でわかるぐらい遅くなります。JST 21時で平均が&lt;strong&gt;350kbps&lt;/strong&gt;とかです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/01/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;After&lt;/h3&gt;
&lt;p&gt;so-netの固定IPアドレスオプションに変更して、2週間ぐらいベンチマークを取った結果がこちら。夜には落ち込みがありますが、平均は&lt;strong&gt;150Mbps&lt;/strong&gt;程度です。上のグラフと横の単位が違うので分かりづらいですが雲泥の差です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/01/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;なかなかプロバイダのベンチマークが無いのでトライアンドエラーで試すしか無くて辛いです。&lt;/li&gt;
&lt;li&gt;so-netでの固定IPオプションは速いです。&lt;/li&gt;
&lt;li&gt;早く契約期間の縛りから開放されて、&lt;a href=&quot;http://www.nuro.jp/campaign/rmd/?recomndNo=dfs84206&quot;&gt;nuro&lt;/a&gt;に切り替えたい。&lt;/li&gt;
&lt;li&gt;speedtestコマンドのuploadは正しい値が返ってこない。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>UbuntuやDebianにおいて古いKernelイメージの削除方法</title><link>https://blog.teraren.com/posts/debian-ubuntu-remove-old-kernels/</link><guid isPermaLink="true">https://blog.teraren.com/posts/debian-ubuntu-remove-old-kernels/</guid><description>UbuntuやDebianで蓄積した古いカーネルイメージをdpkgコマンドで確認・削除する手順とディスク容量を節約するための実践メモ</description><pubDate>Tue, 07 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;UbuntuやDebianを運用していくと、古いkernelのイメージが溜まっていきます。気持ち悪いので古いのは消します。&lt;/p&gt;
&lt;p&gt;まずは、一応、最新のkernelでシステムが起動していることを確認しておきましょう。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/matsu# ls /boot/
System.map-5.0.0-37-generic  System.map-5.3.0-26-generic  config-5.3.0-24-generic  efi/   initrd.img-5.0.0-37-generic  initrd.img-5.3.0-26-generic  vmlinuz-5.0.0-37-generic  vmlinuz-5.3.0-26-generic
System.map-5.3.0-24-generic  config-5.0.0-37-generic      config-5.3.0-26-generic  grub/  initrd.img-5.3.0-24-generic  lost+found/                  vmlinuz-5.3.0-24-generic
root@dell /h/matsu# dpkg -l |grep kernel
ii  kmod                                  26-1ubuntu1                            amd64        tools for managing Linux kernel modules
ii  libaio1:amd64                         0.3.112-5                              amd64        Linux kernel AIO access library - shared library
ii  libdrm-amdgpu1:amd64                  2.4.99-1ubuntu1                        amd64        Userspace interface to amdgpu-specific kernel DRM services -- runtime
ii  libdrm-common                         2.4.99-1ubuntu1                        all          Userspace interface to kernel DRM services -- common files
ii  libdrm-intel1:amd64                   2.4.99-1ubuntu1                        amd64        Userspace interface to intel-specific kernel DRM services -- runtime
ii  libdrm-nouveau2:amd64                 2.4.99-1ubuntu1                        amd64        Userspace interface to nouveau-specific kernel DRM services -- runtime
ii  libdrm-radeon1:amd64                  2.4.99-1ubuntu1                        amd64        Userspace interface to radeon-specific kernel DRM services -- runtime
ii  libdrm2:amd64                         2.4.99-1ubuntu1                        amd64        Userspace interface to kernel DRM services -- runtime
ii  linux-firmware                        1.183.3                                all          Firmware for Linux kernel drivers
ii  linux-generic                         5.3.0.26.30                            amd64        Complete Generic Linux kernel and headers
ii  linux-headers-5.3.0-24                5.3.0-24.26                            all          Header files related to Linux kernel version 5.3.0
ii  linux-headers-5.3.0-24-generic        5.3.0-24.26                            amd64        Linux kernel headers for version 5.3.0 on 64 bit x86 SMP
ii  linux-headers-5.3.0-26                5.3.0-26.28                            all          Header files related to Linux kernel version 5.3.0
ii  linux-headers-5.3.0-26-generic        5.3.0-26.28                            amd64        Linux kernel headers for version 5.3.0 on 64 bit x86 SMP
ii  linux-headers-generic                 5.3.0.26.30                            amd64        Generic Linux kernel headers
rc  linux-image-4.15.0-72-generic         4.15.0-72.81                           amd64        Signed kernel image generic
rc  linux-image-4.4.0-170-generic         4.4.0-170.199                          amd64        Signed kernel image generic
ii  linux-image-5.0.0-37-generic          5.0.0-37.40                            amd64        Signed kernel image generic
ii  linux-image-5.3.0-24-generic          5.3.0-24.26                            amd64        Signed kernel image generic
ii  linux-image-5.3.0-26-generic          5.3.0-26.28                            amd64        Signed kernel image generic
ii  linux-image-generic                   5.3.0.26.30                            amd64        Generic Linux kernel image
rc  linux-modules-4.15.0-72-generic       4.15.0-72.81                           amd64        Linux kernel extra modules for version 4.15.0 on 64 bit x86 SMP
rc  linux-modules-4.4.0-170-generic       4.4.0-170.199                          amd64        Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP
ii  linux-modules-5.0.0-37-generic        5.0.0-37.40                            amd64        Linux kernel extra modules for version 5.0.0 on 64 bit x86 SMP
ii  linux-modules-5.3.0-24-generic        5.3.0-24.26                            amd64        Linux kernel extra modules for version 5.3.0 on 64 bit x86 SMP
ii  linux-modules-5.3.0-26-generic        5.3.0-26.28                            amd64        Linux kernel extra modules for version 5.3.0 on 64 bit x86 SMP
rc  linux-modules-extra-4.15.0-72-generic 4.15.0-72.81                           amd64        Linux kernel extra modules for version 4.15.0 on 64 bit x86 SMP
rc  linux-modules-extra-4.4.0-170-generic 4.4.0-170.199                          amd64        Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP
ii  linux-modules-extra-5.0.0-37-generic  5.0.0-37.40                            amd64        Linux kernel extra modules for version 5.0.0 on 64 bit x86 SMP
ii  linux-modules-extra-5.3.0-24-generic  5.3.0-24.26                            amd64        Linux kernel extra modules for version 5.3.0 on 64 bit x86 SMP
ii  linux-modules-extra-5.3.0-26-generic  5.3.0-26.28                            amd64        Linux kernel extra modules for version 5.3.0 on 64 bit x86 SMP
ii  linux-signed-generic                  5.3.0.26.30                            amd64        Complete Signed Generic Linux kernel and headers (dummy transitional package)
ii  rsyslog                               8.1901.0-1ubuntu4                      amd64        reliable system and kernel logging daemon
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;sudo apt-get --purge autoremove&lt;/code&gt; を打つだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/matsu# sudo apt-get --purge autoremove

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be REMOVED:
  linux-image-5.0.0-37-generic* linux-modules-5.0.0-37-generic* linux-modules-extra-5.0.0-37-generic*
0 upgraded, 0 newly installed, 3 to remove and 0 not upgraded.
After this operation, 253 MB disk space will be freed.
Do you want to continue? [Y/n] y
(Reading database ... 126511 files and directories currently installed.)
Removing linux-modules-extra-5.0.0-37-generic (5.0.0-37.40) ...
Removing linux-image-5.0.0-37-generic (5.0.0-37.40) ...
/etc/kernel/postrm.d/initramfs-tools:
update-initramfs: Deleting /boot/initrd.img-5.0.0-37-generic
/etc/kernel/postrm.d/x-grub-legacy-ec2:
Searching for GRUB installation directory ... found: /boot/grub
Searching for default file ... found: /boot/grub/default
Testing for an existing GRUB menu.lst file ... found: /boot/grub/menu.lst
Searching for splash image ... none found, skipping ...
Found kernel: /vmlinuz-5.3.0-26-generic
Found kernel: /vmlinuz-5.3.0-24-generic
Found kernel: /vmlinuz-5.0.0-37-generic
Replacing config file /run/grub/menu.lst with new version
Found kernel: /vmlinuz-5.3.0-26-generic
Found kernel: /vmlinuz-5.3.0-24-generic
Replacing config file /run/grub/menu.lst with new version
Updating /boot/grub/menu.lst ... done

/etc/kernel/postrm.d/zz-update-grub:
Sourcing file `/etc/default/grub&apos;
Sourcing file `/etc/default/grub.d/init-select.cfg&apos;
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.3.0-26-generic
Found initrd image: /boot/initrd.img-5.3.0-26-generic
Found linux image: /boot/vmlinuz-5.3.0-24-generic
Found initrd image: /boot/initrd.img-5.3.0-24-generic
done
Removing linux-modules-5.0.0-37-generic (5.0.0-37.40) ...
(Reading database ... 120073 files and directories currently installed.)
Purging configuration files for linux-modules-5.0.0-37-generic (5.0.0-37.40) ...
Purging configuration files for linux-modules-extra-5.0.0-37-generic (5.0.0-37.40) ...
dpkg: warning: while removing linux-modules-extra-5.0.0-37-generic, directory &apos;/lib/modules/5.0.0-37-generic/kernel/drivers/net/wireless&apos; not empty so not removed
Purging configuration files for linux-image-5.0.0-37-generic (5.0.0-37.40) ...
rmdir: failed to remove &apos;/lib/modules/5.0.0-37-generic&apos;: Directory not empty
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;古いKernelが消えました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /h/matsu# dpkg -l |grep kernel
ii  kmod                                  26-1ubuntu1                            amd64        tools for managing Linux kernel modules
ii  libaio1:amd64                         0.3.112-5                              amd64        Linux kernel AIO access library - shared library
ii  libdrm-amdgpu1:amd64                  2.4.99-1ubuntu1                        amd64        Userspace interface to amdgpu-specific kernel DRM services -- runtime
ii  libdrm-common                         2.4.99-1ubuntu1                        all          Userspace interface to kernel DRM services -- common files
ii  libdrm-intel1:amd64                   2.4.99-1ubuntu1                        amd64        Userspace interface to intel-specific kernel DRM services -- runtime
ii  libdrm-nouveau2:amd64                 2.4.99-1ubuntu1                        amd64        Userspace interface to nouveau-specific kernel DRM services -- runtime
ii  libdrm-radeon1:amd64                  2.4.99-1ubuntu1                        amd64        Userspace interface to radeon-specific kernel DRM services -- runtime
ii  libdrm2:amd64                         2.4.99-1ubuntu1                        amd64        Userspace interface to kernel DRM services -- runtime
ii  linux-firmware                        1.183.3                                all          Firmware for Linux kernel drivers
ii  linux-generic                         5.3.0.26.30                            amd64        Complete Generic Linux kernel and headers
ii  linux-headers-5.3.0-24                5.3.0-24.26                            all          Header files related to Linux kernel version 5.3.0
ii  linux-headers-5.3.0-24-generic        5.3.0-24.26                            amd64        Linux kernel headers for version 5.3.0 on 64 bit x86 SMP
ii  linux-headers-5.3.0-26                5.3.0-26.28                            all          Header files related to Linux kernel version 5.3.0
ii  linux-headers-5.3.0-26-generic        5.3.0-26.28                            amd64        Linux kernel headers for version 5.3.0 on 64 bit x86 SMP
ii  linux-headers-generic                 5.3.0.26.30                            amd64        Generic Linux kernel headers
rc  linux-image-4.15.0-72-generic         4.15.0-72.81                           amd64        Signed kernel image generic
rc  linux-image-4.4.0-170-generic         4.4.0-170.199                          amd64        Signed kernel image generic
ii  linux-image-5.3.0-24-generic          5.3.0-24.26                            amd64        Signed kernel image generic
ii  linux-image-5.3.0-26-generic          5.3.0-26.28                            amd64        Signed kernel image generic
ii  linux-image-generic                   5.3.0.26.30                            amd64        Generic Linux kernel image
rc  linux-modules-4.15.0-72-generic       4.15.0-72.81                           amd64        Linux kernel extra modules for version 4.15.0 on 64 bit x86 SMP
rc  linux-modules-4.4.0-170-generic       4.4.0-170.199                          amd64        Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP
ii  linux-modules-5.3.0-24-generic        5.3.0-24.26                            amd64        Linux kernel extra modules for version 5.3.0 on 64 bit x86 SMP
ii  linux-modules-5.3.0-26-generic        5.3.0-26.28                            amd64        Linux kernel extra modules for version 5.3.0 on 64 bit x86 SMP
rc  linux-modules-extra-4.15.0-72-generic 4.15.0-72.81                           amd64        Linux kernel extra modules for version 4.15.0 on 64 bit x86 SMP
rc  linux-modules-extra-4.4.0-170-generic 4.4.0-170.199                          amd64        Linux kernel extra modules for version 4.4.0 on 64 bit x86 SMP
ii  linux-modules-extra-5.3.0-24-generic  5.3.0-24.26                            amd64        Linux kernel extra modules for version 5.3.0 on 64 bit x86 SMP
ii  linux-modules-extra-5.3.0-26-generic  5.3.0-26.28                            amd64        Linux kernel extra modules for version 5.3.0 on 64 bit x86 SMP
ii  linux-signed-generic                  5.3.0.26.30                            amd64        Complete Signed Generic Linux kernel and headers (dummy transitional package)
ii  rsyslog                               8.1901.0-1ubuntu4                      amd64        reliable system and kernel logging daemon

root@dell /h/matsu# ls /boot/
System.map-5.3.0-24-generic  config-5.3.0-24-generic  efi/   initrd.img-5.3.0-24-generic  lost+found/               vmlinuz-5.3.0-26-generic
System.map-5.3.0-26-generic  config-5.3.0-26-generic  grub/  initrd.img-5.3.0-26-generic  vmlinuz-5.3.0-24-generic
root@dell /h/matsu#
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>20年前に恐れていたことが現実になってきている</title><link>https://blog.teraren.com/posts/engineer-pricing/</link><guid isPermaLink="true">https://blog.teraren.com/posts/engineer-pricing/</guid><description>大学時代に抱いた中国・インドへの技術格差縮小の懸念が20年後に現実となり、日本エンジニアの国際競争力低下を考察</description><pubDate>Mon, 06 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;主にエンジニア向け。他職種にも通用すると思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;本文&lt;/h2&gt;
&lt;h3&gt;20年前&lt;/h3&gt;
&lt;p&gt;プログラミングや情報理論を勉強していた大学生の時でした。&lt;/p&gt;
&lt;p&gt;当時、ITといえばアメリカ、イギリス、日本がトップを走っているというイメージでした。&lt;/p&gt;
&lt;p&gt;「プログラミングや情報工学を身につけたとしても世界で見ると、日本が少し先にすすんで居るだけであって、しばらくしたら中国やインドに追いつかれてしまって優位性が5年後ぐらいになくなるのではないか。」&lt;/p&gt;
&lt;p&gt;と漠然と不安に思っていました。ITの知識は新しいものが出るのが速いし、1次情報は英語で書かれているので新興国が英語教育を頑張って、ITに少し力を入れればすぐに追いつかれる状態になってしまうだろうと考えていました。&lt;/p&gt;
&lt;p&gt;なので、新興国が日本に追いつく前に、個人としては早くお金を稼いで、勝ち逃げしないとジリ貧になるだろうなぁという焦りは感じていました。&lt;/p&gt;
&lt;p&gt;しかしながら意外と海外での立ち上がりは遅く、大学卒業後の中国におけるエンジニアの単価は日本の10分の1程度でした。&lt;/p&gt;
&lt;h3&gt;ここ数年のトレンド&lt;/h3&gt;
&lt;p&gt;それから20年経った今、中国でのエンジニアの単価は日本と同等。専門職に至ってはそれ以上。ベトナムも急速に追いついてきて日本への出し値は日本で調達する金額の8掛けぐらいの単価にはなってきているという感覚です。&lt;/p&gt;
&lt;p&gt;世界的には、技術者のニーズは高まり、供給も多くなってきました。その中で日本のエンジニアの価値は相対的には20年前に比べるとかなり下落しているのかと思います。&lt;/p&gt;
&lt;p&gt;日本のIT産業の多くは汎用機や制御システムに偏っている気がします。英語はしゃべれないし。&lt;/p&gt;
&lt;p&gt;日本人は真面目な性格なのか、日本語での教材がたくさんあります。英語を日本語に訳したり初心者向けにわかりやすい教材をたくさん作っていて初学者にとってはとても良い環境かと思います。&lt;/p&gt;
&lt;h3&gt;一歩引いて考えてみる&lt;/h3&gt;
&lt;p&gt;しかしながら日本語の教材は1次情報ではないです。日本語の教材やドキュメントを見ている時点で英語ネイティブより伝達が遅れるし、不正確になってしまいます。&lt;/p&gt;
&lt;p&gt;かつては、英語での情報がそこまで多く発信されていなかったので一部の&lt;a href=&quot;https://www.publickey1.jp/&quot;&gt;Publickey&lt;/a&gt;などの日本人の努力によって日本語訳された情報をカバーしていれば世界にはついていけました。今は大量に英語で発信されているので翻訳が追いついていない感じです。&lt;/p&gt;
&lt;p&gt;よって、最前線でスキルを磨くためには英語は必須だし、英語の環境でやりあっていくのは必然です。日本語の中で生きている時点で世界からみたバリューは低いままです。&lt;/p&gt;
&lt;p&gt;振り返ってみると、優秀なエンジニアは海外に早々と行っています。彼らは海外にいるからこそなのか、日本にいるとき以上に成長をしている感じがします。&lt;/p&gt;
&lt;h3&gt;日本の価値&lt;/h3&gt;
&lt;p&gt;日本の価値が海外より上がっていれば、日本で日本のビジネスをするだけで全く問題ないですが、日本だけ成長していません。海外の国々は成長しています。例えば、&lt;a href=&quot;https://www.internetworldstats.com/stats3.htm&quot;&gt;20年前、アジアにおけるインターネットユーザの40％が日本人でしたが、2019年の時点では5％になっています。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;海外旅行へ行くと物価が日本以上だったり、高く感じたりしてしまいます。10年前はそんなことなかったのに。この時点で、日本で稼ぎながら海外で暮らすというアービトラージを利用したプランを行える国の選択肢がかなり減ってきました。&lt;/p&gt;
&lt;p&gt;為替レートは変わっていないので日本が海外に比べて同じかと勘違いしてしまいがちですが、海外において物価が高くなっているので消費財などのApple-to-Appleで比べたら日本での物価は海外に比べると高くはないです。&lt;/p&gt;
&lt;p&gt;日本へ外国人観光客が多くなったのもこのせいです。昔は外国人にとっては、日本はすべてが高くて行けないようなところでしたが、今はアジアをはじめ、様々な国から観光客が来ています。&lt;/p&gt;
&lt;h3&gt;日本人であることのハンディキャップ&lt;/h3&gt;
&lt;p&gt;島国なので、海外に出ることが陸続きの国から比べると心理的、物理的ハードルが高い。まず、日本語が独特すぎます。&lt;/p&gt;
&lt;p&gt;英語の世界から見ると、ハンディキャップを背負った状態です。このハンディを背負い続けたまま生きていくか、このハンディを解消して世界で活躍する必要があります。&lt;/p&gt;
&lt;p&gt;今の10代、20代はグローバルで仕事をすることは必須。30代は日本だけでは将来は結構危険。40、50代は資産がある程度あれば海外に投資することで生きている。60代以降は支出を減らしまくって、田舎で物価が安い生活をすれば生活できるかと思う。&lt;/p&gt;
&lt;h3&gt;働く環境&lt;/h3&gt;
&lt;p&gt;確か、10年前ぐらいはエンジニアは貪欲で英語環境を求めていたし、会社の採用ページでは海外に行けることを全面に押し出したりしている時期がありました。&lt;/p&gt;
&lt;p&gt;しかし、最近の採用ページはワークライフバランス、無料の食事、福利厚生ばかりがフィーチャーされています。それらは重要かもしれませんが長期的に見たら二の次です。&lt;/p&gt;
&lt;h3&gt;起業家&lt;/h3&gt;
&lt;p&gt;10年前に日本から海外へ行こうとする意欲があるベンチャーは多数ありましたが、今は少なくなりました。&lt;/p&gt;
&lt;p&gt;今はベンチャー系ではメルカリ、楽天、BEENOS、ぐらいしか知らないです。（Howの良し悪しは置いておいて）&lt;/p&gt;
&lt;h3&gt;価値&lt;/h3&gt;
&lt;p&gt;働く環境（会社とか場所とか言語） x  個人のスキル（専門性）&lt;/p&gt;
&lt;p&gt;と思っています。&lt;/p&gt;
&lt;p&gt;国レベルで考えると、この働く環境は日本では不十分になってきています。ここ数年はアベノミクスの影響か内需が回復しているように見えますが大したこと無いです。日本に両足を置いて生活していて、ある日海外における自分の価値を考えたら、価値が下がりまくっていたということになります。&lt;/p&gt;
&lt;p&gt;まずは、片足でも海外に出ておかないと。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://toyokeizai.net/articles/-/248186&quot;&gt;10年前に社内の公用語を英語にすると宣言した三木谷社長&lt;/a&gt;は素晴らしいなぁ。でも継続しなかったのは残念。Executionが弱かったのかも。10年間しっかり続けていれば社員はかなり成長できていただろうし、現在よりもっとグローバルの中で存在感を出せたかもしれない。&lt;/p&gt;
&lt;p&gt;と。最近、外国人と仕事をして感じました。&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;書きなぐったので読みづらいと思います。&lt;/li&gt;
&lt;li&gt;PVが増えたら清書します。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>gitにて大容量のファイルを探して履歴から消す</title><link>https://blog.teraren.com/posts/git-remove-large-files/</link><guid isPermaLink="true">https://blog.teraren.com/posts/git-remove-large-files/</guid><description>GitHubへのpushを妨げる100MB超ファイルをgit_find_big.shで特定し、git filter-branchコマンドでリポジトリ履歴から完全に削除する手順を解説。</description><pubDate>Sat, 04 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;githubの個人アカウントにてprivate repositoryが作り放題になったので個人で開発しているソースコードを載せようとしたら、100MB以上のファイルが存在して移行できなかったのでやり方をメモ。&lt;/p&gt;
&lt;p&gt;以下のやり方は、バックアップのことは考えずにやってしまっているのでちゃんとやる場合は、&lt;a href=&quot;https://confluence.atlassian.com/bitbucket/maintaining-a-git-repository-321848291.html&quot;&gt;こちらの記事&lt;/a&gt;を参考にやったほうが良いです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget https://raw.githubusercontent.com/RazorFlow/framework/master/git_find_big.sh
% chmod git_find_big.sh
% ./git_find_big.sh
All sizes are in kB&apos;s. The pack column is the size of the object, compressed, inside the pack file.
size    pack    SHA                                       location
118513  117754  0f44a922dad3f8c8978314f5b931ca855d2dbd05  public/dist/app/macos/郵便番号検索_v1.0.0.zip
50401   50248   43d6d994ec9a7c9369678426bcafbbbf1fea3ba3  public/dist/app/windows/郵便番号検索_v1.0.0.zip
17743   2551    b6cf8085e511bd229d401a46f98140f7efcfc4d7  test/fixtures/KEN_ALL.CSV
5096    1160    75fdc7ed4609fdd02c619685294e4e3d4d27bf68  test/fixtures/concat.csv
4370    837     083ad57d48ab1a08fec1e5e611493d6eee7871eb  test/fixtures/JIGYOSYO.CSV
1298    694     ce74201c4d695087dd2d732f15e311588481aa9b  test/fixtures/KEN_ALL.CSV
1164    333     5d571ecc63e17d18a4e95299b31598c5b3034437  test/fixtures/kyk3.csv
1112    321     d1e6c407c12cf00db2260204f08c12178afed63f  test/fixtures/kyk1.csv
1047    291     a5863b0a1e3e30c5180261c0406b141e65d84135  test/fixtures/kyk4.csv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;あとは、ファイルごとに以下の繰り返し。以下の4コマンドを1ファイルに対して1セットで実行する必要がある。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git filter-branch --index-filter &apos;git rm --cached --ignore-unmatch test/fixtures/kyk4.csv&apos; HEAD
% git for-each-ref --format=&quot;%(refname)&quot; refs/original/ | xargs -n 1 git update-ref -d
% git reflog expire --expire=now --all
% git gc --prune=now
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>プライバシーポリシー</title><link>https://blog.teraren.com/posts/privacy-policy/</link><guid isPermaLink="true">https://blog.teraren.com/posts/privacy-policy/</guid><description>プライバシーポリシー</description><pubDate>Wed, 01 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;私たちについて&lt;/h2&gt;
&lt;p&gt;私たちのサイトアドレスは https://blog.teraren.com/ です。&lt;/p&gt;
&lt;h2&gt;このサイトが収集する個人データと収集の理由&lt;/h2&gt;
&lt;h3&gt;コメント&lt;/h3&gt;
&lt;p&gt;訪問者がこのサイトにコメントを残す際、GitHub Discussionsを通じてコメントが保存されます。コメントにはGitHubアカウントの情報が使用されます。&lt;/p&gt;
&lt;h3&gt;Cookie&lt;/h3&gt;
&lt;p&gt;このサイトはテーマ設定（ライト/ダークモード）の保持にCookieを使用する場合があります。&lt;/p&gt;
&lt;h3&gt;他サイトからの埋め込みコンテンツ&lt;/h3&gt;
&lt;p&gt;このサイトの投稿には埋め込みコンテンツ (動画、画像、投稿など) が含まれます。他サイトからの埋め込みコンテンツは、訪問者がそのサイトを訪れた場合とまったく同じように振る舞います。&lt;/p&gt;
&lt;p&gt;これらのサイトは、あなたのデータを収集したり、Cookie を使ったり、サードパーティによる追加トラッキングを埋め込んだり、あなたと埋め込みコンテンツとのやりとりを監視したりすることがあります。&lt;/p&gt;
&lt;h3&gt;アナリティクス&lt;/h3&gt;
&lt;p&gt;このサイトではアクセス解析を行う場合があります。&lt;/p&gt;
&lt;h2&gt;データに対するあなたの権利&lt;/h2&gt;
&lt;p&gt;個人データの削除リクエストを行うことができます。管理、法律、セキュリティ目的のために保持する義務があるデータは含まれません。&lt;/p&gt;
</content:encoded></item><item><title>LinuxでWiFiと有線LANのmac addressが同じに見える問題</title><link>https://blog.teraren.com/posts/linux-wifi-ethernet/</link><guid isPermaLink="true">https://blog.teraren.com/posts/linux-wifi-ethernet/</guid><description>LinuxでWiFiと有線LANのMACアドレスが重複して見えARPテーブルが混乱する問題をarp_ignoreとarp_announceで解決した記録</description><pubDate>Sun, 22 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;有線LANと無線LANが搭載されているLinuxにおいて、両方の設定を有効にしていると問題なく通信ができるのに、有線LANを抜くと無線LANも繋がらなくなってしまう問題に遭遇しました。&lt;/p&gt;
&lt;p&gt;こちらに、似たような状態が挙げられています。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://ja.stackoverflow.com/questions/1946/raspberry-pi%E3%81%A7lan%E3%82%B1%E3%83%BC%E3%83%96%E3%83%AB%E3%82%92%E6%8A%9C%E3%81%8F%E3%81%A8wifi%E3%81%8C%E4%BD%BF%E3%81%88%E3%81%AA%E3%81%84&quot;&gt;https://ja.stackoverflow.com/questions/1946/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;確かに、Macアドレスが重複している。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% arp -a
? (192.168.1.16) at f8:bc:12:44:3b:fa on en0 ifscope [ethernet]
? (192.168.1.18) at f8:bc:12:44:3b:fa on en0 ifscope [ethernet]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかしながら、OS側では別のMacアドレスが振られているのに。。。上記の記事を頼りに、以下の設定をしました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /etc# echo 2 &amp;gt; /proc/sys/net/ipv4/conf/all/arp_announce
root@dell /etc# echo 1 &amp;gt; /proc/sys/net/ipv4/conf/all/arp_ignore
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そうしたら、治りました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;? (192.168.1.16) at f8:bc:12:44:3b:fa on en0 ifscope [ethernet]
? (192.168.1.18) at 0:13:ef:f3:21:67 on en0 ifscope [ethernet]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかしながら、当初の問題は解決しませんでした。NetworkManagerと/etc/network/interfacesによる管理が混在しているのが原因かと思いましたが、ethernetの設定をNetworkMangerに一元管理しようとするとエラーが出るので一元管理できません。。。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /etc# nmcli device
DEVICE                   TYPE      STATE      CONNECTION
wlx0013eff32167          wifi      connected  mywifiaccesspoint
br-1983bad34c8e          bridge    unmanaged  --
docker0                  bridge    unmanaged  --
eno1                     ethernet  unmanaged  --
eno2                     ethernet  unmanaged  --
lo                       loopback  unmanaged  --
p2p-dev-wlx0013eff32167  wifi-p2p  unmanaged  --
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;本当はこの記事にあるようにEthernetもNetworkManagerで管理したいのですが、管理できません。&lt;/p&gt;
&lt;p&gt;activateしようとすると以下のエラーが出てきます。ググってもほとんど事例がないです。&lt;/p&gt;
&lt;p&gt;https://www.sejuku.net/blog/57933&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Raspberry-Pi関連の記事ですが、このあたりも参考になる。面倒なので深追いはしない。。。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Could not activate connection: Connection &apos;ethernet-eno1&apos; is not available on device eno1 because device is strictly unmanaged&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;最終的には、&lt;br /&gt;
有線LANと無線LANは同時に固定IPで使ってはダメらしい&lt;br /&gt;
IPを固定にする場合は、iface default inet dhcp はコメントアウト&lt;br /&gt;
ということのようです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://shima-kichi.blogspot.com/2015/09/raspberrypi-lanip.html&quot;&gt;https://shima-kichi.blogspot.com/2015/09/raspberrypi-lanip.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;追記&lt;/h3&gt;
&lt;p&gt;Ubuntu 19.10にアップグレードしたら、nmcliで管理できるようになった様子。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell /e/network# nmcli device
DEVICE           TYPE      STATE        CONNECTION
eno1             ethernet  connected    ethernet-eno1
br-1983bad34c8e  bridge    connected    br-1983bad34c8e
docker0          bridge    connected    docker0
eno2             ethernet  unavailable  --
lo               loopback  unmanaged    --
root@dell /e/network# cat /etc/issue
Ubuntu 19.10 \\n \\l
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Ubuntu 19にてLVMでディスクを追加</title><link>https://blog.teraren.com/posts/lvm-add-disk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/lvm-add-disk/</guid><description>Ubuntu 19に新しいディスクを物理追加した後、fdiskでパーティション作成からpvcreate・vgextend・lvextendまでLVMでの容量拡張手順をコマンド付きで解説します。</description><pubDate>Sat, 21 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;新規にディスクをぶっ刺した上で、OS上で認識されているディスクのラベルを探します&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~/a/storcli_all_os# fdisk -l
Disk /dev/loop0: 54.9 MiB, 57532416 bytes, 112368 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/loop1: 89.1 MiB, 93417472 bytes, 182456 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/loop2: 89.1 MiB, 93429760 bytes, 182480 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/sda: 836.6 GiB, 898319253504 bytes, 1754529792 sectors
Disk model: RAID 5/6 SAS 6G
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: gpt
Disk identifier: A0B1AE4D-C4FF-4FDB-90F1-53AD283B479A

Device       Start        End    Sectors   Size Type
/dev/sda1     2048    1050623    1048576   512M EFI System
/dev/sda2  1050624    2549759    1499136   732M Linux filesystem
/dev/sda3  2549760 1754527743 1751977984 835.4G Linux LVM

Disk /dev/sdb: 1.8 TiB, 1999844147200 bytes, 3905945600 sectors
Disk model: RAID 5/6 SAS 6G
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

Disk /dev/mapper/dell--vg-root: 834.5 GiB, 895974637568 bytes, 1749950464 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

Disk /dev/mapper/dell--vg-swap_1: 976 MiB, 1023410176 bytes, 1998848 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;新しく追加したディスクは、容量から察するに/dev/sdbということがわかります。&lt;code&gt;Disk model: RAID 5/6 SAS 6G&lt;/code&gt;と書いてある理由は謎です。Raid1のはずですが。しかも、OSには隠蔽されているはずなのに。一元的にRaidコントローラが表示してしまっているだけなのかもしれません。&lt;/p&gt;
&lt;p&gt;partedでパーティションを切っておきます。&lt;/p&gt;
&lt;p&gt;パーティション単位ではなく、ディスク自体をPhysical Volumeとして追加できるのですが、ぶっ壊れたときに復元しやすくなる&lt;strong&gt;はず&lt;/strong&gt;なので、パーティションを作ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~/a/storcli_all_os# parted /dev/sdb
GNU Parted 3.2
Using /dev/sdb
Welcome to GNU Parted! Type &apos;help&apos; to view a list of commands.
(parted) mkpart primary 0
Error: /dev/sdb: unrecognised disk label
(parted) help
  align-check TYPE N                        check partition N for TYPE(min|opt) alignment
  help [COMMAND]                           print general help, or help on COMMAND
  mklabel,mktable LABEL-TYPE               create a new disklabel (partition table)
  mkpart PART-TYPE [FS-TYPE] START END     make a partition
  name NUMBER NAME                         name partition NUMBER as NAME
  print [devices|free|list,all|NUMBER]     display the partition table, available devices, free space, all found partitions, or a particular partition
  quit                                     exit program
  rescue START END                         rescue a lost partition near START and END
  resizepart NUMBER END                    resize partition NUMBER
  rm NUMBER                                delete partition NUMBER
  select DEVICE                            choose the device to edit
  disk_set FLAG STATE                      change the FLAG on selected device
  disk_toggle [FLAG]                       toggle the state of FLAG on selected device
  set NUMBER FLAG STATE                    change the FLAG on partition NUMBER
  toggle [NUMBER [FLAG]]                   toggle the state of FLAG on partition NUMBER
  unit UNIT                                set the default unit to UNIT
  version                                  display the version number and copyright information of GNU Parted
(parted)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ubuntu 19で作られるVGはGPT対応で作られているようなので、新しいディスクもGPT対応にしておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(parted) mklabel gpt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;では、パーティションを作成します。パーセントで表記したほうが確実です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(parted) mkpart
Partition name?  []?
File system type?  [ext2]?
Start? 0%
End? 100%
(parted) p
Model: LSI RAID 5/6 SAS 6G (scsi)
Disk /dev/sdb: 1999844MB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start   End        Size       File system  Name  Flags
 1      1.05MB  1999843MB  1999842MB  ext2

(parted)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;物理ディスクは準備できたので、次はLVMの設定。まず、Phisical Volumeを作ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~/a/storcli_all_os# pvcreate /dev/sdb1
WARNING: ext4 signature detected on /dev/sdb1 at offset 1080. Wipe it? [y/n]: y
  Wiping ext4 signature on /dev/sdb1.
  Physical volume &quot;/dev/sdb1&quot; successfully created.
root@dell ~/a/storcli_all_os# pvs
  PV         VG      Fmt  Attr PSize    PFree
  /dev/sda3  dell-vg lvm2 a--  &amp;lt;835.41g 12.00m
  /dev/sdb1          lvm2 ---    &amp;lt;1.82t &amp;lt;1.82t
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、Logical Volumeを作ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~/a/storcli_all_os# vgcreate data-vg /dev/sdb1
  Volume group &quot;data-vg&quot; successfully created
root@dell ~/a/storcli_all_os# vgdisplay
  --- Volume group ---
  VG Name               dell-vg
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  3
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                2
  Open LV               2
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               &amp;lt;835.41 GiB
  PE Size               4.00 MiB
  Total PE              213864
  Alloc PE / Size       213861 / 835.39 GiB
  Free  PE / Size       3 / 12.00 MiB
  VG UUID               jqTTRM-hZOZ-uT9x-9ke5-bAuw-78dI-RI3xZf

  --- Volume group ---
  VG Name               data-vg
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               &amp;lt;1.82 TiB
  PE Size               4.00 MiB
  Total PE              476799
  Alloc PE / Size       0 / 0
  Free  PE / Size       476799 / &amp;lt;1.82 TiB
  VG UUID               NUtldx-SilL-6GHG-9eAZ-5rdN-oPxr-6XlhmK
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Logical Volumeを作ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# lvcreate -n data -l 100%FREE data-vg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、フォーマット。他のパーティションがext4なので、それに続きます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~/a/storcli_all_os# mkfs.ext4 /dev/data-vg/data
mke2fs 1.44.6 (5-Mar-2019)
Creating filesystem with 488242176 4k blocks and 122060800 inodes
Filesystem UUID: eb6cb760-73e3-4fd0-8453-66383c3ac4b9
Superblock backups stored on blocks:
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
	4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968,
	102400000, 214990848

Allocating group tables: done
Writing inode tables: done
Creating journal (262144 blocks): done
Writing superblocks and filesystem accounting information: done

root@dell ~/a/storcli_all_os# mkdir /mnt/data
root@dell ~/a/storcli_all_os# mount /dev/data-vg/data /mnt/data
root@dell ~/a/storcli_all_os# df -h|grep data
/dev/mapper/data--vg-data  1.8T   77M  1.7T   1% /mnt/data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一応ベンチマーク。SATAのraid10がdata。SASのRaid5 2台に比べると4倍くらい遅い。SATA遅すぎ。デスクトップワークステーションを買うならSASがよさげ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~# hdparm -t /dev/mapper/data--vg-data

/dev/mapper/data--vg-data:
SG_IO: bad/missing sense data, sb[]:  70 00 05 00 00 00 00 0d 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 Timing buffered disk reads: 684 MB in  3.00 seconds = 227.99 MB/sec

root@dell ~# hdparm -t /dev/mapper/dell--vg-root

/dev/mapper/dell--vg-root:
SG_IO: bad/missing sense data, sb[]:  70 00 05 00 00 00 00 0d 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 Timing buffered disk reads: 1636 MB in  3.00 seconds = 545.06 MB/sec
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;独り言&lt;/h3&gt;
&lt;p&gt;物理ハードディスクから、OSでディスクを扱うまでに抽象化がたくさん入っていて設定が面倒！昔は物理ディスクをそのままマウントしていたのに。そのぶん、自由度は高いですがね。まとめると以下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;物理ディスク&lt;/li&gt;
&lt;li&gt;Raidコントローラによる物理ディスクの仮想化&lt;/li&gt;
&lt;li&gt;OSのPhysical Volumeを使った仮想化&lt;/li&gt;
&lt;li&gt;OSのLogical Volumeを使った仮想化&lt;/li&gt;
&lt;li&gt;OSによるLogical Volumeのマウント&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Raid1のディスクを抜いて挿してみる</title><link>https://blog.teraren.com/posts/raid1-hot-remove-add/</link><guid isPermaLink="true">https://blog.teraren.com/posts/raid1-hot-remove-add/</guid><description>MegaRAID環境でRAID1のディスクをホットリムーブ・ホットアドした際の挙動を検証。抜いて挿したドライブがUnconfigured Badになる動作を確認した実録</description><pubDate>Sat, 21 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;結論&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;抜いたドライブは**Unconfigured Bad (UBad)**になる。同じディスクを同じスロットに挿し直しても自動的には元に戻らない&lt;/li&gt;
&lt;li&gt;&lt;code&gt;set good&lt;/code&gt; → &lt;code&gt;foreign import&lt;/code&gt; の手順でリビルドが開始される&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;検証環境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;RAIDコントローラ: RAID Ctrl SAS 6G 5/6 512MB (D2616)&lt;/li&gt;
&lt;li&gt;管理ツール: storcli64&lt;/li&gt;
&lt;li&gt;構成: DG0 = RAID5 (SAS × 4)、DG1 = RAID1 (SATA × 2)&lt;/li&gt;
&lt;li&gt;検証対象: DG1のRAID1ミラーの片方 (slot 5)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;手順&lt;/h2&gt;
&lt;h3&gt;1. ディスクを抜いて挿した後の状態確認&lt;/h3&gt;
&lt;p&gt;抜いて挿したドライブは、Unconfigured Badになっている。同じディスクが挿されたとしても、もとには戻らない。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~# /opt/MegaRAID/storcli/storcli64 /c0 show
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Generating detailed summary of the adapter, it may take a while to complete.

Controller = 0
Status = Success
Description = None

Product Name = RAID Ctrl SAS 6G 5/6 512MB (D2616)
Serial Number =
SAS Address =  50030057013af4c0
PCI Address = 00:08:00:00
System Time = 12/21/2019 23:37:35
Mfg. Date = 00/00/00
Controller Time = 12/21/2019 14:37:35
FW Package Build = 12.12.0-0174
FW Version = 2.130.353-2727
BIOS Version = 3.29.00_4.14.05.00_0x06000500
Driver Name = megaraid_sas
Driver Version = 07.707.50.00-rc1
Vendor Id = 0x1000
Device Id = 0x79
SubVendor Id = 0x1734
SubDevice Id = 0x1176
Host Interface = PCIE
Device Interface = SAS-6G
Bus Number = 8
Device Number = 0
Function Number = 0
Drive Groups = 2

TOPOLOGY :
========

--------------------------------------------------------------------------
DG Arr Row EID:Slot DID Type  State BT       Size PDC  PI SED DS3  FSpace
--------------------------------------------------------------------------
 0 -   -   -        -   RAID5 Optl  N  836.625 GB dsbl N  N   none N
 0 0   -   -        -   RAID5 Optl  N  836.625 GB dsbl N  N   none N
 0 0   0   252:0    6   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   1   252:1    5   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   2   252:2    7   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   3   252:3    4   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 1 -   -   -        -   RAID1 Dgrd  N    1.818 TB dflt N  N   none N
 1 0   -   -        -   RAID1 Dgrd  N    1.818 TB dflt N  N   none N
 1 0   0   252:4    8   DRIVE Onln  N    1.818 TB dflt N  N   none -
 1 0   1   -        -   DRIVE Msng  -    1.818 TB -    -  -   -    -
--------------------------------------------------------------------------

DG=Disk Group Index|Arr=Array Index|Row=Row Index|EID=Enclosure Device ID
DID=Device ID|Type=Drive Type|Onln=Online|Rbld=Rebuild|Dgrd=Degraded
Pdgd=Partially degraded|Offln=Offline|BT=Background Task Active
PDC=PD Cache|PI=Protection Info|SED=Self Encrypting Drive|Frgn=Foreign
DS3=Dimmer Switch 3|dflt=Default|Msng=Missing|FSpace=Free Space Present

Missing Drives Count = 1

Missing Drives :
==============

-------------------
Array Row     Size
-------------------
    1   1 1.818 TB
-------------------

Virtual Drives = 2

VD LIST :
=======

-----------------------------------------------------------
DG/VD TYPE  State Access Consist Cache sCC       Size Name
-----------------------------------------------------------
0/0   RAID5 Optl  RW     Yes     NRWTD -   836.625 GB
1/1   RAID1 Dgrd  RW     No      RWTD  -     1.818 TB
-----------------------------------------------------------

Cac=CacheCade|Rec=Recovery|OfLn=OffLine|Pdgd=Partially Degraded|dgrd=Degraded
Optl=Optimal|RO=Read Only|RW=Read Write|HD=Hidden|B=Blocked|Consist=Consistent|
R=Read Ahead Always|NR=No Read Ahead|WB=WriteBack|
AWB=Always WriteBack|WT=WriteThrough|C=Cached IO|D=Direct IO|sCC=Scheduled
Check Consistency

Physical Drives = 6

PD LIST :
=======

-----------------------------------------------------------------------------
EID:Slt DID State DG       Size Intf Med SED PI SeSz Model                Sp
-----------------------------------------------------------------------------
252:0     6 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:1     5 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:2     7 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:3     4 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:4     8 Onln   1   1.818 TB SATA HDD N   N  512B WDC WD20EZRX-00DC0B0 U
252:5     9 UBad   F   1.818 TB SATA HDD N   N  512B WDC WD20EARX-00PASB0 U
-----------------------------------------------------------------------------

EID-Enclosure Device ID|Slt-Slot No.|DID-Device ID|DG-DriveGroup
DHS-Dedicated Hot Spare|UGood-Unconfigured Good|GHS-Global Hotspare
UBad-Unconfigured Bad|Onln-Online|Offln-Offline|Intf-Interface
Med-Media Type|SED-Self Encryptive Drive|PI-Protection Info
SeSz-Sector Size|Sp-Spun|U-Up|D-Down|T-Transition|F-Foreign
UGUnsp-Unsupported|UGShld-UnConfigured shielded|HSPShld-Hotspare shielded
CFShld-Configured shielded|Cpybck-CopyBack|CBShld-Copyback Shielded
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. UBadをUGoodに変更する&lt;/h3&gt;
&lt;p&gt;ドライブの状態をUnconfigured Goodに変更する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~# /opt/MegaRAID/storcli/storcli64 /c0/e252/s5 set good
Controller = 0
Status = Success
Description = Set Drive Good Succeeded.
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. UGoodになったことを確認する&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~# /opt/MegaRAID/storcli/storcli64 /c0 show
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Generating detailed summary of the adapter, it may take a while to complete.

Controller = 0
Status = Success
Description = None

Product Name = RAID Ctrl SAS 6G 5/6 512MB (D2616)
Serial Number =
SAS Address =  50030057013af4c0
PCI Address = 00:08:00:00
System Time = 12/21/2019 23:40:50
Mfg. Date = 00/00/00
Controller Time = 12/21/2019 14:40:50
FW Package Build = 12.12.0-0174
FW Version = 2.130.353-2727
BIOS Version = 3.29.00_4.14.05.00_0x06000500
Driver Name = megaraid_sas
Driver Version = 07.707.50.00-rc1
Vendor Id = 0x1000
Device Id = 0x79
SubVendor Id = 0x1734
SubDevice Id = 0x1176
Host Interface = PCIE
Device Interface = SAS-6G
Bus Number = 8
Device Number = 0
Function Number = 0

FOREIGN CONFIGURATION :
=====================

---------------------------------------
DG EID:Slot Type  State     Size NoVDs
---------------------------------------
 0 -        RAID1 Frgn  1.818 TB     1
---------------------------------------

NoVDs - Number of VDs in disk group|DG - Diskgroup
Total foreign drive groups = 1
Drive Groups = 2

TOPOLOGY :
========

--------------------------------------------------------------------------
DG Arr Row EID:Slot DID Type  State BT       Size PDC  PI SED DS3  FSpace
--------------------------------------------------------------------------
 0 -   -   -        -   RAID5 Optl  N  836.625 GB dsbl N  N   none N
 0 0   -   -        -   RAID5 Optl  N  836.625 GB dsbl N  N   none N
 0 0   0   252:0    6   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   1   252:1    5   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   2   252:2    7   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   3   252:3    4   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 1 -   -   -        -   RAID1 Dgrd  N    1.818 TB dflt N  N   none N
 1 0   -   -        -   RAID1 Dgrd  N    1.818 TB dflt N  N   none N
 1 0   0   252:4    8   DRIVE Onln  N    1.818 TB dflt N  N   none -
 1 0   1   -        -   DRIVE Msng  -    1.818 TB -    -  -   -    -
--------------------------------------------------------------------------

DG=Disk Group Index|Arr=Array Index|Row=Row Index|EID=Enclosure Device ID
DID=Device ID|Type=Drive Type|Onln=Online|Rbld=Rebuild|Dgrd=Degraded
Pdgd=Partially degraded|Offln=Offline|BT=Background Task Active
PDC=PD Cache|PI=Protection Info|SED=Self Encrypting Drive|Frgn=Foreign
DS3=Dimmer Switch 3|dflt=Default|Msng=Missing|FSpace=Free Space Present

Missing Drives Count = 1

Missing Drives :
==============

-------------------
Array Row     Size
-------------------
    1   1 1.818 TB
-------------------

Virtual Drives = 2

VD LIST :
=======

-----------------------------------------------------------
DG/VD TYPE  State Access Consist Cache sCC       Size Name
-----------------------------------------------------------
0/0   RAID5 Optl  RW     Yes     NRWTD -   836.625 GB
1/1   RAID1 Dgrd  RW     No      RWTD  -     1.818 TB
-----------------------------------------------------------

Cac=CacheCade|Rec=Recovery|OfLn=OffLine|Pdgd=Partially Degraded|dgrd=Degraded
Optl=Optimal|RO=Read Only|RW=Read Write|HD=Hidden|B=Blocked|Consist=Consistent|
R=Read Ahead Always|NR=No Read Ahead|WB=WriteBack|
AWB=Always WriteBack|WT=WriteThrough|C=Cached IO|D=Direct IO|sCC=Scheduled
Check Consistency

Physical Drives = 6

PD LIST :
=======

-----------------------------------------------------------------------------
EID:Slt DID State DG       Size Intf Med SED PI SeSz Model                Sp
-----------------------------------------------------------------------------
252:0     6 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:1     5 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:2     7 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:3     4 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:4     8 Onln   1   1.818 TB SATA HDD N   N  512B WDC WD20EZRX-00DC0B0 U
252:5     9 UGood  F   1.818 TB SATA HDD N   N  512B WDC WD20EARX-00PASB0 U
-----------------------------------------------------------------------------

EID-Enclosure Device ID|Slt-Slot No.|DID-Device ID|DG-DriveGroup
DHS-Dedicated Hot Spare|UGood-Unconfigured Good|GHS-Global Hotspare
UBad-Unconfigured Bad|Onln-Online|Offln-Offline|Intf-Interface
Med-Media Type|SED-Self Encryptive Drive|PI-Protection Info
SeSz-Sector Size|Sp-Spun|U-Up|D-Down|T-Transition|F-Foreign
UGUnsp-Unsupported|UGShld-UnConfigured shielded|HSPShld-Hotspare shielded
CFShld-Configured shielded|Cpybck-CopyBack|CBShld-Copyback Shielded
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. Foreign Configurationをインポートする&lt;/h3&gt;
&lt;p&gt;同じスロットに同じHDDを挿し直しただけなので、同じRAIDのボリュームに再度構成し直すだけ。RAID自体には変更を加えずに元に戻すコマンドを送る。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~# /opt/MegaRAID/storcli/storcli64 /c0 /fall import
Controller = 0
Status = Success
Description = Successfully imported foreign configuration
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;5. リビルド状態を確認する&lt;/h3&gt;
&lt;p&gt;Rebuildになっているかステータスを確認。予想完了時間は表示されなかった。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~# /opt/MegaRAID/storcli/storcli64 /c0 /e252 /s5 show rebuild
Controller = 0
Status = Success
Description = Show Drive Rebuild Status Succeeded.

------------------------------------------------------
Drive-ID    Progress% Status      Estimated Time Left
------------------------------------------------------
/c0/e252/s5         4 In progress -
------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;MegaRAID環境でRAID1のディスクをホットリムーブ→ホットアドした場合の復旧手順:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;storcli64 /c0/e252/s5 set good&lt;/code&gt; — UBad → UGoodに変更&lt;/li&gt;
&lt;li&gt;&lt;code&gt;storcli64 /c0 /fall import&lt;/code&gt; — Foreign Configurationをインポート&lt;/li&gt;
&lt;li&gt;&lt;code&gt;storcli64 /c0/e252/s5 show rebuild&lt;/code&gt; — リビルド進捗を確認&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;同じディスクを同じスロットに戻しても自動復旧はしないので、手動での操作が必要。&lt;/p&gt;
</content:encoded></item><item><title>Symbios Logic MegaRAID SAS 2108をOSから管理</title><link>https://blog.teraren.com/posts/symbios-logic-megaraid-sas-2108-ubuntu/</link><guid isPermaLink="true">https://blog.teraren.com/posts/symbios-logic-megaraid-sas-2108-ubuntu/</guid><description>Dell PowerEdgeに搭載されたLSI MegaRAID SAS 2108をStorCLIツールでUbuntuから操作し、RAIDコントローラをOS上で管理するセットアップ手順を解説します。</description><pubDate>Sat, 21 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;初期セットアップはBIOSからRaidコントローラの管理画面に入って、仮想ドライブを追加したりしていましたが運用するにあたって毎回OSを再起動したり、ディスクの初期化をするために再起動していたら大変なのでアプリケーションからRAIDコントローラを制御できるようにします。&lt;/p&gt;
&lt;p&gt;ハードウェアはDell PowerEdge T320&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; lspci |grep -i raid
08:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS 2108 [Liberator] (rev 05)
matsu@dell ~&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下から、1-15-05_StorCLI.zipをダウンロード。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.broadcom.com/docs/12354804&quot;&gt;https://docs.broadcom.com/docs/12354804&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;解凍してインストール。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~/a/storcli_all_os&amp;gt; sudo dpkg -i ./Ubuntu/storcli_1.15.05_all.deb
Selecting previously unselected package storcli.
(Reading database ... 85223 files and directories currently installed.)
Preparing to unpack .../Ubuntu/storcli_1.15.05_all.deb ...
Unpacking storcli (1.15.05) ...
Setting up storcli (1.15.05) ...
matsu@dell ~/a/storcli_all_os&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;/optにインストールされるので実行してみる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~/a/storcli_all_os# /opt/MegaRAID/storcli/storcli64 show
Status Code = 0
Status = Success
Description = None

Number of Controllers = 1
Host Name = dell
Operating System  = Linux5.0.0-37-generic

System Overview :
===============

------------------------------------------------------------------------------------------
Ctl Model                        Ports PDs DGs DNOpt VDs VNOpt BBU  sPR DS  EHS ASOs Hlth
------------------------------------------------------------------------------------------
  0 RAIDCtrlSAS6G5/6512MB(D2616)     8   6   2     0   2     0 Msng On  1&amp;amp;2 N      3 Opt
------------------------------------------------------------------------------------------

Ctl=Controller Index|DGs=Drive groups|VDs=Virtual drives|Fld=Failed
PDs=Physical drives|DNOpt=DG NotOptimal|VNOpt=VD NotOptimal|Opt=Optimal
Msng=Missing|Dgd=Degraded|NdAtn=Need Attention|Unkwn=Unknown
sPR=Scheduled Patrol Read|DS=DimmerSwitch|EHS=Emergency Hot Spare
Y=Yes|N=No|ASOs=Advanced Software Options|BBU=Battery backup unit
Hlth=Health|Safe=Safe-mode boot

root@dell ~/a/storcli_all_os#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;詳細を表示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@dell ~/a/storcli_all_os# /opt/MegaRAID/storcli/storcli64 /c0 show
Generating detailed summary of the adapter, it may take a while to complete.

Controller = 0
Status = Success
Description = None

Product Name = RAID Ctrl SAS 6G 5/6 512MB (D2616)
Serial Number =
SAS Address =  50030057013af4c0
PCI Address = 00:08:00:00
System Time = 12/21/2019 19:55:38
Mfg. Date = 00/00/00
Controller Time = 12/21/2019 10:55:39
FW Package Build = 12.12.0-0174
FW Version = 2.130.353-2727
BIOS Version = 3.29.00_4.14.05.00_0x06000500
Driver Name = megaraid_sas
Driver Version = 07.707.50.00-rc1
Vendor Id = 0x1000
Device Id = 0x79
SubVendor Id = 0x1734
SubDevice Id = 0x1176
Host Interface = PCIE
Device Interface = SAS-6G
Bus Number = 8
Device Number = 0
Function Number = 0
Drive Groups = 2

TOPOLOGY :
========

--------------------------------------------------------------------------
DG Arr Row EID:Slot DID Type  State BT       Size PDC  PI SED DS3  FSpace
--------------------------------------------------------------------------
 0 -   -   -        -   RAID5 Optl  N  836.625 GB dsbl N  N   none N
 0 0   -   -        -   RAID5 Optl  N  836.625 GB dsbl N  N   none N
 0 0   0   252:0    6   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   1   252:1    5   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   2   252:2    7   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 0 0   3   252:3    4   DRIVE Onln  N  278.875 GB dsbl N  N   none -
 1 -   -   -        -   RAID1 Optl  Y    1.818 TB dflt N  N   none N
 1 0   -   -        -   RAID1 Optl  Y    1.818 TB dflt N  N   none N
 1 0   0   252:4    8   DRIVE Onln  N    1.818 TB dflt N  N   none -
 1 0   1   252:5    9   DRIVE Onln  N    1.818 TB dflt N  N   none -
--------------------------------------------------------------------------

DG=Disk Group Index|Arr=Array Index|Row=Row Index|EID=Enclosure Device ID
DID=Device ID|Type=Drive Type|Onln=Online|Rbld=Rebuild|Dgrd=Degraded
Pdgd=Partially degraded|Offln=Offline|BT=Background Task Active
PDC=PD Cache|PI=Protection Info|SED=Self Encrypting Drive|Frgn=Foreign
DS3=Dimmer Switch 3|dflt=Default|Msng=Missing|FSpace=Free Space Present

Virtual Drives = 2

VD LIST :
=======

-----------------------------------------------------------
DG/VD TYPE  State Access Consist Cache sCC       Size Name
-----------------------------------------------------------
0/0   RAID5 Optl  RW     Yes     NRWTD -   836.625 GB
1/1   RAID1 Optl  RW     No      RWTD  -     1.818 TB
-----------------------------------------------------------

Cac=CacheCade|Rec=Recovery|OfLn=OffLine|Pdgd=Partially Degraded|dgrd=Degraded
Optl=Optimal|RO=Read Only|RW=Read Write|HD=Hidden|B=Blocked|Consist=Consistent|
R=Read Ahead Always|NR=No Read Ahead|WB=WriteBack|
AWB=Always WriteBack|WT=WriteThrough|C=Cached IO|D=Direct IO|sCC=Scheduled
Check Consistency

Physical Drives = 6

PD LIST :
=======

-----------------------------------------------------------------------------
EID:Slt DID State DG       Size Intf Med SED PI SeSz Model                Sp
-----------------------------------------------------------------------------
252:0     6 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:1     5 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:2     7 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:3     4 Onln   0 278.875 GB SAS  HDD N   N  512B HUS156030VLS600      U
252:4     8 Onln   1   1.818 TB SATA HDD N   N  512B WDC WD20EZRX-00DC0B0 U
252:5     9 Onln   1   1.818 TB SATA HDD N   N  512B WDC WD20EARX-00PASB0 U
-----------------------------------------------------------------------------

EID-Enclosure Device ID|Slt-Slot No.|DID-Device ID|DG-DriveGroup
DHS-Dedicated Hot Spare|UGood-Unconfigured Good|GHS-Global Hotspare
UBad-Unconfigured Bad|Onln-Online|Offln-Offline|Intf-Interface
Med-Media Type|SED-Self Encryptive Drive|PI-Protection Info
SeSz-Sector Size|Sp-Spun|U-Up|D-Down|T-Transition|F-Foreign
UGUnsp-Unsupported|UGShld-UnConfigured shielded|HSPShld-Hotspare shielded
CFShld-Configured shielded|Cpybck-CopyBack|CBShld-Copyback Shielded
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;現時点では、Raid5が4台。Raid1が2台ある状態です。後日、Raid1の方にもう1台ディスクをオンライン状態で追加してみようと思います。&lt;/p&gt;
</content:encoded></item><item><title>Ubuntu 19.04でrtl88x2buをインストール</title><link>https://blog.teraren.com/posts/ubuntu-19-04-rtl88x2bu/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ubuntu-19-04-rtl88x2bu/</guid><description>Ubuntu 19.04のLinuxサーバにRealtek RTL88x2BU搭載USB WiFiアダプタのドライバをgitから取得しコンパイルしてインストールする手順</description><pubDate>Mon, 16 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;最近買ったPC LinuxサーバにWiFi子機をインストールします。&lt;/li&gt;
&lt;li&gt;本来は有線でつないでおきたいのですが、筐体が大きくて邪魔なので無線にして部屋の奥底へ設置しようと思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B0816BY59L&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/3664B077-F6F4-4690-B13E-E88B2ACFE2D7_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;事前準備&lt;/h2&gt;
&lt;p&gt;下調べ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@dell ~&amp;gt; cat /etc/issue
Ubuntu 19.04 \n \l

matsu@dell ~&amp;gt; uname -a
Linux dell 5.0.0-37-generic #40-Ubuntu SMP Thu Nov 14 00:14:01 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この製品、Realtekのチップが乗っています。CD-ROMがついてくるので、その中にもドライバはありますが、最新のものを使いたいのでgitから落としてくることにします。&lt;/p&gt;
&lt;p&gt;とりあえず、ドライバをコンパイルするためにコンパイラを入れておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get install build-essential git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そしてコンパイル&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/its-izhar/rtl88x2bu-driver
cd rtl88x2bu-driver
make clean
make -j8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかし、2箇所でエラーがでます。LinuxのKernelが5にあがってAPIが変わった様子。以下を修正すれば通ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --git a/os_dep/linux/ioctl_cfg80211.c b/os_dep/linux/ioctl_cfg80211.c
index e7e8930..a2c2e6a 100644
--- a/os_dep/linux/ioctl_cfg80211.c
+++ b/os_dep/linux/ioctl_cfg80211.c
@@ -687,8 +687,9 @@ static int rtw_cfg80211_sync_iftype(_adapter *adapter)
 static u64 rtw_get_systime_us(void)
 {
 #if (LINUX_VERSION_CODE &amp;gt;= KERNEL_VERSION(2, 6, 39))
-       struct timespec ts;
-       get_monotonic_boottime(&amp;amp;ts);
+               struct timespec64 ts;
+       ktime_get_boottime_ts64(&amp;amp;ts);
+
        return ((u64)ts.tv_sec * 1000000) + ts.tv_nsec / 1000;
 #else
        struct timeval tv;
diff --git a/os_dep/linux/rtw_android.c b/os_dep/linux/rtw_android.c
index b8b4377..2e4bb31 100644
--- a/os_dep/linux/rtw_android.c
+++ b/os_dep/linux/rtw_android.c
@@ -657,7 +657,7 @@ int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
                goto exit;
        }

-       if (!access_ok(VERIFY_READ, priv_cmd.buf, priv_cmd.total_len)) {
+       if (!access_ok(priv_cmd.buf, priv_cmd.total_len)) {
                RTW_INFO(&quot;%s: failed to access memory\\n&quot;, __FUNCTION__);
                ret = -EFAULT;
                goto exit;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;成功したら、モジュールのインストール。（裏では、installコマンドと modprobeを行っている）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そうすると、認識されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wlx0013eff32167: flags=4099&amp;lt;UP,BROADCAST,MULTICAST&amp;gt;  mtu 1500
        ether 00:13:ef:f3:21:67  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WiFiのアクセスポイントが見えるかを確認してみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そしたら、以下のコマンドで設定。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% nmcli device wifi connect &apos;your ssid&apos; password &apos;your wifi password&apos; ifname wlx0013eff32167
% ifconfig
wlx0013eff32167: flags=4163&amp;lt;UP,BROADCAST,RUNNING,MULTICAST&amp;gt;  mtu 1500
        inet 192.168.1.122  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 240b:10:2120:f400:314b:995:833f:abcd  prefixlen 64  scopeid 0x0&amp;lt;global&amp;gt;
        inet6 240b:10:2120:f400:f93f:c66f:26ff:efgh  prefixlen 64  scopeid 0x0&amp;lt;global&amp;gt;
        inet6 fe80::39cd:14fe:54e1:2d72  prefixlen 64  scopeid 0x20&amp;lt;link&amp;gt;
        ether 00:13:ef:f3:21:67  txqueuelen 1000  (Ethernet)
        RX packets 1978  bytes 559674 (559.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 56  bytes 8113 (8.1 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有線LANを抜いて疎通確認すればOK。&lt;/p&gt;
&lt;h2&gt;WiFiで固定IPを振る場合&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://vega.pgw.jp/~kabe/linux/c7-nm-wifi.html&quot;&gt;このページ&lt;/a&gt;を参考にした。WiFiの設定はNetworkManagerが管理しているようなので、そっちで行う。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;最後に再起動をして、ちゃんとネットワークがつながるかを確認しておく。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Ubuntu 19.10の場合&lt;/h2&gt;
&lt;p&gt;こちらのレポジトリのドライバを使う。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/RinCat/RTL88x2BU-Linux-Driver&quot;&gt;https://github.com/RinCat/RTL88x2BU-Linux-Driver&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>広告をネットワークレイヤでブロックするPi-holeを動かしてみた</title><link>https://blog.teraren.com/posts/pi-hole/</link><guid isPermaLink="true">https://blog.teraren.com/posts/pi-hole/</guid><description>DNSブラックリストで広告をネットワーク全体でブロックするPi-holeをDockerで構築する方法と、Ubuntu環境でのポート競合回避など実際のセットアップ手順を紹介します。</description><pubDate>Sun, 08 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ネットワークレベルで広告をブロックするという&lt;a href=&quot;https://pi-hole.net/&quot;&gt;Pi-hole&lt;/a&gt;を動かしてみました。&lt;/li&gt;
&lt;li&gt;どういうアーキテクチャでブロックしているのかすごい気になっていました。普通はE2Eで暗号化されているのでネットワークにPi-holeを設置したところでどうやって防ぐのかと。。。&lt;/li&gt;
&lt;li&gt;まぁ、意外と仕組みは簡単で、Pi-holeがホスト名の広告サーバリストをブラックリストとして保管していて、ウェブブラウザを行う端末のDNSリゾルバをPi-holeのホストに向けることで広告コンテンツの配信をブロックします。これにより、各自がブラウザでad blockerを入れなくても対処できます。会社で言えば、一元的にブラックリストを管理できるという利点がありそうですが、マーケティング関係者や制作関係者にとっては困ります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;名前にPiと書いてあるからRaspberry-Piで動かすために作られたソフトウェアのようです。&lt;/li&gt;
&lt;li&gt;Dockerコンテナですぐに起動できるイメージがあるので動かしてみました。&lt;/li&gt;
&lt;li&gt;docker-composeのサンプルがありますが、そのままだと動かないので少し改変しました。&lt;/li&gt;
&lt;li&gt;また、Ubuntuにはdns-resolverがすでに53番ポートでlistenしているので止める必要があります。それには再起動も必要なので面倒でした。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% wget https://gist.githubusercontent.com/matsubo/ff8ad2857ad5ae84ea74d51f946330cc/raw/d8f281aff30ff21a5ee8b2df940fd00fa6b8459a/docker-compose.yml
% docker-compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初回の起動時は、ブラックリストとなるホスト名をダウンロードするので2分ぐらいかかります。&lt;/p&gt;
&lt;p&gt;起動したら、UDP 53番ポートがListenしているしていることを確認して、ネットワーク上のホストのDNSリゾルバを向けてあげれば使えます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;画面が見えます。&lt;/p&gt;
&lt;h2&gt;実験&lt;/h2&gt;
&lt;h3&gt;その1&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/Screen-Shot-2019-12-08-at-1.05.46.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pi-hole使用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/Screen-Shot-2019-12-08-at-1.06.21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pi-hole未使用&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;あんまり変わりません。右上のトラッカーとかが無くなっています。&lt;/p&gt;
&lt;h3&gt;その2&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/Screen-Shot-2019-12-08-at-1.07.01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pi-hole使用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/Screen-Shot-2019-12-08-at-1.07.20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pi-hole未使用&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ホスト名レベルでのブロックなので、画像配信サーバがブラックリストにある様子です。&lt;/p&gt;
&lt;p&gt;（それにしても世の中の広告は卑猥な広告か、ゲームばかりです。普段はAdBlockを使っているので目していませんでしたが、広告面の大きさすごいでかい。）&lt;/p&gt;
&lt;h3&gt;管理画面&lt;/h3&gt;
&lt;p&gt;http でアクセスすると管理が見えます。なぜかIPv6のインターフェイスでしかListenしてくれませんでした。設定的にはIPv4もListenするはずなんですが。テストの利用なのでとりあえず先に進めます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/Screen-Shot-2019-12-08-at-2.07.37.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;いろいろな統計情報が出ます&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/Screen-Shot-2019-12-08-at-2.07.40.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;AとAAAAが半分くらい&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/Screen-Shot-2019-12-08-at-2.07.51.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ホスト名ごとの統計&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/12/Screen-Shot-2019-12-08-at-1.58.35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;個別にブラックリストに入れられたりする&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;今すぐPi-holeを使ってみる！&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;なんと、Pi-holeをpublicに運用している人が居ます。自分のDNSリゾルバを変更するだけですぐに試せちゃいます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://public-pihole.com/&quot;&gt;https://public-pihole.com/&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Netherland&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;51.158.168.202&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;France&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;54.39.97.51&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Canada&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;54.39.97.51&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Singapore&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;139.99.74.182&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;一定の効果はありそう。もし、問題が起きたときでも簡単にWebから設定を確認、変更できそうなので良いです。&lt;/li&gt;
&lt;li&gt;外出先からも自分の運用するPi-holeを利用するためにはVPNで自宅に接続する状態にするか、publicにPi-holeを置く感じの運用になりそう。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Raspberry Piで24時間録音機</title><link>https://blog.teraren.com/posts/raspberry-pi-audio-recording/</link><guid isPermaLink="true">https://blog.teraren.com/posts/raspberry-pi-audio-recording/</guid><description>Raspberry Piとarecord+lameでいびき・寝言を24時間MP3録音する方法。systemdでデーモン化して自動起動する設定手順も解説。</description><pubDate>Thu, 05 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;いびきの録音、寝言の録音に使えるかなと。&lt;/li&gt;
&lt;li&gt;こちらと同じハードウェア構成です
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/motion-on-raspberry-pi/&quot;&gt;/posts/motion-on-raspberry-pi/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定内容&lt;/h2&gt;
&lt;p&gt;録音には、arecordというlinuxにあるパッケージを使います。そのままだと音声データは無圧縮のwaveで出力されます。データ量が膨大になるので圧縮するためにlameでMP3に変換します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt update
# apt install arecord lame
# vi /var/audio/mic.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Waveで保存の場合は1時間ごとに1ファイルができるような設定にしています。&lt;/p&gt;
&lt;p&gt;音声データのストリームをパイプでlameに渡して、MP3に圧縮する。&lt;/p&gt;
&lt;p&gt;その場合はファイルを分割できない連続録音です。&lt;/p&gt;
&lt;p&gt;以下は起動用のシェルスクリプトです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh

# wav
# arecord -f cd -D hw:1,0 -r 16000 -t wav --max-file-time 3600 --use-strftime /var/audio/mic-%Y%m%d-%H%M%v.wav

# mp3
arecord -f cd -D hw:1,0 -t wav | lame -b 256 -m s - /var/audio/mic-`date +&quot;%Y%m%d-%H%M%s&quot;`.mp3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;systemctlでデーモン化しておきます。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/systemd/system/mic.service&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description = audio recording daemon

[Service]
ExecStart = /var/audio/mic.sh
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# chmod 755 /var/audio/mic.sh
# systemctl enable mic
# systemctl start mic
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しばらく運用しているとMP3ファイルが152MB（約1.5時間分）で不定期にファイルが分割されて保存されていました。&lt;br /&gt;
arecordデーモンが勝手に再起動しているようです。&lt;br /&gt;
syslogには吐かれていないので原因はよくわかりません。&lt;/p&gt;
&lt;p&gt;256kbpsでのエンコードでは、1日で2.5GBになります。結構大きくなりました。高品質なので仕方が無いです。&lt;/p&gt;
&lt;p&gt;高品質な音楽ぐらいのビットレートなのでただの音声であれば64kbpsとか32kbpsでも十分かと思いますので1/4か1/8ぐらいになります。&lt;/p&gt;
</content:encoded></item><item><title>Raspberry Piで動体検知録画</title><link>https://blog.teraren.com/posts/motion-on-raspberry-pi/</link><guid isPermaLink="true">https://blog.teraren.com/posts/motion-on-raspberry-pi/</guid><description>Raspberry Pi 4とUSBカメラを使ってmotionで動体検知録画システムを構築する手順。発熱対策やカメラデバイスの設定方法も含めて解説</description><pubDate>Wed, 04 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Raspberry Pi 4を買ったので遊んでみます。&lt;/li&gt;
&lt;li&gt;CPUのスペックが高いので結構発熱します。何もしていない状態でも55度ぐらいあります。冬なのに。&lt;/li&gt;
&lt;li&gt;動画処理にはそこそこCPUを使うようなので各ICチップにヒートシンクを付けたり、ファンを付けたりして熱で傷まないように対策をしておいたほうが良いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;ラズパイ４はパフォーマンスが大幅に向上した代わりに、非常に高温の熱を発します。熱を発したままでは火傷などのリスクがあるほか、チップ本来のパフォーマンスを出すことができません。ファンやヒートシンクなどの熱対策が必須となります。またPoE HATなども有効です。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;ハードウェア&lt;/h2&gt;
&lt;p&gt;手元にあったUSBカメラ。マイクも内蔵されています。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07JMQD367&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/02/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07WR5W2D6&quot;}&lt;/p&gt;
&lt;h2&gt;ソフトウェア&lt;/h2&gt;
&lt;p&gt;まずは、動体検知するソフトをインストール。&lt;a href=&quot;https://motion-project.github.io/&quot;&gt;motion&lt;/a&gt;が使い勝手が良いようです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo apt update
% sudo apt install motion -y
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;どこのインターフェイスに刺さっているかを一応調べます。今回は、Busが1で、Deviceが3。要は、1の3。&lt;/li&gt;
&lt;li&gt;1つしかカメラやマイクが刺さっていない場合は、デフォルトのマイク、カメラデバイスとして勝手にaliasが貼られるから調べないでもOKです。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;pi@raspberrypi:/etc/motion $ lsusb|grep Logi
Bus 001 Device 003: ID 046d:082d Logitech, Inc. HD Pro Webcam C920
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そして、設定ファイルを変更します。おそらく、デフォルトで無理やり立ち上げればなんとなく動くような設定になっておりますが、色々調整します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo vim /etc/motion/motion.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;デフォルトの設定の差分です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;デフォルトの解像度が低いので少し上げる。最高にしても良いけど無駄に容量を食うので用途次第。&lt;/li&gt;
&lt;li&gt;framerateが10では、かなりカクカクしているので30に。容量とのトレードオフ。&lt;/li&gt;
&lt;li&gt;動体検知のしきい値を結構上げる。これも環境によって調整を。&lt;/li&gt;
&lt;li&gt;その他諸々調整。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;pi@raspberrypi:/tmp $ diff original.motion.conf new.motion.conf
1c1
&amp;lt; daemon off
---
&amp;gt; daemon yes
3a4
&amp;gt; logfile /var/log/motion/motion.log
13,15c14,17
&amp;lt; width 640
&amp;lt; height 480
&amp;lt; framerate 10
---
&amp;gt; flip_axis none
&amp;gt; width 1280
&amp;gt; height 720
&amp;gt; framerate 30
20d21
&amp;lt; mmalcam_name vc.ril.camera
29c30
&amp;lt; threshold 1500
---
&amp;gt; threshold 5000
46c47
&amp;lt; ffmpeg_output_movies off
---
&amp;gt; ffmpeg_output_movies on
48,49d48
&amp;lt; ffmpeg_timelapse 0
&amp;lt; ffmpeg_timelapse_mode daily
52c51
&amp;lt; ffmpeg_video_codec mpeg4
---
&amp;gt; ffmpeg_video_codec mkv
53a53,56
&amp;gt; timelapse_interval 0
&amp;gt; timelapse_mode daily
&amp;gt; timelapse_fps 30
&amp;gt; timelapse_codec mpg
61a65
&amp;gt; target_dir /var/lib/motion
69,70c73,74
&amp;lt; stream_motion on
&amp;lt; stream_maxrate 10
---
&amp;gt; stream_motion off
&amp;gt; stream_maxrate 1
73,74c77
&amp;lt; stream_auth_method 1
&amp;lt; stream_authentication admin:password
---
&amp;gt; stream_auth_method 0
76c79
&amp;lt; webcontrol_localhost on
---
&amp;gt; webcontrol_localhost off
77a81
&amp;gt; webcontrol_parms 0
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;起動&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# systemctl start motion
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;/var/lib/motion に動体を検知したら吐き出されます。&lt;/p&gt;
&lt;p&gt;HTTPにて8081ポートにアクセスすると、リアルタイムにカメラを見られます。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;簡単に監視カメラが作れます&lt;/li&gt;
&lt;li&gt;設定も簡単&lt;/li&gt;
&lt;li&gt;オフィスのエントランスにて録画をしたり、執務室から誰が来たかをカメラで確認したりできます。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>redashでMySQL自体の見える化</title><link>https://blog.teraren.com/posts/redash-mysql-visualization/</link><guid isPermaLink="true">https://blog.teraren.com/posts/redash-mysql-visualization/</guid><description>redashでshow table statusとINNODB_BUFFER_POOL_STATSクエリを使い、MySQLの統計情報をダッシュボードで可視化する方法と活用例</description><pubDate>Sat, 30 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;システム系の情報表示はMackerelで事足りるのですが、もう少し細かいDBの値をちらっと見るために&lt;strong&gt;MySQL自体&lt;/strong&gt;の統計表示をしてみました。&lt;/p&gt;
&lt;p&gt;とはいってもデータ系で数字が出る指標は少ないのでこの程度です。これは、誰でもすぐに真似して使える指標だと思います！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/MySQL_stat.png&quot; alt=&quot;redashでMySQLの統計&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;使うのは以下の2つのクエリー&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;show table status;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;SELECT (sum(database_pages)/sum(pool_size)) *100 AS used,
       sum(pool_size),
       sum(free_buffers),
       sum(database_pages)
FROM information_schema.INNODB_BUFFER_POOL_STATS
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;おまけ&lt;/h3&gt;
&lt;p&gt;Dashboardに変数を用意しておけば、簡易的なBI(Business Intelligence)っぽいグラフを作れます。&lt;/p&gt;
&lt;p&gt;以下は過去3年分のデータを表示しているところ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/acb1c56a70fb1f2ae1750d0436ff2e13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;この変数に日付のfromとtoを指定させたりすればよくある管理画面でのビジュアライゼーションと同じ機能をredashで作れます。&lt;/li&gt;
&lt;li&gt;それをiframeで読み込めば管理画面でchatjsとかを使って頑張ってグラフを作らなくても良いので無駄なエンジニアリソースを使わなくて良くなります。&lt;/li&gt;
&lt;li&gt;redashが楽しすぎてあっという間に時間が過ぎてしまう。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Fujitsu PRIMERGY TX1310 M3にOSインストール断念</title><link>https://blog.teraren.com/posts/fujitsu-primergy-tx1310-m3-quit-installation/</link><guid isPermaLink="true">https://blog.teraren.com/posts/fujitsu-primergy-tx1310-m3-quit-installation/</guid><description>Fujitsu PRIMERGY TX1310 M3へのDebianやUbuntuインストールを試みたがソフトウェアRAIDの挙動が不安定で断念した経緯と知見メモ</description><pubDate>Sun, 24 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;色々試行したけどトライアンドエラーに時間がかかるから諦めました。&lt;/p&gt;
&lt;p&gt;NAS兼、自宅サーバを作りたかったのですが、別の方法を考えます。家にPCがあっても邪魔ということもわかりましたし。&lt;/p&gt;
&lt;p&gt;結構、文献は読んだけどイマイチわからず。タブが大量にあり、閉じると二度とたどり着けないかもしれないからブラウザを落とせない日々が続きました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;「ディスクをダウンロード、焼く、BIOS設定変更、ブート、OSインストール」のトライに疲れました。&lt;/p&gt;
&lt;p&gt;マザーボードにソフトウェアRAIDのチップが載っていて、それがどのレイヤで抽象化しているのかよくわからず。。。（この時点でハードウェアRAIDじゃないのか？って感じですが。。。。）&lt;/p&gt;
&lt;p&gt;BIOS（EUFI）に設定項目があるので設定したのにも関わらず、OS上からは各物理HDDが見えたりしたり、mdadmで管理できるのかできないのかもよくわかりません。&lt;/p&gt;
&lt;p&gt;同じようにハマっている人が見当たらないので初期不良かもしれませんが、正しい動作が何なのかよくわからないのでトラブルシュートが大変です。&lt;/p&gt;
&lt;p&gt;トラブルシュートをしている最中にもMSIのRaidが勝手に外れたり、リビルドが終わらなかったり、不安定で大変でした。&lt;/p&gt;
&lt;p&gt;1点、収穫はHDDのシグネチャが設定されていることによって、HDDがBIOSレベルでは見えるけど、OSレベルからは見られない事象が発生していたこと。&lt;/p&gt;
&lt;p&gt;試したOSは、&lt;br /&gt;
Debian 10 netinst&lt;br /&gt;
Ubuntu 19 server&lt;br /&gt;
Ubuntu 18 server&lt;br /&gt;
Ubuntu 16 server&lt;/p&gt;
&lt;p&gt;例えば、以下のような感じ。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/primergy-tx1310-m3-4gb-ubuntu-16-04-6/
https://blog.teraren.com/posts/primergy-tx1310-m3/&lt;/p&gt;
&lt;p&gt;OSによってはディスクのパーティションを設定する際にディスク自体が見えなかったりします。&lt;br /&gt;
BIOSでRAIDではなくAHCIに変更してもエラーが出ます。&lt;/p&gt;
&lt;h3&gt;以下に色々試した結果を貼っておきます&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/7D168647-2237-4528-9537-9FEC9A9A0271_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/3247C766-4E41-420D-9D03-426F06DBC2AE_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/68B541B3-4F4D-4466-B3D7-B8FF2F17FFA6_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/F0B052C4-5BC1-4C19-B8F9-812F4D749A02_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/F8A2848A-FEB2-4DEC-A3BA-1F453C194C59_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/F8F2258B-3496-4762-B7D9-523D69D4B927_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/065AF303-EB01-40C3-BD68-D432F72B7F92_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/33A6AED5-CEDB-4642-86B1-54C1C5EC76E8_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/50860FB7-9A0E-416D-8ED6-DBAF81FEC141_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/B74BC223-F93B-4CA3-8A1A-1E96BB60BA53_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/C15497D2-BD4F-4B30-9B0E-6D15F784071A_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/14B6E5A9-FA50-4F2B-950E-11458842D53A_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/97E3F58D-16CB-4E74-A32E-AFEB83F4F973_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/A43827B7-0508-4FEF-B4D2-A4E0463E884C_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/3135A757-D5F8-44FA-A58C-27E63A38A8D0_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/72765F68-A20F-4DC7-A18C-2C3BACC573B3_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/1BA416A1-5E33-4822-A31B-FF16B868DD1A_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/C31B6C76-8768-4A45-8E4A-522CB99F568E_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/1BB35488-5ECD-44C4-A49D-2FDFC01B26A8_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/C43E5980-6E9D-4167-ADEF-DB53AC30666D_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/EB12B6CA-5795-4375-A112-ED74398CDAAF_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/20656E8A-143D-441B-98A2-80223DD86238_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/90A8FD25-F3B8-400B-90B7-5BE3189BF158_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/A8860319-9E43-4BDE-95F7-BDAD6053B75E_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/8F548743-D302-4BE2-895A-676F922FE198_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/2947DFFE-04F0-4DDE-81A2-530608C62351_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/B4534D0C-891A-4D9E-811A-8BB9D94C73D1_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/001E62DA-BB27-4FA3-89E6-1B260942A25B_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/6127A420-1B15-48A4-94D4-398C776B6CDC_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/53F2F3B9-9CDD-4A10-A262-BABA274AF4D1_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/0E5E45F9-239F-4C9D-B4BA-B0A17A67759C_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/07A65325-AF17-4204-8F2D-FFCA69E9EFB8_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/C71940E5-2B56-485E-A9F0-DE667817A176_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/36676600-DEC9-48A6-93F3-2E56D2FAF764_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/374FC1B8-D61F-4956-88BC-B5C45364F8BD_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;おそらく24時間以上時間を使った気がします。&lt;/p&gt;
</content:encoded></item><item><title>PRIMERGY TX1310 M3 4GB にUbuntu 18.04.3を入れようとするけど失敗</title><link>https://blog.teraren.com/posts/primergy-tx1310-m3/</link><guid isPermaLink="true">https://blog.teraren.com/posts/primergy-tx1310-m3/</guid><description>富士通PRIMERGY TX1310 M3にUbuntu 18.04.3 Serverをインストールしようとした記録。BIOSのAHCIモード変更から始まりインストール手順を写真付きで記録した試行ログ。</description><pubDate>Sat, 23 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;こちらのページを参考にしてみました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://meltingrabbit.com/blog/article/2018050801/&quot;&gt;https://meltingrabbit.com/blog/article/2018050801/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使ったイメージファイル&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://releases.ubuntu.com/18.04/ubuntu-18.04.3-desktop-amd64.iso&quot;&gt;ubuntu-18.04.3-live-server-amd64.iso&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/10FE5235-CF43-46B4-8D87-E44C2A64618C_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;BIOSバージョン&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/CF539D04-FBF7-4B9F-ACD5-5FD446D72071_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;AHCIモードに変更。HDDが見えている&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/96030284-F7FC-467C-9D05-D2186E8B9F80_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;インストーラからブート&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/B7AAC735-89CA-4B2C-911C-13732B681151_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;言語を選択&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/D15FDAE5-75C2-465B-BE58-95D3F2C6C95D_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;キーボードを選択&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/36DF9F3B-31EC-49F5-9842-20AF0E75EF56_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ミラーアドレスを選択&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/CEC547C4-3025-40F6-831B-34176776231D_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;proxyサーバを非設定&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/FA9A4D75-32D1-418B-A8EB-22EBB682FF6A_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ネットワーク自動認識&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/741A5F47-BEA2-4AAA-86AF-74E1C397DF4C_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ディスクが見つからない。。。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;probing for devices to install to faied&lt;/p&gt;
&lt;p&gt;unfortunately probing for devices to install to failed. Please report a bug on Launched, and if possible include the contents of the /var/log/installer directory.&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>PRIMERGY TX1310 M3 4GB にUbuntu 16.04.6を入れようとするけど失敗</title><link>https://blog.teraren.com/posts/primergy-tx1310-m3-4gb-ubuntu-16-04-6/</link><guid isPermaLink="true">https://blog.teraren.com/posts/primergy-tx1310-m3-4gb-ubuntu-16-04-6/</guid><description>富士通PRIMERGY TX1310 M3にUbuntu 16.04.6 Serverをインストール試みた記録。サポート対象のはずがAHCIモードでもSSDを認識しないインストーラーの挙動をスクリーンショット付きで報告。</description><pubDate>Sat, 23 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://releases.ubuntu.com/16.04/ubuntu-16.04.6-server-amd64.iso&quot;&gt;ubuntu-16.04.6-server-amd64.iso&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://jp.fujitsu.com/platform/server/primergy/software/linux/products/distribution/pdf/tx1310m3-non-support-os.pdf&quot;&gt;サポート&lt;/a&gt;されているはずなのに。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/primergy-tx1310-m3/&quot;&gt;こちら&lt;/a&gt;と同じように、AHCIモード&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/23773261-C3DB-4C1F-878A-BDBB9DF63793_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/70009D86-97E5-45B3-8B73-581E4F133E5E_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/82DEFD16-56AC-4D92-B555-8FFEB7F184D9_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/3BF413EF-7EF8-41E6-A730-07A459CEC302_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/651C7C65-7860-4963-970F-09744436E6DF_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/211846DB-909E-4A7B-86CB-703096445B02_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/026568D9-C048-4296-93A2-E232B78A58E6_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/AF17AF5B-CFA3-441D-972E-2D1CCCE07C69_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/6B104B49-8F1F-40F2-9127-EE6D271D5DE1_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/373CF1A9-1D60-410D-A0E3-809DD23D91C0_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/4E79F68F-10C0-437E-B4C5-0226332F570E_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/930961A6-DBD8-4226-ABFD-9EA07368769C_1_105_c.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;これはインストーラーのUSBディスク。SSDが見られない。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>収支計画テンプレ</title><link>https://blog.teraren.com/posts/revenue-plan-template/</link><guid isPermaLink="true">https://blog.teraren.com/posts/revenue-plan-template/</guid><description>収支計画テンプレ</description><pubDate>Thu, 14 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;https://x.com/matsubokkuri/status/1194790555173023745&lt;/p&gt;
&lt;p&gt;会計の仕分けよりかは、事業のKPIや数字のシート。&lt;/p&gt;
&lt;p&gt;http://finance-startups.jp/2018/07/17/business-plan-template/&lt;/p&gt;
&lt;p&gt;会計の仕訳関連は別のテンプレで。&lt;/p&gt;
</content:encoded></item><item><title>mineoを解約してワイモバイル(Y! mobile)へ</title><link>https://blog.teraren.com/posts/mineo-to-yahoo/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mineo-to-yahoo/</guid><description>mineoを解約してワイモバイル(Y! mobile)へ</description><pubDate>Tue, 12 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;問題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://mineo.jp/&quot;&gt;mineo&lt;/a&gt;が遅い。2年近く我慢してきたけど、限界。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Twitterを検索しても、文句を言っている人は少ない。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://x.com/matsubokkuri/status/998411559905869824
https://x.com/matsubokkuri/status/996702323639336960&lt;/p&gt;
&lt;h2&gt;次はどこにするか？&lt;/h2&gt;
&lt;p&gt;大きく分けて、&lt;strong&gt;3大キャリア&lt;/strong&gt;にするか&lt;strong&gt;格安SIMの業者&lt;/strong&gt;(MVNO)にするかがああります。&lt;/p&gt;
&lt;p&gt;格安SIMは会社によって速度がまちまちで、スタートしたばかりの会社は速いけど、徐々に遅くなっていくのが通例のようです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://keisoku.io/mobile/&quot;&gt;こちらのサイトで各社のベンチマーク&lt;/a&gt;が掲載されています。&lt;a href=&quot;https://www.ymobile.jp/&quot;&gt;Y!mobile&lt;/a&gt;か、&lt;a href=&quot;https://www.uqwimax.jp/&quot;&gt;UQ Wimax&lt;/a&gt;が速くて安定していそうです。&lt;/p&gt;
&lt;p&gt;Yahoo!のサービスを利用しまくっているし、プレミアム会員なのでY!mobileにしてみます。&lt;/p&gt;
&lt;p&gt;ドコモは自分で回線速度を公開しています。すごい速いです。。。本当にこれだけ出るのならば出戻りになってしまい屈辱的ですが、ドコモに戻っても良いです。6,000円/月でこの速度なら納得できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/11/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Yモバイルに乗り換えた結果&lt;/h2&gt;
&lt;p&gt;https://x.com/matsubokkuri/status/1191554245691990022&lt;/p&gt;
&lt;p&gt;導入して1週間使いました。ソフトバンクの電波が弱いところがあるので、電話が通じないところが多くて困ります。&lt;/p&gt;
&lt;p&gt;我慢できなくなったらドコモに戻ります。&lt;/p&gt;
</content:encoded></item><item><title>Amazon Linux AMI 2018.03でEBS拡張</title><link>https://blog.teraren.com/posts/extend-ebs-amazon-linux-ami-2018-03/</link><guid isPermaLink="true">https://blog.teraren.com/posts/extend-ebs-amazon-linux-ami-2018-03/</guid><description>Amazon Linux AMI 2018.03でEBSボリュームが99%になった際、growpartとresize2fsコマンドでオンラインのまま容量を拡張する手順をコマンド実行例付きで紹介。</description><pubDate>Wed, 06 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;# df
Filesystem     1K-blocks     Used Available Use% Mounted on
devtmpfs          991664       56    991608   1% /dev
tmpfs            1002248        0   1002248   0% /dev/shm
/dev/nvme0n1p1  20509288 20154008    255032  99% /
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EBSの容量を増やす。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# growpart /dev/nvme0n1 1
CHANGED: disk=/dev/nvme0n1 partition=1: start=4096 old: size=41938910,end=41943006 new: size=83881950,end=83886046
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# resize2fs /dev/nvme0n1p1
resize2fs 1.43.5 (04-Aug-2017)
Filesystem at /dev/nvme0n1p1 is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 3
The filesystem on /dev/nvme0n1p1 is now 10485243 (4k) blocks long.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        969M   56K  969M   1% /dev
tmpfs           979M     0  979M   0% /dev/shm
/dev/nvme0n1p1   40G   20G   20G  50% /
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>docker-composeでvolume含めて作り直し</title><link>https://blog.teraren.com/posts/cleanup-current-docker-compose/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cleanup-current-docker-compose/</guid><description>docker-composeでvolume含めて作り直し</description><pubDate>Fri, 01 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;手元のdocker-composeの管理対象だけ「滅びの呪文」※1を適用するコマンド。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker-compose down -v --rmi local
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;※1 「滅びの呪文」&lt;/p&gt;
&lt;p&gt;https://x.com/suin/status/1168742981236510721?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E1168742981236510721&amp;amp;ref_url=https%3A%2F%2Fqiita.com%2Fsuin%2Fitems%2F19d65e191b96a0079417&lt;/p&gt;
</content:encoded></item><item><title>小規模（5〜20人）ベンチャーオフィスのネットワーク構築例</title><link>https://blog.teraren.com/posts/building-small-office-network/</link><guid isPermaLink="true">https://blog.teraren.com/posts/building-small-office-network/</guid><description>5〜20人規模のオフィス移転に際し、VLAN分離・VPN・WiFi冗長化などネットワーク設計から機器選定・設置まで実例を詳しく紹介します。</description><pubDate>Fri, 04 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;事業規模の拡大に伴いオフィスの移転がありました。それに伴い社内ネットワークインフラの構築しました。&lt;/li&gt;
&lt;li&gt;中小ベンチャーのネットワーク構築の記事は5年前の&lt;a href=&quot;https://wadap.hatenablog.com/entry/2013/12/26/094008&quot;&gt;@wadapさんの記事&lt;/a&gt;が詳しいです。まぁ、5年前なので細かいアップデートが色々あるので記事にしておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要求定義&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ゲスト用ネットワークの分離&lt;/strong&gt;（インターネット回線、LAN回線）
&lt;ul&gt;
&lt;li&gt;将来のシステム監査で指摘されるであろうことなので。&lt;/li&gt;
&lt;li&gt;トラフィックのQoS制御のため。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;役割（部署）毎に&lt;strong&gt;LANの分離&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;ウィルス感染した場合に被害を減らすため。&lt;/li&gt;
&lt;li&gt;重要情報を扱うエンジニアのネットワークを守るため。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;安定&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;ストリーミングを扱うプロダクトを扱っているので安定性を高める。&lt;/li&gt;
&lt;li&gt;特にWiFiは安定してほしい。&lt;/li&gt;
&lt;li&gt;WiFiと有線を用意してL1レイヤの冗長性を確保しておく。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;低レイテンシー&lt;/li&gt;
&lt;li&gt;初期費用、固定費は&lt;strong&gt;安く&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;20人ぐらい (平均3台/人で計算して60端末同時接続) ぐらいには耐えられるように。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ISPは2回線用意する。固定IPとゲスト用。&lt;/li&gt;
&lt;li&gt;物理ネットワークに自由度を持たすためにVLANにする。&lt;/li&gt;
&lt;li&gt;WiFiが安定していること。&lt;/li&gt;
&lt;li&gt;オフィス外からネットワークに入れる。&lt;/li&gt;
&lt;li&gt;各席に有線。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設計&lt;/h2&gt;
&lt;p&gt;タグVLANが絡むと設計書を書くのが難しかったです。**物理レイヤ(L1)と論理レイヤ(L2)を同時に考えて1つの図にする必要が有りました。**これが結構難しかったです。&lt;/p&gt;
&lt;p&gt;論理レイヤで考えて、それを物理レイヤに落として。その逆を行ったりと。L1、L2、L3を行ったり来たりして考えていました。vlan使わなければL1だけ考えれば済むので超楽だなぁと思いました。&lt;/p&gt;
&lt;p&gt;VLANを使わなければ、L1とL2は完全に分離して考えられるので非常に簡単ですが、VLANが絡み出すと難易度がかなり上がります。本来は、論理と物理を分けて考えられて便利にするためのVLANなのに。。。&lt;/p&gt;
&lt;p&gt;一部にVLAN非対応機器が居たり、tag, untagを同一ネットワークに混ぜたり出来ちゃうので論理と物理が混ざってしまう原因でした。（この辺、想定した動作と各ベンダーの実装が若干違うので検証が大変でした。例えば、ルーターはvlanの設定しかしていないのに、vlanじゃないパケットも普通にvlan1として扱われたりする。まぁ、そうじゃないとvlanを設定した途端untagのパケットが到達出来なくなったりするのを回避するためなのかと思いますが。）&lt;/p&gt;
&lt;p&gt;どのツールで設計書を書くのが良いのかよくわからないのでとりあえず&lt;a href=&quot;https://cacoo.com/ja/&quot;&gt;cacoo&lt;/a&gt;で設計しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;次に、図にある各エンティティについて詳細を書きます。&lt;/p&gt;
&lt;h3&gt;キャリア&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;フレッツ光ネクストで最高速1Gbpsです。&lt;/li&gt;
&lt;li&gt;最近評判が良いと聞く&lt;a href=&quot;http://www.nuro.jp/campaign/rmd/?recomndNo=dfs84206&quot;&gt;NURO 光&lt;/a&gt;を検討しましたが導入をやめました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NURO光は個人と法人(Nuro Biz)で内容が全然違います&lt;/strong&gt;。根本的なところで&lt;strong&gt;運営している会社自体が違います&lt;/strong&gt;。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.nuro.jp/campaign/rmd/?recomndNo=dfs84206&quot;&gt;NURO光の個人&lt;/a&gt;の利用料は6,000円ぐらい。（大人気らしく敷設に2ヶ月待ちとのこと）&lt;/li&gt;
&lt;li&gt;NURO光の法人(NURO biz)の利用料は月額20,000円ぐらい。サポート充実。固定IPあり。2個 +6,000円とか。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ISP&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Webの管理画面にアクセス制限&lt;/strong&gt;をつけるために、アクセス元のネットワークによってアクセス制限をしたいというユースケースがあります。それを代替出来るアプローチが今のところないので、IPv4の固定IPアドレスが必要です。
&lt;ul&gt;
&lt;li&gt;サーバサイドからの視点では、やはりIPアドレス制限を入れる事でリスクをL3以下は気にしないで良くなる利点は大きい&lt;/li&gt;
&lt;li&gt;IPv6の固定レンジでの割り当てをするISPはほとんど存在指定無い&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;固定IPアドレスを提供するISPは安いしいままで大きな問題が無かった&lt;strong&gt;GMO BB&lt;/strong&gt;を引き続き使います。1,100円/月。（夜20時以降は少し遅い感じがします）&lt;/li&gt;
&lt;li&gt;ゲスト用のネットワークは適当なISPで良いので、キャリアとISPの申し込みを同時にすると安いので適当に選びました。とりあえずIPv6に対応しているso-netにしました。&lt;a href=&quot;https://blog.teraren.com/2018/03/27/%e3%82%a4%e3%83%b3%e3%82%bf%e3%83%bc%e3%83%8d%e3%83%83%e3%83%88%e5%9b%9e%e7%b7%9a%e6%96%b0%e8%a6%8f%e5%a5%91%e7%b4%84%e2%86%92/&quot;&gt;家で使っていたときは下りで400Mbps出ていたので&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ルーター&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;安く済ますために&lt;a href=&quot;https://www.amazon.co.jp/%E3%83%A4%E3%83%9E%E3%83%8F-Yamaha-RTX1200-%E3%82%AE%E3%82%AC%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9VPN%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC/dp/B001G79VGK?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=ae3851d6b6768d49f8dac6e0455a2155&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;YAMAHA RTX1200&lt;/a&gt;です。10年近く前の機種ですが、1Gbps対応、L2TP対応、SNMP対応など十分な機能です。&lt;/li&gt;
&lt;li&gt;定価125,000円ですが、保守終わりの中古機材が&lt;strong&gt;7,000円&lt;/strong&gt;ぐらいで大量に流通しています。保証はないですが、壊れたら買えば良いのです。自宅でも使っていますが2年以上全く落ちませんでした。スループットも1Gbps近くまでは出ます。&lt;/li&gt;
&lt;li&gt;同系統の最新である&lt;a href=&quot;https://www.amazon.co.jp/%E3%83%A4%E3%83%9E%E3%83%8F-Yamaha-RTX1210-%E3%82%AE%E3%82%AC%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9VPN%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC/dp/B00NF2GN6U?pd_rd_w=aVT2S&amp;amp;pf_rd_p=949e26f5-c2ef-4c96-bfde-49d7614d0317&amp;amp;pf_rd_r=PVBRX0HPY0NAYXPP2JEF&amp;amp;pd_rd_r=db5a600e-289a-415a-a190-4564d725fe85&amp;amp;pd_rd_wg=i24s3&amp;amp;pd_rd_i=B00NF2GN6U&amp;amp;psc=1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=8586d4667d9772d353d62f88676b71a8&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;YAMAHA RTX1210&lt;/a&gt;か、RTX1200とほぼ同性能の現行品である&lt;a href=&quot;https://www.amazon.co.jp/%E3%83%A4%E3%83%9E%E3%83%8F-RTX830-%E3%82%AE%E3%82%AC%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9VPN%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC/dp/B075YVK9QF?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=92c57583bd50f0cecee6f30dda8ab87d&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;RTX830&lt;/a&gt;も考えたのですが、中古のRTX1200にコスパでかないませんでした。&lt;/li&gt;
&lt;li&gt;IPv6の様々な接続方式に対応するために、新しいモデルであるRTX1210か&lt;a href=&quot;https://www.amazon.co.jp/%E3%83%A4%E3%83%9E%E3%83%8F-RTX830-%E3%82%AE%E3%82%AC%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9VPN%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC/dp/B075YVK9QF?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=92c57583bd50f0cecee6f30dda8ab87d&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;RTX830&lt;/a&gt;をおすすめします。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B001G79VGK&quot;}&lt;/p&gt;
&lt;h3&gt;スイッチ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;全部YAMAHAで揃えて一元管理したいのが理想ですが、いかんせんVLAN対応のYAMAHAのインテリジェントスイッチは高いです。中古でも出回ってないです。&lt;/li&gt;
&lt;li&gt;安いVLAN対応のスイッチを選択。&lt;a href=&quot;https://www.amazon.co.jp/NETGEAR-%E3%82%B9%E3%82%A4%E3%83%83%E3%83%81%E3%83%B3%E3%82%B0%E3%83%8F%E3%83%96-%E3%82%AE%E3%82%AC%E3%83%93%E3%83%83%E3%83%888%E3%83%9D%E3%83%BC%E3%83%88-%E3%83%95%E3%82%A1%E3%83%B3%E3%83%AC%E3%82%B9%E9%9D%99%E9%9F%B3%E8%A8%AD%E8%A8%88-GS108E-300JPS/dp/B00OMEVV26?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=40cc4a8a3363562c43f6e796db00abb3&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;Netgear GS108e&lt;/a&gt;を2台。約5,000円/台&lt;/li&gt;
&lt;li&gt;参考のために、8ポートのYAMAHA SWX2200-8Gは&lt;strong&gt;実売で約23,000円&lt;/strong&gt;。Netgearの4倍！&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B00OMEVV26&quot;}&lt;/p&gt;
&lt;h3&gt;WiFi AP（アクセスポイント）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/%E3%83%A4%E3%83%9E%E3%83%8F-Yamaha-WLX313-%E7%84%A1%E7%B7%9ALAN%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88/dp/B07DXDPV5R?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=3df4fbdcd472b1eb30ea8e28aaf1297c&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;YAMAHA WLX313&lt;/a&gt;で。実売約6万円。定価69,800円(税抜)&lt;/li&gt;
&lt;li&gt;ここはケチらず。&lt;/li&gt;
&lt;li&gt;WLC（Wireless LAN Controller）とVLANにも対応。&lt;/li&gt;
&lt;li&gt;市販の家庭用アクセスポイントはよく壊れます。コンシューマ向けのWiFiアクセスポイントはすぐに詰まったり、電波飛ばなかったり、動作が怪しい物が多いです。今まで家のAPは1〜2年おきに買い換えています。電波は目に見えなくてトラブルシューティングしづらいので、ここはケチらず良い物を買いましょう。
{/* textlint-disable ja-technical-writing/ja-no-successive-word */}&lt;/li&gt;
&lt;li&gt;WLX313はかなりいろんな機能があって良いのですが、自動制御が不安定です。なので、便利な機能はOFFにしまくってシンプルな設定にして運用する必要がありました。自動チャネル選択、自動出力変更などなど便利そうな機能を一通りOFFにしました。
{/* textlint-enable */}&lt;/li&gt;
&lt;li&gt;PoE対応なので、PoEスイッチに接続して使おうしたのですが&lt;strong&gt;電源容量が足りなくて&lt;/strong&gt;動きませんでした。WiFi APは消費電力が大きいので対応したPoEスイッチを選択する必要があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B06VWLL898&quot;}&lt;/p&gt;
&lt;h2&gt;LANケーブル&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;今回は小規模だしケチりたいので自前で行います。ケーブルと圧着機材一式を揃えました。&lt;/li&gt;
&lt;li&gt;最近は、&lt;a href=&quot;https://item.rakuten.co.jp/sanwadirect/500-lan6fl01/&quot;&gt;楽天で1本200円&lt;/a&gt;でいろいろな長さのcat6ケーブルが売っているので圧着する時間を考えると買った方が安いと思うのですが、ケーブルの品質が悪くて断線が頻繁に起きました。&lt;/li&gt;
&lt;li&gt;かといって市販のケーブルは1m500円とかするので、10本買うと5,000円ぐらいかかったりする。また、長い距離になると5m単位や10m単位のロットしかなくて配線の余りが出てきてしまいます。&lt;/li&gt;
&lt;li&gt;下のリンクにあるエレコムのLANケーブルはローダー付きのRJ45じゃないとコネクタへのケーブルの挿入の難易度高すぎて無理でした。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B0010P69BS&quot;}
::amazon{asin=&quot;B01K9Z4FT2&quot;}
::amazon{asin=&quot;B0778K8WPT&quot;}&lt;/p&gt;
&lt;h2&gt;実装&lt;/h2&gt;
&lt;h3&gt;L1&lt;/h3&gt;
&lt;p&gt;どこに何を通すか設計します。業者からもらった室内の設計図では不十分なので、結局は現況を見てからちゃんと作りました。意外と図面は抽象的なので要注意です。&lt;/p&gt;
&lt;p&gt;現場では、図面に載っていない配線があったりしました。天井裏の配線は謎で、ケーブル通しを使って業者と2人がかりで捜索し、現場の作業員を勝手にお借りしてケーブル通しを手伝ってもらいました。頭数が2人は最低必要な状況でした。&lt;/p&gt;
&lt;p&gt;ケーブリングが終わったら、引き継ぎやすいようにAs-Isを残しておきます。モザイクばかりでよくわかりませんが。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;機材の設定は、設置してしまうと物理的に移動したり、付け替えたり、動作確認が面倒なので事前に一通り設定して動作確認をしておきます。&lt;/p&gt;
&lt;p&gt;VLANの場合は特に、設定確認を行うポイントが多いので事前にやっておくべきです。このために50cmのケーブルをたくさん作る事になって辛かった。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/3B0840DC-35A1-4B6C-BFBD-7CCE7BCE7EAF.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;フリーアクセスなのでカーペットを剥がして床を見て見ると結構堅い締め付けでネジが締められていて、外すのが大変でした。インパクトドライバーが無いと堅くて緩まないので取りに帰りました。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/IMG_3160.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/IMG_3183.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;インパクトでやっと開けられた&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/IMG_3181.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;仮に敷設。ケーブルが堅い。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/IMG_3186.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;テーブルの上に置けるように長めに&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/IMG_3190.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;完了&lt;/p&gt;
&lt;p&gt;WiFi Sannerで帯域をチェック。これを見て利用するチャネルを決めます。2GHz帯は外から回り込んでくるのか、他社のが入ってきます。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;電波が届きにくいところや、外への漏れ具合を確認するときには、&lt;a href=&quot;https://apps.apple.com/jp/app/wi-fi%E3%83%9F%E3%83%AC%E3%83%AB/id1132440751&quot;&gt;WiFiミレル&lt;/a&gt;を使ってチェックします。PCを持ち歩いてうろうろしないで良いので楽です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/4p1BkAWQ724MLTiXU8bJw_thumb_666f.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;AM2時頃。業者もまだやってる。。。お互い大変だ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/IMG_3191.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ルーターの設定&lt;/h3&gt;
&lt;p&gt;RTX1200の設定の要点をいくつか書いておきます。&lt;/p&gt;
&lt;p&gt;4つのvlanを作ります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;社内リソース用&lt;/li&gt;
&lt;li&gt;エンジニア用&lt;/li&gt;
&lt;li&gt;biz用&lt;/li&gt;
&lt;li&gt;ゲスト用&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;vlan lan1/4 802.1q vid=4
vlan lan1/5 802.1q vid=5
vlan lan1/6 802.1q vid=6
vlan lan1/7 802.1q vid=7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、どこからどこに何を通したいかを設定します。ネットワーク間は全てデフォルトではpassなので、一旦全てrejectした上で必要なパケットを通していきます。&lt;/p&gt;
&lt;p&gt;ルール自体はとても複雑なので、使うか使わないかは別にしてルールは一旦全部作って起きます。その後、このルールをip pp secure filterで適用していきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip filter 600000 reject 192.168.4.0/24 192.168.5.0/24
ip filter 600001 reject 192.168.4.0/24 192.168.6.0/24
ip filter 600002 reject 192.168.4.0/24 192.168.7.0/24
ip filter 600011 reject 192.168.5.0/24 192.168.4.0/24
ip filter 600012 reject 192.168.5.0/24 192.168.6.0/24
ip filter 600013 reject 192.168.5.0/24 192.168.7.0/24
ip filter 600021 reject 192.168.6.0/24 192.168.4.0/24
ip filter 600022 reject 192.168.6.0/24 192.168.5.0/24
ip filter 600023 reject 192.168.6.0/24 192.168.7.0/24
ip filter 600031 reject 192.168.7.0/24 192.168.4.0/24
ip filter 600032 reject 192.168.7.0/24 192.168.5.0/24
ip filter 600033 reject 192.168.7.0/24 192.168.6.0/24
ip filter 600045 reject 192.168.4.0/24 192.168.5.0/24
ip filter 600046 reject 192.168.4.0/24 192.168.6.0/24
ip filter 600047 reject 192.168.4.0/24 192.168.7.0/24
ip filter 600054 reject 192.168.5.0/24 192.168.4.0/24
ip filter 600056 reject 192.168.5.0/24 192.168.6.0/24
ip filter 600057 reject 192.168.5.0/24 192.168.7.0/24
ip filter 600064 reject 192.168.6.0/24 192.168.4.0/24
ip filter 600065 reject 192.168.6.0/24 192.168.5.0/24
ip filter 600067 reject 192.168.6.0/24 192.168.7.0/24
ip filter 600074 reject 192.168.7.0/24 192.168.4.0/24
ip filter 600075 reject 192.168.7.0/24 192.168.5.0/24
ip filter 600076 reject 192.168.7.0/24 192.168.6.0/24
ip filter 600145 pass 192.168.4.0/24 192.168.5.0/24 icmp
ip filter 600146 pass 192.168.4.0/24 192.168.6.0/24 icmp
ip filter 600147 pass 192.168.4.0/24 192.168.7.0/24 icmp
ip filter 600154 pass 192.168.5.0/24 192.168.4.0/24 icmp
ip filter 600156 pass 192.168.5.0/24 192.168.6.0/24 icmp
ip filter 600157 pass 192.168.5.0/24 192.168.7.0/24 icmp
ip filter 600164 pass 192.168.6.0/24 192.168.4.0/24 icmp
ip filter 600165 pass 192.168.6.0/24 192.168.5.0/24 icmp
ip filter 600167 pass 192.168.6.0/24 192.168.7.0/24 icmp
ip filter 600174 pass 192.168.7.0/24 192.168.4.0/24 icmp
ip filter 600175 pass 192.168.7.0/24 192.168.5.0/24 icmp
ip filter 600176 pass 192.168.7.0/24 192.168.6.0/24 icmp
ip filter 600245 pass 192.168.4.0/24 192.168.5.0/24 * 631
ip filter 600246 pass 192.168.4.0/24 192.168.6.0/24 * 631
ip filter 600247 pass 192.168.4.0/24 192.168.7.0/24 * 631
ip filter 600254 pass 192.168.5.0/24 192.168.4.0/24 * 631
ip filter 600256 pass 192.168.5.0/24 192.168.6.0/24 * 631
ip filter 600257 pass 192.168.5.0/24 192.168.7.0/24 * 631
ip filter 600264 pass 192.168.6.0/24 192.168.4.0/24 * 631
ip filter 600265 pass 192.168.6.0/24 192.168.5.0/24 * 631
ip filter 600267 pass 192.168.6.0/24 192.168.7.0/24 * 631
ip filter 600274 pass 192.168.7.0/24 192.168.4.0/24 * 631
ip filter 600275 pass 192.168.7.0/24 192.168.5.0/24 * 631
ip filter 600276 pass 192.168.7.0/24 192.168.6.0/24 * 631
ip filter 610047 pass 192.168.4.0/24 192.168.7.0/24 icmp
ip filter 610048 pass 192.168.7.0/24 192.168.4.0/24 icmp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ipv6の設定。社員用はIPv4のアクセス制限があるので、IPv6の利用はゲストネットワークのみにします。lan1/6がゲストネットワークのvlanです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ipv6 prefix 1 ra-prefix@lan2::/64

ipv6 lan1/6 address ra-prefix@lan2::1/64
ipv6 lan1/6 rtadv send 1 o_flag=on
ipv6 lan1/6 dhcp service server

ipv6 lan2 secure filter in 200030 200031 200038 200039
ipv6 lan2 secure filter out 200099 dynamic 200080 200081 200082 200083 200084 200085 200086 200098 200099
ipv6 lan2 dhcp service client ir=on

ipv6 filter 200030 pass * * icmp6 * *
ipv6 filter 200031 pass * * 4
ipv6 filter 200038 pass * * udp * 546
ipv6 filter 200039 reject * *
ipv6 filter 200099 pass * * * * *
ipv6 filter dynamic 200080 * * ftp
ipv6 filter dynamic 200081 * * domain
ipv6 filter dynamic 200082 * * www
ipv6 filter dynamic 200083 * * smtp
ipv6 filter dynamic 200084 * * pop3
ipv6 filter dynamic 200085 * * submission
ipv6 filter dynamic 200086 * * https
ipv6 filter dynamic 200098 * * tcp
ipv6 filter dynamic 200099 * * udp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ゲストネットワークのQoSを最初は設定していましたが、ユーザが少ないので撤廃しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;queue lan1 type shaping
queue lan1 class filter list 1 2
queue lan1 class property 1 bandwidth=100M
queue class filter 1 1 ip 192.168.6.0/24 * * * *
queue class filter 2 1 ip * 192.168.6.0/24 * * *
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;うるさいログをoffにしたり。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip filter dynamic 200080 * * ftp syslog=off
ip filter dynamic 200081 * * domain syslog=off
ip filter dynamic 200082 * * www syslog=off
ip filter dynamic 200083 * * smtp syslog=off
ip filter dynamic 200084 * * pop3 syslog=off
ip filter dynamic 200085 * * submission syslog=off
ip filter dynamic 200098 * * tcp syslog=off
ip filter dynamic 200099 * * udp syslog=off
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;統計情報はこんな感じです。まぁ、キャパまでまだまだ余裕です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;とある日のCPU使用率&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;とある日のトラフィック&lt;/p&gt;
&lt;h3&gt;スイッチの設定&lt;/h3&gt;
&lt;p&gt;ブラウザ上でvlanの設定をポチポチと。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;簡単な統計は出ます&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;WiFi APの設定&lt;/h3&gt;
&lt;p&gt;周波数とSSIDが分離されていて設定しやすいです。このご時世、2.4GHzをオフにしていてもクレームは出ませんでした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WiFi APは見通しの良い高い所に設置するのが理想なので、上に設置します。配線も綺麗に整備しました。マルチカッターがないと切るのが辛かったです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/IMG_4822-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Before&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/IMG_4823.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;カット&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/IMG_4827.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;After&lt;/p&gt;
&lt;p&gt;実際に設置してみてわかったのですが、コンクリの壁を挟んだ向こう側はWiFiの電波がかなり減衰しました。距離にして5mなのですが、Chromecastの感度が悪くて、Chromecastだけ繋がらないという現象が起きました。&lt;/p&gt;
&lt;p&gt;今回わかったのは、5GHzはコンクリを全然通過しないし、回り込みもほとんど無いです。仕方が無いのでAPを1つ追加しました。（確かに自宅の5GHzも見通しじゃないとかなり減衰するなぁと思いました）&lt;/p&gt;
&lt;h3&gt;Chromecastを設置&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;会議室のテレビにはChromecastを設置しました。ゲストネットワークに参加させておきます。&lt;/li&gt;
&lt;li&gt;来訪者がWiFiに繋げれば会議室のテレビをワイヤレスで投影出来るので便利です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/IMG_3573.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;設定管理&lt;/h3&gt;
&lt;p&gt;APIで制御は出来ないので、Infrastructure as Codeの理想に近づけるためにも設定ファイルをダンプしてgithubで管理。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;初期コスト
&lt;ul&gt;
&lt;li&gt;約11万円&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/10/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;内訳&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ランニングコスト
&lt;ul&gt;
&lt;li&gt;1万円未満/月&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ベンチマーク&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;無線LAN&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;有線LAN&lt;/p&gt;
&lt;p&gt;IPv6の&lt;a href=&quot;https://ipv6-test.com/&quot;&gt;設定テスト&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;オフィスの引っ越しに伴いネットワークを構築しました。
{/* textlint-disable ja-technical-writing/ja-no-successive-word */}&lt;/li&gt;
&lt;li&gt;工数は10人日ぐらい使いました。（キャリア選定、機器選定、L1,L2設計、施工、設定、テスト、ケーブル作成などなど）
{/* textlint-enable */}&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Netgear GS108Eで自宅VLAN</title><link>https://blog.teraren.com/posts/netgear-gs108e/</link><guid isPermaLink="true">https://blog.teraren.com/posts/netgear-gs108e/</guid><description>Netgear GS108Eスマートスイッチを使って自宅ネットワークにVLANを構築。初期不良品交換の経緯と管理画面へのアクセス、iperfによるスループット測定結果を記録。</description><pubDate>Thu, 03 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Netgear GS108Eを使って家のVLANを設定してみる。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/netgear-gs108e-unable-to-setup/&quot;&gt;1台目&lt;/a&gt;が初期不良で壊れていたので2台目の挑戦。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B00OMEVV26&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;やっと巡り会えた管理画面。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;スループット&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;VLANなし。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% iperf -c 192.168.1.7
------------------------------------------------------------
Client connecting to 192.168.1.7, TCP port 5001
TCP window size:  129 KByte (default)
------------------------------------------------------------
[  4] local 192.168.1.103 port 62204 connected with 192.168.1.7 port 5001
[ ID] Interval       Transfer     Bandwidth
[  4]  0.0-10.0 sec  1.10 GBytes   942 Mbits/sec
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;L1とL2の設計&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-23.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>GitHubのPull Requestにプレビュー用URLを自動でコメント</title><link>https://blog.teraren.com/posts/github-pull-request-comment/</link><guid isPermaLink="true">https://blog.teraren.com/posts/github-pull-request-comment/</guid><description>CircleCI 2.1とS3を使った静的サイトの自動デプロイ環境で、デプロイ先URLをGitHub Pull Requestのコメントに自動投稿するCircleCIの設定方法を解説します。</description><pubDate>Thu, 12 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/github-circleci-s3-cloudfront-deploy/&quot;&gt;静的サイトの自動デプロイ github -&amp;gt; CircleCI -&amp;gt; S3 -&amp;gt; CloudFront&lt;/a&gt; の記事に関連した設定の続きです。&lt;/li&gt;
&lt;li&gt;上記の設定では、デプロイしたURLをいちいちブランチ名をコピペしてURLにアクセスする必要が有るので若干面倒です。それを無くすためにデプロイ先のURLをPull requestのコメントに自動で書き込みます。&lt;/li&gt;
&lt;li&gt;余談ですが&lt;a href=&quot;https://circleci.com/docs/2.0/configuration-reference/&quot;&gt;CircleCIの設定ファイルのバージョンが2.1&lt;/a&gt;に上がって色々書けるようになりましたね。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;CircleCIの設定&lt;/h2&gt;
&lt;p&gt;いきなりですが回答です。全て変数で書いてあるので、コピペで使えます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
defaults: &amp;amp;defaults
  working_directory: ~/repo
  docker:
    - image: circleci/node:10

version: 2.1
jobs:
  build:
    &amp;lt;&amp;lt;: *defaults
    steps:
      - checkout
      - run: npm install
      - run: npm run build
      - persist_to_workspace:
          root: .
          paths:
            - build
  deploy-job:
    &amp;lt;&amp;lt;: *defaults
    steps:
      - attach_workspace:
          at: .
      - run:
          name: Install newer version of awscli
          command: |
            sudo apt-get install python-dev python-pip
            pip install awscli --user
      - run:
          name: Deploy to S3
          command: /home/circleci/.local/bin/aws s3 sync build s3://${AWS_BUCKET_NAME}${CIRCLE_BRANCH}/ --delete --region=${AWS_S3_REGION}
      - run:
          name: Post URL
          command: |
            if [ ${CI_PULL_REQUEST} ]; then
              curl -X POST \
                -H &apos;Content-Type:application/json&apos; \
                -u matsubo:${GITHUB_ACCESS_TOKEN} \
                -d &quot;{\&quot;body\&quot;:\&quot;Deployed to:\nhttp://${AWS_BUCKET_NAME}.s3-website-${AWS_S3_REGION}.amazonaws.com/${CIRCLE_BRANCH}/\&quot;}&quot; \
                &quot;https://api.github.com/repos/${GITHUB_USER}/${GITHUB_REPO}/issues/${CIRCLE_PULL_REQUEST##*/}/comments&quot;
            fi

workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - deploy-job:
          requires:
            - build
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記のYAMLにある変数に追加してawscliを使うために以下の2つの環境変数なども必要に応じて設定します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt; – IAM ユーザーまたはロールに関連付けられる AWS アクセスキーを指定します。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt; – アクセスキーに関連付けられるシークレットキーを指定します。これは、基本的にアクセスキーの「パスワード」です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;うまく出来ると、下のような感じになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/09/fbe16683c93cceba206ad00872fcbbbb.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;GithubのPull Requestにコメントを書き込む&lt;/h2&gt;
&lt;p&gt;中でも面倒だったのがGithubのAPIの認証です。エラーがわかりづらくて面倒でした。&lt;/p&gt;
&lt;p&gt;まず、&lt;code&gt;Personal Access Token&lt;/code&gt;を&lt;a href=&quot;https://github.com/settings/tokens&quot;&gt;こちら&lt;/a&gt;のページから作ります。2FAを使っている場合もこの手順でOKです。&lt;/p&gt;
&lt;p&gt;権限は、以下の項目（Full control of private repositories）だけチェックをしておけばOKです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/09/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;curlコマンドでテストすると以下のようになります。エンドポイントURLのpathは&lt;code&gt;pull&lt;/code&gt;ではなく、&lt;code&gt;issues&lt;/code&gt;で良いです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -X POST -H &apos;Content-Type:application/json&apos; -u matsubo:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx  -d &quot;{\&quot;body\&quot;:\&quot;GitHub APIからコメント投稿\&quot;}&quot; &quot;https://api.github.com/repos/xxxxxxxxxx/xxxxxxxxxxxxxxxxxxx/issues/14/comments&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;url&quot;: &quot;https://api.github.com/repos/xxxxxxxxxx/xxxxxxxxxxxxxxxxxxx/issues/comments/530435426&quot;,
  &quot;html_url&quot;: &quot;https://github.com/xxxxxxxxxx/xxxxxxxxxxxxxxxxxxx/pull/14#issuecomment-530435426&quot;,
  &quot;issue_url&quot;: &quot;https://api.github.com/repos/xxxxxxxxxx/xxxxxxxxxxxxxxxxxxx/issues/12&quot;,
  &quot;id&quot;: 530435426,
  &quot;node_id&quot;: &quot;MDEyOklzc3VlQ29tbWVudDUzMDQzNTQyNg==&quot;,
  &quot;user&quot;: {
    &quot;login&quot;: &quot;matsubo&quot;,
    &quot;id&quot;: 98103,
    &quot;node_id&quot;: &quot;MDQ6VXNlcjk4MTAz&quot;,
    &quot;avatar_url&quot;: &quot;https://avatars0.githubusercontent.com/u/98103?v=4&quot;,
    &quot;gravatar_id&quot;: &quot;&quot;,
    &quot;url&quot;: &quot;https://api.github.com/users/matsubo&quot;,
    &quot;html_url&quot;: &quot;https://github.com/matsubo&quot;,
    &quot;followers_url&quot;: &quot;https://api.github.com/users/matsubo/followers&quot;,
    &quot;following_url&quot;: &quot;https://api.github.com/users/matsubo/following{/other_user}&quot;,
    &quot;gists_url&quot;: &quot;https://api.github.com/users/matsubo/gists{/gist_id}&quot;,
    &quot;starred_url&quot;: &quot;https://api.github.com/users/matsubo/starred{/owner}{/repo}&quot;,
    &quot;subscriptions_url&quot;: &quot;https://api.github.com/users/matsubo/subscriptions&quot;,
    &quot;organizations_url&quot;: &quot;https://api.github.com/users/matsubo/orgs&quot;,
    &quot;repos_url&quot;: &quot;https://api.github.com/users/matsubo/repos&quot;,
    &quot;events_url&quot;: &quot;https://api.github.com/users/matsubo/events{/privacy}&quot;,
    &quot;received_events_url&quot;: &quot;https://api.github.com/users/matsubo/received_events&quot;,
    &quot;type&quot;: &quot;User&quot;,
    &quot;site_admin&quot;: false
  },
  &quot;created_at&quot;: &quot;2019-09-11T15:32:07Z&quot;,
  &quot;updated_at&quot;: &quot;2019-09-11T15:32:07Z&quot;,
  &quot;author_association&quot;: &quot;COLLABORATOR&quot;,
  &quot;body&quot;: &quot;GitHub APIからコメント投稿&quot;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>上場企業でのITコンサル1.5年間の業務まとめ</title><link>https://blog.teraren.com/posts/what-i-have-done-as-it-consulting/</link><guid isPermaLink="true">https://blog.teraren.com/posts/what-i-have-done-as-it-consulting/</guid><description>上場企業に週4常駐し、レンタルCTOとして技術DD・採用・SaaS開発・クラウド移行・特許出願支援まで幅広く担当した1.5年間の記録</description><pubDate>Wed, 11 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;とある上場企業にITコンサルタントとして1.5年間関わった。週4日程度クライアント先に常駐し、社員アカウントを発行してもらって社内リソースにフルアクセスできる体制だった。&lt;/p&gt;
&lt;p&gt;役割としてはCTOに近い動き方で、「レンタルCTO」というイメージ。技術的な意思決定から採用面接、ベンダーコントロール、自らコードを書くところまで守備範囲は広かった。&lt;/p&gt;
&lt;h3&gt;社外コンサルの限界&lt;/h3&gt;
&lt;p&gt;社外の立場なので、HR関連（評価・異動・組織変更）のエグゼキューションは難しく、時間がかかった。技術的な方針は提案・実行できても、それを実行する組織の動かし方は社内の人間に依存する。これは社外コンサルの構造的な限界だと感じた。&lt;/p&gt;
&lt;h2&gt;コンサルティング業務&lt;/h2&gt;
&lt;h3&gt;技術デューデリジェンス（DD）&lt;/h3&gt;
&lt;p&gt;開発中のシステムを第三者の立場で評価。コード品質、アーキテクチャの妥当性、技術的負債、セキュリティリスクなどを調査してレポートにまとめた。&lt;/p&gt;
&lt;h3&gt;採用&lt;/h3&gt;
&lt;p&gt;エンジニア採用の面接を担当。技術力の評価とカルチャーフィットを判断した。&lt;/p&gt;
&lt;h3&gt;分析基盤リプレイス&lt;/h3&gt;
&lt;p&gt;社内の分析基盤をリプレイスするプロジェクト。ユースケースの整理からアーキテクチャ設計、ベンダー選定までを担当した。&lt;/p&gt;
&lt;h3&gt;電力小売り事業の立ち上げ&lt;/h3&gt;
&lt;p&gt;新規事業として電力小売りを開始するにあたり、ユースケース整理・要件定義・システム設計・基幹システムとのAPI連携設計・ベンダーコントロールを一貫して担当した。&lt;/p&gt;
&lt;h3&gt;全社システム統合&lt;/h3&gt;
&lt;p&gt;基幹システムとユーザ向けシステムを統合するための全社横断プロジェクト。各部署のユースケースを整理し、統合後のシステムを設計した。&lt;/p&gt;
&lt;h3&gt;クラウド移行&lt;/h3&gt;
&lt;p&gt;イントラネットサービスのクラウド化を推進。ファイルサーバ・経費精算システム・ワークフローシステム・グループウェアをクラウドサービスに移行し、運用を軌道に乗せた。&lt;/p&gt;
&lt;h3&gt;IT戦略計画&lt;/h3&gt;
&lt;p&gt;中期的なIT戦略計画を策定。技術スタック・組織・投資の方向性をまとめた。&lt;/p&gt;
&lt;h3&gt;特許出願支援&lt;/h3&gt;
&lt;p&gt;特許出願における技術的な観点でのサポート。発明の技術的な構成要素の整理や、請求項の技術的な妥当性をレビューした。&lt;/p&gt;
&lt;h3&gt;システム疎結合化&lt;/h3&gt;
&lt;p&gt;基幹システムをSaaSで運用するため、REST APIによるシステム間の疎結合化を推進。API設計・実装・開発チームのディレクションを担当した。&lt;/p&gt;
&lt;h2&gt;SaaS開発&lt;/h2&gt;
&lt;p&gt;コンサルティングだけでなく、自ら手を動かしてシステム開発も行った。&lt;/p&gt;
&lt;h3&gt;都市ガス小売り申込システム&lt;/h3&gt;
&lt;p&gt;都市ガスの小売り申込をWebで完結させるシステム。要件定義から設計・開発・運用まで一気通貫で担当した。&lt;/p&gt;
&lt;h3&gt;LINE Bot EC&lt;/h3&gt;
&lt;p&gt;LINE Bot経由でECサービスを提供する企画。企画段階からの立ち上げで、要件定義・設計・開発・運用を担当した。&lt;/p&gt;
&lt;h3&gt;マイページ&lt;/h3&gt;
&lt;p&gt;ユーザ向けマイページの要件定義を担当。&lt;/p&gt;
&lt;h3&gt;リコール品回収システム&lt;/h3&gt;
&lt;p&gt;倉庫の物流システムと連動したリコール品の回収管理システム。物流側のAPIとの連携を含め、要件定義・設計・開発・運用を担当した。&lt;/p&gt;
&lt;h3&gt;決済連携の自動化&lt;/h3&gt;
&lt;p&gt;基幹システムと決済システムをREST APIで連携し、手作業だった決済処理を自動化。要件定義と設計を担当した。&lt;/p&gt;
</content:encoded></item><item><title>PCI DSSの管理システムアイディア</title><link>https://blog.teraren.com/posts/pci-dss-management-web-service/</link><guid isPermaLink="true">https://blog.teraren.com/posts/pci-dss-management-web-service/</guid><description>Excel管理からの脱却を目指し、PCI DSS準拠項目をキーにしたSaaS型管理ツールのビジネスモデルと機能要件を公開するアイデア記事</description><pubDate>Thu, 29 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;仕事でとあるシステムをPCI DSS準拠する必要があって、そのときの管理台帳がExcelでした。&lt;/li&gt;
&lt;li&gt;そのExcel内に準拠状況や、予定、コメント、タスク、依存関係などを記入して管理していましたが結構大変でした。時系列も追いづらく、アクターもわかりづらいです。&lt;/li&gt;
&lt;li&gt;それを解決するためにPCI DSSの準拠内容をキーとした管理ツールを作ろうと考えていました。その最初のステップが準拠項目の構造データが必要だったので作りました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;企画概要&lt;/h2&gt;
&lt;p&gt;時間が経過してめんどくさくなっちゃったのでアイディアだけ公開しておきます。誰か作ってー。協力するので。ビジネスに失敗したら、監査会社に売れば元は余裕で取れるかと思います。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アクター
&lt;ul&gt;
&lt;li&gt;社内のPCI DSS運用に関わる複数の担当者
&lt;ul&gt;
&lt;li&gt;主にオペレーション周りとシステム周り&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;監査役
&lt;ul&gt;
&lt;li&gt;複数人&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;想定している機能
&lt;ul&gt;
&lt;li&gt;1年に1回の監査対応機能。監査員が項目毎にOKかNGかを記録。事業会社とのやりとりのログを残せる。&lt;/li&gt;
&lt;li&gt;タスク管理と、他のタスク管理サービスへの連携。&lt;/li&gt;
&lt;li&gt;SaaS&lt;/li&gt;
&lt;li&gt;サブスク課金&lt;/li&gt;
&lt;li&gt;準拠項目の定期的なアップデート&lt;/li&gt;
&lt;li&gt;ギャップ分析
&lt;ul&gt;
&lt;li&gt;バーンダウンチャート&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;独自にベロシティを付けるとかして、工数見積もりできるようにするとか。&lt;/li&gt;
&lt;li&gt;自社が準拠すべき項目のフィルタリング
&lt;ul&gt;
&lt;li&gt;準拠しなければいけないレベルは、1〜4ある。1は全ての項目。&lt;/li&gt;
&lt;li&gt;レベル4はSAQ（自己問診票）だけ。SAQ自体もWebで行えるようにして上げても良いかな。SAQは無料で提供してフリーミアム的に作っても良いかも。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;想定している金額
&lt;ul&gt;
&lt;li&gt;日本：3万円/月 * 10社 = 360万円/年&lt;/li&gt;
&lt;li&gt;グローバル：2万円/月 * 100社 = 2,400万円/年&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;原価
&lt;ul&gt;
&lt;li&gt;初期：200万円/年&lt;/li&gt;
&lt;li&gt;保守：50万円/年&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;売り先
&lt;ul&gt;
&lt;li&gt;監査会社&lt;/li&gt;
&lt;li&gt;事業会社&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コメントなどのエビデンスはスマートコントラクトに乗せておく。&lt;/li&gt;
&lt;li&gt;i18n&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;準拠項目のマスタデータは以下にあります。&lt;/p&gt;
&lt;p&gt;https://blog.teraren.com/posts/pci-dss-v3-strucure-in-yaml/&lt;/p&gt;
</content:encoded></item><item><title>PCI DSS v3.2 セキュリティ基準の内容を構造化してみた</title><link>https://blog.teraren.com/posts/pci-dss-v3-strucure-in-yaml/</link><guid isPermaLink="true">https://blog.teraren.com/posts/pci-dss-v3-strucure-in-yaml/</guid><description>PCI DSS v3.2の準拠要件PDFをYAML形式で構造化したデータを公開。ファイアウォール設定から暗号化、アクセス管理まで12要件の全チェック項目を検索しやすい形式にまとめています。</description><pubDate>Wed, 28 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;{/* textlint-disable ja-technical-writing/sentence-length */}&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ja.pcisecuritystandards.org/document_library&quot;&gt;PCIセキュリティ基準&lt;/a&gt;の準拠項目を構造化しました。&lt;/li&gt;
&lt;li&gt;ソース
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/matsubo/0f348fa6cd68d9f45b47&quot;&gt;https://gist.github.com/matsubo/0f348fa6cd68d9f45b47&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;最初は自分でPDFからコピペしていましたが、大変だったのでクラウドソーシングに出して作ってもらいました。&lt;/li&gt;
&lt;li&gt;自分が想定していた速度の3倍くらい速かったので、餅は餅屋だなと思いました。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;- 要件1：カード会員データを保護するために、ファイアウォールをインストールして構成を維持する:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1.1 以下の項目を含むファイアウォールおよびルーター構成基準を確立し、実装する。:
&lt;ul&gt;
&lt;li&gt;1.1 ファイアウォール/ルーター構成基準および以下で指定されたその他文書を検査し、標準が完全で、以下のように実施されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.1.1 すべてのネットワーク接続およびファイアウォール/ルーター構成への変更を承認およびテストする正式なプロセス:
&lt;ul&gt;
&lt;li&gt;1.1.1.a　文書化された手順を調べて、すべてをテストし承認する正式なプロセスがあることを確認する。\n・ネットワーク接続\n・ファイアウォール/ルーター構成への変更&lt;/li&gt;
&lt;li&gt;1.1.1.b　ネットワーク接続のサンプルでは、責任者をインタビューし、記録を検査してネットワーク接続が承認されてテストされていることを確認する。&lt;/li&gt;
&lt;li&gt;1.1.1.c　ファイアウォールおよびルーター構成に実際に加えられた変更のサンプルを特定し、変更記録と比較して、責任者をインタビューして変更が承認されテストされたことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.1.2 ワイヤレスネットワークなど、カード会員データへのすべての接続を示す最新ネットワーク図:
&lt;ul&gt;
&lt;li&gt;1.1.2.a ネットワーク図を検査してネットワーク構成を観察し、現在のネットワーク図が存在すること、また、その文書がワイヤレスネットワークを含む、カード会員データへの全接続を含んでいることを確認する。&lt;/li&gt;
&lt;li&gt;1.1.2.b 責任者をインタビューして、図が最新のものであることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.1.3 システムとネットワーク内でのカード会員データのフローを示す最新図。:
&lt;ul&gt;
&lt;li&gt;1.1.3.a データフロー図を調査し、担当者にインタビューし、図を確認する。\n・システムとネットワークを流れるすべてのカード会員データフローを示している。\n・最新になっているか、必要な環境変更が更新されているか。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.1.4 各インターネット接続、およびDMZ (demilitarized zone)と内部ネットワークゾーンとの間のファイアウォール要件:
&lt;ul&gt;
&lt;li&gt;1.1.4.a ファイアウォール構成基準を調査し、そこに、各インターネット接続、およびDMZと内部ネットワークゾーンとの間のファイアウォール要件が含まれていることを確認する。&lt;/li&gt;
&lt;li&gt;1.1.4.b 現在のネットワーク図が、ファイアウォール構成基準と一致していることを確認する。&lt;/li&gt;
&lt;li&gt;1.1.4.c ネットワーク構成を見て、文書化された構成基準とネットワーク図で、各インターネット接続、およびDMZと内部ネットワークゾーンとの間にファイアウォールが設置されているか確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.1.5 ネットワークコンポーネントを論理的に管理するためのグループ、役割、責任に関する記述:
&lt;ul&gt;
&lt;li&gt;1.1.5.a ファイアウォールおよびルーター構成基準に、ネットワークコンポーネントの管理のためのグループ、役割、責任に関する記述が含まれていることを確認する。&lt;/li&gt;
&lt;li&gt;1.1.5.b ネットワークコンポーネントの管理責任者をインタビューし、文書通りに役割と責任が割り当てられていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.1.6 使用が許可されているすべてのサービス、プロトコル、ポートの文書化、および使用が許可されている業務上の理由(安全でないとみなされているプロトコルに実装されているセキュリティ機能の文書化など)。\n安全でないサービス、プロトコル、ポートの例として、FTP、Telnet、POP3、IMAP、SNMP v1 および v2などがある。:
&lt;ul&gt;
&lt;li&gt;1.1.6.a ファイアウォール/ルーター構成基準に、業務における必要性を含む、すべてのサービス、プロトコル、ポートを文書化したリストが含まれていることを確認する（HTTP（ハイパーテキストプロトコル）、SSL（セキュアソケットレイヤ）、SSH（セキュアシェル）、VPN（仮想プライベートネットワーク）プロトコルなど）。&lt;/li&gt;
&lt;li&gt;1.1.6.b 使用が許可されているが安全でないサービス、プロトコル、ポートを識別し、セキュリティ機能が文書化されていることを確認する。&lt;/li&gt;
&lt;li&gt;1.1.6.c ファイアウォールとルーターの構成を検査し、文書化されているセキュリティ機能が安全でない各サービス、プロトコル、ポートに実装されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.1.7 ファイアウォールおよびルーターのルールセットは少なくとも6カ月ごとにレビューされる必要がある:
&lt;ul&gt;
&lt;li&gt;1.1.7.a ファイアウォール/ルーター構成基準で、ファイアウォールおよびルーターのルールセットを少なくとも 6 カ月ごとにレビューするように要求していることを確認する。&lt;/li&gt;
&lt;li&gt;1.1.7.b ルールセットのレビューに関連した文書を検査し、担当者をインタビューすることで、ルールセットが少なくとも 6 カ月ごとにレビューされていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.2 信頼できないネットワークとカード会員データ環境内のすべてのシステムコンポーネントとの接続を制限するファイアウォール/ルーター構成を構築する。\n注：「信頼できないネットワーク」とは、レビュー対象の事業体に属するネットワーク外のネットワーク、または事業体の制御または管理が及ばないネットワーク(あるいはその両方)のことである。:
&lt;ul&gt;
&lt;li&gt;1.2 ファイアウォール/ルーター構成を調査して、信頼できないネットワークとカード会員データ環境内のシステムコンポーネント間で接続が制限されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.2.1 着信および発信トラフィックを、カード会員データ環境に必要なトラフィックにし、それ以外のすべてのトラフィックを特定的に拒否する。:
&lt;ul&gt;
&lt;li&gt;1.2.1.a ファイアウォール/ルーター構成基準を調べて、カード会員データ環境に必要な着信および発信トラフィックが特定されていることを確認する。&lt;/li&gt;
&lt;li&gt;1.2.1.b 着信および発信トラフィックが、カード会員データ環境に必要なトラフィックに制限されており、制限が文書化されていることを確認する。&lt;/li&gt;
&lt;li&gt;1.2.1.c ファイアウォール/ルーター構成を検査して、たとえば明示の「すべてを拒否」、または許可文の後の暗黙の拒否を使用することで、他のすべての着信および発信トラフィックが明確に拒否されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.2.2 ルーター構成ファイルをセキュリティ保護および同期化する。:
&lt;ul&gt;
&lt;li&gt;1.2.2.a ルーター構成ファイルを調べて、不正アクセスからセキュリティ保護されていることを確認する。&lt;/li&gt;
&lt;li&gt;1.2.2.b ルーター構成を調べて、同期化されていることを確認する。たとえば、実行（アクティブ）構成ファイルが起動構成（マシンの再起動時に使用）に一致することを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.2.3 すべてのワイヤレスネットワークとカード会員データ環境の間に境界ファイアウォールをインストールし、ワイヤレス環境からカード会員データ環境へのすべてのトラフィックを拒否または制御するように(そのようなトラフィックが業務上必要な場合)ファイアウォールを構成する。:
&lt;ul&gt;
&lt;li&gt;1.2.3.a ファイアウォール/ルーター構成を調べて、すべてのワイヤレスネットワークとカード会員データ環境間に境界ファイアウォールがインストールされていることを確認する。&lt;/li&gt;
&lt;li&gt;1.2.3.b ファイアウォールが、ワイヤレス環境とカード会員データ環境間のすべてのトラフィックを拒否または、業務上必要な場合、承認されたトラフィックのみ許可することを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.3 インターネットとカード会員データ環境内のすべてのシステムコンポーネント間の、直接的なパブリックアクセスを禁止する。:
&lt;ul&gt;
&lt;li&gt;1.3 ファイアウォール/ルーター構成を以下に説明するとおりに調査し、インターネットと内部のカード会員ネットワークセグメントのシステムコンポーネント間に直接アクセスがないことを確認する。システムコンポーネントには、インターネットのチョークルーター、DMZルーターおよびファイアウォール、DMZカード会員セグメント、境界ルーター、内部のカード会員ネットワークセグメントなどが含まれる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.3.1 DMZ を実装し、承認された公開サービス、プロトコル、ポートを提供するシステムコンポーネントのみへの着信トラフィックに制限する。:
&lt;ul&gt;
&lt;li&gt;1.3.1 ファイアウォール/ルーター構成を検査し、DMZ が実装され、承認された公開サービス、プロトコル、ポートを提供するシステムコンポーネントのみへの着信トラフィックに制限していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.3.2 着信インターネットトラフィックをDMZ内のIPアドレスに制限する。:
&lt;ul&gt;
&lt;li&gt;1.3.2 ファイアウォール/ルーター構成を検査し、着信インターネットトラフィックが、DMZ 内の IP アドレスに制限されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.3.3 インターネットとカード会員データ環境間トラフィックの、すべての直接接続(着信/発信)を使用不可にする。:
&lt;ul&gt;
&lt;li&gt;1.3.3 ファイアウォール/ルーター構成を検査し、インターネットとカード会員データ環境間トラフィックの直接経路（着信/発信）がないことを確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.3.4 アンチスプーフィング対策を実施し、偽の送信元 IP アドレスを検出して、ネットワークに侵入されないようにブロックする。\n（たとえば、内部送信元アドレスを持つインターネットからのトラフィックをブロックするなど）:
&lt;ul&gt;
&lt;li&gt;1.3.4 ファイアウォールおよびルーター構成を検査し、たとえば、内部アドレスがインターネットからDMZ内へ通過できないなど、スプーフィング対策が実装されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.3.5 カード会員データ環境からインターネットへの発信トラフィックを禁止する。:
&lt;ul&gt;
&lt;li&gt;1.3.5 ファイアウォール/ルーター構成を検査し、カード会員データ環境からインターネットへの発信トラフィックが明示的に承認されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.3.6 動的パケットフィルタリングとも呼ばれる、ステートフルインスペクションを実装する。(ネットワーク内へは、「確立された」接続のみ許可される。):
&lt;ul&gt;
&lt;li&gt;1.3.6 ファイアウォール/ルーター構成を検査し、ファイアウォールがステートフルインスペクション（動的パケットフィルタリング）を実行することを確認する。（確立された接続のみ許可され、前に確立されたセッションに関連付けられている場合にのみ許可される必要がある。）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.3.7 DMZ やその他の信頼できないネットワークから隔離されている内部ネットワークゾーンで、カード会員データを保存するコンポーネント（データベース）が実装されている。:
&lt;ul&gt;
&lt;li&gt;1.3.7 ファイアウォール/ルーター構成を検査し、DMZ やその他の信頼できないネットワークから隔離されている内部ネットワークゾーンで、カード会員データを保存するシステムコンポーネントを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.3.8 プライベート IP アドレスとルーティング情報を許可されていない第三者に開示しない。\n注： IP アドレスを開示しない方法には、以下のものが含まれるが、これらに限定されるわけではない:\n・ネットワークアドレス変換（NAT）\n・カード会員データを保持するサーバをプロキシサーバ/ファイアウォールの背後に配置する。\n・ 登録されたアドレス指定を使用するプライベートネットワークのルートアドバタイズを削除するか、フィルタリングする。\n・ 登録されたアドレスの代わりにRFC1918 アドレス空間を内部で使用する。:
&lt;ul&gt;
&lt;li&gt;1.3.8.a ファイアウォール/ルーター構成を検査し、プライベート IP アドレスおよび内部ネットワークからインターネットへのルーティング情報を開示しない方法が導入されていることを確認する。&lt;/li&gt;
&lt;li&gt;1.3.8.b 担当者のインタビューや文書の調査により、どのプライベートIPアドレスおよび外部事業体へのルーティング情報開示にも許可が必要であることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.4 インターネットに直接接続するすべてのモバイルデバイスまたは従業員所有のデバイス（あるいはその両方）で、ネットワークの外側ではインターネットに接続され、またネットワークへのアクセスにも使用されるものに（従業員が使用するラップトップなど）、パーソナルファイアウォールソフトウェアをインストールする。ファイアウォール構成には以下が含まれます。\n• パーソナルファイアウォールソフトウェア専用の構成設定が定義されていること\n• パーソナルファイアウォールソフトウェアがアクティブに実行中であること\n• パーソナルファイアウォールソフトウェアがモバイルデバイスまたは従業員所有のデバイスのユーザによって変更されていないこと:
&lt;ul&gt;
&lt;li&gt;1.4.a ポリシーと構成基準を調べて以下を確認する：\n• ネットワーク外でインターネットに接続し、ネットワークへのアクセスにも使用される、すべてのモバイルデバイスまたは従業員所有のデバイス（あるいはその両方）にパーソナルファイアウォールソフトウェアが必要とされている\n• パーソナルファイアウォールソフトウェア専用の構成設定が定義されている\n• パーソナルファイアウォールソフトウェアがアクティブに実行するために構成されている\n• パーソナルファイアウォールソフトウェアの構成がモバイルデバイスや従業員所有のデバイスのユーザによって変更できないようになっている&lt;/li&gt;
&lt;li&gt;1.4.b モバイルデバイスまたは従業員所有デバイス（またはその両方）を検査して、以下を確認する。\n• パーソナルファイアウォールソフトウェアがインストールされており、組織の構成設定に従って設定されている\n• パーソナルファイアウォールソフトウェアがアクティブに実行中である\n• パーソナルファイアウォールソフトウェアがモバイルデバイスまたは従業員所有のデバイスのユーザによって変更さていない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1.5 ファイアウォールの管理に関するセキュリティポリシーと操作手順が文書化および使用されており、影響を受ける関係者全員に知らされていることを確認する。:
&lt;ul&gt;
&lt;li&gt;1.5 文書を調べ、関係者をインタビューすることで、ファイアウォールの管理に関するセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n• 文書化されている\n• 使用されている\n• 影響を受ける関係者全員に知らされている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件2：システムパスワードおよび他のセキュリティパラメータにベンダ提供のデフォルト値を使用しない:
&lt;ul&gt;
&lt;li&gt;2.1 システムをネットワークに導入する前に、必ずベンダ提供のデフォルト値を変更し、不要なデフォルトアカウントを無効にする。\nこれは、オペレーティングシステム、セキュリティサービスを提供するソフトウェア、アプリケーション、システムアカウント、ポイントオブセールス（POS）端末、簡易ネットワーク管理プロトコル（SNMP）コミュニティ文字列で使用されるがこれらに限定されない、すべてのデフォルトパスワードに適用されます。:
&lt;ul&gt;
&lt;li&gt;2.1.a システムコンポーネントのサンプルを選択し、ベンダ提供のデフォルトのアカウントとパスワードを使用してデバイスへのログオンを試み（システム管理者の協力を得て）、すべてのデフォルトパスワード（オペレーティングシステム、セキュリティサービスを提供するソフトウェア、アプリケーション、システムアカウント、POS 端末、簡易ネットワーク管理プロトコル（SNMP）コミュニティ文字列で使用されるものを含む）が変更されていることを確認する。（ベンダのマニュアルおよびインターネット上のソースを使用して、ベンダ提供のアカウント/パスワードを探す。）&lt;/li&gt;
&lt;li&gt;2.1.b システムコンポーネントのサンプルで、すべての不要なデフォルトアカウントを検証する（オペレーティングシステム、セキュリティソフトウェア、アプリケーション、システム、POS 端末、SNMP などで使用されているアカウントを含む） が削除または無効化されていることを確認する。&lt;/li&gt;
&lt;li&gt;2.1.c 担当者をインタビューし、関係文書を調べて、以下を確認する。\n• システムをネットワークにインストールする前にすべてのベンダデフォルト（オペレーティングシステム、セキュリティサービスを提供するソフトウェア、アプリケーション、システムアカウント、POS 端末、簡易ネットワーク管理プロトコル（SNMP）コミュニティ文字列のデフォルトパスワード）が変更されている\n• システムがネットワークにインストールされる前にすべての不要なデフォルトアカウント（オペレーティングシステム、セキュリティソフトウェア、アプリケーション、システム、POS 端末、SNMP などで使用されているアカウントを含む） が削除または無効化されている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.1.1 カード会員データ環境に接続されている、またはカード会員データを伝送するワイヤレス環境の場合、インストール時にすべてのワイヤレスベンダのデフォルト値を変更する。これには、デフォルトのワイヤレス暗号化キー、パスワード、SNMPコミュニティ文字列が含まれる(ただし、これらに限定されない)。:
&lt;ul&gt;
&lt;li&gt;2.1.1 ワイヤレス環境のベンダデフォルト設定について、次の事項を確認する。&lt;/li&gt;
&lt;li&gt;2.1.1.a 担当者をインタビューし、関係文書を調べて、以下を確認する。\n• 暗号化キーがインストール時のデフォルトから変更されていること。\n• 暗号化キーの知識を持つ人物が退社または異動するたびに、そのキーが変更されていること。&lt;/li&gt;
&lt;li&gt;2.1.1.b 担当者をインタビューし、ポリシーと手順を調べることで、以下を確認する。\n• デフォルトの SNMP コミュニティ文字列をインストール後に変更する必要があること。\n• アクセスポイントのデフォルトのパスワード/パスフレーズをインストールごとに変更する必要があること。&lt;/li&gt;
&lt;li&gt;2.1.1.c システム管理者の協力を得て、ベンダ文書を調べ、ワイヤレスデバイスにログインして、以下を確認する。\n• ワイヤレスデバイスのデフォルトの SNMP コミュニティ文字列が変更されていないこと。\n• アクセスポイントのデフォルトのパスワード/パスフレーズが変更されていないこと。&lt;/li&gt;
&lt;li&gt;2.1.1.d ベンダ文書を調べ、ワイヤレス構成設定を観察して、ワイヤレスデバイスのファームウェアが、以下の強力な暗号化をサポートするために更新されていることを確認する。\n• ワイヤレスネットワーク経由の認証\n• ワイヤレスネットワーク経由での送信&lt;/li&gt;
&lt;li&gt;2.1.1.e ベンダ文書を調べ、ワイヤレス構成設定を観察することで、必要に応じて、他のセキュリティに関するワイヤレスベンダのデフォルトが変更されたことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.2 すべてのシステムコンポーネントについて、構成基準を作成する。この基準は、すべての既知のセキュリティ脆弱性をカバーし、また業界で認知されたシステム強化基準と一致している必要がある。\n業界で認知されたシステム強化基準のソースには以下が含まれる(これらに限定されない)。\n• Center for Internet Security(CIS)\n• 国際標準化機構(ISO)\n• SysAdmin Audit Network Security(SANS) \nInstitute\n• 米国国立標準技術研究所(NIST):
&lt;ul&gt;
&lt;li&gt;2.2.a すべてのタイプのシステムコンポーネントについて企業のシステム構成基準を調べて、システム構成基準が、業界で認知されたシステム強化基準と一致していることを確認する。&lt;/li&gt;
&lt;li&gt;2.2.b ポリシーを調べ、担当者をインタビューすることで、システム構成基準が、新たな脆弱性の問題が見つかったときに、要件 6.2 で規定されているように更新されていることを確認する&lt;/li&gt;
&lt;li&gt;2.2.c ポリシーを調べ、担当者をインタビューすることで、新しいシステムが構成されたときにシステム構成基準が適用され、ネットワークにシステムがインストールされる前にその実装が検証されたことを確認する。&lt;/li&gt;
&lt;li&gt;2.2.d システム構成基準に、すべての種類のシステムコンポーネントに対する以下の手順が含まれていることを確認する。\n• すべてのベンダ提供デフォルト値を変更し、不要なデフォルトアカウントを削除する\n• 同じサーバに異なったセキュリティレベルを必要とする機能が共存しないように、1 つのサーバには、主要機能を 1 つだけ実装する\n• システムの機能に必要な安全性の高いサービス、プロトコル、デーモンなどのみを有効にする\n• 安全でないとみなされている必要なサービス、プロトコル、またはデーモンに追加のセキュリティ機能を実装する\n• システムセキュリティのパラメータが、誤用を防ぐために設定されている\n• スクリプト、ドライバ、機能、サブシステム、ファイルシステム、不要なWeb サーバなど、不要な機能をすべて削除する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.2.1 同じサーバに異なったセキュリティレベルを必要とする機能が共存しないように、1 つのサーバには、主要機能を 1 つだけ実装する。（たとえば、We サーバ、データベースサーバ、DNS は別々のサーバに実装する必要がある。）\n注： 仮想化テクノロジを使用している場合は、1 つの仮想システムコンポーネントに主要機能を 1 つだけ実装する。:
&lt;ul&gt;
&lt;li&gt;2.2.1.a システムコンポーネントのサンプルを選択し、システム構成を調べて 1 つのサーバに主要機能が 1 つだけ実装されていることを確認する。&lt;/li&gt;
&lt;li&gt;2.2.1.b 仮想テクノロジが使用されている場合は、システム構成を調べて、1 つの仮想システムコンポーネントまたはデバイスに主要機能が 1 つだけ実装されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.2.2 システムの機能に必要な安全性の高いサービス、プロトコル、デーモンなどのみを有効にする。:
&lt;ul&gt;
&lt;li&gt;2.2.2.a システムコンポーネントのサンプルを選択し、有効なシステムサービス、デーモン、プロトコルを検査して、必要なサービスまたはプロトコルだけが有効になっていることを確認する。&lt;/li&gt;
&lt;li&gt;2.2.2.b 有効になっているが安全でないサービス、デーモン、プロトコルを特定し、担当者をインタビューして、それらが文書化された構成基準に従って正当化されていることを確認する。
{/* textlint-disable ja-technical-writing/no-unmatched-pair */}&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.2.3 安全でないとみなされている必要なサービス、プロトコル、またはデーモンにセキュリティ機能を実装する（たとえば、SSH、SFTP、SSL、または IPSec VPN などの安全なテクノロジを使用して、 NetBIOS、ファイル共有、Telnet、FTP などの安全性の低いサービスを保護する:
{/* textlint-enable ja-technical-writing/no-unmatched-pair */}
&lt;ul&gt;
&lt;li&gt;2.2.3.a 構成設定を調べて、安全でないすべてのサービス、デーモン、プロトコルに対するセキュリティ機能が文書化および反映されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.2.4 システムの誤用を防止するためにシステムセキュリティパラメータを構成する。:
&lt;ul&gt;
&lt;li&gt;2.2.4.a システム管理者やセキュリティ管理者にインタビューし、システムコンポーネントの一般的なセキュリティパラメータ設定に関する知識があることを確認する。&lt;/li&gt;
&lt;li&gt;2.2.4.b システム構成基準を調べて、一般的なセキュリティパラメータ設定が含まれていることを確認する。&lt;/li&gt;
&lt;li&gt;2.2.4.c システムコンポーネントのサンプルを選択し、一般的なセキュリティパラメータ設定を調べて、それらが構成基準に従って正しく設定されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.2.5 スクリプト、ドライバ、機能、サブシステム、ファイルシステム、および不要なWebサーバなど、すべての不要な機能を削除する。:
&lt;ul&gt;
&lt;li&gt;2.2.5.a システムコンポーネントのサンプルを選択し、構成を調べ、不要な機能（スクリプト、ドライバ、機能、サブシステム、ファイルシステムなど）がすべて削除されていることを確認する。&lt;/li&gt;
&lt;li&gt;2.2.5.b. 文書とセキュリティパラメータを調べて、有効な機能が文書化されていて、セキュリティ保護された構成をサポートしていることを確認する。&lt;/li&gt;
&lt;li&gt;2.2.5.c. 文書とセキュリティパラメータを調べて、文書化された機能だけがサンプリングされたシステムコンポーネントに存在していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.3 強力な暗号化を使用して、すべてのコンソール以外の管理アクセスを暗号化する。\nWebベースの管理など非コンソール管理アクセスについては、SSH、VPN、またはSSL/TLSなどのテクノロジを使用します。:
&lt;ul&gt;
&lt;li&gt;2.3 システムコンポーネントのサンプルを選択し、コンソール以外の管理アクセスが、以下によって暗号化されていることを確認する。&lt;/li&gt;
&lt;li&gt;2.3.a 各システムへの管理者ログオンを観察し、システム構成を調べて、管理者のパスワードが要求される前に、強力な暗号化メソッドが実行されていることを確認する。&lt;/li&gt;
&lt;li&gt;2.3.b サービスおよびパラメータファイルシステムをレビューし、Telnet やその他の安全でないリモートログインコマンドがコンソール外からのアクセスに使用できないことを確認する。&lt;/li&gt;
&lt;li&gt;2.3.c 管理者の各システムへのログオンを観察し、Web ベースの管理インタフェースへの管理者アクセスが、強力な暗号方式で暗号化されていることを確認する。&lt;/li&gt;
&lt;li&gt;2.3.d ベンダ文書を調べ、担当者をインタビューすることで、使用テクノロジの強力な暗号化が業界のベストプラクティスとベンダの推奨事項に従って導入されていることを確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.4 PCI DSS の適用範囲であるシステムコンポーネントのインベントリを維持する:
&lt;ul&gt;
&lt;li&gt;2.4.a システムのインベントリを調べて、ハードウェアとソフトウェアのコンポーネントリストが維持されており、それぞれの機能/使用に関する説明が含まれていることを確認する。&lt;/li&gt;
&lt;li&gt;2.4.b 担当者をインタビューして、文書化されたインベントリが最新状態に保たれていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.5 ベンダデフォルト値およびその他のセキュリティパラメータの管理に関するセキュリティポリシーと操作手順が文書化されて使用されており、影響を受ける関係者全員に知られていることを確認する:
&lt;ul&gt;
&lt;li&gt;2.5 文書を調べ、関係者をインタビューすることで、ベンダーデフォルトとその他のセキュリティパラメータの管理に関するセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n• 文書化されている\n• 使用されている\n• 影響を受ける関係者全員に知らされている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2.6 共有ホスティングプロバイダは、各事業体のホスト環境およびカード会員データを保護する必要がある。これらのプロバイダは、付録A:「共有ホスティングプロバイダでの追加 PCIDSS 要件」に示されているように、特定の要件を満たす必要がある。:
&lt;ul&gt;
&lt;li&gt;2.6 共有ホスティングプロバイダの PCI DSS 評価について、「付録 A: 共有ホスティングプロバイダ向けの PCI DSS 追加要件」に詳しく説明されているテスト手順 A.1.1 ～ A.1.4 を実行し、共有ホスティングプロバイダが事業体（加盟店およびサービスプロバイダ）のホスト環境およびデータを保護していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件3：保存されるカード会員データを保護する:
&lt;ul&gt;
&lt;li&gt;3.1 データ保存および廃棄ポリシー、手順、プロセスを実装し、すべてのカード会員データ（CHD）ストレージに少なくとも以下のものを含めようにすることで保存するカード会員データを最小限に抑える。\n・保存するデータ量と保存期間を、法律上、規則上、業務上必要な範囲に限定する。\n・必要性がなくなった場合のデータを安全に削除するためのプロセス\n・カード会員データの特定のデータ保存要件\n・定義された保存要件を超えるカード会員データを安全に廃棄する四半期ごとのプロセス。:
&lt;ul&gt;
&lt;li&gt;3.1.a データの保存および廃棄について、ポリシー、手順、プロセスを調べ、少なくとも以下のことが含まれていることを確認する。\n• 以下を含むデータ保存についての、法律上、規制上、業務上の要件\n• カード会員データの保存についての特定の要件（カード会員データは、X の期間、Y という業務上の理由で保存する必要がある、など）。\n• 法律上、規制上、または業務上の理由で不要になったカード会員データの安全な削除\n• カード会員データの保存すべてを対象とする\n• 定義された保存要件を超えるカード会員データを安全に廃棄する四半期ごとのプロセス。&lt;/li&gt;
&lt;li&gt;3.1.b 担当者をインタビューして、以下を確認する。\n• 保存されているカード会員データの場所すべてがデータ保存および破棄プロセスに含まれている。\n• カード会員データを見つけて安全に廃棄する四半期ごとの自動または手動プロセスが含まれている。\n• カード会員データのすべての場所に対して四半期ごとの自動または手動プロセスが実施されている。&lt;/li&gt;
&lt;li&gt;3.1.c カード会員データを保存するシステムコンポーネントのサンプル\n• ファイルとシステムレコードを調べて、保存されているデータがデータ保存ポリシーで定義された要件を超えていないことを確認する。\n• 削除方法を観察して、データが安全に削除されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.2 承認後に機密認証データを保存しない（暗号化されている場合でも）。機密認証データを受け取った場合、認証プロセスが完了し次第すべてのデータを復元不可能にする。\n以下の場合に、データが安全に保存される場合は、発行者と企業が、機密認証データを保存するため、発行サービスをサポート可能である。\n• 業務上の理由がある\n• データが安全に保存されている\n機密認証データには、以降の要件 3.2.1～ 3.2.3 で言及されているデータを含む。:
&lt;ul&gt;
&lt;li&gt;3.2.a サービスの発行をサポートし、機密認証データを保存する\n発行者または会社について、機密認証データの保存に関して業務上の理由があることを確認する。&lt;/li&gt;
&lt;li&gt;3.2.b サービスの発行をサポートし、機密認証データを保存する発行者または会社について、データストアとシステム構成を調べて、機密認証データがセキュリティで保存されていることを確認する。&lt;/li&gt;
&lt;li&gt;3.2.c その他のすべての事業体では、機密認証データを受信した場合、ポリシーと手順をレビューし、システム構成を調べて、認証後にデータが保存されていないことを確認します。&lt;/li&gt;
&lt;li&gt;3.2.d その他のすべての事業体では、機密認証データを受け取った場合、手順をレビューしてデータを安全に削除するプロセスを調べ、データが回復不能であることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.2.1 （カードの背面やチップ上の同等のデータなどにある磁気ストライプの）追跡データの完全な内容を保存しない。このデータは、全トラック、トラック、トラック 1、トラック 2、磁気ストライプデータとも呼ばれます。\n注： 通常の取引過程では、磁気ストライプからの以下のデータ要素を保存する必要が生じる場合があります。\n・ カード会員名\n・プライマリアカウント番号（PAN）\n・ 有効期限\n・ サービスコードリスクを最小限に抑えるため、取引に必要なデータ要素のみを保存します。:
&lt;ul&gt;
&lt;li&gt;3.2.1 システムコンポーネントのサンプルで、データソースを調べる。これには、以下の項目が含まれるがこれらに限定されない。また、カード裏面の磁気ストライプまたはチップの同等データから得られたトラック内容が、承認後、保存されていないことを確認する。\n・受信トランザクションデータ\n・すべてのログ（トランザクション、履歴、デバッグ、エラーなど）\n・履歴ファイル\n・トレースファイル\n・データベーススキーマ\n・データベースコンテンツ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.2.2 カードを提示しない取引を検証するために使用された、カード検証コードまたは値（ペイメントカードの前面または背面に印字されている 3 桁または 4 桁の数字）を保存しない。:
&lt;ul&gt;
&lt;li&gt;3.2.2 システムコンポーネントのサンプルについて、カード前面または署名欄に印字されている 3 桁または 4 桁のカード検証コードまたは値（CVV2、CVC2、CID、CAV2 データ）を含む\n（ただし、これらに限定されない）データソースを調べて、これらが、承認後、保存されないことを確認する。\n・受信トランザクションデータ\n・すべてのログ（トランザクション、履歴、デバッグ、エラーなど）\n・履歴ファイル\n・トレースファイル\n・データベーススキーマ\n・データベースコンテンツ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.2.3 個人識別番号（PIN）または暗号化されたPINブロックを保存しない。:
&lt;ul&gt;
&lt;li&gt;3.2.3 システムコンポーネントのサンプルについて、データソースを調べる。これには PIN および暗号化された PIN ブロックが、承認後、保存されないことの確認も含まれる（ただし、これらに限定されない）。\n・受信トランザクションデータ\n・すべてのログ（トランザクション、履歴、デバッグ、エラーなど）\n・履歴ファイル\n・トレースファイル\n・データベーススキーマ\n・データベースコンテンツ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.3 表示時に PAN をマスクして（最初の 6 桁と最後の 4 桁が最大表示桁数）、業務上の正当な必要性がある関係者だけが PAN 全体を見ることができるようにする。注： カード会員データの表示（法律上、またはペイメントカードブランドによる POS レシート要件など）に関するこれより厳しい要件がある場合は、その要件より優先されることはありません。:
&lt;ul&gt;
&lt;li&gt;3.3.a PAN の表示をマスクするための、書面によるポリシーと手順を調べて、以下を確認する。\n• PAN 全体の表示へのアクセスを必要とする役割の一覧が、各役割がそのようなアクセス権を持つ必要性の正当な業務上の理由と共に文書化されていること。\n• PAN は、業務上の合法的な必要性により PAN 全体を見る必要がある担当者のみが PAN 全体をできるようにマスクする必要がある。\n• PAN 全体を表示する承認のない役割の者はすべて、マスクされた PAN しか見えなくする。&lt;/li&gt;
&lt;li&gt;3.3.b システム構成を調べて、文書化された業務上の必要性のあるユーザ/役割に対してのみ PAN 全体が表示され、他のすべての表示要求に対しては PAN はマスクされることを確認する。&lt;/li&gt;
&lt;li&gt;3.3.c PAN の表示（画面、紙のレシートなど）を調べて、業務上の合法的な必要性により PAN 全体を見る必要のある場合を除き、カード会員データを表示する際に PAN がマスクされることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.4 以下の手法を使用して、すべての保存場所でPANを読み取り不能にする(ポータブルデジタルメディア、バックアップメディア、ログを含む)。\n• 強力な暗号化をベースにしたワンウェイハッシュ(PAN全体をハッシュする必要がある)\n• トランケーション(PANの切り捨てられたセグメントの置き換えにはハッシュを使用できない)\n• インデックストークンとパッド(パッドは安全に保存する必要がある)\n• 関連するキー管理プロセスおよび手順を伴う、強力な暗号化\n注： 悪意のある個人がトランケーションされたPANとハッシュ化されたPANの両方を取得した場合、元の PAN を比較的できますができます。ハッシュ化および切り捨てられた PAN の同じバージョンが事業体の環境に存在する場合、元の PAN を再構築するために、ハッシュ化および切り捨てられたバージョンを関連付けることはできないことを確認する追加コントロールを導入する必要があります。:
&lt;ul&gt;
&lt;li&gt;3.4.a 以下の方法を用いて、ベンダ、システム/プロセスのタイプ、暗号化アルゴリズム（該当する場合）などが記載された、PAN の保護に使用されているシステムに関する文書を調べる。\n• 強力な暗号化技術をベースにしたワンウェイハッシュ\n• トランケーション\n• インデックストークンとパッド(パッドは安全に保存する必要がある)\n• 関連するキー管理プロセスおよび手順を伴う、強力な暗号化&lt;/li&gt;
&lt;li&gt;3.4.b データリポジトリのサンプルから複数のテーブルまたはファイルを検査し、PANが読み取り不能になっていることを確認する（平文で保存されていない）。&lt;/li&gt;
&lt;li&gt;3.4.c リムーバブルメディア（バックアップテープなど）を検査し、PAN が読み取り不能であることを確認する。&lt;/li&gt;
&lt;li&gt;3.4.d 監査ログのサンプルを検査し、PAN が読み取り不能であることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.4.1 （ファイルまたは列レベルのデータベース暗号化ではなく）ディスク暗号化が使用される場合、論理アクセスはネイティブなオペレーティングシステムの認証およびアクセス制御メカニズムとは別に管理する必要がある（ローカルユーザアカウントデータベースや一般的なネットワークログイン資格情報を使用しないなどの方法で）。復号キーがユーザアカウントと\n関連付けられていない:
&lt;ul&gt;
&lt;li&gt;3.4.1.a ディスク暗号化を使用している場合、構成を調べて、認証プロセスを観察し、暗号化されたファイルシステムへの論理アクセスが、ネイティブなオペレーティングシステムのメカニズムとは別のメカニズムで実装されていることを確認する\n（ローカルユーザアカウントデータベースや一般的なネットワークログイン資格情報を使用しないなどの方法で）。&lt;/li&gt;
&lt;li&gt;3.4.1.b プロセスを観察し、担当者をインタビューすることで、暗号化キーが安全に保存されていることを確認する（強力なアクセス制御で適切に保護されているリムーバブルメディアに保存されているなど）。&lt;/li&gt;
&lt;li&gt;3.4.1.c 構成を調べて、プロセスを観察することで、どこに保存されている場合でも、リムーバブルメディアのカード会員データが暗号化されていることを確認する。\n注： ディスク暗号化がリムーバブルメディアの暗号化に使用されていない場合は、この媒体に保存されるデータを、他の方法を使って、読み取り不能にする必要があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.5 カード会員データを漏洩と誤用から保護するために使用されるキーを保護するための手順を文書化し、実施する。\n注： この要件は、保存されているカード会員データを暗号化するキーに適用され、またデータ暗号化キーの保護に使用するキー暗号化キーにも適用される。つまり、キー暗号化キーは、少なくともデータ暗号化キーと同じ強度を持つ必要がある。:
&lt;ul&gt;
&lt;li&gt;3.5 キー管理ポリシーと手順を調べて、プロセスがカード会員データを暗号化したキーを漏洩と誤使用から保護する指定となっており、少なくとも以下を含むことを確認する。\n• 暗号化キーへのアクセスが必要最小限の管理者に制限されている\n• キー暗号化キーが少なくとも保護対象データの暗号化キーと同じ強度を持つ\n• キー暗号化キーがデータ暗号化キーとは別に保存されている\n• キーの保存場所と形式を最小限にし、安全に保存する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.5.1 暗号化キーへのアクセスを、必要最小限の管理者に制限する。:
&lt;ul&gt;
&lt;li&gt;3.5.1 ユーザアクセスリストを調査し、キーへのアクセスが必要最小限の管理者に制限されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.5.2 カード会員データの暗号化に使用される秘密暗号化キーは、以下のいずれかの形式（複数可）で常時保存する。\n• 少なくともデータ暗号化キーと同じ強度のキー暗号化キーで暗号化されており、データ暗号化キーとは別の場所に保存されている\n• 安全な暗号化デバイス（ホストセキュリティモジュール（HSM）または PTS 承認の加盟店端末装置など）内\n• 業界承認の方式に従う、少なくとも 2 つの全長キーコンポーネントまたはキー共有として\n注： 公開キーがこれらの形式で保存されていることは要求されていません。:
&lt;ul&gt;
&lt;li&gt;3.5.2.a 文書化された手順を調べて、カード会員データの暗号化に使用される暗号化キーが常に以下のいずれかの形式でのみ存在することを確認する。\n• 少なくともデータ暗号化キーと同じ強度のキー暗号化キーで暗号化されており、データ暗号化キーとは別の場所に保存されている\n• 安全な暗号化デバイス（ホストセキュリティモジュール（HSM）または PTS 承認の加盟店端末装置など）内\n• 業界承認の方式に従う、キーコンポーネントまたはキー共有として&lt;/li&gt;
&lt;li&gt;3.5.2.b システム構成とキー保存場所を調べて、カード会員データの暗号化に使用される暗号化キーが常に次のいずれかの形式（複数可）で存在していることを確認する。\n• キー暗号化キー付き暗号化\n• 安全な暗号化デバイス（ホストセキュリティモジュール（HSM）または PTS 承認の加盟店端末装置など）内\n• 業界承認の方式に従う、キーコンポーネントまたはキー共有として&lt;/li&gt;
&lt;li&gt;3.5.2.c キー暗号化キーを使用する場合、システム構成とキー保存場所を調べて、以下を確認する。\n• キー暗号化キーが少なくとも保護対象データの暗号化キーと同じ強度を持つ\n• キー暗号化キーがデータ暗号化キーとは別に保存されている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.5.3 暗号化キーを最小限の場所に保存する。:
&lt;ul&gt;
&lt;li&gt;3.5.3 キーの保存場所を調べ、プロセスを観察し、必要最小限の場所にキーが保存されていることを確認する。
{/* textlint-disable ja-technical-writing/no-unmatched-pair */}&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.6 カード会員データの暗号化に使用される以下の暗号化キーのキー管理プロセスおよび手順をすべて文書化し、実装する。これには、以下が含まれる。\n注：キー管理には多数の業界標準があり、NIST(http://csrc.nist.govを参照)などさまざまなリソースから入手可能である。:
{/* textlint-enable ja-technical-writing/no-unmatched-pair */}
&lt;ul&gt;
&lt;li&gt;3.6.a サービスプロバイダ用の追加手順：サービスプロバイダがカード会員データの伝送に使用するキーを顧客と共有している場合、サービスプロバイダが顧客に提供する文書を調べて、以下の要件 3.6.1〜3.6.8 に従って、顧客のキー（顧客とサービスプロバイダ間でデータを伝送するために使用される）を安全に伝送、保存、変更する方法が記述されていることを確認する。&lt;/li&gt;
&lt;li&gt;3.6.b カード会員データの暗号化に使用される暗号化キーの管理手順とプロセスを調べて、以下を行う。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.6.1 強力な暗号化キーの生成:
&lt;ul&gt;
&lt;li&gt;3.6.1.a キー管理手順に、強力なキーの生成方法が指定されていることを確認する。&lt;/li&gt;
&lt;li&gt;3.6.1.b キーの生成方法を観察して、強力なキーが生成されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.6.2 安全な暗号化キーの配布:
&lt;ul&gt;
&lt;li&gt;3.6.2.a キー管理手順に、キーの安全な配布方法が指定されていることを確認する。&lt;/li&gt;
&lt;li&gt;3.6.2.b キーを配布する方法を観察し、キーが安全に配布されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.6.3 安全な暗号化キーの保存:
&lt;ul&gt;
&lt;li&gt;3.6.3.a キー管理手順に、キーの安全な保存方法が指定されていることを確認する。&lt;/li&gt;
&lt;li&gt;3.6.3.b キーを保存する方法を観察して、キーが安全に保存されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.6.4 関連アプリケーションベンダまたはキーオーナーが定義し、業界のベストプラクティスおよびガイドライン(たとえば、NIST Special Publication 800-57)に基づいた、暗号化期間の終了時点に到達したキーの暗号化キーの変更。暗号化期間の終了時点とは、たとえば、定義された期間が経過した後、または付与されたキーで一定量の暗号化テキストを作成した後(またはその両方)である。:
&lt;ul&gt;
&lt;li&gt;3.6.4.aキー管理手順に、使用されている各キータイプ用の暗号化期間の定義が含まれており、定義された暗号化期間の終わりに行うキー変更のプロセスが定義されていることを確認する。&lt;/li&gt;
&lt;li&gt;3.6.4.b 担当者をインタビューすることで、定義された暗号化期間の終わりにキーが変更されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.6.5 クリアテキストキーの知識を持つ従業員が離職したなど、キーの整合性が脆弱になっている場合、またはキーの脆弱性が悪用された可能性がある場合に必要な、キーの破棄または取り替え（アーカイブ、破壊、無効化など）。\n注： 破棄された、または取り替えられた暗号化キーを保持する必要がある場合、そのキーを（たとえば、キー暗号化キーを使用することにより）安全にアーカイブする必要がある。アーカイブされた暗号化キーは、復号/検証の目的のためにのみ使用できます。:
&lt;ul&gt;
&lt;li&gt;3.6.5.a キー管理手順に、以下のプロセスが指定されていることを確認する。\n• キーの整合性が脆弱になったときのキーの破棄または取り替え。\n• 侵害されたことがわかっているまたは疑われるキーの取り替え。\n• 破棄された、または取り替えられたキーを保持する場合、そのキーが暗号化操作に使用されていないこと。&lt;/li&gt;
&lt;li&gt;3.6.5.b　担当者をインタビューすることで、以下のプロセスが実施されていることを確認する。\n• キーの知識を持つ従業員が退職した場合など、キーの整合性が脆弱になったときに必要に応じてキーを破棄する、または取り替える。\n• 侵害されたことがわかっているまたは疑われるキーが取り替えられている。\n• 破棄された、または取り替えられたキーを保持する場合、そのキーが暗号化操作に使用されていないこと。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.6.6 平文暗号化キー管理を手動で操作する場合、キーの知識分割と二重管理を使用する必要がある。\n注： 手動のキー管理操作の例には、キーの生成、伝送、読み込み、保存、破棄などが含まれますが、これらに限定されません:
&lt;ul&gt;
&lt;li&gt;3.6.6.a 手動の平文キー管理手順に、以下のプロセスが指定されていることを確認する。\n• キー知識の分割により、キーコンポーネントが 2 人以上の管理下に置かれ、各人は自分のキーコンポーネントに関する知識しか持たないようにする。および\n• キーの二重管理により、どのようなキー管理操作を行う場合にも 2 人以上を必要とし、どちらも他方の認証情報（パスワードやキーなど）にアクセスできないようにする。&lt;/li&gt;
&lt;li&gt;3.6.6 b 担当者をインタビューするかプロセスを観察して、手動の平文キーが次の方法で管理されていることを確認する。\n• 知識分割、および\n• 二重管理&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.6.7 暗号化キーの不正置換の防止。:
&lt;ul&gt;
&lt;li&gt;3.6.7.a キー管理手順で、キーの不正置換を防止するプロセスが指定されていることを確認します。&lt;/li&gt;
&lt;li&gt;3.6.7.b 担当者をインタビューするかプロセスを観察して、キーの不正置換が防止されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.6.8 暗号化キー管理者が自身の責務を理解し、キー管理者としての責務を受諾する。:
&lt;ul&gt;
&lt;li&gt;3.6.8.a キー管理手順に、キー管理者が自身の責務を理解し、キー管理者としての責務を受諾したことを示す書面または電子ファイルへの署名を要求するプロセスが指定されていることを確認する。&lt;/li&gt;
&lt;li&gt;3.6.8.b キー管理手順に、キー管理者がキー管理者としての責務を理解し、受諾したことを書面または電子的に示す文書または他の証拠を調べる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;3.7 保存されているカード会員データを保護するためのセキュリティポリシーと操作手順が文書化および使用されており、影響を受ける関係者全員に知られていることを確認する。:
&lt;ul&gt;
&lt;li&gt;3.7 文書を調べ、関係者をインタビューすることで、保存されているカード会員データを保護するためのセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n• 文書化されている\n• 使用されている\n• 影響を受ける関係者全員に知らされている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件4：オープンな公共ネットワーク経由でカード会員データを伝送する場合、暗号化する:
&lt;ul&gt;
&lt;li&gt;4.1 オープンな公共ネットワーク経由で機密性の高いカード会員データを伝送する場合、以下のような、強力な暗号化とセキュリティプロトコル（SSL/TLS、IPSEC、SSH など）を使用して保護する。\n• 信頼できるキーと証明書のみを受け入れる\n• 使用されているプロトコルが、安全なバージョンまたは構成のみをサポートしている\n• 暗号化の強度が使用中の暗号化方式に適している\nオープンな公共ネットワークの例として\n以下が挙げられるが、これらに限定されない。\n・インターネット\n・802.11 と Bluetooth（ブルートゥース）を含\nむワイヤレステクノロジ\n・Global System for Mobile communications（GSM） や Code division multiple access（CDMA） などの携帯端末テクノロジ\n・General Packet Radio Service （GPRS）\n・ 衛星通信:
&lt;ul&gt;
&lt;li&gt;4.1 カード会員データがオープンな公共ネットワーク経由で送受信される場所をすべて特定し、文書化された基準を調べ、システム構成を比較して、すべての場所でセキュリティプロトコルと強力な暗号化が使用されていることを確認する。&lt;/li&gt;
&lt;li&gt;4.1.a 文書化されたポリシーと手順を調べて、以下のプロセスが指定されていることを確認する。\n• 信頼できるキーまたは証明書（あるいはその両方）のみが受け付けられている\n• 使用されているプロトコルが安全なバージョンと構成のみをサポートしており、安全でないバージョンや構成がサポートされない\n• 使用中の暗号化手法に、適切な強度の暗号化が実装されている&lt;/li&gt;
&lt;li&gt;4.1.b 発信と着信トランザクションのサンプルを選び、トランザクションを実際に観察し、カード会員データが転送中に強力な暗号で暗号化されているかどうかを確認する。&lt;/li&gt;
&lt;li&gt;4.1.c キー/証明書を調べて、信頼できるキー/証明書のみが受け付けられていることを確認する。&lt;/li&gt;
&lt;li&gt;4.1.d システム構成を調べて、プロトコルの安全な構成のみが使用され、安全でないバージョンまたは構成がサポートされないことを確認する。&lt;/li&gt;
&lt;li&gt;4.1.e システム構成を調べて、使用中の暗号化手法に、適切な強度の暗号化が実装されていることを確認する（ベンダの推奨事項/ベストプラクティスを確認する）。&lt;/li&gt;
&lt;li&gt;4.1.f SSL/TLS 実装の場合：システム構成を調べて、カード会員データの送受信時に SSL/TLS が有効になっていることを確認する。\nたとえば、ブラウザベースの実装の場合：\n・ ブラウザの URL プロトコルとして HTTPS が表示される\n・カード会員データは、URL に HTTPS が表示される場合にのみ要求される&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;4.1.1 カード会員データを伝送する、またはカード会員データ環境に接続されているワイヤレスネットワークが、認証および伝送用に強力な暗号化を実装するため、業界のベストプラクティス（IEEE 802.11i 規格など）を使用していることを確認する。\n注： セキュリティ制御としての WEP の使用は、禁止されています。:
&lt;ul&gt;
&lt;li&gt;4.1.1 カード会員データを伝送する、またはカード会員データ環境に接続されているすべてのワイヤレスネットワークを識別する。文書化されている基準を調べ、システム構成設定と比較して、識別されたすべてのワイヤレスネットワークについて以下を確認する。\n• 業界のベストプラクティス（IEEE 802.11i など）を使用して認証および伝送用の強力な暗号化が実装されている。\n• 認証や送信のセキュリティ制御に弱い暗号化（WEP、SSLバージョン 2.0 以前など）が使用されていない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;4.2 保護されていないPANをエンドユーザメッセージングテクノロジ(電子メール、インスタントメッセージング、チャットなど)で送信しない。:
&lt;ul&gt;
&lt;li&gt;4.2.a エンドユーザメッセージングテクノロジを使用してカード会員データを送信する場合は、PAN を送信するプロセスを観察し、送信内容のサンプルを調査して、PAN を読み取り不能にするか、強力な暗号化で保護していることを確認する。&lt;/li&gt;
&lt;li&gt;4.2.b 文書化されているポリシーを調べ、保護されていないPANがエンドユーザメッセージングテクノロジを介して送信されないことを記したポリシーの存在を確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;4.3 カード会員データの伝送を暗号化するためのセキュリティポリシーと操作手順が文書化されて使用されており、影響を受ける関係者全員に知られていることを確認する。:
&lt;ul&gt;
&lt;li&gt;4.3 文書を調べ、関係者をインタビューすることで、カード会員データの伝送を暗号化するためのセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n・ 文書化されている\n・ 使用されている\n・ 影響を受ける関係者全員に知らされている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件5：アンチウィルスソフトウェアまたはプログラムを使用し、定期的に更新する:
&lt;ul&gt;
&lt;li&gt;5.1 悪意のあるソフトウェアの影響を受けやすいすべてのシステム(特にパーソナルコンピュータとサーバ)に、ウィルス対策ソフトウェアを導入する。:
&lt;ul&gt;
&lt;li&gt;5.1 悪意のあるソフトウェアの影響を受けやすいすべてのオペレーティングシステムタイプを含む、システムコンポーネントのサンプルについて、適用可能なウィルス対策テクノロジが存在する場合は、ウィルス対策ソフトウェアが導入されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;5.1.1 ウィルス対策プログラムが、既知の悪意のあるソフトウェアの全タイプに対して、検出、削除、保護が可能であることを確認する。:
&lt;ul&gt;
&lt;li&gt;5.1.1 ベンダ文書を読み、ウィルス対策構成を調べて、ウィルス対策プログラムが以下を行うことを確認する\n• 既知の悪意のあるソフトウェアの全タイプを検出する。\n• 既知の悪意のあるソフトウェアの全タイプを削除する。\n• 既知の悪意のあるソフトウェアの全タイプから保護する。\n例として、ウィルス、トロイの木馬、ワーム、スパイウェア、アドウェア、ルートキットなどがあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;5.1.2 一般的に悪意のあるソフトウェアに影響されないとみなされているシステムでは、定期的に評価して、進化を続けるマルウェアの脅威を特定して評価することで、システムにウィルス対策ソフトウェアが依然として必要ないかどうかを判断する:
&lt;ul&gt;
&lt;li&gt;5.1.2.b 担当者をインタビューすることで、システムにウィルス対策ソフトウェアが依然として必要ないかどうかを判断するために、進化を続けるマルウェアの脅威の、一般的に悪意のあるソフトウェアに影響されないとみなされているシステムに対する影響が監視されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;5.2 すべてのウィルス対策メカニズムが以下のように維持されていることを確認する。\n• 最新の状態である\n• 定期的にスキャンを行う\n• PCI DSS 要件 10.7 に従って監査ロ\n・保持する:
&lt;ul&gt;
&lt;li&gt;5.2 すべてのアンチウィルスソフトウェアが最新で、有効に実行されており、監査ログが生成されることを確認するために、以下の項目を確認する。&lt;/li&gt;
&lt;li&gt;5.2.a ポリシーと手順を調べて、ウィルス対策ソフトウェアおよび定義を最新状態に保つことが要求されていることを確認する。&lt;/li&gt;
&lt;li&gt;5.2.b ソフトウェアのマスタインストールを含め、ウィルス対策構成を調べることで、ウィルス対策メカニズムが以下を満たすことを確認する。\n• 自動更新するように構成されている\n• 定期的にスキャンするように構成されている&lt;/li&gt;
&lt;li&gt;5.2.c 悪意のあるソフトウェアの影響を受けやすいすべてのオペレーティングシステムタイプを含む、システムコンポーネントのサンプルについて、以下を確認する。\n• ウィルス対策ソフトウェアと定義が最新である。\n• 定期的なスキャンが実行される。&lt;/li&gt;
&lt;li&gt;5.2.d ソフトウェアのマスタインストールを含め、ウィルス対策構成を調べることで、ウィルス対策メカニズムが以下を満たすことを確認する。\n• ウィルス対策ソフトウェアログの生成が有効になっている\n• ログが PCI DSS 要件 10.7 に従って保持されている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;5.3 ウィルス対策メカニズムがアクティブに実行されており、経営管理者からケースバイケースで期間を限って特別に許可されない限り、ユーザが無効にしたり変更できないことを確認する。\n注： ウィルス対策ソリューションは、ケースバイケースで経営管理者により許可されたことを前提に、正当な技術上のニーズがある場合に限り、一時的に無効できますす。特定の目的でアンチウィルス保護を無効にする必要がある場合、正式な許可を得る必要があります。アンチウィルス保護が無効になっている間、追加のセキュリティ手段が必要になる場合があります。:
&lt;ul&gt;
&lt;li&gt;5.3.a ソフトウェアのマスタインストールとシステムコンポーネントのサンプルを含め、ウィルス対策構成を調べることで、ウィルス対策ソフトウェアがアクティブに実行されていることを確認する。&lt;/li&gt;
&lt;li&gt;5.3.b ソフトウェアのマスタインストールとシステムコンポーネントのサンプルを含め、ウィルス対策構成を調べることで、ウィルス対策ソフトウェアがユーザによって無効化・変更できないことを確認する。&lt;/li&gt;
&lt;li&gt;5.3.c 責任者をインタビューし、プロセスを観察することで、ウィルス対策ソフトウェアは、経営管理者からケースバイケースで期間を限って特別に許可されない限り、ユーザが無効化・変更できないことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;5.4 マルウェアからシステムを保護するためのセキュリティポリシーと操作手順が文書化されて使用されており、影響を受ける関係者全員に知られていることを確認する。:
&lt;ul&gt;
&lt;li&gt;5.4 文書を調べ、関係者をインタビューすることで、マルウェアからシステムを保護するためのセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n• 文書化されている\n• 使用されている\n• 影響を受ける関係者全員に知らされている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件6：安全性の高いシステムとアプリケーションを開発し、保守する:
&lt;ul&gt;
&lt;li&gt;6.1 セキュリティ脆弱性情報の信頼できる社外提供元を使ってセキュリティの脆弱性を特定し、新たに発見されたセキュリティの脆弱性にリスクのランク（「高」、「中」、「低」など）を割り当てるプロセスを確立する。\n注： リスクのランク分けは、業界のベストプラクティスと考えられる影響の程度に基づいている必要があります。たとえば、脆弱性をランク分けする基準は、CVSS ベーススコア、ベンダによる分類、影響を受けるシステムの種類などを含む場合があります。\n脆弱性を評価し、リスクのランクを割り当てる方法は、組織の環境とリスク評価戦略によって異なります。リスクのランクは、最小限、環境に対する「高リスク」とみなされるすべての脆弱性を特定するものである必要があります。リスクのランク分けに加えて、環境に対する差し迫った脅威をもたらす、重要システムに影響を及ぼす、対処しないと侵害される危険がある場合、脆弱性は「重大」とみなされます。重要システムの例としては、セキュリティシステム、一般公開のデバイスやシステム、データベース、およびカード会員データを保存、処理、送信するシステムなどがあります。:
&lt;ul&gt;
&lt;li&gt;6.1.a ポリシーと手順を調べ、以下のプロセスが定義されていることを確認する。\n• 新しいセキュリティの脆弱性の識別\n• すべての「高」リスクと「重大」な脆弱性の識別を含む脆弱性のランク分けの割り当て\n• セキュリティ脆弱性情報の信頼できる外部情報源の使用&lt;/li&gt;
&lt;li&gt;6.1.b 担当者をインタビューするかプロセスを観察して、以下を確認する。\n• 新しいセキュリティの脆弱性が識別されている\n• すべての「高」リスクと「重大」な脆弱性の識別を含む脆弱性のランク分けが割り当てられている\n• 新しいセキュリティの脆弱性を特定するプロセスに、セキュリティ脆弱性情報を得るための外部情報源の使用が含まれている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.2 すべてのシステムコンポーネントとソフトウェアに、ベンダ提供のセキュリティパッチがインストールされ、既知の脆弱性から保護されている。重要なセキュリティパッチは、リリース後 1 カ月以内にインストールする。\n注： 要件 6.1 で定義されているリスクのランク分けプロセスに従って、重要なセキュリティパッチを識別する必要があります:
&lt;ul&gt;
&lt;li&gt;6.2.a セキュリティパッチのインストールに関連したポリシーと手順を調べて、以下のプロセスが定義されていることを確認する。\n• 該当する、ベンダ提供の重要セキュリティパッチは、リリース後 1 カ月以内にインストールする。\n• 該当する、ベンダ提供のセキュリティパッチをすべて、適切な時間枠内（3 カ月以内など）にインストールする。&lt;/li&gt;
&lt;li&gt;6.2.b システムコンポーネントおよび関連ソフトウェアのサンプルについて、各システムにインストールされたセキュリティパッチのリストと、ベンダの最新のセキュリティパッチのリストを比較して、以下を確認する。\n• 該当する、ベンダ提供の重要セキュリティパッチは、リリース後1 カ月以内にインストールする。\n• 該当するすべてのベンダが提供するセキュリティパッチは、適切な時間枠（たとえば 3 カ月以内）内に設置されている。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.3 内部および外部ソフトウェアアプリケーション（アプリケーションへの Webベースの管理アクセスを含む）を次のように開発する。\n• PCI DSS （安全な認証やロギングなど）に従って。\n• 業界基準やベストプラクティスに基づいて。\n• ソフトウェア開発ライフサイクル全体に情報セキュリティを組み込む。\n注：これは、社内開発ソフトウェアすべて、および第三者によって開発されたカスタムソフトウェアにも当てはまります。:
&lt;ul&gt;
&lt;li&gt;6.3.a 文書化されたソフトウェア開発プロセスを調べて、プロセスが業界標準またはベストプラクティス（あるいはその両方）に基づいていることを確認する。&lt;/li&gt;
&lt;li&gt;6.3.b 記述されたソフトウェア開発プロセスを検査し、ライフサイクル全体に情報セキュリティが組み込まれていることを確認する。&lt;/li&gt;
&lt;li&gt;6.3.c 記述されたソフトウェア開発プロセスを検査し、PCI DSS に従って、ソフトウェアアプリケーションが開発されていることを確認する。&lt;/li&gt;
&lt;li&gt;6.3.d ソフトウェア開発者のインタビューから、文書化されたソフトウェア開発プロセスが実装されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.3.1 アプリケーションがアクティブになる前、または顧客にリリースされる前に、テスト/カスタムアプリケーションアカウント、ユーザ ID、パスワードを削除する:
&lt;ul&gt;
&lt;li&gt;6.3.1 文書化されたソフトウェア開発手順を調べ、責任者をインタビューすることで、本番前とカスタムアプリケーションアカウント、ユーザ ID/パスワードが、システムが本番環境に導入される、または顧客にリリースされる前に削除されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.3.2 コーディングの脆弱性がないことを確認するための、本番または顧客のリリース前のカスタムコードのレビューする（手動または自動プロセスによる）。\n・コード変更は、コード作成者以外の、コードレビュー手法と安全なコーディング手法の知識のある人がレビューする。\n・ コードレビューにより、コードが安全なコーディングガイドラインに従って開発されたことが保証される\n・ リリース前に、適切な修正を実装している。\n・ コードレビュー結果は、リリース前に管理職によってレビューおよび承認される。\n注： このコードレビュー要件は、システム開発ライフサイクルの一環として、すべてのカスタムコード（内部および公開）に適用される。\nコードレビューは、知識を持つ社内担当者または第三者が実施できる。一般に公開されている Web アプリケーションは、実装後の脅威および脆弱性に対処するために、PCI DSS 要件 6.6 に定義されている追加コントロールの対象となる。:
&lt;ul&gt;
&lt;li&gt;6.3.2.a ポリシーを入手してレビューし、すべてのカスタムアプリケーションコードの変更に対して、(手動または自動プロセスで)以下のようにレビューが要求されていることを確認する。\n• コード変更は、コード作成者以外の、コードレビュー手法と安全なコーディング手法の知識のある人がレビューする。\n• コードレビューにより、コードが安全なコーディングガイドラインに従って開発されたことが保証される(PCI DSS要件6.5を参照)。\n• リリース前に、適切な修正を実装している。\n• コードレビュー結果は、リリース前に管理職によってレビューおよび承認される。&lt;/li&gt;
&lt;li&gt;6.3.2.b 最近のカスタムアプリケーションの変更についてサンプルを選択し、そのカスタムアプリケーションコードが上記6.3.2.aに従ってレビューされていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.4 システムコンポーネントへのすべての変更において、変更管理のプロセスおよび手順に従う。これらのプロセスには、以下を含める必要がある。:
&lt;ul&gt;
&lt;li&gt;6.4 ポリシーと手順を調べ、以下が定義されていることを確認する。\n• 開発/テスト環境が、本番環境から分離されていて、分離を実施するためのアクセス制御が行われていること\n• 開発/テスト環境に割り当てられている担当者と本番環境に割り当てられている担当者との間で責務が分離されていること\n• テストまたは開発に本番環境データ（実際の PAN）を使用しないこと。\n• 本番環境システムがアクティブになる前にテストデータとテストアカウントが削除されること\n• セキュリティパッチやソフトウェアの変更の実装に関連する変更管理手順が文書化されていること&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.4.1 開発/テスト環境を本番環境から分離し、分離を実施するためのアクセス制御を行う。:
&lt;ul&gt;
&lt;li&gt;6.4.1.a ネットワーク文書とネットワークデバイス構成を調べて、開発/テスト環境が本番環境から分離されていることを確認する。&lt;/li&gt;
&lt;li&gt;6.4.1.b アクセス制御設定を調べて、開発/テスト環境と本番環境の分離を強制するためのアクセス制御が行われていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.4.2 開発/テスト環境と本番環境での責務の分離:
&lt;ul&gt;
&lt;li&gt;6.4.2 プロセスを観察し、開発/テスト環境に割り当てられている担当者と本番環境に割り当てられている担当者をインタビューすることで、開発/テスト環境と本番環境の責務が分離されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.4.3 テストまたは開発に本番環境データ(実際のPAN)を使用しない:
&lt;ul&gt;
&lt;li&gt;6.4.3.a テストプロセスを観察し、担当者をインタビューすることで、本番環境データ（実際の PAN）がテストまたは開発に使用されていないことを確認する。&lt;/li&gt;
&lt;li&gt;6.4.3.b テストデータのサンプルを観察して、本番環境データ（実際の PAN）がテストまたは開発に使用されていないことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.4.4 本番環境システムがアクティブになる前にテストデータとテストアカウントを削除する:
&lt;ul&gt;
&lt;li&gt;6.4.4.a テストプロセスを観察し、担当者をインタビューすることで、本番環境システムがアクティブになる前にテストデータとアカウントが削除されることを確認する。&lt;/li&gt;
&lt;li&gt;6.4.4.b 最近インストールされたか更新された本番システムからのデータとアカウントのサンプルを調べて、本番環境システムがアクティブになる前にテストデータとアカウントが削除されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.4.5 セキュリティパッチの適用とソフトウェアの変更に関する変更管理手順は以下を含む必要がある。:
&lt;ul&gt;
&lt;li&gt;6.4.5.a セキュリティパッチやソフトウェアの変更の実装に関する文書化された変更管理手順を調べて、以下の手順が定義されていることを確認する。\n• 影響の文書化\n• 適切な権限を持つ関係者による文書化された変更承認。\n• 変更がシステムのセキュリティに悪影響を与えていないことを確認するための機能テスト\n• 回復手順&lt;/li&gt;
&lt;li&gt;6.4.5.b システムコンポーネントのサンプルについて、責任者をインタビューすることで、最新の変更/セキュリティパッチを確認し、それらの変更内容に関連する変更管理文書を確認する。確認した変更内容について、以下を実行する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.4.5.1 影響の文書化。:
&lt;ul&gt;
&lt;li&gt;6.4.5.1 サンプリングした変更で、影響の文書化が変更管理文書に含まれていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.4.5.2 適切な権限を持つ関係者による文書化された変更承認。:
&lt;ul&gt;
&lt;li&gt;6.4.5.2 サンプリングした変更で、適切な権限を持つ関係者による文書化された変更承認が存在していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.4.5.3 変更がシステムのセキュリティに悪影響を与えないことを確認するための機能テスト。:
&lt;ul&gt;
&lt;li&gt;6.4.5.3.a サンプリングした各変更で、変更がシステムのセキュリティに悪影響を与えないことを確認するため、機能テストが実施されたことを確認する。&lt;/li&gt;
&lt;li&gt;6.4.5.3.b カスタムコードの変更では、すべての更新を本番環境に導入する前に、PCI DSS の要件 6.5 に従って準拠がテストされていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.4.5.4 回復手順。:
&lt;ul&gt;
&lt;li&gt;6.4.5.4 サンプリングした各変更で、回復手順が準備されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5 次のようにしてソフトウェア開発プロセスで一般的なコーディングの脆弱性に対応する。\n• 開発者に安全なコーディング技法のトレーニングをする\n• 一般的なコーディングの脆弱性を避け、機密データをメモリで扱う方法を理解することを含め、安全なコーディングガイドラインに基づいてアプリケーションを開発する\n注： 要件6.5.1～6.5.11に挙げられている脆弱性は、このバージョンの PCI DSSが発行された時点の最新の業界ベストプラクティスを踏襲しているが、しかし、脆弱性管理のための業界のベストプラクティスは更新されているため（OWASPガイド、SANS CWE Top 25、CERT\nSecure Coding など）、現在のベストプラクティスは、これらの要件を使用する必要がある。:
&lt;ul&gt;
&lt;li&gt;6.5.a ソフトウェア開発ポリシーと手順を調べ、プロセスが、業界のベストプラクティスとガイダンスに基づき、開発者のための安全なコーディング技法についてトレーニングを要求していることを確認する。&lt;/li&gt;
&lt;li&gt;6.5.b 数人の開発者をインタビューし、安全なコーディング技法に精通していることを確認する。&lt;/li&gt;
&lt;li&gt;6.5.c トレーニング記録を調べて、ソフトウェア開発者が、一般的なコーディングの脆弱性を避け、機密データをメモリで扱う方法を理解することを含め、安全なコーディング技法についてのトレーニングを受けたことを確認する。&lt;/li&gt;
&lt;li&gt;6.5.d アプリケーションを少なくとも以下の脆弱性から保護するためのプロセスが存在することを確認する。\n注：以下の要件 6.5.1 から 6.5.6 は、すべてのアプリケーション\n（内部または外部）に適用されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5.1 インジェクションの不具合（特にSQL インジェクション）。OS コマンドインジェクション、LDAP およびXpath のインジェクションの不具合、その他のインジェクションの不具合も考慮する。:
&lt;ul&gt;
&lt;li&gt;6.5.1 ソフトウェア開発ポリシーと手順を調べ、責任者をインタビューすることで、以下を含め、コーディング技法によってインジェクションの不具合が対処されていることを確認する。\n• 入力を調べて、ユーザデータがコマンドとクエリの意味を変更できないことを確認する\n• パラメータ化クエリを使用する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5.2 バッファオーバーフロー:
&lt;ul&gt;
&lt;li&gt;6.5.2 ソフトウェア開発ポリシーと手順を調べ、責任者をインタビューすることで、以下を含め、コーディング技法によってバッファオーバーフローが対処されていることを確認する。\n• バッファ境界を検証する\n• 入力文字列をトランケーションする&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5.3 安全でない暗号化保存:
&lt;ul&gt;
&lt;li&gt;6.5.3 ソフトウェア開発ポリシーと手順を調べ、責任者をインタビューすることで、以下を含め、コーディング技法によって安全でない暗号化保存が対処されていることを確認する。\n• 暗号化の不具合を防止する\n• 強力な暗号化アルゴリズムとキーを使用する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5.4 安全でない通信:
&lt;ul&gt;
&lt;li&gt;6.5.4 ソフトウェア開発ポリシーと手順を調べ、責任者をインタビューすることで、安全でない通信がすべての機密情報の通信を適切に認証して暗号化するコーディング技法によって対処されていることを確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5.5 不適切なエラー処理:
&lt;ul&gt;
&lt;li&gt;6.5.5 ソフトウェア開発ポリシーと手順を調べ、責任者をインタビューすることで、不適切なエラー処理が、エラーメッセージを通して情報を漏洩しないコーディング技法によって対処されていることを確認する（たとえば、具体的なエラー情報ではなく汎用エラーメッセージを返すなど）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5.6 脆弱性特定プロセス（PCI DSS要件 6.1 で定義）で特定された、すべての「高リスク」脆弱性。:
&lt;ul&gt;
&lt;li&gt;6.5.6 コーディング技法により、アプリケーションを侵害する可能性のある、PCI DSS 要件 6.1 で特定されたすべての「高リスク」脆弱性に対処する。\n- 注：以下の要件6.5.7～6.5.10は、Webアプリケーションとアプリケーションインターフェース(内部または外部)に適用される。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5.7 クロスサイトスクリプティング(XSS):
&lt;ul&gt;
&lt;li&gt;6.5.7 ソフトウェア開発ポリシーと手順を調べ、責任者をインタビューすることで、以下を含め、コーディング技法によってクロスサイトスクリプティング（XSS）が対処されていることを確認する。\n• 取り込む前にすべてのパラメータを検証\n• コンテキスト依存エスケープの使用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5.8 不適切なアクセス制御（安全でないオブジェクトの直接参照、URL アクセス制限の失敗、ディレクトリトラバーサル、機能へのユーザアクセス制限の失敗など）:
&lt;ul&gt;
&lt;li&gt;6.5.8 ソフトウェア開発ポリシーと手順を調べ、責任者をインタビューすることで、不適切なアクセス制御（安全でないオブジェクトの直接参照、URL アクセス制限の失敗、ディレクトリトラバーサルなど）が以下を含むコーディング技法によって対処されていることを確認す。\n•ユーザの適切な認証\n• 入力値の削除\n• 内部オブジェクト参照をユーザに公開しない\n• ユーザインタフェースで無許可の機能へのアクセスを許可しない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5.9 クロスサイトリクエスト偽造(CSRF):
&lt;ul&gt;
&lt;li&gt;6.5.9 ソフトウェア開発ポリシーと手順を調べ、責任者をインタビューすることで、クロスサイトリクエスト偽造（CSRF）は、アプリケーションがブラウザから自動的に送信された認証情報とトークンに依存しないコーディング技法によって対処されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.5.10 不完全な認証管理とセッション管理\n注： 要件 6.5.11 は、2015 年 6 月 30 日まではベストプラクティスとみなされ、それ以降は要件になる。:
&lt;ul&gt;
&lt;li&gt;6.5.10 ソフトウェア開発ポリシーと手順を調べ、責任者をインタビューすることで、以下を含め、コーディング技法によって不完全な認証管理とセッション管理が対処されていることを確認する。\n• セッショントークン（クッキーなど）を「安全」としてフラグ付けする\n• URL にセッションを含めない\n• ログイン後の適切なタイムアウトとセッション ID の巡回\n• ユーザ ID とパスワードがアプリケーションアカウント機能を使って上書きできなくする&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.6 一般公開されているWebアプリケーションで、継続的に新たな脅威や脆弱性に対処し、これらのアプリケーションが、次のいずれかの方法によって、既知の攻撃から保護されていることを確認する。\n・一般公開されているWeb アプリケーションは、アプリケーションのセキュリティ脆弱性を\n手動/自動で評価するツールまたは手法によって、少なくとも年 1 回および何らかの変更を加えた後にレビューする\n注： この評価は、要件 11.2 で実施する脆弱性スキャンとは異なる。\n・Web ベースの攻撃を検知および回避するために、一般公開されている Web アプリケーションの手前に、Web アプリケーションファイアウォールをインストールする。:
&lt;ul&gt;
&lt;li&gt;6.6 一般公開されているWebアプリケーションについて、以下のいずれかの手法がとられていることを確認する。\n・ 文書化されているプロセスを調べ、担当者をインタビューして、アプリケーションセキュリティ評価記録を見ることで、一般公開されている Web アプリケーションが（セキュリティ脆弱性を手動/自動で評価するツールまたは手法を使用して）以下のようにレビューされていることを確認する。\n- 少なくとも年に一度実施する\n- 何らかの変更を加えた後\n- アプリケーションのセキュリティを専門とする組織によって\n- 評価に少なくとも要件 6.5 に記載されている脆弱性を含める\n- 脆弱性がすべて修正されている\n- 修正後、アプリケーションが再評価されている\n・防止する技術的な解決策（Web アプリケーションファイアウォールなど）が以下の通り備わっていることを確認する。\n- Web ベースの攻撃を検知および防止するために、一般公開されている Web アプリケーションの手前にインストールされている\n- アクティブに実行されており、最新状態である（該当する場合）\n- 監査ログを生成する\n- Web ベースの攻撃をブロックするか、アラートを生成する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6.7 セキュアシステムとアプリケーションを開発・保守するためのセキュリティポリシーと操作手順が文書化されて使用されており、影響を受ける関係者全員に知られていることを確認する。
&lt;ul&gt;
&lt;li&gt;6.7 文書を調べ、関係者をインタビューすることで、安全なシステムとアプリケーションを開発・保守するためのセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n• 文書化されている\n• 使用されている\n• 影響を受ける関係者全員に知らされている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件7：カード会員データへのアクセスを、業務上必要な範囲内に制限する:
&lt;ul&gt;
&lt;li&gt;7.1 システムコンポーネントとカード会員データへのアクセスを、業務上必要な人に限定する。:
&lt;ul&gt;
&lt;li&gt;7.1.a アクセス制御に関する文書化されたポリーを入手して検討し、ポリシーが以下のように 7.1.1〜7.1.4 を含んでいることを確認する。\n• 各役割のアクセスニーズと特権割り当てを定義する\n• 特権ユーザ ID に与えるアクセス権が、職務の実行に必要な最小限の特権に制限されていること\n• 特権の付与は、個人の職種と職務に基づくこと\n• すべてのアクセスに対して、権限を持つ関係者による、許可された特権のリストを含む、文書化された承認（書面または電子的）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;7.1.1 以下を含む、各役割のアクセスニーズを定義する\n• 各役割が職務上アクセスする必要のあるシステムコンポーネントとデータリソース\n• リソースへのアクセスに必要な特権レベル（ユーザ、管理者など）:
&lt;ul&gt;
&lt;li&gt;7.1.1 役割のサンプルを選択し、各役割のアクセスニーズが定義されており、以下を含むことを確認する。\n• 各役割が職務上アクセスする必要のあるシステムコンポーネントとデータリソース\n• 各役割が職務を遂行するために必要な特権の特定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;7.1.2 特権ユーザ ID に与えるアクセス権を職務の実行に必要な最小限の特権に制限する。:
&lt;ul&gt;
&lt;li&gt;7.1.2.a アクセス権の割り当ての責任者をインタビューすることで、特権ユーザ ID へのアクセスが以下を満たしていることを確認する。\n• そのようなアクセス権を特に必要とする役割にのみ割り当てられる\n• 職務の実行に必要な最小限の特権に制限されている&lt;/li&gt;
&lt;li&gt;7.1.2.b アクセス権を持つユーザ ID のサンプルを選択し、管理責任者をインタビューすることで、割り当てられた特権が以下を満たすことを確認する。\n• そのユーザの職務に必要\n• 職務の実行に必要な最小限の特権に制限されている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;7.1.3 個人の職種と職務に基づくアクセス権の割り当てる。:
&lt;ul&gt;
&lt;li&gt;7.1.3 ユーザ ID のサンプルを選択し、管理責任者をインタビューすることで、割り当てられた特権がその個人の職種と職務に基づいていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;7.1.4適切な権限を持つ関係者による文書化された変更承認を必要とする。:
&lt;ul&gt;
&lt;li&gt;7.1.4 ユーザ ID を選択し、文書化された承認と比較することで、以下を確認する。\n• 割り当てられた特権に対する文書化された承認が存在する\n• その承認は権限のある関係者によるものである\n• 指定された特権がその個人に割り当てられた役割に一致している&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;7.2 システムコンポーネントで、ユーザの必要性に基づいてアクセスが制限され、特に許可のない場合は「すべてを拒否」に設定された、アクセス制御システムを確立する。\nアクセス制御システムには以下の項目を含める必要がある。:
&lt;ul&gt;
&lt;li&gt;7.2 システムの設定とベンダの文書を検査し、アクセス制御システムが以下のように実装されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;7.2.1 すべてのシステムコンポーネントを対象に含む:
&lt;ul&gt;
&lt;li&gt;7.2.1 アクセス制御システムがすべてのシステムコンポーネントに実装されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;7.2.2 職種と職能に基づく、個人への特権の付与:
&lt;ul&gt;
&lt;li&gt;7.2.2 アクセス制御システムが、職種と職務に基づいて個人に割り当てられる特権を強制するよう構成されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;7.2.3 デフォルトでは「すべてを拒否」の設定:
&lt;ul&gt;
&lt;li&gt;7.2.3 アクセス制御システムに「すべてを拒否」がデフォルト設定されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;7.3 カード会員データへのアクセスを制限するためのセキュリティポリシーと操作手順が文書化されて使用されており、影響を受ける関係者全員に知られていることを確認する。:
&lt;ul&gt;
&lt;li&gt;7.3 文書を調べ、担当者をインタビューすることで、カード会員データへのアクセスを制限するためのセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n• 文書化されている\n• 使用されている\n• 影響を受ける関係者全員に知らされている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件8：コンピュータにアクセスできる各ユーザに一意のIDを割り当てる:
&lt;ul&gt;
&lt;li&gt;8.1 ポリシーと手順を定義して実装することで、次のように、すべてのシステムコンポーネントで、非消費者ユーザと管理者のための適切なユーザ識別および認証の管理が行われるようにする。:
&lt;ul&gt;
&lt;li&gt;8.1.a 手順を調べて、以下の 8.1.1 ～ 8.1.8 の各項目についてのプロセスが定義されていることを確認する。&lt;/li&gt;
&lt;li&gt;8.1.b 以下を実行することによって、ユーザ識別管理のための手順が実施されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.1.1 システムコンポーネントまたはカード会員データへのアクセスを許可する前に、すべてのユーザに一意のIDを割り当てる。:
&lt;ul&gt;
&lt;li&gt;8.1.1 管理責任者をインタビューすることで、すべてのユーザに、システムコンポーネントまたはカード会員データにアクセスするための一意のIDが割り当てられていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.1.2 追加、削除、ユーザ ID の変更、資格情報、およびその他の識別オブジェクトを管理する。:
&lt;ul&gt;
&lt;li&gt;8.1.2 特権ユーザ ID と一般ユーザ ID について、関連付けられている権限を調べ、システム設定を観察して、各ユーザ ID と特権ユーザ ID に、文書化されている承認内容で指定されている特権のみが実装されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.1.3 契約終了したユーザのアクセスを直ちに取り消す。:
&lt;ul&gt;
&lt;li&gt;8.1.3.a 過去 6 カ月間に契約終了したユーザのサンプルを選択し、現在のユーザアクセスリストを調べて、– ローカルとリモートアクセス両方につき – これらのユーザの ID が無効化または削除されていることを確認する。&lt;/li&gt;
&lt;li&gt;8.1.3.b スマートカード、トークンなど、すべての物理的認証方法が返還されたか、無効にされたことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.1.4少なくとも 90 日ごとに非アクティブなユーザアカウントを削除/無効にする。:
&lt;ul&gt;
&lt;li&gt;8.1.4 ユーザアカウントを観察することで、90 日間を超える非アクティブなアカウントが削除または無効になっていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.1.5 ベンダがリモートアクセス経由でシステムコンポーネントのアクセス、サポート、メンテナンスに使用するユーザ ID を以下のように管理する。\n• 必要な期間内だけ有効になり、使用されていないときは無効になっている。\n• 使用時に監視されている。:
&lt;ul&gt;
&lt;li&gt;8.1.5.a 担当者をインタビューし、ベンダがシステムコンポーネントのアクセス、サポート、メンテナンスに使用するアカウントを管理するためのプロセスを観察して、ベンダがリモートアクセスに使用するアカウントが以下を満たしていることを確認する。\n• 使用されていないときに無効になっている\n• ベンダが必要なときにのみ有効になり、使用されていない場合は無効になる&lt;/li&gt;
&lt;li&gt;8.1.5.b 担当者をインタビューし、プロセスを観察することで、使用中にベンダのリモートアクセスアカウントが監視されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.1.6  6 回以下の試行で、ユーザ ID をロックアウトすることによって、アクセスの試行回数を制限する。:
&lt;ul&gt;
&lt;li&gt;8.1.6.a システムコンポーネントのサンプルで、システム構成設定を調べ、6 回以上無効のログオンを繰り返した場合に、ユーザのアカウントがロックされることを要求するよう、認証パラメータが設定されていることを確認する。&lt;/li&gt;
&lt;li&gt;8.1.6.b サービスプロバイダの場合のみの追加の手順、内部プロセスと顧客/ユーザマニュアルをレビューし、実装されたプロセスを観察することで、6 回以上無効のログオンを繰り返した場合に、ユーザのアカウントが一時的にロックされるこを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.1.7 最低 30 分間、または管理者がユーザ ID を有効にするまでのロックアウト期間を設定する。:
&lt;ul&gt;
&lt;li&gt;8.1.7 システムコンポーネントのサンプルで、システム構成設定を調べ、ユーザアカウントがロックアウトされたら、最低 30 分間、または管理者がユーザ ID を有効にするまでのロックアウト状態が続くことを要求するよう、認証パラメータが設定されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.1.8 セッションのアイドル状態が 15分を超えた場合、ターミナルまたはセッションを再度アクティブにするため、ユーザの再認証が必要となる。:
&lt;ul&gt;
&lt;li&gt;8.1.8 システムコンポーネントのサンプルで、システム構成設定を調べ、セッションのアイドル状態が 15 分を超えた場合、ターミナルまたはセッションを再度アクティブにするため、ユーザの再認証が必要となることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.2 一意の ID を割り当てることに加え、すべてのユーザを認証するため、次の方法の少なくとも 1 つを使用することで、すべてのシステムコンポーネント上での顧客以外のユーザと管理者の適切なユーザ認証管理を確認する。\n• ユーザが知っていること（パスワードやパスフレーズなど）\n• トークンデバイスやスマートカードなど、ユーザが所有しているもの\n• ユーザ自身を示すもの（生体認証など）:
&lt;ul&gt;
&lt;li&gt;8.2ユーザがカード会員データ環境にアクセスするための一意の ID と追加の認証（パスワード/パスフレーズなど）を使用して認証されることを確認するため、次の項目を実行する。\n• 使用される認証方法について記述した文書を調べる。\n• 使用される認証方法の各種類およびシステムコンポーネントの各種類について、認証を調べて、文書に記述された認証方法に従って認証が機能していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.2.1 強力な暗号化を使用して、すべてのシステムコンポーネントで、送信と保存中に認証情報（パスワード/パスフレーズなど）をすべて読み取り不能とする。:
&lt;ul&gt;
&lt;li&gt;8.2.1.a ベンダ文書とシステム構成設定を調べて、送信および保存中にパスワードが強力な暗号化によって保護されていることを確認する。&lt;/li&gt;
&lt;li&gt;8.2.1.b システムコンポーネントのサンプルに対して、パスワードファイルを調べて、パスワードが保存中に読み取り不能であることを確認する。&lt;/li&gt;
&lt;li&gt;8.2.1.c システムコンポーネントのサンプルに対して、データ伝送を調べて、パスワードが保存中に読み取り不能であることを確認する。&lt;/li&gt;
&lt;li&gt;8.2.1.d サービスプロバイダ用の追加手順。パスワードファイルを観察して、保存中に顧客のパスワードが読み取れないことを確認する。&lt;/li&gt;
&lt;li&gt;8.2.1.e サービスプロバイダ用の追加手順。データの送信を観察して、送信中に顧客のパスワードが読み取れないことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.2.2 パスワードのリセット、新しいトークンの準備、新しいキーの生成など、認証情報を変更する前に、ユーザの身元を確認する。:
&lt;ul&gt;
&lt;li&gt;8.2.2 認証情報を変更するための認証手順を調べて、セキュリティ担当者を観察して、ユーザが、電話、電子メール、Web、または他の非対面法でパスワードのリセットを要求した場合、パスワードがリセットされる前に、ユーザの身元が確認されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.2.3 パスワード/パスフレーズは以下を満たす必要がある。\n• パスワードに 7 文字以上が含まれる\n• 数字と英文字の両方を含む\nあるいは、上記のパラメータに等しい複雑さと強度を持つパスワード/パスフレーズ:
&lt;ul&gt;
&lt;li&gt;8.2.3a システムコンポーネントのサンプルについて、システム構成設定を調べて、少なくとも以下の強度/複雑さを必要とするようにユーザパスワードのパラメータが設定されていることを確認する。\n• パスワードに 7 文字以上が含まれる\n• 数字と英文字の両方を含む&lt;/li&gt;
&lt;li&gt;8.2.3.b サービスプロバイダ用の追加手順。内部プロセスおよび顧客/ユーザ文書を確認して、消費者以外のユーザのパスワードが少なくとも次の強度/複雑さを満たすことが要求されていることを確認する。\n• パスワードに 7 文字以上が含まれる\n• 数字と英字の両方を含む&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.2.4 ユーザパスワード/パスフレーズは、少なくとも90日ごと変更する。:
&lt;ul&gt;
&lt;li&gt;8.2.4.a システムコンポーネントのサンプルについて、システム構成設定を調べて、少なくとも 90 日ごとにパスワードを変更することを要求するようにユーザパスワードのパラメータが設定されていることを確認する。&lt;/li&gt;
&lt;li&gt;8.2.4.b サービスプロバイダ用の追加手順。内部プロセスおよび顧客/ユーザ文書を調べて、以下を確認する。\n• 非消費者ユーザパスワードを定期的に変更することが要求されている\n• 消費者以外のユーザに、いつどのような状況下でパスワードを変更する必要があるかについてのガイダンスが与えられている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.2.5 これまでに使用した最後の 4 つのパスワード/パスフレーズのいずれかと同じである新しいパスワード/パスフレーズを許可しない。:
&lt;ul&gt;
&lt;li&gt;8.2.5.a システムコンポーネントのサンプルで、システム構成設定を入手して調べ、新しいパスワードとして、これまでに使用した最後の 4 つのパスワードのいずれかと同じパスワードを指定できないことを要求するユーザパスワードパラメータが設定されていることを確認する。&lt;/li&gt;
&lt;li&gt;8.2.5.b サービスプロバイダ用の追加手順。内部プロセスと顧客/ユーザマニュアルを調べて、非消費者ユーザのパスワードがこれまでに使用した 4 つのパスワードのいずれかにできなくなっていることを確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.2.6 初期パスワード/パスフレーズとリセットパスワード/パスフレーズをユーザごとに一意の値にリセットし、初回の使用後直ちに変更する。:
&lt;ul&gt;
&lt;li&gt;8.2.6 パスワード手順を調べて、新しいユーザの初期パスワードと既存ユーザのリセットパスワードが、各ユーザで一意の値に設定され、初回の使用後に変更されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.3 従業員（ユーザと管理者を含む）および第三者（サポートやメンテナンス用のベンダアクセスを含む）によるネットワークへのリモートアクセス（ネットワーク外部からのネットワークレベルアクセス）に 2 因子認証を組み込む。\n注： 2 因子認証では、3 つの認証方法のうち 2 つを認証に使用する必要がある（認証方法については、要件 8.2 を参照）。1 つの因子を 2 回使用すること（たとえば、2 つの個別パスワードを使用する）は、2 因子認証とは見なされない。\n2 因子認証方式の例としては、トークン\n使用の RADIUS（Remote Authentication\nand Dial-In Service）、トークン使用の\nTACACS（Terminal Access Controller\nAcceess Control System）、および 2 因\n子認証を促進する他の方式があります。:
&lt;ul&gt;
&lt;li&gt;8.3.a リモートアクセスサーバとシステムのシステム構成を調べて、以下に対して 2 因子認証が要求されていることを確認する。\n• 従業員によるすべてのリモートアクセス\n• すべての第三者/ベンダリモートアクセス（サポートやメンテナンス目的でのアプリケーションやシステムコンポーネントへのアクセスを含む）&lt;/li&gt;
&lt;li&gt;8.3.b ネットワークにリモート接続する従業員（ユーザや管理者など）のサンプルを観察し、3 つの認証方法のうち 2 つが使用されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.4以下を含む認証手順およびポリシーを文書化し、すべてのユーザに通達する。\n• 強力な認証情報を選択するためのガイダンス\n• ユーザが自分の認証情報を保護する方法についてのガイダンス\n• 前に使用していたパスワードを再使用しないという指示\n・パスワードが侵害された疑いがある場合にはパスワードを変更するという指示:
&lt;ul&gt;
&lt;li&gt;8.4.a 手順を調べ、担当者をインタビューすることで、認証手順とポリシーがすべてのユーザに配布されていることを確認する。&lt;/li&gt;
&lt;li&gt;8.4.b ユーザに配布された認証手順とポリシーを調べることで、以下を確認する。\n• 強力な認証情報を選択するためのガイダンス\n• ユーザが自分の認証情報を保護する法方についてのガイダンス\n• 前に使用していたパスワードを再使用しないという指示\n• パスワードが侵害された疑いがある場合にはパスワードを変更するという指示&lt;/li&gt;
&lt;li&gt;8.4.c ユーザのサンプルにインタビューし、認証手順およびポリシーに精通していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.5 次のように、グループ、共有、または汎用の ID やパスワード、または他の認証方法が使用されていない。\n• 汎用ユーザ ID およびアカウントが無効化または削除されている\n• システム管理作業およびその他の重要な機能に対する共有ユーザ ID が存在しない\n• システムコンポーネントの管理に共有および汎用ユーザ ID が使用されていない:
&lt;ul&gt;
&lt;li&gt;8.5.a システムコンポーネントのサンプルについて、ユーザ ID リストを調べて、以下を確認する。\n• 汎用ユーザ ID が無効化または削除されている\n• システム管理作業およびその他の重要な機能のための共有ユーザ ID が存在しない\n• システムコンポーネントの管理に共有および汎用ユーザ ID が使用されていない&lt;/li&gt;
&lt;li&gt;8.5.b 認証ポリシー/手順を調べて、グループおよび共有 ID やパスワードまたは他の認証方法が明示的に禁止されていることを確認する。&lt;/li&gt;
&lt;li&gt;8.5.c システム管理者にインタビューし、グループおよび共有 ID やパスワード、または他の認証方法が、要求があっても配布されないことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.5.1 サービスプロバイダに対する追加要件：顧客環境へのアクセス権を持つサービスプロバイダは、各顧客に一意な認証情報（パスワード/パスフレーズなど）を使用する必要がある。\n注： この要件は、複数の顧客環境がホストされている、独自のホスティング環境にアクセスする共有ホスティングプロバイダに適用することを意図していません。\n注： 要件 8.5.1 は、2015 年 6 月 30 日まではベストプラクティスとみなされ、それ以降は要件になる。:
&lt;ul&gt;
&lt;li&gt;8.5.1 サービスプロバイダ用の追加手続き: 認証ポリシーと手順を調べ、担当者をインタビューすることで、各顧客環境にアクセスするために異なる認証が使用されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.6 その他の認証メカニズムが使用されている（たとえば、物理的または論理的セキュリティトークン、スマートカード、証明書など）これらのメカニズムの使用は、以下のように割り当てる必要がある。\n• 認証メカニズムは、個々のアカウントに割り当てなければならず、複数アカウントで共有できない\n• 物理/論理制御により、意図されたアカウントのみがアクセスできるようにする必要がある:
&lt;ul&gt;
&lt;li&gt;8.6.a 認証ポリシーと手順を調べ、物理セキュリティトークン、スマートカード、証明書などを使用する手順が定義されており以下を含むことを確認する。\n• 認証メカニズムが、個々のアカウントに割り当てられており、複数アカウントで共有されていない\n• 物理/論理制御により、意図されたアカウントのみがアクセスできるようになっている&lt;/li&gt;
&lt;li&gt;8.6.b セキュリティ担当者をインタビューすることで、認証メカニズムが、個々のアカウントに割り当てられており、複数アカウントで共有されていないことを確認する。&lt;/li&gt;
&lt;li&gt;8.6.c システム構成設定や該当する場合は物理制御を調べて、物理/論理制御により、意図されたアカウントのみがそのメカニズムを使ってアクセスできるようにする制御が実装されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.7 カード会員データを含むデータベースへのすべてのアクセス（アプリケーション、管理者、およびその他のすべてのユーザによるアクセスを含む）が以下のように制限されている。\n• データベースへのユーザアクセス、データベースのユーザクエリ、データベースに対するユーザアクションはすべて、プログラムによる方法によってのみ行われる。\n・ データベースへの直接アクセスまたはクエリはデータベース管理者のみに制限される。\n・ データベースアプリケーション用のアプリケーション ID を使用できるのはそのアプリケーションのみである\n（個々のユーザやその他の非アプリケーションプロセスは使用できない）。:
&lt;ul&gt;
&lt;li&gt;8.7.a データベースおよびアプリケーションの構成設定を調べ、すべてのユーザがアクセスする前に認証されていることを確認する。&lt;/li&gt;
&lt;li&gt;8.7.b データベースおよびアプリケーションの構成設定を調べて、データベースでのすべてのユーザアクセス、ユーザのクエリ、およびユーザのアクション（たとえば、移動、コピー、削除）が、プログラムを使用する方法（ストアドプロシージャを介してなど）によってのみ実行されることを確認する。&lt;/li&gt;
&lt;li&gt;8.7.c データベースアクセス制御設定とデータベースアプリケーション構成設定を調べて、ユーザの直接アクセスまたはデータベースへのクエリがデータベース管理者に制限されていることを確認する。&lt;/li&gt;
&lt;li&gt;8.7.d データベースアクセス制御設定、データベースアプリケーション設定、および関連アプリケーション ID を調べて、アプリケーション ID がアプリケーションによってのみ使用できることを確認する（個々のユーザまたはその他のプロセスでは使用できない）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;8.8 識別と認証に関するセキュリティポリシーと操作手順が文書化されて使用されており、影響を受ける関係者全員に知られていることを確認する。:
&lt;ul&gt;
&lt;li&gt;8.8 文書を調べ、関係者をインタビューすることで、識別と認証に関するセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n• 文書化されている\n• 使用されている\n• 影響を受ける関係者全員に知らされている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件9：カード会員データへの物理アクセスを制限する:
&lt;ul&gt;
&lt;li&gt;9.1 適切な施設入館管理を使用して、カード会員データ環境内のシステムへの物理アクセスを制限および監視する。:
&lt;ul&gt;
&lt;li&gt;9.1 各コンピュータルーム、データセンター、およびカード会員データ環境内のシステムを備えた物理的なエリアで、物理的なセキュリティコントロールが存在することを確認する。\n・バッジ読み取り機または承認済みバッジ、施錠、鍵などのその他のデバイスによってアクセスが管理されていることを確認する。\n・システム管理者がカード会員環境内のランダムに選択したシステムのコンソールにログインするのを観察して、コンソールが不正使用を防止するように「ロック」されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.1.1 ビデオカメラやアクセス管理メカニズムを使用して、機密エリアへの個々の物理アクセスを監視する。収集されたデータを確認し、その他のエントリと相関付ける。法律によって別途定められていない限り、少なくとも3カ月間保管する。\n注：「機密エリア」とは、データセンタ、サーバルーム、またはカード会員データを保存、処理、または伝送するシステムが設置されているエリアのこと。これには、小売店のレジなど、POS端末のみが存在するエリアは含まれない。:
&lt;ul&gt;
&lt;li&gt;9.1.1.a ビデオカメラやアクセス制御メカニズムを使用して、機密エリアへの入退場ポイントを監視する。&lt;/li&gt;
&lt;li&gt;9.1.1.b ビデオカメラやアクセス制御メカニズムが改ざんや無効化から保護されていることを確認する。&lt;/li&gt;
&lt;li&gt;9.1.1.c ビデオカメラやアクセス管理メカニズムが監視されていて、カメラまたはその他のメカニズムからのデータが少なくとも3カ月間保管されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.1.2 物理/論理制御を実施することで、誰でもアクセス可能なネットワークジャックへのアクセスを制限する。\nたとえば、公共の場や訪問者がアクセス可能なエリアにあるネットワークジャックは、無効にしておき、ネットワークへのアクセスが明示的に承認されている場合にのみ有効できる。。または、アクティブなネットワークジャックがあるエリアでは訪問者に常に同行者をつけるプロセスを実施できる。:
&lt;ul&gt;
&lt;li&gt;9.1.2 責任者をインタビューし、誰でもアクセスできる場所にあるネットワークジャックの場所を観察して、物理/論理制御が備わっており、誰でもアクセスできる場所にあるネットワークジャックへのアクセスを制限していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.1.3 ワイヤレスアクセスポイント、ゲートウェイ、ハンドヘルドデバイス、ネットワーク/通信ハードウェア、および電気通信回線への物理アクセスを制限する。:
&lt;ul&gt;
&lt;li&gt;9.1.3 ワイヤレスアクセスポイント、ゲートウェイ、ハンドヘルドデバイス、ネットワーク/通信ハードウェア、および電気通信回線への物理的なアクセスが適切に制限されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.2 次のようにオンサイト要員と訪問者を容易に区別できるような手順を開発する。\n・新しいオンサイト要因や訪問者を識別する\n（バッジの使用など）\n・アクセス要件を変更する\n・契約が終了したオンサイト要員や期限切れの訪問者の ID（バッジなど）を無効にする:
&lt;ul&gt;
&lt;li&gt;9.2.a オンサイト要員および訪問者にバッジを割り当てるためのプロセスと手順を確認して、これらのプロセスに以下が含まれていることを確認する。\n• 新しいバッジを付与すること\n• アクセス要件を変更すること\n• 契約が終了したオンサイト要員と期限切れの訪問者バッジを取り消すこと&lt;/li&gt;
&lt;li&gt;9.2.b オンサイト担当者と訪問者を識別し、区別するプロセスを観察し、以下を確認する。\n• 訪問者が明確に識別される\n• オンサイト要員と訪問者を容易に区別できる&lt;/li&gt;
&lt;li&gt;9.2.c 識別プロセス（バッジシステムなど）へのアクセスが、許可された担当者に制限されていることを確認する。&lt;/li&gt;
&lt;li&gt;9.2.d 使用されている識別方法（ID バッジなど）を調べて、訪問者を明確に識別し、オンサイト担当者と訪問者を簡単に区別できることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.3 オンサイト要員の機密エリアへの物理アクセスを次のように制御する。\n• アクセスが個々の職務に基づいて許可される\n• 職務の終了後直ちにアクセスを無効とし、鍵、アクセスカードなどすべての物理アクセスメカニズムを返還するか無効にする:
&lt;ul&gt;
&lt;li&gt;9.3.a CDE への物理アクセス権を持つオンサイト要員のサンプルに対して、責任者をインタビューし、アクセス制御リストを見て、以下を確認する。\n• CDE へのアクセスが許可されている\n• アクセスがその個人の職務に必要&lt;/li&gt;
&lt;li&gt;9.3.b 関係者による CDE へのアクセスを観察して、すべての関係者は、アクセスを許可される前に、承認が必要であることを確認する。&lt;/li&gt;
&lt;li&gt;9.3.c 最近退職した従業員のサンプルを選択し、アクセス制御リストを調べ、その従業員が CDE への物理アクセスを持たないことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.4 訪問者を識別し、承認する手順を実施する。\n手順には、以下を含める必要がある。:
&lt;ul&gt;
&lt;li&gt;9.4 訪問者の承認とアクセス制御が次のように行われていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.4.1 訪問者は、カード会員データが処理または保守されているエリアに入る前に承認が行われ、そのエリアにいる間ずっと同行者に付き添われている:
&lt;ul&gt;
&lt;li&gt;9.4.1.a 手順を観察し、担当者をインタビューすることで、訪問者は、カード会員データが処理または保守されているエリアに入ることが許可される前に承認が行われ、そのエリアにいる間ずっと同行者に付き添われていることを確認する。&lt;/li&gt;
&lt;li&gt;9.4.1.b 訪問者 ID バッジまたは他のID の使用を観察して、物理トークンのバッジがカード会員データの処理または保守がされている物理エリアに同行者なしでアクセスできないことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.4.2 訪問者が識別され、オンサイト担当者から明確に区別するための有効期限付きバッジその他の ID を与えられる。:
&lt;ul&gt;
&lt;li&gt;9.4.2.a 施設内にいる人を観察し、訪問者バッジが使用されていて、訪問者とオンサイト担当者を明確に区別できることを確認する。&lt;/li&gt;
&lt;li&gt;9.4.2.b 訪問者のバッジその他の ID が有効期限を過ぎると無効になることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.4.3 施設を出る前、または期限が切れる日にバッジその他の ID の返還を求められる:
&lt;ul&gt;
&lt;li&gt;9.4.3 施設から出る訪問者を観察して、訪問者が退去時または期限切れのときにバッジその他の ID の返還を求められていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.4.4 訪問者ログを使用して、カード会員データの保存または送信が行われているコンピュータルームやデータセンターなどの施設への訪問者の行動の物理的監査証跡を保持する。\n訪問者の名前、所属会社、物理アクセスを承認したオンサイト要員をログに記録する。\n法律によって別途定められていない限り、このログを少なくとも3カ月間保管する。:
&lt;ul&gt;
&lt;li&gt;9.4.4.a カード会員データが保存または伝送されるコンピュータルームやデータセンターだけでなく、施設への物理アクセスの記録にも訪問者ログが使用されていることを確認する。&lt;/li&gt;
&lt;li&gt;9.4.4.b ログに以下が含まれていることを確認する。\n• 訪問者名\n• 所属会社\n• 物理アクセスを承認したオンサイト担当者&lt;/li&gt;
&lt;li&gt;9.4.4.c ログが 3 カ月以上保持されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.5 すべての媒体を物理的にセキュリティ保護する。:
&lt;ul&gt;
&lt;li&gt;9.5 カード会員データを保護する手順に、すべての媒体（コンピュータ、リムーバブル電子媒体、紙の受領書、紙のレポート、FAX を含むがこれらに限定されない）のセキュリティを物理的に保護するための管理が含まれていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.5.1 バックアップの入った媒体を安全な場所に保管する（代替またはバックアップサイト、商用ストレージ施設などのオフサイト施設が望ましい）。保管場所のセキュリティを少なくとも年に一度確認する:
&lt;ul&gt;
&lt;li&gt;9.5.1.a 保管場所の物理的なセキュリティを観察して、バックアップメディアの保管が安全であることを確認する。&lt;/li&gt;
&lt;li&gt;9.5.1.b 保管場所のセキュリティを少なくとも年に一度レビューしていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.6 次の項目を含め、あらゆるタイプの媒体を内部または外部に配布する際の厳格な管理を維持する。:
&lt;ul&gt;
&lt;li&gt;9.6 媒体の配布を管理するためのポリシーが存在し、そのポリシーが、個人に配布されるものを含め、すべての配布媒体に対応していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.6.1 データの機密性を識別できるように、媒体を分類する。:
&lt;ul&gt;
&lt;li&gt;9.6.1 データの感度を決定できるように、すべての媒体が分類されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.6.2 安全な配達業者または正確に追跡できるその他の方法によって媒体を送付する。:
&lt;ul&gt;
&lt;li&gt;9.6.2.a 担当者をインタビューし、記録を調べて、施設の外部に送付されるすべての媒体がログに記録され、安全な配達業者または追跡可能なその他の配送方法によって送付されることを確認する。&lt;/li&gt;
&lt;li&gt;9.6.2.b すべての媒体の数日分のオフサイト追跡ログの最新サンプルを選択し、追跡の詳細がログに記録されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.6.3 安全なエリアから移動されるすべての媒体を管理者が承認していることを確認する\n（媒体が個人に配布される場合を含む）。:
&lt;ul&gt;
&lt;li&gt;9.6.3 すべての媒体の数日分のオフサイト追跡ログの最新サンプルを選択する。ログを調べ、責任者をインタビューすることで、媒体が安全なエリアから移動される（媒体が個人に配達される場合を含む）たびに適切な管理者の承認が得られていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.7 媒体の保管およびアクセスについて、厳密な管理を維持する。:
&lt;ul&gt;
&lt;li&gt;9.7 すべての媒体の保管と維持を管理するためのポリシーを入手して調べ、ポリシーで定期的な媒体の在庫調査が要求されていることを確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.7.1 すべての媒体の在庫ログを保持し、少なくとも年に一度、媒体の在庫調査を実施する:
&lt;ul&gt;
&lt;li&gt;9.7.1 媒体の在庫ログを調べて、媒体の在庫調査が少なくとも年に一度行われていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.8 次のように、ビジネスまたは法律上不要になった媒体を破棄する。:
&lt;ul&gt;
&lt;li&gt;9.8 定期的な媒体破棄ポリシーを調べて、すべての媒体が対象になっており、以下の要件が定義されていることを確認する。\n• ハードコピー資料は再現できないことの合理的な保証が得られるように、クロスカット裁断、焼却、またはパルプ化する必要がある。\n• 破棄する資料を保管する容器は安全でなければならない。\n• 電子媒体上のカード会員データが、安全な削除に関して業界が承認した標準に従った安全なワイププログラムによって、またはそれ以外の場合は媒体の物理的な破壊によって、回復不能になっている必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.8.1 カード会員データを再現できないよう、ハードコピー資料を裁断、焼却、またはパルプ化する。破棄する資料を保管する容器を安全に保護する。:
&lt;ul&gt;
&lt;li&gt;9.8.1.a 担当者をインタビューし、手順を調べて、ハードコピーの資料が再現できないことの合理的な保証が得られるように、クロスカット裁断、焼却、またはパルプ化されていることを確認する。&lt;/li&gt;
&lt;li&gt;9.8.1.b 破棄される情報を含む資料の保管に使用されるコンテナを調べて、コンテナが安全に保護されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.8.2 カード会員データを再現できないよう、電子媒体上のカード会員データを回復不能にする。:
&lt;ul&gt;
&lt;li&gt;9.8.2 電子媒体上のカード会員データが、安全な削除に関して業界が承認した標準に従った安全なワイププログラムによって、またはそれ以外の場合は媒体の物理的な破壊によって、回復不能になっていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.9 カードの物理的な読み取りによってペイメントカードデータを取り込む装置を改ざんや不正置換から保護する。\n注： これには、カード（カードのスワイプやディップ）によるトランザクションに使用されるカード読み取り装置も含まれる。この要件は、コンピュータのキーボードや POS のキーパッドのような手動キー入力コンポーネントには適用されない。\n注： この要件は、2015 年 6 月 30 日まではベストプラクティスとみなされ、それ以降は要件になる。:
&lt;ul&gt;
&lt;li&gt;9.9 文書化されたポリシーと手順を調べ、以下が含まれていることを確認する。\n• デバイスのリストの管理\n• デバイスを定期的に検査して改ざんや不正置換がないか調べる\n• 関係者にトレーニングを受けさせて、怪しい行動を識別し、デバイスの改ざんや不正置換を報告できるようにする&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.9.1 装置のリストを保持する。リストには以下を含める必要がある。\n• 装置のメーカーと型式\n• 装置の場所（装置が設置されている店舗の住所など）\n• 装置の連番や他の一意識別方法:
&lt;ul&gt;
&lt;li&gt;9.9.1.a 装置のリストを見て、以下が含まれていることを確認する。\n• 装置のメーカーと型式\n• 装置の場所（装置が設置されている店舗の住所など）\n• 装置の連番や他の一意識別方法&lt;/li&gt;
&lt;li&gt;9.9.1.b リストから装置のサンプルを選択して、装置の場所を観察し、リストが正確で最新のものであることを確認する。&lt;/li&gt;
&lt;li&gt;9.9.1.c 担当者をインタビューすることで、装置が追加、移動、廃棄された場合に装置のリストが更新されることを確認する。
{/* textlint-disable ja-technical-writing/no-doubled-joshi */}&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.9.2 定期的に装置の表面を検査して改ざん（カードスキマーの取り付けなど）や不正置換（連番など装置の特性を調べて偽の装置に差し替えられていないことを確認する）を検出する。\n注： 装置が改ざんされたり不正置換されたりする兆候の例としては、予期していない付着物やケーブルが装置に差し込まれている、セキュリティラベルが無くなっていたり、変更されている、ケースが壊れていたり色が変わっている、あるいは連番その他の外部マーキングが変更されているなどがある:
{/* textlint-enable ja-technical-writing/no-doubled-joshi */}
&lt;ul&gt;
&lt;li&gt;9.9.2.a 文書化された手順を調べて、プロセスに以下が含まれるように定義されていることを確認する。\n• 装置を検査する手順\n• 検査の頻度&lt;/li&gt;
&lt;li&gt;9.9.2.b 責任者をインタビューし、検査プロセスを観察して、以下を確認する。\n• 関係者が装置を検査する手順を知っている\n• すべての装置が改ざんや不正置換の形跡がないことを定期的に検査されている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.9.3 関係者が装置の改ざんや不正置換の試みを認識できるようにトレーニングを実施する。トレーニングには以下を含める必要がる。\n・保守要員を名乗っている者に装置へのアクセスを許可する前に、身元を確認する。\n• 検証なしで装置を設置、交換、返品しない。\n• 装置の周辺での怪しい行動（知らない人が装置のプラグを抜いたり装置を開けたりする）に注意する\n• 怪しい行動や装置が改ざんや不正置換された形跡がある場合には適切な関係者（マネージャーやセキュリティ要員など）に報告する:
&lt;ul&gt;
&lt;li&gt;9.9.3.a 販売場所の関係者用トレーニング材料を調べて、以下のトレーニングが含まれていることを確認する。\n・保守要員を名乗っている者に装置への変更、トラブルシューティングのためのアクセスを許可する前に、身元を確認する。\n• 検証なしで装置を設置、交換、返品しない\n• 装置の周辺での怪しい行動（知らない人が装置のプラグを抜いたり装置を開けたりする）に注意する\n• すべての怪しい行動を適切な関係者（マネージャーやセキュリティ要員など）に報告する\n• 怪しい行動や装置が改ざんや不正置換された形跡がある場合には適切な関係者（マネージャーやセキュリティ要員など）に報告する&lt;/li&gt;
&lt;li&gt;9.9.3.b 販売場所の関係者のサンプルをインタビューすることで、彼らがトレーニングを受けており、以下の手順を知っていることを確認します。\n・保守要員を名乗っている者に POS 装置への変更、トラブルシューティングのためのアクセスを許可する前に、身元を確認する。\n• 検証なしで装置を設置、交換、返品しない\n• POS 装置の周辺での怪しい行動（知らない人が装置のプラグを抜いたり装置を開けたりする）に注意する\n• 怪しい行動や POS 装置が改ざんや不正置換された形跡がある場合には適切な関係者（マネージャーやセキュリティ要員など）に報告する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;9.10 カード会員データへのアクセスを制限するためのセキュリティポリシーと操作手順が文書化されて使用されており、影響を受ける関係者全員に知られていることを確認する。:
&lt;ul&gt;
&lt;li&gt;9.10 文書を調べ、担当者をインタビューすることで、カード会員データへのアクセスを制限するためのセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n• 文書化されている\n• 使用されている\n• 影響を受ける関係者全員に知らされている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件10：ネットワークリソースおよびカード会員データへのすべてのアクセスを追跡および監視する:
&lt;ul&gt;
&lt;li&gt;10.1 システムコンポーネントへのすべてのアクセスを各ユーザにリンクする監査証跡を確立する:
&lt;ul&gt;
&lt;li&gt;10.1 システム管理者の観察とインタビューを通じて、\n• システムコンポーネントに対する監査証跡が有効になっていてアクティブであることを確する\n• システムコンポーネントへのアクセスを各ユーザにリンクする&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.2 次のイベントを再現するために、すべてのシステムコンポーネントの自動監査証跡を実装する。:
&lt;ul&gt;
&lt;li&gt;10.2 責任者のインタビュー、監査ログの調査、および監査ログ設定の調査を通じて、以下を実行する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.2.1 カード会員データへのすべての個人アクセス:
&lt;ul&gt;
&lt;li&gt;10.2.1 カード会員データへのすべてのアクセスがログに記録されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.2.2 ルート権限または管理権限を持つ個人によって行われたすべてのアクション:
&lt;ul&gt;
&lt;li&gt;10.2.2 ルートまたは管理者権限を持つ個人によって実施されたすべてのアクションが記録されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.2.3 すべての監査証跡へのアクセス:
&lt;ul&gt;
&lt;li&gt;10.2.3 すべての監査証跡へのアクセスがログ記録されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.2.4 無効な論理アクセス試行:
&lt;ul&gt;
&lt;li&gt;10.2.4 無効な論理アクセス試行が記録されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.2 5 識別と認証メカニズムの使用および変更（新しいアカウントの作成、特権の上昇を含むがこれらに限定されない）、およびルートまたは管理者権限を持つアカウントの変更、追加、削除のすべて:
&lt;ul&gt;
&lt;li&gt;10.2.5.a 識別および認証メカニズムの使用がログに記録されることを確認する。&lt;/li&gt;
&lt;li&gt;10.2.5.b 特権の上昇がすべてログに記録されることを確認する&lt;/li&gt;
&lt;li&gt;10.2.5.c ルートまたは管理者権限を持つアカウントの変更、追加、または削除がすべてログに記録されていることを確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.2.6 監査ログの初期化、停止、一時停止:
&lt;ul&gt;
&lt;li&gt;10.2.6 以下がログに記録されていることを確認する。\n• 監査ログの初期化\n• 監査ログの停止と一時停止&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.2.7 システムレベルオブジェクトの作成および削除:
&lt;ul&gt;
&lt;li&gt;10.2.7 システムレベルオブジェクトの作成および削除がログ記録されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.3 イベントごとに、すべてのシステムコンポーネントについて少なくとも以下の監査証跡エントリを記録する。:
&lt;ul&gt;
&lt;li&gt;10.3 インタビューと観察を通じて、監査可能なイベント(10.2に記載)ごとに、以下を実行する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.3.1 ユーザ識別:
&lt;ul&gt;
&lt;li&gt;10.3.1 ユーザ識別がログエントリに含まれることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.3.2 イベントの種類:
&lt;ul&gt;
&lt;li&gt;10.3.2 ログエントリにイベントの種類が含まれていることを確する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.3.3 日付と時刻:
&lt;ul&gt;
&lt;li&gt;10.3.3 ログエントリに日付と時刻が含まれていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.3.4 成功または失敗を示す情報:
&lt;ul&gt;
&lt;li&gt;10.3.4 ログエントリに成功または失敗を示す情報が含まれることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.3.5 イベントの発生元:
&lt;ul&gt;
&lt;li&gt;10.3.5 ログエントリにイベントの発生元が含まれていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.3.6 影響を受けるデータ、システムコンポーネント、またはリソースのIDまたは名前:
&lt;ul&gt;
&lt;li&gt;10.3.6 影響を受けるデータ、システムコンポーネント、またはリソースのIDまたは名前がログエントリに含まれることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.4 時刻同期技術を使用してすべての重要なシステムクロックおよび時間を同期し、時間を取得、配布、保存するために以下の要件が実施されていることを確認する。\n注： ネットワークタイムプロトコル（NTP）は、時刻同期技術の一例である。:
&lt;ul&gt;
&lt;li&gt;10.4 構成基準とプロセスを調べることで、時刻同期技術が実装され、PCI DSS の要件 6.1 と 6.2 に従って最新状態に保たれていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.4.1 重要なシステムが正確で一貫性のある時刻を持っている。:
&lt;ul&gt;
&lt;li&gt;10.4.1.a 組織内で正しい時刻を取得、配布、保存するプロセスを調べて、以下を確認する。\n• 指定した中央タイムサーバが、外部ソースから時刻信号を受信し、外部ソースからの時刻信号は国際原子時または UTC に基づいている。\n• 複数のタイムサーバがある場合、それらのタイムサーバが正確な時刻を保つためにお互いに通信する。\n• システムは時刻情報を指定した中央タイムサーバからのみ受信する。&lt;/li&gt;
&lt;li&gt;10.4.1.b システムコンポーネントのサンプルに対して、時刻関係のシステムパラメータ設定を観察して、以下を確認する。\n• 指定した中央タイムサーバが、外部ソースから時刻信号を受信し、外部ソースからの時刻信号は国際原子時または UTC に基づいている\n• 複数のタイムサーバが指定されている場合、指定した中央タイムサーバが正確な時刻を保つためにお互いに通信する\n• システムは時刻情報を指定した中央タイムサーバからのみ受信する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.4.2 時刻データが保護されている。:
&lt;ul&gt;
&lt;li&gt;10.4.2.a システム構成および時刻同期設定を調べて、時刻データへのアクセスは、業務上時刻データにアクセスする必要のある担当者のみに制限されていることを確認する。&lt;/li&gt;
&lt;li&gt;10.4.2.b システム構成および時刻同期設定とプロセスを調べて、重要なシステムの時刻設定への変更が、ログ記録、監視、およびレビューされていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.4.3 時刻設定は、業界で認知されている時刻ソースから受信されている。:
&lt;ul&gt;
&lt;li&gt;10.4.3 システム構成を調べて、タイムサーバが（悪意のある個人が時計を変更するのを防ぐために）業界で認知されている特定の外部ソースから時刻更新を受け付けることを確認する。（内部タイムサーバの不正使用を防ぐために）これらの更新を対称キーで暗号化し、時刻更新が提供されるクライアントマシンの IP アドレスを指定するアクセス制御リストを作成もできる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.5 変更できないよう、監査証跡をセキュリティで保護する。:
&lt;ul&gt;
&lt;li&gt;10.5 システム管理者をインタビューし、システム構成とアクセス権限を調べて、次のように、監査証跡が変更できないようにセキュリティで保護されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.5.1 監査証跡の表示を、業務上の必要がある人物のみに制限する。:
&lt;ul&gt;
&lt;li&gt;10.5.1 業務上の必要がある個人のみが監査証跡ファイルを表示できることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.5.2 監査証跡ファイルを不正な変更から保護する。:
&lt;ul&gt;
&lt;li&gt;10.5.2 アクセス制御メカニズム、物理的な分離、ネットワークの分離などによって、現在の監査証跡ファイルが不正な変更から保護されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.5.3 監査証跡ファイルを、変更が困難な一元管理ログサーバまたは媒体に即座にバックアップする。:
&lt;ul&gt;
&lt;li&gt;10.5.3 現在の監査証跡ファイルが変更が困難な一元管理ログサーバまたは媒体に即座にバックアップされることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.5.4 外部に公開されているテクノロジのログを、安全な一元管理の内部ログサーバまたは媒体デバイス上に書き込む。:
&lt;ul&gt;
&lt;li&gt;10.5.4 外部に公開されているテクノロジ（ワイヤレス、ファイアウォール、DNS、メールなど）のログが安全な一元管理される内部ログサーバまたは媒体に書き込まれることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.5.5 ログに対してファイル整合性監視または変更検出ソフトウェアを使用して、既存のログデータを変更すると警告が生成されるようにする(ただし、新しいデータを追加する場合は警告を発生させない)。:
&lt;ul&gt;
&lt;li&gt;10.5.5 システム設定、監視対象ファイル、および監視作業からの結果を調査して、ログに対してファイル整合性監視または変更検出ソフトウェアが使用されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.6 すべてのシステムコンポーネントのログとセキュリティイベントを調べ、異常や怪しい活動を特定する。\n 注： この要件に準拠するために、ログの収集、解析、および警告ツールを使できますす。:
&lt;ul&gt;
&lt;li&gt;10.6 以下のことを実行します&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.6.1 毎日一度以上以下をレビューす\n• すべてのセキュリティイベン\n• CHD や SAD を保存、処理、または送信する、または CHD や SAD のセキュリティに影響を及ぼす可能性のあるすべてのシステムコンポーネントのログ\n• すべての重要なシステムコンポーネントのログ\n• すべてのサーバとセキュリティ機能のあるシステムコンポーネント（ファイアウォール、侵入検出システム/侵入防止システム（IDS/IPS）、認証サーバ、電子商取引リダイレクションサーバなど）のログ:
&lt;ul&gt;
&lt;li&gt;10.6.1.a セキュリティポリシーと手順を調べて、手動またはログツールを用いて、以下を少なくとも毎日一度レビューする手順が定義されていることを確認する。\n• すべてのセキュリティイベン\n• CHD や SAD を保存、処理、または送信する、または CHD やSAD のセキュリティに影響を及ぼす可能性のあるすべてのシステムコンポーネントのログ\n• すべての重要なシステムコンポーネントのログ\n• すべてのサーバとセキュリティ機能のあるシステムコンポーネント（ファイアウォール、侵入検出システム/侵入防止システム（IDS/IPS）、認証サーバ、電子商取引リダイレクションサーバなど）のログ&lt;/li&gt;
&lt;li&gt;10.6.1.b プロセスを観察し、担当者をインタューすることで、以下が少なくとも毎日一度レビューされていることを確認する。\n• すべてのセキュリティイベント\n• CHD や SAD を保存、処理、または送信する、または CHD やSAD のセキュリティに影響を及ぼす可能性のあるすべてのシステムコンポーネントのログ\n• すべての重要なシステムコンポーネントのログ\n• すべてのサーバとセキュリティ機能のあるシステムコンポーネント（ファイアウォール、侵入検出システム/侵入防止システム（IDS/IPS）、認証サーバ、電子商取引リダイレクションサーバなど）のログ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.6.2 組織のポリシー、および年間リスク評価によって決定されたリスク管理戦略に基づいて他のシステムコンポーネントすべてのログを定期的にレビューする:
&lt;ul&gt;
&lt;li&gt;10.6.2.a セキュリティポリシーと手順を調べて、組織のポリシーとリスク管理戦略に基づき定期的に、手動またはログツールを用いて、他のすべてのシステムコンポーネントをレビューする手順が定義されていることを確認する。&lt;/li&gt;
&lt;li&gt;10.6.2.b 組織のリスク評価文書を調べ、担当者をインタビューして、レビューが組織のポリシーとリスク管理戦略に従って実施されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.6.3 レビュープロセスで特定された例外と異常をフォローアップする。:
&lt;ul&gt;
&lt;li&gt;10.6.3.a セキュリティポリシーと手順を調べて、レビュープロセスで特定された例外と異常をフォローアップする手順が定義されていることを確認する。&lt;/li&gt;
&lt;li&gt;10.6.3.b プロセスを観察し、担当者をインタビューすることで、例外と異常のフォローアップが実施されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.7 監査証跡の履歴を少なくとも1年間保持する。少なくとも3カ月はすぐに分析できる状態にしておく(オンライン、アーカイブ、バックアップから復元可能など)。:
&lt;ul&gt;
&lt;li&gt;10.7.a セキュリティポリシーと手順を調べ、以下が定義されていることを確認する。\n• 監査ログ保存ポリシー\n• 監査ログを少なくとも 1 年間保持し、最低 3 カ月はすぐに使用できる状態にしておくための手順。&lt;/li&gt;
&lt;li&gt;10.7.b 担当者をインタビューし、監査ログを調べることで、監査ログが少なくとも1年間利用可能であることを確認する。&lt;/li&gt;
&lt;li&gt;10.7.c 担当者をインタビューし、プロセスを観察することで、解析用に、少なくとも過去3カ月分のログが即座に復元できることを確認する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10.8 ネットワークリソースとカード会員データへのすべてのアクセスを監視するためのセキュリティポリシーと操作手順が文書化され、使用されており、影響を受ける関係者全員に知られていることを確認する。:
&lt;ul&gt;
&lt;li&gt;10.8 文書を調べ、担当者をインタビューすることで、ネットワークリソースとカード会員データへのすべてのアクセスを監視するためのセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n• 文書化されている\n• 使用されている\n• 影響を受ける関係者全員に知られている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件11：セキュリティシステムおよびプロセスを定期的にテストする:
&lt;ul&gt;
&lt;li&gt;11.1 四半期ごとにワイヤレスアクセスポイントの存在をテストし（802.11）、すべての承認されているワイヤレスアクセスポイントと承認されていないワイヤレスアクセスポイントを検出し識別するプロセスを実施する\n 注： プロセスで使用される方法には、ワイヤレスネットワークのスキャン、システムコンポーネントおよびインフラストラクチャの論理的/物理的な検査、ネットワークアクセス制御（NAC）、無線 IDS/IPS が含まれるがこれらに限定されるわけではない。\nいずれの方法を使用する場合も、承認されてるデバイスと承認されていないデバイスを両方検出および識別できる機能を十分に備えている必要がある。:
&lt;ul&gt;
&lt;li&gt;11.1.a ポリシーと手順を調べ、四半期ごとに承認されているワイヤレスアクセスポイントと承認されていないワイヤレスアクセスポイントを両方検出し識別するプロセスが定義されていることを確認する。&lt;/li&gt;
&lt;li&gt;11.1.b 方法が、少なくとも以下を含むすべての不正なワイヤレスアクセスポイントを検出して識別するのに十分であることを確認する。\n・ システムコンポーネントに挿入された WLAN カード\n・ ワイヤレスアクセスポイントを作成するためにシステムコンポーネントに（USB などで）接続したポータブルやモバイルデバイス\n・ネットワークポートまたはネットワークデバイスに接続されたワイヤレスデバイス&lt;/li&gt;
&lt;li&gt;11.1.c 最近のワイヤレススキャンの出力を調べて、以下を確認する。\n• 承認されているワイヤレスアクセスポイントと承認されていないワイヤレスアクセスポイントが識別される\n• すべてのシステムコンポーネントおよび施設に対し、このスキャンが少なくとも四半期ごとに実施されている&lt;/li&gt;
&lt;li&gt;11.1.d 自動監視（ワイヤレス IDS/IPS や NAC など）が使用されている場合は、担当者に通知するための警告が生成されるように構成されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.1.1 文書化されている業務上の理由を含め、承認されているワイヤレスアクセスポイントのインベントリを維持する。:
&lt;ul&gt;
&lt;li&gt;11.1.1 文書化されている記録を調べて、承認されているワイヤレスアクセスポイントのインベントリが維持されており、すべての承認されているワイヤレスアクセスポイントに対して業務上の理由が文書化されていることを確認す&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.1.2 不正なワイヤレスデバイスが検出された場合のインシデント対応計画を実装する。:
&lt;ul&gt;
&lt;li&gt;11.1.2.a 組織のインシデント計画を調べて（要件 12.9）、承認されていないワイヤレスアクセスポイントが検出された場合に、その応答を定義し、要求していることを確認する。null&lt;/li&gt;
&lt;li&gt;11.1.2.b 責任者をインタビューし、最近のワイヤレススキャンと関連応答を調べて、承認されていないワイヤレスアクセスポイントが見つかった場合に対処されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.2 内部と外部ネットワークの脆弱性スキャンを少なくとも四半期に一度およびネットワークでの大幅な変更（新しいシステムコンポーネントのインストール、ネットワークトポロジの変更、ファイアウォール規則の変更、製品アップグレードなど）後に実行する。\n注： 四半期ごとのスキャンプロセスの複数のスキャンレポートをまとめて、すべてのシステムがスキャンされ、すべての脆弱性に対処されたことを示すことができる。未修正の脆弱性が対処中であることを確認するために、追加の文書が要求される場合がある。\n初期の PCI DSS 準拠では、評価者が 1）最新のスキャン結果が合格スキャンであったこと、2）事業体で四半期に一度のスキャンを要求するポリシーと手順が文書化されていること、および 3）スキャン結果で判明した脆弱性が再スキャンにおいて示されているとおりに修正されたことを確認した場合、初回のPCI DSS 準拠のために、四半期に一度のスキャンに 4 回合格することは要求されない。\n初回 PCI DSS レビュー以降は毎年、四半期ごとのスキャンに 4 回合格しなければならない。:
&lt;ul&gt;
&lt;li&gt;11.2 スキャンレポートと関連文書を調べて、内部および外部脆弱性スキャンが、次のように実行されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.2.1 すべての「高リスク」脆弱性（要件6.1 で識別）が解決されるまで、必要に応じて四半期ごとの内部脆弱性スキャンを繰り返す。スキャンは有資格者が実施する必要がある。:
&lt;ul&gt;
&lt;li&gt;11.2.1.a スキャンレポートをレビューし、四半期ごとの内部スキャンが過去 12 カ月間で 4 回行われたことを確認する。&lt;/li&gt;
&lt;li&gt;11.2.1.b スキャンレポートをレビューし、スキャンプロセスで再スキャンを行ったこと、または PCI DSS 要件 6.1 で定義されたすべての「高リスク」の脆弱性が解決されるまで再スキャンを行ったことを確認する。&lt;/li&gt;
&lt;li&gt;11.2.1.c 担当者をインタビューすることで、スキャンが内部リソースまたは資格のある外部の第三者によって行われたこと、該当する場合は、テスターの組織の独立性（QSA や ASV である必要はない）が存在することを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.2.2 四半期に一度の外部の脆弱性スキャンは、PCI（Payment Card Industry）セキュリティ基準審議会（PCI SSC）によって資格を与えられた認定スキャニングベンダ（ASV）によって実行される必要がある。スキャンに合格するまで、必要に応じて再スキャンする。\n注： 四半期に一度の外部の脆弱性スキャンは、PCI（Payment Card Industry）セキュリティ基準審議（PCI SSC）によって資格を与えられた認定スキャニングベンダ（ASV）によって実行される必要がある。\nスキャンにおける顧客の責任、スキャンの準備などについては、PCI SSC Web サイトで公開されている『ASV プログラムガイド』を参照してください。:
&lt;ul&gt;
&lt;li&gt;11.2.2.a 四半期ごとに行われた最新の 4 回の内部スキャンからの結果をレビューし、過去 12 カ月間で四半期ごとのスキャンが 4回行われたことを確認する。&lt;/li&gt;
&lt;li&gt;11.2.2.b 四半期ごとの各スキャンの結果をレビューし、『ASV プログラムガイド』の要件（たとえば、CVSS による 4.0 以上のレートの脆弱性がなく、自動エラーがない）を満たすことを確認する。&lt;/li&gt;
&lt;li&gt;11.2.2.c スキャンレポートをレビューし、PCI SSC認定スキャニングベンダ（ASV）がスキャンを完了したことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.2.3 最初の変更があった後の内部と外部脆弱性スキャンを必要に応じて繰り返す。\nスキャンは有資格者が実施する必要がある。:
&lt;ul&gt;
&lt;li&gt;11.2.3.a 変更管理文書とスキャンレポートを調べて相関させ、大幅な変更の対象となるシステムコンポーネントがスキャンされたことを確認する。&lt;/li&gt;
&lt;li&gt;11.2.3.b スキャンレポートをレビューし、スキャンプロセスに、以下の要件を満たすまで再スキャンを実行することが含まれていることを確認する。\n・ 外部スキャンの場合、CVSS スコアで 4.0 以上の脆弱性がないこと。\n・ 内部スキャンの場合、合格結果が取得されること、またはPCI DSS 要件 6.1 で定義されたすべての「高リスク」脆弱性が解消されること。&lt;/li&gt;
&lt;li&gt;11.2.3.c スキャンが有資格の内部リソースまたは有資格の外部第三者によって行われたこと、該当する場合は、テスターの組織の独立性（ QSA や ASV である必要はない）が存在することを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.3 少なくとも以下を含むペネトレーションテスト方法を開発し、実装する。\n• 業界承認のペネトレーションテスト方法（NISTSP800-115 など）に基づいている\n• CDE 境界と重要システム全体を対象とした対応を含める\n• ネットワークの内部と外部からの侵入テスト\n• セグメンテーションと範囲減少制御の有効性テストを含める\n• アプリケーション層のペネトレーションテストは、少なくとも要件 6.5 に記載されている脆弱性を含める必要がある\n• ネットワーク層のペネトレーションテストには、ネットワーク機能とオペレーティングシステムをサポートするコンポーネントを含める必要がある\n• 過去 12 カ月にあった脅威と脆弱性のレビューと考慮を含める\nペネトレーションテスト結果と修正実施結果の保持を指定する\n注： 要件 11.3 へのこの更新は、2015 年 6 月30 日まではベストプラクティスとみなされ、それ以降は要件になる。ペネトレーションテストの PCI DSS v2.0 要件は、v3.0 で更新されるまで順守する必要がある。:
&lt;ul&gt;
&lt;li&gt;11.3 ペネトレーションテスト方法を調べ、責任者をインタビューすることで、この方法が実装されており少なくとも以下を含むことを確認する。\n• 業界承認のペネトレーションテスト方法に基づいている\n• CDE 境界と重要システム全体を対象とした対応\n• ネットワークの内部と外部からの侵入テスト\n• セグメンテーションと範囲減少制御の有効性テスト\n• アプリケーション層のペネトレーションテストは、少なくとも要件 6.5 に記載されている脆弱性を含める必要がある\n• ネットワーク層のペネトレーションテストには、ネットワーク機能とオペレーティングシステムをサポートするコンポーネントを含める必要がある\n• 過去 12 カ月にあった脅威と脆弱性のレビューと考慮\n• ペネトレーションテスト結果と修正実施結果の保持を指定する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.3.1 外部のペネトレーションテストを少なくとも年に一度および大幅なインフラストラクチャまたはアプリケーションのアップグレードや変更（オペレーティングシステムのアップグレード、環境へのサブネットワークの追加、環境への Web サーバの追加など）後に実行する。:
&lt;ul&gt;
&lt;li&gt;11.3.1.a 最新の外部ペネトレーションテストの対象範囲と結果を調べて、ペネトレーションテストが以下を満たしていることを確認する。\n• 定義された方法に従っている\n• 少なくとも年に一度実施する\n• 環境に対して重大な変更が行われた後実施する&lt;/li&gt;
&lt;li&gt;11.3.1.b テストが認定された内部リソースまたは認定された外部の第三者によって実行されたこと、および該当する場合はテスターが組織的に独立した立場であること（QSA または ASV である必要はない）を確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.3.2 内部ペネトレーションテストを少なくとも年に一度および大幅なインフラストラクチャまたはアプリケーションのアップグレードや変更（オペレーティングシステムのアップグレード、環境へのサブネットワークの追加、環境への Web サーバの追加など）後に実行する。:
&lt;ul&gt;
&lt;li&gt;11.3.2.a 最新の内部ペネトレーションテストの結果を調べて、ペネトレーションテストが少なくとも年に一度および環境への大幅な変更後に実行されていることを確認する。\n• 定義された方法に従っている\n• 少なくとも年に一度実施する\n• 環境に対して重大な変更が行われた後に実施する&lt;/li&gt;
&lt;li&gt;11.3.2.b テストが認定された内部リソースまたは認定された外部の第三者によって実行されたこと、および該当する場合はテスターが組織的に独立した立場であること（QSA または ASV である必要はない）を確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.3.3 ペネトレーションテストで検出された悪用可能な脆弱性が修正され、テストが繰り返されて修正が確認される。:
&lt;ul&gt;
&lt;li&gt;11.3.3 ペネトレーションテスト結果を調べて、既知の悪用可能な脆弱性が修正され、テストが繰り返されて脆弱性が修正されたことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.3.4 セグメンテーションを用いて CDE を他のネットワークから分離した場合、少なくとも年に一度とセグメンテーションの制御/方法が変更された後にペネトレーションテストを行って、セグメンテーション方法が運用可能で効果的であり、適用範囲内のシステムから適用範囲外のシステムをすべて分離することを確認する:
&lt;ul&gt;
&lt;li&gt;11.3.4.a セグメンテーション制御を調べ、ペネトレーションテスト方法をレビューして、ペネトレーションテスト手順ですべてのセグメンテーション方法をテストし、ペネトレーションテストを行って、セグメンテーション方法が運用可能で効果的であり、適用範囲内のシステムから適用範囲外のシステムをすべて分離することを確認する。&lt;/li&gt;
&lt;li&gt;11.3.4.b 最新のペネトレーションテストからの結果を調べて、セグメンテーション制御を確認するペネトレーションテストが以下を満たしていることを確認する。\n• 少なくとも年 1 回およびセグメンテーション制御/方法に何らかの変更を加えた後に実施される\n• 使用されているすべてのセグメンテーション制御/方法を対象とする\n• セグメンテーション方法が運用可能で効果的であり、対象範囲内システムから対象範囲外システムを分離する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.4侵入検知システムや侵入防止手法を使用して、ネットワークへの侵入を検知および/または防止する。カード会員データ環境との境界およびカード会員データ環境内の重要なポイントを通過するすべてのトラフィックを監視し、侵害の疑いがある場合は担当者に警告する。\nすべての侵入検知および防止エンジン、ベースライン、シグネチャを最新状態に保つ。:
&lt;ul&gt;
&lt;li&gt;11.4.a システム構成とネットワーク図を調べて、（侵入検知システムや侵入防止などの）手法が使用されていて、すべてのトラフィックが監視されていることを確認する。\n• カード会員データ環境の境界で\n• カード会員データ環境内の重要なポイントで&lt;/li&gt;
&lt;li&gt;11.4.b システム構成を調べ、責任者をインタビューすることで、侵入検知や侵入防止が侵害の疑いを担当者に警告することを確認する。&lt;/li&gt;
&lt;li&gt;11.4.c 侵入検知や侵入防止手法の構成とベンダ文書を調べて、侵入検知や侵入防止手法デバイスが最適な保護を実現するためのベンダの指示に従って構成、保守、更新されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.5 変更検出メカニズム（ファイル整合性監視ツールなど）を導入して重要なシステムファイル、構成ファイル、またはコンテンツファイルの不正な変更を担当者に警告し、重要なファイルの比較を少なくとも週に一度実行するようにソフトウェアを構成する。\n注：変更検出目的で、重要なファイルとは通常、定期的に変更されないが、その変更がシステムの侵害や侵害のリスクを示す可能性があるファイルを示す。ファイル整合性監視製品などの変更検出メカニズムでは通常、関連オペレーティングシステム用の重要なファイルがあらかじめ構成されている。カスタムアプリケーション用のファイルなど、その他の重要なファイルは、事業体（つまり、加盟店またはサービスプロバイダ）による評価および定義が必要である。:
&lt;ul&gt;
&lt;li&gt;11.5.a システム設定と監視されたファイルを観察し、監視活動の結果をレビューすることで、カード会員データ環境で、変更検出メカニズムが使用されていることを確認する。\n監視する必要があるファイルの例:\n・ システム実行可能ファイル\n・ アプリケーション実行可能ファイル\n・ 構成およびパラメータファイル\n・ 集中的に保存されている、履歴またはアーカイブされた、ログおよび監査ファイル\n・ 事業体が指定した追加の重要ファイル（リスク評価その他の方法で）&lt;/li&gt;
&lt;li&gt;11.5.b 重要なファイルの不正な変更を担当者に警告し、重要なファイルの比較を少なくとも週に 1 回実行するようにメカニズムが構成されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.5.1 変更検出ソリューションによって生成された警告に対応するプロセスを実装する。:
&lt;ul&gt;
&lt;li&gt;11.5.1 担当者をインタビューすることで、すべての警告が調査され解決されたことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;11.6 セキュリティ監視とテストに関するセキュリティポリシーと操作手順が文書化されて使用されており、影響を受ける関係者全員に知られていることを確認する。:
&lt;ul&gt;
&lt;li&gt;11.6 文書を調べ、担当者をインタビューすることで、セキュリティ監視とテストに関するセキュリティポリシーと操作手順が以下の要件を満たしていることを確認する。\n• 文書化されている\n• 使用されている\n• 影響を受ける関係者全員に知られている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;要件12：従業員および派遣社員向けの情報セキュリティポリシーを整備する:
&lt;ul&gt;
&lt;li&gt;12.1 セキュリティポリシーを確立、公開、維持、普及させる:
&lt;ul&gt;
&lt;li&gt;12.1 情報セキュリティポリシーを調べて、ポリシーが公開され、すべての関係者（ベンダ、ビジネスパートナーを含む）に普及されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.1.1 少なくとも年に一度レビューし、環境が変更された場合にポリシーを更新する。:
&lt;ul&gt;
&lt;li&gt;12.1.1 情報セキュリティポリシーを少なくとも年に一度レビューし、ビジネス目標またはリスク環境への変更を反映するため、必要に応じて更新されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.2 以下のリスク評価プロセスを実装する。\n• 少なくとも年に一度と環境に大きな変更があった場合（買収、合併、移転など）に実施される\n• 重要なアセット、脅威、脆弱性を識別する\n• 正式なリスク評価に至る\n（リスク評価方法の例としては、OCTAVE、ISO 27005、および NIST SP800-30 が挙げられますが、これらに限定されません。）:
&lt;ul&gt;
&lt;li&gt;12.2.a 正式なリスク評価で、脅威、脆弱性、結果を識別する、年に一度のリスク評価プロセスが文書化されていることを確認する。&lt;/li&gt;
&lt;li&gt;12.2.b リスク評価文書をレビューし、リスク評価プロセスが少なくとも年に一度と大きな変更があった場合に実施されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3 重要なテクノロジに関する使用ポリシーを作成して、これらのテクノロジの適切な使用を定義する\n注： 重要なテクノロジの例には、リモートアクセスおよびワイヤレステクノロジ、ノートパソコン、タブレット、リムーバブル電子メディア、電子メールの使用、インターネットの使用がありますが、これらに限定されません\nこれらの使用ポリシーで以下を要求することを確認する。
&lt;ul&gt;
&lt;li&gt;12.3 重要なテクノロジに関する使用ポリシーを調べ、責任者をインタビューすることで、ポリシーが実装・順守されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3.1 権限を持つ関係者による明示的な承認:
&lt;ul&gt;
&lt;li&gt;12.3.1 使用ポリシーが、テクノロジを使用するために、許可された当事者からの明示的な承認を要求していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3.2 テクノロジの使用に対する認証:
&lt;ul&gt;
&lt;li&gt;12.3.2 使用ポリシーが、すべてのテクノロジの使用に、ユーザ ID とパスワードまたはその他の認証項目（トークンなど）による認証を要求するプロセスを含んでいることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3.3 このようなすべてのデバイスおよびアクセスできる担当者のリスト:
&lt;ul&gt;
&lt;li&gt;12.3.3 使用ポリシーが、すべてのデバイスおよびデバイスの使用を許可された担当者のリストを定義していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3.4 デバイスの所有者、連絡先情報、目的を正確にその場で識別できる方法（ラベル付け、コーディング、デバイスのインベントリ）:
&lt;ul&gt;
&lt;li&gt;12.3.4 使用ポリシーがデバイスの所有者、連絡先情報、目的を正確にその場で識別できる方法（ラベル付け、コーディング、デバイスのインベントリ）を定義することを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3.5 テクノロジの許容される利用法:
&lt;ul&gt;
&lt;li&gt;12.3.5 使用ポリシーが、テクノロジの許容される利用法を定義していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3.6 テクノロジの許容されるネットワーク上の場所:
&lt;ul&gt;
&lt;li&gt;12.3.6 使用ポリシーが、テクノロジの許容されるネットワーク上の場所を定義していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3.7 会社が承認した製品のリスト:
&lt;ul&gt;
&lt;li&gt;12.3.7 使用ポリシーが、会社が承認した製品のリストを含むことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3.8 非アクティブ状態が特定の期間続いた後のリモートアクセステクノロジのセッションの自動切断:
&lt;ul&gt;
&lt;li&gt;12.3.8.a 使用ポリシーが、非アクティブ状態が一定期間続いた後のリモートアクセステクノロジのセッションの自動切断を要求していることを確認する。&lt;/li&gt;
&lt;li&gt;12.3.8.b リモートアクセステクノロジの構成を調べて、非アクティブ状態が一定期間続いた後にリモートアクセステクノロジのセッションが自動切断されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3.9 ベンダおよびビジネスパートナーには必要とする場合にのみリモートアクセステクノロジをアクティブ化し、使用後直ちに非アクティブ化する:
&lt;ul&gt;
&lt;li&gt;12.3.9 使用ポリシーで、ベンダやビジネスパートナーが必要とする場合にのみリモートアクセステクノロジをアクティブ化し、使用後直ちに非アクティブ化することが要求されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.3.10 リモートアクセステクノロジ経由でカード会員データにアクセスする担当者については、定義されたビジネスニーズのために明示的に承認されていない限り、ローカルハードドライブおよびリムーバブル電子メディアへのカード会員データのコピー、移動、保存を禁止する。　承認されたビジネスニーズがある場合、使用ポリシーはデータが適用される PCI DSS 要件すべてに従って保護されることを要求する必要がある。:
&lt;ul&gt;
&lt;li&gt;12.3.10.a 使用ポリシーで、リモートアクセステクノロジを介してカード会員データにアクセスする場合、このようなデータをローカルハードドライブやリムーバブル電子媒体にコピー、移動、保存することは禁止されていることを確認する。&lt;/li&gt;
&lt;li&gt;12.3.10.b 適切な承認を持つ担当者について、使用ポリシーが PCI DSS 要件に従って、カード会員データの保護を要求していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.4 セキュリティポリシーと手順が、すべての担当者に関する情報セキュリティ責任を明確に定義していることを確認する。:
&lt;ul&gt;
&lt;li&gt;12.4.a すべての担当者について、情報セキュリティを明確に定義する情報セキュリティポリシーを確認する。&lt;/li&gt;
&lt;li&gt;12.4.b 責任者のサンプルをインタビューして、セキュリティポリシーを理解していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.5 個人またはチームに以下の情報セキュリティ管理責任を割り当てる。:
&lt;ul&gt;
&lt;li&gt;12.5 情報セキュリティポリシーと手順を調べ、以下を確認する。\n• 情報セキュリティが最高セキュリティ責任者またはマネージメントのその他のセキュリティに詳しいメンバーに正式に割り当てられている。\n• 以下の情報セキュリティ責任が明確かつ正式に割り当てられている：&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.5.1 セキュリティポリシーおよび手続きを確立、文書化、配布する。:
&lt;ul&gt;
&lt;li&gt;12.5.1 セキュリティポリシーと手順を確立、文書化、および配布する責任が、正式に割り当てられていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.5.2 セキュリティの警告や情報を監視および分析し、適切な担当者に配布する。:
&lt;ul&gt;
&lt;li&gt;12.5.2 セキュリティの警告を監視および分析し、情報を適切な情報セキュリティおよび部署管理担当者に配布する責任が、正式に割り当てられていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.5.3 セキュリティインシデントの対応およびエスカレーション手順を確立、文書化、配布し、すべての状況にタイムリーかつ効率的に対処することを確認する。:
&lt;ul&gt;
&lt;li&gt;12.5.3 セキュリティインシデントの対応およびエスカレーション手順を確立、文書化、および配布する責任が、正式に割り当てられていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.5.4 追加、削除、変更を含め、ユーザアカウントを管理する:
&lt;ul&gt;
&lt;li&gt;12.5.4 ユーザアカウントの管理（追加、削除、変更）の責任と認証管理の責任が正式に割り当てられていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.5.5 すべてのデータへのアクセスを監視および管理する。:
&lt;ul&gt;
&lt;li&gt;12.5.5 すべてのデータへのアクセスを監視および管理する責任が正式に割り当てられていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.6 カード会員データセキュリティの重要性を全担当者が認識できるように正式なセキュリティ意識向上プログラムを実装する:
&lt;ul&gt;
&lt;li&gt;12.6.a 正式なセキュリティ意識向上プログラムを調べて、このプログラムがカード会員データセキュリティの重要性を全担当者に認識させることができることを確認する。&lt;/li&gt;
&lt;li&gt;12.6.b セキュリティ意識向上プログラム手順と文書を調べて、以下を実施する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.6.1 担当者の教育を採用時および少なくとも年に一度行う。\n注： 方法は、担当者の役割とカード会員データへのアクセスレベルに応じて異なる。:
&lt;ul&gt;
&lt;li&gt;12.6.1.a セキュリティ意識向上プログラムが、担当者の意識向上と教育を図るため、複数の方法（たとえば、ポスター、手紙、メモ、Webベースのトレーニング、会議、プロモーションなど）で提供されていることを確認する。&lt;/li&gt;
&lt;li&gt;12.6.1.b 担当者が、採用時および少なくとも年に一度、セキュリティ意識向上トレーニングに参加していることを確認する。&lt;/li&gt;
&lt;li&gt;12.6.1.c 担当者のサンプルをインタビューすることで、意識向上トレーニングを完了しており、カード会員データセキュリティの重要さを認識していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.6.2 担当者は、少なくとも年に一度セキュリティポリシーおよび手順を読み、理解したことを認める必要がある。:
&lt;ul&gt;
&lt;li&gt;12.6.2 担当者が、少なくとも年に一度セキュリティポリシーおよび手順を読み、理解したことを書面または電子的に認める必要があることを、セキュリティ意識向上プログラムが要求していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.7 雇用する前に、可能性のある担当者を選別して、内部ソースからの攻撃リスクを最小限に抑える。（バックグラウンドチェックの例には、職歴、犯罪歴、信用履歴、経歴照会がある。）\n注： このような可能性のある担当者を、トランザクションの実施で一度に 1 つのカード番号にしかアクセスできないようなレジ係など、特定の役職に採用する場合は、この要件は推奨のみです。:
&lt;ul&gt;
&lt;li&gt;12.7 人事部門の管理者に問い合わせて、カード会員データまたはカード会員データ環境にアクセスする可能性のある担当者については、雇用の前にバックグラウンドチェックが（地域法の制約内で）実施されることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.8 カード会員データがサービスプロバイダと共有される場合は、次の項目を含め、サービスプロバイダを管理するポリシーと手順を維持および実装する。:
&lt;ul&gt;
&lt;li&gt;12.8 ポリシーと手順の観察とレビュー、関連文書のレビューを通して、カード会員データを共有するか、カード会員データのセキュリティに影響を及ぼす可能性のあるサービスプロバイダ（たとえば、バックアップテープ保管施設、Web ホスティング企業やセキュリティサービスプロバイダなどの管理対象サービスプロバイダ、または不正モデリング目的でデータを受信するサービスプロバイダなど）を次のように管理するプロセスが実装されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.8.1 サービスプロバイダのリストを維持する。:
&lt;ul&gt;
&lt;li&gt;12.8.1 サービスプロバイダのリストが維持されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.8.2サービスプロバイダは、プロバイダが、顧客に代わって所有、保存、処理、送信するカード会員データのセキュリティについて、または顧客のカード会員データのセキュリティに影響を与える範囲について責任を持つことを認める内容の書面による契約書を維持する。\n注： 同意の正確な言葉づかいは、提供されるサービスの詳細、各事業体に割り当てられる責任など、2 つの事業体間の同意よって異なります。同意の正確な言葉づかいに、この要件で提供されているのと同じものを含める必要はありません。:
&lt;ul&gt;
&lt;li&gt;12.8.2 書面による契約を調べて、サービスプロバイダが、顧客に代わって所有、保存、処理、送信するカード会員データのセキュリティについて、または顧客のカード会員データのセキュリティに影響を与える範囲について責任を持つことを認める内容の書面による契約書を維持していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.8.3 契約前の適切なデューディリジェンスを含め、サービスプロバイダとの契約に関するプロセスが確立されている。:
&lt;ul&gt;
&lt;li&gt;12.8.3 サービスプロバイダとの契約前の適切なデューディリジェンスを含め、ポリシーと手順が文書化されて、実施されていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.8.4 少なくとも年に一度、サービスプロバイダのPCI DSS準拠ステータスを監視するプログラムを維持する。:
&lt;ul&gt;
&lt;li&gt;12.8.4 事業体が、少なくとも年に一度そのサービスプロバイダのPCI DSS準拠ステータスを監視するためのプログラムを維持していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.8.5 各サービスプロバイダに対し、どのPCI DSS 要件がサービスプロバイダによって管理され、どの PCI DSS が事業体によって管理されるかについての情報を維持する。:
&lt;ul&gt;
&lt;li&gt;12.8.5 各サービスプロバイダに対し、どの PCI DSS 要件がサービスプロバイダによって管理され、どの PCI DSS が事業体によって管理されるかについての情報を事業体が維持していることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.9 サービスプロバイダ用の追加要件:顧客に代わって所有、保存、処理、送信するカード会員データのセキュリティについて、または顧客のカード会員データのセキュリティに影響を与える範囲について責任を持つことを認める内容の書面による契約書を維持する。\n注： この要件は、2015 年 6 月 30 日まではベストプラクティスとみなされ、それ以降は要件になる。\n注： 同意の正確な言葉づかいは、提供されるサービスの詳細、各事業体に割り当てられる責任など、2 つの事業体間の同意よって異なります。同意の正確な言葉づかいに、この要件で提供されているのと同じものを含める必要はありません。:
&lt;ul&gt;
&lt;li&gt;12.9.1 サービスプロバイダのポリシーと手順をレビューし、書面による契約のテンプレートを読んで、サービスプロバイダが、顧客のカード会員データや機密の認証データを取り扱う、アクセスする、または他の方法で保存、処理、送信するか、顧客のカード会員データ環境を顧客に委託されて管理するという業務範囲において該当するすべての PCI DSS 要件を順守するという同意を書面にて顧客に提示したことを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.10 インシデント対応計画を実施する。システム違反に直ちに対応できるよう準備する。:
&lt;ul&gt;
&lt;li&gt;12.10 インシデント対応計画と関連手順を調べて、事業体がシステム違反に対して以下を実施することで即時対応する用意があることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.10.1 システム違反が発生した場合に実施されるインシデント対応計画を作成する。計画では、最低限、以下に対応する。\n・ペイメントブランドへの通知を最低限含む、侵害が発生した場合の役割、責任、および伝達と連絡に関する戦略\n・具体的なインシデント対応手順\n・ビジネスの復旧および継続手順\n・データバックアッププロセス\n・侵害の報告に関する法的要件の分析\n・すべての重要なシステムコンポーネントを対象とした対応\n・ペイメントブランドによるインシデント対応手順の参照または包含:
&lt;ul&gt;
&lt;li&gt;12.10.1.a インシデント対応計画に以下が含まれていることを確認する。\n・ペイメントブランドへの通知を最低限含む、侵害が発生した場合の役割、責任、および伝達に関する戦略\n・具体的なインシデント対応手順\n・ビジネスの復旧および継続手順\n・データバックアッププロセス\n・侵害の報告に関する法的要件の分析（データベースにカリフォルニア在住者が含まれている企業に対し、実際の侵害または侵害の可能性が発生した場合に、影響を受ける消費者への通知を要求するCalifornia Bill 1386 など）\n・すべての重要なシステムコンポーネントを対象とした対応\n・ペイメントブランドによるインシデント対応手順の参照または包含&lt;/li&gt;
&lt;li&gt;12.10.1.b 担当者をインタビューし、以前に報告されたインシデントや警告をレビューして、文書化されたインシデントレスポンス計画と手順に従っていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.10.2 少なくとも年に一度、計画をテストする。:
&lt;ul&gt;
&lt;li&gt;12.10.2 少なくとも年に一度、計画がテストされていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.10.3 警告に 24 時間 365 日体制で対応できる担当者を指定する。:
&lt;ul&gt;
&lt;li&gt;12.10.3 ポリシーの観察とレビュー、および責任者のインタビューを通じて、承認されていない活動、承認されていないワイヤレスアクセスポイントの検出、重要な IDS 警告、重要なシステムまたはコンテンツファイルの承認されていない変更の痕跡がないかどうかを調査するために、インシデント対応および監視が 24 時間体制で行われていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.10.4 セキュリティ違反への対応を担当するスタッフに適切なトレーニングを提供する。:
&lt;ul&gt;
&lt;li&gt;12.10.4 ポリシーの観察とレビュー、および責任者のインタビューを通じて、セキュリティ違反への対応に責任を持つスタッフが定期的にトレーニングされていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.10.5 侵入検知、侵入防止、ファイアウォール、ファイル整合性監視システムを含むがこれらに限定されない、セキュリティ監視システムからの警告を含める。:
&lt;ul&gt;
&lt;li&gt;12.10.5 ポリシーの観察とレビューを通じて、承認されていない無線アクセスポイントの検出を含め、セキュリティ監視システムからの警告の監視および対応がインシデント対応計画に含まれていることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;12.10.6 得られた教訓を踏まえてインシデント対応計画を変更および改善し、業界の発展を組み込むプロセスを作成する。:
&lt;ul&gt;
&lt;li&gt;12.10.6 ポリシーの観察とレビュー、および責任者のインタビューを通じて、得られた教訓を踏まえてインシデント対応計画を変更および改善し、業界の発展を組み込むプロセスがあることを確認する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{/* textlint-enable */}&lt;/p&gt;
</content:encoded></item><item><title>PHPのDeployerをCircleCI上で実行して自動デプロイ</title><link>https://blog.teraren.com/posts/php-deployer/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-deployer/</guid><description>PHPアプリのデプロイをDeployerとCircleCI 2.0で完全自動化する設定例をサンプルリポジトリ付きで解説。1分以内にデプロイ完了する構成を紹介</description><pubDate>Mon, 19 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PHPのDeployはファイルコピーなので、Railsのアプリケーションサーバが絡むデプロイに比べて楽で良い。&lt;/li&gt;
&lt;li&gt;CircleCI2.0上で、コンテナの準備を含めても1分で完了する。&lt;/li&gt;
&lt;li&gt;サンプルソースコード。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/phpapp&quot;&gt;https://github.com/matsubo/phpapp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Live app
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://phpapp.teraren.com/&quot;&gt;http://phpapp.teraren.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ソース
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/phpapp/blob/master/webroot/index.php&quot;&gt;https://github.com/matsubo/phpapp/blob/master/webroot/index.php&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/08/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;CircleCIからDeployer&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/08/Screen-Shot-2019-08-19-at-12.19.48.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/matsubo/phpapp/blob/master/README.md&quot;&gt;https://github.com/matsubo/phpapp/blob/master/README.md&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Setup&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% git clone git@github.com:matsubo/phpapp.git
% cd phpapp
% composer install
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Command example&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% time php vendor/bin/dep deploy test
✈︎ Deploying master on blog.teraren.com
✔ Executing task deploy:prepare
✔ Executing task deploy:lock
✔ Executing task deploy:release
➤ Executing task deploy:update_code
Cloning into &apos;/home/matsu/Sites/teraren.com/phpapp/releases/2&apos;...
Counting objects: 36, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (16/16), done.
Writing objects: 100% (36/36), done.
Total 36 (delta 12), reused 36 (delta 12)
Connection to blog.teraren.com closed.
✔ Ok
✔ Executing task deploy:shared
✔ Executing task deploy:writable
✔ Executing task deploy:vendors
✔ Executing task deploy:clear_paths
✔ Executing task deploy:symlink
✔ Executing task deploy:unlock
✔ Executing task cleanup
Successfully deployed!
       15.56 real         0.65 user         0.60 sys
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Setup history&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% composer init
% composer require deployer/deployer --dev
% php vendor/bin/dep init
% vim deploy.php; vim hosts.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nginx側の設定。普通な感じで。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen 80;
    listen [::]:80;

    server_name phpapp.teraren.com;

    location / {
        root /home/matsu/Sites/teraren.com/phpapp/current/webroot;
        index index.php index.html index.htm;
        access_log /var/log/nginx/phpapp.teraren.com main;

        location ~ \.php {
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;DeployerとCircleCIの組み合わせはとても楽。&lt;/li&gt;
&lt;li&gt;AutoScale用の設定が無いので、AWSのCodeDeployと連携した方が良さそうです。
&lt;ul&gt;
&lt;li&gt;CircleCI -&amp;gt; bastion -&amp;gt; Application server という構成のベストな設定は見つからなかった。自分でコマンドを色々書かないといけなさそうな気がする。それを考えるとCodeDeployに任せた方が楽な気がする。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Center for trade facilitation and e-business (UN/CEFACT)</title><link>https://blog.teraren.com/posts/un-cefact/</link><guid isPermaLink="true">https://blog.teraren.com/posts/un-cefact/</guid><description>Center for trade facilitation and e-business (UN/CEFACT)</description><pubDate>Wed, 14 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;Uploaded XML Schema file to github.
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/uncefact&quot;&gt;https://github.com/matsubo/uncefact&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Now, we can check difference between each version and file change history.&lt;/li&gt;
&lt;li&gt;TODO
&lt;ul&gt;
&lt;li&gt;Core Components Library (UN/CCL)
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.unece.org/cefact/codesfortrade/unccl/ccl_index.html&quot;&gt;http://www.unece.org/cefact/codesfortrade/unccl/ccl_index.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/08/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Face ID Is Not Available</title><link>https://blog.teraren.com/posts/face-id-is-not-available/</link><guid isPermaLink="true">https://blog.teraren.com/posts/face-id-is-not-available/</guid><description>Face ID Is Not Available</description><pubDate>Sun, 11 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;After 1 hour chat with Apple customer support, the iPhone XS was set to replace with a new phone.&lt;/p&gt;
&lt;p&gt;交換になりました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/08/EBM1do8U8AEkOYv.jpeg&quot; alt=&quot;Face ID Is Not Available&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Face ID Is Not Available&lt;/p&gt;
</content:encoded></item><item><title>中小企業共通EDI標準あたりをまとめてみる</title><link>https://blog.teraren.com/posts/edi/</link><guid isPermaLink="true">https://blog.teraren.com/posts/edi/</guid><description>政府の「未来投資戦略2018」を背景に、商流EDIと金融EDIの標準化動向や関連団体・規格をエンジニア視点で整理した解説記事</description><pubDate>Sat, 10 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;日経 xTECHが出版した「&lt;a href=&quot;https://tech.nikkeibp.co.jp/atcl/nxt/mag/nc/18/070300121/&quot;&gt;受発注革命&lt;/a&gt;」というタイトルの記事。B2Cの業界は古くからECが発展しているが、B2B受発注はアナログが多い。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;「未来投資戦略 2018 ―「&lt;strong&gt;Society 5.0&lt;/strong&gt;」「データ駆動型社会」への変革―」にて&lt;strong&gt;商流EDI&lt;/strong&gt;と&lt;strong&gt;金融EDI&lt;/strong&gt;について言及されている。EDIとはElectronic Data Interchangeの略。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;ⅲ）金・商流連携等に向けたインフラの整備&lt;br /&gt;
・本年 12 月の全銀 EDI システムの稼働、平成 32 年までの送金電文の全面的 XML 化を着実に実現するため、全国銀行協会、商工会議所等の金融界・産業界や関係省庁が連携し、周知活動や当該システムの活用事例の共有などの取組を推進する。&lt;br /&gt;
・企業間の受発注の電子化（商流 EDI）の共通化を引き続き推進するとともに、金融界・産業界・関係省庁が連携して、全銀 EDI システムを用いた送金情報と商流EDI の接続に係る実証実験を本年度中に実施するなど、金融 EDI と商流 EDI の連携を推進する。&lt;br /&gt;
・手形・小切手機能の電子化に向け、金融界・産業界・関係省庁が連携して議論を行っている「手形・小切手機能の電子化に関する検討会」において、諸課題の検討を進め、本年度中を目途に課題の整理を行う。&lt;br /&gt;
・納税・公金納付に関し、来年 10 月の地方税共通納税システム稼働に向けた準備を引き続き進めるとともに、金融機関、関係府省庁、地方自治体、FinTech 企業などの関係者が連携した「税・公金収納・支払の効率化等に関する勉強会」において、IT による利用者利便の向上・効率化に向けた課題等について、本年度中を目途に検討を進める。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www5.cao.go.jp/keizai-shimon/kaigi/minutes/2018/0615/shiryo_03-2.pdf&quot;&gt;未来投資戦略2018 PDF&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上に登場する、Society 5.0とは。「&lt;strong&gt;未来投資戦略2018年&lt;/strong&gt;」の中に登場している。（Society 4.0は探しても見つかりませんでした）&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;昨年末の「新しい経済政策パッケージ」（平成 29 年 12 月８日閣議決定）では、2020 年までの３年間を生産性革命・集中投資期間とし、大胆な税制、予算、規制改革などあらゆる施策を総動員することとした。「Society 5.0」の実現に向けて、最先端の取組を伸ばし、日本経済全体の生産性の底上げを図るため、様々な施策を講じることとした。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www5.cao.go.jp/keizai-shimon/kaigi/minutes/2018/0615/shiryo_03-2.pdf&quot;&gt;未来投資戦略2018 PDF&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;「&lt;strong&gt;新しい経済政策パッケージ&lt;/strong&gt;」とは。これが一番上流のコンセプト。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;生産性革命を実現し、人工知能、ロボット、ＩｏＴなど、生産性を劇的に押し上げるイノベーションを実現していく。人手不足に悩む中小・小規模事業者も含め、企業による設備や人材への投資を力強く促進する。あらゆる施策を総動員し、力強い賃金アップと投資を後押しすることで、デフレ脱却を確実なものとし、名目ＧＤＰ600 兆円の実現を目指す。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www5.cao.go.jp/keizai1/package/20171208_package.pdf&quot;&gt;https://www5.cao.go.jp/keizai1/package/20171208_package.pdf&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上記をまとめると、「&lt;strong&gt;商流EDIと金融EDIがあれば企業間の取引をXMLでやりとりできるので、日本全体の会社間商取引に関わる処理コストを減らせる。それにより余ったリソースを使って日本のGDPを上げる&lt;/strong&gt;。」&lt;/p&gt;
&lt;h3&gt;関連する団体&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;中小企業庁 (上部組織は経済産業省)が指揮
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.chusho.meti.go.jp/keiei/gijut/edi.htm&quot;&gt;https://www.chusho.meti.go.jp/keiei/gijut/edi.htm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;中小企業庁経営支援部技術・経営革新課（イノベーション課）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中小企業共通EDI標準&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;中小企業庁が「特定非営利活動法人ITコーディネータ協会」へ依頼。&lt;/li&gt;
&lt;li&gt;商流EDIの標準化&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itc.or.jp/datarenkei/&quot;&gt;https://www.itc.or.jp/datarenkei/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;会長。66歳（2019年時点）。&lt;a href=&quot;https://x.com/shibuyahiroyuki&quot;&gt;9年前のTweetが最後&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;Wikipedia: &lt;a href=&quot;https://ja.wikipedia.org/wiki/%E4%B8%AD%E5%B0%8F%E4%BC%81%E6%A5%AD%E5%85%B1%E9%80%9AEDI%E6%A8%99%E6%BA%96&quot;&gt;中小企業共通EDI標準&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;つなぐITコンソーシアム&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;特定非営利活動法人ITコーディネータ協会内の組織。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tsunagu-it.com/cons/member/&quot;&gt;入会方法&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;「入会申込書に記入・押印頂き、PDFにてメールでお送りください。」&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tsunagu-it.com/cons/&quot;&gt;https://tsunagu-it.com/cons/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;一般社団法人全国銀行協会
&lt;ul&gt;
&lt;li&gt;金融EDI(&lt;strong&gt;ZEDI&lt;/strong&gt;)の標準化&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.zenginkyo.or.jp/abstract/efforts/smooth/xml/&quot;&gt;https://www.zenginkyo.or.jp/abstract/efforts/smooth/xml/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;関連する仕様・プロトコル&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/08/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;United Nations Centre for Trade Facilitation and Electronic Business&lt;strong&gt;中小企業共通EDI標準&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;UN/CEFACT&lt;/strong&gt;を拡張して作っている。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;v1 (2018.3)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itc.or.jp/datarenkei/j_edi/firstedition.html&quot;&gt;https://www.itc.or.jp/datarenkei/j_edi/firstedition.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;注文のプロトコルのみを定義した様子。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;v2 (2019.6.3)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itc.or.jp/datarenkei/edi_ver2.html&quot;&gt;https://www.itc.or.jp/datarenkei/edi_ver2.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;標準企業コード&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;これが使われるのか謎だけど。発行は有料。国レベルで連携出来ているのかもよくわからないが。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cii-kcode.jipdec.or.jp/code_list.html&quot;&gt;https://cii-kcode.jipdec.or.jp/code_list.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;EDIFACT (UN/EDIFACT)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;EDIFACT は、商業部門および非商業部門での EDI 取引の国際標準
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ibm.com/support/knowledgecenter/ja/SSMKHH_10.0.0/com.ibm.etools.mft.doc/ad09560_.htm&quot;&gt;https://www.ibm.com/support/knowledgecenter/ja/SSMKHH_10.0.0/com.ibm.etools.mft.doc/ad09560_.htm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;国際EDI標準
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.fujitsu.com/downloads/JP/archive/imgjp/jmag/vol49-4/paper10.pdf&quot;&gt;https://www.fujitsu.com/downloads/JP/archive/imgjp/jmag/vol49-4/paper10.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;UN/EDIFACT = The United Nations rules for Elec­tronic Data Interchange for Administration, Commerce and Transport&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CEFACT (UN/CEFACT)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;XML Schema
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.unece.org/cefact/xml_schemas/index&quot;&gt;https://www.unece.org/cefact/xml_schemas/index&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;XML schemaのリリース毎にtagを打ってあるので差分を追える。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/uncefact&quot;&gt;https://github.com/matsubo/uncefact&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Core Component
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.unece.org/cefact/codesfortrade/unccl/ccl_index.html&quot;&gt;http://www.unece.org/cefact/codesfortrade/unccl/ccl_index.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;日本語解説
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.caos-a.co.jp/SIPS/dictionary/dictionary_download.html&quot;&gt;http://www.caos-a.co.jp/SIPS/dictionary/dictionary_download.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CEFACT入門
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jastpro.org/files/libs/1422//20220613104534295.pdf&quot;&gt;CEFACT入門 PDF&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;UN/CEFACT = United Nations Centre for Trade Facilitation and Electronic Business&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/08/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;注文メッセージの概念モデル&lt;/p&gt;
&lt;h3&gt;プロトコルの所感&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ビジネスレイヤの分析はしっかりしているので参考になる
&lt;ul&gt;
&lt;li&gt;ユースケースやシーケンスはちゃんと整理できていて納得感がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;設計、実装レイヤは緩いので怪しい
&lt;ul&gt;
&lt;li&gt;DTDが無いし、スキーマの仕様書がExcelで書かれており、仕様として不十分な印象。&lt;/li&gt;
&lt;li&gt;これだけで良く実装できるなぁと思う。実際に運用し出すと問題多発しそうな緩い定義。XML Schemaが無いからメッセージの検証も出来ないし、大丈夫なのかと不安になる。&lt;/li&gt;
&lt;li&gt;通信プロトコルが明示されていないのはわざとなのか。まぁいいけど。&lt;/li&gt;
&lt;li&gt;文字数やフォーマットといった細かいことは&lt;a href=&quot;https://www.itc.or.jp/datarenkei/dlfiles/edi/3EDIv1.pdf&quot;&gt;受け手側依存&lt;/a&gt;と書かれている。プロトコルなのに。&lt;/li&gt;
&lt;li&gt;こんなにPDFの長々としたドキュメントじゃなくて、xsdファイルをgithubに上げるだけで終わるのに。この辺はお役所感出てる。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.unece.org/cefact/xml_schemas/index&quot;&gt;本家はxsdがしっかり定義されている。&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;中小企業共通 EDI 実装ガイドライン V2.0_draft_r10
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itc.or.jp/datarenkei/dlfiles/edi/EDI_deploy_guideline_v2.0_draft_r10.pdf&quot;&gt;https://www.itc.or.jp/datarenkei/dlfiles/edi/EDI_deploy_guideline_v2.0_draft_r10.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;この資料を見ると悲しくなります。具体的すぎる実装内容、しかもWindows端末がグローバルに出ている前提で作られている。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/08/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;謎な要件。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/08/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;謎な要件が盛りだくさん&lt;/p&gt;
&lt;h2&gt;共通EDI実装&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;EC Orange&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://ec-orange.jp/&quot;&gt;https://ec-orange.jp&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;パッケージ。売り切り。&lt;a href=&quot;https://ec-orange.jp/product/price.html&quot;&gt;1,000万円～&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;中小企業共通EDIに対応しているらしいが、具体性は不明。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;取引先のデータを同一形式（自社用）のCSV、Excel、またはXMLとして扱うことができます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;EcoChange&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ecochange.jp/ja/about.html&quot;&gt;https://www.ecochange.jp/ja/about.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;初期 167.7万円〜、運用4,500円/月&lt;/li&gt;
&lt;li&gt;「取引先のデータを同一形式（自社用）のCSV、Excel、またはXMLとして扱うことができます。」と書いてあるので、共通EDIに標準で対応しているのかちょっと怪しい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;インフォマートのBtoB受発注&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infomart.co.jp/asp/index.asp&quot;&gt;https://www.infomart.co.jp/asp/index.asp&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;初期 40万円〜、月額31,800円〜&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;花王の事例
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://tech.nikkeibp.co.jp/atcl/nxt/column/18/00784/052700001/&quot;&gt;https://tech.nikkeibp.co.jp/atcl/nxt/column/18/00784/052700001/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;インフォマートのBtoB受発注を使っている様子。&lt;/li&gt;
&lt;li&gt;タイミングと機能から察するに、中小企業共通EDI標準 v1。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;EDiFAS&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://xeex-products.jp/extelligence/&quot;&gt;https://xeex-products.jp/extelligence/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ACMS&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.dal.co.jp/acms/protocol/index.html&quot;&gt;https://www.dal.co.jp/acms/protocol/index.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ZEDI実装&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;2018/12/25 AM8:00 JSTからZEDIが稼働しだした。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;銀行全体の65%にあたる91行の銀行と、信用金庫業態（信金中央金庫と229の信用金庫）の合計321金融機関が、サービス提供開始当初から参加。&lt;/li&gt;
&lt;li&gt;2019年8月5日時点で、320金融機関。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;例: みずほ銀行&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mizuhobank.co.jp/corporate/oshirase/zedi181225.html&quot;&gt;https://www.mizuhobank.co.jp/corporate/oshirase/zedi181225.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;利用量：初期10万円、月額5万円。50円/件。（税抜き）&lt;/li&gt;
&lt;li&gt;明細部分がXMLでなかったりするのでよくわからない。&lt;/li&gt;
&lt;li&gt;中小企業がターゲットのはずなのに高額。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Vol.70 企業間のデータ連携で、受発注の業務コストを削減する！｜
&lt;ul&gt;
&lt;li&gt;https://www.mirasapo.jp/features/policy/vol70/ （サイト閉鎖）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;「つながらないEDI」をつなぐ、共通EDIの破壊力
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://tech.nikkeibp.co.jp/atcl/nxt/column/18/00784/052700002/&quot;&gt;https://tech.nikkeibp.co.jp/atcl/nxt/column/18/00784/052700002/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;「IT導入補助金」「ものづくり補助金」活用で次世代EDIを導入することのメリット
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tokyo-cci-ict.com/column/201902-02/&quot;&gt;https://www.tokyo-cci-ict.com/column/201902-02/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;関連用語&lt;/h2&gt;
&lt;p&gt;所感：業界自体、基本となる用語の定義が曖昧なので、言葉の定義や使われ方も曖昧。。。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Web-EDI
&lt;ul&gt;
&lt;li&gt;定義がよくわからないですが、Webの画面からEDI用のXMLファイルを入れたり出したりする機能のことを指している様子。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;インターネットEDI
&lt;ul&gt;
&lt;li&gt;かつてのISDNによる専用線接続に対して使われている用語。&lt;/li&gt;
&lt;li&gt;要は、ISDN以外による通信のことを指している様子。インターネットVPN、プライベートVPN、LAN。TCP/IPによる伝送あたりをなんとなく指していそう。&lt;/li&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;メールEDI&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;EDI用のXMLファイルをメールで添付して送ることを指しているらしい。&lt;/li&gt;
&lt;li&gt;登場する前に滅びて欲しい感はある。
{/* textlint-disable ja-technical-writing/ja-no-successive-word */}
&lt;ul&gt;
&lt;li&gt;よくよく考えてみると、手元にコピーは残るし、検索はしやすい。伝送方法にSMTPを用いるのはメリットだと思ったしかし、以下のデメリットが大きすぎる。
{/* textlint-enable */}&lt;/li&gt;
&lt;li&gt;リアルタイム性は失われるし、送信側と受信側のどちらの責任になるのかがあやふやになる。インターネット上でロストする場合がある。在庫管理に絡んできたときに、排他制御が無理。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;サンプル&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;たくさんEDIについて話されているけど、中小企業共通EDI標準のXMLで作られたサンプルファイルはどこにあるの・・・？&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Ethereum動かしてみた</title><link>https://blog.teraren.com/posts/ethereum-survey/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ethereum-survey/</guid><description>gethを使ってEthereumのプライベートネットワークをローカルで構築し、アカウント作成やマイニング、送金などの基本操作を試したハンズオン記録です。</description><pubDate>Sat, 10 Aug 2019 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;ソースコード
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/eth_private_net&quot;&gt;https://github.com/matsubo/eth_private_net&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Ethereum survey&lt;/h2&gt;
&lt;h3&gt;setup&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% brew install ethereum
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Run daemon&lt;/h3&gt;
&lt;p&gt;setup private network.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% geth --datadir . init myGenesis.json
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Run CLI&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% geth --datadir &quot;.&quot; attach ipc:geth.ipc
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; eth.accounts
[]
&amp;gt; personal.newAccount(&quot;hogehoge01&quot;)
&quot;0x6d3341d8a5314a084a097091c4a0d6d792cbca56&quot;
&amp;gt; eth.accounts
[&quot;0x6d3341d8a5314a084a097091c4a0d6d792cbca56&quot;]
&amp;gt; personal.newAccount(&quot;hogehoge02&quot;)
&quot;0xb3bae63ea54f3dfaf26ea08bc3862e1eef55c01c&quot;
&amp;gt; eth.accounts
[&quot;0x6d3341d8a5314a084a097091c4a0d6d792cbca56&quot;, &quot;0xb3bae63ea54f3dfaf26ea08bc3862e1eef55c01c&quot;]
&amp;gt;
&amp;gt; eth.coinbase
&quot;0x6d3341d8a5314a084a097091c4a0d6d792cbca56&quot;
&amp;gt; miner.setEtherbase(eth.accounts[1])
true
&amp;gt; eth.coinbase
&quot;0xb3bae63ea54f3dfaf26ea08bc3862e1eef55c01c&quot;
&amp;gt; miner.start()
null
&amp;gt; miner.stop()
null
&amp;gt; eth.blockNumber
0
&amp;gt; miner.start()
null
&amp;gt; eth.mining
true
&amp;gt; eth.hashrate
0
&amp;gt; eth.hashrate
11774
&amp;gt; eth.hashrate
11774
&amp;gt; eth.hashrate
22131
&amp;gt; miner.stop()
null
&amp;gt; eth.blockNumber
24
&amp;gt; eth.getBlock(1)
{
  difficulty: 131072,
  extraData: &quot;0xd983010901846765746888676f312e31322e378664617277696e&quot;,
  gasLimit: 134086657,
  gasUsed: 0,
  hash: &quot;0x4529f0f308d01294b5e65a118d3ad92541e005798a6473c1746e89b4317c2d20&quot;,
  logsBloom: &quot;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&quot;,
  miner: &quot;0xb3bae63ea54f3dfaf26ea08bc3862e1eef55c01c&quot;,
  mixHash: &quot;0xb3e9d16d11d790086db82c3c9590ff9bee6308784de11efd09f5e9bf4157f788&quot;,
  nonce: &quot;0x29bc0504ee137827&quot;,
  number: 1,
  parentHash: &quot;0x7b2e8be699df0d329cc74a99271ff7720e2875cd2c4dd0b419ec60d1fe7e0432&quot;,
  receiptsRoot: &quot;0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421&quot;,
  sha3Uncles: &quot;0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347&quot;,
  size: 538,
  stateRoot: &quot;0x09882d0e65b4a5af352b1823add77b36086b955c31fcfd9de8b30e160375deb8&quot;,
  timestamp: 1565088821,
  totalDifficulty: 147456,
  transactions: [],
  transactionsRoot: &quot;0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421&quot;,
  uncles: []
}
&amp;gt; eth.getBlock(2)
{
  difficulty: 131072,
  extraData: &quot;0xd983010901846765746888676f312e31322e378664617277696e&quot;,
  gasLimit: 133955714,
  gasUsed: 0,
  hash: &quot;0x926777bc57d6bccd4c35cf48e902f7c82c6eddab994823289a0f0d6489d3cf27&quot;,
  logsBloom: &quot;0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&quot;,
  miner: &quot;0xb3bae63ea54f3dfaf26ea08bc3862e1eef55c01c&quot;,
  mixHash: &quot;0x83a9aaee23fe2ca84c98a955ba5a1d83751e3553cb418ed72476d0fced969f1e&quot;,
  nonce: &quot;0x316150b329a6230f&quot;,
  number: 2,
  parentHash: &quot;0x4529f0f308d01294b5e65a118d3ad92541e005798a6473c1746e89b4317c2d20&quot;,
  receiptsRoot: &quot;0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421&quot;,
  sha3Uncles: &quot;0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347&quot;,
  size: 538,
  stateRoot: &quot;0x879c5e58e60028f7cd9a019efb8622a668f28386d9098cf7eb194e67b1e174a5&quot;,
  timestamp: 1565088849,
  totalDifficulty: 278528,
  transactions: [],
  transactionsRoot: &quot;0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421&quot;,
  uncles: []
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;check balance&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; eth.coinbase == eth.accounts[1]
true
&amp;gt; eth.getBalance(eth.accounts[1])
815000000000000000000
&amp;gt; web3.fromWei(eth.getBalance(eth.accounts[1]),&quot;ether&quot;)
1140
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;transfer amount&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; personal.unlockAccount(eth.accounts[0])
Unlock account 0x6d3341d8a5314a084a097091c4a0d6d792cbca56
Passphrase:
true
&amp;gt; eth.getBalance(eth.accounts[1])
2.86e+21
&amp;gt; personal.unlockAccount(eth.accounts[1])
Unlock account 0xb3bae63ea54f3dfaf26ea08bc3862e1eef55c01c
Passphrase:
true
&amp;gt; eth.sendTransaction({from: eth.accounts[1], to: eth.accounts[0], value: web3.toWei(5, &quot;ether&quot;)})
&quot;0x9e25f0f6d2e85b7a8045730c65af2b93b3a0ae3fbd3c14fc7db0abda4a0d44fb&quot;
&amp;gt; eth.getBalance(eth.accounts[0])
0
&amp;gt; eth.getBalance(eth.accounts[1])
6.345e+21
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;amount cannot be transfered...
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://book.ethereum-jp.net/first_use/sending_ether.html&quot;&gt;https://book.ethereum-jp.net/first_use/sending_ether.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>iOSで使えるsshターミナル</title><link>https://blog.teraren.com/posts/ios-terminal/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ios-terminal/</guid><description>iOSで使えるsshターミナル</description><pubDate>Tue, 30 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://itunes.apple.com/us/app/termius-ssh-client/id549039908?mt=8&quot;&gt;Terminus&lt;/a&gt; が一番よさげ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公開鍵認証で、SSHログインして、htopをしてみた結果がこちら。なかなかよい。（お値段以外）&lt;/li&gt;
&lt;li&gt;使い方マニュアルは、すごく長くて覚えるのが大変そうでしたが、適当に読み飛ばしてOKです。直感的に利用出来るので問題無いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/IMG_4253.png&quot; alt=&quot;terminus&quot; /&gt;&lt;/p&gt;
&lt;p&gt;利用料はサブスクリプションになっていて、ちょっとお高いです。iOSから緊急対応することが多い場合は必要かなーと。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>X-RoadにBlockchainは使われていない</title><link>https://blog.teraren.com/posts/x-road-does-not-use-blockchain/</link><guid isPermaLink="true">https://blog.teraren.com/posts/x-road-does-not-use-blockchain/</guid><description>X-RoadにBlockchainは使われていない</description><pubDate>Tue, 16 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Source 1&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.niis.org/blog/2018/4/26/there-is-no-blockchain-technology-in-the-x-road&quot;&gt;https://www.niis.org/blog/2018/4/26/there-is-no-blockchain-technology-in-the-x-road&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.niis.org/blog?author=5a5375ad6f935e0cce16c1ed&quot;&gt;Petteri Kivimäki&lt;/a&gt;  &lt;a href=&quot;https://www.niis.org/blog/2018/4/26/there-is-no-blockchain-technology-in-the-x-road&quot;&gt;April 26, 2018&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Source 2&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://e-estonia.com/why-x-road-is-not-blockchain/&quot;&gt;https://e-estonia.com/why-x-road-is-not-blockchain/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;e-Estonia&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>自宅もIPv6対応 (GMO BB フレッツ光 固定IP）</title><link>https://blog.teraren.com/posts/home-ipv6-gmo-bb/</link><guid isPermaLink="true">https://blog.teraren.com/posts/home-ipv6-gmo-bb/</guid><description>自宅もIPv6対応 (GMO BB フレッツ光 固定IP）</description><pubDate>Mon, 15 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;GMO BBの固定IPサービス「フレッツ光マンション 1IP接続サービス」（月額1,100円）を使っているのですが、なんかIPv6でも接続出来るようになったみたいです。&lt;/p&gt;
&lt;p&gt;テストに使ったのはこちらのサイト：&lt;a href=&quot;https://test-ipv6.com/&quot;&gt;https://test-ipv6.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ルーターはRTX1200に&lt;a href=&quot;https://network.yamaha.com/setting/router_firewall/ipv6/v6plus&quot;&gt;IPv6の設定&lt;/a&gt;を入れてます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/Pasted_Image_2019_07_11_23_18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gmobb.jp/lp/flets_v6plus/&quot;&gt;こちらのページ&lt;/a&gt;には固定IPとIPv6は併用できないと書かれているのですができちゃってます。&lt;/p&gt;
</content:encoded></item><item><title>MTX ConnectのeSIMをヨーロッパで使ってみました</title><link>https://blog.teraren.com/posts/mtx-connect-esim/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mtx-connect-esim/</guid><description>スロベニア・クロアチア・ハンガリー旅行でMTX ConnectのeSIMを使い、登録手順・料金・テザリング可否・現地での使用感をレポート</description><pubDate>Fri, 05 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ヨーロッパ（スロベニア、クロアチア、ハンガリー）へ旅行に行ったので、&lt;a href=&quot;/posts/3hongkong-esim/&quot;&gt;前回の香港でのeSIMの利用&lt;/a&gt;に引き続き、eSIMを使ってみました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;eSIMを自分のiPhoneに登録するだけなら無料で登録できる&lt;/strong&gt;ので、試したい方にはもってこいです。&lt;/li&gt;
&lt;li&gt;旅行中、eSIMが使えなかったら困るのでレンタルWiFiも持参です。（最近のはでかい電池内蔵なので重くて辛い）&lt;/li&gt;
&lt;li&gt;トランジットで寄ったカタールでは使えませんでした。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;MTX Connect&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;前回もそうでしたが、&lt;strong&gt;eSIMの登録にはQRコードで登録&lt;/strong&gt;する仕様だったので、事前にPCがある環境で購入しておきます。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://esimdb.com/ja/region/europe&quot;&gt;eSIMdb&lt;/a&gt;という、行き先ごとにキャリアの料金プランを整理してくれているサイトを見つけて、&lt;a href=&quot;https://www.mtxc.eu/en/&quot;&gt;MTX Connect&lt;/a&gt;が要望にフィットしそうなので選びました。ウェブを軽く見ていたらアプリもあるし、ウェブサイトのデザインもまともそうだったから他社を見ずに即決しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ウェブからユーザ登録、eSIMの購入を済ませませて、携帯にeSIMとして登録しました。&lt;/li&gt;
&lt;li&gt;この時点ではeSIMの残高はゼロなので、wechatなどのいくつかのアプリとSMSしか使えないと書いてありました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/Pasted_Image_2019_07_04_10_12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アクティベートするためには、公的機関が発行した身分証明書と、その身分証明書と自撮りした写真をアップロードする必要が有りました。おそらく日本語は読めないだろうけど、運転免許証をアップロードしたら問題無く使えたようです。（おそらく無審査。すぐに使えたので）&lt;/li&gt;
&lt;li&gt;次に、&lt;a href=&quot;https://apps.apple.com/us/app/mtx-connect-is-european-mobile-internet-carrier/id1189100693&quot;&gt;iOSアプリ&lt;/a&gt;をインストールしました。&lt;/li&gt;
&lt;li&gt;APNのインストールはアプリからクリックすればAPNインストール用のURLに飛ぶのでインストールがすぐに出来ました。&lt;/li&gt;
&lt;li&gt;eSIMにチャージするには、まずmtx connectのウォレットにチャージする必要が有ります。細かい金額でチャージできなくて、たしか、5ポンドごとある程度のキリ番でしかチャージできないという不親切な仕様です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;24.95ポンドのプランを使いたかったので、それを買える分である20ポンドをチャージ。7ポンドは元から付与されていた。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/UNADJUSTEDNONRAW_thumb_591c.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;aa&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/UNADJUSTEDNONRAW_thumb_5915.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アプリの見た目は以下のような感じです。&lt;/li&gt;
&lt;li&gt;ほぼリアルタイムで使用量が反映されていました。利用した国や購入履歴が時系列で表示されてすごい見やすいです。&lt;/li&gt;
&lt;li&gt;非常にUIの参考になります。&lt;/li&gt;
&lt;li&gt;MTX ConnectのeSIMでは&lt;strong&gt;テザリングは出来ません&lt;/strong&gt;でした。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/UNADJUSTEDNONRAW_thumb_5ab0.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/UNADJUSTEDNONRAW_thumb_5ab1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/UNADJUSTEDNONRAW_thumb_5ab2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;MTX ConnectのeSIMを日本で使ってみた&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;日本でもローミングで使えます。&lt;/li&gt;
&lt;li&gt;速度は24Mbpsでてました。ISPは香港にあるMTX Connectのようです。&lt;/li&gt;
&lt;li&gt;希に接続不可能になります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/IMG_4699.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/IMG_4700.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;海外旅行時のポータブルWiFi運用のコツ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;iOSの場合はWiFiに接続時（デフォルト設定）は、iCloudが裏で写真や動画をクラウドにアップロードすることで、かなりの容量を食ってしまう。また、様々なバックアップが裏で動いているので容量を勝手に消費してしまいます。&lt;/li&gt;
&lt;li&gt;それを防ぐためにはiCloudをオフにすることで回避出来ますが、同期が切れることでデータが消えたりしてしまいます。（私は過去に2年分の写真が消えました）&lt;/li&gt;
&lt;li&gt;WebやポータブルWiFiの業者が書いてるマニュアルには設定で色々変更するように書かれていますが、1個の設定で全てを出来る事がわかりました。&lt;/li&gt;
&lt;li&gt;それは「&lt;strong&gt;低電力モード&lt;/strong&gt;」にするだけ！そうすると、iCloudの同期が止まります。&lt;/li&gt;
&lt;li&gt;欠点が1つあって、デバイスを充電しだして、残り容量が80％を越えたら低電力モードが勝手に解除されてしまいます。なので、毎回低電力モードにする必要があります。&lt;/li&gt;
&lt;li&gt;充電をする際にはホテルで充電するのでホテルに帰ったらポータブルWiFiはオフにするような運用をするのが良いと思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;旅行中、重いポータブルWiFiを持って行かなくて良いのはかなり楽。&lt;/li&gt;
&lt;li&gt;旅行中は移動が多いので、荷物が多くなるのは予想以上に辛いものです。&lt;/li&gt;
&lt;li&gt;ポータブルWiFiのレンタル受け取り、返却といった面倒な手続きが無くなる。金額はあまり変わらない。&lt;/li&gt;
&lt;li&gt;複数人で旅行に行く場合で、WiFiを共有する場合は各々でeSIMを契約するよりかは、ポータブルWiFiのほうが安いかな。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>SQLにおけるBETWEENの境界とカラムの小数精度に注意</title><link>https://blog.teraren.com/posts/sql-between-boundary/</link><guid isPermaLink="true">https://blog.teraren.com/posts/sql-between-boundary/</guid><description>SQLのBETWEEN句は両端の値を含む仕様と、DATETIMEカラムの小数秒精度を考慮しないと期待と異なる結果になる落とし穴を実行例で詳しく解説します。</description><pubDate>Tue, 02 Jul 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;BETWEEN句を使うときには&lt;strong&gt;境界&lt;/strong&gt;と&lt;strong&gt;精度&lt;/strong&gt;に気をつける必要がある。これを知らないで書くと要件と違う結果が返される場合がある。&lt;/p&gt;
&lt;h2&gt;BETWEEN句の境界&lt;/h2&gt;
&lt;h3&gt;仕様&lt;/h3&gt;
&lt;p&gt;BETWEENの境界値は指定した&lt;strong&gt;2つの項を含む&lt;/strong&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[column] BETWEEN [x] AND [y]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上のクエリーは&lt;strong&gt;以下と同等&lt;/strong&gt;です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[x] &amp;lt;= [column] AND [column] &amp;lt;= [y]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;境界値を含めたくない場合はbetweenを使えないので、それぞれの項の条件を指定する必要がある。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[x] &amp;lt; [column] AND [column] &amp;lt;= [y]
or
[x] &amp;lt;= [column] AND [column] &amp;lt; [y]
or
[x] &amp;lt; [column] AND [column] &amp;lt; [y]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかしながら、カラムの精度を考えないと正しいSQL（プログラム）を書けない問題がある。&lt;/p&gt;
&lt;h3&gt;BETWEENを使った悪い例&lt;/h3&gt;
&lt;p&gt;時間を区切った集計でBETWEEN句を使っている場合は、間違ったコードを書いている可能性がある。&lt;/p&gt;
&lt;p&gt;間違った例を挙げる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BETWEEN A AND B
BETWEEN B AND C
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この場合ですと、Bの期間が1行目と2行目に含まれてしまいます。正しくは以下のようなコードになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BETWEEN A AND (B - 最小単位)
BETWEEN B AND (C - 最小単位)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;具体的な正しいコードは以下です。（仮定: カラムの精度が秒の場合。この仮定の理由は後述。）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;BETWEEN &apos;2022-01-01 00:00:00&apos; AND &apos;2022-01-01 23:59:59&apos;
BETWEEN &apos;2022-01-02 00:00:00&apos; AND &apos;2022-01-02 23:59:59&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;精度&lt;/h2&gt;
&lt;h3&gt;カラムの精度によって結果が変わってしまう書き方&lt;/h3&gt;
&lt;p&gt;datetimeのカラムに小数点が無い前提では以下は等価です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[column] between &apos;2020-01-01 00:00:00&apos; and &apos;2020-01-01 23:59:59&apos;
=
&apos;2020-01-01 00:00:00&apos; &amp;lt;= [column] and [column] &amp;lt;= &apos;2020-01-01 23:59:59&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;datetimeには小数を持つことができるので、もしdatetimeカラムに小数の精度で値が保存されている場合は等価ではなくなります。&lt;/p&gt;
&lt;p&gt;例えば、最初のデータベースの実装では精度が秒までだったのに、途中から小数第2位まで持つようになるケースがありえます。&lt;/p&gt;
&lt;p&gt;上記のようなコードを書いた場合はカラムの精度によってビジネス要件と異なる結果が返されます。プログラマーはカラムの精度に関係なく意図したとおりに動くコードを書くべきです。精度が秒の前提で書かれたコードは、将来の精度変更でバグになるリスクがあります。&lt;/p&gt;
&lt;p&gt;ストレージやストレージの型に対してできるだけ依存性のないコードを書くのが理想です。&lt;/p&gt;
&lt;p&gt;MySQLではDATETIME型は物理スキーマでは秒を小数点6桁まで保持できます。カラムを作成する際に精度を省略すれば秒単位で作成されます。&lt;/p&gt;
&lt;p&gt;もし、小数6桁まで保存するオプションによってカラムが作られている場合は以下のようなデータが保存されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2019-01-31 23:59:59.000000&lt;/li&gt;
&lt;li&gt;2019-01-31 23:59:59.000001&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上記のようなデータが入ることから、プログラマは物理スキーマに依存した特定の精度で動くコードを書くか、物理スキーマの精度に依存しないクエリーを書く必要があります。&lt;/p&gt;
&lt;h3&gt;精度を考慮していないで書いたSQLの例&lt;/h3&gt;
&lt;p&gt;例えば、月の集計をしたいから以下のようなクエリーを書くケースがあると思います。カラムの精度が秒ならば問題なく動きます。カラムの精度が小数点の場合には集計漏れが発生します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[column] BETWEEN &apos;2019-01-01 00:00:00&apos; AND &apos;2019-01-31 23:59:59&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例えば、以下のように、&quot;2019-01-31 23:59:59.x&quot; のデータが入っていても集計対象には入りません。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* NOT THE BEST CODE EXAMPLE */
&amp;gt;  select &apos;2019-01-31 23:59:59.1&apos; between  &apos;2019-01-01 00:00:00&apos; and &apos;2019-01-31 23:59:59&apos; ;
+-----------------------------------------------------------------------------------+
| &apos;2019-01-31 23:59:59.1&apos; between  &apos;2019-01-01 00:00:00&apos; and  &apos;2019-01-31 23:59:59&apos; |
+-----------------------------------------------------------------------------------+
|                                                                                 0 |
+-----------------------------------------------------------------------------------+
1 row in set (0.004 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;よって、精度が小数点の場合は以下のように書く必要があります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* THE BEST CODE EXAMPLE */
&amp;gt; set @columnA=&apos;2019-02-01 00:00:00&apos;;
Query OK, 0 rows affected (0.002 sec)

&amp;gt; select &apos;2019-01-01 00:00:00&apos; &amp;lt;= @columnA AND @columnA &amp;lt; &apos;2019-02-01 00:00:00&apos;;
+-------------------------------------------------------------------------+
| &apos;2019-01-01 00:00:00&apos; &amp;lt;= @columnA AND @columnA &amp;lt; &apos;2019-02-01 00:00:00&apos;  |
+-------------------------------------------------------------------------+
|                                                                       0 |
+-------------------------------------------------------------------------+
1 row in set (0.007 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;betweenをどうしても使いたいのであれば、以下のように書く必要があります。しかし、これも小数点の精度が最大6桁という前提で書かれているのでMySQL以外のRDBMS、例えばOracleだと9桁まで保存できるのでストレージ依存のコードになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/* NOT THE BEST CODE EXAMPLE */
root@&amp;gt; select &apos;2019-01-31 23:59:59.1&apos; between  &apos;2019-01-01 00:00:00&apos; and &apos;2019-01-31 23:59:59.999999&apos; as result;
+--------+
| result |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下に関連するMySQLのマニュアルを引用しておきます。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;DATETIME[(fsp)]&lt;/code&gt;
日付と時間の組み合わせです。サポートしている範囲は &lt;code&gt;&apos;1000-01-01 00:00:00.000000&apos;&lt;/code&gt; から &lt;code&gt;&apos;9999-12-31 23:59:59.999999&apos;&lt;/code&gt; です。小数秒の精度を指定するために 0 から 6 の範囲でオプションの &lt;code&gt;fsp&lt;/code&gt; 値を指定できます。0 の値は、小数部がないことを表します。省略した場合、デフォルトの精度は 0 です。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/datetime.html&quot;&gt;https://dev.mysql.com/doc/refman/8.0/en/datetime.html&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;MySQLにおける&lt;code&gt;datetime&lt;/code&gt;はオプションによって秒より高い精度で保存されている可能性があるので、このクエリーでは意図しない結果が返ってくる可能性があります。&lt;/p&gt;
&lt;h3&gt;日付と時間の指定の注意&lt;/h3&gt;
&lt;p&gt;上記の理由から「betweenの2つ目の項は含む」とだけ覚えると、以下のようなケースで問題が起きます。&lt;/p&gt;
&lt;p&gt;2つ目の後に、2019年1月31日を指定して含まれるならば同日の何時でも良さそうと考えられますが、実際には&apos;2019-01-31&apos;は00:00:00と扱われるようです。&lt;/p&gt;
&lt;p&gt;精度の違うカラムの比較は注意しましょう。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select cast(&apos;2019-01-31 00:00:00&apos; as datetime) BETWEEN &apos;2019-01-01&apos; AND &apos;2019-01-31&apos;;
+-------------------------------------------------------------------------------+
| cast(&apos;2019-01-31 00:00:00&apos; as datetime) BETWEEN &apos;2019-01-01&apos; AND &apos;2019-01-31&apos; |
+-------------------------------------------------------------------------------+
|                                                                             1 |
+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select cast(&apos;2019-01-31 00:00:01&apos; as datetime) BETWEEN &apos;2019-01-01&apos; AND &apos;2019-01-31&apos;;
+-------------------------------------------------------------------------------+
| cast(&apos;2019-01-31 00:00:01&apos; as datetime) BETWEEN &apos;2019-01-01&apos; AND &apos;2019-01-31&apos; |
+-------------------------------------------------------------------------------+
|                                                                             0 |
+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同じ型のチェックであれば普通に含まれるので大丈夫です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select cast(&apos;2019-01-31&apos; as date) BETWEEN &apos;2019-01-01&apos; AND &apos;2019-01-31&apos;;
+------------------------------------------------------------------+
| cast(&apos;2019-01-31&apos; as date) BETWEEN &apos;2019-01-01&apos; AND &apos;2019-01-31&apos; |
+------------------------------------------------------------------+
|                                                                1 |
+------------------------------------------------------------------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記により、datetimeのカラムに対してbetweenを使っての集計は困難かと思います。&lt;/p&gt;
&lt;p&gt;betweenを使うならば、カラムの精度の要件（実装の前段階）が決まった状態でないと正しいかどうか判断できなくてコードレベルでは判定できません。&lt;/p&gt;
&lt;p&gt;コードレベルで判定するためには、betweenの利用は避けて書く必要があります。&lt;/p&gt;
&lt;h2&gt;怪しいコード、問題のあるコードの見つけ方&lt;/h2&gt;
&lt;h3&gt;コードレビューで見つける&lt;/h3&gt;
&lt;p&gt;このページに有る境界と精度についてちゃんと理解した上で人間がチェックすることです。&lt;/p&gt;
&lt;p&gt;実装が意図通りかどうかは最終的にはビジネスロジックの要件によるので人間が判断する必要があります。&lt;/p&gt;
&lt;h3&gt;CIで見つける&lt;/h3&gt;
&lt;p&gt;コードレビューの時に見逃しそうで怖いので、ある程度はユニットテストで担保するのが良さそうです。&lt;/p&gt;
&lt;p&gt;世の中の人はどうしているのか気になって「mysql between 23:59:59」でググってみたら、大量の怪しい記述が出てきました。BETWEEN句と23:59:59を組み合わせて使っている場合、境界値がおそらく誤って扱われています。&lt;/p&gt;
&lt;p&gt;言い換えると、プログラムのソースコードを全文検索して、23:59:59という表記があったら要注意です。&lt;/p&gt;
&lt;h3&gt;集計の悪い例&lt;/h3&gt;
&lt;p&gt;集計用のプログラムを書く際に、betweenを使って値の部分を変数にして書くと、以下のようなコードが実行されることになりますが、これは重複した範囲を集計することになるので間違いです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;between A and B
between B and C
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;BETWEEN句を使って重複してカウントされる例&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;root@&amp;gt; select &apos;2019-01-02 00:00:00&apos; between &apos;2019-01-01 00:00:00&apos; and &apos;2019-01-02 00:00:00&apos; as result;
+--------+
| result |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)

root@&amp;gt; select &apos;2019-01-02 00:00:00&apos; between &apos;2019-01-02 00:00:00&apos; and &apos;2019-01-03 00:00:00&apos; as result;
+--------+
| result |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;境界値として23:59:59を使うと逆に含まれない例&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;root@&amp;gt; select &apos;2019-01-01 23:59:59.1&apos; between &apos;2019-01-01 00:00:00&apos; and &apos;2019-01-01 23:59:59&apos; as result;
+--------+
| result |
+--------+
|      0 |
+--------+
1 row in set (0.00 sec)

root@&amp;gt; select &apos;2019-01-01 23:59:59.1&apos; between &apos;2019-01-02 00:00:00&apos; and &apos;2019-01-02 23:59:59&apos; as result;
+--------+
| result |
+--------+
|      0 |
+--------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;精度を考慮して、betweenを集計で使う場合の正しい例&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@&amp;gt; select &apos;2019-01-01 23:59:59.1&apos; between &apos;2019-01-01 00:00:00&apos; and &apos;2019-01-01 23:59:59.999999&apos; as result;
+--------+
| result |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)

root@&amp;gt; select &apos;2019-01-01 23:59:59.1&apos; between &apos;2019-01-02 00:00:00&apos; and &apos;2019-01-02 23:59:59.999999&apos; as result;
+--------+
| result |
+--------+
|      0 |
+--------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;こう考えると、between句の使い所って無い気がします。&lt;/p&gt;
&lt;p&gt;正しくは以下のようなコードを書く必要があります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;A &amp;lt;= column and column &amp;lt; B
B &amp;lt;= column and column &amp;lt; C
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;境界値の表現方法と、カラムの精度をちゃんと理解して実装する必要がある。&lt;/li&gt;
&lt;li&gt;datetimeのカラムの精度を秒までと仮定して、Between句を使う。or datetimeのカラムの精度が変わっても同じ結果を得られるようにするために、A &amp;lt;= column AND column &amp;lt; Bという表現を使う。&lt;/li&gt;
&lt;li&gt;between句を使った場合、&lt;strong&gt;datetime型のカラムの精度を変更すると&lt;/strong&gt;予期しない結果が出てくる場合がある。&lt;/li&gt;
&lt;li&gt;big dataを扱う場合は特にテストのときの件数が膨大になるので境界値の問題に気づきづらいので要注意です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B088M1BMBG&quot;}&lt;/p&gt;
</content:encoded></item><item><title>物理メモリが不足したらpumaを自動で再起動</title><link>https://blog.teraren.com/posts/puma-auto-restart/</link><guid isPermaLink="true">https://blog.teraren.com/posts/puma-auto-restart/</guid><description>物理メモリが不足したらpumaを自動で再起動</description><pubDate>Thu, 20 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/puma/puma&quot;&gt;puma&lt;/a&gt;がどんどんメモリを食っていってしまう。同様に、sidekiqもたくさんメモリを食ってしまっている。&lt;/li&gt;
&lt;li&gt;GCしても減らない。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;ObjectSpace.each_object(ActiveRecord::Relation).each(&amp;amp;:reset)
GC.start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;オレンジはswap used. 減るときは再起動しているタイミング。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;物理メモリが80％以上使われていたらpumaを再起動するスクリプト書いた。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Puma&lt;/h3&gt;
&lt;h3&gt;Sidekiq&lt;/h3&gt;
&lt;h2&gt;導入結果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;swapにまで食い込まなくなりました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Facebookのブロックチェーン&quot;Libra&quot;を動かしてみました</title><link>https://blog.teraren.com/posts/libra-test-on-ubuntu/</link><guid isPermaLink="true">https://blog.teraren.com/posts/libra-test-on-ubuntu/</guid><description>FacebookのブロックチェーンプロジェクトLibraをUbuntu上のDockerでチュートリアル実行。ホワイトペーパーの考察とDockerfileの課題も紹介。</description><pubDate>Wed, 19 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Libra&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;昨日、Libraの&lt;a href=&quot;https://libra.org/en-US/white-paper/&quot;&gt;ホワイトペーパー&lt;/a&gt;を一通り読みました。率直な感想は、技術的には中央集権、stable blockchain。blockchainという技術を社会にどうやってデプロイし、良い社会を作り上げるかが本質かと思っています。これだけLibraがガチで社会実験をすること自体、どうなるかが楽しみです。&lt;/li&gt;
&lt;li&gt;しかし個人的には、人間がリアルで生活している以上、法定通貨との折り合いをどうやってつけていくのかが見物です。国の立場からすれば厄介な登場人物のはずなので。&lt;/li&gt;
&lt;li&gt;それはともあれ、とりあえずどんな感じか触ってみます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;チュートリアル&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Dockerで&lt;a href=&quot;https://developers.libra.org/docs/my-first-transaction&quot;&gt;チュートリアル&lt;/a&gt;をやってみました。Ubuntu 18.04.2で動かしています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/image-9.png&quot; alt=&quot;Libra&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;手元のmacでセットアップを始めたら、大量にダウンロードが必要だし、homebrewで大量にパッケージを入れらそうになったので止めた方がいいです。とりあえずdockerでやりました。&lt;/li&gt;
&lt;li&gt;リアルタイム、無編集なので、適当にスキップしながら進めてもらえればと思います。&lt;/li&gt;
&lt;li&gt;TOEIC 890程度の英語のリーディング速度の参考値としてご参照ください。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://www.youtube.com/watch?v=KX0nQzieZzc&amp;amp;feature=youtu.be&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Dockerfileを作れよという感じですが、とりあえず動かしてみたかったので、この程度でおわり。&lt;/li&gt;
&lt;li&gt;裏でDocker Engineが暴走してるし、夜だからネットワークが遅くてダウンロードに時間がかかりましたが、チュートリアルを読み始めてから40分ぐらいで完了しました。&lt;/li&gt;
&lt;li&gt;この動画の内容を、解説付きでYoutube liveすると良いんだろうね。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://libra.org/en-US/white-paper/#what-is-next-for-libra&quot;&gt;テクニカルペーパー&lt;/a&gt;もわかりやすいので、教材としても良い。&lt;/li&gt;
&lt;li&gt;blockchainの技術はここ2年で急速に社会実験が行われて成熟が進んだ印象です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Dockerfile&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;作ってみたけど、./scripts/dev_setup.shが完了しないので直してくれたらうれしいです。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/libra-docker&quot;&gt;https://github.com/matsubo/libra-docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>AWS LightsailでWordPressをホスティング</title><link>https://blog.teraren.com/posts/lightsail-wordpress/</link><guid isPermaLink="true">https://blog.teraren.com/posts/lightsail-wordpress/</guid><description>AWS LightsailにWordPressを構築。EC2との違いや月約2,200円の運用コスト、ACMによるHTTPS設定、ロードバランサの制限など実際の構築記録をまとめた。</description><pubDate>Mon, 10 Jun 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;とあるWordPressサイトをホスティングすることになりました。EC2よりLightsailの方がお手軽そうだし、WordPressサーバの運用に拘りは余り無いから適当に構築して運用したい。&lt;/li&gt;
&lt;li&gt;もちろんhttpsで。letsencryptを使った解説はたくさん見かけますが、AWS ACMのほうが楽です。&lt;/li&gt;
&lt;li&gt;予備知識として、&lt;a href=&quot;https://qiita.com/Hikery/items/8933e1969c971eaa649d&quot;&gt;Lightsailでのインスタンス構築方法はこちら&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;Lightsailは安いっぽいし↓&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;LightsailとEC2の違い&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Lightsailが出た当初はインスタンスの機能しかなかったけど、色々付け加わったりしています。&lt;/li&gt;
&lt;li&gt;解説記事を読んでいると、EC2とLightsailでかつては共通で使えたような機能の記述があったりしますが、現在はほぼ完全に分断されています。2019年11月に&lt;a href=&quot;https://dev.classmethod.jp/cloud/aws/reinvent2018-upgrade-lightsail-to-ec2/&quot;&gt;インスタンスのイメージはLightsailからEC2に移動出来る&lt;/a&gt;ようになったみたいです。。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/image-3.png&quot; alt=&quot;EC2 vs Lightsail&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/Instances___Lightsail.png&quot; alt=&quot;lightsail instance&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一番安いインスタンスサイズで、WordPressのテンプレから構築。東京に作られたみたい。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/image.png&quot; alt=&quot;htop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;結構Swapまで使ってしまっています。。。。MySQLが使いまくっている。（面倒だからチューニング無し）&lt;/p&gt;
&lt;p&gt;仮想メモリは8割ぐらい使い切ってます。&lt;br /&gt;
物理メモリ溢れています。どういう初期設定しているのだ。。。。怒&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ free -m
              total        used        free      shared  buff/cache   available
Mem:            486         259           6          38         220         145
Swap:           634         385         249
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/image-4.png&quot; alt=&quot;lightsail database&quot; /&gt;&lt;/p&gt;
&lt;p&gt;データベースを作れるけれど、今回は面倒だからインスタンス内に立てておく&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;この辺りから、AWSの囲い込みが始まりました。ロードバランサを登録するためには、Route53ではなく、LightsailのDNS zoneを使う必要があります。&lt;/li&gt;
&lt;li&gt;もちろん、ロードバランサはLightsail内のロードバランサでないとバランシング出来ません（昔はEC2からIP指定で出来たみたいですが今は出来なさそうです）&lt;/li&gt;
&lt;li&gt;ロードバランサには、ACMの証明書を利用出来ます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/image-5.png&quot; alt=&quot;lightsail network&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;スナップショットはインスタンス毎にグループ分けされて表示されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ランニングコスト&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;$0.69/d = $20.7/30d&lt;/li&gt;
&lt;li&gt;1月2,200円ぐらいです。（初月無料キャンペーンは、昔遊んでいたときに使ってしまった様子。）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/06/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Lightsailに色々足していけば、結局はEC2と同じような値段感になりました。EC2より若干安いかな。&lt;/li&gt;
&lt;li&gt;運用しだして24時間後になぜか5分ぐらい接続出来ない状態が発生しました。ロードバランサからLightsailのインスタンスのHTTP接続が出来なくなった模様。しかし、インスタンスは稼働していました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>スタートアップにお勧めのコーヒーメーカー</title><link>https://blog.teraren.com/posts/office-coffee/</link><guid isPermaLink="true">https://blog.teraren.com/posts/office-coffee/</guid><description>スタートアップにお勧めのコーヒーメーカー</description><pubDate>Tue, 28 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;要求定義&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;背景：毎日コンビニの100円ドリップコーヒーを買っています。最近は、コンビニの100円コーヒーが苦みばかりで、香りが薄いし、おいしく無いなぁと感じている。&lt;/li&gt;
&lt;li&gt;予算: 数万まで&lt;/li&gt;
&lt;li&gt;定性：おいしいコーヒーを手軽に飲みたい。自分で豆を選びたい。ドリップ。&lt;/li&gt;
&lt;li&gt;定量：1日4杯分くらい&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;議論の過程&lt;/h2&gt;
&lt;p&gt;ディスカッションの過程はこちらのスレをご覧ください。定性調査の超短期MROC的アプローチ。&lt;/p&gt;
&lt;p&gt;最終的にはこれを買いました。アマゾンの評判通り、とても良いです！&lt;/p&gt;
&lt;p&gt;ハンドドリップと同じクオリティでドリップできます。お手入れが若干面倒かなってくらいです。ドリップが終わった後は中に湿気が籠もらないように蓋を開けておく必要があるみたいな。&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;::amazon{asin=&quot;B07DTDHP7Q&quot;}&lt;/p&gt;
&lt;p&gt;補足：趣味としてドリップ自体を楽しむときは、カリタの電動グラインダーで豆を挽いてドリップしています。&lt;/p&gt;
</content:encoded></item><item><title>Web系エンジニアなら必ず読むべき技術書5冊</title><link>https://blog.teraren.com/posts/book-recommendation/</link><guid isPermaLink="true">https://blog.teraren.com/posts/book-recommendation/</guid><description>Code Complete、詳解TCP/IP、デザインパターン入門など、5〜20年使える普遍的な知識を習得できるWeb系エンジニア向け技術書5冊を厳選紹介。</description><pubDate>Thu, 23 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;5年とか10年、20年ぐらいの期間にわたって使える普遍的な知識を得るための本を紹介します。&lt;/li&gt;
&lt;li&gt;一朝一夕で読み切れるような分量ではありませんが、知識として獲得しておくと今後開発をしているときに困った際に、振り返れるポイントとなると思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1位 Code Complete 2 上下&lt;/h2&gt;
&lt;p&gt;::amazon{asin=&quot;489100455X&quot;}&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;4891004568&quot;}&lt;/p&gt;
&lt;h2&gt;2位 詳解TCP/IP&lt;/h2&gt;
&lt;p&gt;::amazon{asin=&quot;4274224473&quot;}&lt;/p&gt;
&lt;h2&gt;3位 デザインパターン入門&lt;/h2&gt;
&lt;p&gt;::amazon{asin=&quot;4815609802&quot;}&lt;/p&gt;
&lt;h2&gt;4位 エリック・エヴァンスのドメイン駆動設計&lt;/h2&gt;
&lt;p&gt;::amazon{asin=&quot;4798121967&quot;}&lt;/p&gt;
&lt;h2&gt;5位 Modern Operating System&lt;/h2&gt;
&lt;p&gt;::amazon{asin=&quot;013359162X&quot;}&lt;/p&gt;
&lt;h2&gt;補足&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;リーダブルコード
&lt;ul&gt;
&lt;li&gt;いろいろなところで推薦されていますが、浅いです。&lt;/li&gt;
&lt;li&gt;Code Completeで詳しく論文のエビデンスを元に解説されているので読まなくて良いと思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>エンジニア視点のコストコのおすすめベスト10</title><link>https://blog.teraren.com/posts/costco/</link><guid isPermaLink="true">https://blog.teraren.com/posts/costco/</guid><description>7年間のコストコ会員歴を持つエンジニアが、実際に買い続けて殿堂入りしたコスパ抜群の商品をランキング形式で紹介</description><pubDate>Thu, 23 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;かれこれ&lt;strong&gt;7年間&lt;/strong&gt;ぐらい&lt;a href=&quot;https://www.costco.co.jp/FAQ/Membership&quot;&gt;コストコ会員&lt;/a&gt;です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;コストコおすすめサイト&lt;/strong&gt;や、お店で他人が&lt;strong&gt;物理カート&lt;/strong&gt;に入れている物を見た上で、&lt;strong&gt;様々な無駄な買い物をした結果&lt;/strong&gt;、私の中での殿堂入りしたおすすめ商品をランキングにします。&lt;/li&gt;
&lt;li&gt;ターゲット属性：&lt;strong&gt;めんどくさがり屋&lt;/strong&gt;。&lt;strong&gt;食に意識高い系&lt;/strong&gt;。&lt;strong&gt;時間重要&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;コストコ初心者へのアドバイスは、「&lt;strong&gt;空腹で買い物してはだめ！&lt;/strong&gt;」無駄な物をたくさん買ってしまうので。腹ごしらえをしてから買い物しましょう。&lt;/li&gt;
&lt;li&gt;とりあえず、騙されたと思って1位から10位まで全部買いましょう。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1位 500mlペットボトルの水&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;KIRKLAND purified. water&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;これを買うためにコストコへ行っている&lt;/strong&gt;と言っても過言ではありません。毎回買います。&lt;/li&gt;
&lt;li&gt;家を出るときや、ランニングに行くときに1本持って行けます。35本で588円（&lt;strong&gt;1本約16円&lt;/strong&gt;）。コンビニで買う6分の1の値段。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;朝は脱水状態&lt;/strong&gt;なので、家を出た直後に少し歩くだけで喉が渇いたりします。夏においては、水分は肌身離さず持っておいた方が良いです。水分だけだと吸収されづらいので、家でバナナを1本食べてからとかが良いです。&lt;/li&gt;
&lt;li&gt;中身は濾過された&lt;strong&gt;水道水&lt;/strong&gt;です。臭いはありません。&lt;/li&gt;
&lt;li&gt;飲み終わったら、ペットボトルのゴミが発生するのがecoじゃなくて良くないですが、リサイクル出来る（はず）なのでよしとします。利便性と時間効率を考えるとしょうが無いと自分を納得させています。&lt;/li&gt;
&lt;li&gt;ランニングに行くときには、この水に&lt;a href=&quot;https://www.wiggle.jp/high5-zero-%E9%9B%BB%E8%A7%A3%E8%B3%AA%E3%83%89%E3%83%AA%E3%83%B3%E3%82%AF-%E3%82%BF%E3%83%96%E3%83%AC%E3%83%83%E3%83%88-20%E5%80%8B-/&quot;&gt;Wiggleで買ったhigh5のタブレット&lt;/a&gt;を入れてスポーツドリンクにして持って行っています。低コスト、短時間です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2位：無塩ミックスナッツ&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;KIRKLAND Unsalted Mixed Nuts&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1.13kgで約2,600円。&lt;/li&gt;
&lt;li&gt;ちょっと高いですが、間食のために買っています。会社に置いておく感じです。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;../../assets/uploads/2019/05/image-17.png&quot;&gt;セブンイレブンの無塩ミックスナッツ72gで321円&lt;/a&gt;なので単価は約1/2。&lt;/li&gt;
&lt;li&gt;市販のナッツには味のレベルがあり、おいしい物からまずい物まであります。&lt;strong&gt;これはおいしい&lt;/strong&gt;です。空腹時に食べ出したら止まらなくなるので要注意。糖分がないのでいくら食べても血糖値が上がらないので、低血糖を回復できないので空腹時に食べ出すこと自体がNGか。&lt;/li&gt;
&lt;li&gt;カロリーは高いですが植物性油脂だし、脂肪燃焼を促進する効果による&lt;strong&gt;ダイエット効果&lt;/strong&gt;があるので?とします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3位 センサー付きゴミ箱&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;EKO センサー付きゴミ箱　47L&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;6000円ぐらい。**ゴミ箱のくせに高い！しかし、削減出来る時間を考えると6,000円の価値はあります。**なぜなら、&lt;strong&gt;1年で14時間を節約出来るから。&lt;/strong&gt;（1回当たり2秒、10回/日）&lt;/li&gt;
&lt;li&gt;10商品のうち、これだけ消耗品じゃ無くてすいません。&lt;/li&gt;
&lt;li&gt;「&lt;strong&gt;自動開閉ゴミ箱が便利！&lt;/strong&gt;」と聞いて半信半疑で買ってみましたが、&lt;strong&gt;本当に便利&lt;/strong&gt;でした。&lt;/li&gt;
&lt;li&gt;蓋付きのゴミ箱だと、ゴミの臭いが外に出てきません。この商品は密閉度が高いから良いです。夏は生ゴミが腐りやすくなるので蓋付きのゴミ箱は必須です。&lt;/li&gt;
&lt;li&gt;今までは手動で開閉するゴミ箱でしたが、毎回&lt;strong&gt;開けたり閉めたりの作業が面倒&lt;/strong&gt;でした。これなら楽です。&lt;/li&gt;
&lt;li&gt;料理中、&lt;strong&gt;手が濡れていても手をかざすだけで開けられるので楽&lt;/strong&gt;です。&lt;/li&gt;
&lt;li&gt;中身は45Lのゴミ袋を入れ替える感じです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;騙されたと思って買ってみてください。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;汚れても、本体はステンレスなのでお掃除が楽です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4位 トイレットペーパー&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;KIRKLAND Bath Tissue&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;値段的には安くないですが、2重で柔らかくて質が良いです。&lt;/li&gt;
&lt;li&gt;ドラッグストアとかで12ロールを都度買うのが面倒なので、&lt;strong&gt;まとめて買って運搬コストを削減&lt;/strong&gt;するためです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5位 プルコギビーフ&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;コストコのプルコギビーフ&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大量に入っていて、値段は3,000円ぐらいするのでちょっと高い感じがしますがタレの味付けがおいしくて、&lt;strong&gt;他では味わえない&lt;/strong&gt;感じなので割高かも知れませんが買います。&lt;/li&gt;
&lt;li&gt;賞味期限が数日しか無いので、買ったその日のうちに真空パックにして冷凍しています。&lt;/li&gt;
&lt;li&gt;私は肉を焼いて、&lt;strong&gt;ご飯に載せて、生卵をかけて&lt;/strong&gt;食べています。&lt;/li&gt;
&lt;li&gt;動物性タンパク質。ここ数年、肉質が若干低下気味。筋や脂身が多くなってきている気がします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;6位 塩と胡椒&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大量なのでなかなか無くなりません。&lt;/li&gt;
&lt;li&gt;岩塩は&lt;strong&gt;ミネラル&lt;/strong&gt;が入っているので良いです。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;胡椒は香りが強く&lt;/strong&gt;て良いです。&lt;/li&gt;
&lt;li&gt;ツナ缶に胡椒をかけるだけですごくおいしく食べられたりします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;7位 OXI CLEAN&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;OXI CLEAN&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;お掃除革命&lt;/strong&gt;が起きます。&lt;/li&gt;
&lt;li&gt;「家事ヤロウ!!!」でも登場回数が多い、酸素系漂白剤です。&lt;/li&gt;
&lt;li&gt;「&lt;a href=&quot;http://xn--08jyjja4b7228c&quot;&gt;オキシ漬け&lt;/a&gt;」というバズワードも生まれました。&lt;/li&gt;
&lt;li&gt;油汚れや、泥汚れ、茶渋、衣類の汚れがつけ置きするだけで綺麗になります。塩素では無いので臭いがありません。&lt;/li&gt;
&lt;li&gt;洗濯槽に使えます。&lt;/li&gt;
&lt;li&gt;手で直接触ると手が荒れます。&lt;/li&gt;
&lt;li&gt;大量なのでなかなか使い切れません。&lt;/li&gt;
&lt;li&gt;縦型洗濯機にお湯を張って、洗濯物や食器や家具やガジェットを一気に綺麗にするのが良いと思います。&lt;strong&gt;洗濯槽とモノを一気に洗浄できます。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;8位 Downy&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Downy&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;言わずと知れた良い匂いがする柔軟剤。&lt;/li&gt;
&lt;li&gt;タンクが使いやすいです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;9位 キッコーマン調製豆乳&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;調製豆乳&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1本90円ぐらいなので安いです。&lt;/li&gt;
&lt;li&gt;大量なので1人で飲んでいると、後半は飽きてくるので要注意です。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;高タンパク質。植物性タンパク質。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;仕方なく糖分を取る必要が有るときには、1本飲んでおいて&lt;strong&gt;胃腸をコーティングして急激な血糖値の上昇を抑えられます&lt;/strong&gt;。牛乳でも良いのですが、脂肪分が多いので豆乳の方がベターです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;10位 ギリシャヨーグルト&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;GREEK YOGURT&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1kg 880円&lt;/li&gt;
&lt;li&gt;コンビニの&lt;a href=&quot;../../assets/uploads/2019/05/image-16.png&quot;&gt;パルテノは80gで143円&lt;/a&gt;なので、単価は1/2。&lt;/li&gt;
&lt;li&gt;大量ですが、乳酸菌を補給するために毎日食べているので1人で朝に食べると賞味期限ギリギリに無くなります。&lt;/li&gt;
&lt;li&gt;タンパク質を多く含むのでタンパク質が不足しがちな日本人にもってこいです。&lt;/li&gt;
&lt;li&gt;蜂蜜や、冷凍ブルーベリーなどをかけて食べます。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;動物性タンパク質。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;番外編&lt;/h2&gt;
&lt;p&gt;健康にはあまり良くないけど、おいしい物。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ディナーロール
&lt;ul&gt;
&lt;li&gt;冷凍しておけば日持ちするし安くておいしい。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;糖質の塊&lt;/strong&gt;なので買わない。&lt;/li&gt;
&lt;li&gt;グルテン。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ティラミス
&lt;ul&gt;
&lt;li&gt;見た目ほど甘くなく、ほどよい甘さで&lt;strong&gt;とてもおいしい&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;糖分の塊&lt;/strong&gt;なので買わない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;さくらどり むね肉
&lt;ul&gt;
&lt;li&gt;大量で品質が良いけどさほど安くない。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;小分けにして保管するのが面倒&lt;/strong&gt;なので買わない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;寿司・ちらし寿司
&lt;ul&gt;
&lt;li&gt;サーモンが特においしい。その他のネタは普通においしい。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;糖分の多い&lt;/strong&gt;ので買わない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ノルウェー産アトランティックサーモンフィレ
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;とてもおいしい。タンパク質。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;後半は飽きるので買わない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Bocca 牧家 白いプリン
&lt;ul&gt;
&lt;li&gt;とてもおいしい。昔は買いまくってました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;糖分の塊&lt;/strong&gt;なので買わない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ヨシダソース ステーキ
&lt;ul&gt;
&lt;li&gt;おいしい！&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;すぐに飽きて消費できません。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>webp画像をMicrosoft Wordに貼り付ける</title><link>https://blog.teraren.com/posts/webp-paste-into-word/</link><guid isPermaLink="true">https://blog.teraren.com/posts/webp-paste-into-word/</guid><description>webp画像をMicrosoft Wordに貼り付ける</description><pubDate>Wed, 08 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;macosにおいて、webp形式の画像データや、画像ファイルをMicrosoft Wordに貼付け出来ない様子。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ペーストしても何もペーストされないです。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一旦、gifやpngなどのファイルフォーマットに変換してから、コピペするか画像を挿入する必要があります。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% convert image.webp image.png
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/05/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>要求定義 (Request Definition)</title><link>https://blog.teraren.com/posts/request-definition/</link><guid isPermaLink="true">https://blog.teraren.com/posts/request-definition/</guid><description>要求定義の目的・進め方とユースケース図・シーケンス図・要求定義書などのアウトプット例をソフトウェア開発の上流工程として解説</description><pubDate>Mon, 08 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/software-development-flow/&quot;&gt;ソフトウェア開発プロセス&lt;/a&gt;という記事の子要素となる記事です。&lt;/li&gt;
&lt;li&gt;要求定義の進め方、アウトプットの例を説明します。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;要求&lt;/strong&gt;と&lt;strong&gt;要件&lt;/strong&gt;を理解しないで使っている人が多いので要注意。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要求定義とは&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;発注側が何をしたいのか&lt;/strong&gt;を形に表した図や書類。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ビジネス関連の人が頭の中で思い描いているゴールを、図やドキュメントに書く事です。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;図やドキュメントに書くことによって、空中戦の議論では無く、図やドキュメントをベースとしたディスカッションを行えるようになります。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;図やディスカッションをベースに議論することにより、MECEな視点でエンティティを捉えられるようになったり、欠陥を見つけやすくします。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;作る人は&lt;strong&gt;ビジネス責任者&lt;/strong&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;書き方やディスカッションにはプロダクト開発の責任者もアドバイザとして参加し、クリティカルシンキングを用いながら質問をすることで&lt;strong&gt;具現化や問題のあぶり出し&lt;/strong&gt;を行います。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;アウトプット例&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ユースケース図&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;頭の中では思い描けているから普通はドキュメントとして残さないだろうけど、&lt;strong&gt;必須です。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;途中からプロジェクトに参加した人、引き継ぎ、ビジネスサイドとプロダクトサイドのゴールを共通化するために。&lt;/li&gt;
&lt;li&gt;どうせ5分とか10分で書ける図なので、コスパは高いです。&lt;/li&gt;
&lt;li&gt;以下にユースケースの例を貼り付けます。
&lt;ul&gt;
&lt;li&gt;とあるシステムのユースケース図です。&lt;/li&gt;
&lt;li&gt;シンプルなので図を書くほどでは無いと思われてしまいますが、情報量はとても多いです。システムのステークホルダーが明確になり、どのようなインタラクションがあるかが一目でわかります。&lt;/li&gt;
&lt;li&gt;これは、一番抽象度の高いユースケースです。各アクター毎にユースケースを整理した図を書いても良いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;UMLは&lt;a href=&quot;http://astah.change-vision.com/ja/shopping/price.html#uml&quot;&gt;Astah UML&lt;/a&gt;を使っています。
&lt;ul&gt;
&lt;li&gt;¥670～/月ですが、コスパ高いので必要です。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cacoo.com/ja/&quot;&gt;Cacoo&lt;/a&gt;や&lt;a href=&quot;https://www.draw.io/&quot;&gt;draw.io&lt;/a&gt;のf無料ツールはありますが、追加変更の操作性の良さはAstahが一番です。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/04/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ユースケース図の例&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;要求定義書&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;ユースケースを見れば、システムのゴールが大体わかるから、ユースケースで網羅出来ない機能などはドキュメントで補足します。&lt;/li&gt;
&lt;li&gt;スコープ
&lt;ul&gt;
&lt;li&gt;予算&lt;/li&gt;
&lt;li&gt;期間
&lt;ul&gt;
&lt;li&gt;場合によってはマイルストーン&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ユーザ数&lt;/li&gt;
&lt;li&gt;対応端末
&lt;ul&gt;
&lt;li&gt;アプリ、Web、PC、スマホ、ブラウザ種別&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;シーケンス図&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;ユースケースだけではビジネスのフローが見えないので、正常系のメインの流れに関してはシーケンス図を書いておきます。ユースケース図だけではわからないユースケースの順番がわかるようになります。&lt;/li&gt;
&lt;li&gt;上記のユースケース図と同じシステムの、ビジネスレベルのユースケースをどのような順番で行われるか抜き出したシーケンス図です。&lt;/li&gt;
&lt;li&gt;まだ、上流工程なので細かい部分は割愛して、&lt;strong&gt;ビジネスレベルのユースケースを決めることにフォーカス&lt;/strong&gt;しています。この時点で、より少ないシーケンス、少ない同期処理、少ないインタラクションを心がけて&lt;strong&gt;ブラッシュアップ&lt;/strong&gt;します。&lt;/li&gt;
&lt;li&gt;要求定義の段階では、同期処理や、タイミング、排他、例外処理に関しては割愛しています。&lt;/li&gt;
&lt;li&gt;明記はしませんが、このシーケンス図を見ればプロダクト開発責任者の頭の中では考えられているはずです。ビジネスサイドの合意が必要な例外処理は記載しておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/04/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;類似サービス、システムのサーベイ
&lt;ul&gt;
&lt;li&gt;類似サービスがあれば、その実態のあるサービスを見ることでゴールが明確に想像できるようになります。&lt;/li&gt;
&lt;li&gt;ドキュメントにはその差分だけを書けば良いのでドキュメンテーションのコストがかなり減らせます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要求定義のゴール&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;プロジェクト責任者の合意&lt;/li&gt;
&lt;li&gt;ビジネス責任者の合意&lt;/li&gt;
&lt;li&gt;プロダクト開発責任者の合意&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要求定義の使われ方&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;要求定義書を、プロダクト開発責任者が合意したら要件定義となります。&lt;/li&gt;
&lt;li&gt;要求定義がそのまま要件定義になることは考えずらいですが、システム開発の視点からより具体化していき、最終的にビジネス責任者と合意できれば要件定義が完成として良いと思います。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;このプロダクト開発に関わるビジネス関係者、開発関係者が最初に見るようなドキュメント&lt;/strong&gt;になります。&lt;/li&gt;
&lt;li&gt;要望定義書は、そのまま&lt;strong&gt;RFP&lt;/strong&gt; (Request For Proposal（提案依頼書）)として&lt;strong&gt;流用&lt;/strong&gt;出来ます。&lt;/li&gt;
&lt;li&gt;自社で要件定義書を作成出来ない場合、ベンダーに要望定義書を投げて要件定義書を作成すると言ったことも可能です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;余談&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;要件定義をRD(Requirements Definition)と略されたりしますが、Request DefinitionもRDなのでどうしてRDと略されるのか謎です。略さないでください。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>CO2濃度を測定して集中力低下と眠気の原因を特定する</title><link>https://blog.teraren.com/posts/co2-concentration/</link><guid isPermaLink="true">https://blog.teraren.com/posts/co2-concentration/</guid><description>CO2センサを3台用意し、車・オフィス・寝室など様々な場所でCO2濃度を実測。Raspberry Pi + mackerelでモニタリングする仕組みも構築</description><pubDate>Sun, 07 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;CO2濃度と集中力の関係&lt;/h2&gt;
&lt;p&gt;二酸化炭素濃度と集中力には密接な関連がある。ハーバード大学の研究（&lt;a href=&quot;https://ehp.niehs.nih.gov/doi/10.1289/ehp.1510037&quot;&gt;Allen et al., 2016&lt;/a&gt;）では、CO2濃度が1,000ppmを超えると認知機能が有意に低下することが示されている。&lt;/p&gt;
&lt;p&gt;一般的な目安:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CO2濃度&lt;/th&gt;
&lt;th&gt;状態&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;〜600ppm&lt;/td&gt;
&lt;td&gt;屋外レベル。快適&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;600〜1,000ppm&lt;/td&gt;
&lt;td&gt;許容範囲。換気していれば問題なし&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,000〜1,500ppm&lt;/td&gt;
&lt;td&gt;集中力低下・眠気が出始める&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,500ppm〜&lt;/td&gt;
&lt;td&gt;頭痛・倦怠感。即座に換気が必要&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;CO2センサを3台買って、車・オフィス・自宅で計測できるようにした。&lt;/p&gt;
&lt;p&gt;参考記事: https://www.daringdaddy.com/entry/2018/01/03/%E3%82%AA%E3%83%95%E3%82%A3%E3%82%B9%E3%81%AE%E4%BA%8C%E9%85%B8%E5%8C%96%E7%82%AD%E7%B4%A0%E6%BF%83%E5%BA%A6%EF%BC%88CO2%E6%BF%83%E5%BA%A6%EF%BC%89%E3%81%8C%E3%80%81%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC&lt;/p&gt;
&lt;h2&gt;計測結果&lt;/h2&gt;
&lt;h3&gt;車&lt;/h3&gt;
&lt;p&gt;普段は暖房効率と外気の臭いを避けるため内気循環にしている。長時間ドライブで眠くなることが多かったが、計測してみると内気循環だと短時間でCO2濃度が急上昇した。ドライブ中の眠気はCO2濃度が大きな原因だと考えられる。&lt;/p&gt;
&lt;p&gt;対策としては、定期的に外気導入に切り替えるか、窓を少し開ける。眠気を感じたらまずCO2濃度を疑うのが良い。&lt;/p&gt;
&lt;h3&gt;オフィス&lt;/h3&gt;
&lt;p&gt;室内でも、1部屋あたりの人数が多いとすぐにCO2濃度が上がる。計測値は上下が大きいので、瞬間値ではなく履歴のトレンドで判断するのが良い。&lt;/p&gt;
&lt;p&gt;締め切った会議室は特に危険で、数十分で1,000ppmを超える。環境によっては常時換気が必要。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/IMG_2849.jpg&quot; alt=&quot;オフィスに設置したCO2モニター&quot; /&gt;&lt;/p&gt;
&lt;p&gt;タブレットの横に設置しておけば、作業中に常時確認できる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/IMG_2850.jpg&quot; alt=&quot;タブレット横のCO2モニター&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B01AVS0JSS&quot;}&lt;/p&gt;
&lt;h3&gt;自宅&lt;/h3&gt;
&lt;p&gt;自宅でも仕事をするのでCO2モニタを設置した。いくつかわかったこと:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ガスコンロ&lt;/strong&gt;: 換気扇なしでお湯を沸かすだけで、あっという間に1,000ppmを超える&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;エアコン+24時間換気のみ&lt;/strong&gt;: 1人で過ごしていても数時間で700ppm程度になる。たまに窓を開けて換気が必要&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;寝室&lt;/strong&gt;: 見落としがちだが、寝るときは換気しないためCO2濃度が上がる。寝ている間は酸欠に気づけないので、寝室の換気は意識的に行う必要がある&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;モニタリング環境の構築&lt;/h2&gt;
&lt;h3&gt;デバイス&lt;/h3&gt;
&lt;p&gt;市販のディスプレイ付きCO2モニタは1万円前後。その中でも以下の商品はUSB経由でセンサ値を取得できるので、プログラムとの連携に便利（&lt;a href=&quot;https://stefafafan.hatenablog.com/entry/2016/12/10/140000&quot;&gt;参考記事&lt;/a&gt;）。&lt;/p&gt;
&lt;h3&gt;Raspberry Pi + mackerelで常時監視&lt;/h3&gt;
&lt;p&gt;Raspberry Pi 4にUSB接続して、mackerel-agentからカスタムメトリクスとして送信している。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/06/image-15.png&quot; alt=&quot;mackerelでのCO2濃度モニタリンググラフ&quot; /&gt;&lt;/p&gt;
&lt;p&gt;mackerelに送信するPythonスクリプト:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;from CO2Meter import *
import time
from datetime import datetime

sensor = CO2Meter(&quot;/dev/hidraw0&quot;)
time.sleep(5)  # 認識待ち

data = sensor.get_data()
timestamp = int(time.time())

print(&quot;co2mini.co2\t{}\t{}&quot;.format(data[&quot;co2&quot;], timestamp))
print(&quot;co2mini.temp\t{}\t{}&quot;.format(data[&quot;temperature&quot;], timestamp))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mackerel-agentの設定でこのスクリプトを定期実行すれば、CO2濃度と室温をグラフで可視化・アラート設定ができる。&lt;/p&gt;
</content:encoded></item><item><title>NetgearのPVID(Port VLAN ID)とは</title><link>https://blog.teraren.com/posts/pvid/</link><guid isPermaLink="true">https://blog.teraren.com/posts/pvid/</guid><description>NetgearスイッチのTag VLAN設定時に必要なPVID（Port VLAN ID）の意味を解説。Native VLANとの関係や、タグなしパケットをどのVLANに送るかの動作原理をまとめた調査メモ。</description><pubDate>Sun, 07 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/NETGEAR-%E3%82%B9%E3%82%A4%E3%83%83%E3%83%81%E3%83%B3%E3%82%B0%E3%83%8F%E3%83%96-%E3%82%AE%E3%82%AC%E3%83%93%E3%83%83%E3%83%888%E3%83%9D%E3%83%BC%E3%83%88-%E3%83%95%E3%82%A1%E3%83%B3%E3%83%AC%E3%82%B9%E9%9D%99%E9%9F%B3%E8%A8%AD%E8%A8%88-GS108E-300JPS/dp/B00OMEVV26?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=2c3fa338bd0f6e4085d7b9bbef652fda&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;Netgear GS108e&lt;/a&gt;で&lt;strong&gt;tag VLAN&lt;/strong&gt;を組んだときに、tag vlanにも関わらず、Port VLANのIDを指定する必要があるので何を指定すれば良いのかよくわから無いので調査したときのメモ。&lt;/li&gt;
&lt;li&gt;（特に結論は出ず）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B00OMEVV26&quot;}&lt;/p&gt;
&lt;h2&gt;資料&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;PVID とは、Port VLAN ID の意味で、ポートに設定されたPVID により、タグ無しのパケットを受信した場合、どのVLAN に送信するかを決定します。タグ付きのパケットを受信した場合は、PVID とは関係なくタグの送信するパケットのVLAN IDを参照し、送信先のVLAN を決定します。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://buffalo.jp/products/catalog/network/setting_ex/bs/g20/vlan-internet/&quot;&gt;http://buffalo.jp/products/catalog/network/setting_ex/bs/g20/vlan-internet/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;こちらでは、Native VLANと呼ばれていたりもする。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Native VLAN とは、トランクポートの中で、タグを付けない VLAN ID のことを指します。デフォルトVLAN や PVID (Port VLAN ID) も同じ意味です。&lt;/p&gt;
&lt;p&gt;この Native VLAN も IEEE802.1q の規格で決まっており、各トランクポートで1つだけ、この Native VLAN を指定することができます（機器単位ではなくポート単位で指定できるものが多いです）。デフォルトでは全ポート VLAN ID=1 が Native VLAN になっています。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://milestone-of-se.nesuke.com/nw-basic/ethernet/tag-native-vlan/&quot;&gt;https://milestone-of-se.nesuke.com/nw-basic/ethernet/tag-native-vlan/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;PVIDについては納得では、ユースケース。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;例えばネイティブVLANを10にすると、そのポートにPCやVLAN非対応のスイッチングハブを接続すると、VLAN10で通信できます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://milestone-of-se.nesuke.com/nw-basic/ethernet/tag-native-vlan/&quot;&gt;https://milestone-of-se.nesuke.com/nw-basic/ethernet/tag-native-vlan/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;なるほど。じゃあ、以下のような構成のL2 switchはどうすれば良いのかと。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;trunk&lt;/li&gt;
&lt;li&gt;vlan100&lt;/li&gt;
&lt;li&gt;vlan100&lt;/li&gt;
&lt;li&gt;vlan100&lt;/li&gt;
&lt;li&gt;vlan101&lt;/li&gt;
&lt;li&gt;vlan101&lt;/li&gt;
&lt;li&gt;vlan101&lt;/li&gt;
&lt;li&gt;vlan101&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;1つめには、適当にvlan1でも振っておいて、あとは普通に2,3,4ポートにvlan100, 5,6,7,8ポートにvlan101を振っておけば良いのかなと。&lt;/p&gt;
&lt;p&gt;そうすれば、管理用の論理ネットワークには接続出来なくなるのかなと。1番を抜いて挿せば管理用のネットワークに入れてしまうことになるが。&lt;/p&gt;
&lt;p&gt;よく見る例は以下のようになっているようですが、これだと間違いだと思うんだけどなぁ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/04/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下のような感じが正解かと思っているのだが。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/04/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00OMEVUJK&quot;}&lt;/p&gt;
</content:encoded></item><item><title>UDP 17500ポートへのブロードキャスト</title><link>https://blog.teraren.com/posts/udp-17500-dropbox/</link><guid isPermaLink="true">https://blog.teraren.com/posts/udp-17500-dropbox/</guid><description>ルーターログに頻出するUDP 17500番ポートへのブロードキャストはDropboxのLAN Sync機能によるもの。設定で無効化できる原因と対処法を紹介。</description><pubDate>Thu, 04 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;2019/04/04 17:56:04: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.60:17500 &amp;gt; 255.255.255.255:17500
2019/04/04 17:56:04: same message repeated 2 times
2019/04/04 17:56:04: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.60:17500 &amp;gt; 192.168.2.255:17500
2019/04/04 17:56:04: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.60:17500 &amp;gt; 255.255.255.255:17500
2019/04/04 17:56:19: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.66:17500 &amp;gt; 255.255.255.255:17500
2019/04/04 17:56:19: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.66:17500 &amp;gt; 192.168.2.255:17500
2019/04/04 17:56:34: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.60:17500 &amp;gt; 255.255.255.255:17500
2019/04/04 17:56:34: same message repeated 2 times
2019/04/04 17:56:34: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.60:17500 &amp;gt; 192.168.2.255:17500
2019/04/04 17:56:34: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.60:17500 &amp;gt; 255.255.255.255:17500
2019/04/04 17:56:49: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.66:17500 &amp;gt; 255.255.255.255:17500
2019/04/04 17:56:49: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.66:17500 &amp;gt; 192.168.2.255:17500
2019/04/04 17:57:04: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.60:17500 &amp;gt; 255.255.255.255:17500
2019/04/04 17:57:04: same message repeated 2 times
2019/04/04 17:57:04: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.60:17500 &amp;gt; 192.168.2.255:17500
2019/04/04 17:57:04: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.60:17500 &amp;gt; 255.255.255.255:17500
2019/04/04 17:57:19: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.66:17500 &amp;gt; 255.255.255.255:17500
2019/04/04 17:57:19: LAN2 Rejected at IN(2000) filter: UDP 192.168.2.66:17500 &amp;gt; 192.168.2.255:17500
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ルーターのパケットフィルタのログを眺めていたら、10秒から20秒に3回ぐらいブロードキャスト出してるホストがいる。。。（自分）&lt;/p&gt;
&lt;p&gt;ググったら、dropboxのLAN syncがやっているとのこと。&lt;/p&gt;
&lt;p&gt;頻度高すぎて辛い。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/04/dropbox-lan-sync-17500.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;dropboxのLAN sync&lt;/p&gt;
</content:encoded></item><item><title>DNSレコードのリグレッションテスト</title><link>https://blog.teraren.com/posts/dns-regression-test/</link><guid isPermaLink="true">https://blog.teraren.com/posts/dns-regression-test/</guid><description>DNSゾーンサーバ移行時の設定ミスや漏れを検出するRuby製リグレッションテストツールを作成。成功・失敗時のスクリーンショット付きで使い方を解説。</description><pubDate>Wed, 27 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;DNSのzoneサーバを移行する際に、新サーバで設定が正しく行われているかをプログラムで確認するためのコードを書きました。&lt;/li&gt;
&lt;li&gt;zoneサーバの移行は基本的にはコピペかと思いますので。&lt;/li&gt;
&lt;li&gt;設定が間違っていたり漏れていると大惨事になるのでテスト出来る事が重要です。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/dns_regression_test&quot;&gt;https://github.com/matsubo/dns_regression_test&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;forkして使うのが良いかと思います。&lt;/li&gt;
&lt;li&gt;ツールにするまでも無いぐらいの利用頻度なので、作り込んでいません。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;使い方&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% bundle
% bundle exec ruby dns_test.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-29.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;正しい場合の実行結果&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-30.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;失敗したときの実行結果&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DNSレコードのリグレッションテストを書きました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安全にzoneサーバを移行出来ます。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>ソフトウェア開発プロセス</title><link>https://blog.teraren.com/posts/software-development-flow/</link><guid isPermaLink="true">https://blog.teraren.com/posts/software-development-flow/</guid><description>ウォーターフォール的なスケジュール管理とアジャイルのプラクティスを組み合わせた理想的なソフトウェア開発プロセスを、要求定義からリリースまで体系的に整理した独自フレームワークを解説します。</description><pubDate>Mon, 25 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ソフトウェアの開発プロセスを説明しているサイトを見ても&lt;strong&gt;デファクトスタンダードが見つからない&lt;/strong&gt;。
&lt;ul&gt;
&lt;li&gt;粒度が異なったり、用語が異なったりしている。&lt;/li&gt;
&lt;li&gt;既存のプロセスも私の感覚と異なっており、ベストなモデルが見当たらなかった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;私の理想とする開発プロセスは、&lt;strong&gt;ウォーターフロー的にスケジューリングや観測が可能で、アジャイルのプラクティスによって進められるようなモデル&lt;/strong&gt;です。&lt;/li&gt;
&lt;li&gt;ここ数年、大手企業のシステム開発に携わる事がありますが、この開発工程についての正しい認識と進め方が行われていないという印象があるので&lt;strong&gt;私の頭の中をドキュメント化&lt;/strong&gt;しておきます。&lt;/li&gt;
&lt;li&gt;先行事例を確認するためにIPAの最新の開発プロセス体系である「共通フレーム2013」を確認してみましたが、しっくりこない。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ipa.go.jp/files/000027415.pdf&quot;&gt;https://www.ipa.go.jp/files/000027415.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;資料の中には複数の開発プロセスが前提となった記述があったりして、資料のスコープ時点でロジカルではない点が多数あり、&lt;strong&gt;標準な感じはしない&lt;/strong&gt;。複数人で分担して書いて、くっつけたような資料の印象。&lt;/li&gt;
&lt;li&gt;そもそも複雑！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;例：わかりづらすぎる。&lt;/p&gt;
&lt;h2&gt;私が考える開発プロセス&lt;/h2&gt;
&lt;p&gt;私が頭の中で、フレームワークとしている開発の流れは以下です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;0. ビジネスゴールの設定&lt;/li&gt;
&lt;li&gt;1. 開発系
&lt;ul&gt;
&lt;li&gt;1.1 要求定義&lt;/li&gt;
&lt;li&gt;1.2 要件定義&lt;/li&gt;
&lt;li&gt;1.3 外部設計&lt;/li&gt;
&lt;li&gt;1.4 内部設計&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2. コーディング&lt;/li&gt;
&lt;li&gt;3. 検証系
&lt;ul&gt;
&lt;li&gt;3. 1 コードレビュー&lt;/li&gt;
&lt;li&gt;3.2 ブラックボックステスト&lt;/li&gt;
&lt;li&gt;3.3 受け入れテスト&lt;/li&gt;
&lt;li&gt;3.4 デプロイ＆微修正&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;プロセスの補足&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;上記のプロセスを使えば、以下のようなケースは対応出来ると考えています。このステップをマイルストーンに進める上で、各ステップを&lt;strong&gt;進行と管理を出来る人&lt;/strong&gt;が必要です。
&lt;ul&gt;
&lt;li&gt;世の中にはこのロールの人が少なくて失敗プロジェクトがたくさん生まれてしまっていると思っています。&lt;/li&gt;
&lt;li&gt;プロセス管理は具体的に、スケジュール管理はもちろん、クオリティコントロール、リーダシップ、エンジニアリング面の相談に乗る、日々コードレビュー、自分で修正といったことをするスキルが必要です。&lt;/li&gt;
&lt;li&gt;このロールの人は重要視されることは少ないですが重要です。スキルを評価しづらいし、ロールが管理業務になるので必要なスキルセットが一般的なPMみたいに誤認されてしまいます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自分で下の方まで進めれば進めるほど、自分の頭の中のイメージに近い物が出来る。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;ベンチャーのシステム開発の1機能開発、1イテレーション。スクラムを使っていても、1つのtaskや機能にも当てはまるような&lt;strong&gt;汎用的なプロセス&lt;/strong&gt;かなと思います。&lt;/li&gt;
&lt;li&gt;要求定義と要件定義が1つになっている例が多いですが、明確に分けるべきです。なぜなら、ほとんどの場合、承認者が別だからです。&lt;strong&gt;要求と要件は明確に区別&lt;/strong&gt;すべきです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;責任領域&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;システム開発をもう少し具体的に言うと、「ビジネスゴールを達成するためのプロダクト開発」と定義することが出来ます。&lt;/li&gt;
&lt;li&gt;ゴールへ向かってビジネスサイドの責任者、プロダクト開発の責任者がお互いの領域を学習、理解しながら進めることが重要です。詳しくは、&lt;a href=&quot;https://www.amazon.co.jp/%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9%E3%81%AE%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88-Architects%E2%80%99Archive-%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E5%AE%9F%E8%B7%B5-%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9/dp/4798121967/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;keywords=ddd&amp;amp;qid=1554688575&amp;amp;s=gateway&amp;amp;sr=8-1&quot;&gt;DDD本&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;トップラインから考えると、以下の&lt;strong&gt;3つの責任者は立てるべき&lt;/strong&gt;です。プロジェクト責任者とビジネス責任者は兼務で良いと思います。
&lt;ul&gt;
&lt;li&gt;プロジェクト責任者&lt;/li&gt;
&lt;li&gt;ビジネスサイド責任者&lt;/li&gt;
&lt;li&gt;プロダクト開発責任者&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/04/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;各ステップの詳細&lt;/h2&gt;
&lt;p&gt;例なので、無くても良い。太字はビジネスサイドとエンジニアサイドで意思疎通をするためにも作るべき。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ビジネスゴールの設定
&lt;ul&gt;
&lt;li&gt;背景&lt;/li&gt;
&lt;li&gt;問題&lt;/li&gt;
&lt;li&gt;目的&lt;/li&gt;
&lt;li&gt;アプローチ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;開発系
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/request-definition/&quot;&gt;要求定義&lt;/a&gt; (内容が多いので、別ページに分離しました)&lt;/li&gt;
&lt;li&gt;要件定義
&lt;ul&gt;
&lt;li&gt;図
&lt;ul&gt;
&lt;li&gt;要求定義で作った資料を清書、スコープなどを確定する。&lt;/li&gt;
&lt;li&gt;外注に出す場合にはしっかりと作る。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;フェーズ定義
&lt;ul&gt;
&lt;li&gt;スコープを明確にするためにフェーズが切れる場合はフェーズを切る。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;外部設計
&lt;ul&gt;
&lt;li&gt;重要なページのワイヤーフレーム&lt;/li&gt;
&lt;li&gt;デザインをちゃんと入れるならデザイン案など&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;内部設計
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;主要部分のER図&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;DB設計をしっかり出来る人は意外と少ないので、自分で出来るなら作ってしまった方がコスパ高い。&lt;/li&gt;
&lt;li&gt;カラム名のルールや、外部キーのルールなど、細かい所でルール作りが必要になってしまうので、ルールの定義をするよりかは自分で作ってしまった方が早い。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;クラス図&lt;/li&gt;
&lt;li&gt;デプロイ図&lt;/li&gt;
&lt;li&gt;サーバソフトウェア、言語、ミドルウェアの選定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コーディング
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;コーディング要件&lt;/strong&gt;（静的チェックツールの設定など）
&lt;ul&gt;
&lt;li&gt;最初は大変ですが、2回目以降は使い回せます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コード
&lt;ul&gt;
&lt;li&gt;VCSは必須です。git必須。git使えない人やベンダーはあり得ないくらい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ユニットテスト
&lt;ul&gt;
&lt;li&gt;プロダクトを継続的に運用していくなら、ユニットテストは必須です。&lt;strong&gt;ユニットテストが無いとリファクタリングが出来ないので&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;検証系
&lt;ul&gt;
&lt;li&gt;コードレビュー＆ユニットテスト
&lt;ul&gt;
&lt;li&gt;コードカバレッジ&lt;/li&gt;
&lt;li&gt;静的チェック結果&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ブラックボックステスト
&lt;ul&gt;
&lt;li&gt;なし&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;受け入れテスト
&lt;ul&gt;
&lt;li&gt;なし&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;デプロイ＆微修正
&lt;ul&gt;
&lt;li&gt;リリースノート&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;補足&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;システム開発の前段階の企画（ビジネスプラン）がちゃんと詰められている必要があります。企画が詰められていないと、要求定義や要件定義の前のフェーズである企画にまでシステム担当が入る必要がでてきてしまいます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://x.com/yasuoyasuo/status/1118203818825510913&lt;/p&gt;
</content:encoded></item><item><title>英語の勉強を始める前に読む話</title><link>https://blog.teraren.com/posts/english-learning/</link><guid isPermaLink="true">https://blog.teraren.com/posts/english-learning/</guid><description>UCLA留学経験をもとに英語習得のピラミッド理論を紹介し、社会人が効率よく英語力を伸ばすための考え方と実体験をまとめた記事</description><pubDate>Thu, 21 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1. 英語学習の考え方に関して、激しく同意できる資料があるので共有&lt;/li&gt;
&lt;li&gt;2. それに追加して、私の英語学習の過程とか考え方を共有&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;英語学習の神資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;メモメモ。&lt;/li&gt;
&lt;li&gt;色々な英語学習法が紹介されているけど、それらの学習法以下のスライドはとても良くまとまっているので記録しておく。&lt;/li&gt;
&lt;li&gt;学習法はたくさんあるけど、どこから何をやって良いのかを判断するための理論的な位置づけの資料。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;//www.slideshare.net/yasushikomori31/ss-107509666&quot;&gt;英語が喋れるようになるまで(社会人編)&lt;/a&gt;&lt;/strong&gt; from &lt;strong&gt;&lt;a href=&quot;https://www.slideshare.net/yasushikomori31&quot;&gt;Yas&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/uploads/2019/03/howtolearnenglishaftergraduated-180725205920.pdf&quot;&gt;PDF&lt;/a&gt;&lt;a href=&quot;/uploads/2019/03/howtolearnenglishaftergraduated-180725205920.pdf&quot;&gt;ダウンロード&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;特にこのピラミッドはよく整理されていて良いです。&lt;/li&gt;
&lt;li&gt;下の方がちゃんと出来ていないと上は無理なので土台からかためていく必要ありです。&lt;/li&gt;
&lt;li&gt;ピラミッドの高さが、TOEICの点数と捉えても良いかなぁと。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-18.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;私の場合&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;高校時代
&lt;ul&gt;
&lt;li&gt;高校時代は、教科書棒読みの教師だったので、英語が面白くなくなり、まともに勉強をしなかった。&lt;/li&gt;
&lt;li&gt;初海外。ネイティブスピーカーの話は理解不能。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;大学時代
&lt;ul&gt;
&lt;li&gt;英語のクラス分けは、ABCの&lt;strong&gt;B&lt;/strong&gt;だった気がする。2年の時は一部の科目でAだったような気がする。&lt;/li&gt;
&lt;li&gt;大学4年の時に受けてみた結果は、TOEFL IBTで163点だったらしい。（最高は300点なので、&lt;strong&gt;TOEICで言えば550&lt;/strong&gt;点ぐらい）&lt;/li&gt;
&lt;li&gt;ネイティブスピーカーの言っていることは&lt;strong&gt;ほぼ聞き取れない&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;英語の論文作成は、かなり苦労。日本語で書いてから英訳していた印象があるのでとても効率が悪いし、英訳した感じがとても出ていた。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-19.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;大学卒業後
&lt;ul&gt;
&lt;li&gt;研究室の周りの人に合わせて大学院を受験し、合格していて大学院へ行く予定になっていた。&lt;/li&gt;
&lt;li&gt;研究を進めるためにも、英語の論文をすらすら読むためにも、国際学会で発表して、質疑応答するためにも英語という壁があり、&lt;strong&gt;英語の能力を身につけないと今後かなりストレス&lt;/strong&gt;が発生すると感じていた。旅行も楽しめないし。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.uclaextension.edu/&quot;&gt;UCLA Extension&lt;/a&gt;のALC(American Language School)へ。UCLAに留学する人達が英語を学習するために来るところなので学生はみんな真剣モードで、語学遊学ではない所を選択。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;UCLA Extension
&lt;ul&gt;
&lt;li&gt;学費は&lt;strong&gt;1 quarterで40万円&lt;/strong&gt;ぐらいだった気がする。2 quarterの間（＝半年）在籍していた。それにプラスして家賃、食費費用。半年で約200万円ぐらいかかった気がする。&lt;/li&gt;
&lt;li&gt;初日に行ったクラス分けのテストでは、ABCDEのCぐらいだった気がする。&lt;/li&gt;
&lt;li&gt;最初の1クオーターでは、中学と高校の英文法を1クオーターで全部おさらいした感じ。Essayやら、プレゼンやら、グループディスカッションやら、色々やった。英語の授業を英語で聞けるので、&lt;strong&gt;一石二鳥&lt;/strong&gt;。テーマはアメリカのカルチャーなので同時にアメリカ人の背景を知れて良かった。&lt;/li&gt;
&lt;li&gt;最初の2週間、日常生活はマジ苦痛。食事をするためには**店員と会話をしなければならない。**日本のように必要最低限の会話では終わらないので、最初はストレス溜まる。でも、すぐ慣れる。&lt;/li&gt;
&lt;li&gt;覚えているのは、滞在2日目にスーパーに買い物に行ったときに、&quot;Paper or plastic bag?&quot; と質問されたが、聞き取れなくて3回聞き返した。&lt;/li&gt;
&lt;li&gt;宿題が毎日たくさん出されたので、9時から15時まで授業。家に帰って宿題して、仕事して寝るという生活の繰り返し。（1つ下のクラスの&lt;strong&gt;ルームメイトは毎日夜まで遊び歩いて、夜に帰ってくる生活&lt;/strong&gt;。謎。毎日友だちと遊んでいるせいか&lt;strong&gt;スピーキングは上手い&lt;/strong&gt;。）&lt;/li&gt;
&lt;li&gt;日本人とも英語で会話するようにして、思考もinput、outputも英語にすることにより、&lt;strong&gt;24時間英語漬け&lt;/strong&gt;にしていたら思考も英語になり、リスニングはなれてくるし、スピーキングもいちいち日本語と英語の変換が無くなったので普通になった。&lt;strong&gt;いつの間にかニュースも聞こえる&lt;/strong&gt;ようになった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;帰国
&lt;ul&gt;
&lt;li&gt;帰国して1年後ぐらいにTOEICを受験。たしか&lt;strong&gt;750点&lt;/strong&gt;ぐらい。海外に行っていたのにさほど点数が良く無くて軽く悲しかった。&lt;/li&gt;
&lt;li&gt;その3年後ぐらい、通勤時に暇だったのでTOEICをリベンジするために英語勉強を再開。テスト対策として&lt;a href=&quot;https://www.amazon.co.jp/DUO-3-0-%E9%88%B4%E6%9C%A8-%E9%99%BD%E4%B8%80/dp/4900790052?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=duo+3.0&amp;amp;qid=1618363081&amp;amp;sr=8-1&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=8ff69ed742b6d7d0d85e1f6c128cb40a&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;Duo 3.0&lt;/a&gt;とTOEIC向けの&lt;a href=&quot;https://www.amazon.co.jp/%E3%80%90%E9%9F%B3%E5%A3%B0DL%E3%80%91TOEIC-R-L-R%E3%83%86%E3%82%B9%E3%83%88-%E7%A9%B6%E6%A5%B5%E3%81%AE%E6%A8%A1%E8%A9%A6600%E5%95%8F/dp/4757433964?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=%E9%81%8E%E5%8E%BB%E5%95%8F+toeic&amp;amp;qid=1618363119&amp;amp;sr=8-2-spons&amp;amp;psc=1&amp;amp;spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEzSTFHM0wwOUJWOU5RJmVuY3J5cHRlZElkPUEwNzk5Mjc1M0dLRVFGSFlOMEcwRiZlbmNyeXB0ZWRBZElkPUEyTkdLRE1EWDk0M1QwJndpZGdldE5hbWU9c3BfYXRmJmFjdGlvbj1jbGlja1JlZGlyZWN0JmRvTm90TG9nQ2xpY2s9dHJ1ZQ%3D%3D&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=a8e8b97fc15577690c4a8bb7b94f3a87&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;過去問&lt;/a&gt;と、足りなかった文法をやって、&lt;strong&gt;875点&lt;/strong&gt;。TOEICの点数を上げたところで、目的がないのでこれで辞める。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;4900790052&quot;}
::amazon{asin=&quot;4757433964&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-21.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;業務（帰国後約10年間、英語を使った場面）
&lt;ul&gt;
&lt;li&gt;オフショア開発のために現地の外人と英語でやりとり。&lt;/li&gt;
&lt;li&gt;海外イベント出展と説明員&lt;/li&gt;
&lt;li&gt;海外に関連した事業のエンジニアリーダー&lt;/li&gt;
&lt;li&gt;チームメンバーの外国人との会話&lt;/li&gt;
&lt;li&gt;海外チームとのミーティング&lt;/li&gt;
&lt;li&gt;海外旅行10回ぐらい（コミュニケーションで困ることは無くなった）&lt;/li&gt;
&lt;li&gt;迷子の外国人を助けること10回ぐらい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;主観的な英語能力&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;主観的な自分の英語スキルは以下のようなイメージ。アメリカに居るときになんか慣れたって感じです。日本で地道に勉強していたら、&lt;strong&gt;なかなか達成出来ない壁&lt;/strong&gt;を簡単に突き破った感じがします。&lt;/li&gt;
&lt;li&gt;大学での授業、研究での英語論文読み書きでも、この壁は越えらる感じを得られなかったので、ブレイクスルーを狙ってノープランでとりあえず海外へ行った。&lt;/li&gt;
&lt;li&gt;おそらく日本で英語学習を普通にやっていてはなかなか突破しづらい物。大量の英語インプット、英語での思考、英語でのアウトプットをすることで越えられた。&lt;/li&gt;
&lt;li&gt;また、英語に限らず何事もそうだが、スキルを獲得するのは早ければ早いほど使える場所が増えるし、自分の価値が高まる。&lt;/li&gt;
&lt;li&gt;「英語が重要！」と思っているのなら&lt;strong&gt;さっさと時間と金を突っ込んで&lt;/strong&gt;、スキルを獲得してしまった方が良い。頭の良さ悪さは関係無く、語学はinputとoutputの量と質かとおもう。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;20歳で獲得するのと、40歳で獲得するのでは、英語を活用出来る機会が全然違う。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;日本人の居ない海外留学は良い。200万円と半年間の投資は余裕で回収出来ている。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;語学留学すると、ピラミッドの全てをまんべんなく全方位で鍛えられる。学生だから間違っても許容される。ミドルくらいのスキルの人にはコスパは最強かと思う。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;受験勉強のように、&lt;strong&gt;ある程度の時間集中してがっつりやらないと獲得出来ないスキル&lt;/strong&gt;かと思う。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;大学卒業後、すぐにアメリカへ行ったときの気持ちは、イチローが言っている、このフレーズに近い感覚です。↓&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Netgear GS108E 繋がらない</title><link>https://blog.teraren.com/posts/netgear-gs108e-unable-to-setup/</link><guid isPermaLink="true">https://blog.teraren.com/posts/netgear-gs108e-unable-to-setup/</guid><description>Netgear GS108E 繋がらない</description><pubDate>Thu, 21 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Netgear GS108E&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1年以上前に買って、放置していたVLAN対応のL2スイッチを設定しようとしたら、壊れていて設定出来なかった。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;30日以内に製品登録&lt;/strong&gt;をしないと、永久保障が受けられなくなり、1年の保障になってしまう。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;やったこと&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/jp/app/netgear-insight/id1186392308?mt=8&quot;&gt;Netgear Insightアプリ&lt;/a&gt;で設定できるみたいだから、挑戦してみたら機材はちゃんと見えており、アプリからIPアドレスを設定しました。そしたら、二度と見えなくなりました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/IMG_2758.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;arpコマンドで探したけど、見つからず。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.netgear.com/support/product/ProSafe%20Plus%20Utility#download&quot;&gt;Prosafe Plus&lt;/a&gt;でも見つからず。&lt;/li&gt;
&lt;li&gt;DHCPサーバの配布先のリストでも見つからず。&lt;/li&gt;
&lt;li&gt;ファクトリーリセットをかけても見つからず。（インジケーターが-無反応なのでファクトリーリセットがかかっているかも謎ですが）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.netgear.com/support/product/netgear-switch-discovery-tool.aspx#download&quot;&gt;NETGEAR Switch Discovery Tool (NSDT)&lt;/a&gt;でも見つからず。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ただのL2スイッチとしてなら使えています。&lt;/li&gt;
&lt;li&gt;でも、挙動が怪しいので使い続けるのは怖いので、予備機として使う程度。&lt;/li&gt;
&lt;li&gt;仕方が無いので、新しいGS108Eを買いました。新しい機器は問題無く管理画面が見えました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B00OMEVV26&quot;}&lt;/p&gt;
</content:encoded></item><item><title>エストニアのe-Residency（電子国民）を更新してみた</title><link>https://blog.teraren.com/posts/estonia-e-residency-update/</link><guid isPermaLink="true">https://blog.teraren.com/posts/estonia-e-residency-update/</guid><description>エストニアe-ResidencyカードをDigiDoc4クライアントで更新する手順とPIN変更の注意点、その後の活用実態を報告</description><pubDate>Sun, 10 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/e-residency/&quot;&gt;エストニアの電子国民&lt;/a&gt;になってから1年と9ヶ月が経ちました。エストニアに行く用事が無いので、1度も利用しませんでしたが。&lt;/li&gt;
&lt;li&gt;せっかく面倒な思いをして取得したので更新してみます。無料です。&lt;/li&gt;
&lt;li&gt;更新作業によって&lt;strong&gt;PINが変わります&lt;/strong&gt;。初回のPINはカードをもらったときにカードの箱に入っていた番号です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;更新通知&lt;/h2&gt;
&lt;p&gt;以下のようなメールが来ました。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dear document holder,&lt;/p&gt;
&lt;p&gt;Add two years of validity to your e-resident’s digital identity card without leaving home - extend your document number &lt;code&gt;&amp;lt;snip&amp;gt;&lt;/code&gt; now, using the latest ID-software and the DigiDoc4 client. You need the same software for digital authentication and signing documents.&lt;/p&gt;
&lt;p&gt;To extend the validity of your document, please download the latest DigiDoc4 software from &lt;a href=&quot;https://installer.id.ee/&quot;&gt;https://installer.id.ee/&lt;/a&gt;. To launch the process, the document must be valid according to UTC time and you must know its PINs. If you  launch the process but do not complete it right away, then you have 30 days to do so. Once an e-resident’s digital identity card has expired, it cannot be extended.&lt;br /&gt;
 &lt;br /&gt;
If you do not extend the validity of your e-resident’s digital identity card, it remains valid until the date of expiry indicated on your card.&lt;/p&gt;
&lt;p&gt;For more information on extending the validity of your document, please see &lt;a href=&quot;https://www.id.ee/index.php?id=38741&quot;&gt;https://www.id.ee/index.php?id=38741&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Please note that this is an automated notification.&lt;/p&gt;
&lt;p&gt;Sincerely,&lt;br /&gt;
Police and Border Guard Board&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;要点は、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;証明書の有効期限は2年なので、更新して延長しないと無効になるよ。&lt;/li&gt;
&lt;li&gt;更新プロセスを開始したら30日以内に完了しないと無効になるよ。&lt;/li&gt;
&lt;li&gt;更新にはPIN1が必要になるよ。&lt;/li&gt;
&lt;li&gt;更新のやり方は&lt;a href=&quot;https://www.id.ee/index.php?id=38741&quot;&gt;URL&lt;/a&gt;を見てね。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;更新作業&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://itunes.apple.com/jp/app/digidoc4-client/id1370791134?mt=12&quot;&gt;DigiDoc4&lt;/a&gt; Clientをダウンロードして、2年前にもらったカードリーダーにカードを挿して行います。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;まず、DigiDoc Client4を立ち上げて、左のMy eIDをクリックします。そうすると以下のような画面になるので、右上のBeginを押して更新作業を開始します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/DigiDoc4_client.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2年ぶりのDigiDoc Client&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;更新作業を開始すると、途中で何回かPIN1の入力を求められます。&lt;/li&gt;
&lt;li&gt;PIN1の入力ボックスが表示されてから、&lt;strong&gt;1〜2分以内に入力しないとタイムアウト&lt;/strong&gt;になって途中からやり直しなので注意してください。&lt;/li&gt;
&lt;li&gt;私は、ウィンドウを背景に追いやって別の作業をしていたので、3回ぐらいタイムアウトになってトータル10分ぐらいかかりました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;タイムアウトになったときのエラー表示&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;更新の途中で、新しいPIN1，PIN2，PUKが発行されるので安全な場所に保管しておくようにしましょう。古いPIN等はこれ以降使えなくなります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;*完了すると以下のような表示が出てきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;なぜか、4年後の2023年まで使えるようになったみたいです。（元の年数は確認し忘れましたが）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;DigiDoc Clientは使いやすいインターフェイスで、説明を一切読まないで更新作業を行えました。&lt;/li&gt;
&lt;li&gt;すでに、&lt;a href=&quot;https://alexblog.jp/e-residency-whitepaper/&quot;&gt;e-Residency 2.0のホワイトペーパー&lt;/a&gt;が出ている模様。目指している内容が良い。（どうして日本ではこういうセンスの良いビジョンと戦略がでてこないのだろうか）&lt;/li&gt;
&lt;li&gt;昔、e-taxの証明書で、かなり苦労していたので、それに比べると100000倍楽でした。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;その後&lt;/h2&gt;
&lt;p&gt;更新にコストがかかるようになってしまったので更新をやめました！&lt;/p&gt;
&lt;p&gt;電子国民になったことによる実質的な生活の変化が無かったため。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;エストニアのe-Residencyの申請料金は、受け取り場所によって異なりますが、一般的には100〜130ユーロ程度（&lt;strong&gt;約16,000円〜19,000円前後&lt;/strong&gt;※為替による）で、オンライン申請時にクレジットカードで支払います。申請が承認されると、エストニア大使館や領事館などでデジタルIDカードを受け取る流れで、この申請料が主な費用となりますが、カードの受け取りは無料です。&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>nginxでサイトメンテナンスの設定</title><link>https://blog.teraren.com/posts/nginx-site-maintenance-setting/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nginx-site-maintenance-setting/</guid><description>ALB+EC2構成でnginxにreturn 503を追加したメンテナンス用インスタンスを立て、ポチポチするだけで切り替える方法を解説</description><pubDate>Tue, 05 Mar 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;DBに大きく変更を加えるリリースだったのでサイトを止めて作業する必要がありました。&lt;/li&gt;
&lt;li&gt;サイトの一時的なメンテナンスの場合は、&lt;a href=&quot;https://www.suzukikenichi.com/blog/using-503-error-at-site-maintenance/&quot;&gt;HTTPレスポンスは503を返す&lt;/a&gt;のが正しいやり方のようです。&lt;/li&gt;
&lt;li&gt;ALBの5xxページはダサいので、ちょっとかっこいい503ページを出力したかったです。&lt;/li&gt;
&lt;li&gt;ALB(ACM) -&amp;gt; EC2 -&amp;gt; RDS 構成だと簡単に切り替えができます。
&lt;ul&gt;
&lt;li&gt;しかも、管理画面だけ本番サーバに繫ぐとかをポチポチするだけで。&lt;/li&gt;
&lt;li&gt;普通ならIP制限とか、nginxの設定を入れて、テストして、nginxの動作確認をしたり、nginxを再起動したりと面倒な事があります。&lt;/li&gt;
&lt;li&gt;クラウドでサービスレイヤー毎に綺麗に抽象化しているなら柔軟にブラウザだけで操作できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;メンテナンス時に受けるEC2を作って、ALBからのtarget groupを設定しておきます。&lt;/li&gt;
&lt;li&gt;Amazon Linux 2のインスタンスを立ち上げ、yumでnginx nginxの設定はデフォルトの設定に以下の &lt;em&gt;return 503;&lt;/em&gt; を追加するだけ。&lt;/li&gt;
&lt;li&gt;これによってどこのページにアクセスしてもHTTPレスポンスコードとして503が返るようになります。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;location / {
  return 503;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;補足&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;追加で、ALBのヘルスチェックを使うならば、ヘルスチェック用のエンドポイントを追加して200を返すようにしておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;location /healthcheck.html {
  return 200;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;では、nginxが503のステータスを返却した際に、どんなページが表示されるのかというとerror_pageディレクティブで指定した50x.htmlファイルが返されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;error_page 500 502 503 504 /50x.html;
    location = /50x.html {
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ページの準備&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;次に、50x.htmlの準備。nginxのデフォルトはかっこ悪いので、ペラ一で良い感じのテンプレが無いかをググってみつけました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/pitch-gist/2999707&quot;&gt;https://gist.github.com/pitch-gist/2999707&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;サイト名をちょっと変更して完成。デフォルトではvimが日本語使えなかったから、手抜きして英語です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/Pasted_Image_2019_03_05_10_13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ALBの設定&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ユーザ向けのページへのアクセスだけをメンテナンス用のターゲットグループへフォワード。反映はタイムラグ無しで行われました。&lt;/li&gt;
&lt;li&gt;（ちなみに、HTTPのHostヘッダでルーティングする設定であるhost based routingの場合は、積集合で条件が書けないので無理そうな気がします。）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/Pasted_Image_2019_03_05_10_22.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;メンテナンスページを表示している間に、RDS snapshot, デプロイ, 動作確認, 公開前のRDS snapshotなどを行って終わり。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Railsのroutesのshallowは安易に使わないで欲しい</title><link>https://blog.teraren.com/posts/rails-routes-shallow-not-recommend/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-routes-shallow-not-recommend/</guid><description>RailsルーティングのshallowオプションはRESTの思想に反し、権限チェックや実装コストで多くの問題を生じるため使用を避けるべき理由を解説</description><pubDate>Thu, 31 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Shallowの説明は&lt;a href=&quot;https://railsguides.jp/routing.html#%E3%80%8C%E6%B5%85%E3%81%84%E3%80%8D%E3%83%8D%E3%82%B9%E3%83%88&quot;&gt;Rails Guide&lt;/a&gt;にあるとおり。&lt;/li&gt;
&lt;li&gt;example
&lt;ul&gt;
&lt;li&gt;normal: &lt;code&gt;/authors/1/articles/1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;shallow:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/articles/1&lt;/code&gt; （authorのIDはarticleのIDがわかれば自明だから指定しないで良いでしょという理由により）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;shallowの説明には設計レベルのメリットしか書いていない。&lt;/li&gt;
&lt;li&gt;実装レベルの観点が抜けており、実装レベルでは問題がありそうと直感的に思ったので考えをまとめてみた。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;メリット&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;親と子のリソースがある前提で、親のIDは子供のIDから導き出せるから親のIDを指定することを省略できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;デメリット&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;RESTの思想から外れる&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tsurugeek.hatenablog.jp/entry/2015/04/18/205341&quot;&gt;railsのroutesで指定するshallowではまった&lt;/a&gt;のように、実装レベルでの問題が起きる&lt;/li&gt;
&lt;li&gt;実装レベルの話で、子供のEntityの管理ページ一式(Create, Read, Update, Delete)を作成するときに、shallowを使わなければ親の事は気にする必要無いけど、shallowを使う場合は親のIDを子供が持ち回したりしないといけなくなります。
&lt;ul&gt;
&lt;li&gt;主に、newと、destroyのリダイレクト先。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/articles/new?author_id=1&lt;/code&gt; みたいな。pathでこの必須パラメータを表現出来ないので、routes.rbに仕様として落とし込めない。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;redirect_to [:articles, author_id: &amp;lt; 削除前のauthor_id&amp;gt;]&lt;/code&gt; みたいにして変数をわざわざ1個用意してあげないといけない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;上記に付随して、親のIDを使った権限チェックなどを行っている場合は子供側で親の権限もケアしなければいけなくなり、ロールが綺麗に分割出来ない。
&lt;ul&gt;
&lt;li&gt;パラメータインジェクションすることが容易になり、脆弱性を生みやすくなる。&lt;/li&gt;
&lt;li&gt;shallowを使わなければ親レベルで制御出来るので。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;pathとディレクトリ構造が異なるのでメンテナンス性が悪くなる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;自分の考え&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;URLは短くなりますが、やっぱり基本的にRESTの思想を優先してURLを設計したほうが良いと強く思いました。&lt;/li&gt;
&lt;li&gt;これだけ多くのデメリットがあるshallowを使うケースって一体どのようなときだろうか。&lt;/li&gt;
&lt;li&gt;URLのpathは短くなりますが、弊害が多すぎ。10害あって1利あるぐらい。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下に、もう少し深掘りした議論が続きます。&lt;/p&gt;
&lt;p&gt;https://x.com/E46prog/status/1121293225510064129&lt;/p&gt;
</content:encoded></item><item><title>3香港のeSIMをマカオ、香港、中国、日本で使ってみた</title><link>https://blog.teraren.com/posts/3hongkong-esim/</link><guid isPermaLink="true">https://blog.teraren.com/posts/3hongkong-esim/</guid><description>iPhone XSを使って3香港のeSIMをアクティベートし、マカオ・香港・中国・日本でデュアルSIM運用した実体験レポート</description><pubDate>Sat, 26 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;eSIM&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;最近のiPhone XSなどはeSIMをサポートしています。eSIMとは、今まで物理的にSIMカードを電話に入れていた行為が不要になり、iPhoneに内蔵しているRAMにSIM情報を読み書きできる仕組みです。&lt;/li&gt;
&lt;li&gt;今回は、iPhone XSを使って物理SIMとeSIMを使ってみました。（eSIMでデュアルバンドとかも出来るのかな？）&lt;/li&gt;
&lt;li&gt;1週間前に、&lt;a href=&quot;https://toyokeizai.net/articles/-/260620&quot;&gt;iPhoneで｢eSIM｣をまだ使ってない人は大損だ | iPhoneの裏技 | 東洋経済オンライン | 経済ニュースの新基準&lt;/a&gt;という釣り記事がバズって居ましたが、実際に使ってはいなく、微妙なかんじでした。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;事前調査&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ハードウェアはeSIMに対応しているけど、eSIMに対応しているキャリアがそもそも世界的に見てほとんど無い。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://support.apple.com/ja-jp/HT209096&quot;&gt;アップル出しているのeSIM対応キャリア一覧&lt;/a&gt;にはたくさん載っていますが、実際に提供しているキャリアはほんの一部。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.three.com.hk/eSIMMall/chi/eSIMMall/index.jsp?lang=eng&quot;&gt;3香港&lt;/a&gt;というキャリアが世界初の様子。偶然にも今回旅行へ行く国のキャリア。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3香港のeSIMサービス内容&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;音声
&lt;ul&gt;
&lt;li&gt;20か国以上ローミング出来ます
&lt;ul&gt;
&lt;li&gt;China, Macau, Taiwan, Japan, South Korea, Singapore, Malaysia, Thailand, Philippines, Vietnam, Australia, USA, Canada, United Kingdom, Italy, Sweden, Ireland, Denmark, Austria, France&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;10日分のデータローミング付き。1日の利用通信量は無制限。複数都市に行ったとしても1日とカウントされる。&lt;/li&gt;
&lt;li&gt;eSIMの音声通話はeSIMを有効化してから180日以内&lt;/li&gt;
&lt;li&gt;30日分の香港の固定電話と携帯電話への無料発信、受信 (アクティベートしてから_127_359#を押す)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;データ通信
&lt;ul&gt;
&lt;li&gt;eSIMを有効化してから90日以内に利用する必要あり。&lt;/li&gt;
&lt;li&gt;テザリング可能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;オンラインで購入可能&lt;/li&gt;
&lt;li&gt;気になるお値段は、&lt;strong&gt;138 香港ドル&lt;/strong&gt; =&amp;gt; &lt;strong&gt;1,927円&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;購入からアクティベーション&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;用意する物はクレジットカードだけ。&lt;/li&gt;
&lt;li&gt;買ってからアクティベーションするまでは、時間が空いても大丈夫なので、海外に行く前に買うのが良いです。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.three.com.hk/eSIMMall/chi/eSIMMall/index.jsp?lang=eng&quot;&gt;このページ&lt;/a&gt;にアクセスして、&quot;Buy Now&quot;を押します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1794.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;適当に、必要情報を入力します。&lt;/li&gt;
&lt;li&gt;対応言語は英語と中国語のみ。&lt;/li&gt;
&lt;li&gt;簡単に買えました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1795.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;購入が完了すると、購入時に入力したメールアドレスへQRコードが送られてきます。&lt;/li&gt;
&lt;li&gt;このQRコードを読み込むだけでeSIMを登録出来てしまいます。&lt;/li&gt;
&lt;li&gt;eSIMを使う端末でQRコードを表示して読み込むことは出来ないので、2台必要になる。&lt;/li&gt;
&lt;li&gt;友人にQRコードを送ってもよいけど、このQRコードだけでeSIMを使えてしまうのでセキュリティ的に微妙&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1796.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;メールの下の方には、eSIMに登録するための手順が書いてあります。&lt;/li&gt;
&lt;li&gt;これの通りにやれば簡単に登録出来ました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1797.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;では、登録してみます。iPhoneの言語設定が英語になっているのでスクリーンショットは英語です。&lt;/li&gt;
&lt;li&gt;設定 -&amp;gt; モバイル通信 あたりのメニューで真ん中の&quot;Add Cellular Plan&quot;を押します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1799.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;そうすると、QRコードリーダーが立ち上がるので読み込みます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1800.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;確認画面が表示されます&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1801.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自分で、キャリアの名前を付けられます。&lt;/li&gt;
&lt;li&gt;スクリーンショットの表示はデフォルト。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1802.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SIMが2枚入っている状態なので、通話するときにどちらをデフォルトにするか聞かれます。&lt;/li&gt;
&lt;li&gt;電話アプリで、都度キャリアは選べるので、お好みに応じて。&lt;/li&gt;
&lt;li&gt;データ通信も同様に。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1804.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;登録し終わった後に、eSIMの設定を見たスクリーンショット。日本で撮ったので日本のキャリアになっています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1806.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;日本だと、以下のように表示されます。ドコモにローミングされている模様。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1807.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SIMを登録したら以下のようなSMSが送られてきます。&lt;/li&gt;
&lt;li&gt;使い方とか、残りの日にちの確認方法が記載されています。でも、実際には使えなかったのでよくわかりません。&lt;/li&gt;
&lt;li&gt;$58 HKD分のクレジットが付与されたとかかいてあったりと、事前情報と違う点があったりしてよくわからないかんじです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/IMG_1812.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;eSIMのデータ通信設定において、「データローミング」は有効にする必要が有ります。これが無いと通信が出来ませんでした。&lt;/li&gt;
&lt;li&gt;普通、メインのSIMで「データローミング」をオンにすると日本のキャリアから海外ローミングの請求が来ることになり、怖いイメージがありますが大丈夫かと思います。&lt;/li&gt;
&lt;li&gt;一応、eSIMは1度の買い切りなので、キャリアにクレジットカード番号が登録されているので、追加請求が来たら怖いけど。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実際にデータ通信を利用してみると&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;香港：使える（データ通信が不安定）&lt;/li&gt;
&lt;li&gt;深圳：たまに使える。使えたり使えなかったり。そもそも中国だからグレートファイアウォールで弾かれているのかよくわからない。&lt;/li&gt;
&lt;li&gt;マカオ：使える。（データ通信が不安定）&lt;/li&gt;
&lt;li&gt;日本：使える（データ通信の接続元が中国になった）&lt;/li&gt;
&lt;li&gt;音声通話は使えませんでした。理由は不明。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/UNADJUSTEDNONRAW_thumb_50a8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;まだ実用するには厳しい。&lt;/li&gt;
&lt;li&gt;安くeSIMを試せるので使ってみても良いかも。&lt;/li&gt;
&lt;li&gt;今後はeSIMが主流になると思います。わざわざ海外へ行くときにモバイルWiFiを借りなくても良くなりそう。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Nexus 7にAndroid 9 Pieをインストール（失敗）</title><link>https://blog.teraren.com/posts/android9-on-nexus7/</link><guid isPermaLink="true">https://blog.teraren.com/posts/android9-on-nexus7/</guid><description>Nexus 7 (2013) LTEにAndroid 9 Pieを導入しようとしたが、GAppsの容量不足エラーなどに阻まれ断念した試行錯誤の記録</description><pubDate>Wed, 09 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Android 9 Pie on Nexus 7&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.itmedia.co.jp/news/articles/1809/01/news024.html&quot;&gt;Android 9 Pieをインストールしたら、わりと快適&lt;/a&gt;という話を信じてNexus 7 (2013) LTEにAndroid 9 Pieをインストールしようとしたけれど、結構大変だったという話。&lt;/li&gt;
&lt;li&gt;色々試しましたが、結局は未だドライバなどが対応していない様子。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;トライ1&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;以下のブログの内容にのっとって、Android 8の部分をAndroid 9のイメージを使って進めていましたが、gappsをインストールする際に、&quot;error 70 gapps Additional Space Required&quot; と出てしまってインストールが失敗します。&lt;/li&gt;
&lt;li&gt;error 70は、空き容量が足りないエラーです。&lt;/li&gt;
&lt;li&gt;単体のAndroid 9はインストール出来て起動はできます。しかし、Play Storeが入らない状態では実際は実質使えない。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://gadgetrip.jp/2018/03/install_oreo_to_nexus7_2013/&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Begin GApps Size Calculations
------------------------------------------------------------------
  TYPE  |         DESCRIPTION        |      SIZE |   TOTAL
        |         Current Free Space |    160384 |  160384
 Remove |             Existing GApps | +       0 |  160384
 Remove |             Obsolete Files | +       0 |  160384
 Remove |           extservicesstock | +      56 |  160440
 Remove |             extsharedstock | +      24 |  160464
 Remove |      packageinstallerstock | +    8632 |  169096
 Remove |                  provision | +      24 |  169120
Install |                       Core | -  164184 |    4936
Install |                    calsync | -    1796 |    3140
Install |                  googletts | -   22708 |  -19568
Install |     packageinstallergoogle | -    8340 |  -27908
        |               Buffer Space | -    9216 |  -37124
------------------------------------------------------------------
                      Additional Space Required |   37124
------------------------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# End GApps Size Calculations
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Android 9になって、圧縮された状態で17MB程度増えた&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/media/&lt;/code&gt; の内容を削除したりしてがんばって空き容量を開けたりしてみましたが、空き容量が全然足りませんでした。&lt;/li&gt;
&lt;li&gt;単位はたぶんKB（キロバイト）&lt;/li&gt;
&lt;li&gt;元々picoのパッケージなので削除出来るファイルが少ないので断念。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;トライ2&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;容量が少なければ、システムが入っているパーティションを拡張してしまえば良い。&lt;/li&gt;
&lt;li&gt;ここにやり方が書いてある。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://forum.xda-developers.com/nexus-7-2013/general/guide-repartition-nexus72013-to-t3599907&quot;&gt;https://forum.xda-developers.com/nexus-7-2013/general/guide-repartition-nexus72013-to-t3599907&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;手順が多くて大変だけれどもパーティション情報は1バイトも違いはなく、コピペで基本的には行けます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;unmountが必要だったりするのでそのままコピペではいけないけど、&lt;strong&gt;最終的にはAndroid 9 PieとgappsをNexus 7にインストールできた！しかし、ネットワーク周りが不安定で通信が出来ない！&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;~ # /parted /dev/block/mmcblk0 p
Model: MMC HBG4e (sd/mmc)
Disk /dev/block/mmcblk0: 31.3GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system  Name      Flags
 1      67.1MB  157MB   89.6MB  fat16        radio
 2      201MB   204MB   3146kB               modemst1
 3      204MB   208MB   3146kB               modemst2
 4      268MB   284MB   15.4MB  ext4         persist
 5      336MB   336MB   799kB                m9kefs1
 6      336MB   337MB   799kB                m9kefs2
 7      403MB   403MB   799kB                m9kefs3
 8      403MB   407MB   3146kB               fsg
 9      470MB   471MB   1536kB               sbl1
10      471MB   473MB   1536kB               sbl2
11      473MB   475MB   2097kB               sbl3
12      475MB   480MB   5243kB               aboot
13      480MB   481MB   524kB                rpm
14      537MB   554MB   16.8MB               boot
15      604MB   605MB   524kB                tz
16      605MB   605MB   1024B                pad
17      605MB   606MB   1536kB               sbl2b
18      606MB   608MB   2097kB               sbl3b
19      608MB   613MB   5243kB               abootb
20      613MB   614MB   524kB                rpmb
21      614MB   614MB   524kB                tzb
22      671MB   671MB   8192B   ext2         unused1
23      671MB   2139MB  1468MB  ext4         cache
24      2147MB  2149MB  1049kB               misc
25      2215MB  2225MB  10.5MB               recovery
26      2282MB  2282MB  8192B                DDR
27      2282MB  2282MB  8192B                ssd
28      2282MB  2282MB  1024B                m9kefsc
29      2349MB  2349MB  32.8kB               metadata
30      2416MB  5570MB  3154MB  ext4         system
31      5637MB  31.3GB  25.6GB  ext4         userdata
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/01/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;これで止まる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;logcatをしてもよくわからないエラーが。WiFiとかBluetooth周りで変になっている様子。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;01-09 19:27:51.987   514   535 I ActivityManager: Start proc 2572:com.android.bluetooth/1002 for service com.android.bluetooth/.btservice.AdapterService
01-09 19:27:51.994  2572  2572 I Zygote  : seccomp disabled by setenforce 0

01-09 19:27:52.048   514   526 I ActivityManager: Killing 1695:com.google.android.configupdater/u0a25 (adj 906): empty #17

01-09 19:27:52.056   514   536 W libprocessgroup: kill(-1695, 9) failed: No such process

01-09 19:27:52.098   514   536 W libprocessgroup: kill(-1695, 9) failed: No such process
01-09 19:27:52.098   514   536 I libprocessgroup: Successfully killed process cgroup uid 10025 pid 1695 in 41ms
01-09 19:27:52.108   220   220 I Zygote  : Process 1695 exited due to signal (9)

01-09 19:27:52.128   514   543 E BluetoothManagerService: MESSAGE_TIMEOUT_BIND
01-09 19:27:52.138  2572  2572 D BluetoothOppFileProvider: Initialized

01-09 19:27:52.161  2572  2572 V AdapterServiceConfig: Adding HeadsetService
01-09 19:27:52.162  2572  2572 V AdapterServiceConfig: Adding A2dpService
01-09 19:27:52.162  2572  2572 V AdapterServiceConfig: Adding HidHostService
01-09 19:27:52.163  2572  2572 V AdapterServiceConfig: Adding HealthService
01-09 19:27:52.163  2572  2572 V AdapterServiceConfig: Adding PanService
01-09 19:27:52.163  2572  2572 V AdapterServiceConfig: Adding GattService
01-09 19:27:52.163  2572  2572 V AdapterServiceConfig: Adding BluetoothMapService
01-09 19:27:52.163  2572  2572 V AdapterServiceConfig: Adding AvrcpTargetService
01-09 19:27:52.164  2572  2572 V AdapterServiceConfig: Adding HidDeviceService
01-09 19:27:52.164  2572  2572 V AdapterServiceConfig: Adding BluetoothOppService
01-09 19:27:52.164  2572  2572 V AdapterServiceConfig: Adding BluetoothPbapService
01-09 19:27:52.179  2572  2572 I         : [0109/192752.179576:INFO:com_android_bluetooth_btservice_AdapterService.cpp(630)] hal_util_load_bt_library loaded HAL: btinterface=0x98709234, handle=0x8fef4759
01-09 19:27:52.180  2572  2572 D BluetoothAdapterService: onCreate()

01-09 19:27:52.186  2572  2572 D AdapterState: make() - Creating AdapterState
01-09 19:27:52.189  2572  2572 I bt_btif : init
01-09 19:27:52.190  2572  2572 D bt_osi_allocation_tracker: canary initialized
01-09 19:27:52.190  2572  2590 I AdapterState: OFF : entered
01-09 19:27:52.190  2572  2590 D AdapterProperties: Setting state to OFF
01-09 19:27:52.191  2572  2591 I bt_osi_thread: run_thread: thread id 2591, thread name stack_manager started
01-09 19:27:52.191  2572  2591 I bt_stack_manager: event_init_stack is initializing the stack
01-09 19:27:52.195  2572  2594 I bt_osi_thread: run_thread: thread id 2594, thread name alarm_default_ca started
01-09 19:27:52.196  2572  2595 I bt_osi_thread: run_thread: thread id 2595, thread name alarm_dispatcher started
01-09 19:27:52.199  2572  2591 I bt_btif_core: btif_init_bluetooth entered
01-09 19:27:52.199  2572  2591 I bt_stack_config: init attempt to load stack conf from /etc/bluetooth/bt_stack.conf
01-09 19:27:52.200  2572  2596 I bt_osi_thread: run_thread: thread id 2596, thread name bt_jni_workqueue started
01-09 19:27:52.200  2572  2591 I bt_btif_core: btif_init_bluetooth finished
01-09 19:27:52.200  2572  2591 I bt_stack_manager: event_init_stack finished
01-09 19:27:52.200  2572  2596 I bt_btif_core: run_message_loop entered
01-09 19:27:52.201  2572  2572 I bt_osi_wakelock: wakelock_set_os_callouts set to non-native
01-09 19:27:52.201  2572  2572 I bt_btif : get_profile_interface: id = socket
01-09 19:27:52.202  2572  2596 E bt_btif_storage: btif_storage_get_adapter_property: Controller not ready! Unable to return Bluetooth Address
01-09 19:27:52.202  2572  2596 E BluetoothServiceJni: adapter_properties_callback: Status 1 is incorrect
01-09 19:27:52.203  2572  2572 I bt_btif : get_profile_interface: id = sdp
01-09 19:27:52.205  2572  2596 D AdapterProperties: Name is: Nexus 7
01-09 19:27:52.205  2572  2596 D AdapterProperties: BT Class:1a0114
01-09 19:27:52.206   514   514 D BluetoothManagerService: Bluetooth Adapter name changed to Nexus 7
01-09 19:27:52.206   514   514 D BluetoothManagerService: Stored Bluetooth name: Nexus 7
01-09 19:27:52.207  2572  2572 I BluetoothAdapterService: Phone policy enabled
01-09 19:27:52.209  2572  2572 D BluetoothActiveDeviceManager: start()
01-09 19:27:52.216  2572  2597 D BluetoothActiveDeviceManager: onAudioDevicesAdded
01-09 19:27:52.216  2572  2572 D BluetoothAdapterService: setAdapterService() - trying to set service to com.android.bluetooth.btservice.AdapterService@9f97a7
01-09 19:27:52.216  2572  2597 D BluetoothActiveDeviceManager: Audio device added: Nexus 7 type: 2
01-09 19:27:52.216  2572  2597 D BluetoothActiveDeviceManager: Audio device added: Nexus 7 type: 15

01-09 19:27:52.216  2572  2597 D BluetoothActiveDeviceManager: Audio device added: Nexus 7 type: 15
01-09 19:27:52.221  2572  2572 D BluetoothAdapterService: onBind()
01-09 19:27:52.221   514   514 D BluetoothManagerService: BluetoothServiceConnection: com.android.bluetooth.btservice.AdapterService
01-09 19:27:52.222   514   543 D BluetoothManagerService: MESSAGE_BLUETOOTH_SERVICE_CONNECTED: 1
01-09 19:27:52.223   514   543 D BluetoothManagerService: Broadcasting onBluetoothServiceUp() to 5 receivers.
01-09 19:27:52.223   514   543 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@f61ad32
01-09 19:27:52.223   729   754 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@a9eb792
01-09 19:27:52.224   841   872 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@58b882b
01-09 19:27:52.224  2572  2585 D BluetoothAdapter: onBluetoothServiceUp: com.android.bluetooth.btservice.AdapterService$AdapterServiceBinder@4dfa26d
01-09 19:27:52.224  1130  1154 D BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@b1e56ed
01-09 19:27:52.226  2572  2585 D BluetoothAdapterService: enable() - Enable called with quiet mode status =  false
01-09 19:27:52.226  2572  2590 I AdapterState: BLE_TURNING_ON : entered
01-09 19:27:52.226  2572  2590 D AdapterProperties: Setting state to BLE_TURNING_ON
01-09 19:27:52.226  2572  2590 D BluetoothAdapterService: updateAdapterState() - Broadcasting state BLE_TURNING_ON to 1 receivers.
01-09 19:27:52.226   514   543 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: OFF &amp;gt; BLE_TURNING_ON
01-09 19:27:52.226   514   543 D BluetoothManagerService: Sending BLE State Change: OFF &amp;gt; BLE_TURNING_ON
01-09 19:27:52.227  2572  2590 D BluetoothAdapterService: bleOnProcessStart()
01-09 19:27:52.227  2572  2590 I AdapterProperties: init(), maxConnectedAudioDevices, default=5, propertyOverlayed=5, finalValue=5
01-09 19:27:52.230  2572  2590 D BluetoothAdapterService: bleOnProcessStart() - Make Bond State Machine
01-09 19:27:52.231  2572  2590 D BluetoothBondStateMachine: make
01-09 19:27:52.232  2572  2603 I BluetoothBondStateMachine: StableState(): Entering Off State
01-09 19:27:52.236  2572  2572 I BtGatt.JNI: classInitNative(L875): classInitNative: Success!
01-09 19:27:52.240  2572  2572 D BtGatt.DebugUtils: handleDebugAction() action=null
01-09 19:27:52.240  2572  2572 D BluetoothAdapterService: getAdapterService() - returning com.android.bluetooth.btservice.AdapterService@9f97a7
01-09 19:27:52.243  2572  2572 I bt_btif : get_profile_interface: id = gatt
01-09 19:27:52.243  2572  2572 D BluetoothAdapterService: getAdapterService() - returning com.android.bluetooth.btservice.AdapterService@9f97a7

01-09 19:27:52.251  2572  2572 D BluetoothAdapterService: getAdapterService() - returning com.android.bluetooth.btservice.AdapterService@9f97a7
01-09 19:27:52.252  2572  2572 D BluetoothAdapterService: handleMessage() - Message: 2
01-09 19:27:52.252  2572  2572 D BluetoothAdapterService: handleMessage() - MESSAGE_PROFILE_SERVICE_REGISTERED
01-09 19:27:52.252  2572  2572 D BluetoothAdapterService: handleMessage() - Message: 1
01-09 19:27:52.252  2572  2572 D BluetoothAdapterService: handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED
01-09 19:27:52.253  2572  2572 I bt_btif : enable: start restricted = 0
01-09 19:27:52.253  2572  2591 I bt_stack_manager: event_start_up_stack is bringing up the stack
01-09 19:27:52.253  2572  2591 I bt_core_module: module_start_up Starting module &quot;btif_config_module&quot;
01-09 19:27:52.253  2572  2591 I bt_core_module: module_start_up Started module &quot;btif_config_module&quot;
01-09 19:27:52.254  2572  2591 I bt_core_module: module_start_up Starting module &quot;btsnoop_module&quot;
01-09 19:27:52.254  2572  2591 I bt_core_module: module_start_up Started module &quot;btsnoop_module&quot;
01-09 19:27:52.254  2572  2591 I bt_core_module: module_start_up Starting module &quot;hci_module&quot;
01-09 19:27:52.254  2572  2591 I bt_hci  : hci_module_start_up
01-09 19:27:52.254  2572  2607 I bt_osi_thread: run_thread: thread id 2607, thread name hci_thread started
01-09 19:27:52.255  2572  2607 I bt_hci  : hci_initialize
01-09 19:27:52.255  2572  2591 D bt_hci  : hci_module_start_up starting async portion
01-09 19:27:52.256   201   201 W hwservicemanager: getTransport: Cannot find entry android.hardware.bluetooth@1.0::IBluetoothHci/default in either framework or device manifest.
01-09 19:27:52.257  2572  2607 D vndksupport: Loading /vendor/lib/hw/android.hardware.bluetooth@1.0-impl.so from current namespace instead of sphal namespace.
01-09 19:27:52.262  2572  2607 I bt_hci  : hci_initialize: IBluetoothHci::getService() returned 0xa9a4e3c0 (local)
01-09 19:27:52.262  2572  2607 I android.hardware.bluetooth@1.0-impl: BluetoothHci::initialize()
01-09 19:27:52.264  2572  2607 I bt_vendor: bt-vendor : init
01-09 19:27:52.264  2572  2607 D android.hardware.bluetooth@1.0-impl: Open vendor library loaded
01-09 19:27:52.264  2572  2607 I bt_hwcfg: Starting hciattach daemon
01-09 19:27:52.264  2572  2607 I bt_hwcfg: try to set true
01-09 19:27:52.641   841   841 D ServiceStateProvider: subId=1
01-09 19:27:53.502   514   883 I WifiService: startScan uid=10008
01-09 19:27:53.503   261   261 W wificond: Copy constructor is only used for unit tests
01-09 19:27:53.504   261   261 W wificond: Failed to get NL80211_ATTR_EXT_FEATURES
01-09 19:27:53.504   261   261 W wificond: Copy constructor is only used for unit tests
01-09 19:27:53.504   261   261 W wificond: Failed to get NL80211_ATTR_EXT_FEATURES
01-09 19:27:53.505   261   261 W wificond: Copy constructor is only used for unit tests
01-09 19:27:53.505   261   261 W wificond: Failed to get NL80211_ATTR_EXT_FEATURES
01-09 19:27:54.164   514   880 D WificondControl: Scan result ready event
01-09 19:27:54.186   514  2061 I ActivityManager: Killing 1736:com.google.android.onetimeinitializer/u0a38 (adj 906): empty #17
01-09 19:27:54.198   514   536 W libprocessgroup: kill(-1736, 9) failed: No such process
01-09 19:27:54.239   514   536 W libprocessgroup: kill(-1736, 9) failed: No such process
01-09 19:27:54.264   220   220 I Zygote  : Process 1736 exited due to signal (9)
01-09 19:27:54.284   514   536 W libprocessgroup: kill(-1736, 9) failed: No such process
01-09 19:27:54.284   514   536 I libprocessgroup: Successfully killed process cgroup uid 10038 pid 1736 in 86ms
01-09 19:27:54.576   514   514 I GnssLocationProvider: WakeLock acquired by sendMessage(SUBSCRIPTION_OR_SIM_CHANGED, 0, null)
01-09 19:27:54.591   514   880 I WifiService: WifiService trying to set country code to jp
01-09 19:27:54.591   514   880 I WifiService: setCountryCode uid=1001
01-09 19:27:54.601   514  1893 D AlarmManagerService: Kernel timezone updated to -540 minutes west of GMT
01-09 19:27:54.607   514   525 D AlarmManagerService: Kernel timezone updated to -540 minutes west of GMT
01-09 19:27:54.620   514   532 I GnssLocationProvider: WakeLock released by handleMessage(SUBSCRIPTION_OR_SIM_CHANGED, 0, null)
01-09 19:27:54.626   841   841 D ServiceStateProvider: subId=1
01-09 19:27:54.658   841   841 D CallNotifier: updatePhoneStateListeners: update CF notifications.
01-09 19:27:54.658   841   841 I NotificationMgr: updateCfi: subId= 1, visible=N
01-09 19:27:54.659   841   841 W NotificationMgr: Called updateMwi() on non-voice-capable device! Ignoring...
01-09 19:27:54.660   841   841 I TelecomFramework: PstnIncomingCallNotifier: Unregistering: Handler (com.android.internal.telephony.GsmCdmaPhone) {b503d98}
01-09 19:27:54.677   514   883 W Telecom : : registerPhoneAccount not allowed on non-voice capable device.: TSI.rPA@ADY
01-09 19:27:54.678   841   841 I TelecomFramework: AccountEntry: Registered phoneAccount: [\[ ] PhoneAccount: ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, *\*\*, UserHandle{0} Capabilities: CallProvider MultiUser PlaceEmerg SimSub  Audio Routes: BESW Schemes: tel voicemail  Extras: Bundle[{android.telecom.extra.SUPPORTS_VIDEO_CALLING_FALLBACK=true}] GroupId: *\*\*\] with handle: ComponentInfo{com.android.phone/com.android.services.telephony.TelephonyConnectionService}, *\*\*, UserHandle{0}
01-09 19:27:54.678   841   841 I TelecomFramework: PstnIncomingCallNotifier: Registering: Handler (com.android.internal.telephony.GsmCdmaPhone) {b503d98}
01-09 19:27:54.688   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.688   841   841 D TelephonyProvider: getPreferredApnIdFromApn: for subId 1
01-09 19:27:54.695   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.701   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.701   841   841 D TelephonyProvider: getPreferredApnIdFromApn: for subId 1
01-09 19:27:54.707   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.708   841   841 D TelephonyProvider: getPreferredApnIdFromApn: for subId 1
01-09 19:27:54.714   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.714   841   841 D TelephonyProvider: getPreferredApnIdFromApn: for subId 1
01-09 19:27:54.721   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.721   841   841 D TelephonyProvider: getPreferredApnIdFromApn: for subId 1
01-09 19:27:54.726   228   228 E WifiHAL : wifi_get_link_stats: requestResponse Error:-3
01-09 19:27:54.726   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.728   514   656 E WifiVendorHal: getWifiLinkLayerStats(l.937) failed {.code = ERROR_NOT_SUPPORTED, .description = }
01-09 19:27:54.736   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.736   841   841 D TelephonyProvider: getPreferredApnIdFromApn: for subId 1
01-09 19:27:54.741   841   860 W System  : A resource failed to call close.
01-09 19:27:54.741   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.741   841   841 D TelephonyProvider: getPreferredApnIdFromApn: for subId 1
01-09 19:27:54.749   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.755   841   841 D TelephonyProvider: subIdString = 1 subId = 1
01-09 19:27:54.755   841   841 D TelephonyProvider: getPreferredApnIdFromApn: for subId 1
01-09 19:27:54.764   841   841 I TelecomFramework: PstnPhoneCapabilitiesNotifier: handleVideoCapabilitesChanged. Video capability - false
01-09 19:27:54.780   514  1393 W Telecom : : registerPhoneAccount not allowed on non-voice capable device.: TSI.rPA@ADk
01-09 19:27:54.812   223   223 I healthd : type=1400 audit(0.0:122): avc: denied { read } for name=&quot;present&quot; dev=&quot;sysfs&quot; ino=13630 scontext=u:r:healthd:s0 tcontext=u:object_r:sysfs:s0 tclass=file permissive=1
01-09 19:27:54.881   514   880 D AlarmManagerService: Kernel timezone updated to -540 minutes west of GMT
01-09 19:27:56.191  2076  2090 W System  : A resource failed to call release.
01-09 19:27:56.192   226  2233 E WVCdm   : App requested unknown byte array property metrics
01-09 19:27:56.231  2572  2590 E AdapterState: BLE_TURNING_ON : BLE_START_TIMEOUT
01-09 19:27:56.231  2572  2590 I AdapterState: BLE_TURNING_OFF : entered
01-09 19:27:56.231  2572  2590 D AdapterProperties: Setting state to BLE_TURNING_OFF
01-09 19:27:56.231  2572  2590 D BluetoothAdapterService: updateAdapterState() - Broadcasting state BLE_TURNING_OFF to 1 receivers.
01-09 19:27:56.232   514   543 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: BLE_TURNING_ON &amp;gt; BLE_TURNING_OFF
01-09 19:27:56.232   514   543 D BluetoothManagerService: Sending BLE State Change: BLE_TURNING_ON &amp;gt; BLE_TURNING_OFF
01-09 19:27:56.233  2572  2590 D AdapterProperties: onBleDisable
01-09 19:27:56.236  2572  2572 D BtGatt.DebugUtils: handleDebugAction() action=null
01-09 19:27:56.240  2572  2572 D BluetoothAdapterService: handleMessage() - Message: 1
01-09 19:27:56.240  2572  2572 D BluetoothAdapterService: handleMessage() - MESSAGE_PROFILE_SERVICE_STATE_CHANGED
01-09 19:27:56.240  2572  2572 D BluetoothAdapterService: handleMessage() - Message: 3
01-09 19:27:56.240  2572  2572 D BluetoothAdapterService: handleMessage() - MESSAGE_PROFILE_SERVICE_UNREGISTERED
01-09 19:27:56.241  2572  2572 W         : [0109/192756.241008:WARNING:bta_gattc_api.cc(61)] GATTC Module not enabled/already disabled
01-09 19:27:56.241  2572  2572 W         : [0109/192756.241160:WARNING:bta_gatts_api.cc(56)] GATTS Module not enabled/already disabled
01-09 19:27:56.241  2572  2590 I AdapterState: OFF : entered
01-09 19:27:56.241  2572  2590 D AdapterProperties: Setting state to OFF
01-09 19:27:56.241  2572  2590 D BluetoothAdapterService: updateAdapterState() - Broadcasting state OFF to 1 receivers.
01-09 19:27:56.242   514   543 D BluetoothManagerService: MESSAGE_BLUETOOTH_STATE_CHANGE: BLE_TURNING_OFF &amp;gt; OFF
01-09 19:27:56.242   514   543 D BluetoothManagerService: Bluetooth is complete send Service Down
01-09 19:27:56.242   514   543 D BluetoothManagerService: Broadcasting onBluetoothServiceDown() to 5 receivers.
01-09 19:27:56.242   514   543 D BluetoothAdapter: onBluetoothServiceDown: android.bluetooth.IBluetooth$Stub$Proxy@f61ad32
01-09 19:27:56.242  2572  2584 D BluetoothAdapter: onBluetoothServiceDown: com.android.bluetooth.btservice.AdapterService$AdapterServiceBinder@4dfa26d
01-09 19:27:56.242   514   543 D BluetoothManagerService: unbindAndFinish(): android.bluetooth.IBluetooth$Stub$Proxy@f61ad32 mBinding = false mUnbinding = false
01-09 19:27:56.243   729  1019 D BluetoothAdapter: onBluetoothServiceDown: android.bluetooth.IBluetooth$Stub$Proxy@a9eb792
01-09 19:27:56.244   841   874 D BluetoothAdapter: onBluetoothServiceDown: android.bluetooth.IBluetooth$Stub$Proxy@58b882b
01-09 19:27:56.244  1130  1154 D BluetoothAdapter: onBluetoothServiceDown: android.bluetooth.IBluetooth$Stub$Proxy@b1e56ed
01-09 19:27:56.245   514   543 D BluetoothManagerService: Sending BLE State Change: BLE_TURNING_OFF &amp;gt; OFF
01-09 19:27:56.245   514   543 D BluetoothManagerService: Entering STATE_OFF but mEnabled is true; restarting.
01-09 19:27:56.245   514   543 E BluetoothManagerService: waitForOnOff time out
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: exception when invoking removeOnUidImportanceListener
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: java.lang.IllegalArgumentException: Listener not registered: com.android.bluetooth.gatt.ScanManager$2@11869ab
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at android.app.ActivityManager.removeOnUidImportanceListener(ActivityManager.java:3552)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at com.android.bluetooth.gatt.ScanManager.cleanup(ScanManager.java:157)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at com.android.bluetooth.gatt.GattService.cleanup(GattService.java:244)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at com.android.bluetooth.btservice.ProfileService.onDestroy(ProfileService.java:211)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at android.app.ActivityThread.handleStopService(ActivityThread.java:3735)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at android.app.ActivityThread.access$1700(ActivityThread.java:200)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1693)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at android.os.Handler.dispatchMessage(Handler.java:106)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at android.os.Looper.loop(Looper.java:193)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at android.app.ActivityThread.main(ActivityThread.java:6718)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at java.lang.reflect.Method.invoke(Native Method)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
01-09 19:27:56.245  2572  2572 W BtGatt.ScanManager: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: exception when invoking unregisterReceiver(mLocationReceiver)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: java.lang.IllegalArgumentException: Receiver not registered: com.android.bluetooth.gatt.ScanManager$3@cd94808
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:1271)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1504)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:659)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at com.android.bluetooth.gatt.ScanManager.cleanup(ScanManager.java:178)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at com.android.bluetooth.gatt.GattService.cleanup(GattService.java:244)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at com.android.bluetooth.btservice.ProfileService.onDestroy(ProfileService.java:211)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at android.app.ActivityThread.handleStopService(ActivityThread.java:3735)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at android.app.ActivityThread.access$1700(ActivityThread.java:200)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1693)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at android.os.Handler.dispatchMessage(Handler.java:106)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at android.os.Looper.loop(Looper.java:193)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at android.app.ActivityThread.main(ActivityThread.java:6718)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at java.lang.reflect.Method.invoke(Native Method)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
01-09 19:27:56.246  2572  2572 W BtGatt.ScanManager: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
01-09 19:27:56.247  2572  2572 D BluetoothAdapterService: onUnbind() - calling cleanup
01-09 19:27:56.247  2572  2572 D BluetoothAdapterService: cleanup()
01-09 19:27:56.249  2572  2572 W BluetoothSdpJni: Cleaning up Bluetooth SDP Interface...
01-09 19:27:56.249  2572  2572 W BluetoothSdpJni: Cleaning up Bluetooth SDP object
01-09 19:27:56.249  2572  2572 D BluetoothAdapterService: cleanup() - Cleaning up adapter native
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;WiFiに繋げて、設定するところを後回しにしたらホーム画面まで行くことが出来ました。&lt;/li&gt;
&lt;li&gt;Google Play Storeでインストールしようと、Googleアカウントを入力して同期が始まるところで詰まる。ネットワーク周りが調子悪い様子。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;諦めて、Android 8に戻します。。。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;→&lt;/strong&gt;「Android」と表示されて起動しなくなってしまったので、一度ファクトリーのイメージを書き込む。&lt;/li&gt;
&lt;li&gt;→起動しない。。。ハードウェアが壊れたっぽい。文鎮になってしまった。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;補足&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Android 9のflo（WiFi用）はあるようです。2019年1月2日に作られた模様。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://forum.xda-developers.com/showpost.php?p=78575088&amp;amp;postcount=1811&quot;&gt;https://forum.xda-developers.com/showpost.php?p=78575088&amp;amp;postcount=1811&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>rm -rf / を実行してみる</title><link>https://blog.teraren.com/posts/rm-rf-linux/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rm-rf-linux/</guid><description>rm -rf / を実行してみる</description><pubDate>Wed, 09 Jan 2019 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;最近は、&lt;code&gt;rm -rf&lt;/code&gt; が実行出来ないという書き込みを見つけたので実験してみます。&lt;/li&gt;
&lt;li&gt;仮想コンテナのおかげで、実験環境が1秒で立ち上がるので楽です。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% docker run --rm -it ubuntu bash
root@76448df2b47f:/# rm -rf /
rm: it is dangerous to operate recursively on &apos;/&apos;
rm: use --no-preserve-root to override this failsafe
root@76448df2b47f:/#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;確かに、実行出来ないですね。このオプションを付けないと実行出来ないようです。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;--no-preserve-root&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@76448df2b47f:/# rm -rf / --no-preserve-root
rm: cannot remove &apos;/etc/resolv.conf&apos;: Device or resource busy
rm: cannot remove &apos;/etc/hostname&apos;: Device or resource busy
rm: cannot remove &apos;/etc/hosts&apos;: Device or resource busy
たくさん出力されたので省略
root@76448df2b47f:/# ls
bash: /bin/ls: No such file or directory
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;無事に消えて、主要なコマンドが消えてしまって何も実行出来なくなってしまいました。&lt;/li&gt;
&lt;li&gt;shellのビルトインコマンドは利用出来ます。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Chrome 70からExtension無しでスクリーンキャストができます</title><link>https://blog.teraren.com/posts/chrome-70-screen-sharing/</link><guid isPermaLink="true">https://blog.teraren.com/posts/chrome-70-screen-sharing/</guid><description>Chrome 70からExtension無しでスクリーンキャストができます</description><pubDate>Fri, 21 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Chromeから、extensionをインストールすることなく画面共有を出来るようになりました。&lt;a href=&quot;https://www.chromestatus.com/feature/6744724455030784&quot;&gt;source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;MediaStream.getDisplayMedia() メソッドを呼ぶと、Chromeがユーザに画面を共有するかどうかのパーミッションを求める画面が表示されます。&lt;/p&gt;
&lt;p&gt;Chrome 70以降で、&lt;a&gt;chrome://flags#enable-experimental-web-platform-features&lt;/a&gt;にアクセスして、&quot;Enable Experimental Web Platform Features&quot; フラグを&quot;Enabled&quot; にします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/12/Screen-Shot-2018-12-21-at-15.13.28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Experimental Web Platform features&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/12/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Chromeがこんな感じでどのスクリーンを共有するのかを聞いてきます。&lt;/p&gt;
&lt;p&gt;設定を反映するためにはブラウザ自体の再起動が必要になります。&lt;/p&gt;
&lt;h3&gt;追記&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Chrome M72 で getMediaDisplay が利用できるようになる。これで Chrome 拡張なしで画面共有が利用可能になる。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/voluntas/59a135343538c290e515#chrome-1&quot;&gt;https://gist.github.com/voluntas/59a135343538c290e515#chrome-1&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;M72は2019年1月29日にリリース予定&lt;/p&gt;
&lt;p&gt;2019年1月30日追記：Chrome 72が出ました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/12/Screen-Shot-2019-01-30-at-11.44.12.png&quot; alt=&quot;Chrome 72&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>WordPress 5.0にアップグレードしてみました</title><link>https://blog.teraren.com/posts/worespres5/</link><guid isPermaLink="true">https://blog.teraren.com/posts/worespres5/</guid><description>自動更新でWordPress5.0に上がった体験談。新エディタGutenbergの使い勝手、Markdownとの相性の悪さ、wp coreコマンドのメジャーアップデート制御不可の問題を解説。</description><pubDate>Sun, 16 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/12/Screen-Shot-2018-12-12-at-22.01.17.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WordPress 5.0 Upgrade&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;WordPress5に上がってしまった&lt;/h2&gt;
&lt;p&gt;WordPress5に上げたくてあげたのでは無く、勝手に上がってしまったのです。&lt;/p&gt;
&lt;p&gt;なぜなら、運用しているブログが10個ぐらいあり、それぞれをセキュリティアップグレードするのが面倒 &amp;amp;&amp;amp; ゼロデイアタックを防ぐために毎日自動でWordPress coreをアップグレードするようにしているためです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wp core update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;本来ならもう少し落ち着いてからアップグレードしたかった。wp coreコマンドにはメジャーアップデートは防ぐようなオプションが無いから仕方が無いです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ wp core
usage: wp core check-update [--minor] [--major] [--field=] [--fields=] [--format=]
   or: wp core download [--path=] [--locale=] [--version=] [--skip-content] [--force]
   or: wp core install --url= --title= --admin_user= [--admin_password=] --admin_email= [--skip-email]
   or: wp core is-installed [--network]
   or: wp core multisite-convert [--title=] [--base=] [--subdomains]
   or: wp core multisite-install [--url=] [--base=] [--subdomains] --title= --admin_user= [--admin_password=] --admin_email= [--skip-email] [--skip-config]
   or: wp core update [] [--minor] [--version=] [--force] [--locale=]
   or: wp core update-db [--network] [--dry-run]
   or: wp core version [--extra]
See &apos;wp help core &apos; for more information on a specific command.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Markdownが使いづらくなった&lt;/h2&gt;
&lt;p&gt;WordPress5の大きな違いはGutenbergというエディティング画面です。これは今までと全然違った編集画面を提供してくれています。慣れないと使いづらいけれど、今までとは違った新たな段組みやレイアウトなどの機能などが追加されていて自由度が高いレイアウトを作れそうです。&lt;/p&gt;
&lt;p&gt;Markdownに関して言えば、GutenbergにはCode Editorというモードがあって、HTMLモードみたいな物なのですがこれでMarkdownを書こうかと思っていましたが、Gutenburgが生成するコードがHTMLに似たDSLみたいなものを生成するので相性が悪そうです。&lt;/p&gt;
&lt;p&gt;過去にMarkdownで綺麗に構造化して書いていた記事は実はDB上ではHTMLで保存されていた模様です。過去の記事を見ると普通にHTMLで表示されます。&lt;/p&gt;
&lt;p&gt;大きな流れには乗った方が良いと思うのでMarkdownで記事を書くというマイノリティな考えは捨てようと思います。Gutenberg上でオリジナルのブロックを作るときにMarkdown用のブロックを作ればMarkdownで書けますがなかなか面倒です。&lt;/p&gt;
&lt;p&gt;参考までに、以下のような画面で執筆しています。スクリーンショットのコピペがGrab &amp;amp; Saveプラグイン不要で出来るようになって便利です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;img src=&quot;../../assets/uploads/2018/12/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;レスポンスが速くなった気がする&lt;/h2&gt;
&lt;p&gt;このブログはフロントエンド側は静的HTMLでキャッシュしているので高速にサーバから返却されていると思います。&lt;/p&gt;
&lt;p&gt;逆に管理画面側はキャッシュ出来ないのでサーバからのレスポンスは遅めです。しかしながら、WordPress5になってからは全体的に体感でレンダリング完了まで2割ほど速い気がします。地味にうれしい。&lt;/p&gt;
</content:encoded></item><item><title>Google Pixel 3を買ってiPhone XSと比較</title><link>https://blog.teraren.com/posts/google-pixel3-vs-iphone-xs/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-pixel3-vs-iphone-xs/</guid><description>Google Pixel 3とiPhone XSを実際に使い比較。夜景撮影の明るさ差異、車載クレードル利用時のアンロック方式の優劣、Android 9のUX改善など個人的視点でレビュー。</description><pubDate>Tue, 04 Dec 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;iPhoneXSとPixel 3の比較&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.apple.com/jp/iphone-xs/&quot;&gt;iPhone XS&lt;/a&gt;を持っていましたが、Pixel 3の評判が良いので買ってみました。&lt;/li&gt;
&lt;li&gt;スペック上でわかる比較は比較サイトにお任せして、ここでは個人的な視点で違いを見ます&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1. 液晶のコントラストの違い&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Pixel3の液晶パネルは&lt;strong&gt;鮮やか&lt;/strong&gt;に味付けされています。使い出したときは、撮った写真の発色が良くて驚きましたが、しばらく使っていると画面に映る全ての映像の発色が良い事に気づきました。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pixel3で撮影した夜景の写真が明るい&lt;/strong&gt;という評判のTweetがよく見られます。色々実験してみると、その理由がわかりました。明るさに関して言えばPixel3が全体的にiOSに比べて1段階高いISO（光の感度）で撮影されているためです。Pixel3, iPhone XSともに常用感度がわからないので限界値はわかりませんが普通の夜景には十分の感度です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/12/img_5c05d542c5273.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;光学レンズのスペックはほぼ同等。左がPixel3右がiPhone XSです。あとはソフトウェア部分の処理が違うということになります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;以下に同条件で撮影した写真を掲載しておきます。露出だけ補正してます。
&lt;ul&gt;
&lt;li&gt;それぞれ、どっちのカメラで撮ったかは記事の一番下に書いておきます。&lt;/li&gt;
&lt;li&gt;左下の建物が下の写真では明るく写っています。HDRが強めに効いている感じ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/12/img_5c060b1d5de3d.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pixel3 VS iPhone XS Camera in night sight.&lt;/p&gt;
&lt;h2&gt;2. アンロック方法の違い&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;車での利用時に大きな違いが出ます。&lt;/li&gt;
&lt;li&gt;車ではスマホクレードルに置いて、Google Mapsでナビゲーションしたり、音楽を再生するようなユースケースで利用しています。&lt;/li&gt;
&lt;li&gt;Pixel3は一度ロックされると指紋認証がPixel本体の裏にあるので指紋を使ってアンロックが難しいです。よって、クレードルに置いているときはパスコードによるアンロックが基本になります。&lt;/li&gt;
&lt;li&gt;iPhoneXSの顔認証は顔が暗いと反応しないので辛いです。理想はiPhone8までの画面前側に付いている指紋センサー。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/12/img_5c07825fec539.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Pixel3 指紋センサ&lt;/p&gt;
&lt;h2&gt;3. UI/UXの違い&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/12/android-p-new-system-navigation-0.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Android 9.0 Pieになり、かなりUXが良くなりました。iOSで実現しているUXがほとんど行えるようになりました。&lt;/p&gt;
&lt;p&gt;いままでiOSに慣れていたこともあり、ちょっと慣れるまで時間がかかりそうでしたが、慣れれば不便は無さそうです。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;比較サイトに書いてあるので書きませんでしたが、Pixel3の軽さはかなり魅力的でした。&lt;/li&gt;
&lt;li&gt;ここには書き切れない小さな点でPixel3の魅力も多く、メイン機をPixel3にするか、iPhone XSにするか1週間ぐらい悩みました。&lt;/li&gt;
&lt;li&gt;答え：サンプルの写真は、上がiPhone XSで、下がGoogle Pixel 3です。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>SES -&gt; SNS -&gt; SQS -&gt;  Lambda -&gt; DynamoDB</title><link>https://blog.teraren.com/posts/ses-sns-sqs-lambda-dynamodb/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ses-sns-sqs-lambda-dynamodb/</guid><description>AWSでSESのバウンス・クレームメールを適切に処理するアーキテクチャ。SES→SNS→SQS→Lambda→DynamoDBのパイプライン設定とLambdaコードを紹介。</description><pubDate>Mon, 26 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AWS SESを使いだすのは簡単ですが、エラーメールや、クレーム、バウンスなどを適切に処理しないとSES上のエラーレートが上がってしまうので対策をする設定です。&lt;/li&gt;
&lt;li&gt;このあたりを参考にしながら
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://qiita.com/zaru/items/4be9b55ba807670cf224&quot;&gt;https://qiita.com/zaru/items/4be9b55ba807670cf224&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下は、スクリーンショットをメインに適当にメモ書きです&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/11/img_5bf41f70e1a86.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/11/img_5bf422168c4c6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/11/img_5bf421fca333d.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/11/img_5bf41fdfa9ada.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/11/img_5bf41fab764b1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const AWS = require(&apos;aws-sdk&apos;);
const documentClient = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event, context, callback) =&amp;gt; {

  const tableName = &apos;ses_complaint&apos;;

  // event[&quot;Records&quot;][0][&quot;ses&quot;][&quot;mail&quot;][&quot;commonHeaders&quot;][&quot;messageId&quot;];
  var message_id = (new Date).getTime().toString();

  Object.assign(event, { id: message_id });

  var params = {
    TableName: tableName,
    Item: event
  };

  await documentClient.put(params).promise();
};
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ aws --profile minedia --region us-east-1 ses send-email \
  --to complaint@simulator.amazonses.com --from mymailaddress@minedia.com \
  --subject &quot;complaint&quot; \
  --text &quot;ses mail complaint body&quot;

$ aws --profile minedia --region us-east-1 ses send-email \
  --to bounce@simulator.amazonses.com --from mymailaddress@minedia.com \
  --subject &quot;bounce&quot; \
  --text &quot;ses mail bounce body&quot;

$ aws --profile minedia --region us-east-1 ses send-email \
  --to success@simulator.amazonses.com --from mymailaddress@minedia.com \
  --subject &quot;success&quot; \
  --text &quot;ses mail bounce body&quot;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>PHPでIPv6か判定</title><link>https://blog.teraren.com/posts/php-ipv6-ipv4/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-ipv6-ipv4/</guid><description>PHPでIPv6か判定</description><pubDate>Sat, 24 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;filter_var($_SERVER[&apos;REMOTE_ADDR&apos;], FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? &apos;IPv6&apos; : &apos;IPv4&apos;;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>So-netから配られたDNSサーバがAAAAレコードを返してくれない</title><link>https://blog.teraren.com/posts/so-net-ipv6/</link><guid isPermaLink="true">https://blog.teraren.com/posts/so-net-ipv6/</guid><description>So-netのIPv6回線でAAAAレコードが返らない問題の調査記録。プロバイダ配布のDNSサーバがAAAA問い合わせに対応していない原因を特定し、DNSサーバ変更で解決した手順を紹介。</description><pubDate>Sat, 24 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;回線はIPv6にしたのに、なぜかIPv6でサーバに繋がらなかったので調査。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat /etc/resolv.conf
search flets-east.jp iptvf.jp
nameserver 240b:11:4a60:b600::1
nameserver 192.168.3.1
nameserver 1.1.1.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DHCPでプロバイダから配られたDNSサーバを使うようにしていた。しかしながら、このDNSサーバがAAAAレコードの問い合わせに反応してくれない。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% host -t aaaa awsblog.teraren.com  240b:11:4a60:b600::1
Using domain server:
Name: 240b:11:4a60:b600::1
Address: 240b:11:4a60:b600::1#53
Aliases:

awsblog.teraren.com has no AAAA record
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;他のpublic DNSはちゃんと返してくれる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% host -t aaaa  awsblog.teraren.com 1.1.1.1
Using domain server:
Name: 1.1.1.1
Address: 1.1.1.1#53
Aliases:

awsblog.teraren.com has IPv6 address 2406:da14:e67:4500:9d34:aba7:1c9e:aad8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;他のドメインのAAAAレコードを返してくれるのかをテスト。返してくれない。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% host -t aaaa google.com  240b:11:4a60:b600::1
Using domain server:
Name: 240b:11:4a60:b600::1
Address: 240b:11:4a60:b600::1#53
Aliases:

google.com has no AAAA record
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そもそも、このDNSサーバへの接続はIPv6で行ってないからDNSフィルタをされてしまっているのかも。。。調べられないので調査出来ず。&lt;/p&gt;
&lt;p&gt;ということで、ローカルネットワークで利用するDNSキャッシュサーバのアドレスを変えたら無事にIPv6で繋がった模様。&lt;a href=&quot;https://kakunin.teraren.com/&quot;&gt;確認君&lt;/a&gt;もIPv6対応済み。IPv6かどうかを表示するようにした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/11/img_5bf910530fd8c.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;まぁ、加入する家が&lt;a href=&quot;http://www.nuro.jp/campaign/rmd/?recomndNo=dfs84206&quot;&gt;nuro&lt;/a&gt;に対応してなかったから仕方なくSo-netですが本来は、&lt;a href=&quot;http://www.nuro.jp/campaign/rmd/?recomndNo=dfs84206&quot;&gt;nuro&lt;/a&gt;が良い。&lt;/p&gt;
</content:encoded></item><item><title>Google APIのOAuth2に関連したトークンの扱い方法とシーケンス</title><link>https://blog.teraren.com/posts/google-api-oauth2-sequence/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-api-oauth2-sequence/</guid><description>Google APIのOAuth2認証フローをシーケンス図で解説し、authorization code・access token・refresh tokenの取得タイミングと安全な管理方法をまとめた記事</description><pubDate>Thu, 22 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Using OAuth 2.0 to Access Google APIsにシーケンスがかいてあります。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/identity/protocols/OAuth2&quot;&gt;https://developers.google.com/identity/protocols/OAuth2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/11/webflow.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上記のシーケンスはシンプルすぎて、重要なシーケンスとアクターが漏れているので、もう少し細かくシーケンス図を書き直しました。&lt;/li&gt;
&lt;li&gt;特に、&lt;code&gt;refresh token&lt;/code&gt;の取得方法と、取得タイミング、保存タイミングなどの情報がアプリケーション開発者がアプリケーションを設計する上で重要なのですが、オフィシャルドキュメントでは網羅されていませんでした。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;シーケンス図&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/11/img_5bf676d5c8596.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;用語の整理&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;authorization code&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;認証コード&lt;/li&gt;
&lt;li&gt;これを元に、&lt;code&gt;refresh token&lt;/code&gt;と&lt;code&gt;access token&lt;/code&gt;を交換する。取得したら&lt;code&gt;authorization code&lt;/code&gt;は無効になる。&lt;/li&gt;
&lt;li&gt;ユーザが承認した直後にしか使わない。&lt;/li&gt;
&lt;li&gt;expireする。Googleでは時間の記載は無いけど、Facebookでは&lt;a href=&quot;https://developers.facebook.com/docs/graph-api/changelog/archive/migrations&quot;&gt;10分&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;4番のシーケンスにおける、&lt;code&gt;code&lt;/code&gt; パラメータで取得出来る。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;access token&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;API呼び出しに使うトークン。&lt;/li&gt;
&lt;li&gt;レスポンスを見ていると、Googleでは3600秒（=60分）でexpireするトークンが発行されている。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;refresh token&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;基本的には、アプリケーション側で永続化しておく。&lt;/li&gt;
&lt;li&gt;expireはしない。ユーザ側でrevokeできる。&lt;/li&gt;
&lt;li&gt;無効になってしまったら&lt;code&gt;authorization code&lt;/code&gt;から生成する必要がある。そのために、ユーザに再び承認をもらう必要がある。この時点では&lt;code&gt;authorization code&lt;/code&gt;は存在していないはずなので。&lt;/li&gt;
&lt;li&gt;大事に保存しておく必要がある。このcredentialとアプリ情報が第三者に漏れると、権限を乱用出来てしまう。&lt;/li&gt;
&lt;li&gt;漏れた場合は、Googleに登録したアプリをのcredentialをリセットする必要があるので、他のユーザにも影響するため厳重に管理する必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;メモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;expirationやトークンのライフサイクルに関してはこの辺りが情報ソース。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/identity/protocols/OAuth2&quot;&gt;https://developers.google.com/identity/protocols/OAuth2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;authorization tokenを再発行するためには、自分のGoogleのSecurity&amp;amp;Privacyページに手アプリの認証をrevokeする必要がある。
&lt;ul&gt;
&lt;li&gt;そうじゃないと、新しいaccess_tokenが発行されるだけで、認証情報はリセットされない。&lt;/li&gt;
&lt;li&gt;アプリ側で生成する認証ページのURLのパラメータを変更したときには、revokeしなければ、前回と同じパラメータの認証情報のままaccess tokenなどが生成されてしまうので注意。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ソースコード&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;rubyのコードで主要なコードスニペットを書いておきます。&lt;/li&gt;
&lt;li&gt;わかりやすいように値の例も書いておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;refresh token&lt;/code&gt;を取得できる、&lt;code&gt;authorization code&lt;/code&gt;を取得するコード。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;client = Signet::OAuth2::Client.new({
  client_id: ENV.fetch(&apos;GOOGLE_API_CLIENT_ID&apos;),
  client_secret: ENV.fetch(&apos;GOOGLE_API_CLIENT_SECRET&apos;),
  authorization_uri: &apos;https://accounts.google.com/o/oauth2/auth&apos;,
  scope: [Google::Apis::GmailV1::AUTH_GMAIL_READONLY, &apos;email&apos;],
  redirect_uri: &apos;http://localhost:3000/callback&apos;,
  access_type: &apos;offline&apos;, # need this to get refresh_token.
})

# ex:
# http://localhost:3000/callback?code=4/nQCxXval2Q8tfg0StBx81vcILZU7kEp9BMkGq27geFsSJU3fOQ8c_dMz5VW_hySmXVq0BWtJ_lopkUk66u8ZoCx&amp;amp;scope=openid+email+https://www.googleapis.com/auth/plus.me+https://www.googleapis.com/auth/gmail.readonly+https://www.googleapis.com/auth/userinfo.email
client.authorization_uri.to_s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;authorization code&lt;/code&gt;から&lt;code&gt;refresh token&lt;/code&gt;と&lt;code&gt;access token&lt;/code&gt;を取得するコード。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;client = Signet::OAuth2::Client.new({
  client_id: ENV.fetch(&apos;GOOGLE_API_CLIENT_ID&apos;),
  client_secret: ENV.fetch(&apos;GOOGLE_API_CLIENT_SECRET&apos;),
  token_credential_uri: &apos;https://oauth2.googleapis.com/token&apos;,
})

client.code = &quot;[authorization code]&quot;
access_token_hash = client.fetch_access_token!

# ex:
# ya29.GltcBh5BsH71zSz3HI_NCTTyn2W5gfn3eVUXoQU3sHkMxF-Tu3x1gL3mZSNFM_HIglSz8oKiVj-vgFB1td-UzdXaKbutynonpws-dsG4l1mnudwFiZv9Dku8Hb-X
access_token_hash[&apos;access_token&apos;]

# ex:
# 1/L8qZrV5S88vOmRd9WVWxAmv4c8QJB9lMf9mqnfkZkVk
access_token_hash[&apos;refresh_token&apos;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;refresh token&lt;/code&gt;を使って、&lt;code&gt;access token&lt;/code&gt;を取得する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;client = Signet::OAuth2::Client.new({
  client_id: ENV.fetch(&apos;GOOGLE_API_CLIENT_ID&apos;),
  client_secret: ENV.fetch(&apos;GOOGLE_API_CLIENT_SECRET&apos;),
  token_credential_uri: &apos;https://oauth2.googleapis.com/token&apos;,
})

client.refresh_token = &apos;[refresh_token]&apos;
access_token_hash = client.fetch_access_token!

# ex:
# ya29.GltcBhsO9iH4fWJITG3chjNrki5vk0M1I-bFcjTsHW2Ln4CBRZjT-eGBSlf_Qa4MewfWxsrU_s-DMb4AwOrkFpgUuGegStiGKKZkiazoPU5c3JUihNzOTcdJeKKX
access_token_hash[&apos;access_token&apos;]
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Google::Apis::GmailV1の主要オブジェクト図</title><link>https://blog.teraren.com/posts/google-apis-gmailv1-object/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-apis-gmailv1-object/</guid><description>Google::Apis::GmailV1の主要オブジェクト図</description><pubDate>Thu, 22 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rubydoc.info/github/google/google-api-ruby-client/Google/Apis/GmailV1&quot;&gt;https://www.rubydoc.info/github/google/google-api-ruby-client/Google/Apis/GmailV1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;オブジェクトの関連性が複雑だったので図にまとめました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/04/image-7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;要点
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rubydoc.info/github/google/google-api-ruby-client/Google/Apis/GmailV1/MessagePart&quot;&gt;MessagePart&lt;/a&gt;は再帰で1:nを保持している&lt;/li&gt;
&lt;li&gt;重要なデータが入っているクラスとそのプロパティ&lt;/li&gt;
&lt;li&gt;Array[MessaegPartBody] MessaegPart.parts&lt;/li&gt;
&lt;li&gt;[MessaegPartBody] MessaegPart.body&lt;/li&gt;
&lt;li&gt;[Array] MessaegPart.headers&lt;/li&gt;
&lt;li&gt;件名
&lt;ul&gt;
&lt;li&gt;[String] MessagePartHeaderのnameがsubjectのvalue&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[String] MessaegPartBody.data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;感想&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Subjectが入っているクラスが深い所にあるので取得するのが大変。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>mysqlにてユーザを追加するときのクエリーテンプレ</title><link>https://blog.teraren.com/posts/mysql-add-user-query-template/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-add-user-query-template/</guid><description>mysqlにてユーザを追加するときのクエリーテンプレ</description><pubDate>Mon, 19 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;毎回ググってクエリーを作るのが面倒なのでメモ。&lt;/li&gt;
&lt;li&gt;ユーザを作って、そのユーザはあるDBのCRUDと、スキーマのmigrationを出来るようにするという最低限の権限を付与。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;メモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;前提
&lt;ul&gt;
&lt;li&gt;ユーザ名: &lt;code&gt;newuser&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;パスワード: &lt;code&gt;password&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;DB: &lt;code&gt;newdb&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;create user newuser@&apos;%&apos; identified by &apos;password&apos;;

insert into db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, References_priv, Index_priv, Alter_priv, Lock_tables_priv)
  values(&apos;%&apos;, &apos;newdb&apos;, &apos;newuser&apos;, &apos;Y&apos;, &apos;Y&apos;, &apos;Y&apos;, &apos;Y&apos;, &apos;Y&apos;, &apos;Y&apos;, &apos;Y&apos;, &apos;Y&apos;, &apos;Y&apos;, &apos;Y&apos;);

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;反映を忘れずに&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;flush privileges;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>c5d.18xlargeを使ってみた</title><link>https://blog.teraren.com/posts/c5d-18xlarge/</link><guid isPermaLink="true">https://blog.teraren.com/posts/c5d-18xlarge/</guid><description>c5d.18xlargeを使ってみた</description><pubDate>Thu, 01 Nov 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;動画のエンコーディングを行うために、一番速いCPUを使ってみました。 気になるお値段は、on-demand AP1で4.392USD/時間。これだけのスペックのマシンを即座に利用出来て、この値段は良いね。 &lt;img src=&quot;../../assets/uploads/2018/11/img_5bda83f305a46.png&quot; alt=&quot;&quot; /&gt; 2.3GHzクアッドコアIntel Core i7（Turbo Boost使用時最大3.3GHz）、6MB三次キャッシュで1.5時間ぐらいかかっていた動画のエンコードが13分で終わった。 ロードアベレージが200越え！ &lt;img src=&quot;../../assets/uploads/2018/11/Screen-Shot-2018-10-25-at-20.02.36.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>githubのrepositoryを一括でバックアップする</title><link>https://blog.teraren.com/posts/github-repository-backup/</link><guid isPermaLink="true">https://blog.teraren.com/posts/github-repository-backup/</guid><description>githubのrepositoryを一括でバックアップする</description><pubDate>Wed, 24 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;用途：gitbucketに移行するとき等に使う。&lt;/li&gt;
&lt;li&gt;1ページ100レポジトリまでしか表示出来ないので最大100件ずつcloneする。そのために&lt;code&gt;page=1&lt;/code&gt; の数字を増加させていく。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Userのレポジトリの場合&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% curl -s -H &quot;Authorization: token &amp;lt;token&amp;gt;&quot; &apos;https://api.github.com/orgs/&amp;lt;org name&amp;gt;/repos?per_page=100&amp;amp;page=1&apos; |grep ssh_url | sed  &apos;s/.*: &quot;//g&apos; |sed &apos;s/&quot;,.*//g&apos;| xargs -n 1 git clone
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Organizationのレポジトリの場合&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% curl -s -H &quot;Authorization: token &amp;lt;token&amp;gt;&quot; &apos;https://api.github.com/users/&amp;lt;user name&amp;gt;/repos?per_page=100&amp;amp;page=1&apos; |grep ssh_url | sed  &apos;s/.*: &quot;//g&apos; |sed &apos;s/&quot;,.*//g&apos;| xargs -n 1 git clone
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>yarn.lockのコンフリクトを自動的に解消</title><link>https://blog.teraren.com/posts/yarn-lock-conflict/</link><guid isPermaLink="true">https://blog.teraren.com/posts/yarn-lock-conflict/</guid><description>git rebaseやgit pull --rebase後にyarn.lockが大量にコンフリクトした場合、yarn installコマンド一発で自動解消できることを実例とともに紹介します。</description><pubDate>Fri, 12 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;大きめフィーチャーブランチを&lt;code&gt;% git pull --rebase&lt;/code&gt;したら、&lt;code&gt;yarn.lock&lt;/code&gt;が盛大にconflictした。&lt;/li&gt;
&lt;li&gt;「やっちまったー」と思ったけど、コマンド1発で解決してくれる仕組みがあった。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;yarn install&lt;/code&gt; するだけで解決！！！！&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下のようなコンフリクトがあったけど、&lt;code&gt;yarn install&lt;/code&gt; のみで綺麗に解決できた！&lt;br /&gt;
（抜粋）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;diff --cc yarn.lock
index 59ab0fba,477b4a42..00000000
--- a/yarn.lock
+++ b/yarn.lock
@@@ -46,40 -10,53 +46,66 @@@
      esutils &quot;^2.0.2&quot;
      js-tokens &quot;^3.0.0&quot;

++&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD
 +&quot;@babel/runtime@7.0.0-beta.42&quot;:
 +  version &quot;7.0.0-beta.42&quot;
 +  resolved &quot;https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.42.tgz#352e40c92e0460d3e82f49bd7e79f6cda76f919f&quot;
++=======
+ &quot;@babel/code-frame@^7.0.0&quot;:
+   version &quot;7.0.0&quot;
+   resolved &quot;https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8&quot;
+   dependencies:
+     &quot;@babel/highlight&quot; &quot;^7.0.0&quot;
+
+ &quot;@babel/helper-function-name@7.0.0-beta.32&quot;:
+   version &quot;7.0.0-beta.32&quot;
+   resolved &quot;https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.0.0-beta.32.tgz#6161af4419f1b4e3ed2d28c0c79c160e218be1f3&quot;
++&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; origin/develop
    dependencies:
 -    &quot;@babel/helper-get-function-arity&quot; &quot;7.0.0-beta.32&quot;
 -    &quot;@babel/template&quot; &quot;7.0.0-beta.32&quot;
 -    &quot;@babel/types&quot; &quot;7.0.0-beta.32&quot;
 +    core-js &quot;^2.5.3&quot;
 +    regenerator-runtime &quot;^0.11.1&quot;

 -&quot;@babel/helper-get-function-arity@7.0.0-beta.32&quot;:
 -  version &quot;7.0.0-beta.32&quot;
 -  resolved &quot;https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0-beta.32.tgz#93721a99db3757de575a83bab7c453299abca568&quot;
 +&quot;@babel/runtime@^7.0.0-beta.55&quot;:
 +  version &quot;7.0.0-beta.56&quot;
 +  resolved &quot;https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.0.0-beta.56.tgz#cda612dffd5b1719a7b8e91e3040bd6ae64de8b0&quot;
    dependencies:
 -    &quot;@babel/types&quot; &quot;7.0.0-beta.32&quot;
 +    regenerator-runtime &quot;^0.12.0&quot;

++&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD
 +&quot;@babel/template@7.0.0-beta.44&quot;:
 +  version &quot;7.0.0-beta.44&quot;
 +  resolved &quot;https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.44.tgz#f8832f4fdcee5d59bf515e595fc5106c529b394f&quot;
++=======
+ &quot;@babel/highlight@^7.0.0&quot;:
+   version &quot;7.0.0&quot;
+   resolved &quot;https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4&quot;
+   dependencies:
+     chalk &quot;^2.0.0&quot;
+     esutils &quot;^2.0.2&quot;
+     js-tokens &quot;^4.0.0&quot;
+
+ &quot;@babel/template@7.0.0-beta.32&quot;:
+   version &quot;7.0.0-beta.32&quot;
+   resolved &quot;https://registry.yarnpkg.com/@babel/template/-/template-7.0.0-beta.32.tgz#e1d9fdbd2a7bcf128f2f920744a67dab18072495&quot;
++&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; origin/develop
    dependencies:
 -    &quot;@babel/code-frame&quot; &quot;7.0.0-beta.32&quot;
 -    &quot;@babel/types&quot; &quot;7.0.0-beta.32&quot;
 -    babylon &quot;7.0.0-beta.32&quot;
 +    &quot;@babel/code-frame&quot; &quot;7.0.0-beta.44&quot;
 +    &quot;@babel/types&quot; &quot;7.0.0-beta.44&quot;
 +    babylon &quot;7.0.0-beta.44&quot;
      lodash &quot;^4.2.0&quot;

 -&quot;@babel/traverse@^7.0.0-beta.31&quot;:
 -  version &quot;7.0.0-beta.32&quot;
 -  resolved &quot;https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.32.tgz#b78b754c6e1af3360626183738e4c7a05951bc99&quot;
 -  dependencies:
 -    &quot;@babel/code-frame&quot; &quot;7.0.0-beta.32&quot;
 -    &quot;@babel/helper-function-name&quot; &quot;7.0.0-beta.32&quot;
 -    &quot;@babel/types&quot; &quot;7.0.0-beta.32&quot;
 -    babylon &quot;7.0.0-beta.32&quot;
 -    debug &quot;^3.0.1&quot;
 -    globals &quot;^10.0.0&quot;
 +&quot;@babel/traverse@7.0.0-beta.44&quot;:
 +  version &quot;7.0.0-beta.44&quot;
 +  resolved &quot;https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.0.0-beta.44.tgz#a970a2c45477ad18017e2e465a0606feee0d2966&quot;
 +  dependencies:
 +    &quot;@babel/code-frame&quot; &quot;7.0.0-beta.44&quot;
 +    &quot;@babel/generator&quot; &quot;7.0.0-beta.44&quot;
 +    &quot;@babel/helper-function-name&quot; &quot;7.0.0-beta.44&quot;
 +    &quot;@babel/helper-split-export-declaration&quot; &quot;7.0.0-beta.44&quot;
 +    &quot;@babel/types&quot; &quot;7.0.0-beta.44&quot;
 +    babylon &quot;7.0.0-beta.44&quot;
 +    debug &quot;^3.1.0&quot;
 +    globals &quot;^11.1.0&quot;
      invariant &quot;^2.2.0&quot;
      lodash &quot;^4.2.0&quot;

@@@ -219,13 -128,17 +241,23 @@@ acorn@^4.0.3
    version &quot;4.0.13&quot;
    resolved &quot;https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787&quot;

++&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD
 +acorn@^5.0.0, acorn@^5.5.0:
 +  version &quot;5.7.1&quot;
 +  resolved &quot;https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8&quot;
++=======
+ acorn@^5.0.0:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/42939113/how-do-you-resolve-git-conflicts-in-yarn-lock&quot;&gt;元記事&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-12-at-21.22.11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;コメントのやりとりが面白い。&lt;/p&gt;
</content:encoded></item><item><title>EC2で運用しているWebサイトをIPv6対応した時の設定</title><link>https://blog.teraren.com/posts/ec2-ipv6/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ec2-ipv6/</guid><description>VPC・EC2・ALB・Route 53を使ったWebサイトをIPv6対応させるための設定手順をステップごとに解説した実践ガイド</description><pubDate>Thu, 11 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AWSのサービスは&lt;a href=&quot;https://dev.classmethod.jp/cloud/aws/vpc-ipv6/&quot;&gt;2016年末あたりからIPv6に対応&lt;/a&gt;しています。&lt;/li&gt;
&lt;li&gt;普通に構築する手順にプラスアルファするだけでIPv6対応にできるのでやっちゃいましょう。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.google.com/intl/en/ipv6/statistics.html#tab=ipv6-adoption&quot;&gt;GoogleのIPv6利用率統計&lt;/a&gt; はこんな感じになっています。&lt;/li&gt;
&lt;li&gt;日本は先進国の中では低めです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-29-at-14.22.25.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-29-at-14.22.32.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;設定例&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;VPC, EC2, ALB, Route 53を使ったTLS対応のWebサイトの場合における、設定例を紹介します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;VPCの設定&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;まずVPC自体の設定で、IPv6のネットワークアドレスを設定します。
&lt;ul&gt;
&lt;li&gt;IPv6の場合は、prefixが56bitで振られます！贅沢！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IPv6の場合はサブネット内にもグローバルアドレスが振られます。NATはありません。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-11-at-15.15.06.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;route tableにIPv6のルートが追加されるはずです。追加されていなかったら手動で追加します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-11-at-15.31.04.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Subnetに対してもIPv6のネットワークアドレスを割り振ります。なんとなく64ビットずつ。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-11-at-15.16.05.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;そのsubnetにインスタンスが追加された際に、自動的にIPv6のアドレスを振るように設定を変更しておく。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-11-at-15.17.04.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;そうすると、EC2を対象とするsubnetに追加するとこんな感じに、IPv4とIPv6のアドレスが振られます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-11-at-15.18.35.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ALBは、構築時にIPv4のみか、IPv4とIPv6の両方に対応するかを選ばされます。既にIPv4で作成済みだったら、dualstackで新規構築します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-11-at-15.19.46.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Route 53にはAレコードと、AAAAレコードに同じ値を入れればOKです。2個作らないといけないのが面倒です。&lt;/li&gt;
&lt;li&gt;変更があったら両方やらないといけません。IPv4とIPv6で別のエンティティを返却出来る事になります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-11-at-15.22.28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;nginx側は設定不要で、IPv6のインターフェイスのポートもLISTENしてくれていました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ netstat -l | grep http
tcp 0 0 0.0.0.0:http 0.0.0.0:* LISTEN
tcp6 0 0 [::]:http [::]:* LISTEN
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DNSのテスト。hostコマンドでは、AレコードとAAAAレコードが帰ってくる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ host matsu.teraren.com
matsu.teraren.com is an alias for awsblog.teraren.com.
awsblog.teraren.com has address 54.64.69.23
awsblog.teraren.com has IPv6 address 2406:da14:e67:4500:9d34:aba7:1c9e:aad8
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;トラブルシューティング&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;運用しているOSによっては、&lt;a href=&quot;https://docs.aws.amazon.com/vpc/latest/userguide/vpc-migrate-ipv6.html#ipv6-dhcpv6-ubuntu&quot;&gt;OS側のNICの設定&lt;/a&gt;が必要そうです。&lt;/li&gt;
&lt;li&gt;security group周りも自動的にIPv6の設定が入っているので特に設定しないでOKですが、念のためご確認を。&lt;/li&gt;
&lt;li&gt;VPCのルーティングテーブルにて、IPv6のルーティングがegress only internetになっている場合は外から入れないので、IPv4と同じように普通のインターネットゲートウェイを指定してください&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;検証&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://ipv6-test.com/validate.php&quot;&gt;ここ&lt;/a&gt;のサイトで確認出来ます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/Screen-Shot-2018-10-11-at-15.10.49.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nginxのアクセスログに、2行目にあるようなIPv6のアドレスで接続が来るようになっていればOK。&lt;/li&gt;
&lt;li&gt;IPv6チェッカーや、IPv6に対応した端末からアクセスしてみてください。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;172.31.24.248 - - [11/Oct/2018:06:46:40 +0000] &quot;GET / HTTP/1.1&quot; 200 396 &quot;-&quot; &quot;ELB-HealthChecker/2.0&quot;
2600:3c00::f03c:91ff:fe93:dcd4 - - [11/Oct/2018:06:46:49 +0000] &quot;GET / HTTP/1.1&quot; 200 612 &quot;-&quot; &quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;curlで、IPv6のhttpsでの接続性もテスト&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$ curl -6 -I -vv https://blog.teraren.com/
*   Trying 2406:da14:e67:4500:9d34:aba7:1c9e:aad8...
* TCP_NODELAY set
* Connected to matsu.teraren.com (2406:da14:e67:4500:9d34:aba7:1c9e:aad8) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=matsu.teraren.com
*  start date: Aug 14 19:18:15 2018 GMT
*  expire date: Nov 12 19:18:15 2018 GMT
*  subjectAltName: host &quot;matsu.teraren.com&quot; matched cert&apos;s &quot;matsu.teraren.com&quot;
*  issuer: C=US; O=Let&apos;s Encrypt; CN=Let&apos;s Encrypt Authority X3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x5562dd0a5940)
&amp;gt; HEAD /blog/ HTTP/2
&amp;gt; Host: matsu.teraren.com
&amp;gt; User-Agent: curl/7.58.0
&amp;gt; Accept: */*
&amp;gt;
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
&amp;lt; HTTP/2 200
HTTP/2 200
&amp;lt; server: nginx/1.14.0
server: nginx/1.14.0
&amp;lt; date: Thu, 11 Oct 2018 07:51:10 GMT
date: Thu, 11 Oct 2018 07:51:10 GMT
&amp;lt; content-type: text/html; charset=UTF-8
content-type: text/html; charset=UTF-8
&amp;lt; vary: Accept-Encoding
vary: Accept-Encoding
&amp;lt; expires: Wed, 11 Jan 1984 05:00:00 GMT
expires: Wed, 11 Jan 1984 05:00:00 GMT
&amp;lt; cache-control: no-cache, must-revalidate, max-age=0
cache-control: no-cache, must-revalidate, max-age=0
&amp;lt; pragma: no-cache
pragma: no-cache
&amp;lt; link: ; rel=&quot;https://api.w.org/&quot;
link: ; rel=&quot;https://api.w.org/&quot;
&amp;lt; link: ; rel=shortlink
link: ; rel=shortlink
&amp;lt;
* Connection #0 to host matsu.teraren.com left intact
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ついでに、このブログもIPv6 readyにしました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://ipv6-test.com/validate.php?url=matsu.teraren.com&quot;&gt;&lt;img src=&quot;../../assets/uploads/2018/10/button-ipv6-big.png&quot; alt=&quot;ipv6 ready&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;しばらく運用してみました。IPv6のアクセスはとても少ないです。&lt;/li&gt;
&lt;li&gt;363/40757=0.008906446=0.8%&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;追記2&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://minedia.com/&quot;&gt;こちらのサイト&lt;/a&gt;もIPv6対応。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% host -t aaaa minedia.com
www.minedia.com has IPv6 address 2406:da14:9cd:7103:863a:d6cf:32b1:80a0
www.minedia.com has IPv6 address 2406:da14:9cd:7100:dc9c:9b11:ba:ea7e
www.minedia.com has IPv6 address 2406:da14:9cd:7102:c893:4482:c987:22ef

% host -t a minedia.com
www.minedia.com has address 13.112.43.184
www.minedia.com has address 52.194.55.79
www.minedia.com has address 13.114.169.247
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-migrate-ipv6.html&quot;&gt;https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-migrate-ipv6.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>docker-composeでEC2上に開発環境を作る上でのメモ</title><link>https://blog.teraren.com/posts/docker-compose-ec2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-compose-ec2/</guid><description>EC2でdocker-composeを使ったプレビュー環境構築時のAMI選択・インスタンスタイプ・ディスク容量・セキュリティグループ設定のハマりどころまとめ</description><pubDate>Fri, 05 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;EC2にプレビュー環境を作るにあたって、いくつかハマったので要点を書いておく。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AMIの選択
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Ubuntu 18.04.1 LTS&lt;/code&gt; ではdockerが&lt;a href=&quot;/posts/docker-error-processing-tar-file/&quot;&gt;変な挙動&lt;/a&gt;をしているからだめ。&lt;/li&gt;
&lt;li&gt;Amazon Linux 2ではすんなりと動く。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;instance typeは&lt;code&gt;t2.medium&lt;/code&gt;以上は必要。これ未満だとbuildがくっそ時間かかる。&lt;/li&gt;
&lt;li&gt;diskは20GBぐらい
&lt;ul&gt;
&lt;li&gt;たまにdockerが挙動がおかしくなってディスクを消費しまくって、rebootしないと復帰しない状態になる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;docker, docker-composeのインストール&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% sudo yum install docker -y
% sudo curl -L &quot;https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)&quot; -o /usr/local/bin/docker-compose
% sudo chmod +x /usr/local/bin/docker-compose
% sudo service docker start
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;vigrして、&lt;code&gt;docker&lt;/code&gt;にユーザを追加する。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% sudo vigr
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;shellのログアウト、ログイン。&lt;/li&gt;
&lt;li&gt;security group変更
&lt;ul&gt;
&lt;li&gt;アプリケーションサーバポートの解放&lt;/li&gt;
&lt;li&gt;webpackerのポートを開放（基本的には不要だけど、webpackerで起きているエラーを表示するために開けるべき）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% docker-compose up --build
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Mercari Tech Conf 2018 自分用メモ</title><link>https://blog.teraren.com/posts/mercari-tech-conf-2018-memo/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mercari-tech-conf-2018-memo/</guid><description>Mercari Tech Conf 2018に参加してマイクロサービスアーキテクチャの実例やSREの取り組み、グローバル展開の技術的課題などの発表から印象に残った点をまとめたメモです。</description><pubDate>Thu, 04 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0214.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Mercari Tech Conf 2018&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://techconf.mercari.com/&quot;&gt;Mercari Tech Conf 2018&lt;/a&gt;へ行ってきました。&lt;/li&gt;
&lt;li&gt;microservice architectureの実例として参考になるキーワードがあったのでメモっておきます。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://qiita.com/taisuke_h/items/5f8a5bfbc583a33f12dd&quot;&gt;スライド&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://x.com/search?q=%23mtc18&amp;amp;src=typd&quot;&gt;Twitter#mtc18&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;自分用メモ&lt;/h2&gt;
&lt;p&gt;一般論な所は省き、mercariの特徴が出ている部分だけを書いてあります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;10:00 基調講演
&lt;ul&gt;
&lt;li&gt;Yuki Hamada (CPO)
&lt;ul&gt;
&lt;li&gt;テクノロジーで解決してきたこと
&lt;ul&gt;
&lt;li&gt;商品画像認識&lt;/li&gt;
&lt;li&gt;規約違反商品検出&lt;/li&gt;
&lt;li&gt;重さ推定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;テックカンパニー
&lt;ul&gt;
&lt;li&gt;テクノロジーで世の中を変える&lt;/li&gt;
&lt;li&gt;開発者が使えるテクノロジーを作り出す&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2020年までに1000人のエンジニアを採用する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CTO
&lt;ul&gt;
&lt;li&gt;エンジニア
&lt;ul&gt;
&lt;li&gt;Oct 2018: 350&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;EM/PM体制
&lt;ul&gt;
&lt;li&gt;Engineering Manager
&lt;ul&gt;
&lt;li&gt;採用、育成、配属、組織開発&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tech Lead
&lt;ul&gt;
&lt;li&gt;技術、設計、想像、品質&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;US CTO
&lt;ul&gt;
&lt;li&gt;MLがんばっている&lt;/li&gt;
&lt;li&gt;f(item)=&amp;gt; ML input matrix
&lt;ul&gt;
&lt;li&gt;genomeと呼んでいる&lt;/li&gt;
&lt;li&gt;この概念を使って、予測とかいろいろやっている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;merpay CTO
&lt;ul&gt;
&lt;li&gt;お金に替わる信用を蓄積する。&lt;/li&gt;
&lt;li&gt;エスクローやっている&lt;/li&gt;
&lt;li&gt;mercariX
&lt;ul&gt;
&lt;li&gt;ブロックチェーンでメルカリポイントのやりとりをする&lt;/li&gt;
&lt;li&gt;社内実験のみ&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;13:00 microservice
&lt;ul&gt;
&lt;li&gt;1年前は1つ。今は19個。開発中は73個。&lt;/li&gt;
&lt;li&gt;API gateway作ってすべてはそこを通すようにした。&lt;/li&gt;
&lt;li&gt;GCP
&lt;ul&gt;
&lt;li&gt;Kubernetes。チーム毎にnamespaceを作る。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IaC
&lt;ul&gt;
&lt;li&gt;terraform&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;deploy tool
&lt;ul&gt;
&lt;li&gt;spinnaker
&lt;ul&gt;
&lt;li&gt;https://www.spinnaker.io/&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SLI/SLOをサービス毎に設ける&lt;/li&gt;
&lt;li&gt;Chaos Testing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;16:00 microservice
&lt;ul&gt;
&lt;li&gt;トランザクションのbreakdown
&lt;ul&gt;
&lt;li&gt;同期&lt;/li&gt;
&lt;li&gt;非同期&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GraphQLのライブラリ
&lt;ul&gt;
&lt;li&gt;Go + gqlgen&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0218.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0222.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0219.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;その他&lt;/h2&gt;
&lt;p&gt;開始前。&lt;/p&gt;
&lt;p&gt;席が広く、空調も快適です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0214.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ブース。各プロジェクト毎に用意されており、いろいろ説明してくれます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0210.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;今半のお弁当。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0217.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;飲み物と軽食&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0211.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;新しい技術が使えて楽しそうな環境。それと同時にレガシーコードとの戦いが大変そうな印象でした。&lt;/li&gt;
&lt;li&gt;絶賛microservice化中って感じ。&lt;/li&gt;
&lt;li&gt;月間の流通金額半端ないっす。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>docker-compose で Error processing tar file(exit status 1): unexpected EOF</title><link>https://blog.teraren.com/posts/docker-error-processing-tar-file/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-error-processing-tar-file/</guid><description>docker-composeビルド時に発生する「Error processing tar file: unexpected EOF」の原因と対処法。ワークディレクトリのパーミッション問題が根本原因。</description><pubDate>Wed, 03 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;エラーの内容&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ docker-compose build app
Building app
ERROR: Error processing tar file(exit status 1): unexpected EOF
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/42784396/docker-error-error-processing-tar-fileexit-status-1-unexpected-eof&quot;&gt;これ&lt;/a&gt;を試しても直らなかった。&lt;/p&gt;
&lt;p&gt;ただどうやら、&lt;a href=&quot;https://forums.docker.com/t/docker-commit-error-error-processing-tar-file-exit-status-1-chmod-opt-permission-denied/92138&quot;&gt;ワークディレクトリにパーミッションが変なファイルがあると発生するみたい。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;こんな感じでマウントしていたので、&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  db:
    image: mysql:5.7
    volumes:
      - ./etc/docker/mysql/data:/var/lib/mysql
      - ./etc/docker/mysql/conf.d:/etc/mysql/conf.d
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;解決方法&lt;/h2&gt;
&lt;p&gt;以下のように権限を書き換えて、解決。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo chown -R  `whoami` etc/docker/mysql/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そういえば、Linuxのdockerって権限周りが変になるんだよなぁ。。。以前、Cloud9で試したときにそうだった。&lt;/p&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;再発した。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;dockerの再起動、/var/lib/dockerの削除、OSの再起動などを試しても駄目だった。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Ubuntu 18.04.1 LTS&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;こんなエラーも出たのだが、&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;dockerグループにユーザを追加しても駄目。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;sudo使えば利用可能。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;仕方が無いので、Ubuntu 18を使うことを諦める。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;$ docker-compose build
ERROR: Couldn&apos;t connect to Docker daemon at http+docker://localhost - is it running?
If it&apos;s at a non-standard location, specify the URL with the DOCKER_HOST environment variable.
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Amazon Linux 2を使ったら全く問題無かった。
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;amzn-ami-hvm-2018.03.0.20180811-x86_64-gp2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;相変わらず、dockerでマウントしてwriteしたファイルはroot権限になってしまっているが。（まぁ、これは、dockerのvolumeを使うようにして回避しよう）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>iPhone XSの深度情報テスト</title><link>https://blog.teraren.com/posts/iphone-xs-portrait/</link><guid isPermaLink="true">https://blog.teraren.com/posts/iphone-xs-portrait/</guid><description>iPhone XSが記録する深度情報をFocosアプリで活用し、購入後に絞りを自由に調整したポートレート写真のサンプルを紹介</description><pubDate>Wed, 03 Oct 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;iPhone XSを買っちゃいました。これがあれば、Web用素材はデジタル一眼レフを持ち出さなくても大丈夫なくらい良い写真が撮れます。&lt;/li&gt;
&lt;li&gt;iPhone XSでは深度情報を記録できるようになり、この機能がおもしろくて、ポートレート写真ばっかり撮ってます！&lt;/li&gt;
&lt;li&gt;iPhone XSで写真を撮ると、1枚の写真に、絵と深度情報（遠さ）が記録されます。それを元に自然なボケを画像加工で作れます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;深度情報&lt;/h3&gt;
&lt;p&gt;どのように深度情報を持っているかというと、下の動画を見てもらうのが一目瞭然です。&lt;br /&gt;
アプリは、&lt;a href=&quot;https://itunes.apple.com/us/app/focos/id1274938524?mt=8&quot;&gt;Focos&lt;/a&gt;を使っています。&lt;/p&gt;
&lt;p&gt;https://youtu.be/Jp0ocRBWLjA&lt;/p&gt;
&lt;h3&gt;例&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;深度情報を持っていると、以下のように絞りを調整したり出来ます。これがまた、精度がそこそこ高い！&lt;/li&gt;
&lt;li&gt;サンプル写真は物撮りだけど、人物だとボケの綺麗さが良い感じに写ります。&lt;/li&gt;
&lt;li&gt;左後ろの机のボケ方を見てもらうのがわかりやすいです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0197.jpg&quot; alt=&quot;f1.6&quot; /&gt;&lt;/p&gt;
&lt;p&gt;f1.6&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0199.jpg&quot; alt=&quot;f4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;f4&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0201.jpg&quot; alt=&quot;f8&quot; /&gt;&lt;/p&gt;
&lt;p&gt;f8&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0202.jpg&quot; alt=&quot;f16&quot; /&gt;&lt;/p&gt;
&lt;p&gt;f16&lt;/p&gt;
&lt;h3&gt;応用&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Focosを使って、光源を壁と物の間に後から置いてみた作例。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/10/IMG_0204.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Processed with Focos&lt;/p&gt;
&lt;h2&gt;Pro/Con&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Pros
&lt;ul&gt;
&lt;li&gt;後から被写界深度をいじれる&lt;/li&gt;
&lt;li&gt;デジタル一眼レフの代替にすこしなる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cons
&lt;ul&gt;
&lt;li&gt;写真を撮るときにPortraitモードにしなければいけない&lt;/li&gt;
&lt;li&gt;焦点距離が伸びるので、マクロレンズ的な使い方は出来ない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>iPhone8電池無償交換→データが完全に消える。</title><link>https://blog.teraren.com/posts/iphone-battery-replacement/</link><guid isPermaLink="true">https://blog.teraren.com/posts/iphone-battery-replacement/</guid><description>iPhone8電池無償交換→データが完全に消える。</description><pubDate>Thu, 13 Sep 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;iPhone SE、iPhone 6、iPhone 6 Plus、iPhone 6s、iPhone 6s Plus、iPhone 7、iPhone 7 Plus、iPhone 8、iPhone 8 Plus、iPhone Xを対象にしたバッテリー交換プログラムに関して、非正規品バッテリーでなければ、希望するユーザー全てを対象に提供が開始されている。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ref: &lt;a href=&quot;http://www.itmedia.co.jp/news/articles/1801/04/news030.html&quot;&gt;http://www.itmedia.co.jp/news/articles/1801/04/news030.html&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;年末になると混み合うだろうから、今のうちに修理に出してみました。&lt;/li&gt;
&lt;li&gt;修理に出す前には、バッテリーに問題は無い状態ですが、さすがに1年弱使うと少し電池の持ちが若干悪くなってきたので依頼してみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;注意&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;どのくらい時間がかかるか？
&lt;ul&gt;
&lt;li&gt;土曜朝に発送して木曜日朝に受け取り。&lt;/li&gt;
&lt;li&gt;3営業日&lt;/li&gt;
&lt;li&gt;約5日間&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;データは消えるのか？
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;消えた。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/09/Screenshot_2018_09_13_10_50.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iCloudへのバックアップを有効にしてあるのに、最後にiCloudへバックアップされたタイミングが2ヶ月前の状態。以下を行うので凄い時間がかかった。手動でバックアップしてから出すのが良い。
&lt;ul&gt;
&lt;li&gt;復元&lt;/li&gt;
&lt;li&gt;2ヶ月分のアプリのアップデート&lt;/li&gt;
&lt;li&gt;2ヶ月分の設定差分を変更&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://iphone-beginners.com/backup/kiji-11172.html&quot;&gt;iCloudのバックアップタイミング&lt;/a&gt;には適合しているから、バックアップされているはずなのに謎。手動でバックアップを適宜しておく必要あり。&lt;/li&gt;
&lt;li&gt;SIMカードを入れっぱなしにして、配送に出してしまったので、SIMカードだけ水曜日（本体到着の1日前）に返送されてきました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>SSHのキーペアを安全な暗号アルゴリズムで作る</title><link>https://blog.teraren.com/posts/ssh-keypair-ed25519/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ssh-keypair-ed25519/</guid><description>SSHのキーペアを安全な暗号アルゴリズムで作る</description><pubDate>Mon, 03 Sep 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ssh-keygen のデフォルトオプションで作成するキーペアのアルゴリズムは今のところまぁ問題無いだろうけど数年後には赤信号になる事を知りました。&lt;/p&gt;
&lt;p&gt;よって、2018年9月時点では以下のようにしてキーペアを作るのが推奨。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ssh-keygen -o -a 100 -t ed25519
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;秘密鍵は、&lt;code&gt;~/.ssh/id_ed25519&lt;/code&gt; に生成されます。&lt;/li&gt;
&lt;li&gt;公開鍵は、&lt;code&gt;~/.ssh/id_ed25519.pub&lt;/code&gt; に生成されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OpenSSHのデフォルトはRSA 2048ですが、現時点では黄色信号なので、新たに作るときには &lt;code&gt;Ed25519&lt;/code&gt; を使う。。&lt;/p&gt;
&lt;p&gt;Quoted: &lt;a href=&quot;https://blog.g3rt.nl/upgrade-your-ssh-keys.html&quot;&gt;https://blog.g3rt.nl/upgrade-your-ssh-keys.html&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;関連した日本語での解説。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://qiita.com/wnoguchi/items/a72a042bb8159c35d056&quot;&gt;https://qiita.com/wnoguchi/items/a72a042bb8159c35d056&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>ガートナー、先進テクノロジーのハイプサイクル2018年版</title><link>https://blog.teraren.com/posts/hype-cycle/</link><guid isPermaLink="true">https://blog.teraren.com/posts/hype-cycle/</guid><description>ガートナー、先進テクノロジーのハイプサイクル2018年版</description><pubDate>Fri, 24 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;メモ&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/08/img_a9efdedb20afa4b0b915c0836f5533cb106243.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/08/Screen-Shot-2018-08-24-at-11.45.43.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://it.impressbm.co.jp/articles/-/16586&quot;&gt;参照&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Unexpected server respose while doing caching_sha2 authの直し方</title><link>https://blog.teraren.com/posts/unexpected-server-respose-while-doing-caching-sha2-auth/</link><guid isPermaLink="true">https://blog.teraren.com/posts/unexpected-server-respose-while-doing-caching-sha2-auth/</guid><description>MySQL 8.0へのアップグレード後にPHP7.2からWordPressが接続できなくなるcaching_sha2_password認証エラーをALTER USERで解決する方法</description><pubDate>Fri, 24 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PHP7.2の環境でWordPressが動かなくなった。&lt;/li&gt;
&lt;li&gt;MySQL 8.0にあがったのが理由&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;解決方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;以下のようなエラーログが出る感じ。&lt;/li&gt;
&lt;li&gt;mysqli系でもPDOでも出るので、PHPのmysqlの深いところで問題が起きている様子。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;respose&lt;/code&gt;はtypoしてる。。。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/php/php-src/blob/ef999f07355490f13d612be10960d21c7bd22a85/ext/mysqlnd/mysqlnd_auth.c#L1071&quot;&gt;https://github.com/php/php-src/blob/ef999f07355490f13d612be10960d21c7bd22a85/ext/mysqlnd/mysqlnd_auth.c#L1071&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;[23-Aug-2018 15:59:59 UTC] PHP Warning:  mysqli_real_connect(): Unexpected server respose while doing caching_sha2 auth: 109 in /xxxxxxxxx/wp-includes/wp-db.php on line 1531
[23-Aug-2018 16:00:09 UTC] PHP Warning:  mysqli_real_connect(): MySQL server has gone away in /xxxxxxxxx/wp-includes/wp-db.php on line 1531
[23-Aug-2018 16:00:09 UTC] PHP Warning:  mysqli_real_connect(): (HY000/2006): MySQL server has gone away in /xxxxxxxxx/wp-includes/wp-db.php on line 1531
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解決するには、MySQLでパスワードのハッシュ方式を変更してあげる必要がある。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ALTER USER `username`@`localhost` IDENTIFIED WITH caching_sha2_password BY &apos;same password&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;変更後は以下を忘れずに。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FLUSH PRIVILEGES;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これだけで完了。&lt;/p&gt;
&lt;p&gt;しばらくしたらPHP側で&lt;a href=&quot;https://github.com/docker-library/wordpress/issues/319#issuecomment-407471597&quot;&gt;caching_sha2がサポートされるらしい&lt;/a&gt;ので、この記事の対処は不要になるとのことですが、本家PHPのbug reportにはコメントが一切書かれていません。。。&lt;/p&gt;
</content:encoded></item><item><title>CG-HDC4EU3500所感</title><link>https://blog.teraren.com/posts/comments-for-cg-hdc4eu3500/</link><guid isPermaLink="true">https://blog.teraren.com/posts/comments-for-cg-hdc4eu3500/</guid><description>コレガ製4ベイRAIDケースCG-HDC4EU3500を5年運用した結果、RAID5の極端な低速さとデータ消失リスクを実体験から総括</description><pubDate>Thu, 23 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;::amazon{asin=&quot;B0020NPME4&quot;}&lt;/p&gt;
&lt;h2&gt;結論&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;RAID5が超遅い&lt;/li&gt;
&lt;li&gt;RAID1は2台だけ。1台壊れるだけで冗長性が無くなる。
&lt;ul&gt;
&lt;li&gt;残りのベイに刺さったディスクはホットスタンバイとして利用される。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/08/Screen-Shot-2018-08-23-at-18.26.26.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;買ったときの記録&lt;/h2&gt;
&lt;p&gt;Raid5コントローラが載った割には、当時、安いのはこれしか無かったからしょうが無い感じですが、後々の対応を考えると高くつきました。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;お届け予定日： 2012年7月12日 - 2012年7月17日&lt;br /&gt;
1 &quot;コレガ(アライドテレシス) 4BAY RAID対応 eSATA/USB3.0接続 PC連動電源機能 SATA3.5インチHDDケース WEBモデル CG-HDC4EUS35-W&quot;&lt;br /&gt;
Personal Computers; ￥ 16,800&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;細かい不具合&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;再起動するとマウントされない事が起きていた。何回か再起動するとマウントされたりする。&lt;/li&gt;
&lt;li&gt;diskutilコマンドで無理矢理マウントすれば使えるようになる。&lt;/li&gt;
&lt;li&gt;macosのバージョンが上がったタイミングで発生しなくなった。&lt;/li&gt;
&lt;li&gt;raid5の読み書きが超遅い。MySQLのデータを置いていたのですが、超遅いです。常用のディスクでは無くバックアップ用途に限るべきでした。あらゆる読み書きが遅い。HUDのアクセスランプがつきっぱなしの状態になります。ハードディスクが遅い可能性もありますが、単体ハードディスクより遙かに遅い。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;そして故障&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;RAID5、HFSでフォーマットして、macminiに接続して、24時間稼働で使っていました。&lt;/li&gt;
&lt;li&gt;2TB x 4本です。&lt;/li&gt;
&lt;li&gt;5年ほど運用しました。&lt;/li&gt;
&lt;li&gt;実運用しているデータは3TBぐらい。&lt;/li&gt;
&lt;li&gt;ハードディスクが1年に1本くらいの頻度で壊れました。毎回、すぐに交換して自動リビルドで回復しました。&lt;/li&gt;
&lt;li&gt;しかし、2017年冬、macosにてどうしても読み取れなくなりました。半年以上前なので細かい症状を忘れましたが、マウントは出来るけど、ファイルを読み出そうとすると、読み出せない感じ。raid boxの異常ランプはついていないので、ファイルシステムのエラーっぽい。&lt;/li&gt;
&lt;li&gt;macosだとトラブルシューティングが大変なので、Linuxが動く&lt;a href=&quot;https://japanese.engadget.com/2017/12/01/1-9800-muga-pc/&quot;&gt;2万円の格安PC&lt;/a&gt;をドンキで買ってきて、Windowsからマウントを試みましたが不可能。ハードウェア的に認識しない。（評判が良さそうだったから買ったけど、このPCは遅すぎて作業が捗らない。もう少し良いのを買えば良かった。）&lt;/li&gt;
&lt;li&gt;しかし、それをUbuntuのデュアルブートにして、Linux上からマウントするとギリギリ読み出せる。一部のファイルは消えているけど9割方は救出出来そう。&lt;/li&gt;
&lt;li&gt;rsyncでデータを吸い出すが、途中で止まる。。。。夜な夜なディレクトリ指定で実行して、少しずつrsyncを完了させていく日々。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;安いraidボックスを信用すると痛い目にみる&lt;/li&gt;
&lt;li&gt;データにも利用頻度や重要度に応じて3パターンぐらい分けて、ユースケースにあった運用する必要がある。&lt;/li&gt;
&lt;li&gt;例
&lt;ul&gt;
&lt;li&gt;重要なデータ：raid box -&amp;gt; AWS S3にsync -&amp;gt; アクセス頻度が低いファイルをGracierへ。&lt;/li&gt;
&lt;li&gt;重要ではないデータ：raid box&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>別アカウントのS3バケットに転送する手順</title><link>https://blog.teraren.com/posts/qiita-20180816-7d317e5eac77d87fc294/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20180816-7d317e5eac77d87fc294/</guid><description>S3 のアカウント名は、AWS 全体でユニークな ID があります。Account A にて bucket を適当に作ると、デフォルトではそのユーザのアクセス権限が付与されているので、そこからログイン中の ID がわかります。</description><pubDate>Thu, 16 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;いくつか記事がありますが、ただのデータ移行という前提では簡単にできるので記事として書いておきます。
&lt;ul&gt;
&lt;li&gt;https://dev.classmethod.jp/cloud/aws/how-to-use-s3-cross-account/&lt;/li&gt;
&lt;li&gt;https://aws.amazon.com/jp/premiumsupport/knowledge-center/account-transfer-s3/&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;前提条件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;転送元
&lt;ul&gt;
&lt;li&gt;アカウント A&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;転送先
&lt;ul&gt;
&lt;li&gt;アカウント B&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;手順&lt;/h2&gt;
&lt;h3&gt;アカウントAでの作業&lt;/h3&gt;
&lt;h4&gt;1. アカウント個別の設定を入れます。&lt;/h4&gt;
&lt;p&gt;S3 のアカウント名は、AWS 全体でユニークな ID があります。Account A にて bucket を適当に作ると、デフォルトではそのユーザのアクセス権限が付与されているので、そこからログイン中の ID がわかります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/08/28f5c6b6-51cd-4c63-6bd8-4945c2ab809a.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;2. 移行元のbucketにbucket policyを入れます。&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;
{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Sid&quot;: &quot;DelegateS3Access&quot;,
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Principal&quot;: {
                &quot;AWS&quot;: &quot;arn:aws:iam::&amp;lt;AWS ID of Account B&amp;gt;:user/&amp;lt;IAM account name on Account B&amp;gt;&quot;
            },
            &quot;Action&quot;: [
                &quot;s3:ListBucket&quot;,
                &quot;s3:GetObject&quot;
            ],
            &quot;Resource&quot;: [
                &quot;arn:aws:s3:::&amp;lt;minedia-source-bucket&amp;gt;/*&quot;,
                &quot;arn:aws:s3:::&amp;lt;minedia-source-bucket&amp;gt;&quot;
            ]
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;例：
&lt;img src=&quot;../../assets/uploads/2018/08/58c32e19-373b-947d-1b1b-eabd3cea976c.png&quot; alt=&quot;image.png&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;アカウントBでの作業&lt;/h3&gt;
&lt;p&gt;アカウントBの認証を設定している前提で、普通にaws s3コマンドを発行すれば終わりです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% aws s3 sync s3://minedia-source-bucket/ s3://minedia-destination-bucket/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;平均して 260MB/s で転送出来ていまいました。&lt;/p&gt;
</content:encoded></item><item><title>エンジニア不足を解消するソリューションの仮説</title><link>https://blog.teraren.com/posts/engineer-oss/</link><guid isPermaLink="true">https://blog.teraren.com/posts/engineer-oss/</guid><description>エンジニア採用難の解決策として、ソースコードをOSSとして公開し全世界のエンジニアがPull Requestで貢献できる仕組みを提案する考察記事です。</description><pubDate>Mon, 13 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;結論&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;ソースコードをオープンソースにして、全世界のエンジニアがコミット出来る状態にすればいいんじゃね？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;以下に説明を書く。&lt;/p&gt;
&lt;h2&gt;背景・問題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;最近、「&lt;strong&gt;エンジニアが足りない&lt;/strong&gt;！」「&lt;strong&gt;エンジニアの単価が上昇していて辛い&lt;/strong&gt;」といった、エンジニアの採用に関する問題を聞く。&lt;/li&gt;
&lt;li&gt;しかしながら、エンジニアの採用はミクロな問題と考える。本質は、ビジネスゴールはプロダクトをリリースすること。&lt;/li&gt;
&lt;li&gt;そのためにエンジニアを採用し、開発するのが主流になっているのが現況。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;目的&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ビジネス目標達成のために、システムの開発、運用を安価にスピーディーに行う。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;エンジニアが自社プロダクトを開発するまでのフローを、ファネルで考えると以下のようになる。
&lt;ul&gt;
&lt;li&gt;全世界のエンジニア &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; 要望にマッチ &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; 転職可能 &amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; 採用 &amp;gt;&amp;gt; パフォーマンスを発揮する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;最初の取りこぼしが大きい。じゃあ、まずは全世界のエンジニアがコミット出来る状態にするのがスタートと考える。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000148322.html&quot;&gt;働き方改革&lt;/a&gt;とも言えるが、どちらかというとアイディアによる働かせ方改革。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;方法&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ソースコードをPublicにする&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;課題管理はIssue機能を使う。
&lt;ul&gt;
&lt;li&gt;要望、bugfix、機能開発、技術的な質問、戦略コンサルティング。&lt;/li&gt;
&lt;li&gt;ソースコードは&lt;strong&gt;Pull-requestで納品&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;技術的な質問は回答が行われたら報酬を付与。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;報酬
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Issue毎に報酬金額&lt;/strong&gt;を設定する。&lt;/li&gt;
&lt;li&gt;付与タイミング&lt;/li&gt;
&lt;li&gt;1つのissueあたりの金額設定&lt;/li&gt;
&lt;li&gt;売上連動のレベニューシェア。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;報酬の受け取り
&lt;ul&gt;
&lt;li&gt;pull-requestが&lt;strong&gt;mergeされたタイミングで検収&lt;/strong&gt;とみなす。&lt;/li&gt;
&lt;li&gt;報酬は、日本円、外貨、仮想通貨、ウォレットなどで受け取れるようにする。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/08/Screen-Shot-2018-08-13-at-20.59.08.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ユースケース図にすると以下のようなモデル。&lt;/p&gt;
&lt;h2&gt;評価&lt;/h2&gt;
&lt;h3&gt;メリット&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Issueやドキュメントを&lt;strong&gt;英語で書けば、海外の安い単価のエンジニアを呼び込めるので単価が下がる&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;透明性が高い
&lt;ul&gt;
&lt;li&gt;公平なプライシング。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;中間業者によるコストは無し&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;C2C&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Githubの費用が無料。(Private Repositoryでは無いので)&lt;/li&gt;
&lt;li&gt;英語でドキュメントを書けばオフショア開発を出来る&lt;/li&gt;
&lt;li&gt;サーバサイド、アプリ、デザイナを同一の方法でマネージ出来る。&lt;/li&gt;
&lt;li&gt;趣味で作りたいサービスがあって、お金も少し出せるなら良い。目的が勉強ではなくてサービスのリリースという前提。割り切り必要。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;デメリット&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ソースコードを公開するという心理的障壁がある。&lt;/li&gt;
&lt;li&gt;第三者にまねされるリスクがある。（特許であらかじめ押さえるとかが必要）&lt;/li&gt;
&lt;li&gt;セキュリティホールがあったら、悪用されてしまう。（逆に見つけてもらえるかも知れない）&lt;/li&gt;
&lt;li&gt;報酬管理をする必要がある。
&lt;ul&gt;
&lt;li&gt;githubにはAPIがあるので報酬振り込み用のプログラムを書けば自動化できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;案件のディスカバリ、マッチングの方法
&lt;ul&gt;
&lt;li&gt;広告打つ&lt;/li&gt;
&lt;li&gt;アフィリエイトの運用を作る。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ローカルで開発環境を簡単に再現できる必要あり。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;他にも考えないといけないこと&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;著作権周りの権利ルール設定。&lt;/li&gt;
&lt;li&gt;適用出来そうなプロダクト
&lt;ul&gt;
&lt;li&gt;マッチしそう：コンシューマ向けサービス。(Togetterとか、mercariとか。世の中のほとんどのプロダクトに適用出来そう)&lt;/li&gt;
&lt;li&gt;マッチしなさそう：期限が厳しいプロダクト。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;応用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;このような目的で作られたgithubのrepositoryのissueをまとめるようなサイトを作る。
&lt;ul&gt;
&lt;li&gt;金額、報酬、納期、使用テクノロジーなどでソートやフィルタが出来るようにする。&lt;/li&gt;
&lt;li&gt;アフィリエイターの立ち位置&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;アイディアが面白ければ、資金調達も可能になるはず。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参考事例&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://issuehunt.io/&quot;&gt;IssueHunt&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;GithubのIssueに対してFund raiseを行えるサービス。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/BoostIO/Boostnote&quot;&gt;BoostIo/Boostnote&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;IssueHuntをうまく利用して開発を進めているサービス。1つのissueに対して$20が相場。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://about.gitlab.com/handbook/&quot;&gt;Gitlab handbook&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;gitlabがより進んだ形で運用しています。会社のたくさんの情報がpublicになっており、開発にジョインできる状態になっています。ドキュメントが大量にあるので初期のラーニングは大変そうですが、一見価値あり。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;プロダクト担当者が勇気を振り絞れば、ワークするかも知れない。&lt;/li&gt;
&lt;li&gt;まねされても痛手にならないようなプロダクトの開発に使えそう。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;FAQ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Q: Issueにまとめられる人が居ません。
&lt;ul&gt;
&lt;li&gt;A: 自分で努力してスキルを獲得してIssueにまとめるか、業務委託やコンサルに依頼する。依頼内容は、要望定義、要件定義、設計までを依頼してアウトプットをissueへの登録にする。&lt;/li&gt;
&lt;li&gt;A: むしろIssueにまとめる人を募集すれば良い。それを評価出来ない場合は二重投資になるが複数人に投げて比較、和集合を取るなどして整形する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>mercariファミリーデー</title><link>https://blog.teraren.com/posts/mercari-family-day/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mercari-family-day/</guid><description>mercariファミリーデー</description><pubDate>Fri, 03 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;mercariファミリーデー&lt;/p&gt;
&lt;h2&gt;感想&lt;/h2&gt;
&lt;p&gt;みんな若い！&lt;/p&gt;
</content:encoded></item><item><title>Beoplay E8 VS Bose SoundSport Free</title><link>https://blog.teraren.com/posts/e8-vs-soundsport/</link><guid isPermaLink="true">https://blog.teraren.com/posts/e8-vs-soundsport/</guid><description>ジムや通勤用に完全ワイヤレスイヤホンを比較。B&amp;O Beoplay E8とBose SoundSport Freeの音質・フィット感・価格を実際に使って徹底比較。</description><pubDate>Tue, 10 Jul 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2年前ぐらいから、&lt;a href=&quot;/posts/bose-quietcomfort-35/&quot;&gt;Bose QuietComfort 35&lt;/a&gt;を使ってます。これはこれで最高です。
&lt;ul&gt;
&lt;li&gt;しかし、通勤中とか電車の中で使うには重いから持ち運びに不便で、ジムでトレッドミルやスピニングバイクを漕いでいるときに使う物を探していました。&lt;/li&gt;
&lt;li&gt;電車の中で&lt;a href=&quot;http://rebuild.fm/&quot;&gt;rebuild.fm&lt;/a&gt;を聞きたい。&lt;/li&gt;
&lt;li&gt;Bluetoothのイヤホンで4000円ぐらいの物を昔買いましたが、音質が悪いしフィット感も悪くて困ってました。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;結果：Beoplay E8 を買いました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;要望整理&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Bluetooth&lt;/li&gt;
&lt;li&gt;音質良い&lt;/li&gt;
&lt;li&gt;生活防水&lt;/li&gt;
&lt;li&gt;エコライザーあり&lt;/li&gt;
&lt;li&gt;電池は3時間は持つ&lt;/li&gt;
&lt;li&gt;見た目がゴツゴツしていない&lt;/li&gt;
&lt;li&gt;ちゃんとしたブランド&lt;/li&gt;
&lt;li&gt;耳からうどんは垂らしたくない&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;候補&lt;/h2&gt;
&lt;p&gt;この2つ。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B074WTKWG6&quot;}
::amazon{asin=&quot;B074TBPV5Z&quot;}&lt;/p&gt;
&lt;h2&gt;比較&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.rtings.com/headphones/tools/compare/bose-soundsport-free-vs-b-o-play-e8/560/566&quot;&gt;比較サイト&lt;/a&gt;とかにも掲載あるけど、自分的に。&lt;br /&gt;
（っていうか、この比較サイトすごい細かくKPIが別れていて凄い！）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;見た目：Boseは大きくて見た目が微妙。E8のほうが小さくて良い。&lt;/li&gt;
&lt;li&gt;音：Boseの方がちょっとよいけど、Semi-openなので、リスニング状態が悪そう。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/07/Screen-Shot-2018-07-10-at-10.07.24.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;金額：海外で、&lt;strong&gt;SoundFreeは2万円ぐらい。E8は3万円ぐらい。&lt;/strong&gt; 日本では、両方3万円ぐらい。よって、SoundFreeは損している感じがする！（海外で買うなら問題ないけど）&lt;/li&gt;
&lt;li&gt;ブランド：&lt;a href=&quot;https://www.beoplay.com/en&quot;&gt;Beoplay&lt;/a&gt; って聞いたこと無いけど、世界的には高級ブランドということでメジャーらしい。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;B&amp;amp;O E8の使用感&lt;/h2&gt;
&lt;h3&gt;良い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;音は良い。問題無い。&lt;/li&gt;
&lt;li&gt;小さくて、見た目がスマートで良い。&lt;/li&gt;
&lt;li&gt;iOS/Androidアプリのエコライザーで音質を調整出来る。（デフォルトの音質だと微妙なので、アプリを入れてエコライザーを設定すべき！）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/07/IMG_4923.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;今のところのエコライザーの設定↓&lt;/p&gt;
&lt;h3&gt;悪い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;左耳だけ、1時間に数回音飛びする。&lt;/li&gt;
&lt;li&gt;インナーイヤーだから、運動している時に汗をかくと、耳とイヤホンの隙間に入ってきて、気持ち悪い。&lt;/li&gt;
&lt;li&gt;タッチで操作は、デリケートな操作を求められるから難しい。&lt;/li&gt;
&lt;li&gt;複数デバイスとペアリングしている場合、機器の切り替えがイヤホンから出来ない。別の端末に接続する場合は、端末側から接続してあげる必要がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;その後&lt;/h2&gt;
&lt;p&gt;Beoplay E8は音質はとても良いのですが、耐久性とフィット感に問題が有ります。&lt;/p&gt;
&lt;p&gt;まず、そんなに使っていないのにイヤホン本体のボンドづけしてある部分が剥がれて分離してきました。また、本体の音量を最大にしても小さい音でしか聞こえません。ファームウェアアップデートやリセット、再ペアリングなどを試してもだめでした。&lt;/p&gt;
&lt;p&gt;サポートに問い合わせたら、新品交換修理となるとのことで新古品で売られている商品より高い金額を請求されたのでサポートに出すことは諦めました。殆ど使っていないのに壊れたので悲しいです。&lt;/p&gt;
&lt;p&gt;フィット感に関しては、トレッドミルでランニング中に使うと耳から落ちてきます。やはり、小型ワイヤレスイヤホン開発の実績が少ないメーカーは良くないです。&lt;/p&gt;
</content:encoded></item><item><title>合同会社を作ってみたけど事務処理が複雑だったので流れまとめておく</title><link>https://blog.teraren.com/posts/company/</link><guid isPermaLink="true">https://blog.teraren.com/posts/company/</guid><description>freeeを使って合同会社を設立した体験記。総コスト約7万円+資本金、シーケンス図で手続きの全体像を整理。行政手続きの煩雑さとハマりどころを解説。</description><pubDate>Mon, 25 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;政府の推し進める&lt;a href=&quot;https://www.kantei.go.jp/jp/headline/ichiokusoukatsuyaku/hatarakikata.html&quot;&gt;働き方改革&lt;/a&gt;などで、個人のワーキングスタイルが多種多様になっていくだろう。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.freee.co.jp/launch/&quot;&gt;freee会社設立&lt;/a&gt;の説明を見ていると簡単そうだったのでやってみた。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;税金面などのメリットを生かすために法人を最小限の手続きで設立してみる。
&lt;ul&gt;
&lt;li&gt;法人の種別は合同会社で。個人プラスアルファぐらいの規模しか考えていないので。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;freeeを使ってみたが、落とし穴がたくさんありすぎたので自分なりに大きな流れをシーケンス図にまとめておく。
&lt;ul&gt;
&lt;li&gt;法人設立の方法をググってもサイトによって書いてあることがまちまちだったり、行政のサイトは相変わらずまとまっていなくてわかりづらい。&lt;/li&gt;
&lt;li&gt;どうして世の中にこのシーケンス図にまとまって居ないのか不思議。&lt;/li&gt;
&lt;li&gt;不正確なところもあると思うので参考程度に！どのくらい大変なのかを共有するのが目的。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;総コスト: 約7万円+資本金
&lt;ul&gt;
&lt;li&gt;会社印の3本セットは&lt;a href=&quot;https://hb.afl.rakuten.co.jp/hgc/16cd069d.07152461.16cd069e.8295d8f8/?pc=https%3A%2F%2Fitem.rakuten.co.jp%2Fkomakihanko%2Fc%2F0000000102%2F&amp;amp;m=https%3A%2F%2Fitem.rakuten.co.jp%2Fkomakihanko%2Fc%2F0000000102%2F&amp;amp;link_type=text&amp;amp;ut=eyJwYWdlIjoidXJsIiwidHlwZSI6InRlc3QiLCJjb2wiOjB9&quot;&gt;楽天&lt;/a&gt;で5000円ぐらい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;シーケンス図&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;前提条件
&lt;ul&gt;
&lt;li&gt;電子定款&lt;/li&gt;
&lt;li&gt;役員報酬は無し（Minium Value Productのアプローチで。純利益が積み上がるようになってきたら考える）&lt;/li&gt;
&lt;li&gt;従業員なし&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/06/sequence.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;法人設立は時間がかかる。慣れている人ならすぐなんだろうけど、正確な手順書が存在しないし、地方などによってフォーマットが異なるから一概に定型化できない問題がある。
&lt;ul&gt;
&lt;li&gt;暇な人はやっても良いけど、外注したほうが良いレベル。設立作業は滅多に行わないしナレッジを溜めたところで業務の役に立たない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;freeeの資料はわかりやすいが、Webサイトに不備があったり、提出書類や提出先が間違って記載されていたりして振り回された。&lt;/li&gt;
&lt;li&gt;たぶん、なんだかんだで24時間ぐらいは費やしたと思う。3営業日分に値する。この時間を別の事に使った方が有意義。ケチるところでは無かった。&lt;/li&gt;
&lt;li&gt;アナログな処理が多すぎて萎える。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>RTX1200 ファームウェアアップデート</title><link>https://blog.teraren.com/posts/rtx1200-firmware/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rtx1200-firmware/</guid><description>YAMAHA RTX1200のファームウェアをブラウザ経由でなくtelnetコンソールからアップデートする手順と注意点のまとめ</description><pubDate>Mon, 18 Jun 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;httpのブラウザ経由だとなぜかアップデートが上手くいかなかったのでコンソールでやる方法。&lt;/p&gt;
&lt;h2&gt;ファームウェアのアップデート&lt;/h2&gt;
&lt;p&gt;ファームウェアのバックアップ中はスイッチの処理は止まるのでご注意を。しかも、1分ぐらいかかった感じがします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is &apos;^]&apos;.

Password:

RTX1200 Rev.10.01.75 (Fri Feb 16 13:38:37 2018)
  Copyright (c) 1994-2018 Yamaha Corporation. All Rights Reserved.
  Copyright (c) 1991-1997 Regents of the University of California.
  Copyright (c) 1995-2004 Jean-loup Gailly and Mark Adler.
  Copyright (c) 1998-2000 Tokyo Institute of Technology.
  Copyright (c) 2000 Japan Advanced Institute of Science and Technology, HOKURIKU.
  Copyright (c) 2002 RSA Security Inc. All rights reserved.
  Copyright (c) 1997-2010 University of Cambridge. All rights reserved.
  Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, All rights reserved.
  Copyright (c) 1995 Tatu Ylonen , Espoo, Finland All rights reserved.
  Copyright (c) 1998-2004 The OpenSSL Project.  All rights reserved.
  Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) All rights reserved.
  Copyright (c) 2006 Digital Arts Inc. All Rights Reserved.
  Copyright (C) 1994-2012 Lua.org, PUC-Rio.
  Copyright (c) 1988-1992 Carnegie Mellon University All Rights Reserved.
  Copyright (C) 2004-2007 Diego Nehab. All rights reserved.
  Copyright (c) 2005 JSON.org
00:a0:de:68:90:0c, 00:a0:de:68:90:0d, 00:a0:de:68:90:0e
Memory 128Mbytes, 3LAN, 1BRI
&amp;gt; administrator
Password:
# show exec list
No.   Revision
----- --------------------------------
* 0   Rev.10.01.75
----- --------------------------------
# copy exec 0 1
コピー中... EXEC0 終了
# show config list
No.   Date       Time     Size    Sects   Comment
----- ---------- -------- ------- ------- ------------------------------------
* 0   2018/04/30 18:16:29    8578 126/126
  0.1 2018/04/07 21:39:19    8554 124/124
  0.2 2018/04/07 21:36:35    8571 125/125
  4   2018/03/21 22:20:59    8045 123/123
----- ---------- -------- ------- ------- ------------------------------------
# copy config 0 4
# show config list
No.   Date       Time     Size    Sects   Comment
----- ---------- -------- ------- ------- ------------------------------------
* 0   2018/04/30 18:16:29    8578 126/126
  0.1 2018/04/07 21:39:19    8554 124/124
  0.2 2018/04/07 21:36:35    8571 125/125
  4   2018/06/18 00:44:31    8578 122/122
  4.1 2018/03/21 22:20:59    8045 123/123
----- ---------- -------- ------- ------- ------------------------------------
# http revision-up go
新しいリビジョンのファームウェアが存在します
現在のリビジョン: Rev.10.01.75
新しいリビジョン: Rev.10.01.76
更新しますか? (Y/N)Y
ダウンロード中...: 100% ( 5076848/ 5076848bytes)
リビジョンアップ中...終了
Restarting ...
Connection closed by foreign host.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ファームウェアがアップデートされたことの確認&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is &apos;^]&apos;.

Password:

RTX1200 Rev.10.01.76 (Fri Apr 13 12:25:45 2018)
  Copyright (c) 1994-2018 Yamaha Corporation. All Rights Reserved.
  Copyright (c) 1991-1997 Regents of the University of California.
  Copyright (c) 1995-2004 Jean-loup Gailly and Mark Adler.
  Copyright (c) 1998-2000 Tokyo Institute of Technology.
  Copyright (c) 2000 Japan Advanced Institute of Science and Technology, HOKURIKU.
  Copyright (c) 2002 RSA Security Inc. All rights reserved.
  Copyright (c) 1997-2010 University of Cambridge. All rights reserved.
  Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, All rights reserved.
  Copyright (c) 1995 Tatu Ylonen , Espoo, Finland All rights reserved.
  Copyright (c) 1998-2004 The OpenSSL Project.  All rights reserved.
  Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) All rights reserved.
  Copyright (c) 2006 Digital Arts Inc. All Rights Reserved.
  Copyright (C) 1994-2012 Lua.org, PUC-Rio.
  Copyright (c) 1988-1992 Carnegie Mellon University All Rights Reserved.
  Copyright (C) 2004-2007 Diego Nehab. All rights reserved.
  Copyright (c) 2005 JSON.org
00:a0:de:68:90:0c, 00:a0:de:68:90:0d, 00:a0:de:68:90:0e
Memory 128Mbytes, 3LAN, 1BRI

The login password is factory default setting. Please request an administrator to change the password by the &apos;login password&apos; command.
&amp;gt; administrator
Password:
# show exec list
No.   Revision
----- --------------------------------
* 0   Rev.10.01.76
  1   Rev.10.01.75
----- --------------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;::amazon{asin=&quot;B0989BCKZY&quot;}&lt;/p&gt;
</content:encoded></item><item><title>basic認証をGETパラメータでスキップするサービス作った</title><link>https://blog.teraren.com/posts/basic-auth-skip-by-get-parameter/</link><guid isPermaLink="true">https://blog.teraren.com/posts/basic-auth-skip-by-get-parameter/</guid><description>Google CalendarなどBasic認証非対応のHTTPクライアント向けに、GETパラメータで認証情報を渡してBasic認証を通過させるOSSプロキシサービスの作成経緯と使い方。</description><pubDate>Fri, 25 May 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GETパラメータでbasic認証の情報を渡すと、basic認証が使えないhttpクライアントでもbasic認証を通過出来るようにするサービス。&lt;/li&gt;
&lt;li&gt;2年前に作ったのですが、blogとして記事を書いていませんでした。&lt;/li&gt;
&lt;li&gt;OSSです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://github.com/matsubo/http-basic-auth-proxy&lt;/p&gt;
&lt;h2&gt;いきさつ（ユースケース）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;とあるグループウェアがbasic認証付きでicalのfeedが吐かれる。&lt;/li&gt;
&lt;li&gt;google calendarで上記のbasic認証がかかったicalを直接取得出来ない。
&lt;ul&gt;
&lt;li&gt;Google calendarが http://user:password@host/ical というURLスキームに対応していない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;basic認証を何らかの方法で突破しなければいけない。&lt;/li&gt;
&lt;li&gt;ハードコードするようなリバースプロクシを書いても良いけど、同じように困っている人が居るはずなのでサービスとして作ろう。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/05/ed4d44f0-acdc-11e6-9ab7-5d8cf8fd3a4a.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;使い方&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;basic認証のかかっているURLが以下とすると
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;http://example.com/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;ID: &lt;code&gt;username&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;PW: &lt;code&gt;passw0rd&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;以下のURLでbasic認証を回避出来る
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;https://http-basic-auth-proxy.herokuapp.com/proxy.php?http_basic_user=username&amp;amp;http_basic_password=passw0rd&amp;amp;http_host_path=example.com/&amp;amp;additional=parameters&amp;amp;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;こだわりの点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;basic認証情報をGETパラメータに載せることになるのでセキュリティが気になります。第三者のサービスに渡すのが嫌な場合は自前のherokuに立てられるようにOSSです。&lt;/li&gt;
&lt;li&gt;herokuでボタン1発で自前のherokuアカウントにデプロイできます。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://http-basic-auth-proxy.herokuapp.com/&quot;&gt;https://http-basic-auth-proxy.herokuapp.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>静的サイトの自動デプロイ github -&gt; CircleCI -&gt; S3 -&gt; CloudFront</title><link>https://blog.teraren.com/posts/github-circleci-s3-cloudfront-deploy/</link><guid isPermaLink="true">https://blog.teraren.com/posts/github-circleci-s3-cloudfront-deploy/</guid><description>GitHubへのpushを契機にCircleCIが自動でS3デプロイとCloudFrontキャッシュ削除を行うCI/CD設定。config.ymlの具体例とAWSアクセスキーの環境変数設定方法を解説。</description><pubDate>Fri, 25 May 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;コーポレートページや、ランディングページなどの静的サイトを自動デプロイする設定をしました。&lt;/li&gt;
&lt;li&gt;AWSの基本設定に追加して、CircleCIの設定ファイルを1つだけ追加するのみで出来ます。&lt;/li&gt;
&lt;li&gt;一般的な構成のはずなのに、設定ファイルが出回っていなかったので作りました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;前提となるサービス構成&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CDPの&lt;a href=&quot;http://aws.clouddesignpattern.org/index.php/CDP:Cache_Distribution%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3&quot;&gt;Cache Distribution&lt;/a&gt;パターンで静的サイトを運用している場合。&lt;/li&gt;
&lt;li&gt;S3(Public Hosting) -&amp;gt; CloudFront (AWS Certificate ManagerでSSL配信) &lt;a href=&quot;https://qiita.com/Ichiro_Tsuji/items/c174d580587a622d3358&quot;&gt;やり方&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/05/cache-distribution-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;設定方法&lt;/h2&gt;
&lt;h3&gt;CircleCI&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;CircleCIの管理画面から、githubと連携する。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;以下の設定を&lt;code&gt;.circleci/config.yml&lt;/code&gt;に入れる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;括弧内は、自分の環境に合わせる。&lt;/li&gt;
&lt;li&gt;S3のbucket名&lt;/li&gt;
&lt;li&gt;CloudFrontのID&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CircleCIの環境変数にAWSのアクセスキーを入れる。権限は、S3の読み書き、CloudFrontのVarinsh追加。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;githubへpushすると2分後ぐらいにはS3に入り、その1分後にはCloudFrontのキャッシュも消える。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CircleCIのビルドには以下のように出る。buildが走り、deployが走る。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/05/CircleCI.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;考察&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;良い点
&lt;ul&gt;
&lt;li&gt;デザイナーやビジネスサイドに更新作業を委譲できる。&lt;/li&gt;
&lt;li&gt;無料&lt;/li&gt;
&lt;li&gt;CircleCI 2.0のラーニングが出来た。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;悪い点
&lt;ul&gt;
&lt;li&gt;新しめの&lt;code&gt;awscli&lt;/code&gt;だとパラメータが少なくて設定が楽（この記事の方法）。そのために、最新の&lt;code&gt;awscli&lt;/code&gt;をインストールする手順がちょっとかっこ悪い。&lt;/li&gt;
&lt;li&gt;dockerイメージのキャッシュをすればもっと速くなるけど、設定ファイルが汚れるから今度。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>hostコマンドが信頼出来ない場合がある</title><link>https://blog.teraren.com/posts/host-d-option/</link><guid isPermaLink="true">https://blog.teraren.com/posts/host-d-option/</guid><description>hostコマンドで-dオプションの有無によってDNSの問い合わせ結果が変わる原因を調査。TCPとUDPの違いやDNSパケットサイズが挙動に影響することを解説します。</description><pubDate>Tue, 24 Apr 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;挙動が怪しい&lt;/h2&gt;
&lt;p&gt;どうして &lt;code&gt;-d&lt;/code&gt; オプションを付けると結果が違うのか？&lt;/p&gt;
&lt;p&gt;パターン1。見つからない。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% host   -t ns recall.nichigas.co.jp. gntdns02.alpha-plt.jp
Using domain server:
Name: gntdns02.alpha-plt.jp
Address: 157.205.136.242#53
Aliases:

recall.nichigas.co.jp has no NS record
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;パターン2。&lt;code&gt;-d&lt;/code&gt;を付けると見つかる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% host -d  -t ns recall.nichigas.co.jp. gntdns02.alpha-plt.jp
Trying &quot;recall.nichigas.co.jp&quot;
Using domain server:
Name: gntdns02.alpha-plt.jp
Address: 157.205.136.242#53
Aliases:

;; -&amp;gt;&amp;gt;HEADER&amp;lt;&amp;lt;- opcode: QUERY, status: NOERROR, id: 59337
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 0

;; QUESTION SECTION:
;recall.nichigas.co.jp.   IN  NS

;; AUTHORITY SECTION:
recall.nichigas.co.jp.  18000 IN  NS  ns-907.awsdns-49.net.
recall.nichigas.co.jp.  18000 IN  NS  ns-1293.awsdns-33.org.
recall.nichigas.co.jp.  18000 IN  NS  ns-2044.awsdns-63.co.uk.
recall.nichigas.co.jp.  18000 IN  NS  ns-429.awsdns-53.com.

Received 179 bytes from 157.205.136.242#53 in 6 ms
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;パケットは同じなのに。&lt;/p&gt;
&lt;p&gt;パターン1&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# host   -t ns recall.nichigas.co.jp. gntdns02.alpha-plt.jp
21:50:32.985406 IP (tos 0x0, ttl 64, id 37754, offset 0, flags [none], proto UDP (17), length 67)
    10.2.115.113.62866 &amp;gt; 157.205.136.242.53: [udp sum ok] 55210+ NS? recall.nichigas.co.jp. (39)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;パターン2&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# host -d  -t ns recall.nichigas.co.jp. gntdns02.alpha-plt.jp
21:50:36.674210 IP (tos 0x0, ttl 64, id 59469, offset 0, flags [none], proto UDP (17), length 67)
    10.2.115.113.49603 &amp;gt; 157.205.136.242.53: [udp sum ok] 15839+ NS? recall.nichigas.co.jp. (39)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;試行錯誤&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;macosもLinuxも。&lt;/li&gt;
&lt;li&gt;digコマンドはちゃんと返ってきているので、パターン1の挙動が変。&lt;/li&gt;
&lt;li&gt;TCPを使うために&lt;code&gt;-T&lt;/code&gt;オプションを付けても同じ。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;パターン1の&lt;code&gt;-T&lt;/code&gt;オプション。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;22:25:25.985128 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 64)
    10.2.115.113.60081 &amp;gt; gntdns02.alpha-plt.jp.domain: Flags [SEW], cksum 0x64d1 (correct), seq 2201148386, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 659143667 ecr 0,sackOK,eol], length 0
22:25:26.000590 IP (tos 0x0, ttl 48, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    gntdns02.alpha-plt.jp.domain &amp;gt; 10.2.115.113.60081: Flags [S.E], cksum 0xc875 (correct), seq 3011752540, ack 2201148387, win 14480, options [mss 1386,sackOK,TS val 3495313232 ecr 659143667,nop,wscale 7], length 0
22:25:26.000623 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 52)
    10.2.115.113.60081 &amp;gt; gntdns02.alpha-plt.jp.domain: Flags [.], cksum 0x1f9f (correct), seq 1, ack 1, win 4122, options [nop,nop,TS val 659143682 ecr 3495313232], length 0
22:25:26.000711 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 93)
    10.2.115.113.60081 &amp;gt; gntdns02.alpha-plt.jp.domain: Flags [P.], cksum 0x6207 (correct), seq 1:42, ack 1, win 4122, options [nop,nop,TS val 659143682 ecr 3495313232], length 411906+ NS? recall.nichigas.co.jp. (39)
22:25:26.011217 IP (tos 0x0, ttl 48, id 36099, offset 0, flags [DF], proto TCP (6), length 52)
    gntdns02.alpha-plt.jp.domain &amp;gt; 10.2.115.113.60081: Flags [.], cksum 0x2f10 (correct), seq 1, ack 42, win 114, options [nop,nop,TS val 3495313246 ecr 659143682], length 0
22:25:26.011229 IP (tos 0x2,ECT(0), ttl 48, id 36100, offset 0, flags [DF], proto TCP (6), length 233)
    gntdns02.alpha-plt.jp.domain &amp;gt; 10.2.115.113.60081: Flags [P.], cksum 0x5573 (correct), seq 1:182, ack 42, win 114, options [nop,nop,TS val 3495313247 ecr 659143682], length 1811906- q: NS? recall.nichigas.co.jp. 0/4/0 ns: recall.nichigas.co.jp. NS ns-2044.awsdns-63.co.uk., recall.nichigas.co.jp. NS ns-907.awsdns-49.net., recall.nichigas.co.jp. NS ns-1293.awsdns-33.org., recall.nichigas.co.jp. NS ns-429.awsdns-53.com. (179)
22:25:26.011360 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 52)
    10.2.115.113.60081 &amp;gt; gntdns02.alpha-plt.jp.domain: Flags [.], cksum 0x1eae (correct), seq 42, ack 182, win 4116, options [nop,nop,TS val 659143692 ecr 3495313247], length 0
22:25:26.011860 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 52)
    10.2.115.113.60081 &amp;gt; gntdns02.alpha-plt.jp.domain: Flags [F.], cksum 0x1ead (correct), seq 42, ack 182, win 4116, options [nop,nop,TS val 659143692 ecr 3495313247], length 0
22:25:26.022157 IP (tos 0x0, ttl 48, id 36101, offset 0, flags [DF], proto TCP (6), length 52)
    gntdns02.alpha-plt.jp.domain &amp;gt; 10.2.115.113.60081: Flags [F.], cksum 0x2e42 (correct), seq 182, ack 43, win 114, options [nop,nop,TS val 3495313259 ecr 659143692], length 0
22:25:26.022197 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 52)
    10.2.115.113.60081 &amp;gt; gntdns02.alpha-plt.jp.domain: Flags [.], cksum 0x1e96 (correct), seq 43, ack 183, win 4116, options [nop,nop,TS val 659143702 ecr 3495313259], length 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;でも、他のドメインならちゃんと返ってくる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% host -t ns teraren.com
teraren.com name server ns1.gslb2.sakura.ne.jp.
teraren.com name server ns2.gslb2.sakura.ne.jp.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同じzoneサーバの別のNSも同様の挙動&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% host -t ns weborder.nichigas.co.jp. gntdns02.alpha-plt.jp
Using domain server:
Name: gntdns02.alpha-plt.jp
Address: 157.205.136.242#53
Aliases:

weborder.nichigas.co.jp has no NS record
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;% host -t ns www.nichigas.co.jp. gntdns02.alpha-plt.jp
Using domain server:
Name: gntdns02.alpha-plt.jp
Address: 157.205.136.242#53
Aliases:

www.nichigas.co.jp has no NS record
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;現時点での結論&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;hostコマンド（−dオプション無し）と、特定のネームサーバの場合に結果が本来と違う。&lt;/li&gt;
&lt;li&gt;トラブルシュートをする戦闘力が足りない。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>今時のメールアドレス正規表現</title><link>https://blog.teraren.com/posts/qiita-20190409-3dfb1ddb6e155c44643b/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20190409-3dfb1ddb6e155c44643b/</guid><description>email_validator gemのv2での正規表現変更を調査し、実運用でのメールアドレスバリデーション方針を考察。</description><pubDate>Mon, 09 Apr 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;メールアドレス入力フォームの検証に正規表現でチェックしています。&lt;/li&gt;
&lt;li&gt;このたび、メールアドレスの検証に使っている正規表現が書かれている gem にて、メールアドレスの検証ロジックに大幅な変更が入ったので調査してみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;きっかけ
&lt;ul&gt;
&lt;li&gt;Web アプリケーションのメールアドレスの validation には &lt;code&gt;email_validator&lt;/code&gt; という gem を使っていました。これが v2 からすごい緩いバリデーションになっていました。
&lt;ul&gt;
&lt;li&gt;https://github.com/balexand/email_validator/blob/a479ff6bf9305ba7944df459402664fc9d74a339/lib/email_validator.rb#L13&lt;/li&gt;
&lt;li&gt;この &lt;a href=&quot;https://rubygems.org/gems/email_validator/&quot;&gt;gem&lt;/a&gt;は300万ダウンロードあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;理由
&lt;ul&gt;
&lt;li&gt;https://hackernoon.com/the-100-correct-way-to-validate-email-addresses-7c4818f24643
&lt;ul&gt;
&lt;li&gt;タイトルに文句がある方はこの記事へ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;https://hackernoon.com/how-to-reduce-incorrect-email-addresses-df3b70cb15a9&lt;/li&gt;
&lt;li&gt;https://en.wikipedia.org/wiki/Email_address&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;テストケース
&lt;ul&gt;
&lt;li&gt;https://github.com/balexand/email_validator/blob/v2.0.0/spec/email_validator_spec.rb#L25-L57&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実運用ではどうするか考える&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;AWS SES は &lt;code&gt;test＿test@example.com&lt;/code&gt; というマルチバイトを含んだメールアドレスは reject される。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ASCII 以外の文字列って、ユーザの入力ミスの可能性が 90％以上だろうし。悩ましい。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTML5 のブラウザ側の正規表現は、もっと厳しい。マルチバイトは許されない。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;実際は、v1.6 の &lt;code&gt;strict_mode&lt;/code&gt; オプションを使うのが良いのかなと。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://github.com/balexand/email_validator/blob/ef9c09161831946c5fb85e4273b2cc2a559cc758/lib/email_validator.rb#L11&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;v1.6 の strict な正規表現で怪しいメアドをあぶり出すショートコード&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;name_validation = &quot;-\\p{L}\\d+._&quot;
regex = /\A\s*([#{name_validation}]{1,64})@((?:[-\p{L}\d]+\.)+\p{L}{2,})\s*\z/i
User.all.select {|u| puts u.id unless u.email.match(regex) }
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;URI::MailTo::EMAIL_REGEXP&lt;/code&gt; もよさそう。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;/\A[a-zA-Z0-9.!\#$%&amp;amp;&apos;*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;結論&lt;/h2&gt;
&lt;p&gt;広く許容する場合は以下の正規表現。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[^\s]+@[^\s]+
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;解説：アットマークの直前がホワイトスペース以外かつ、アットマークの直後がホワイトスペース以外。&lt;/li&gt;
&lt;li&gt;参照：https://github.com/balexand/email_validator/blob/a479ff6bf9305ba7944df459402664fc9d74a339/lib/email_validator.rb#L13&lt;/li&gt;
&lt;li&gt;注意: 上記のメールアドレスの正規表現では valid だけど、AWS SES や別の MTA で弾かれる場合がある。
&lt;ul&gt;
&lt;li&gt;ユーザ登録を優先するか、メールの到達性を優先するかはサービスのポリシー次第で決める。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>so-net 光を契約。実測下り400Mbps,  上り800Mbps</title><link>https://blog.teraren.com/posts/sonet-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/sonet-benchmark/</guid><description>So-net光コラボレーションを契約し、YAMAHA RTX1200で運用した際の実測ベンチマーク結果と回線品質を詳細レポート</description><pubDate>Tue, 27 Mar 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;kakaku.comでインターネットの申し込みを調べても、制約事項が多すぎてどこのISPの割引が一番お得か良いかわからないし、どのISPも月額利用料が高めなので躊躇していました。&lt;/li&gt;
&lt;li&gt;還元率が高い大手電機量販店（ビックカメラ）に行きましたが、「ここ数年はあまりキャンペーンはやっていない」とのこと。kakaku.comの方がお得と店員に言われる。。。&lt;/li&gt;
&lt;li&gt;そして、これを申し込む。 &lt;a href=&quot;http://kakaku.com/bb/plan.asp?bb_planUnitCD=2651400&amp;amp;bb_pref=13&amp;amp;lid=bb_step_2-1-1&quot;&gt;So-net 光 コラボレーション (戸建)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ベストエフォートで、アップリンク、ダウンリンクそれぞれ1Gbps。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;物理回線は既に引かれていたので、立ち会い工事は無し。局内工事だけ。&lt;/li&gt;
&lt;li&gt;1週間ぐらいでメディアコンバータが送られてきた。&lt;/li&gt;
&lt;li&gt;ルータはヤフオクで買ったRTX1200で運用。（1万円ぐらい）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;お待ちかねのベンチマーク！！&lt;/p&gt;
&lt;p&gt;下りは100Mbpsちょっと、上りは800Mbps以上出ています！&lt;br /&gt;
そんなに上りは使わないので、ダウンロードが速いほうがうれしいのですが。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/03/Screen-Shot-2018-03-27-at-16.33.14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/03/Screen-Shot-2018-03-27-at-16.36.47.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接続先によっては下りは450Mbps出るので、プロバイダの問題では無さそう。すごい。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/03/Screen-Shot-2018-03-25-at-20.04.12.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;RTX1200のリソースモニタを見てみます。もう少しで1Gbpsなのに。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2018/03/Screen-Shot-2018-03-27-at-14.59.09.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;トラフィックの処理にCPUを使うんですね。CPUが限界に近いみたい。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;IPv6はまだ設定していないので、今後のTODO&lt;/li&gt;
&lt;li&gt;本来は家がnuroに対応していれば&lt;a href=&quot;http://www.nuro.jp/campaign/rmd/?recomndNo=dfs84206&quot;&gt;nuro&lt;/a&gt;に申し込みたかった&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B014CNJHE0&quot;}&lt;/p&gt;
</content:encoded></item><item><title>TTSとTTBを取得するrubygem作った</title><link>https://blog.teraren.com/posts/tts-ttb-rubygem/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tts-ttb-rubygem/</guid><description>経理処理で必要な三菱UFJ銀行のTTS・TTB為替レートをスクレイピングで取得するRuby gemを作成。CodeCoverage 100%・GitHub Actionsでの自動リリース設定も解説。</description><pubDate>Thu, 22 Feb 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;経理処理などで、TTS、TTB、TTMといった為替の値を使って処理する場合がある。&lt;/li&gt;
&lt;li&gt;日本では&lt;a href=&quot;http://www.murc-kawasesouba.jp/fx/past/index.php?id=180129&quot;&gt;東京三菱UFJ銀行&lt;/a&gt;が提供している為替の値を使うことがデファクトスタンダードになっている気がする。&lt;/li&gt;
&lt;li&gt;しかし、プログラム上から利用しやすい形態で情報が提供されていない。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そこで、rubyで&lt;a href=&quot;http://www.murc-kawasesouba.jp/fx/past/index.php?id=180129&quot;&gt;東京三菱UFJ銀行&lt;/a&gt;のTTS、TTBが掲載されているページをスクレイピングして取得するライブラリを書いてみました。&lt;/p&gt;
&lt;p&gt;https://github.com/matsubo/ttsttb&lt;/p&gt;
&lt;h2&gt;こだわりポイント&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;codecoverage 100%&lt;/li&gt;
&lt;li&gt;rubygemの自動リリース&lt;/li&gt;
&lt;li&gt;rubocopの自動実行&lt;/li&gt;
&lt;li&gt;rspecの自動実行&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ここまで準備しておけば、rubygemの開発をしてもらうときにオンボーディングがスムーズになると思います。&lt;/p&gt;
&lt;p&gt;CodeClimateのcoverage reportの連携は、Github Actionsの設定ファイルに以下のコードを追加するだけでできました。本当なら、1つ前に実行しているrspecの結果を流用したいのですがcoverageCommandパラメータが必須なので無駄ですが再実行しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- uses: paambaati/codeclimate-action@v3.0.0
  env:
    CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
  with:
    coverageCommand: bundle exec rspec
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>エストニアのe-Reidency（電子国民）取得方法</title><link>https://blog.teraren.com/posts/e-residency/</link><guid isPermaLink="true">https://blog.teraren.com/posts/e-residency/</guid><description>エストニアのe-Residency申請に必要な書類・費用・手順を実体験をもとに解説。日本にいながら欧州で法人設立・銀行口座開設が可能な制度の概要も紹介</description><pubDate>Fri, 09 Feb 2018 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;日本の&lt;a href=&quot;http://www.soumu.go.jp/kojinbango_card/01.html&quot;&gt;マイナンバー制度&lt;/a&gt;は政府目線の納税者囲い込みシステムというスコープでしか考えられていなく、ビジョンが無いです。そこで、世界的にも良いと評判のエストニアの電子政府を使ってみたくなりました。&lt;/li&gt;
&lt;li&gt;エストニアのe-Residencyとは、外国人がエストニアの電子国民になれる制度です。このe-Residencyを使うことで、日本にいながらエストニアに会社を作れたり、銀行口座を開設できたりします。&lt;/li&gt;
&lt;li&gt;エストニアのe-residencyの個人番号は、公開情報です。名前と同じで、名刺にも表示してあるレベルです。
&lt;ul&gt;
&lt;li&gt;そもそも、マイナンバーはなぜ番号が機密情報とあつかわれているのか謎。&lt;/li&gt;
&lt;li&gt;そして、なぜマイナンバーを持ち歩いてはいけないのか。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;申込に必要な物の準備&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;クレカ（The state fee for e-Resident digi-ID card is 100 euros.）&lt;/li&gt;
&lt;li&gt;パスポートのコピー画像データ&lt;/li&gt;
&lt;li&gt;自分の写真 (画像サイズ：600px x 750px)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;写真の要件↓&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;be a colour photo of 4 x 5 cm or approx. 1,6 x 2 inches, with print resolution of at least 300 dots per inch;&lt;/li&gt;
&lt;li&gt;be no more than 6 months old;&lt;/li&gt;
&lt;li&gt;show you looking directly into the camera (upon photographing the camera must be on the same level with your face);&lt;/li&gt;
&lt;li&gt;show you alone on a plain light-coloured background;&lt;/li&gt;
&lt;li&gt;enable to verify your identity unambiguously.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;申込&lt;/h2&gt;
&lt;p&gt;2018/1/10 に&lt;a href=&quot;https://e-resident.gov.ee/&quot;&gt;申込&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;件名：Your e-Residency application has been received&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dear Applicant,&lt;/p&gt;
&lt;p&gt;Thank you for applying for e-Residency. Your application has been submitted and the Estonian Police and Border Guard Board will keep you informed about the application process by sending progress reports to the e-mail address you provided in the application. If your application is approved, you will be notified, and the e-resident digital ID will be sent to your chosen pickup location.&lt;/p&gt;
&lt;p&gt;For additional questions please see:&lt;/p&gt;
&lt;p&gt;With best regards,&lt;/p&gt;
&lt;p&gt;Estonian Police and Border Guard Board &amp;amp; Estonian e-Residency Program team&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;「受理した」とメールが来た&lt;/h2&gt;
&lt;p&gt;2018/2/6&lt;/p&gt;
&lt;p&gt;約1ヶ月待たされる。&lt;/p&gt;
&lt;p&gt;件名：E-Residency Digi-ID — e-Residency granted&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Dear YUKI MATSUKURA,&lt;/p&gt;
&lt;p&gt;Estonian Police and Border Guard Board has granted e-Residency to YUKI MATSUKURA born on 04.06.1982.&lt;/p&gt;
&lt;p&gt;You will be notified upon the document’s arrival to the place of issue marked on the application form.&lt;/p&gt;
&lt;p&gt;Sincerely,&lt;br /&gt;
Police and Border Guard Board&lt;br /&gt;
xxxxx.xxxx.xx&lt;br /&gt;
xxxxx@xxxxxx.xx&lt;br /&gt;
Client information (+372) 612 3000&lt;/p&gt;
&lt;p&gt;e-Residency support: xxxxxx@xxxx.xxx&lt;/p&gt;
&lt;p&gt;Please do not reply to this automatic notification!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;待機&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1.5ヶ月ぐらい待機したと思います。&lt;/li&gt;
&lt;li&gt;エストニア大使館からメールが来て、取りに行く予約をメールでやりとりします。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;受け取り&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-8.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;早く着きすぎたので、近くのカフェで仕事。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-9.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-11.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;エストニア共和国大使館。この建物で正しい。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;約束の時間に、インターホンを押しても出てこない。。。何回も押しまくりました。&lt;/li&gt;
&lt;li&gt;仕方が無いので周辺を散歩して10分後ぐらいに戻ってきて、インターホンを押したら人が出て、中に入れてもらえました。&lt;/li&gt;
&lt;li&gt;英語で、e-Residencyの目的を聞かれたり、職業とかを聞かれました。&lt;/li&gt;
&lt;li&gt;指紋を登録したりしました。&lt;/li&gt;
&lt;li&gt;あと、使い方とかを丁寧に説明してくれました。20分ぐらいかかりました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-13.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;パッケージがかっこいい&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-14.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;カードリーダーとカードが入っています&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-15.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;カードリーダーが機能的。住基カードとリーダーの比じゃ無い。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/03/image-16.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;色々出来るみたい。でも、まずは銀行口座が必要みたい。それが大変。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;説明書通りに、DigiDoc clientを入れたりして一通り遊んでみて終了。&lt;/li&gt;
&lt;li&gt;目的が無いから特にやる事が無いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ネクストステップ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;エストニアへ視察に行きたい&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Faradayでproxyサーバを指定する</title><link>https://blog.teraren.com/posts/qiita-20171116-24d61f3869222ded0b5b/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20171116-24d61f3869222ded0b5b/</guid><description>Faradayのオフィシャルドキュメントに書いてないので防備録。</description><pubDate>Thu, 16 Nov 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/lostisland/faraday&quot;&gt;Faraday&lt;/a&gt;のオフィシャルドキュメントに書いてないので防備録。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;irb(main):004:0&amp;gt; Faraday.new(&apos;http://example.com&apos;, proxy: &apos;http://103.238.225.61:3128/&apos; ).get(&apos;&apos;)
=&amp;gt; #&amp;lt;Faraday::Response:0x007ff80b23ba80 @on_complete_callbacks=[], @env=#&amp;lt;Faraday::Env @method=:get @body=&quot;&amp;lt;!doctype html&amp;gt;\n&amp;lt;html&amp;gt;\n&amp;lt;head&amp;gt;\n    &amp;lt;title&amp;gt;Example Domain&amp;lt;/title&amp;gt;\n\n    &amp;lt;meta charset=\&quot;utf-8\&quot; /&amp;gt;\n    &amp;lt;meta http-equiv=\&quot;Content-type\&quot; content=\&quot;text/html; charset=utf-8\&quot; /&amp;gt;\n    &amp;lt;meta name=\&quot;viewport\&quot; content=\&quot;width=device-width, initial-scale=1\&quot; /&amp;gt;\n    &amp;lt;style type=\&quot;text/css\&quot;&amp;gt;\n    body {\n        background-color: #f0f0f2;\n        margin: 0;\n        padding: 0;\n        font-family: \&quot;Open Sans\&quot;, \&quot;Helvetica Neue\&quot;, Helvetica, Arial, sans-serif;\n        \n    }\n    div {\n        width: 600px;\n        margin: 5em auto;\n        padding: 50px;\n        background-color: #fff;\n        border-radius: 1em;\n    }\n    a:link, a:visited {\n        color: #38488f;\n        text-decoration: none;\n    }\n    @media (max-width: 700px) {\n        body {\n            background-color: #fff;\n        }\n        div {\n            width: auto;\n            margin: 0 auto;\n            border-radius: 0;\n            padding: 1em;\n        }\n    }\n    &amp;lt;/style&amp;gt;    \n&amp;lt;/head&amp;gt;\n\n&amp;lt;body&amp;gt;\n&amp;lt;div&amp;gt;\n    &amp;lt;h1&amp;gt;Example Domain&amp;lt;/h1&amp;gt;\n    &amp;lt;p&amp;gt;This domain is established to be used for illustrative examples in documents. You may use this\n    domain in examples without prior coordination or asking for permission.&amp;lt;/p&amp;gt;\n    &amp;lt;p&amp;gt;&amp;lt;a href=\&quot;http://www.iana.org/domains/example\&quot;&amp;gt;More information...&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;\n&amp;lt;/div&amp;gt;\n&amp;lt;/body&amp;gt;\n&amp;lt;/html&amp;gt;\n&quot; @url=#&amp;lt;URI::HTTP http://example.com/&amp;gt; @request=#&amp;lt;Faraday::RequestOptions proxy=#&amp;lt;Faraday::ProxyOptions uri=#&amp;lt;URI::HTTP http://103.238.225.61:3128/&amp;gt;&amp;gt;&amp;gt; @request_headers={&quot;User-Agent&quot;=&amp;gt;&quot;Faraday v0.12.0.1&quot;} @ssl=#&amp;lt;Faraday::SSLOptions (empty)&amp;gt; @response=#&amp;lt;Faraday::Response:0x007ff80b23ba80 ...&amp;gt; @response_headers={&quot;accept-ranges&quot;=&amp;gt;&quot;bytes&quot;, &quot;cache-control&quot;=&amp;gt;&quot;max-age=604800&quot;, &quot;content-type&quot;=&amp;gt;&quot;text/html&quot;, &quot;date&quot;=&amp;gt;&quot;Thu, 16 Nov 2017 09:08:11 GMT&quot;, &quot;etag&quot;=&amp;gt;&quot;\&quot;359670651+gzip\&quot;&quot;, &quot;expires&quot;=&amp;gt;&quot;Thu, 23 Nov 2017 09:08:11 GMT&quot;, &quot;last-modified&quot;=&amp;gt;&quot;Fri, 09 Aug 2013 23:54:35 GMT&quot;, &quot;server&quot;=&amp;gt;&quot;ECS (rhv/818F)&quot;, &quot;vary&quot;=&amp;gt;&quot;Accept-Encoding&quot;, &quot;x-cache&quot;=&amp;gt;&quot;HIT, MISS from www.54sdqz.com&quot;, &quot;content-length&quot;=&amp;gt;&quot;606&quot;, &quot;x-cache-lookup&quot;=&amp;gt;&quot;MISS from www.54sdqz.com:3128&quot;, &quot;via&quot;=&amp;gt;&quot;1.0 www.54sdqz.com (squid/3.1.23)&quot;, &quot;connection&quot;=&amp;gt;&quot;close&quot;} @status=200 @reason_phrase=&quot;OK&quot;&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;open proxy のアドレスは &lt;a href=&quot;https://www.proxynova.com/proxy-server-list/&quot;&gt;ここ&lt;/a&gt;から適当に拾ってきました。&lt;/p&gt;
</content:encoded></item><item><title>railsをdockerで構築して、Host &apos;172.18.0.5&apos; is not allowed to connect to this MySQL server</title><link>https://blog.teraren.com/posts/rails-docker-host-is-not-allowed-to-connect-to-this-mysql-server/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-docker-host-is-not-allowed-to-connect-to-this-mysql-server/</guid><description>railsをdockerで構築して、Host &apos;172.18.0.5&apos; is not allowed to connect to this MySQL server</description><pubDate>Sat, 11 Nov 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;dockerをクリーンインストールしたら繋がらなくなった&lt;/li&gt;
&lt;li&gt;コードを追っていく必要あって、ちょっと面倒だった&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;トレース&lt;/h2&gt;
&lt;p&gt;調べた流れ&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mysqlの権限が無くなっているっぽいから、docker-compose execして、mysqlの中身を見てみると、からっぽ。rootのパスワードも設定されていない状態。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;host&lt;/code&gt; テーブルに許可情報を入れようと思って、&lt;a href=&quot;https://github.com/docker-library/mysql/blob/883703dfb30d9c197e0059a669c4bb64d55f6e0d/5.7/docker-entrypoint.sh#L129-L139&quot;&gt;entry-point.sh&lt;/a&gt; を見てみて、&lt;code&gt;MYSQL_ROOT_HOST&lt;/code&gt; を設定したりしたけど、実行されていない。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/docker-library/mysql/blob/883703dfb30d9c197e0059a669c4bb64d55f6e0d/5.7/docker-entrypoint.sh#L129-L139&quot;&gt;このあたり&lt;/a&gt; のコードが実行されていれば良いのだけれど、実行されていない。&lt;/li&gt;
&lt;li&gt;もうすこし &lt;code&gt;entry-point.sh&lt;/code&gt;を見てみると、mysqlのデータディレクトリの存在チェックが行われている。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最終的には、docker-compose.ymlで定義してあるvolumeの中身を消して、docker-compose upしたら直った。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker compose down -v
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;発生原因ちょっと謎。docker-composeとかdockerでmysqlを構築していて、volumeをデータディレクトリに使っている場合に発生する。&lt;/li&gt;
&lt;li&gt;発生原因が謎。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>TLS 1.1以下の対応を無くし、TLS 1.2と1.3だけを有効化</title><link>https://blog.teraren.com/posts/tls-1-3-support/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tls-1-3-support/</guid><description>PCI DSS 3.2への準拠を目的にnginxでTLS 1.1以下を無効化し、TLS 1.2と1.3のみを有効にするssl_protocols設定の方法とssllabsでの検証結果を解説します。</description><pubDate>Mon, 30 Oct 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PCI DSS 3.2では、SSLとTLS1.1は2018年6月28日までに無くさなければいけないと明示している。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.pcisecuritystandards.org/are-you-ready-for-30-june-2018-sayin-goodbye-to-ssl-early-tls&quot;&gt;https://blog.pcisecuritystandards.org/are-you-ready-for-30-june-2018-sayin-goodbye-to-ssl-early-tls&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Visaは2018年2月にTLS1.1以下を無効にする主旨を発表し、各プログラミング言語に応じた移行方法を出している。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://community.developer.visa.com/t5/Developer-Tools/Reducing-Risk-TLS-1-2-Mandatory-Upgrade-Details/ba-p/6691?elqTrackId=807630e0dc9c4221ae723c312a8a2278&amp;amp;elq=b5307826a50a4d92bb1741bf56ae0558&amp;amp;elqaid=749&amp;amp;elqat=1&amp;amp;elqCampaignId=293&quot;&gt;https://community.developer.visa.com/t5/Developer-Tools/Reducing-Risk-TLS-1-2-Mandatory-Upgrade-Details/ba-p/6691?elqTrackId=807630e0dc9c4221ae723c312a8a2278&amp;amp;elq=b5307826a50a4d92bb1741bf56ae0558&amp;amp;elqaid=749&amp;amp;elqat=1&amp;amp;elqCampaignId=293&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;最近の流れ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;新規でhttpsサーバを構築するならば、TLS1.2のみを有効にしておく&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_1.3_.28draft.29&quot;&gt;TLS1.3は現在Working Draft&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.wolfssl.jp/wolfblog/2017/06/16/tls1-2-tls1-3/&quot;&gt;TLS1.2と1.3の違い&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;このサイトで、TLS 1.3を使えるように設定してみました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nginx 1.12を使っていましたが、nginxはバージョン1.13からTLS 1.3 draftに対応しているので、nginxを1.13にアップグレードしました。&lt;/li&gt;
&lt;li&gt;ssl関連の設定を抜粋するとこんな感じです。TLS 1.3のcipherが優先されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers &apos;TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:ECDHE:!COMPLEMENTOFDEFAULT&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;ssllabsでテストをしてみましたが、TLS 1.3はドラフトなのでちゃんと認識されない模様です。FirefoxでTLS1.3のみを有効にして実験した接続できました。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ssllabs.com/ssltest/analyze.html?d=teraren.com&quot;&gt;https://www.ssllabs.com/ssltest/analyze.html?d=teraren.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2017/10/Screen-Shot-2017-10-30-at-20.21.31-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;各種ブラウザの対応バージョン
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ja.wikipedia.org/wiki/Template:%E3%82%A6%E3%82%A7%E3%83%96%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8BTLS/SSL%E3%81%AE%E5%AF%BE%E5%BF%9C%E7%8A%B6%E6%B3%81%E3%81%AE%E5%A4%89%E5%8C%96&quot;&gt;https://ja.wikipedia.org/wiki/Template:%E3%82%A6%E3%82%A7%E3%83%96%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8BTLS/SSL%E3%81%AE%E5%AF%BE%E5%BF%9C%E7%8A%B6%E6%B3%81%E3%81%AE%E5%A4%89%E5%8C%96&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;軽く&lt;code&gt;ab&lt;/code&gt;でテスト。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ab -n 5 -n 100  https://triathlon.teraren.com/
This is ApacheBench, Version 2.3 &amp;lt;$Revision: 1879490 $&amp;gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking triathlon.teraren.com (be patient).....done

Server Software:        nginx/1.13.0
Server Hostname:        triathlon.teraren.com
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
Server Temp Key:        ECDH X25519 253 bits
TLS Server Name:        triathlon.teraren.com

Document Path:          /
Document Length:        284282 bytes

Concurrency Level:      1
Time taken for tests:   19.852 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      28472700 bytes
HTML transferred:       28428200 bytes
Requests per second:    5.04 [#/sec] (mean)
Time per request:       198.516 [ms] (mean)
Time per request:       198.516 [ms] (mean, across all concurrent requests)
Transfer rate:          1400.66 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       46   57  13.3     54     169
Processing:    88  141  47.8    121     371
Waiting:       33   39   6.3     37      63
Total:        137  198  48.8    177     444

Percentage of the requests served within a certain time (ms)
  50%    177
  66%    224
  75%    235
  80%    241
  90%    256
  95%    283
  98%    305
  99%    444
 100%    444 (longest request)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;TLS1.3が出てない。クライアント側のopensslが古いからかな。。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% openssl version
LibreSSL 2.8.3
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;nginxをアップグレード。 1.12 -&amp;gt; 1.13&lt;/li&gt;
&lt;li&gt;TLS 1.0, TLS 1.1を無効化。TLS 1.2とTLS 1.3 draftを有効化&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>久しぶりにmysqltuner</title><link>https://blog.teraren.com/posts/mysqltuner/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysqltuner/</guid><description>MySQLTunerでパフォーマンスとセキュリティを診断し、innodb_buffer_poolの過剰割り当てによるOOM問題の実例も紹介</description><pubDate>Fri, 06 Oct 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;mysqltunerは、MySQLの統計情報を使ってパフォーマンスチューニングのアドバイスをしてくれる。&lt;/li&gt;
&lt;li&gt;最近はCVE（セキュリティ情報）も教えてくれるみたい。&lt;/li&gt;
&lt;li&gt;調べた背景は、64GBのRAMが載ったApacheやbatchプログラムが共存したEC2インスタンスに48GBも&lt;code&gt;innodb_buffer_pool&lt;/code&gt;を盲目的に割り当てたベンダーが居て、それってどうなのよ？と思った。ベンダーに丸投げって怖いな。
&lt;ul&gt;
&lt;li&gt;案の定、「2周間後にメモリが100％になりそうになってOOM Killerが発動されてmysqlが落ちるよ」と3回ぐらい警告したら設定値を変更してくれた。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;cd /tmp
wget https://github.com/major/MySQLTuner-perl/zipball/master
unzip master
cd major-MySQLTuner-perl-b828a6e/
./mysqltuner.pl
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;実行&lt;/h2&gt;
&lt;p&gt;自分のサーバはどうなんだろうと思って実行してみたけど、まぁ、適当に設定している割には良い感じ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[OK] Currently running supported MySQL version 5.7.18-log
[OK] Operating on 64-bit architecture

-------- Log file Recommendations ------------------------------------------------------------------
[--] Log file: /usr/local/var/mysql/teraren.local.err(0B)
[!!] Log file /usr/local/var/mysql/teraren.local.err doesn&apos;t exist
[!!] Log file /usr/local/var/mysql/teraren.local.err isn&apos;t readable.

-------- Storage Engine Statistics -----------------------------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MEMORY +MRG_MYISAM +MyISAM +PERFORMANCE_SCHEMA
[--] Data in InnoDB tables: 15G (Tables: 490)
[--] Data in MyISAM tables: 60M (Tables: 161)
[!!] Total fragmented tables: 1

-------- Security Recommendations ------------------------------------------------------------------
[OK] There are no anonymous accounts for any database users
[OK] All database users have passwords assigned
[!!] User &apos;tel@%&apos; hasn&apos;t specific host restriction.
[--] There are 612 basic passwords in the list.

-------- CVE Security Recommendations --------------------------------------------------------------
[OK] NO SECURITY CVE FOUND FOR YOUR VERSION

-------- Performance Metrics -----------------------------------------------------------------------
[--] Up for: 60d 2h 32m 18s (124M q [23.963 qps], 1M conn, TX: 409G, RX: 16G)
[--] Reads / Writes: 91% / 9%
[--] Binary logging is enabled (GTID MODE: OFF)
[--] Physical Memory     : 8.0G
[--] Max MySQL memory    : 496.0M
[--] Other process memory: 6.3G
[--] Total buffers: 424.0M global + 1.1M per thread (64 max threads)
[--] P_S Max memory usage: 72B
[--] Galera GCache Max memory usage: 0B
[OK] Maximum reached memory usage: 430.8M (5.26% of installed RAM)
[OK] Maximum possible memory usage: 496.0M (6.05% of installed RAM)
[OK] Overall possible memory usage with other process is compatible with memory available
[OK] Slow queries: 0% (66/124M)
[OK] Highest usage of available connections: 9% (6/64)
[OK] Aborted connections: 0.00%  (4/1550671)
[!!] name resolution is active : a reverse name resolution is made for each new connection and can reduce performance
[!!] Query cache may be disabled by default due to mutex contention.
[OK] Query cache efficiency: 74.9% (81M cached / 109M selects)
[!!] Query cache prunes per day: 100750
[OK] Sorts requiring temporary tables: 0% (4K temp sorts / 3M sorts)
[OK] No joins without indexes
[!!] Temporary tables created on disk: 30% (2M on disk / 6M total)
[OK] Thread cache hit rate: 99% (6 created / 1M connections)
[!!] Table cache hit rate: 19% (1K open / 9K opened)
[OK] Open file limit used: 0% (323/65K)
[OK] Table locks acquired immediately: 99% (985K immediate / 986K locks)
[OK] Binlog cache memory access: 99.93% (2455619 Memory / 2457387 Total)

-------- Performance schema ------------------------------------------------------------------------
[--] Memory used by P_S: 72B
[--] Sys schema is installed.

-------- ThreadPool Metrics ------------------------------------------------------------------------
[--] ThreadPool stat is disabled.

-------- MyISAM Metrics ----------------------------------------------------------------------------
[!!] Key buffer used: 19.9% (1M used / 8M cache)
[OK] Key buffer size / total MyISAM indexes: 8.0M/4.2M
[OK] Read Key buffer hit rate: 100.0% (8M cached / 134 reads)
[OK] Write Key buffer hit rate: 99.3% (462K cached / 458K writes)

-------- InnoDB Metrics ----------------------------------------------------------------------------
[--] InnoDB is enabled.
[--] InnoDB Thread Concurrency: 0
[OK] InnoDB File per table is activated
[!!] InnoDB buffer pool / data size: 256.0M/15.5G
[!!] Ratio InnoDB log file size / InnoDB Buffer pool size (37.5 %): 48.0M * 2/256.0M should be equal 25%
[OK] InnoDB buffer pool instances: 1
[--] Number of InnoDB Buffer Pool Chunk : 2 for 1 Buffer Pool Instance(s)
[OK] Innodb_buffer_pool_size aligned with Innodb_buffer_pool_chunk_size &amp;amp; Innodb_buffer_pool_instances
[OK] InnoDB Read buffer efficiency: 99.91% (53923725522 hits/ 53974926093 total)
[!!] InnoDB Write Log efficiency: 66.99% (7965306 hits/ 11890918 total)
[OK] InnoDB log waits: 0.00% (0 waits / 3925612 writes)

-------- AriaDB Metrics ----------------------------------------------------------------------------
[--] AriaDB is disabled.

-------- TokuDB Metrics ----------------------------------------------------------------------------
[--] TokuDB is disabled.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2017/10/Screen-Shot-2017-10-06-at-22.45.28.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>hanami - The web, with simplicity</title><link>https://blog.teraren.com/posts/hanami-new-ruby-web-framework/</link><guid isPermaLink="true">https://blog.teraren.com/posts/hanami-new-ruby-web-framework/</guid><description>hanami - The web, with simplicity</description><pubDate>Wed, 23 Aug 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hanami/hanami&quot;&gt;hanami&lt;/a&gt;を軽く使ってみました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rubykaigi.org/2017/presentations/anton_davydov.html&quot;&gt;http://rubykaigi.org/2017/presentations/anton_davydov.html&lt;/a&gt; の予習用です。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://shinjukurb.connpass.com/event/64107/&quot;&gt;https://shinjukurb.connpass.com/event/64107/&lt;/a&gt; で発表しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;資料&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;//www.slideshare.net/matsubokkuri/20170823-shinjuku-rbhanami&quot;&gt;20170823 shinjuku rb_hanami&lt;/a&gt;&lt;/strong&gt; from &lt;strong&gt;&lt;a href=&quot;https://www.slideshare.net/matsubokkuri&quot;&gt;Yuki Matsukura&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>hbstudy 第75回： 「SRE大全: メルカリ編」 個人的なログ</title><link>https://blog.teraren.com/posts/hbstudy75-summary/</link><guid isPermaLink="true">https://blog.teraren.com/posts/hbstudy75-summary/</guid><description>hbstudy第75回メルカリSRE講演のメモ。PHP7移行でCPU負荷半減、mackerel/PagerDutyによる監視体制、CDNキャッシュ制御、GKE+gRPCの活用事例などをまとめた。</description><pubDate>Thu, 17 Aug 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://hbstudy.connpass.com/event/62296/&quot;&gt;hbstudy 第75回： SRE大全: メルカリ編&lt;/a&gt; の個人的なまとめ。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tech.mercari.com/entry/2017/08/21/120000&quot;&gt;資料&lt;/a&gt; 2017/8/21 更新&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ログ&lt;/h2&gt;
&lt;h3&gt;前半&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;「新規サービスの開発以外のエンジニアリングは全部やる」&lt;/li&gt;
&lt;li&gt;メンバー：9人&lt;/li&gt;
&lt;li&gt;SREの業務範囲
&lt;ul&gt;
&lt;li&gt;Operation&lt;/li&gt;
&lt;li&gt;Software Enginerring&lt;/li&gt;
&lt;li&gt;基盤構築 (log, analytics, server provisioning, deploy)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;リソース監視は &lt;a href=&quot;https://mackerel.io/ja/&quot;&gt;mackerel&lt;/a&gt; 使っている。&lt;/li&gt;
&lt;li&gt;mackerel-agent, Norikra, mkr =&amp;gt; mackerel =&amp;gt; Slack&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.sakura.ne.jp/&quot;&gt;Sakura&lt;/a&gt;で物理サーバを使っている。&lt;/li&gt;
&lt;li&gt;エラーのエスカレーションPagerDuty使っている。高いらしい。
&lt;ul&gt;
&lt;li&gt;担当者が気づくまでいろいろな手段で通知を送る。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.pagerduty.com/&quot;&gt;https://www.pagerduty.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Infra
&lt;ul&gt;
&lt;li&gt;JP: Sakura&lt;/li&gt;
&lt;li&gt;US: AWS, GCP&lt;/li&gt;
&lt;li&gt;UK: GCP&lt;/li&gt;
&lt;li&gt;Log: BigQuery&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Application stack
&lt;ul&gt;
&lt;li&gt;Solr&lt;/li&gt;
&lt;li&gt;MySQL, memcached&lt;/li&gt;
&lt;li&gt;app&lt;/li&gt;
&lt;li&gt;nginx&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CDN問題
&lt;ul&gt;
&lt;li&gt;CDNにおいてExpireヘッダで過去日を指定したとしても、0秒のキャッシュが存在することになる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;nginxの設定。CDNやブラウザに絶対キャッシュされないようにヘッダを制御。cookieを設定するとキャッシュされないことは確認済み。
&lt;ul&gt;
&lt;li&gt;more_clear_headers expires …&lt;/li&gt;
&lt;li&gt;more_set_headers cache-control private no-cache no-store …&lt;/li&gt;
&lt;li&gt;add_header Set-Cookie ...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CDNを使う理由：DDoS体制。セキュリティ対策。&lt;/li&gt;
&lt;li&gt;今は、インフラチームは無くなった。SREだけ。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;後半&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PHP 5.6.x -&amp;gt; PHP 7.1 に切り替えた
&lt;ul&gt;
&lt;li&gt;CPU負荷半分&lt;/li&gt;
&lt;li&gt;CI速度も上がった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;全世界同じソースコードで動いている。&lt;/li&gt;
&lt;li&gt;ボトルネックは&lt;a href=&quot;https://newrelic.com/&quot;&gt;NewRelic&lt;/a&gt;とapacheのstraceで探している&lt;/li&gt;
&lt;li&gt;ソフトウェアエンジニアが本番環境をいじれない
&lt;ul&gt;
&lt;li&gt;将来的にはmicroservice化して、エンジニアがオーナーシップを持って行けるようにする。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;最近は、GKE + GRPCで動いているサービスがある。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cloud.google.com/spanner/&quot;&gt;spanner&lt;/a&gt; 使っている&lt;/li&gt;
&lt;li&gt;理想は12人欲しい。当番が2人体制にしたいから。&lt;/li&gt;
&lt;li&gt;なぜsakura？
&lt;ul&gt;
&lt;li&gt;最初から使っている。物理サーバならではのパフォーマンス。今のところ、最終的にはコストメリットがある。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;誰がCDNに関連した障害のblogを書く事を許可したの？
&lt;ul&gt;
&lt;li&gt;ボードメンバーの一人が &lt;code&gt;ブログ書いて&lt;/code&gt; と言ったことがトリガー。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Twitter&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/hashtag/hbstudy&quot;&gt;#hbstudy Tweets&lt;/a&gt;&lt;br /&gt;
{/* textlint-disable ja-technical-writing/sentence-length &lt;em&gt;/}
{/&lt;/em&gt; Twitter widget script removed for MDX compatibility &lt;em&gt;/}
{/&lt;/em&gt; textlint-enable */}&lt;/p&gt;
</content:encoded></item><item><title>WebRTC概論</title><link>https://blog.teraren.com/posts/webrtc/</link><guid isPermaLink="true">https://blog.teraren.com/posts/webrtc/</guid><description>WebRTC概論</description><pubDate>Fri, 14 Jul 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;社内でLTしたときの資料。 LTでは、デモとコード解説しました。&lt;/p&gt;
&lt;p&gt;[slideshare id=77857899&amp;amp;doc=20171005webrtc-170714025415]&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://matsu.teraren.com/static/opentok-web-samples/&quot;&gt;デモコード&lt;/a&gt; シグナル用のサーバを動かしていないので動作しませんが。&lt;/p&gt;
</content:encoded></item><item><title>PoloniexのAPIを使って、指定した金額になったら取引する(IFD)プログラム</title><link>https://blog.teraren.com/posts/qiita-20170612-d45637e72c53fa7ceab1/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20170612-d45637e72c53fa7ceab1/</guid><description>Poloniex APIを使い、日本円換算で指定金額に達したら自動で仮想通貨を売買するRubyプログラムの実装。</description><pubDate>Mon, 12 Jun 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://poloniex.com/&quot;&gt;Poloniex&lt;/a&gt;で仮想通貨を取引していますが、法定通貨がUSDTしか無い。&lt;/li&gt;
&lt;li&gt;ETH/BTC とか USDT/BTC がメイン。JPY は存在しない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題と解決&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;「日本円で指定金額になったら注文する」というユースケースを実現できない。&lt;/li&gt;
&lt;li&gt;例えば、「ETH が 50000 円になったら、51000 円で指し値注文して ETH を売って BTC を買う」という注文が出来ない。&lt;/li&gt;
&lt;li&gt;Poloniex で API が公開されているので &lt;a href=&quot;https://github.com/matsubo/poloniex_order&quot;&gt;プログラム書いた&lt;/a&gt;。
&lt;ul&gt;
&lt;li&gt;https://github.com/matsubo/poloniex_order&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;仕様&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Stop Limit Order を行っています。
&lt;ul&gt;
&lt;li&gt;1 分に 1 回レートを取得&lt;/li&gt;
&lt;li&gt;指定の金額になったら macOS の notification center に通知を表示&lt;/li&gt;
&lt;li&gt;一応、1 分待つ。&lt;/li&gt;
&lt;li&gt;1％高い所で指値(Limit order)を入れる。&lt;/li&gt;
&lt;li&gt;プログラムが終了&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;24 時間稼働させたいならサーバで動かしておけば良い。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;スクリーンショット&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2017/06/3451b012-c5aa-ff35-658a-b00f545184cb.png&quot; alt=&quot;Screen Shot 2017-06-12 at 15.50.41.png&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ソースコード&lt;/h2&gt;
&lt;p&gt;https://github.com/matsubo/poloniex_order/blob/master/main.rb&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;require &apos;rubygems&apos;
require &apos;bundler/setup&apos;

Bundler.require(:default)
Dotenv.load

Poloniex.setup do |config|
  config.key = ENV[&apos;POLONIEX_KEY&apos;]
  config.secret = ENV[&apos;POLONIEX_SECRET&apos;]
end

check_currency_pair = &apos;USDT_ETH&apos;
sell_currency_pair = &apos;ETH_BTC&apos;

usd_jpy = 110.24

sell_amount = 0.1

loop do
  ticker = Poloniex.ticker
  usdt_btc = JSON.parse(ticker)[check_currency_pair][&apos;last&apos;]

  jpy_btc = usdt_btc.to_f * usd_jpy

  puts Time.now.to_s + &quot;\t&quot; + jpy_btc.to_s

  if jpy_btc &amp;gt; 38_000
    contents = jpy_btc
    title = &apos;Rate alert&apos;
    system(&apos;osascript -e \&apos;display notification &quot;%s&quot; with title &quot;%s&quot; \&apos;&apos; % %w[contents title])

    # execute order
    sleep 60
    rate = JSON.parse(ticker)[&apos;BTC_ETH&apos;][&apos;lowestAsk&apos;].to_f * 1.01
    Poloniex.sell(sell_currency_pair, rate, sell_amount)

    contents = rate
    title = &apos;Placed and selling order&apos;
    system(&apos;osascript -e \&apos;display notification &quot;%s&quot; with title &quot;%s&quot; \&apos;&apos; % %w[contents title])

    break
  end

  sleep 60
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Happy FX life!&lt;/p&gt;
</content:encoded></item><item><title>DockerのMySQL5.7でエラー Unix socket lock file is empty /var/run/mysqld/mysqld.sock.lock</title><link>https://blog.teraren.com/posts/docker-mysql-unix-socket-lock-file-is-empty/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-mysql-unix-socket-lock-file-is-empty/</guid><description>DockerのMySQL5.7でエラー Unix socket lock file is empty /var/run/mysqld/mysqld.sock.lock</description><pubDate>Wed, 19 Apr 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Mac OS Xでしばらく使っていたのに、こんな感じのエラーが出て、もううんともすんとも行かなくなった。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2017-04-19T10:11:11.269836Z 0 [ERROR] Unix socket lock file is empty /var/run/mysqld/mysqld.sock.lock.
2017-04-19T10:11:11.269966Z 0 [ERROR] Unable to setup unix socket lock file.
2017-04-19T10:11:11.269995Z 0 [ERROR] Aborting
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;環境は、ほぼ素のMySQL 5.7の公式imageをmacos Xで運用。ボリュームはローカルのファイルシステムをマウント。&lt;/p&gt;
&lt;p&gt;試したこと&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dockerの再起動&lt;/li&gt;
&lt;li&gt;macosの再起動&lt;/li&gt;
&lt;li&gt;ディスク容量のチェック&lt;/li&gt;
&lt;li&gt;他のcontainerの停止&lt;/li&gt;
&lt;li&gt;socketファイルが存在していないことの確認&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-successive-word &lt;em&gt;/}
などなど
{/&lt;/em&gt; textlint-enable */}&lt;/p&gt;
&lt;p&gt;最終的に、docker containerの削除で解決しました。&lt;/p&gt;
</content:encoded></item><item><title>SI系とWeb系の違いをまとめてみる</title><link>https://blog.teraren.com/posts/qiita-20170328-a5989372a3508f752bda/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20170328-a5989372a3508f752bda/</guid><description>SI系とWeb系の違いを要件定義・設計・実装・テスト・納品・マネジメントの観点で比較した一覧表。</description><pubDate>Tue, 28 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SI 系と Web 系の違いの説明を求められて、良い感じの説明が出来なかったので、まとめてみる。&lt;/li&gt;
&lt;li&gt;主観。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;違い&lt;/h2&gt;
&lt;h3&gt;要件定義&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SI&lt;/th&gt;
&lt;th&gt;Web&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ドキュメント&lt;/td&gt;
&lt;td&gt;Excel&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API仕様書&lt;/td&gt;
&lt;td&gt;Excel&lt;/td&gt;
&lt;td&gt;OpenAPI-Specification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;プレゼン&lt;/td&gt;
&lt;td&gt;Powerpoint&lt;/td&gt;
&lt;td&gt;keynote, HTML5, &lt;a href=&quot;slides.com&quot;&gt;slides&lt;/a&gt; などのWebサービス&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;見積もり&lt;/td&gt;
&lt;td&gt;「持ち帰って検討します」「100人月以上です」（ゴールは仕様書、実装、テスト仕様書、納品、受け入れ、本番稼働）&lt;/td&gt;
&lt;td&gt;「プロトタイプはすぐできます」「1人で3日〜1週間です」（ゴールはプロトタイプレベル）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;設計&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SI&lt;/th&gt;
&lt;th&gt;Web&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ERD&lt;/td&gt;
&lt;td&gt;Excel&lt;/td&gt;
&lt;td&gt;MySQL Workbench, UML&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;クラス図&lt;/td&gt;
&lt;td&gt;Excel&lt;/td&gt;
&lt;td&gt;Astahなど&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;スクリーンショット&lt;/td&gt;
&lt;td&gt;Excelに貼られた画像&lt;/td&gt;
&lt;td&gt;画像ファイル&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API仕様書&lt;/td&gt;
&lt;td&gt;Excel, Word&lt;/td&gt;
&lt;td&gt;Swagger, Open API&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;実装&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SI&lt;/th&gt;
&lt;th&gt;Web&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ドキュメント&lt;/td&gt;
&lt;td&gt;Excel&lt;/td&gt;
&lt;td&gt;Markdown&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;開発ツール&lt;/td&gt;
&lt;td&gt;Eclipse, 秀丸, さくらエディタ&lt;/td&gt;
&lt;td&gt;Vim, Emacs, Visual Studio Code, Atom, Sublime Text, RubyMineなどのJetBrains製品, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;文字コード&lt;/td&gt;
&lt;td&gt;Shift-JIS&lt;/td&gt;
&lt;td&gt;Unicode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;システム連携&lt;/td&gt;
&lt;td&gt;CSV&lt;/td&gt;
&lt;td&gt;Web API, gRPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SCM&lt;/td&gt;
&lt;td&gt;Subversion, ファイルコピー&lt;/td&gt;
&lt;td&gt;Git&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stylesheetの管理&lt;/td&gt;
&lt;td&gt;生CSS&lt;/td&gt;
&lt;td&gt;Sass, webpackなど&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;フォーム&lt;/td&gt;
&lt;td&gt;CGI、Java&lt;/td&gt;
&lt;td&gt;SPA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ブラウザ&lt;/td&gt;
&lt;td&gt;Internet Explorer&lt;/td&gt;
&lt;td&gt;Google Chrome, Firefox, iOS, Android&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;データベース&lt;/td&gt;
&lt;td&gt;Oracle, MS-SQL&lt;/td&gt;
&lt;td&gt;MySQL, Postgres, Cassandra, Mongo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;インフラ&lt;/td&gt;
&lt;td&gt;オンプレ、クラウドをオンプレっぽく使う&lt;/td&gt;
&lt;td&gt;クラウド(AWS, GCPなど)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;品質&lt;/td&gt;
&lt;td&gt;悪い（クソコードを書けば書くほど保守費用をぼったくれる）&lt;/td&gt;
&lt;td&gt;良い（保守で自分の首を絞めたくない）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;テスト&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SI&lt;/th&gt;
&lt;th&gt;Web&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;テスター&lt;/td&gt;
&lt;td&gt;人&lt;/td&gt;
&lt;td&gt;CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;テスト仕様書&lt;/td&gt;
&lt;td&gt;Excel&lt;/td&gt;
&lt;td&gt;テストコード&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;納品&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SI&lt;/th&gt;
&lt;th&gt;Web&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;価値観&lt;/td&gt;
&lt;td&gt;納品がゴール&lt;/td&gt;
&lt;td&gt;リリースがスタート&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;メディア&lt;/td&gt;
&lt;td&gt;zipでファイルを固める&lt;/td&gt;
&lt;td&gt;Gitリポジトリ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ファイルのやりとり&lt;/td&gt;
&lt;td&gt;ZIP + パスワード, 宅ファイル便&lt;/td&gt;
&lt;td&gt;Box Sync, Dropbox, G suite&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;プロジェクトマネジメント&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SI&lt;/th&gt;
&lt;th&gt;Web&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ツール&lt;/td&gt;
&lt;td&gt;Excel&lt;/td&gt;
&lt;td&gt;Redmine, Jira, Pivotal Tracker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;開発モデル&lt;/td&gt;
&lt;td&gt;ウォーターフォール&lt;/td&gt;
&lt;td&gt;アジャイル&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;プロダクトマネジメント&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SI&lt;/th&gt;
&lt;th&gt;Web&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;組織&lt;/td&gt;
&lt;td&gt;プロダクトマネジメントしていない&lt;/td&gt;
&lt;td&gt;PdMが製品理念を定義しチームに連携している&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;働く人&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SI&lt;/th&gt;
&lt;th&gt;Web&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;モチベーション&lt;/td&gt;
&lt;td&gt;金, なんとなく&lt;/td&gt;
&lt;td&gt;QOL、自己実現、SO、MA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;徹夜&lt;/td&gt;
&lt;td&gt;デスマで徹夜&lt;/td&gt;
&lt;td&gt;仕事が楽しいから徹夜&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ブラインドタッチ&lt;/td&gt;
&lt;td&gt;できない&lt;/td&gt;
&lt;td&gt;できる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;休日の過ごし方&lt;/td&gt;
&lt;td&gt;寝る&lt;/td&gt;
&lt;td&gt;プログラミング、趣味&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;趣味&lt;/td&gt;
&lt;td&gt;アニメ&lt;/td&gt;
&lt;td&gt;アニメ、写真、プログラミング、ロードバイクetc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;服装&lt;/td&gt;
&lt;td&gt;スーツ&lt;/td&gt;
&lt;td&gt;カジュアル&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SNS&lt;/td&gt;
&lt;td&gt;はてな匿名ダイアリー&lt;/td&gt;
&lt;td&gt;はてなダイアリー,Facebook, Instagram, Twitter,note&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;仕事中に聞く音楽&lt;/td&gt;
&lt;td&gt;許されない&lt;/td&gt;
&lt;td&gt;EDM、Jazz、環境音、耳栓など&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;勤務形態&lt;/td&gt;
&lt;td&gt;時間給&lt;/td&gt;
&lt;td&gt;フレックス, 成果報酬&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;契約形態&lt;/td&gt;
&lt;td&gt;社員,契約社員,派遣&lt;/td&gt;
&lt;td&gt;社員,業務委託&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;スキル&lt;/td&gt;
&lt;td&gt;狭く深く&lt;/td&gt;
&lt;td&gt;広く浅く&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;将来性&lt;/td&gt;
&lt;td&gt;無くなると言われ続けて早10年。無くならない。&lt;/td&gt;
&lt;td&gt;今のところ市場ニーズは大きくなるばかり&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;海外勤務&lt;/td&gt;
&lt;td&gt;あり得ない&lt;/td&gt;
&lt;td&gt;機会は多いと思う&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PC&lt;/td&gt;
&lt;td&gt;Windows&lt;/td&gt;
&lt;td&gt;Mac, Linux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;人気の会社&lt;/td&gt;
&lt;td&gt;IBM, UNISYS, NTT Data, HITACHI, NEC, Microsoft&lt;/td&gt;
&lt;td&gt;Google, Facebook, Apple, メルカリ, Freee, Smart HRなど&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;生息場所&lt;/td&gt;
&lt;td&gt;みずほ銀行関連の案件&lt;/td&gt;
&lt;td&gt;資金が豊富なところ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;主な年代&lt;/td&gt;
&lt;td&gt;40〜60代&lt;/td&gt;
&lt;td&gt;10代〜30代&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;勤続年数&lt;/td&gt;
&lt;td&gt;10〜数十年&lt;/td&gt;
&lt;td&gt;数ヶ月〜数年&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;お金&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;SI&lt;/th&gt;
&lt;th&gt;Web&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;給料&lt;/td&gt;
&lt;td&gt;低〜中&lt;/td&gt;
&lt;td&gt;低〜高&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;発注金額&lt;/td&gt;
&lt;td&gt;高(数百万円〜数百億円)&lt;/td&gt;
&lt;td&gt;低(数十万円〜数千万円)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;端から見れば同じ IT ですが、カルチャーや重要視されるスキルは大きく異なる。&lt;/li&gt;
&lt;li&gt;面接やミートアップにおいて、上記の項目についてヒアリングすれば、どちらの人種なのかを判別できる。&lt;/li&gt;
&lt;li&gt;発注する際は、どっちの畑の会社なのかを見極める必要あり。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>dockerでno space left on deviceが出た時の対処法</title><link>https://blog.teraren.com/posts/docker-no-space-left-on-device/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-no-space-left-on-device/</guid><description>Dockerで「no space left on device」が表示されたときに、不要なイメージやボリュームを段階的に削除してディスク容量を回収する手順を解説</description><pubDate>Tue, 14 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;no space left on device&lt;/code&gt;は、日本語訳すると「空きディスク容量がありません」ということです。まずは、OS自体のディスク容量不足をまずはチェックします。&lt;/li&gt;
&lt;li&gt;OSのディスク容量が空いているのに、&lt;code&gt;no space left on device&lt;/code&gt;が表示された場合はDocker自体に割り当てられたディスク容量が枯渇したことが原因です。&lt;/li&gt;
&lt;li&gt;例えば、Docker for Macは20GB分しか確保しないです。&lt;/li&gt;
&lt;li&gt;普通にDockerを利用しているとゴミデータが溜まっていくので、不要なデータを消していきます。&lt;/li&gt;
&lt;li&gt;下に行けば下に行くほど、重要なデータを消していくことになりますのでご注意ください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;0. 割当領域の拡張&lt;/h2&gt;
&lt;p&gt;macOSであれば以下のような設定画面から、割り当てているディスク容量の変更を行えます。設定を変更後はDockerの再起動が必要になります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/image-6.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そもそも、自分が思っている以上にDockerがディスクを消費していると感じる場合は、以降にあるような手順でゴミファイルの削除を進めて行ってください。&lt;/p&gt;
&lt;h2&gt;現状の確認&lt;/h2&gt;
&lt;p&gt;掃除を始める前に、&lt;code&gt;docker system df&lt;/code&gt;コマンドで現在のディスク使用量を確認しておきましょう。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          95        53        55.52GB   36.55GB (65%)
Containers      571       0         6.355GB   6.355GB (100%)
Local Volumes   95        38        9.812GB   1.456GB (14%)
Build Cache     927       0         19.06GB   19.06GB
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この例では約89GB使っています。Reclaimableの列が回収可能な容量なので、かなり削減できそうなことがわかります。&lt;/p&gt;
&lt;h2&gt;1. ゴミ掃除&lt;/h2&gt;
&lt;p&gt;まずは、名前が割り振られていない仮想ディスクを削除します。&lt;/p&gt;
&lt;h3&gt;GUIから行う場合&lt;/h3&gt;
&lt;p&gt;Docker Desktopから簡単に行なえます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/Pasted_Image_2022_11_22_14_23.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;danglingなコンテナはほとんど再利用することはないので消してしまっても問題はほとんど起きないと思います。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2022/11/image-5.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;CLIから行う場合&lt;/h3&gt;
&lt;p&gt;dockerコマンドのdanglingフィルタはコンテナから参照されていない（dangling＝宙ぶらりんな）ボリュームに一致します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker volume rm $(docker volume ls -qf dangling=true)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、1週間以上使っていないコンテナの削除をします。以下の例では1週間使っていないコンテナを削除します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker container prune --force --filter &quot;until=168h&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、&lt;a href=&quot;http://stackoverflow.com/a/17237701/985436&quot;&gt;1週間以上前に停止したコンテナの削除&lt;/a&gt;です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker ps --filter &quot;status=exited&quot; | grep &apos;weeks ago&apos; | awk &apos;{print $1}&apos; | xargs docker rm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;全コンテナの削除をします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker rm $(docker ps -aq)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;dangilingなimageを一括削除する。&lt;/p&gt;
&lt;p&gt;Dangilingなimageとは、Dockerfileから作ってタグを打っていないimageです。&lt;/p&gt;
&lt;p&gt;基本的に再利用することはないので消してOKです。普通の利用方法をしていればイメージはDockerfileから再生成できます。docker-composeから作ったり、tagが打ってあるイメージは消えません。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker rmi $(docker images -f &quot;dangling=true&quot; -q)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ビルドキャッシュの削除&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;docker build&lt;/code&gt;で作成された中間イメージ（ビルドキャッシュ）も意外とディスクを食います。上の&lt;code&gt;docker system df&lt;/code&gt;の例ではBuild Cacheだけで19GBも使っていました。以下のコマンドで削除できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker builder prune
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;全イメージの削除&lt;/h3&gt;
&lt;p&gt;次に、全イメージを削除します。imageが全部消えます。関連しているコンテナがまだ存在している場合はエラーが表示されて消えません。以下の2つのコマンドはほぼ同義です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker rmi $(docker images -q)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ docker image prune
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;停止中の全コンテナを削除するコマンド&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker container prune
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;全ての停止中のコンテナ、ボリューム、ネットワーク、イメージを一括削除するコマンドです。ほぼDockerのリセットと同義です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker system prune
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;掃除後の確認&lt;/h3&gt;
&lt;p&gt;掃除が終わったら、再度&lt;code&gt;docker system df&lt;/code&gt;で効果を確認しましょう。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          61        5         37.26GB   36.23GB (97%)
Containers      13        0         78.64MB   78.64MB (100%)
Local Volumes   38        6         8.356GB   4.673GB (55%)
Build Cache     405       0         0B        0B
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;半年ぐらい運用した環境では、89GBから35GBまで削減できました。最後の3つの破壊的なコマンド（全コンテナ削除、全イメージ削除、system prune）は実行せずにこの結果なので、安全な範囲のクリーンアップだけでもかなり効果があります。&lt;/p&gt;
&lt;h3&gt;定期実行用シェルスクリプト&lt;/h3&gt;
&lt;p&gt;上記の安全なコマンド群をシェルスクリプトにまとめておくと、定期的にサクッと実行できて便利です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash

set -Eeuo pipefail

docker volume rm $(docker volume ls -qf dangling=true)
docker container prune --force --filter &quot;until=168h&quot;
docker ps --filter &quot;status=exited&quot; | grep &apos;weeks ago&apos; | awk &apos;{print $1}&apos; | xargs docker rm
docker rmi $(docker images -f &quot;dangling=true&quot; -q)
docker builder prune -f
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. ディスクイメージの再構築&lt;/h2&gt;
&lt;p&gt;Docker version 20.10.22では、Docker Desktopから行えます。&lt;/p&gt;
&lt;p&gt;（これは、macosだけかも）&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.qemu-project.org/&quot;&gt;qemu&lt;/a&gt;をインストール。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ brew install qemu
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ cd ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux
$ mv Docker.qcow2 Docker.qcow2.original
$ du -hs Docker.qcow2.original
12G     Docker.qcow2.original
$ qemu-img convert -O qcow2 Docker.qcow2.original Docker.qcow2
$ du -hs Docker.qcow2
772M    Docker.qcow2
$ rm Docker.qcow2.original
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;source: &lt;a href=&quot;https://github.com/docker/for-mac/issues/371#issuecomment-242047368&quot;&gt;https://github.com/docker/for-mac/issues/371#issuecomment-242047368&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;私の場合、これでは19GBから18GBに減っただけでした。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ls -l Docker.qcow2*
-rw-r--r--  1 yuki_matsukura  staff  19443286016 Mar 14 10:31 Docker.qcow2
-rw-r--r--  1 yuki_matsukura  staff  20844183552 Mar 14 10:30 Docker.qcow2.original
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. ディスクイメージの拡張&lt;/h2&gt;
&lt;p&gt;Docker version 20.10.22では、Docker Desktopから行えます。&lt;/p&gt;
&lt;p&gt;そもそも20GBしか確保してくれないのは少ないので。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% qemu-img info Docker.qcow2
image: Docker.qcow2
file format: qcow2
virtual size: 64G (68719476736 bytes)
disk size: 18G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;% qemu-img resize Docker.qcow2 +10G
Image resized.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;% qemu-img info Docker.qcow2
image: Docker.qcow2
file format: qcow2
virtual size: 74G (79456894976 bytes)
disk size: 18G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;4. 設定ファイル書き換え&lt;/h2&gt;
&lt;p&gt;Docker version 20.10.22では、Docker Desktopから行えます。&lt;/p&gt;
&lt;p&gt;（Docker 17で変わらなかった。）&lt;/p&gt;
&lt;p&gt;&lt;code&gt;~/.docker/machine/machines/default/config.json&lt;/code&gt;を開いて、DiskSizeを20000から大きい値に変更。&lt;/p&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://uorat.hatenablog.com/entry/2017/01/31/164506&quot;&gt;2017/1/31のdocker v1.13 stable releaseにて、ディスクの圧縮には対応しているらしい&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/yuvraajsj18/how-to-fix-docker-no-space-left-on-device-error-co7&quot;&gt;https://dev.to/yuvraajsj18/how-to-fix-docker-no-space-left-on-device-error-co7&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B07NDT526Q&quot;}&lt;/p&gt;
</content:encoded></item><item><title>iPhone Pro 新大久保駅前店で修理→壊された</title><link>https://blog.teraren.com/posts/iphone-pro-broken/</link><guid isPermaLink="true">https://blog.teraren.com/posts/iphone-pro-broken/</guid><description>iPhone6のガラス・電池交換を非認定業者に依頼したら、Siri無効化・寒冷時電源断・充電不能と次々と不具合が発生。修理のたびに症状が悪化した体験談と業者の対応を詳述。</description><pubDate>Sun, 19 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;iPhone6の液晶交換、電池交換を&lt;a href=&quot;http://iphonepro.co.jp/&quot;&gt;iPhone Pro&lt;/a&gt;という業者に依頼したら、全然プロの仕事をしてくれなかった。&lt;/li&gt;
&lt;li&gt;ここの口コミにもあるように、低品質業者だった。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://saiyasu-syuuri.com/company/iphone-pro-shinokubo-ekimae/?tab=1&quot;&gt;http://saiyasu-syuuri.com/company/iphone-pro-shinokubo-ekimae/?tab=1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2017/4/12 会社名が変わっている。iPhone pro から、「あいプロ」になってる。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;経緯&lt;/h2&gt;
&lt;h3&gt;業者選び&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;iPhone6のApple Care+の期限がうっかり切れてしまったので保障で色々直す事が出来なくなりました。&lt;/li&gt;
&lt;li&gt;液晶欠けと、電池の持ちが悪いという問題があって、旅行に行ったときに辛いので、電池交換を決意。&lt;/li&gt;
&lt;li&gt;自分で交換は面倒だし、壊したときのリスクがあるから安くて即日修理できる、Apple非認定業者に頼むことに。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;修理1&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ガラス交換と、電池交換。40分待ち。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;その結果、Siriが使えなくなる。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;外気温が摂氏10度以下になると、電池残量があるにもかかわらず電源が落ちるようになった。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;液晶が青みがかっている。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2017/02/matyukura-img600x600-14851764731485176473.165317757pnnlw117757.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;仕事が忙しくて、再訪が難しく、1ヶ月半、そのまま使い続ける。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;修理2&lt;/h3&gt;
&lt;p&gt;だんだんと寒くなってきて、寒いときに外で電源が落ちて不便すぎるから、保証書を武器にして再度修理を依頼しに行く。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Siriが使えなくなったのは前回の修理が原因では無いと説明されて、責任逃れをされた。&lt;/li&gt;
&lt;li&gt;原因調査のために、店員が分解して試行錯誤する間、2時間ぐらい待たされた。&lt;/li&gt;
&lt;li&gt;責任の所在が曖昧な感じになって終了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;家に帰って気づいた事。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;普通のUSBケーブルによる充電が出来なくなった。急速充電の場合だけ充電されるようになった。よって、モバイルバッテリーなどの低電流からの充電が出来なくなった。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;修理のために持って行くと、壊され、どんどん症状が悪化していって、事態は&lt;strong&gt;泥沼化....&lt;/strong&gt;。&lt;/p&gt;
&lt;h2&gt;感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;業者がクソ&lt;/strong&gt;。使っている&lt;strong&gt;部品もクソ&lt;/strong&gt;。
{/* textlint-disable ja-technical-writing/ja-no-successive-word */}&lt;/li&gt;
&lt;li&gt;たかが部品の交換でも、こんなに金と時間を費やすことになるとは、、、、悲しい。
{/* textlint-enable ja-technical-writing/ja-no-successive-word */}&lt;/li&gt;
&lt;li&gt;さすがにiPhoneを2年使うと、色々ガタは来るなぁ。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;正規修理にしておけば良かった。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;結局、新しいiPhone7を買うことになりました。iPhone7快適！！&lt;/li&gt;
&lt;li&gt;早く買っておけば良かった。それにしても携帯が10万円を超えるなんて。。。macbook airより高いよ！！&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>king of timeのgemを作りました</title><link>https://blog.teraren.com/posts/king-of-time-gem/</link><guid isPermaLink="true">https://blog.teraren.com/posts/king-of-time-gem/</guid><description>king of timeのgemを作りました</description><pubDate>Sun, 19 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;勤怠管理システムの『キングオブタイム』の打刻をRubyから行うgemを作りました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/king_of_time&quot;&gt;https://github.com/matsubo/king_of_time&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;応用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Alfredのショートカットに登録しておけば、ランチャーから打刻できます。&lt;/li&gt;
&lt;li&gt;LINE Messaging APIと組み合わせて打刻をLINEからおこなったり。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2017/02/Screenshot_2017_02_19_1_10.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;King Of Timeのシステムは脆弱性が多い。UI使いづらい。&lt;/li&gt;
&lt;li&gt;Webとかログイン画面だけはモダンなデザインだけど、システムの中身はグダグダ。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Bose QuietComfort 35が予想以上に良い！</title><link>https://blog.teraren.com/posts/bose-quietcomfort-35/</link><guid isPermaLink="true">https://blog.teraren.com/posts/bose-quietcomfort-35/</guid><description>ATH-ANC9からBose QuietComfort 35へ乗り換えた2ヶ月使用レビュー。軽量・長時間バッテリー・ワイヤレスの快適さを絶賛。コード断線リスクからの解放も評価。</description><pubDate>Thu, 16 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/audio-technica-QuietPoint-%E5%AF%86%E9%96%89%E5%9E%8B%E3%83%98%E3%83%83%E3%83%89%E3%83%9B%E3%83%B3-%E3%83%8E%E3%82%A4%E3%82%BA%E3%82%AD%E3%83%A3%E3%83%B3%E3%82%BB%E3%83%AA%E3%83%B3%E3%82%B0-ATH-ANC9/dp/B0077YTFPS?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=audio-technica+QuietPoint+ATH-ANC9&amp;amp;qid=1618363229&amp;amp;sr=8-3&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=7b7e0eee531b11fb94666c30a60961d5&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;audio-technica QuietPoint ATH-ANC9&lt;/a&gt;からの乗り換えです。&lt;/li&gt;
&lt;li&gt;かれこれ9年間、仕事中はノイズキャンセリングヘッドフォンを使って音楽を聴いています。今回で4機目。&lt;/li&gt;
&lt;li&gt;言いたいことは、&lt;strong&gt;これは買い！&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B0077YTFPS&quot;}
::amazon{asin=&quot;B076W9W5PR&quot;}&lt;/p&gt;
&lt;h2&gt;ATH-ANC9が駄目な理由&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;イヤーパッドを毎年買い換えるので、3000円かかる。&lt;/li&gt;
&lt;li&gt;単4電池で稼働しているのですが、電池が切れた瞬間「ぶちっ」って大きな音が鳴るのでびっくりする。&lt;/li&gt;
&lt;li&gt;電池を取り出して、入れ替えて、再度入れる操作がめんどくさい。1日1回か2回必要。&lt;/li&gt;
&lt;li&gt;コードが邪魔！足とか手に引っかかって机から落ちる。これで1回折れて1万円出して交換になった。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;開封の儀&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;パッケージはこんな感じ。&lt;/li&gt;
&lt;li&gt;いかんせん高いので、大事に扱う。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2017/02/img_8128.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2017/02/img_8127.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;アプリでファームウェアのアップデートなどが出来る。&lt;br /&gt;
&lt;img src=&quot;../../assets/uploads/2017/02/img_0131.png&quot; alt=&quot;&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2ヶ月使ったレビュー&lt;/h2&gt;
&lt;h3&gt;良い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;軽いのは良い。ヘッドフォンを長時間使っていると、頭との接地部が痛くなってきたりするので、軽さは超重要！長時間付けていても頭が痛くなくならなくなった。&lt;/li&gt;
&lt;li&gt;電池が超長持ち！&lt;/li&gt;
&lt;li&gt;ワイヤレスは最高！&lt;/li&gt;
&lt;li&gt;冬、外に付けていくと耳当てになって暖かい。&lt;/li&gt;
&lt;li&gt;iPhoneとペアリングしておけば、電話が来たらワンタッチで会話出来るので、凄い楽！（っていうか、iPhone7は便利！早く買い換えれば良かった）&lt;/li&gt;
&lt;li&gt;音質が、ATH-ANC9に比べて多少良くなった。前のも高いので、あんまり変わらない。&lt;/li&gt;
&lt;li&gt;昔は環境音の音声はキャンセリングしなかった仕様だったけど、今はキャンセリングしてくれるみたい。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;悪い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Macとの接続が不安定になる時がある。0.5秒ごとに無音が発生する感じ。Mac側が悪い可能性が高いけど、検証が難しい。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;結論&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;高いけど、買って良かった。色々時間節約になった！&lt;/li&gt;
&lt;li&gt;SONYのMDR-1000Xもちょっと惹かれたけど、Amazonのレビュー数が十分の一くらいしか無いので、止めた。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B01LXS5BXS&quot;}&lt;/p&gt;
&lt;h3&gt;追記&lt;/h3&gt;
&lt;p&gt;2018/12/1 2年経過してイヤーパッドが壊れてきた。&lt;/p&gt;
&lt;p&gt;3rdパーティの品物は品質が高くないので1〜3年に1回ペースで、イヤーパッドを交換していく感じになりました。&lt;/p&gt;
</content:encoded></item><item><title>Railsの404エラーページをコマンド1発でクールにする</title><link>https://blog.teraren.com/posts/make-rails-404-page-fancy/</link><guid isPermaLink="true">https://blog.teraren.com/posts/make-rails-404-page-fancy/</guid><description>Railsの404エラーページをコマンド1発でクールにする</description><pubDate>Wed, 15 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Railsのエラーページがかっこ悪い！&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2017/02/Screen-Shot-2017-02-15-at-19.10.44.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ググっても欲しいテンプレが見つからない！ってことで、作りました。&lt;/p&gt;
&lt;p&gt;以下のコマンドを1発叩くだけでマシなテンプレートになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl https://gist.githubusercontent.com/matsubo/1fc73d7632dc45a6ecb6d75edfc7764d/raw/b2363a18e001c07f2288f4a90c50c0edbb12a90e/main.sh | sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;スクリーンショット&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2017/02/Screen-Shot-2017-02-15-at-19.02.54.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2017/02/Screen-Shot-2017-02-15-at-19.03.30.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;デモ: &lt;a href=&quot;https://postcode.teraren.com/asdfasdf&quot;&gt;https://postcode.teraren.com/asdfasdf&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;ソースコード&lt;/h2&gt;
&lt;p&gt;適当に作っただけなので、もっとかっこよくしたい場合はForkどうぞ。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/matsubo/1fc73d7632dc45a6ecb6d75edfc7764d&quot;&gt;https://gist.github.com/matsubo/1fc73d7632dc45a6ecb6d75edfc7764d&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Rubyでn営業日目を取得する方法と注意</title><link>https://blog.teraren.com/posts/qiita-20170215-406096cf930a9b75a7ad/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20170215-406096cf930a9b75a7ad/</guid><description>business_time gemを使ったn営業日後の日付取得で、タイムゾーンと営業時間にハマった際の対処法。</description><pubDate>Wed, 15 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;概要&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;営業日計算には &lt;a href=&quot;https://github.com/bokmann/business_time&quot;&gt;business_time&lt;/a&gt;を使うのが便利です。&lt;/li&gt;
&lt;li&gt;しかしながら、タイムゾーン関連でハまったので、メモを残しておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;結論&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;実行環境のタイムゾーンに依存しないように、日本時間で 4 営業日目の日付を取得したかったら以下のように書く必要があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;4.business_days.after(Time.current.in_time_zone(&apos;Tokyo&apos;).midnight).to_date
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;例えば、上記コマンドの実行日が土曜日か日曜日の場合、1営業日後を求めると火曜日の日付が返却されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;試行錯誤した過程&lt;/h1&gt;
&lt;p&gt;以下に、意図した値とは違う値が返ってくる例を書いておきます。
&lt;strong&gt;一般的なユースケースでは使われないと思うコードなので単純にコピー&amp;amp;ペーストしないように。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;Time.zoneの値に依存した結果が返る&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;公式のサンプルコードがこれです。&lt;/li&gt;
&lt;li&gt;当たり前ですが、ローカルタイムで計算されます。&lt;/li&gt;
&lt;li&gt;意図した日の前後が返ってくる場合があります。&lt;/li&gt;
&lt;li&gt;営業時間が考慮されてしまうので、そのタイムゾーンの、その日の営業時間が終わると+1日された値が返ってくる&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;4.business_days.from_now.to_date
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;タイムゾーンは考慮しているが、時間帯によって1日プラスされる&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;タイムゾーンは東京のタイムゾーンで計算されるので問題無いです。&lt;/li&gt;
&lt;li&gt;しかしながら、その日の営業時間が終了したら、次の日と扱われるので日本時間で営業時間が終了すると1日意図した値より大きい値が返ってきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;4.business_days.after(Time.current.in_time_zone(&apos;Tokyo&apos;)).to_date
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;番外編：休日から1営業日後は月曜日では無く、火曜日&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;土曜日から換算した、1営業日後は月曜だと考えますが、営業日の定義によっては火曜が返ってくるのが正しいです。&lt;/li&gt;
&lt;li&gt;個人的にはモードで切り替えたいが。&lt;/li&gt;
&lt;li&gt;詳細な議論はこちら
&lt;ul&gt;
&lt;li&gt;https://github.com/bokmann/business_time/pull/116&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;rspec&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;意図した時間を返却するかどうかは、以下のようなrspecを使って検証するのが良いと思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;  describe &apos;check behavior of business_days gem&apos; do
    let(:freeze) { Time.utc(2017, 2, 15) }
    let(:expected_date) { (freeze + 6.days).to_date }
    let(:timezone) { &apos;Asia/Tokyo&apos; }

    shared_examples &apos;success&apos; do
      it &apos;should be correct day&apos; do
        Time.use_zone(timezone) do
          Timecop.freeze(freeze)
          expect(4.business_days.after(freeze.in_time_zone(&apos;Tokyo&apos;)).to_date).to eq expected_date
        end
      end
    end

    it_behaves_like &apos;success&apos;

    context &apos;Different Timezone&apos; do
      it_behaves_like &apos;success&apos; do
        let(:timezone) { &apos;UTC&apos; }
      end
      it_behaves_like &apos;success&apos; do
        let(:timezone) { &apos;America/Los_Angeles&apos; }
      end
      it_behaves_like &apos;success&apos; do
        let(:timezone) { &apos;Samoa&apos; }
      end
    end
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;参考資料&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Fix methods after and before when date is on weekend #116
&lt;ul&gt;
&lt;li&gt;https://github.com/bokmann/business_time/pull/116&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Rails における Timezone の扱い方
&lt;ul&gt;
&lt;li&gt;https://blog.teraren.com/2016/09/29/rails-timezone/&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[Ruby]祝日判断や休日判断を ruby でやるなら、これでいいんじゃないかな - メモ
&lt;ul&gt;
&lt;li&gt;http://qiita.com/ryoff/items/02b00ffc121037c25e16&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>xargsで並列処理してCPUを100％使い切ろう</title><link>https://blog.teraren.com/posts/xargs-concurrent-execution/</link><guid isPermaLink="true">https://blog.teraren.com/posts/xargs-concurrent-execution/</guid><description>xargsで並列処理してCPUを100％使い切ろう</description><pubDate>Fri, 03 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;6000枚の画像を一括変換したかったので。&lt;/li&gt;
&lt;li&gt;普通にmogrifyを打つだけだと1プロセスなので1コアしか使ってくれないです。&lt;/li&gt;
&lt;li&gt;最近のPCは1コアの周波数を低めにして、多くのコアを積んで処理を並列に動かすことによって高速化を行うのが主流です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ちゃんと全てのコアを使い切って変換をする必要があります。&lt;/li&gt;
&lt;li&gt;xargsコマンドを使うと並行処理を簡単に行えます。-Pで並列数、-nで1コマンド辺りの引数の数を指定します。-nは無くても良いですが1コマンドの起動コストを減らすために指定してあげるのが良いです。&lt;/li&gt;
&lt;li&gt;ファイル名に半角スペースが入っている場合があるので、find側に-print0オプションと、xargs側に-0オプションを指定しています。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% find . -type f -print0 -name &apos;*svg&apos; | xargs -0 -n 5 -P 8 mogrify -format eps
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>OOPでPPAP</title><link>https://blog.teraren.com/posts/qiita-20161227-583531c592a181c27603/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20161227-583531c592a181c27603/</guid><description>オブジェクト指向（Ruby）で PPAP を表現してみました。</description><pubDate>Tue, 27 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;オブジェクト指向（Ruby）で PPAP を表現してみました。
何をモデリングして、どこまで作り込むかを若干悩みました。30 分程度のスコープでアウトプットするという目標でやりました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#
# &quot;PPAP (Pen-Pineapple-Apple-Pen)&quot;
#
require &apos;./ppap&apos;

# P-P-A-P
class PPAP
  def sing
    i = Human.new

    # I have a pen, I have an apple
    i.have Pen.new
    i.have Apple.new
    #
    # Uh! Apple-Pen!
    apple_pen = i.combine

    # I have a pen, I have pineapple
    i.have Pen.new
    i.have Pineapple.new

    # Uh! Pineapple-Pen!
    pineapple_pen = i.combine

    # Apple-Pen, Pineapple-Pen
    # Uh! Pen-Pineapple-Apple-Pen
    i.have apple_pen
    i.have pineapple_pen
    pen_pineapple_apple_pen = i.combine

    # Pen-Pineapple-Apple-Pen
    pen_pineapple_apple_pen

  end
end

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;テスト付き&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;class TestPPAP &amp;lt; Minitest::Test

  def test_ppap
    assert_instance_of PenPinappleApplePen, PPAP.new.sing
  end

end
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ソースコード&lt;/h2&gt;
&lt;p&gt;https://github.com/matsubo/oop_ppap/&lt;/p&gt;
</content:encoded></item><item><title>YAMAHA RTX1200をmackerelで監視</title><link>https://blog.teraren.com/posts/yamaha-rtx1200-mackerel-monitoring/</link><guid isPermaLink="true">https://blog.teraren.com/posts/yamaha-rtx1200-mackerel-monitoring/</guid><description>自宅のYAMAHA RTX1200ルーターのトラフィックやリソースをMackerelで可視化・監視する設定手順をRTX1200の設定ファイルとともに紹介</description><pubDate>Sat, 29 Oct 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;MackerelでRTX1200を監視設定&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;家のRTX1200のリソースを監視します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B001G79VGK&quot;}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/dolpen/items/89a5dfc2f8ab788e75da&quot;&gt;こちら&lt;/a&gt;を参考にセットアップしてみました&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;現在のRTX1200の設定&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# RTX1200 Rev.10.01.71 (Thu Sep 29 15:08:40 2016)
# MAC Address : 00:a0:de:68:90:0c, 00:a0:de:68:90:0d, 00:a0:de:68:90:0e
# Memory 128Mbytes, 3LAN, 1BRI
# main:  RTX1200 ver=c0 serial=D2F004125 MAC-Address=00:a0:de:68:90:0c MAC-Address=00:a0:de:68:90:0d MAC-Address=00:a0:de:68:90:0e
# Reporting Date: Oct 29 02:12:00 2016
ip route default gateway pp 3
ip keepalive 1 icmp-echo 10 5 dhcp lan3
ip lan1 address 192.168.1.1/24
ip lan1 proxyarp on
ip lan1 secure filter in 100000 100001 100002 100003 100004 100005 100006 100007 100099
ip lan2 secure filter in 102003 102020 102021 102022 102023 102024 102025 102030 102032
ip lan2 secure filter out 102013 102020 102021 102022 102023 102024 102025 102026 102027 102099 dynamic 102080 102081 102082 102083 102084 102085 102098 102099
ip lan2 nat descriptor 299
description lan3 PRV/DHCP/226:
lan shutdown lan3
ip lan3 address dhcp
ip lan3 secure filter in 102003 102020 102021 102022 102023 102024 102025 102030 102032
ip lan3 secure filter out 102013 102020 102021 102022 102023 102024 102025 102026 102027 102099 dynamic 102080 102081 102082 102083 102084 102085 102098 102099
pp select 3
 description pp PRV/PPPoE/2:gmo
 pp keepalive interval 30 retry-interval=30 count=12
 pp always-on on
 pppoe use lan2
 pppoe auto connect on
 pppoe auto disconnect off
 pp auth accept pap chap
 pp auth myname xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxx
 ppp lcp mru on 1454
 ppp ipcp ipaddress on
 ppp ipcp msext on
 ppp ccp type none
 ip pp mtu 1500
 ip pp secure filter in 202003 202020 202021 202022 202023 202024 202025 202030 202032 202080 202081 202082 13 14
 ip pp secure filter out 202013 202020 202021 202022 202023 202024 202025 202026 202027 202099 dynamic 202080 202081 202082 202083 202084 202085 202098 202099
 ip pp nat descriptor 1200
 pp enable 3
pp select anonymous
 pp name &quot;pptp server&quot;
 pp bind tunnel1
 pp auth request mschap-v2
 pp auth username xxxxxxxxxxxx xxxxxxxxxxxxxxxx
 ppp ipcp ipaddress on
 ppp ipcp msext on
 ip pp remote address pool dhcp
 ip pp mtu 1258
 pp enable anonymous
tunnel select 1
 tunnel encapsulation l2tp
 ipsec tunnel 1
  ipsec sa policy 1 1 esp aes-cbc sha-hmac
  ipsec ike keepalive log 1 off
  ipsec ike keepalive use 1 off
  ipsec ike nat-traversal 1 on
  ipsec ike pre-shared-key 1 text xxxxxxxxxxxxxxxxxxxxxxx
  ipsec ike remote address 1 any
 l2tp tunnel auth off
 l2tp tunnel disconnect time off
 l2tp keepalive use on
 ip tunnel tcp mss limit auto
 tunnel enable 1
ip filter 1 pass * 192.168.1.7 tcp * 22,www,https,domain
ip filter 2 pass * 192.168.1.7 udp * domain
ip filter 3 pass * 192.168.1.1 esp * *
ip filter 4 pass * 192.168.1.1 udp * 500
ip filter 5 pass * 192.168.1.1 udp * 4500
ip filter 6 pass * 192.168.1.1 udp * 1701
ip filter 7 pass * 192.168.1.7 tcp * 22,www,https,domain
ip filter 8 pass * 192.168.1.7 udp * domain
ip filter 9 pass * * esp * *
ip filter 10 pass * 192.168.1.7 udp * 500
ip filter 11 pass * 192.168.1.7 udp * 4500
ip filter 12 pass * 192.168.1.7 udp * 1701
ip filter 13 pass * * tcp * 22,www,https,domain
ip filter 14 pass * * udp * domain
ip filter 100000 reject * * udp,tcp 135 *
ip filter 100001 reject * * udp,tcp * 135
ip filter 100002 reject * * udp,tcp netbios_ns-netbios_dgm *
ip filter 100003 reject * * udp,tcp * netbios_ns-netbios_dgm
ip filter 100004 reject * * udp,tcp netbios_ssn *
ip filter 100005 reject * * udp,tcp * netbios_ssn
ip filter 100006 reject * * udp,tcp 445 *
ip filter 100007 reject * * udp,tcp * 445
ip filter 100099 pass * * * * *
ip filter 102000 reject 10.0.0.0/8 * * * *
ip filter 102001 reject 172.16.0.0/12 * * * *
ip filter 102002 reject 192.168.0.0/16 * * * *
ip filter 102003 reject 192.168.1.0/24 * * * *
ip filter 102010 reject * 10.0.0.0/8 * * *
ip filter 102011 reject * 172.16.0.0/12 * * *
ip filter 102012 reject * 192.168.0.0/16 * * *
ip filter 102013 reject * 192.168.1.0/24 * * *
ip filter 102020 reject * * udp,tcp 135 *
ip filter 102021 reject * * udp,tcp * 135
ip filter 102022 reject * * udp,tcp netbios_ns-netbios_ssn *
ip filter 102023 reject * * udp,tcp * netbios_ns-netbios_ssn
ip filter 102024 reject * * udp,tcp 445 *
ip filter 102025 reject * * udp,tcp * 445
ip filter 102026 restrict * * tcpfin * www,21,nntp
ip filter 102027 restrict * * tcprst * www,21,nntp
ip filter 102030 pass * 192.168.1.0/24 icmp * *
ip filter 102031 pass * 192.168.1.0/24 established * *
ip filter 102032 pass * 192.168.1.0/24 tcp * ident
ip filter 102033 pass * 192.168.1.0/24 tcp ftpdata *
ip filter 102034 pass * 192.168.1.0/24 tcp,udp * domain
ip filter 102035 pass * 192.168.1.0/24 udp domain *
ip filter 102036 pass * 192.168.1.0/24 udp * ntp
ip filter 102037 pass * 192.168.1.0/24 udp ntp *
ip filter 102099 pass * * * * *
ip filter 103000 pass * * tcp * 8000
ip filter 202000 reject 10.0.0.0/8 * * * *
ip filter 202001 reject 172.16.0.0/12 * * * *
ip filter 202002 reject 192.168.0.0/16 * * * *
ip filter 202003 reject 192.168.1.0/24 * * * *
ip filter 202010 reject * 10.0.0.0/8 * * *
ip filter 202011 reject * 172.16.0.0/12 * * *
ip filter 202012 reject * 192.168.0.0/16 * * *
ip filter 202013 reject * 192.168.1.0/24 * * *
ip filter 202020 reject * * udp,tcp 135 *
ip filter 202021 reject * * udp,tcp * 135
ip filter 202022 reject * * udp,tcp netbios_ns-netbios_ssn *
ip filter 202023 reject * * udp,tcp * netbios_ns-netbios_ssn
ip filter 202024 reject * * udp,tcp 445 *
ip filter 202025 reject * * udp,tcp * 445
ip filter 202026 restrict * * tcpfin * www,21,nntp
ip filter 202027 restrict * * tcprst * www,21,nntp
ip filter 202030 pass * 192.168.1.0/24 icmp * *
ip filter 202031 pass * 192.168.1.0/24 established * *
ip filter 202032 pass * 192.168.1.0/24 tcp * ident
ip filter 202033 pass * 192.168.1.0/24 tcp ftpdata *
ip filter 202034 pass * 192.168.1.0/24 tcp,udp * domain
ip filter 202035 pass * 192.168.1.0/24 udp domain *
ip filter 202036 pass * 192.168.1.0/24 udp * ntp
ip filter 202037 pass * 192.168.1.0/24 udp ntp *
ip filter 202080 pass * 192.168.1.1 esp * *
ip filter 202081 pass * 192.168.1.1 udp * 500
ip filter 202082 pass * 192.168.1.1 udp * 4500
ip filter 202099 pass * * * * *
ip filter 500000 restrict * * * * *
ip filter dynamic 102080 * * ftp
ip filter dynamic 102081 * * domain
ip filter dynamic 102082 * * www
ip filter dynamic 102083 * * smtp
ip filter dynamic 102084 * * pop3
ip filter dynamic 102085 * * submission
ip filter dynamic 102098 * * tcp
ip filter dynamic 102099 * * udp
ip filter dynamic 202080 * * ftp
ip filter dynamic 202081 * * domain
ip filter dynamic 202082 * * www
ip filter dynamic 202083 * * smtp
ip filter dynamic 202084 * * pop3
ip filter dynamic 202085 * * submission
ip filter dynamic 202098 * * tcp
ip filter dynamic 202099 * * udp
nat descriptor type 1 masquerade
nat descriptor address outer 1 ipcp
nat descriptor address inner 1 auto
nat descriptor masquerade static 1 1 192.168.1.1 esp
nat descriptor masquerade static 1 2 192.168.1.1 udp 500
nat descriptor masquerade static 1 3 192.168.1.1 udp 4500
nat descriptor type 299 masquerade
nat descriptor address outer 299 primary
nat descriptor type 1000 nat-masquerade
nat descriptor type 1200 masquerade
nat descriptor masquerade static 1200 1 192.168.1.7 tcp www
nat descriptor masquerade static 1200 2 192.168.1.7 udp domain
nat descriptor masquerade static 1200 3 192.168.1.7 tcp domain
nat descriptor masquerade static 1200 4 192.168.1.7 tcp 22
nat descriptor masquerade static 1200 5 192.168.1.7 tcp https
nat descriptor masquerade static 1200 6 192.168.1.7 esp
nat descriptor masquerade static 1200 7 192.168.1.7 udp 4500
nat descriptor masquerade static 1200 8 192.168.1.7 udp 500
nat descriptor masquerade static 1200 9 192.168.1.7 tcp 9001
ipsec auto refresh on
ipsec transport 1 1 udp 1701
syslog notice on
syslog info off
tftp host 192.168.1.101
dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.1.100-192.168.1.254/24
dns server pp 3
dns server select 500003 pp 3 any . restrict pp 3
dns server select 500227 dhcp lan3 any .
dns private address spoof on
snmp sysname yamaha-rtx1200-00a0de68900c
schedule at 1 startup * lua mackerel.lua
l2tp service on
httpd host lan1
upnp use on
statistics cpu on
statistics memory on
statistics traffic on
statistics flow on
statistics route on
statistics nat on
statistics filter on
lua use on
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;luaファイル。RTX1200へtftpで転送して、実行する。
sjisで保存する必要があります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-------------------------- ##  設定値  ##--------------------------------

-- 監視間隔（1 - 864000 秒）
-- 5分以上の間隔にすると Mackerel の Connectivity アラートが上がるので監視から外すか5分未満にする
idle_time = 60

-- os.time と unix time のオフセット(秒)
os_time_offset = 315532800;

-- Mackerel API に向けた http プロキシのエンドポイントURL
proxy_tsdb = &quot;http://rtx1200.teraren.com/api/v0/tsdb&quot;

-- Mackerel で実行端末用に作成した hostId
-- @see http://help-ja.mackerel.io/entry/spec/api/v0#host-create
host = &quot;2QCKGHipash&quot;

---------------------- ##  設定値ここまで  ##----------------------------

------------------------------------------------------------
-- ルーターのハードウェアリソースの使用状況を取得する関数         --
-- サンプルからありがたく拝借
------------------------------------------------------------
function rt_res_status(table)
    local rtn, str
    local cmd = &quot;show environment&quot;
    rtn, str = rt.command(cmd)
    if (rtn) and (str) then
        for k, v in pairs(table) do
            v.val = str:match(v.ptn)
            if (v.val) then
                v.val = tostring(v.val)
            end
        end
    else
        str = cmd .. &quot;コマンド実行失敗\r\n\r\n&quot;
    end
    return rtn, str
end

------------------------------------------------------------
-- Mackerel 向けの MetricValue API Post 文字列生成                    --
-- @see http://help-ja.mackerel.io/entry/spec/api/v0#metric-value-post
------------------------------------------------------------
function make_post_text(host, time, table)
    local a = &quot;&quot;;
    for k, v in pairs(table) do
        a = a .. string.format(&quot;{\&quot;hostId\&quot;:\&quot;%s\&quot;,\&quot;name\&quot;:\&quot;%s\&quot;,\&quot;value\&quot;:%s,\&quot;time\&quot;:%d}&quot;, host, v.name, v.val, time) .. &quot;,&quot;
    end
    return &quot;[&quot; .. string.sub(a,1,-2) .. &quot;]&quot;
end

------------------------------------------------------------
-- メインルーチン                                           --
------------------------------------------------------------

-- ハードウェアリソース情報テーブル
local rt_res_tbl = {
    cpu_5sec = { ptn = &quot;(%d+)%%%(5sec%)&quot;, val = 0 , name = &quot;custom.rtx.cpu.5sec&quot;},
    cpu_1min = { ptn = &quot;(%d+)%%%(1min%)&quot;, val = 0 , name = &quot;custom.rtx.cpu.1min&quot;},
    cpu_5min = { ptn = &quot;(%d+)%%%(5min%)&quot;, val = 0 , name = &quot;custom.rtx.cpu.5min&quot;},
    memory = { ptn = &quot;(%d+)%% used&quot;, val = 0 , name = &quot;custom.rtx.memory.usage&quot;},
    packet_small = { ptn = &quot;(%d+)%%%(small%)&quot;, val = 0 , name = &quot;custom.rtx.packetbuff.small&quot;},
    packet_middle = { ptn = &quot;(%d+)%%%(middle%)&quot;, val = 0 , name = &quot;custom.rtx.packetbuff.middle&quot;},
    packet_large = { ptn = &quot;(%d+)%%%(large%)&quot;, val = 0 , name = &quot;custom.rtx.packetbuff.large&quot;},
    packet_huge = { ptn = &quot;(%d+)%%%(huge%)&quot;, val = 0 , name = &quot;custom.rtx.packetbuff.huge&quot;},
    temp = { ptn = &quot;筐体内温度%(℃%): (%d+)&quot;, val = 0 , name = &quot;custom.rtx.temperature.body&quot;}
}

-- HTTPリクエスト用テーブル
local http_req_tbl = {
    url = proxy_tsdb,
    method = &quot;POST&quot;,
    content_type = &quot;application/json&quot;
}

local rtn, str, num, now

while (true) do
    -- リソースの取得
    rtn, str = rt_res_status(rt_res_tbl)
    -- 現在時刻をエポック秒にする
    now = os.time() + os_time_offset
    -- コマンド失敗時は処理しない(Mackerel の Connectivity アラートを上げさせる)
    if (rtn) then
        -- リクエストを発行
        http_req_tbl.post_text = make_post_text(
            host,
            now,
            rt_res_tbl
        )
        rt.httprequest(http_req_tbl)
        -- http_res_tbl = rt.httprequest(http_req_tbl)
        -- print(http_req_tbl.post_text)
        -- print(http_res_tbl.body)
    end
    rt.sleep(idle_time)
end
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;LANにあるnginxの設定&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;server{
    listen 80;
    server_name rtx1200.teraren.com;
    access_log /var/log/nginx/rtx1200.teraren.com main;

    location / {
      proxy_pass https://mackerel.io;
      proxy_set_header X-Api-key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx;
      proxy_ssl_session_reuse off;
      allow 192.168.1.0/24;
      allow 222.230.108.57;
      deny  all;
    }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;夏は熱くなるなぁ。。。&lt;br /&gt;
密閉されているところにおいてあるから厳しそう。&lt;/p&gt;
</content:encoded></item><item><title>WordPressのページキャッシュを一括で作る</title><link>https://blog.teraren.com/posts/wordpress-bulk-page-cache/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-bulk-page-cache/</guid><description>WordPressのComet Cacheプラグインで全記事のページキャッシュをwp-cliとcurlを組み合わせて一括生成するシェルコマンドを紹介。</description><pubDate>Thu, 27 Oct 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1ヶ月前ぐらいにzencacheの再作成が重いから、アクセスも少ないし、無効にしたのだが、それはそれでページ表示がもっさりしていてむかつくので、再度有効にしてみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そもそも、この遅さは一体なんなんだろうか。。。。プロファイリングするのも面倒だし。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ab -n 10 https://blog.teraren.com/
This is ApacheBench, Version 2.3 &amp;lt;$Revision: 1748469 $&amp;gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking matsu.teraren.com (be patient)...
..done

Server Software:        nginx/1.10.1
Server Hostname:        matsu.teraren.com
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256

Document Path:          /blog/
Document Length:        131866 bytes

Concurrency Level:      1
Time taken for tests:   84.083 seconds
Complete requests:      10
Failed requests:        0
Total transferred:      1321440 bytes
HTML transferred:       1318660 bytes
Requests per second:    0.12 [#/sec] (mean)
Time per request:       8408.298 [ms] (mean)
Time per request:       8408.298 [ms] (mean, across all concurrent requests)
Transfer rate:          15.35 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        9   11   3.6      9      21
Processing:  5717 8397 2605.1   7828   13292
Waiting:      218  334 306.4    240    1205
Total:       5726 8408 2604.3   7837   13301
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;キャッシュの一括生成&lt;/h2&gt;
&lt;p&gt;以下のコマンドで一括で作れる。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://ja.wordpress.org/plugins/comet-cache/&quot;&gt;Comet Cache&lt;/a&gt;を使っている場合。&lt;/p&gt;
&lt;p&gt;1記事にcurlでリクエスト出して、キャッシュを作らせる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wp post list --fields=url | xargs -n 1 curl
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ローカルからのアクセスの場合、Comet Cacheがcacheを作らないので、以下の行を&lt;code&gt;wp-config.php&lt;/code&gt;へ入れておく。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;define(&apos;LOCALHOST&apos;, TRUE);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;キャッシュを一括削除するにはファイルを物理削除&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% rm -rf wp-content/cache/zencache/cache/
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>FS01BUをMac OS X El Capitanで使う方法</title><link>https://blog.teraren.com/posts/fs01bu-mac/</link><guid isPermaLink="true">https://blog.teraren.com/posts/fs01bu-mac/</guid><description>FS01BUをMac OS X El Capitanで使う方法</description><pubDate>Mon, 03 Oct 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.amazon.co.jp/3G-USB-%E3%83%89%E3%83%B3%E3%82%B0%E3%83%AB-FS01BU/dp/B015J4WVEO?&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=4e4a267b06b0bace6589562833d2e624&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;FS01BU&lt;/a&gt;をMacに差して、so netの0simを使う方法です。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B015J4WVEO&quot;}&lt;/p&gt;
&lt;p&gt;command + R を押しながら Macし、リカバリモードに入ります。「ターミナル」を起動して&quot;csrutil disable&quot; と入力し、セキュリティ整合性保護機能（SIP）を無効化します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# csrutil disable
Successfully disabled System Integrity Protection. Please restart the machine for the changes to effect.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そして、再起動&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# shutdown -r now
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;USBドングルを差すとCD-ROMとして認識するので、Mac Installationをダブルクリックしてインストールする。&lt;/p&gt;
&lt;p&gt;so-netの0SIMの場合、以下のように設定をすれば、繋がる。&lt;br /&gt;
パスワードは &lt;code&gt;nuro&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/10/Screen-Shot-2016-10-03-at-10.48.30.png&quot; alt=&quot;FS01BU&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>nexus7 (2013)のタッチ不具合を紙で直す</title><link>https://blog.teraren.com/posts/nexus7-2013-touch-panel/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nexus7-2013-touch-panel/</guid><description>Nexus 7 (2013)のタッチパネルが勝手に反応する不具合を、分解して紙1枚を挟むだけで修正できたアーシング対策のDIY修理記録</description><pubDate>Mon, 03 Oct 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;nexus 7 (2013) のタッチパネルの挙動がおかしくなり、タッチしていないところでタッチされるようになってしまった&lt;/li&gt;
&lt;li&gt;かなりストレス溜まる
{/* textlint-disable ja-technical-writing/no-doubled-joshi */}&lt;/li&gt;
&lt;li&gt;USBケーブル接続時は問題無いという書き込みもあったが、差した状態でも外した状態でも再現。
{/* textlint-enable */}&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;解決法&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;紙を1枚入れる。。。。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/10/IMG_6555-2.jpg&quot; alt=&quot;IMG_6555&quot; /&gt;&lt;/p&gt;
&lt;p&gt;まず、ふたを開けます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/10/IMG_6556-2.jpg&quot; alt=&quot;IMG_6556&quot; /&gt;&lt;/p&gt;
&lt;p&gt;バッテリーと下側の基盤が覆われる大きさに紙を切ります。横幅がちょうど良かった手元にあった民宿の案内をカットしました&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/10/IMG_6557-2.jpg&quot; alt=&quot;IMG_6557&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こんなかんじで紙を乗せて、普通にふたを閉めるだけ。&lt;/p&gt;
&lt;p&gt;これだけで直りました。&lt;br /&gt;
デフォルトの状態だと、アーシング不十分なため静電気がディスプレイに溜まってしまって反応してしまう模様。&lt;/p&gt;
&lt;p&gt;nexus7は不具合とか、壊れやすい部品が多くて、数年使って居ると様々なところにダメージがきて、メンテナンスが大変になってくるので、中古品を買う時は使用時間を気にしないといけない。&lt;/p&gt;
&lt;p&gt;おとなしく、高いけどiPad miniにしておけばよかったか。&lt;/p&gt;
&lt;h2&gt;2017年5月12日追記&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;やっぱり、Kindle用に端末が欲しくなって、これを買った。&lt;/li&gt;
&lt;li&gt;iPad miniレベルのクオリティで半額以下の値段なので満足！CPUが遅いのが辛いから、読書用端末って感じ。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>RailsにおけるTimezoneの扱い方</title><link>https://blog.teraren.com/posts/rails-timezone/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-timezone/</guid><description>RailsにおけるTimezoneの扱い方</description><pubDate>Thu, 29 Sep 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;理論&lt;/h2&gt;
&lt;p&gt;前提として、理論に関してはこちらが良くまとまっています。&lt;br /&gt;
&lt;a href=&quot;http://qiita.com/joker1007/items/2c277cca5bd50e4cce5e&quot;&gt;Railsと周辺のTimeZone設定を整理する (active_record.default_timezoneの罠)&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;実践&lt;/h2&gt;
&lt;p&gt;実際、運用する場合はこちらの内容を踏まえてコーディングルールを作る。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;//www.slideshare.net/matsubokkuri/time-zone-in-rails&quot;&gt;Time zone in Rails&lt;/a&gt;&lt;/strong&gt; from &lt;strong&gt;&lt;a href=&quot;//www.slideshare.net/matsubokkuri&quot;&gt;Yuki Matsukura&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;要点&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/09/Screen-Shot-2016-09-30-at-08.30.23.png&quot; alt=&quot;Screen Shot 2016-09-30 at 08.30.23&quot; /&gt;&lt;/p&gt;
&lt;p&gt;UTC+0:00 からの差分が12を越えるタイムゾーンも存在する。もはや、別の日。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/09/Screen-Shot-2016-09-29-at-12.47.26.png&quot; alt=&quot;timezone in rails&quot; /&gt;&lt;/p&gt;
&lt;p&gt;基本的に、日付や時間表記は&lt;code&gt;ActiveSupport::TimeWithZone&lt;/code&gt;クラスで表現しておくようにする。&lt;/p&gt;
&lt;p&gt;関連するサンプルコード。タイムゾーンの扱いを注意する必要がある。&lt;/p&gt;
</content:encoded></item><item><title>livedoor providorからGMOとくとくBBへ乗り換え</title><link>https://blog.teraren.com/posts/isp-gmo-bb/</link><guid isPermaLink="true">https://blog.teraren.com/posts/isp-gmo-bb/</guid><description>7年使ったlivedoorプロバイダのサービス終了に伴いGMOとくとくBBへ移行。固定IP月1100円で夜間11Mbpsの速度と朝の100Mbps台を実測レポート</description><pubDate>Tue, 13 Sep 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;サービス開始直後から今まで7年以上使い続けた、&lt;a href=&quot;http://gigazine.net/news/20090918_livedoor_isp/&quot;&gt;Livedoorプロバイダ&lt;/a&gt;から&lt;a href=&quot;https://px.a8.net/svt/ejp?a8mat=2NSXRO+G3ASDU+50+3HMW2P&quot;&gt;GMOとくとくBB&lt;/a&gt;へ乗り換えました。&lt;/li&gt;
&lt;li&gt;Livedoorプロバイダ自体は申し込み自体は数年前から新規受付は止まっていました。&lt;/li&gt;
&lt;li&gt;ついに、2016年10月にサービスが完全に停止します。Livedoorプロバイダは途中、&lt;a href=&quot;https://www.qit.ne.jp/&quot;&gt;Qit&lt;/a&gt; → so-netへの事業譲渡があり、最終的にso-netが停止に踏み切った模様。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://px.a8.net/svt/ejp?a8mat=2NSXRO+G3ASDU+50+3HMW2P&quot;&gt;&lt;img src=&quot;../../assets/uploads/2019/04/bgt.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;ISPの要件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宅サーバが動いているので、固定IPアドレス1個を安く使えること。今まで1500円/月でした。&lt;/li&gt;
&lt;li&gt;変なフィルタが行われていないこと。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;その要件で探すと、&lt;a href=&quot;https://px.a8.net/svt/ejp?a8mat=2NSXRO+G3ASDU+50+3HMW2P&quot;&gt;GMOとくとくBB&lt;/a&gt;が一番安く、1,100円でした。(今までより安い。。。)&lt;/p&gt;
&lt;h2&gt;ベンチマークなど&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/09/Screen-Shot-2016-09-13-at-01.33.02.png&quot; alt=&quot;Screen Shot 2016-09-13 at 01.33.02&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2016年9月13日 AM1時頃に測定すると、この遅さ。。。11Mbpsか。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/09/Screen-Shot-2016-09-13-at-01.31.04.png&quot; alt=&quot;Screen Shot 2016-09-13 at 01.31.04&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/archive/tag/YAMAHA/&quot;&gt;RTX1200&lt;/a&gt;にて、PP01からPP03へ切り替え。&lt;br /&gt;
マルチホーミングで様子を見たかったのですが、マルチホーミングをするとなぜだかIPマスカレードが動かなくなるので、夜中にダウンタイム覚悟で切り換えました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2016-08-26-at-10.52.11.png&quot; alt=&quot;Screen Shot 2016-08-26 at 10.52.11&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/archive/tag/YAMAHA/&quot;&gt;RTX1200&lt;/a&gt;を設定してから動き続けていたISPとルーター。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/09/Screen-Shot-2016-09-13-at-06.57.29.png&quot; alt=&quot;Screen Shot 2016-09-13 at 06.57.29&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2016年9月13日 朝7時頃に計測すると、100Mbps近くでているので、夜だけが遅い模様。。。&lt;br /&gt;
フレッツのギガを導入するかなーとおもって調べてみたら、工事費が1〜2万円かかりそうなので止めた。&lt;/p&gt;
</content:encoded></item><item><title>Shinjuku.rb #40で発表してきました</title><link>https://blog.teraren.com/posts/shinjuku-rb-40/</link><guid isPermaLink="true">https://blog.teraren.com/posts/shinjuku-rb-40/</guid><description>Shinjuku.rb #40で発表してきました</description><pubDate>Fri, 26 Aug 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://shinjukurb.connpass.com/event/37689/&quot;&gt;Shinjuku.rb #40&lt;/a&gt; で発表してきました。&lt;/p&gt;
&lt;h2&gt;スライド&lt;/h2&gt;
&lt;h2&gt;感想&lt;/h2&gt;
&lt;p&gt;http://x.com/itkrt2y/status/768404695396212736&lt;/p&gt;
&lt;p&gt;http://x.com/treby006/status/768407078079639556&lt;/p&gt;
&lt;p&gt;http://x.com/treby006/status/768404434745384960&lt;/p&gt;
</content:encoded></item><item><title>iPhone6 au SIMロック付を格安SIMで使う</title><link>https://blog.teraren.com/posts/iphone6-au-sim/</link><guid isPermaLink="true">https://blog.teraren.com/posts/iphone6-au-sim/</guid><description>auのSIMロック付きiPhone 6でmineoのau回線SIMを使い4G通信に成功した検証結果と1年利用後の料金比較レポート</description><pubDate>Thu, 25 Aug 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;auのiPhone 6を持っているのですが、SIMロックは解除の対象ではありません。また、auのMVNOでもSIMロックがかかっていると、利用が保証されていない状態でした。&lt;/li&gt;
&lt;li&gt;しかし、携帯料金が不本意に高いので、&lt;a href=&quot;http://mineo.jp/syokai/?jrp=syokai&amp;amp;kyb=T1E6C0A0S8&quot;&gt;mineo&lt;/a&gt;のauキャリア用 SIMを使ってみました！&lt;/li&gt;
&lt;li&gt;結果は、ちゃんと動く！4Gで通信できます！！デメリットは、テザリングは不可能。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;auキャリア時代&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;外出先でインターネットに接続する必要が、たまーにあるので、テザリング有りのプランでした。&lt;/li&gt;
&lt;li&gt;ほとんど電話はかけません。とにかく、定額パケット代がほとんどを占めている状態です。そのくせして6GB/月しか使えません。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/08/Screen-Shot-2016-08-25-at-20.43.26.png&quot; alt=&quot;Screen Shot 2016-08-25 at 20.43.26&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/08/Screen_Shot_2017-08-21_at_12_29_56.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;&lt;a href=&quot;http://mineo.jp/syokai/?jrp=syokai&amp;amp;kyb=T1E6C0A0S8&quot;&gt;mineo&lt;/a&gt;のau料金&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;本当に使えるのか！？と思ってしまうくらい、今までの料金に比べて安い。&lt;/li&gt;
&lt;li&gt;テザリングのために、3GBのSIMを2枚契約しても、900 + 1510 = 2410円/月！（複数回線割引があるので、これに−50円）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/08/price-table-2.png&quot; alt=&quot;price table&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;iPhone 6 auではテザリング不能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;オフィシャルでは、テザリング不可能と有ります。実際は繋がるかも？と思ったけど、表記通り無理でした。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/08/Screen-Shot-2016-08-25-at-21.09.45.png&quot; alt=&quot;Screen Shot 2016-08-25 at 21.09.45&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;パーソナルホットスポットのメニューがiOSの設定メニューから消えました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/08/IMG_6525.jpg&quot; alt=&quot;IMG_6525&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;送られてきたSIMカードは、auで使われている物と同じ。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/08/IMG_6526.jpg&quot; alt=&quot;IMG_6526&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;スピードテスト&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;新宿の屋外で計測しました。&lt;/li&gt;
&lt;li&gt;速度は充分速いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/08/IMG_6522.jpg&quot; alt=&quot;IMG_6522&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://mineo.jp/syokai/?jrp=syokai&amp;amp;kyb=T1E6C0A0S8&quot;&gt;mineo&lt;/a&gt;のau版は、iPhone 6 au SIMロックでも使えます！&lt;/li&gt;
&lt;li&gt;1GBプランでは少なかったかも。3GBでも100円/月増えるだけなので、3GBプランぐらいが良いかと思います。1GBだと、ちょっと使いすぎたり重めのアプリをダウンロードするとすぐに上限になってしまう。&lt;/li&gt;
&lt;li&gt;単純計算で、(6000-1500)*12=54,000円/年 お得になりますね。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1年使った結果（2017/8月追記）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1年使ってみたのでレビュー。&lt;/li&gt;
&lt;li&gt;mineoの利用料金。最初の3ヶ月はタブレット用にデータ専用SIMも使っており、それも含んだ結果です。&lt;/li&gt;
&lt;li&gt;また、データ容量は3GBでは足りないので、2017年4月から6GBにしました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/08/Screen-Shot-2017-08-21-at-12.48.55.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;1年間合計：39,382円&lt;br /&gt;
1ヶ月平均：3,282円&lt;/p&gt;
&lt;p&gt;金額は想定の範囲ですが、たまに5000円ぐらいかかっているのは通話料です。格安SIMの通話料が凄い高いので。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/08/Screen-Shot-2017-08-21-at-12.45.04.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;例として、2017年3月の明細。&lt;/p&gt;
&lt;p&gt;結果としては、約15,000円/年 安くなりました。&lt;/p&gt;
&lt;h2&gt;3年使った感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;mineoは昼間がほとんどつながらなくて解約しました。&lt;/li&gt;
&lt;li&gt;1年ぐらい我慢していましたが、耐えられなくなりました。&lt;/li&gt;
&lt;li&gt;移行先は&lt;a href=&quot;https://ymobile-store.yahoo.co.jp/&quot;&gt;Yahooモバイル&lt;/a&gt;にしました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Shinjuku.rb #38で発表してきました</title><link>https://blog.teraren.com/posts/shinjuku-rb-line-bot/</link><guid isPermaLink="true">https://blog.teraren.com/posts/shinjuku-rb-line-bot/</guid><description>Shinjuku.rb #38で発表してきました</description><pubDate>Thu, 23 Jun 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;発表資料&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://shinjukurb.doorkeeper.jp/events/47236&quot;&gt;Shinjuku.rb #38&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;https://x.com/matsubokkuri/status/745591642233528320&lt;/p&gt;
&lt;h2&gt;コメント&lt;/h2&gt;
&lt;p&gt;http://x.com/threetreeslight/status/745585217616830464&lt;/p&gt;
&lt;p&gt;http://x.com/sinsoku_listy/status/745583012490809344&lt;/p&gt;
</content:encoded></item><item><title>PayPal Tech Meetup #2で発表してきました</title><link>https://blog.teraren.com/posts/paypal-tech-meetup-2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/paypal-tech-meetup-2/</guid><description>PayPal Tech Meetup #2で発表してきました</description><pubDate>Thu, 16 Jun 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;https://x.com/matsubokkuri/status/743041321128984576&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://eventdots.jp/event/588605&quot;&gt;PayPal Tech Meetup #2&lt;/a&gt;でLTしてきました。&lt;/li&gt;
&lt;li&gt;主なテクノロジー
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.paypal.com/docs/api/&quot;&gt;PayPal REST API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Billing Plans&lt;/li&gt;
&lt;li&gt;Billing Agreements&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://business.line.me/services/products/4/introduction&quot;&gt;BOT API Trial Account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;nginx + let’s encrypt&lt;/li&gt;
&lt;li&gt;Ruby 2.3 + Sinatra + Redis&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;感想
&lt;ul&gt;
&lt;li&gt;PayPalのサブスクリプション周りの仕様がドキュメントにはあまり細かく書いていなかったので、gemのテストケースを見ながら実装することになりました。&lt;/li&gt;
&lt;li&gt;若干、AgreementのCallback周り、Webhook周りの仕様が書かれていなかったり、PayPal側がちゃんと動いていないような気がします。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;発表スライド&lt;/h2&gt;
&lt;p&gt;https://www.slideshare.net/matsubokkuri/line-63086362&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://eventdots.jp/report/20160615_588605&quot;&gt;dotsさんのスペシャルレポート&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/06/Screen-Shot-2016-06-24-at-10.59.32.png&quot; alt=&quot;dots paypal&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;サンプルコード&lt;/h2&gt;
&lt;p&gt;PayPalのSubscription （継続課金）のサンプルコード&lt;/p&gt;
</content:encoded></item><item><title>certbotを使ってSSL証明書を自動更新</title><link>https://blog.teraren.com/posts/lets-encrypt-certbot/</link><guid isPermaLink="true">https://blog.teraren.com/posts/lets-encrypt-certbot/</guid><description>certbotを使ってSSL証明書を自動更新</description><pubDate>Wed, 08 Jun 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Let&apos;s encryptのSSL証明書を自動更新するためのプログラムがcertbotとして切り出されたので対応してみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Mac OS Xの場合&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% brew install certbot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;試しに更新してみる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# brew services stop nginx &amp;amp;&amp;amp; sudo certbot renew ; brew services start nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;期限が近づかないと更新されないので、エラーが表示される。&lt;/p&gt;
&lt;p&gt;/etc/crontabに登録しておく。&lt;br /&gt;
週1回実行する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5 6 * * 0 root brew services stop nginx &amp;amp;&amp;amp; sudo certbot renew ; brew services start nginx &amp;gt;&amp;gt; /var/log/certbot.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>torのリレーnodeセットアップ</title><link>https://blog.teraren.com/posts/tor-relay-node/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tor-relay-node/</guid><description>Torネットワークの仕組みと多段暗号化プロキシとしての特徴を解説し、Mac OS XでHomebrewを使ったTorリレーノードのセットアップ手順をまとめています。</description><pubDate>Thu, 02 Jun 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://forest.watch.impress.co.jp/docs/news/760018.html&quot;&gt;Tor browser 6.0&lt;/a&gt;がリリースされましたね。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Torはひと言で言えば、&lt;a href=&quot;https://www.torproject.org/&quot;&gt;Tor&lt;/a&gt;は「経路が暗号化された多段Socks Proxy」但し、最後のエンドポイントから目的地への通信は平文。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open proxyは悪意のあるproxyの場合、ダダ漏れだし、スピードも遅い。それに対し、Torのnodeは速いし経路上は暗号化されている。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;概念図は以下のようになります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/06/htw2.png&quot; alt=&quot;tor description&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Torを使った不正アクセスをプロテクションするために軽く実験してみました。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;専用ブラウザでTorネットワーク経由で&lt;a href=&quot;http://kakunin.teraren.com/&quot;&gt;確認君&lt;/a&gt;を見るとこんな感じ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/06/Screen-Shot-2016-06-02-at-15.24.07.png&quot; alt=&quot;tor browser&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;セットアップ&lt;/h2&gt;
&lt;p&gt;公式サイトの&lt;a href=&quot;https://www.torproject.org/docs/tor-doc-relay.html.en&quot;&gt;セットアップ手順&lt;/a&gt;はDebianが前提で書かれています。&lt;br /&gt;
このページではMac OS Xでのセットアップ方法を書きます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% brew install tor

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;デフォルトの設定ファイルをダウンロードして、Relayを許可するための設定をします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget https://svn.torproject.org/svn/tor/branches/tor-0_0_9-patches/src/config/torrc.sample.in
% sudo mv torrc.sample.in /usr/local/tor/etc/torrc
% sudo vi /usr/local/tor/etc/torrc

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重要な設定項目はこの辺りです。&lt;br /&gt;
設定ファイルに説明が丁寧に書いてあるので読めばある程度わかると思います。&lt;/p&gt;
&lt;p&gt;Exit nodeとして使われたくないので、ExitPolicyはrejectにしてあります。Exit nodeとして動かすと、Banされたりするので、rejectしています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Nickname matsubokkuri
ContactInfo @matsubokkuri
ORPort 9001
ORBindAddress 192.168.1.7:9001
ExitPolicy reject *:*

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;テンポラリーディレクトリを作成する。（作らなければエラーが出る）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo mkdir -p /usr/local/tor/var/tor

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;サーバをスタートして、ログを確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo brew services start tor
% sudo tail -f /usr/local/var/log/tor.log

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のようなメッセージが表示されて、Torネットワークのnodeから当該ポートにアクセスが可能かが確認されます。&lt;br /&gt;
確認がOKなら、ログに表示されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Jun 02 11:30:02.000 [notice] Bootstrapped 80%: Connecting to the Tor network
Jun 02 11:30:02.000 [notice] Guessed our IP address as 222.230.110.122 (source: 193.23.244.244).
Jun 02 11:30:03.000 [notice] Bootstrapped 85%: Finishing handshake with first hop
Jun 02 11:30:05.000 [notice] Bootstrapped 90%: Establishing a Tor circuit
Jun 02 11:30:07.000 [notice] Tor has successfully opened a circuit. Looks like client functionality is working.
Jun 02 11:30:07.000 [notice] Bootstrapped 100%: Done
Jun 02 11:30:07.000 [notice] Now checking whether ORPort 222.230.110.122:9001 is reachable... (this may take up to 20 minutes -- look for log messages indicating success)

Jun 02 11:39:19.000 [notice] Self-testing indicates your ORPort is reachable from the outside. Excellent. Publishing server descriptor.
Jun 02 11:39:34.000 [notice] Performing bandwidth self-test...done.

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;感想&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;TorのExit nodeを立ち上げたとしても、* リスクしかないから立ち上げる必要無い * ので、やめるべき。Relay nodeを立ち上げることでTorネットワークを応援するのが良いと思います。&lt;/li&gt;
&lt;li&gt;Tor自体はクラッカーではない普通のユーザとして使う分には便利なネットワークです。&lt;/li&gt;
&lt;li&gt;クラッカーからすればTorって便利な仕組み。クラッカーを排除する仕組みをTor自体に入れた方が良いかなーと個人的には思います。でも、そもそものTorの匿名性が損なわれるけど。難しいですね。&lt;/li&gt;
&lt;li&gt;悪意のあるexit nodeが居たら、目的地がHTTPSであっても全部漏れるだろうから、センシティブな情報はTorに流してはいけない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;しばらく運用していると、以下のような感じでログに書かれている。&lt;br /&gt;
大体4日で200MBぐらいのトラフィックを処理している様子。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Jun 08 05:03:54.000 [notice] Heartbeat: Tor&apos;s uptime is 3 days 18:00 hours, with 3 circuits open. I&apos;ve sent 136.31 MB and received 189.31 MB.
Jun 08 05:03:54.000 [notice] Circuit handshake stats since last time: 46/46 TAP, 13/13 NTor.
Jun 08 05:03:54.000 [notice] Since startup, we have initiated 0 v1 connections, 0 v2 connections, 0 v3 connections, and 1378 v4 connections; and received 237 v1 connections, 73 v2 connections, 0 v3 connections, and 4790 v4 connections.
Jun 08 11:03:54.000 [notice] Heartbeat: Tor&apos;s uptime is 4 days 0:00 hours, with 1 circuits open. I&apos;ve sent 143.97 MB and received 198.43 MB.
Jun 08 11:03:54.000 [notice] Circuit handshake stats since last time: 42/42 TAP, 1/1 NTor.
Jun 08 11:03:54.000 [notice] Since startup, we have initiated 0 v1 connections, 0 v2 connections, 0 v3 connections, and 1452 v4 connections; and received 249 v1 connections, 95 v2 connections, 0 v3 connections, and 5103 v4 connections.

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tor nodeを運用していると、HULUとかNetflixにIPアドレスをbanされます。。。&lt;/p&gt;
</content:encoded></item><item><title>固定費0円！0 SIMとYAMAHA RTX1200で回線を冗長化してみる</title><link>https://blog.teraren.com/posts/0sim-rtx1200/</link><guid isPermaLink="true">https://blog.teraren.com/posts/0sim-rtx1200/</guid><description>So-netの0 SIMとFS01BU USBドングルをYAMAHA RTX1200に接続し、月額固定費0円でインターネット回線を冗長化する手順と設定例</description><pubDate>Sun, 14 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宅ネットワークは&lt;a href=&quot;https://amzn.to/3uehBKb&quot;&gt;RTX1200&lt;/a&gt;で構築してあります。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.serverworks.co.jp/tech/2015/11/25/soracom-air-and-rtx1200/&quot;&gt;http://blog.serverworks.co.jp/tech/2015/11/25/soracom-air-and-rtx1200/&lt;/a&gt; を2014年の11月に見つけて、自宅でもやりたいと思ってました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://amzn.to/32NouqM&quot;&gt;FS01BU&lt;/a&gt;と&lt;a href=&quot;https://www.amazon.co.jp/3G-USB%E3%83%89%E3%83%B3%E3%82%B0%E3%83%AB-AK-020-SORACOM%E3%82%B9%E3%82%BF%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%AD%E3%83%83%E3%83%88/dp/B01G1GSYHW?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=Soracom+AIR&amp;amp;qid=1618364409&amp;amp;sr=8-3&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=b7a7ef4e39f620dbacfb5e04d5bd287c&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;Soracom Air&lt;/a&gt;は買ってありました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B001G79VGK&quot;}
::amazon{asin=&quot;B015J4WVEO&quot;}
::amazon{asin=&quot;B01G1GSYHW&quot;}&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.co.jp/3G-USB%E3%83%89%E3%83%B3%E3%82%B0%E3%83%AB-AK-020-SORACOM%E3%82%B9%E3%82%BF%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%AD%E3%83%83%E3%83%88/dp/B01G1GSYHW?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&amp;amp;dchild=1&amp;amp;keywords=Soracom+AIR&amp;amp;qid=1618364409&amp;amp;sr=8-3&amp;amp;linkCode=ll1&amp;amp;tag=matsubo0e-22&amp;amp;linkId=aed29f1772e5c647a20c518bf431aab5&amp;amp;language=ja_JP&amp;amp;ref_=as_li_ss_tl&quot;&gt;Soracom AIR&lt;/a&gt;は、利用しなくても月額300円かかり、あとは従量課金です。自宅用途で遊び使うだけなので躊躇していました。&lt;/li&gt;
&lt;li&gt;ログインしてのactivationもちょっと面倒で放置してました。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ソリューション&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;So-netが&lt;a href=&quot;http://lte.so-net.ne.jp/sim/0sim/&quot;&gt;0 SIM&lt;/a&gt;という、月額固定費0円で、500MBまで使えるサービスを開始しました。&lt;/li&gt;
&lt;li&gt;速攻申し込んで、SIMカードが届いたので、早速、RTX1200に設定してみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;h3&gt;ハードウェアのセットアップ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;FS01BUにnano SIM -&amp;gt; SIMアダプタを噛ませて挿入します。
&lt;ul&gt;
&lt;li&gt;Soracomと違い、Webでのアクティベーションなどは一切不要でした。届いたらそのまま使えます。&lt;/li&gt;
&lt;li&gt;0 SIMのWeb管理画面にログインしても設定出来る項目は、支払い方法の変更ぐらいでした。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RTX1200に差し込むと、ビービーと音が鳴りますが、すぐに鳴り止みます。&lt;/li&gt;
&lt;li&gt;FS01BUのLEDが緑に点滅していることを確認します。&lt;/li&gt;
&lt;li&gt;RTX1200のWebインターフェイスメニューから、PPP(モバイル)を選択してインターフェイスを追加します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/RTX1200_Rev_10_01_65___1.png&quot; alt=&quot;RTX1200_Rev_10_01_65___1&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;プリセットの選択&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;立ち上がったウィンドウでセットアップをしていきます。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;この画面はプリセットの選択なので、どれでもOKです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/RTX1200_Rev_10_01_65___2.png&quot; alt=&quot;RTX1200_Rev_10_01_65___2&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;接続情報の登録&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;0 SIMの説明書に書いてある情報を入力します。&lt;/li&gt;
&lt;li&gt;下の、「累積データ量や累積通信時間を監視して発信制限を行う」にチェックをすると、デフォルトでは、0が設定されるので、発信を一切出来ない状態になります。&lt;/li&gt;
&lt;li&gt;この部分は、後ほど細かく設定(500MBまで)するので、チェックの有無はどちらでも良いです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/RTX1200_Rev_10_01_65___3.png&quot; alt=&quot;RTX1200_Rev_10_01_65___3&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;フィルタ設定&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;短時間しか接続しないので、フィルタはとりあえず無し。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/RTX1200_Rev_10_01_65___5.png&quot; alt=&quot;RTX1200_Rev_10_01_65___5&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;設定内容の確認&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;これでインターフェイスの追加は終わり。次はルーティング。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/RTX1200_Rev_10_01_65___6.png&quot; alt=&quot;RTX1200_Rev_10_01_65___6&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;完了&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/RTX1200_Rev_10_01_65___7.png&quot; alt=&quot;RTX1200_Rev_10_01_65___7&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ルーティング&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;「ルーティング」の、「静的経路の設定」メニューにある「設定」ボタンを押す。&lt;/li&gt;
&lt;li&gt;接続のダウンを検知するためにキープアライブを設定します。&lt;/li&gt;
&lt;li&gt;Keepaliveのホストは、Tracerouteして、一番近いISPのホストを指定してみました。
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;163.139.126.165&lt;/code&gt;, &lt;code&gt;tok1nn1m4.vectant.ne.jp&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;その他は、よしなに、スクリーンショットのような感じに設定します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/RTX1200_Rev_10_01_65___routing.png&quot; alt=&quot;RTX1200_Rev_10_01_65___routing&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;500MB制限の追加&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;先ほどの設定で、制限を付けた場合は以下の設定が入っており接続出来ないです。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;mobile access limit length
mobile access limit time
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;こんな感じのエラーが出ます。
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Call request is rejected due to length limitation&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;2016/02/13 18:07:47: PP[02] IP Commencing:
2016/02/13 18:07:47: PP[02] IP Commencing: UDP 192.168.1.102:65470 &amp;gt; 216.58.220.206:443
2016/02/13 18:07:47:      45 00 05 62 a7 7c 00 00  3f 11 57 f7 c0 a8 01 66
2016/02/13 18:07:47:      d8 3a dc ce ff be 01 bb  05 4e c9 6f 0d 96 85 b0
2016/02/13 18:07:47:      47 13 30 83 bf 51 30 32  35 03 1a 2f 60 91 67 78
2016/02/13 18:07:47:      5e 32 bb 68 99 35 00 a0  01 00 04 43 48 4c 4f 16
2016/02/13 18:07:47: PP[02] Call request is rejected due to length limitation
2016/02/13 18:07:47: PP[02] IP Commencing:
2016/02/13 18:07:47: PP[02] IP Commencing: UDP 192.168.1.7:53 &amp;gt; c:59326 (DNS response)
2016/02/13 18:07:47:      45 00 00 a4 90 94 00 00  3f 11 1f 4d c0 a8 01 07
2016/02/13 18:07:47:      36 97 d3 21 00 35 e7 be  00 90 0c aa 1f 82 84 00
2016/02/13 18:07:47:      00 01 00 01 00 03 00 01  0d 79 75 6b 69 6d 69 64
2016/02/13 18:07:47:      61 69 66 75 6b 75 03 63  6f 6d 00 00 01 00 01 c0
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;上記の制約を解除しつつ、500MBの制限を設定するコマンド。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;pp select 2
no mobile access limit time
mobile access limit length 500000000
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;500MBの制限は、ルータ再起動か、制限の再設定、クリアコマンドでリセットされます。&lt;/li&gt;
&lt;li&gt;クリアコマンドの例&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;pp select 2
clear mobile access limitation
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;接続確認&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;主回線を物理的に抜くか、キープアライブのホストを存在しないホストに指定するなどして落とせば副回線に切り替わります。&lt;/li&gt;
&lt;li&gt;帯域が細いので、グラフで見ると少し上がるくらいです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/RTX1200_Rev_10_01_65___traffic_.png&quot; alt=&quot;RTX1200_Rev_10_01_65___traffic_&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;接続が成功した場合は以下のようなログが表示されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;2016/02/13 21:13:51: [KEEPALIVE 2] STATUS LED is ON
2016/02/13 21:13:51: PP[02] IP Commencing:
2016/02/13 21:13:51: PP[02] IP Commencing: TCP 192.168.1.110:53906 &amp;gt; 183.79.226.159:80
2016/02/13 21:13:51:      45 00 00 28 ad 69 40 00  3f 06 32 61 c0 a8 01 6e
2016/02/13 21:13:51:      b7 4f e2 9f d2 92 00 50  69 e2 e6 e0 5f e7 f3 39
2016/02/13 21:13:51:      50 10 1f a7 bd 60 00 00
2016/02/13 21:13:51: PP[02] Calling so-net.jp with usb1
2016/02/13 21:13:51: [MOBILE] Signal Strength (0-31): 9 [|  ] (usb1)
2016/02/13 21:13:51: USB[1] SEND [ATDT*99***1#]
2016/02/13 21:13:51: USB[1] RECV [CONNECT 14400000]
2016/02/13 21:13:51: USB[1] Connected
2016/02/13 21:13:51: PP[02] SEND LCP ConfReq in STARTING
2016/02/13 21:13:51:   ff 03 c0 21 01 01 00 12  02 06 00 00 00 00 05 06
2016/02/13 21:13:51:   42 8e f8 4c 07 02
2016/02/13 21:13:51: PP[02] RECV LCP ConfReq in REQSENT
2016/02/13 21:13:51:   ff 03 c0 21 01 00 00 19  02 06 00 00 00 00 03 05
2016/02/13 21:13:51:   c2 23 05 05 06 03 9d d8  1e 07 02 08 02
2016/02/13 21:13:51: PP[02] SEND LCP ConfRej in REQSENT
2016/02/13 21:13:51:   ff 03 c0 21 04 00 00 06  08 02
2016/02/13 21:13:51: PP[02] RECV LCP ConfAck in REQSENT
2016/02/13 21:13:51:   ff 03 c0 21 02 01 00 12  02 06 00 00 00 00 05 06
2016/02/13 21:13:51:   42 8e f8 4c 07 02
2016/02/13 21:13:51: PP[02] RECV LCP ConfReq in ACKRCVD
2016/02/13 21:13:51:   ff 03 c0 21 01 01 00 17  02 06 00 00 00 00 03 05
2016/02/13 21:13:51:   c2 23 05 05 06 03 9d d8  1e 07 02
2016/02/13 21:13:51: PP[02] SEND LCP ConfAck in ACKRCVD
2016/02/13 21:13:51:   ff 03 c0 21 02 01 00 17  02 06 00 00 00 00 03 05
2016/02/13 21:13:51:   c2 23 05 05 06 03 9d d8  1e 07 02
2016/02/13 21:13:51: PP[02] RECV LCP Discard in OPENED
2016/02/13 21:13:51:   ff 03 c0 21 0b 02 00 08  03 9d d8 1e
2016/02/13 21:13:51: PP[02] RECV CHAP Challenge in CS_LISTEN/SS_CLOSED
2016/02/13 21:13:51:   ff 03 c2 23 01 01 00 23  10 00 00 00 00 00 00 00
2016/02/13 21:13:51:   00 00 00 00 00 00 00 00  00 55 4d 54 53 5f 43 48
2016/02/13 21:13:51:   41 50 5f 53 52 56 52
2016/02/13 21:13:51: PP[02] SEND CHAP Response in CS_LISTEN/SS_CLOSED
2016/02/13 21:13:51:   ff 03 c2 23 02 01 00 19  10 1b e1 96 ce a4 d2 ca
2016/02/13 21:13:51:   e0 c4 7a 74 7b ab 02 fe  10 6e 75 72 6f
2016/02/13 21:13:51: PP[02] RECV CHAP Success in CS_OPEN/SS_CLOSED
2016/02/13 21:13:51:   ff 03 c2 23 03 01 00 04
2016/02/13 21:13:51: PP[02] SEND CCP ConfReq in STARTING
2016/02/13 21:13:51:   ff 03 80 fd 01 01 00 09  11 05 00 01 03
2016/02/13 21:13:51: PP[02] SEND IPCP ConfReq in STARTING
2016/02/13 21:13:51:   ff 03 80 21 01 01 00 16  03 06 00 00 00 00 81 06
2016/02/13 21:13:51:   00 00 00 00 83 06 00 00  00 00
2016/02/13 21:13:51: PP[02] RECV LCP ProtRej in OPENED
2016/02/13 21:13:51:   ff 03 c0 21 08 03 00 0f  80 fd 01 01 00 09 11 05
2016/02/13 21:13:51:   00 01 03
2016/02/13 21:13:52: PP[02] RECV IPCP ConfNak in REQSENT
2016/02/13 21:13:52:   ff 03 80 21 03 01 00 1c  81 06 0a 0b 0c 0d 83 06
2016/02/13 21:13:52:   0a 0b 0c 0e 82 06 0a 0b  0c 0d 84 06 0a 0b 0c 0e
2016/02/13 21:13:52: PP[02] SEND IPCP ConfReq in REQSENT
2016/02/13 21:13:52:   ff 03 80 21 01 02 00 22  03 06 00 00 00 00 81 06
2016/02/13 21:13:52:   0a 0b 0c 0d 82 06 0a 0b  0c 0d 83 06 0a 0b 0c 0e
2016/02/13 21:13:52:   84 06 0a 0b 0c 0e
2016/02/13 21:13:53: PP[02] RECV IPCP ConfNak in REQSENT
2016/02/13 21:13:53:   ff 03 80 21 03 02 00 1c  81 06 0a 0b 0c 0d 83 06
2016/02/13 21:13:53:   0a 0b 0c 0e 82 06 0a 0b  0c 0d 84 06 0a 0b 0c 0e
2016/02/13 21:13:54: PP[02] RECV IPCP ConfReq in REQSENT
2016/02/13 21:13:54:   ff 03 80 21 01 00 00 04
2016/02/13 21:13:54: PP[02] SEND IPCP ConfNak in REQSENT
2016/02/13 21:13:54:   ff 03 80 21 03 00 00 0a  03 06 00 00 00 00
2016/02/13 21:13:54: PP[02] RECV IPCP ConfRej in REQSENT
2016/02/13 21:13:54:   ff 03 80 21 04 02 00 10  82 06 0a 0b 0c 0d 84 06
2016/02/13 21:13:54:   0a 0b 0c 0e
2016/02/13 21:13:54: PP[02] SEND IPCP ConfReq in REQSENT
2016/02/13 21:13:54:   ff 03 80 21 01 03 00 16  03 06 00 00 00 00 81 06
2016/02/13 21:13:54:   0a 0b 0c 0d 83 06 0a 0b  0c 0e
2016/02/13 21:13:54: PP[02] RECV IPCP ConfReq in REQSENT
2016/02/13 21:13:54:   ff 03 80 21 01 01 00 04
2016/02/13 21:13:54: PP[02] SEND IPCP ConfAck in REQSENT
2016/02/13 21:13:54:   ff 03 80 21 02 01 00 04
2016/02/13 21:13:54: PP[02] RECV IPCP ConfNak in ACKSENT
2016/02/13 21:13:54:   ff 03 80 21 03 03 00 16  03 06 64 40 ff 65 81 06
2016/02/13 21:13:54:   76 ee c9 21 83 06 76 ee  c9 31
2016/02/13 21:13:54: PP[02] SEND IPCP ConfReq in ACKSENT
2016/02/13 21:13:54:   ff 03 80 21 01 04 00 16  03 06 64 40 ff 65 81 06
2016/02/13 21:13:54:   76 ee c9 21 83 06 76 ee  c9 31
2016/02/13 21:13:54: PP[02] RECV IPCP ConfAck in ACKSENT
2016/02/13 21:13:54:   ff 03 80 21 02 04 00 16  03 06 64 40 ff 65 81 06
2016/02/13 21:13:54:   76 ee c9 21 83 06 76 ee  c9 31
2016/02/13 21:13:54: PP[02] PPP/IPCP up  (Local: 100.64.255.101, Remote: None)
2016/02/13 21:13:54: PP[02] Local  PP IP address 100.64.255.101
2016/02/13 21:13:54: PP[02] Remote PP IP address 0.0.0.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;念のため&lt;a href=&quot;https://kakunin.teraren.com/&quot;&gt;確認君&lt;/a&gt;で。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/Screen-Shot-2016-02-14-at-01.17.18.png&quot; alt=&quot;Screen Shot 2016-02-14 at 01.17.18&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;自宅のインターネット回線を無駄に冗長化しました。&lt;/li&gt;
&lt;li&gt;毎月500MBのカウンタをリセットするLUAを書く。（今は、単純に累計で計算されてしまうので。）&lt;/li&gt;
&lt;li&gt;3ヶ月に1回、接続するLUAを書く。（最低3ヶ月に1回が無いと解約されてしまうので）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今の設定&lt;/p&gt;
</content:encoded></item><item><title>FS01BUからSIMカードが外せなかったので、分解して取り出す</title><link>https://blog.teraren.com/posts/fs01bu-sim/</link><guid isPermaLink="true">https://blog.teraren.com/posts/fs01bu-sim/</guid><description>USB型3GドングルFS01BUでNano SIMアダプターが引っかかり取り出せなくなった際に、トルクスドライバーで分解してSIMを救出した手順</description><pubDate>Sat, 13 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;FS01BUに、Nano SIM -&amp;gt; SIMアダプターを使っていました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B015J4WVEO&quot;}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SIMを入れ替えるために、抜こうと思ったら、抜けない。。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/IMG_3795-7.jpg&quot; alt=&quot;FS01BU 分解&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ここまでしか、トレイを引き出せない。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/Screen-Shot-2016-02-13-at-21.28.50.png&quot; alt=&quot;FS01BU&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本来なら、ここぐらいまで引き出せるはずなのですが、ここまで引き出ません。&lt;br /&gt;
無理矢理引き抜こうとしたら、プラスチックが壊れそうなかんじです。&lt;/p&gt;
&lt;h2&gt;分解&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/IMG_3796-1.jpg&quot; alt=&quot;FS01BU T4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;T4くらいのトルクスドライバーでネジを2本抜きます。1本は、シールでねじ穴が隠されています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/IMG_3797-6.jpg&quot; alt=&quot;FS01BU 分解&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ネジを外したら、無理矢理カバーを少し筒引きはがせば開きます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/IMG_3799-4.jpg&quot; alt=&quot;FS01BU 分解&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こんな感じで、nano SIMが引っかかっていたので、外せない状態でした。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/IMG_3798-1.jpg&quot; alt=&quot;FS01BU 分解&quot; /&gt;&lt;/p&gt;
&lt;p&gt;このとおり、ちゃんと抜けました。&lt;/p&gt;
</content:encoded></item><item><title>CircleCIでRAMを節約</title><link>https://blog.teraren.com/posts/circleci-reduce-ram/</link><guid isPermaLink="true">https://blog.teraren.com/posts/circleci-reduce-ram/</guid><description>CircleCIのコンテナでデフォルト起動する不要なサービス（MongoDB、PostgreSQLなど）を停止してメモリを節約する方法。circle.ymlの設定例付き。</description><pubDate>Fri, 05 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://circleci.com/&quot;&gt;CircleCI&lt;/a&gt;のコンテナは、デフォルトだと以下のサービスが立ち上がっているコンテナでテストが走ります。
&lt;ul&gt;
&lt;li&gt;couchdb (1.3.0)&lt;/li&gt;
&lt;li&gt;memcached (1.4.13)&lt;/li&gt;
&lt;li&gt;mongodb (2.4.13)&lt;/li&gt;
&lt;li&gt;mysql (5.5.41)&lt;/li&gt;
&lt;li&gt;postgresql (9.4 with postgis 2.0 extensions)&lt;/li&gt;
&lt;li&gt;rabbitmq (3.4.4)&lt;/li&gt;
&lt;li&gt;redis (3.0.3)&lt;/li&gt;
&lt;li&gt;zookeeper (3.3.5)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;しかしながら、普通のサービスは全てを使うわけでは無いので、&lt;strong&gt;不要なサービスは落として&lt;/strong&gt;しまって、メモリを節約しましょう。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;サンプルコード&lt;/h2&gt;
&lt;p&gt;こんな感じで。&lt;/p&gt;
&lt;p&gt;circle.yml抜粋。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;machine:
  pre:
    - sudo /etc/init.d/postgresql stop
    - sudo /etc/init.d/mongodb stop
    - sudo /etc/init.d/memcached stop
    - sudo /etc/init.d/mysql stop
    - sudo /etc/init.d/couchdb stop
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ぐぐっても、同じことをしている人は見つからず。。。&lt;/li&gt;
&lt;li&gt;効果としては微量ですけど、メモリの無駄遣いを抑制し、気分的にテストが少し速くなったように感じます。（プラシーボ）&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Qit(Vectant)が不安定なので調査してみた</title><link>https://blog.teraren.com/posts/vectant-qit-unstable/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vectant-qit-unstable/</guid><description>ISPのQit（Vectant）でパケットロスが頻発する問題をtracerouteとpingで調査し、原因箇所を特定して1ヶ月以上対応が遅れたサポートとのやり取りを記録</description><pubDate>Tue, 02 Feb 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ISPはQitを使っているのですが、パケットロスがあって不安定。&lt;/li&gt;
&lt;li&gt;たまに接続がプチフリって感じです。普通の通信はTCPだからあまり気にならないですが、SSHしていると気になります！&lt;/li&gt;
&lt;li&gt;1ヶ月以上前から問い合わせしているのに、いっこうに解決してくれないです。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;tracerouteの結果はこちら&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% traceroute -w 1  www.qit.ne.jp
traceroute to www.qit.ne.jp (61.122.116.145), 64 hops max, 52 byte packets
 1  192.168.1.1 (192.168.1.1)  0.652 ms  0.471 ms  0.401 ms
 2  tok1nn1m4.vectant.ne.jp (163.139.126.165)  3.023 ms  2.402 ms *
 3  163-139-126-190.rv.vectant.ne.jp (163.139.126.190)  2.382 ms  5.077 ms  6.246 ms
 4  163-139-68-53.rv.vectant.ne.jp (163.139.68.53)  7.137 ms  11.134 ms  4.140 ms
 5  ae29.core1.nihonbashi.vectant.ne.jp (163.139.130.161)  3.764 ms  5.269 ms
    ae29.core2.nihonbashi.vectant.ne.jp (163.139.130.165)  9.821 ms
 6  ae0.peer3.nihonbashi.vectant.ne.jp (163.139.128.190)  5.495 ms
    ae1.peer3.nihonbashi.vectant.ne.jp (163.139.128.194)  9.376 ms  7.092 ms
 7  58x159x238x121.ap58.ftth.ucom.ne.jp (58.159.238.121)  6.810 ms  9.550 ms *
 8  61.122.123.82 (61.122.123.82)  9.550 ms
    usen-61x122x114x57.gate01.com (61.122.114.57)  9.200 ms
    61.122.123.82 (61.122.123.82)  7.937 ms
 9  58x159x223x66.ap58.ftth.ucom.ne.jp (58.159.223.66)  16.667 ms *  6.670 ms
10  * 58x159x238x10.ap58.ftth.ucom.ne.jp (58.159.238.10)  8.519 ms  8.941 ms
11  * * *
12  * * *
13  * * *
14  * * *
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;実験&lt;/h2&gt;
&lt;p&gt;28時間、pingを1秒タイムアウトで、0.5秒間隔で送り続けた結果がこちらです。&lt;/p&gt;
&lt;h3&gt;1. ローカルPC→ルータ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;さすが定価10万円のルータ。全くパケットロスしていません。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;--- 192.168.1.1 ping statistics ---
199143 packets transmitted, 199143 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.308/0.927/45.672/0.379 ms
ping -i 0.5 192.168.1.1  11.71s user 83.59s system 0% cpu 28:00:33.96 total
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. ローカルPC→ローカルネットワークルータの1つ先&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;1.5%パケットロスしています。タイムアウト1秒、インターバル0.5秒なので、時間的には3％！！落ちすぎ。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;--- 163.139.126.165 ping statistics ---
199120 packets transmitted, 196223 packets received, 1.5% packet loss
round-trip min/avg/max/stddev = 1.481/2.971/291.843/5.976 ms
ping -i 0.5 163.139.126.165  11.94s user 87.21s system 0% cpu 28:00:22.55 total
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. ローカルPC→ISP出口&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;3.1%パケットロスしています。ISP内のネットワークでも1.5%落ちてるし。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;--- 163.139.128.190 ping statistics ---
199128 packets transmitted, 192997 packets received, 3.1% packet loss
round-trip min/avg/max/stddev = 2.041/6.276/85.520/6.610 ms
ping -i 0.5 163.139.128.190  10.87s user 78.10s system 0% cpu 28:00:25.82 total
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. ローカルPC→ヤフー&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;3.0%パケットロスしています。ISP出口と同じくらいの値なので、納得です。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;--- www.g.yahoo.co.jp ping statistics ---
199149 packets transmitted, 193091 packets received, 3.0% packet loss
round-trip min/avg/max/stddev = 4.919/7.091/49.972/2.061 ms
ping -i 0.5 www.yahoo.co.jp  10.84s user 82.71s system 0% cpu 28:00:37.25 total
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;pingを0.01秒間隔で送る&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;とりあえず、視覚的にどのくらい不安定なのかを見てみるために、pingを断続的に送ってみる。&lt;/li&gt;
&lt;li&gt;あまり良くない行為なので、root権限が必要です。&lt;/li&gt;
&lt;li&gt;宛先は、最寄りのISPホストです&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt; % sudo ping -W 100 -i 0.01 163.139.126.165
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;そのときの動画がこちらです
&lt;ul&gt;
&lt;li&gt;描画が一瞬止まるのは、外部ネットワークから自宅LANにVPNしてやっているためです。&lt;/li&gt;
&lt;li&gt;回線が一瞬不安定になるので、描画が一瞬遅れています。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://www.youtube.com/watch?v=JGJFL_C7vE4&lt;/p&gt;
&lt;h2&gt;帯域は全然使っていません。&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/02/Screen-Shot-2016-02-02-at-21.30.23.png&quot; alt=&quot;Screen Shot 2016-02-02 at 21.30.23&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B014CNJHE0&quot;}&lt;/p&gt;
</content:encoded></item><item><title>.zshrcを4年ぶりにメンテナンス。モダンなzsh環境にしてみた。</title><link>https://blog.teraren.com/posts/modern-zsh-setting/</link><guid isPermaLink="true">https://blog.teraren.com/posts/modern-zsh-setting/</guid><description>zplugをプラグイン管理に採用し、iTerm2のSolarizedカラースキーマも刷新して高速で快適なモダンzsh環境を構築した記録</description><pubDate>Wed, 06 Jan 2016 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;4年ほどメンテナンスしていなかった.zshrcをメンテナンスします。&lt;/li&gt;
&lt;li&gt;1ヶ月前ぐらい、zshのplugin管理のために&lt;a href=&quot;https://github.com/zsh-users/antigen&quot;&gt;antigen&lt;/a&gt;を入れたら、zshの起動に4秒くらいかかるようになってストレスフルだった。
&lt;ul&gt;
&lt;li&gt;しかし、便利なので我慢していた。重いのは初回起動時だけだし。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;やっと重い腰を上げて調査と整理
&lt;ul&gt;
&lt;li&gt;見た目も色々変える。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;見た目Before&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/01/Screen-Shot-2016-01-06-at-23.27.44.png&quot; alt=&quot;zsh before&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;見た目After&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/01/tty.gif&quot; alt=&quot;new zsh setting&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2016/01/Screen-Shot-2016-01-06-at-23.39.21.png&quot; alt=&quot;zsh solarized&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;やったこと&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;zshのplugin管理に&lt;a href=&quot;https://github.com/b4b4r07/zplug&quot;&gt;zplug&lt;/a&gt;を使うようにした
&lt;ul&gt;
&lt;li&gt;かなり速い！すばらしい！オプションも多数！最高です。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;iTerms2のカラースキーマを変更
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/altercation/solarized/blob/master/iterm2-colors-solarized/Solarized%20Dark.itermcolors&quot;&gt;https://github.com/altercation/solarized/blob/master/iterm2-colors-solarized/Solarized%20Dark.itermcolors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;設定をダウンロードして、iTerm2にimport&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;設定後の.zshrc
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/matsu-shell-setting/blob/master/.zshrc&quot;&gt;https://github.com/matsubo/matsu-shell-setting/blob/master/.zshrc&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;oh-my-zshのpluginを色々入れようとしてコード読んでいたけど、ハードコード多くて使えないのばっかり。&lt;/li&gt;
&lt;li&gt;oh-my-zshのプラグインがメンテされていないのが多い。
&lt;ul&gt;
&lt;li&gt;使いたいプラグインがあるなら、自分でコピーしてカスタマイズして使うのが良さそう。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;なんか、zshって数年前盛り上がって、みんな使い出して、今もみんな使っていると思うけど、ちゃんとpluginを整理するプラットフォームって存在していないよね。。。悲しい。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fzf&lt;/code&gt;の連携もやっていきたい。今度は、vimrcの大掃除をする。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;4774138649&quot;}&lt;/p&gt;
</content:encoded></item><item><title>PHP 5.5.30 から PHP 7.0.1 にアップグレードしたら本当に約2.4倍の速くなった</title><link>https://blog.teraren.com/posts/qiita-20151227-5ad75008ce6aa22f62cd/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20151227-5ad75008ce6aa22f62cd/</guid><description>WordPress環境でPHP 5.5からPHP 7.0+Opcacheにアップグレードし、実測で約2.4倍の高速化を確認。</description><pubDate>Sun, 27 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codezine.jp/article/detail/9136&quot;&gt;PHP 7がPHP 5.6と比べて2倍速い&lt;/a&gt;みたいな発表があったので試してみました。&lt;/li&gt;
&lt;li&gt;&lt;a&gt;このBlog&lt;/a&gt; が実験台です。今は、PHP 7 で動いています。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.php.net/ChangeLog-7.php&quot;&gt;Changelog&lt;/a&gt;を見る感じだと、まだまだ大きなバグが出ているので運用環境で使うのは時期早々かもしれません。
&lt;ul&gt;
&lt;li&gt;PHP 5 系から PHP 7 系にするだけで本当に 2 倍速くなります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;測定環境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Wordpres4.4 と ZenCache の環境です。&lt;/li&gt;
&lt;li&gt;純粋に 1 プロセスの処理時間を計測するために並列数は 1&lt;/li&gt;
&lt;li&gt;運用環境に近い環境で測定したかったので ZenCache は有効にした状態で計測&lt;/li&gt;
&lt;li&gt;Mac macOS&lt;/li&gt;
&lt;li&gt;ページのテキスト量が多いので gzip 付きで。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;測定コマンド&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ab -n 1000 -c 1 -H &quot;Accept-Encoding: gzip,deflate&quot; http://matsu.teraren.com/blog/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;PHP 5.5 + APCU&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Requests per second:    101.03 [#/sec] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;PHP 7.0.1 + APCU&lt;/h3&gt;
&lt;p&gt;約14％しか速くなっていないぞ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Requests per second:    116.01 [#/sec] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;PHP 7.0.1 + Opcache&lt;/h3&gt;
&lt;p&gt;よく調べてみると、PHP 7自体にOpcode cacheがある。
PHP7はPHPに元から付いているOpcacheを使った方が良さそう。&lt;/p&gt;
&lt;p&gt;ということで、&lt;code&gt;ini&lt;/code&gt; ファイルでopcache関連を適当に有効化します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Requests per second:    241.69 [#/sec] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;お。かなり速くなりました。&lt;/p&gt;
&lt;p&gt;手元の環境では、&lt;strong&gt;約2.4倍&lt;/strong&gt;速くなりました ！&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;本当に &lt;strong&gt;2.4倍速くなった！&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;ktai style や one click updater で、PHP 7 の Deprecated warning 出たので、プラグインを消して対応しました（もう使っていないので）&lt;/li&gt;
&lt;li&gt;apcu_store() などの APCU 関連がまだ PHP 7 には対応していません。代替方法を調べるのが面倒なので、Redis に置き換えて対応しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.teraren.com/2015/12/26/php7-benchmark/&quot;&gt;元記事&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>RTX1200でVPN(L2TP)設定</title><link>https://blog.teraren.com/posts/rtx1200-l2tp/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rtx1200-l2tp/</guid><description>YAMAHA RTX1200のWebインターフェイスからL2TP/IPsec VPNを設定してリモートから自宅ネットワークに接続する手順と設定ファイルを公開</description><pubDate>Sun, 27 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;前回の、&lt;a href=&quot;/posts/rtx1200-deployment/&quot;&gt;ルータをRTX1200に置き換えて快適生活！&lt;/a&gt;に引き続き、リモートから自宅にVPNするための設定&lt;/li&gt;
&lt;li&gt;現在のRTX1200の最新ファームウェアである、&lt;code&gt;10.01.65&lt;/code&gt;は、L2TPの設定は全てWebインターフェイスから設定可能です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;負荷状態&lt;/h2&gt;
&lt;p&gt;1本1時間ぐらいセッションを張った状態。負荷は余裕ですね。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-27-at-14.11.39.png&quot; alt=&quot;RTX1200 status&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-27-at-14.11.48.png&quot; alt=&quot;RTX1200 status&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;アカウント関連の情報は&lt;code&gt;xxxxx&lt;/code&gt;でマスクしてあります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# RTX1200 Rev.10.01.65 (Tue Oct 13 12:23:48 2015)
# MAC Address : 00:a0:de:68:90:0c, 00:a0:de:68:90:0d, 00:a0:de:68:90:0e
# Memory 128Mbytes, 3LAN, 1BRI
# main:  RTX1200 ver=c0 serial=D2F004125 MAC-Address=00:a0:de:68:90:0c MAC-Address=00:a0:de:68:90:0d MAC-Address=00:a0:de:68:90:0e
# Reporting Date: Dec 27 04:23:25 2015
ip route default gateway pp 1 filter 500000
ip keepalive 1 icmp-echo 10 5 dhcp lan3
ip lan1 address 192.168.1.1/24
ip lan1 proxyarp on
ip lan1 secure filter in 100000 100001 100002 100003 100004 100005 100006 100007 100099
ip lan2 secure filter in 102003 102020 102021 102022 102023 102024 102025 102030 102032
ip lan2 secure filter out 102013 102020 102021 102022 102023 102024 102025 102026 102027 102099 dynamic 102080 102081 102082 102083 102084 102085 102098 102099
ip lan2 nat descriptor 299
description lan3 PRV/DHCP/226:
lan shutdown lan3
ip lan3 address dhcp
ip lan3 secure filter in 102003 102020 102021 102022 102023 102024 102025 102030 102032
ip lan3 secure filter out 102013 102020 102021 102022 102023 102024 102025 102026 102027 102099 dynamic 102080 102081 102082 102083 102084 102085 102098 102099
pp select 1
 description pp PRV/PPPoE/0:livedoor
 pp keepalive interval 30 retry-interval=30 count=12
 pp always-on on
 pppoe use lan2
 pppoe auto disconnect off
 pp auth accept pap chap
 pp auth myname l01085390001619@n01obb02.vbbnet.jp 9934fc3a
 ppp lcp mru on 1454
 ppp ipcp ipaddress on
 ppp ipcp msext on
 ppp ccp type none
 ip pp secure filter in 200003 200020 200021 200022 200023 200024 200025 200030 200032 1 2 3 4 5 6
 ip pp secure filter out 200013 200020 200021 200022 200023 200024 200025 200026 200027 200099 dynamic 200080 200081 200082 200083 200084 200085 200098 200099
 ip pp nat descriptor 1000
 pp enable 1
pp select anonymous
 pp name &quot;pptp server&quot;
 pp bind tunnel1
 pp auth request mschap-v2
 pp auth username xxxxx xxxxxxxx
 ppp ipcp ipaddress on
 ppp ipcp msext on
 ip pp remote address pool dhcp
 ip pp mtu 1258
 pp enable anonymous
tunnel select 1
 tunnel encapsulation l2tp
 ipsec tunnel 1
  ipsec sa policy 1 1 esp aes-cbc sha-hmac
  ipsec ike keepalive log 1 off
  ipsec ike keepalive use 1 off
  ipsec ike nat-traversal 1 on
  ipsec ike pre-shared-key 1 text xxxxxxxx
  ipsec ike remote address 1 any
 l2tp tunnel auth off
 l2tp tunnel disconnect time off
 l2tp keepalive use on
 ip tunnel tcp mss limit auto
 tunnel enable 1
ip filter 1 pass * 192.168.1.7 tcp * 22,www,https,domain
ip filter 2 pass * 192.168.1.7 udp * domain
ip filter 3 pass * 192.168.1.1 esp * *
ip filter 4 pass * 192.168.1.1 udp * 500
ip filter 5 pass * 192.168.1.1 udp * 4500
ip filter 6 pass * 192.168.1.1 udp * 1701
ip filter 100000 reject * * udp,tcp 135 *
ip filter 100001 reject * * udp,tcp * 135
ip filter 100002 reject * * udp,tcp netbios_ns-netbios_dgm *
ip filter 100003 reject * * udp,tcp * netbios_ns-netbios_dgm
ip filter 100004 reject * * udp,tcp netbios_ssn *
ip filter 100005 reject * * udp,tcp * netbios_ssn
ip filter 100006 reject * * udp,tcp 445 *
ip filter 100007 reject * * udp,tcp * 445
ip filter 100099 pass * * * * *
ip filter 102000 reject 10.0.0.0/8 * * * *
ip filter 102001 reject 172.16.0.0/12 * * * *
ip filter 102002 reject 192.168.0.0/16 * * * *
ip filter 102003 reject 192.168.1.0/24 * * * *
ip filter 102010 reject * 10.0.0.0/8 * * *
ip filter 102011 reject * 172.16.0.0/12 * * *
ip filter 102012 reject * 192.168.0.0/16 * * *
ip filter 102013 reject * 192.168.1.0/24 * * *
ip filter 102020 reject * * udp,tcp 135 *
ip filter 102021 reject * * udp,tcp * 135
ip filter 102022 reject * * udp,tcp netbios_ns-netbios_ssn *
ip filter 102023 reject * * udp,tcp * netbios_ns-netbios_ssn
ip filter 102024 reject * * udp,tcp 445 *
ip filter 102025 reject * * udp,tcp * 445
ip filter 102026 restrict * * tcpfin * www,21,nntp
ip filter 102027 restrict * * tcprst * www,21,nntp
ip filter 102030 pass * 192.168.1.0/24 icmp * *
ip filter 102031 pass * 192.168.1.0/24 established * *
ip filter 102032 pass * 192.168.1.0/24 tcp * ident
ip filter 102033 pass * 192.168.1.0/24 tcp ftpdata *
ip filter 102034 pass * 192.168.1.0/24 tcp,udp * domain
ip filter 102035 pass * 192.168.1.0/24 udp domain *
ip filter 102036 pass * 192.168.1.0/24 udp * ntp
ip filter 102037 pass * 192.168.1.0/24 udp ntp *
ip filter 102099 pass * * * * *
ip filter 103000 pass * * tcp * 8000
ip filter 200000 reject 10.0.0.0/8 * * * *
ip filter 200001 reject 172.16.0.0/12 * * * *
ip filter 200002 reject 192.168.0.0/16 * * * *
ip filter 200003 reject 192.168.1.0/24 * * * *
ip filter 200010 reject * 10.0.0.0/8 * * *
ip filter 200011 reject * 172.16.0.0/12 * * *
ip filter 200012 reject * 192.168.0.0/16 * * *
ip filter 200013 reject * 192.168.1.0/24 * * *
ip filter 200020 reject * * udp,tcp 135 *
ip filter 200021 reject * * udp,tcp * 135
ip filter 200022 reject * * udp,tcp netbios_ns-netbios_ssn *
ip filter 200023 reject * * udp,tcp * netbios_ns-netbios_ssn
ip filter 200024 reject * * udp,tcp 445 *
ip filter 200025 reject * * udp,tcp * 445
ip filter 200026 restrict * * tcpfin * www,21,nntp
ip filter 200027 restrict * * tcprst * www,21,nntp
ip filter 200030 pass * 192.168.1.0/24 icmp * *
ip filter 200031 pass * 192.168.1.0/24 established * *
ip filter 200032 pass * 192.168.1.0/24 tcp * ident
ip filter 200034 pass * 192.168.1.0/24 tcp,udp * domain
ip filter 200035 pass * 192.168.1.0/24 udp domain *
ip filter 200036 pass * 192.168.1.0/24 udp * ntp
ip filter 200037 pass * 192.168.1.0/24 udp ntp *
ip filter 200099 pass * * * * *
ip filter 500000 restrict * * * * *
ip filter dynamic 102080 * * ftp
ip filter dynamic 102081 * * domain
ip filter dynamic 102082 * * www
ip filter dynamic 102083 * * smtp
ip filter dynamic 102084 * * pop3
ip filter dynamic 102085 * * submission
ip filter dynamic 102098 * * tcp
ip filter dynamic 102099 * * udp
ip filter dynamic 200080 * * ftp
ip filter dynamic 200081 * * domain
ip filter dynamic 200082 * * www
ip filter dynamic 200083 * * smtp
ip filter dynamic 200084 * * pop3
ip filter dynamic 200085 * * submission
ip filter dynamic 200098 * * tcp
ip filter dynamic 200099 * * udp
nat descriptor type 1 masquerade
nat descriptor address outer 1 ipcp
nat descriptor address inner 1 auto
nat descriptor masquerade static 1 1 192.168.1.1 esp
nat descriptor masquerade static 1 2 192.168.1.1 udp 500
nat descriptor masquerade static 1 3 192.168.1.1 udp 4500
nat descriptor type 299 masquerade
nat descriptor address outer 299 primary
nat descriptor type 1000 masquerade
nat descriptor masquerade static 1000 1 192.168.1.7 tcp www
nat descriptor masquerade static 1000 2 192.168.1.7 udp domain
nat descriptor masquerade static 1000 3 192.168.1.7 tcp domain
nat descriptor masquerade static 1000 4 192.168.1.7 tcp 22
nat descriptor masquerade static 1000 5 192.168.1.7 tcp https
nat descriptor masquerade static 1000 6 192.168.1.1 esp
nat descriptor masquerade static 1000 7 192.168.1.1 udp 4500
nat descriptor masquerade static 1000 8 192.168.1.1 udp 500
ipsec auto refresh on
ipsec transport 1 1 udp 1701
syslog debug on
dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.1.100-192.168.1.254/24
dns server pp 1
dns server dhcp lan3
dns server select 500001 pp 1 any . restrict pp 1
dns server select 500227 dhcp lan3 any .
dns private address spoof on
snmp sysname yamaha-rtx1200-00a0de68900c
schedule at 1 */* 05:00:00 * ntpdate ntp.sfc.keio.ac.jp syslog
l2tp service on
httpd host lan1
statistics cpu on
statistics memory on
statistics traffic on
#
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;考察&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;VPNは、約1秒で接続完了します。超速いのでストレス無し！&lt;/li&gt;
&lt;li&gt;1アカウント、同時に1本しかコネクションを張れません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://tips4somebody.blogspot.jp/2014/01/iphone-rtx1200-vpn.html&quot;&gt;iPhone から ヤマハルーター（RTX1200）に VPN 接続する（１）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://jp.yamaha.com/products/network/solution/vpn/smartphone/vpn-smartphone-setup_fwx120/&quot;&gt;複数のL2TPクライアント(アドレス不定)の接続を受け付ける&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;など。あちらこちらから、必要な設定を寄せ集めて作りました。&lt;/p&gt;
</content:encoded></item><item><title>本当だった！PHP 5.5.30 から PHP 7.0.1 に上げて約2.4倍の高速化</title><link>https://blog.teraren.com/posts/php7-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php7-benchmark/</guid><description>WordPress環境でPHP5からPHP7へ移行した実測ベンチマーク。ApacheBenchによる計測でOpcache有効時に約2.4倍の高速化を確認。</description><pubDate>Sat, 26 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://codezine.jp/article/detail/9136&quot;&gt;PHP 7がPHP 5.6と比べて2倍速い&lt;/a&gt;みたいな発表があったので試してみました。&lt;/li&gt;
&lt;li&gt;このBlogはPHP7で動いています。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://php.net/ChangeLog-7.php&quot;&gt;Changelog&lt;/a&gt;を見る感じだと、まだまだ大きなバグが出ているので運用環境で使うのは時期早々かと思いますが、PHP5系からPHP7系にするだけで本当に2倍速くなります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;測定環境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Wordpres4.4とZenCacheの環境です。&lt;/li&gt;
&lt;li&gt;純粋に1プロセスの処理時間を計測するために並列数は1&lt;/li&gt;
&lt;li&gt;運用環境に近い環境で測定したかったのでZenCacheは有効にした状態で計測&lt;/li&gt;
&lt;li&gt;Mac OS X&lt;/li&gt;
&lt;li&gt;ページのテキスト量が多いのでgzip付きで。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;測定コマンド&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ab -n 1000 -c 1 -H &quot;Accept-Encoding: gzip,deflate&quot; https://blog.teraren.com/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;PHP 5.5 + APCU&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Requests per second:    101.03 [#/sec] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;PHP 7.0.1 + APCU&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;Requests per second:    116.01 [#/sec] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;PHP 7.0.1 + Opcache&lt;/h3&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-successive-word &lt;em&gt;/}
よくよく調べてみると、PHP7自体にOpcode cacheがあるので、そちらを使った方が良さそう。
{/&lt;/em&gt; textlint-enable */}
&lt;code&gt;ini&lt;/code&gt;ファイルでopcache関連を適当に有効化します。&lt;/p&gt;
&lt;p&gt;設定ファイルの差分&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Requests per second:    241.69 [#/sec] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ということで、手元の環境では、&lt;strong&gt;約2.4倍&lt;/strong&gt;速くなりました ！&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PHP5.5 + APCuと比較して、&lt;strong&gt;2.4倍速くなった！&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;ktai styleやone click updaterで、Deprecated warning出たので、プラグインを消して対応しました。&lt;/li&gt;
&lt;li&gt;apcu_store() などのAPCU関連がまだPHP7には対応していません。redisに置き換えて対応しました。
&lt;ul&gt;
&lt;li&gt;たぶん、APCuはPHP7では不要な感じなので、別のストレージにした方が良いと思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>爆速！nginxを1分でHTTP2対応</title><link>https://blog.teraren.com/posts/nginx-http2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nginx-http2/</guid><description>既存のSSL対応nginxにhttp2フラグとssl_ciphers設定を2行追加するだけでHTTP/2化できる最速セットアップ手順を解説</description><pubDate>Tue, 22 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/advent-calendar/2015/one-minute&quot;&gt;1分で実現できる有用な技術&lt;/a&gt;の12月22日分です&lt;/li&gt;
&lt;li&gt;前提として、HTTP2のパフォーマンスは&lt;a href=&quot;http://qiita.com/takapan/items/756be5b47134f9e51a11&quot;&gt;nginxでHTTP2接続(not spdy3.1)の検証&lt;/a&gt;などを参照していただければと思います。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tech.recruit-sumai.co.jp/%E3%83%86%E3%83%83%E3%82%AF%E3%83%96%E3%83%AD%E3%82%B0%E3%82%92http2php7wordpress%E3%81%A7%E6%A7%8B%E7%AF%89%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/&quot;&gt;テックブログをHTTP/2+PHP7+WordPressで構築してみた&lt;/a&gt; がFacebookのフィードに流れてきて、触発されました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;手順&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;手元の環境がMac OSで動いているサーバなので、Mac前提の設定です。&lt;/li&gt;
&lt;li&gt;こちらのサービスをHTTP2化してみます。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://teraren.com/&quot;&gt;https://teraren.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;NginxをHTTP2オプション付きでインストール（20秒）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% brew install nginx --devel --with-http2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;もともとSSLで動いているサイトの設定にhttp2の設定を2つ追加するだけです。（30秒）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;http2&lt;/code&gt;をlistenの部分に追加。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;AESGCM:HIGH&lt;/code&gt;をssl_ciphersの先頭に追加。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下に差分。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@@ -19,7 +19,7 @@ server {
 # HTTPS server
 server {
-    listen 443 ssl;
+    listen 443 ssl http2;
     server_name teraren.com;
     root /Users/matsu/Sites/teraren.com/www/public/;
     access_log /var/log/nginx/www.teraren.com main;
@@ -32,7 +32,7 @@ server {
     ssl_prefer_server_ciphers on;
     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
-    ssl_ciphers ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!aNULL!eNull:!EXPORT:!DES:!3DES:!MD5:!DSS;
+    ssl_ciphers AESGCM:HIGH:ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!aNULL!eNull:!EXPORT:!DES:!3DES:!MD5:!DSS;
     try_files $uri @unicorn;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;nginxを再起動（5秒）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo brew services restart nginx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/http2-and-spdy-indicator/mpbpobfflnpcgagjijhmgnchggcjblin?hl=ja&quot;&gt;この&lt;/a&gt;プラグインを入れたChromeで確認。（5秒）&lt;br /&gt;
青い稲妻が表示されていれば、HTTP2で接続出来ていると言うことです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-22-at-21.33.05.png&quot; alt=&quot;chrome http2 nginx&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1分でnginxをHTTP2対応しました。&lt;/li&gt;
&lt;li&gt;SSL証明書は&lt;a href=&quot;/posts/lets-encrypt-free-ssl-certificate/&quot;&gt;Let’s Encryptを使って簡単0円でサーバ証明書を取得&lt;/a&gt;を参考にして個人でも簡単に取得出来ます。&lt;/li&gt;
&lt;li&gt;やっとHTTP2が簡単に導入できる時代になってきました！&lt;/li&gt;
&lt;li&gt;簡単なので、ついでにこっちもHTTP2に対応しました。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://matsu.teraren.com/static/spike_checkout/&quot;&gt;https://matsu.teraren.com/static/spike_checkout/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>家庭用ルータを業務用のYAMAHA RTX1200に置き換えて快適生活！</title><link>https://blog.teraren.com/posts/rtx1200-deployment/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rtx1200-deployment/</guid><description>頻繁に再起動する家庭用WiFiルータをYAMAHA RTX1200に置き換え、PPPoE・静的NAT・VPNなどを設定し自宅ネットワークを安定化させた体験レポート</description><pubDate>Mon, 21 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-successive-word */}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ルータをBuffaloのWiFiルータからRTX1200に置き換えました。（定価 125,000円（税抜き））
{/* textlint-enable ja-technical-writing/ja-no-successive-word */}
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://amzn.to/3jEgZbm&quot;&gt;今は中古5,000円ぐらいで買えます&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;もともと、WiFiルーターは1，2ヶ月に1回、勝手に再起動して接続が切れるときがあります。今まで10台くらいいろいろなメーカーのルータを使ってきたけどどこも同じ。もう、家庭用ルーターには耐えられない！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;さすが、Gbps対応なので、ポテンシャルが高いですね。&lt;/li&gt;
&lt;li&gt;自分のOUTのグローバルIPのルーティングもしてくれるから楽。
&lt;ul&gt;
&lt;li&gt;同じLAN内で、外向きのDNSサーバを運用していると、Buffaloのルータがルーティングしてくれなくて、不便でした。（＝LANから自分の外側のグローバルIPアドレスのルーティングが行われない）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B001G79VGK&quot;}&lt;/p&gt;
&lt;h2&gt;状態&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PPPoEの設定、自宅サーバを公開するための静的NATの設定をしただけです。&lt;/li&gt;
&lt;li&gt;まだまだ余裕な感じです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-21-at-01.06.43.png&quot; alt=&quot;RTX1200 Stats&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-21-at-01.07.01.png&quot; alt=&quot;RTX1200 Stats&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;設置した状態&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;玄関にある、ねじドメされている分電盤に放り込んでます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/image.jpeg&quot; alt=&quot;Rtx1200&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/image-3.jpeg&quot; alt=&quot;image&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;RTX1200の設定&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;今のところの設定内容は以下のようになってます。&lt;/li&gt;
&lt;li&gt;秘密の情報は&lt;code&gt;xxxxx&lt;/code&gt;でマスクしてあります。&lt;/li&gt;
&lt;li&gt;ポート開放（静的NAT）は、フィルタの解放と連動していないので、手動でやる必要があります。
&lt;ul&gt;
&lt;li&gt;たまに、静的NATだけの説明しか書いていない場合がありますが。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# RTX1200 Rev.10.01.65 (Tue Oct 13 12:23:48 2015)
# MAC Address : 00:a0:de:68:90:0c, 00:a0:de:68:90:0d, 00:a0:de:68:90:0e
# Memory 128Mbytes, 3LAN, 1BRI
# main:  RTX1200 ver=c0 serial=D2F004125 MAC-Address=00:a0:de:68:90:0c MAC-Address=00:a0:de:68:90:0d MAC-Address=00:a0:de:68:90:0e
# Reporting Date: Dec 21 01:04:29 2015
ip route default gateway pp 1 filter 500000 gateway dhcp lan3
ip keepalive 1 icmp-echo 10 5 dhcp lan3
ip lan1 address 192.168.1.1/24
ip lan1 secure filter in 100000 100001 100002 100003 100004 100005 100006 100007 100099
ip lan2 secure filter in 102003 102020 102021 102022 102023 102024 102025 102030 102032
ip lan2 secure filter out 102013 102020 102021 102022 102023 102024 102025 102026 102027 102099 dynamic 102080 102081 102082 102083 102084 102085 102098 102099
ip lan2 nat descriptor 299
description lan3 PRV/DHCP/226:
lan shutdown lan3
ip lan3 address dhcp
ip lan3 secure filter in 102003 102020 102021 102022 102023 102024 102025 102030 102032
ip lan3 secure filter out 102013 102020 102021 102022 102023 102024 102025 102026 102027 102099 dynamic 102080 102081 102082 102083 102084 102085 102098 102099
ip lan3 nat descriptor 300
pp select 1
 description pp PRV/PPPoE/0:livedoor
 pp keepalive interval 30 retry-interval=30 count=12
 pp always-on on
 pppoe use lan2
 pppoe auto disconnect off
 pp auth accept pap chap
 pp auth myname xxxxxxxxxxxxxxxxxxxxx 9934fc3a
 ppp lcp mru on 1454
 ppp ipcp ipaddress on
 ppp ipcp msext on
 ppp ccp type none
 ip pp secure filter in 200003 200020 200021 200022 200023 200024 200025 200030 200032 1 2
 ip pp secure filter out 200013 200020 200021 200022 200023 200024 200025 200026 200027 200099 dynamic 200080 200081 200082 200083 200084 200085 200098 200099
 ip pp nat descriptor 1000
 pp enable 1
pp select anonymous
 pp name &quot;pptp server&quot;
 pp bind tunnel1
 pp auth request mschap-v2
 pp auth username xxxxxxx xxxxxxxx
 ppp ipcp ipaddress on
 ppp ipcp msext on
 ip pp remote address pool dhcp
 ip pp mtu 1258
 pp enable anonymous
tunnel select 1
 tunnel encapsulation l2tp
 ipsec tunnel 1
  ipsec sa policy 1 1 esp aes-cbc sha-hmac
  ipsec ike keepalive log 1 off
  ipsec ike keepalive use 1 off
  ipsec ike nat-traversal 1 on
  ipsec ike pre-shared-key 1 text xxxxxxxx
  ipsec ike remote address 1 any
 l2tp tunnel auth off
 l2tp tunnel disconnect time 600
 l2tp keepalive use on
 ip tunnel tcp mss limit auto
 tunnel enable 1
ip filter 1 pass * 192.168.1.7 tcp * 22,www,https,domain
ip filter 2 pass * 192.168.1.7 udp * domain
ip filter 100000 reject * * udp,tcp 135 *
ip filter 100001 reject * * udp,tcp * 135
ip filter 100002 reject * * udp,tcp netbios_ns-netbios_dgm *
ip filter 100003 reject * * udp,tcp * netbios_ns-netbios_dgm
ip filter 100004 reject * * udp,tcp netbios_ssn *
ip filter 100005 reject * * udp,tcp * netbios_ssn
ip filter 100006 reject * * udp,tcp 445 *
ip filter 100007 reject * * udp,tcp * 445
ip filter 100099 pass * * * * *
ip filter 102000 reject 10.0.0.0/8 * * * *
ip filter 102001 reject 172.16.0.0/12 * * * *
ip filter 102002 reject 192.168.0.0/16 * * * *
ip filter 102003 reject 192.168.1.0/24 * * * *
ip filter 102010 reject * 10.0.0.0/8 * * *
ip filter 102011 reject * 172.16.0.0/12 * * *
ip filter 102012 reject * 192.168.0.0/16 * * *
ip filter 102013 reject * 192.168.1.0/24 * * *
ip filter 102020 reject * * udp,tcp 135 *
ip filter 102021 reject * * udp,tcp * 135
ip filter 102022 reject * * udp,tcp netbios_ns-netbios_ssn *
ip filter 102023 reject * * udp,tcp * netbios_ns-netbios_ssn
ip filter 102024 reject * * udp,tcp 445 *
ip filter 102025 reject * * udp,tcp * 445
ip filter 102026 restrict * * tcpfin * www,21,nntp
ip filter 102027 restrict * * tcprst * www,21,nntp
ip filter 102030 pass * 192.168.1.0/24 icmp * *
ip filter 102031 pass * 192.168.1.0/24 established * *
ip filter 102032 pass * 192.168.1.0/24 tcp * ident
ip filter 102033 pass * 192.168.1.0/24 tcp ftpdata *
ip filter 102034 pass * 192.168.1.0/24 tcp,udp * domain
ip filter 102035 pass * 192.168.1.0/24 udp domain *
ip filter 102036 pass * 192.168.1.0/24 udp * ntp
ip filter 102037 pass * 192.168.1.0/24 udp ntp *
ip filter 102099 pass * * * * *
ip filter 103000 pass * * tcp * 8000
ip filter 200000 reject 10.0.0.0/8 * * * *
ip filter 200001 reject 172.16.0.0/12 * * * *
ip filter 200002 reject 192.168.0.0/16 * * * *
ip filter 200003 reject 192.168.1.0/24 * * * *
ip filter 200010 reject * 10.0.0.0/8 * * *
ip filter 200011 reject * 172.16.0.0/12 * * *
ip filter 200012 reject * 192.168.0.0/16 * * *
ip filter 200013 reject * 192.168.1.0/24 * * *
ip filter 200020 reject * * udp,tcp 135 *
ip filter 200021 reject * * udp,tcp * 135
ip filter 200022 reject * * udp,tcp netbios_ns-netbios_ssn *
ip filter 200023 reject * * udp,tcp * netbios_ns-netbios_ssn
ip filter 200024 reject * * udp,tcp 445 *
ip filter 200025 reject * * udp,tcp * 445
ip filter 200026 restrict * * tcpfin * www,21,nntp
ip filter 200027 restrict * * tcprst * www,21,nntp
ip filter 200030 pass * 192.168.1.0/24 icmp * *
ip filter 200031 pass * 192.168.1.0/24 established * *
ip filter 200032 pass * 192.168.1.0/24 tcp * ident
ip filter 200034 pass * 192.168.1.0/24 tcp,udp * domain
ip filter 200035 pass * 192.168.1.0/24 udp domain *
ip filter 200036 pass * 192.168.1.0/24 udp * ntp
ip filter 200037 pass * 192.168.1.0/24 udp ntp *
ip filter 200099 pass * * * * *
ip filter 500000 restrict * * * * *
ip filter dynamic 102080 * * ftp
ip filter dynamic 102081 * * domain
ip filter dynamic 102082 * * www
ip filter dynamic 102083 * * smtp
ip filter dynamic 102084 * * pop3
ip filter dynamic 102085 * * submission
ip filter dynamic 102098 * * tcp
ip filter dynamic 102099 * * udp
ip filter dynamic 200080 * * ftp
ip filter dynamic 200081 * * domain
ip filter dynamic 200082 * * www
ip filter dynamic 200083 * * smtp
ip filter dynamic 200084 * * pop3
ip filter dynamic 200085 * * submission
ip filter dynamic 200098 * * tcp
ip filter dynamic 200099 * * udp
nat descriptor type 299 masquerade
nat descriptor address outer 299 primary
nat descriptor masquerade static 299 1 192.168.1.7 tcp 22
nat descriptor masquerade static 299 2 192.168.1.7 tcp https
nat descriptor masquerade static 299 3 192.168.1.7 tcp domain
nat descriptor masquerade static 299 4 192.168.1.7 udp domain
nat descriptor masquerade static 299 5 192.168.1.7 tcp www
nat descriptor type 300 masquerade
nat descriptor address outer 300 primary
nat descriptor type 1000 masquerade
nat descriptor masquerade static 1000 1 192.168.1.7 tcp www
nat descriptor masquerade static 1000 2 192.168.1.7 udp domain
nat descriptor masquerade static 1000 3 192.168.1.7 tcp domain
nat descriptor masquerade static 1000 4 192.168.1.7 tcp 22
nat descriptor masquerade static 1000 5 192.168.1.7 tcp https
ipsec transport 1 1 udp 1701
syslog debug on
dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.1.100-192.168.1.254/24
dns server pp 1
dns server dhcp lan3
dns server select 500001 pp 1 any . restrict pp 1
dns server select 500227 dhcp lan3 any .
dns private address spoof on
snmp sysname yamaha-rtx1200-00a0de68900c
schedule at 1 */* 05:00:00 * ntpdate ntp.sfc.keio.ac.jp syslog
httpd host lan1
statistics cpu on
statistics memory on
statistics traffic on
#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;HULU見た感じ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-28-at-23.39.12.png&quot; alt=&quot;RTX1200 status&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;スピードテストの結果です。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.musen-lan.com/speed/&quot;&gt;http://www.musen-lan.com/speed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;フレッツマンション100Mbpsなので、そこそこ。&lt;/li&gt;
&lt;li&gt;ISPはVectant。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Beforeを取り忘れたから何とも言えないのですが。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;------ BNRスピードテスト (ダウンロード速度) ------
測定サイト： http://www.musen-lan.com/speed/ Ver5.6001
測定日時： 2015/12/21 00:53:26
回線/ISP/地域：
--------------------------------------------------
1.NTTPC(WebARENA)1： 97.20Mbps (12.15MB/sec)
2.NTTPC(WebARENA)2： 98.65Mbps (12.33MB/sec)
推定転送速度： 98.65Mbps (12.33MB/sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;今後&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;拠点間VPN&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/0sim-rtx1200/&quot;&gt;メイン回線が落ちたときの予備回線（SoracomのSIMをUSBで使う）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/rtx1200-l2tp/&quot;&gt;MacなどからL2TPログイン&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;自宅の部屋間の埋設してあるLANがCAT5っぽくて、オートネゴシエーションが100-fdxとして認識されてしまうこと。
&lt;ul&gt;
&lt;li&gt;無理矢理1000-fdxにしたら、接続出来なくなった。。。 → 壁からスイッチまでのケーブルがCAT5だったので、CAT6にしたら、1000-fdxになった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2016-08-26-at-10.52.11.png&quot; alt=&quot;Screen Shot 2016-08-26 at 10.52.11&quot; /&gt;&lt;/p&gt;
&lt;p&gt;現時点で246日連続稼働中。とても安定している。&lt;/p&gt;
&lt;h2&gt;後継機&lt;/h2&gt;
&lt;p&gt;RTX1200はすでに販売停止されているので後継機を買うのが良いです。同程度の性能ならば RTX830あたりで良いかと思います。RTX&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B075YVK9QF&quot;}&lt;/p&gt;
&lt;p&gt;サポートや保証が不要であればRTX1210の中古も狙い目かと思います。絶対的な金額は安くはありませんが、コスパは良いです。しかし、故障したときが困ります。。。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00NF2GN6U&quot;}&lt;/p&gt;
</content:encoded></item><item><title>決済代行会社を選ぶときのKPIベスト10</title><link>https://blog.teraren.com/posts/payment-gateway-kpi-best-10/</link><guid isPermaLink="true">https://blog.teraren.com/posts/payment-gateway-kpi-best-10/</guid><description>手数料・API提供・セキュリティ・サポートなど決済代行会社を選定する際に確認すべき10項目のKPIをエンジニア兼事業者の視点で解説</description><pubDate>Wed, 16 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/advent-calendar/2015/payment&quot;&gt;Payment Advent Calendar 2015&lt;/a&gt; 12月12日分です。&lt;/li&gt;
&lt;li&gt;決済代行会社は世の中にたくさんあります。&lt;/li&gt;
&lt;li&gt;業者選定時に見落とさないようにするためにもKPIをまとめておきます。&lt;/li&gt;
&lt;li&gt;決済会社選定の際はこれらのKPIをマトリックスにして評価するのが良いと思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;KPIベスト10&lt;/h2&gt;
&lt;h3&gt;第1位：経済条件&lt;/h3&gt;
&lt;p&gt;が一番重要ですね。決済サービスの乗り換えはとても困難です。お互い持ちつ持たれつなので、長期的に良い関係を築けるところとおつきあいしましょう。&lt;br /&gt;
利用ブランドによっても金額が変わってきます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;決済手数料&lt;/li&gt;
&lt;li&gt;トランザクション手数料&lt;/li&gt;
&lt;li&gt;初期費用&lt;/li&gt;
&lt;li&gt;月額費用&lt;/li&gt;
&lt;li&gt;入金サイクル&lt;/li&gt;
&lt;li&gt;チャージバック手数料&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;第2位：API提供の可否&lt;/h3&gt;
&lt;p&gt;自社サービスの特性に合わせて選びましょう。&lt;/p&gt;
&lt;p&gt;大きく分けて以下の3種類があります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100％全部マーチャント側でユーザからの決済をproxy
&lt;ul&gt;
&lt;li&gt;SPIKE, Stripe, Webpay, PayPalなど&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;クレジットカード番号を扱う部分だけはゲートウェイでやり、その他はAPIで行う
&lt;ul&gt;
&lt;li&gt;SPIKE, Stripe, Webpayなど&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;全てゲートウェイ側に投げるか
&lt;ul&gt;
&lt;li&gt;PayPalなど&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;第3位：システムの安定性&lt;/h3&gt;
&lt;p&gt;どの程度安定しているのか、既に導入しているマーチャントに聞くのが良いです。また、障害報を見てみたりするのも良いですが、運用がずさんな所では、障害報を出しません。&lt;/p&gt;
&lt;p&gt;また、SLAが用意されているかも確認しておきたい所です。&lt;/p&gt;
&lt;p&gt;サービスインしたら、New Relicなどを使って決済ゲートウェイのエンドポイントをしっかり監視しておきましょう。&lt;/p&gt;
&lt;p&gt;決済が止まるとたたき起こされるのはエンジニアです。。。&lt;/p&gt;
&lt;h3&gt;第4位：リカーリング（継続課金）の可否&lt;/h3&gt;
&lt;p&gt;継続課金を独自で実装するのはかなり大変なので、継続課金をするならば、継続課金機能を利用するのが吉です。&lt;/p&gt;
&lt;p&gt;Stripeの&lt;a href=&quot;https://stripe.com/docs/subscriptions&quot;&gt;Subscription&lt;/a&gt;を見てもわかるとおり、継続課金のパラメータは膨大です。&lt;br /&gt;
自社のビジネスロジックに応じたパラメータがあるかを確認しておきましょう。&lt;/p&gt;
&lt;h3&gt;第5位：ちゃんとしたテスト環境の有無&lt;/h3&gt;
&lt;p&gt;ずさんなテスト環境を提供してくるところがあったりします。&lt;/p&gt;
&lt;p&gt;要点としては、以下を確認します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;テスト用のマーチャントIDや、カード番号をちゃんと発行しているか？&lt;/li&gt;
&lt;li&gt;24時間利用可能か？&lt;/li&gt;
&lt;li&gt;本番と挙動は全く同じか？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Stripeのようなすばらしい環境が用意されているとは限りません。&lt;br /&gt;
テスト環境が満足に提供されていない代行会社も多いです。&lt;/p&gt;
&lt;h3&gt;第6位：APIライブラリの有無&lt;/h3&gt;
&lt;p&gt;使う言語のライブラリがあるのと無いのでは、実装工数が1週間程度変わってきます。&lt;/p&gt;
&lt;h3&gt;第7位：トークン決済（リファレンストランザクション）の可否&lt;/h3&gt;
&lt;p&gt;マーチャント側でクレジットカード番号を保存しないためには、決済ゲートウェイ側でカード番号をトークン化し、マーチャントはそのトークンを使って決済操作を行うようにします。&lt;/p&gt;
&lt;h3&gt;第8位：管理画面のアクセスのしやすさ、欲しいレポートが出力されるか&lt;/h3&gt;
&lt;p&gt;たまに、SFTPなどで取りに行かないと行けないゲートウェイなどがあります。&lt;/p&gt;
&lt;h3&gt;第9位: 決済ステータスのアクティビティ&lt;/h3&gt;
&lt;p&gt;決済ステータスは普通、5種類ぐらい存在します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;仮売上&lt;/li&gt;
&lt;li&gt;実売上&lt;/li&gt;
&lt;li&gt;仮売上キャンセル&lt;/li&gt;
&lt;li&gt;実売上キャンセル&lt;/li&gt;
&lt;li&gt;チャージバック&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;たまに、ステータスが10個ぐらい存在し、時間経過によって勝手にステータスが変わったりする決済ゲートウェイがあり、そのステータスに応じて呼び出すAPIや操作出来る内容が変わったりする場合があります。&lt;/p&gt;
&lt;p&gt;決済ステータスの一覧や、アクティビティ図（状態遷移図）を事前に確認しておきましょう。&lt;/p&gt;
&lt;h3&gt;第10位：APIのタイムアウト秒数&lt;/h3&gt;
&lt;p&gt;呼び出し側が最大何秒待たなければいけないかを決めるために必要になります。&lt;/p&gt;
&lt;p&gt;決済ゲートウェイのタイムアウトより先に、呼び出し側がタイムアウトと判断してしまうと、呼び出し元では失敗と判断しているが、決済ゲートウェイでは成功と判断してしまう状態に陥ってしまいます。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://shinjukurb.doorkeeper.jp/events/34473&quot;&gt;Shinjuku.rb #31&lt;/a&gt;で発表した資料を補足資料として貼り付けてあります。
&lt;ul&gt;
&lt;li&gt;今まで出くわした、決済ゲートウェイの落とし穴や、常識を越えた仕様などが書いてあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;https://www.slideshare.net/matsubokkuri/payment-service-overview-and-payment-gateways&lt;/p&gt;
</content:encoded></item><item><title>並列に、再帰的に、EXIF情報を消すコマンド</title><link>https://blog.teraren.com/posts/mogrify-imagemagick-recursive/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mogrify-imagemagick-recursive/</guid><description>並列に、再帰的に、EXIF情報を消すコマンド</description><pubDate>Tue, 15 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ImageMagickのmogrifyコマンドをつかいます。mogrifyコマンドは、元のファイルを変更して上書き保存します。&lt;/p&gt;
&lt;p&gt;たとえば、カレントディレクトリ以下のjpgファイルから、EXIF情報を消す。&lt;br /&gt;
しかも、4並列で行う場合。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% find . | grep &quot;.jpe\?g$&quot; | xargs -t -n 10 -P 4 mogrify -strip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;core i7の8コアで処理した場合は、CPUがこんな感じで使われます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-20.47.54.png&quot; alt=&quot;htop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;クイックにやるなら、以下の方法でも可能。&lt;/p&gt;
&lt;p&gt;zshの場合。1プロセス。ファイル制限あり。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% mogrify -strip **/*.jpg
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>15分でNew Relicを用いてMac OS Xを監視する設定</title><link>https://blog.teraren.com/posts/newrelic-on-mac-os-x/</link><guid isPermaLink="true">https://blog.teraren.com/posts/newrelic-on-mac-os-x/</guid><description>公式非対応のMac OS XにnewRelic-unix-pluginを導入し、CPU・メモリ・ネットワークをNew Relicで監視する設定手順</description><pubDate>Tue, 15 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/advent-calendar/2015/newrelic&quot;&gt;New Relic Advent Calendar 2015&lt;/a&gt;の12月11日分です。&lt;/li&gt;
&lt;li&gt;NewRelicで、Mac OS Xのリソースモニタリングを行います。&lt;/li&gt;
&lt;li&gt;公式には対応していないので、サードパーティが公開しているプラグイン、&lt;a href=&quot;https://github.com/sschwartzman/newrelic-unix-plugin&quot;&gt;newrelic-unix-plugin&lt;/a&gt;を利用します。&lt;/li&gt;
&lt;li&gt;このblogはMac OS X 10.10で動いています。(10.11にはまだ怖いので上げられない)
&lt;ul&gt;
&lt;li&gt;世にも珍しい普通のMac OS X（Serverではない）が当時フルスペックのMac Miniで動いています。&lt;/li&gt;
&lt;li&gt;場所を取らなくて良いですが、月に何回かハングアップします。。。。&lt;/li&gt;
&lt;li&gt;Mac OSのマイナーバージョンアップの度に、とても大変なアップグレード作業があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;セットアップ&lt;/h2&gt;
&lt;p&gt;一応注意：動作要件として、javaが必要になります。&lt;/p&gt;
&lt;p&gt;適当なディレクトリで、最新のファイルをダウンロードして展開します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget https://github.com/sschwartzman/newrelic-unix-plugin/blob/master/dist/newrelic_unix_plugin.tar.gz?raw=true
% tar xf newrelic_unix_plugin.tar.gz
% cd newrelic_unix_plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;config/newrelic.json&lt;/code&gt;ファイルを開いて、ライセンスキーを上書き保存します。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pluginctl.sh&lt;/code&gt;ファイルを開いて、上の方にある設定を必要に応じて変更します。&lt;/p&gt;
&lt;p&gt;デフォルトのインストール先ディレクトリが、&lt;br /&gt;
&lt;code&gt;/opt/newrelic/newrelic_unix_plugin&lt;/code&gt;推奨しているようなので、ディレクトリごと移動します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cd ..
% sudo mv newrelic_unix_plugin /opt/newrelic/newrelic_unix_plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;rootで起動します。&lt;/p&gt;
&lt;p&gt;1分後ぐらいに、newrelicで見られるようになります。&lt;br /&gt;
一応、起動直後は&lt;code&gt;log&lt;/code&gt;ディレクトリにあるファイルにエラーが無いかを確認します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ./pluginctl.sh start
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;スクリーンショット&lt;/h2&gt;
&lt;h3&gt;Overview&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-21.51.23.png&quot; alt=&quot;new relic overview&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;CPU&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-21.51.31.png&quot; alt=&quot;new relic CPU&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Disks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ちゃんとデータが取得出来ていない。桁数も違う。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-21.51.39.png&quot; alt=&quot;new relic Disk&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Memory&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-21.51.46.png&quot; alt=&quot;new relic  memory&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Network&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-21.51.53.png&quot; alt=&quot;new relic network&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;Processes&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-21.52.07.png&quot; alt=&quot;new relic  processes&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;VM Totals&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-21.52.27.png&quot; alt=&quot;new relic  vm totals&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;余談&lt;/h3&gt;
&lt;p&gt;ちょっとスタートアップスクリプトにエラーがあったので、PR送りました。→mergeされました&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pull-Request
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sschwartzman/newrelic-unix-plugin/pull/8&quot;&gt;https://github.com/sschwartzman/newrelic-unix-plugin/pull/8&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;まとめ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;UNIX用プラグインを使って、Mac OS XをNewrelicで監視しました。&lt;/li&gt;
&lt;li&gt;設定ファイルや、インストーラがない点、Javaで動いている点など、色々突っ込みどころはありますが、温かい目で見守っていきましょう。&lt;/li&gt;
&lt;li&gt;スタートアップスクリプト書かないと。。。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>SPIKE REST APIのWebhookを受信してみる</title><link>https://blog.teraren.com/posts/spike-rest-api-webhook/</link><guid isPermaLink="true">https://blog.teraren.com/posts/spike-rest-api-webhook/</guid><description>SPIKE決済サービスのWebhookエンドポイントをPHPで実装する方法。チャージバックや強制キャンセル時の通知受信、秘密鍵によるリクエスト検証手順をシーケンス図付きで解説。</description><pubDate>Tue, 15 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/advent-calendar/2015/payment&quot;&gt;Payment Advent Calendar&lt;/a&gt; 12月10日分&lt;/li&gt;
&lt;li&gt;Webhookにて、サーバサイドで決済情報に変更があった場合の通知を受け取ってみます。&lt;/li&gt;
&lt;li&gt;Webhookの利用頻度は少ないのですが、決済ゲートウェイ側でチャージバックや、やむを得ないキャンセルが行われた場合、マーチャントで保持している決済情報を同期を取るために重要になります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Webhook受信プログラムを書きます&lt;/li&gt;
&lt;li&gt;Webhookで受信したデータを表示します。&lt;/li&gt;
&lt;li&gt;Webhookのシーケンスはこんな感じになります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/img_5670c0fecf7c5.png&quot; alt=&quot;webhook seequence diagram&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;デモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;デモページ
&lt;ul&gt;
&lt;li&gt;HTTP &lt;a href=&quot;https://matsu.teraren.com/spike-api-demo-php/webhook/&quot;&gt;https://matsu.teraren.com/spike-api-demo-php/webhook/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;HTTPS &lt;a href=&quot;https://matsu.teraren.com/spike-api-demo-php/webhook/&quot;&gt;https://matsu.teraren.com/spike-api-demo-php/webhook/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;github
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/spike-api-demo-php&quot;&gt;ソースコード&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1ページ目&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;説明とともに、前回受信したWebhookの内容が表示されています。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-23.35.38.png&quot; alt=&quot;spike webhook&quot; /&gt;&lt;/p&gt;
&lt;p&gt;エンドポイントのURLを&lt;a href=&quot;https://spike.cc/dashboard/developer/webhook/urls&quot;&gt;SPIKEのWebhook管理ページ&lt;/a&gt;上で登録します。&lt;/p&gt;
&lt;p&gt;今回のでもプログラムの場合のエンドポイントURLはこちらになります：&lt;br /&gt;
&lt;code&gt;https://matsu.teraren.com/spike-api-demo-php/webhook/endpoint.php&lt;/code&gt;&lt;br /&gt;
または&lt;br /&gt;
&lt;code&gt;https://matsu.teraren.com/spike-api-demo-php/webhook/endpoint.php&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-23.52.34.png&quot; alt=&quot;SPIKE webhook管理ページ&quot; /&gt;&lt;/p&gt;
&lt;p&gt;登録したら、テストのためにPINGを送ってみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/1529c12ca39a2e12df79764e00b7cfa2.png&quot; alt=&quot;webhook ping&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下のように、表示されたないようが変われば、正常にデータを受信できています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-23.37.38.png&quot; alt=&quot;spike webhook&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Webhookで送られてくるデータは、送信元を保障するために、秘密鍵を利用したチェックサムなどを含んでいます。&lt;br /&gt;
ちょっと面倒ですが、サンプルプログラムのように送信元の検証をしっかりしましょう。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SPIKE側の決済情報の変更を検知するためにwebhookのエンドポイントを作りました。&lt;/li&gt;
&lt;li&gt;一通りSPIKEのデモページをまとめました
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://matsu.teraren.com/spike-api-demo-php/&quot;&gt;https://matsu.teraren.com/spike-api-demo-php/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>進化したSPIKEで、10分でECを始める方法</title><link>https://blog.teraren.com/posts/spike-shop/</link><guid isPermaLink="true">https://blog.teraren.com/posts/spike-shop/</guid><description>決済手数料無料のSPIKEを使って個人・小規模事業者がECショップを最短10分で開設する手順とコスト感を紹介</description><pubDate>Tue, 15 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;決済手数料無料というキャッチコピーでスタートした&lt;a href=&quot;https://spike.cc/&quot;&gt;SPIKE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;機能が徐々に増えていき、ECサイトとして使えるようになってきています。&lt;/li&gt;
&lt;li&gt;主な機能
&lt;ul&gt;
&lt;li&gt;クレジットカード決済&lt;/li&gt;
&lt;li&gt;コンビニ決済（NEW）&lt;/li&gt;
&lt;li&gt;ストア機能&lt;/li&gt;
&lt;li&gt;任意の実売り上げタイミング設定が可能&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://spike.cc/market/&quot;&gt;SPIKE Market&lt;/a&gt;（SPIKEが主体となっているEC）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;誰にお勧めか？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;個人、小規模事業者&lt;/li&gt;
&lt;li&gt;ヤフオクやメルカリといったプラットフォームに出品しないで、自分で販売チャネルを持っている人や、ソーシャルメディアで自分でマーケティング出来る方。&lt;/li&gt;
&lt;li&gt;初期コストを無くして、商品を販売し、スモールスタートしたい人&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;かかる費用&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;決済手数料とトランザクション手数料は無料。&lt;/li&gt;
&lt;li&gt;出金に手数料がかかります。
&lt;ul&gt;
&lt;li&gt;出金手数料：540円（税込み）&lt;/li&gt;
&lt;li&gt;しかしながら、SPIKE上に貯めた売り上げ金額を使って、&lt;a href=&quot;https://spike.cc/market/&quot;&gt;SPIKE Market&lt;/a&gt;で買い物をすれば出金手数料なしに売上金を使うことが出来ます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;売り上げが月に100万円を超える場合は、決済手数料に手数料がかかります。&lt;/li&gt;
&lt;li&gt;料金の詳細はこちら。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://spike.cc/business/payments/price&quot;&gt;https://spike.cc/business/payments/price&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-09.10.58.png&quot; alt=&quot;SPIKE Pricing&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;ショップを作ってみる&lt;/h2&gt;
&lt;p&gt;ゴールは、こんな感じのショップを作ることです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/img_566f582718e0a.png&quot; alt=&quot;SPIKE shop&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;アカウント登録&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://spike.cc/users/sign_up&quot;&gt;アカウント作成&lt;/a&gt;ページから、Facebookログインか、メアドとパスワードを入力します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-15-at-09.14.29.png&quot; alt=&quot;spike signup&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/46c5fb0ff40463b52bb8e05d8749b927-1.png&quot; alt=&quot;spike dashboard&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://spike.cc/dashboard/products/new&quot;&gt;商品作成&lt;/a&gt;ページから商品を登録します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/c5139a53cc60ab5d2646ce1da9c2ca89-1.png&quot; alt=&quot;SPIKE register product&quot; /&gt;&lt;/p&gt;
&lt;p&gt;商品の例&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://spike.cc/dashboard/shop/settings/edit&quot;&gt;ショップ管理&lt;/a&gt;へ行き、ショップ自体を設定します。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;送料設定、コンビニ決済の設定、ショップ名、カバー画像などの項目があるので、一通り入力します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/085e47014dd87d2ca381792a23672d9f-2.png&quot; alt=&quot;spike shop management&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://spike.cc/dashboard/account/sellers/edit&quot;&gt;販売者情報&lt;/a&gt;ページにある、売上処理設定を確認しておきます。おそらく、普通のECモールには無いような細かい売り上げ計上設定が可能です。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SPIKEでは、仮売り上げ、実売り上げ処理を行えるようになっていて、注文が実売り上げになると売り手の口座に入金されます。デフォルトですと、注文の4日後に自動的に実売り上げになります。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;販売する商品の特性に合わせて設定してください。&lt;/li&gt;
&lt;li&gt;受注と同時に実売り上げになる設定も行えます。&lt;/li&gt;
&lt;li&gt;実売り上げをキャンセルする場合は、270円（税込み）かかるのでご注意を。仮売り上げのキャンセルは無料です。詳細は&lt;a href=&quot;https://spike.cc/dashboard/account/refund_charges&quot;&gt;課金の取り消し可能期間と手数料について&lt;/a&gt;に載っています。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/656da20644dd38bb3ce6b871784e53b6-1.png&quot; alt=&quot;spike seller property&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/ba915008514cffe8213c2c6da2bded53-1.png&quot; alt=&quot;spike.cc see shop&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上記の設定が一通り終わりましたら、右上のメニューから自分のショップを見てみます。&lt;/p&gt;
&lt;p&gt;これで完了です。&lt;/p&gt;
&lt;h2&gt;SPIKE REST API&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;APIのテスト（サンドボックス環境）は&lt;a href=&quot;https://spike.cc/dashboard/developer/analytics&quot;&gt;開発ダッシュボード&lt;/a&gt;をクリックすると飛べて、すぐに利用することが出来ます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/28fb153c218835d423384807fedbe1cf-1.png&quot; alt=&quot;SPIKE api&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SPIKEでショップを作る最短手順を記載しました&lt;/li&gt;
&lt;li&gt;SPIKEのREST APIを利用するためにはビジネスプレミアへ申し込む必要があります。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>UPS(無停電電源装置)をMac miniで設定</title><link>https://blog.teraren.com/posts/ups-mac-mini-apc-rs-400/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ups-mac-mini-apc-rs-400/</guid><description>計画停電に備えてAPC RS 400をMac miniと自宅サーバに接続。ドライバ不要でmacOSの省電力設定から管理でき、バッテリーは6時間半以上持続することを確認。</description><pubDate>Tue, 15 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;マンションに携帯電話の基地局のアンテナを設置する工事をするらしく、1時間の計画停電があります。&lt;/li&gt;
&lt;li&gt;アンテナの施工会社に自宅サーバを運用している事を相談したら、UPSを貸してもらえることになりました。&lt;/li&gt;
&lt;li&gt;せっかくなので、記録しておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;製品&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;APC RS 400 [BR400G-JP]&lt;/li&gt;
&lt;li&gt;12,000円。安い。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B01N30S30G&quot;}&lt;/p&gt;
&lt;h2&gt;テスト&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ちゃんと動くかテストします。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Macbook Pro&lt;/strong&gt;に繋げて、商用電源を切ったりして、停電時の挙動を確認します。&lt;/li&gt;
&lt;li&gt;なんと、65Wとか食ってます。ノートPC恐るべし。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/IMG_2806-3.jpg&quot; alt=&quot;IMG_2806&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;設置&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Mac miniとHDD4台が入ったRaidボックスをUPSに接続します&lt;/li&gt;
&lt;li&gt;付属のUSBケーブルを使って、UPS管理のためにMac Miniに接続します。&lt;/li&gt;
&lt;li&gt;OSの起動時は10W程度でしたが、安定期に入ると5Wでした。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/IMG_2816.jpg&quot; alt=&quot;IMG_2816&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UPSのフロントパネルにあるボタンを押すと、現在の使用W数で、どの程度の時間電池が持つかが表示されます。&lt;/li&gt;
&lt;li&gt;6時間半は持ちます！十分すぎる。。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/IMG_2817.jpg&quot; alt=&quot;ups&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;UPSの設定&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;設定用ソフトウェアやドライバは一切不要！&lt;/li&gt;
&lt;li&gt;システム管理パネルから、省電力設定パネルで設定出来ます。&lt;/li&gt;
&lt;li&gt;今回は、サーバなのでsleepに入らないようにします。ディスプレイは無いですが、無駄な電力を使わないために、速攻スリープするようにしておきます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen_Shot_2015-12-15_at_00_40_54-1.png&quot; alt=&quot;energy saver ups&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;シャットダウンの設定を追加します。&lt;/li&gt;
&lt;li&gt;今回は、UPSの電池残量が少なくなったらシャットダウンプロセスを開始するように設定します。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen_Shot_2015-12-15_at_00_40_45-1.png&quot; alt=&quot;energy saver ups setting&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;設定は簡単&lt;/li&gt;
&lt;li&gt;あとは停電を待つのみ！&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Let&apos;s Encryptを使って簡単0円でサーバ証明書を取得</title><link>https://blog.teraren.com/posts/lets-encrypt-free-ssl-certificate/</link><guid isPermaLink="true">https://blog.teraren.com/posts/lets-encrypt-free-ssl-certificate/</guid><description>Let&apos;s Encryptを使ってNginxサーバに無料のSSL証明書を10分で取得・設置する手順を解説。Qualys SSLテストでの評価確認まで含めて紹介</description><pubDate>Sat, 12 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://letsencrypt.org/&quot;&gt;Let&apos;s Encrypt&lt;/a&gt; を使って、無料サーバ証明書を発行して設置します。
&lt;ul&gt;
&lt;li&gt;手順通りやれば、10分程度で出来ると思います。&lt;/li&gt;
&lt;li&gt;最近Facebookがゴールドスポンサーになって、盛り上がってきています。&lt;/li&gt;
&lt;li&gt;12月3日にPublic Betaになりました。&lt;/li&gt;
&lt;li&gt;今は3ヶ月分の証明書を取得出来ます（コマンド1発で、無料で更新可能）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;サーバ環境は、Mac OS X 10.10 + Nginx 1.8です。
&lt;ul&gt;
&lt;li&gt;おそらく、各種OS + Nginxなら同じ手順で行けると思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Google Chromeが、WebRTCを使うためには&lt;a href=&quot;http://www.tokbox.com/blog/the-impact-of-googles-new-chrome-security-policy-on-webrtc/&quot;&gt;HTTPSが必須&lt;/a&gt;になりました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;セットアップ&lt;/h3&gt;
&lt;p&gt;cloneしてくる。ちょっと容量は重め。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git clone https://github.com/letsencrypt/letsencrypt
% cd letsencrypt
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;証明書取得&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;普通の証明書取得は、メアド確認やら存在確認やらで凄い時間と手間がかかりますが、そこら辺はクライアントアプリが自動でやってくれます。&lt;/li&gt;
&lt;li&gt;80番ポートを使って、ドメインの所在確認をしているので、既に80番ポートが使われていると以下のようなエラーが出ます。&lt;/li&gt;
&lt;li&gt;80番ポートで稼動しているサービスがある場合は止める必要があります。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/img_566becf100326.png&quot; alt=&quot;img_566becf100326&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;私の場合、Mac OSで動いているHTTPサーバを止めました。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% sudo brew services stop nginx-full
Stopping `nginx-full`... (might take a while)
==&amp;gt; Successfully stopped `nginx-full` (label: homebrew.mxcl.nginx-full)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そして、キーペアの生成などを一発で行えるコマンドを実行します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./letsencrypt-auto certonly --standalone
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Mac OS X 場合、&lt;code&gt;-d&lt;/code&gt;オプションでホスト名を指定したら、プログラムが異常終了したため、オプションは渡さずに実行しました。そうすると、インタラクティブにホスト名を聞かれるので、そこで入力します。&lt;/li&gt;
&lt;li&gt;Debianで実行した場合、以下のパッケージをインストールするように求められます&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;augeas-lenses libexpat1-dev libpython-dev libpython2.7 libpython2.7-dev python-chardet-whl python-colorama-whl python-distlib-whl python-html5lib-whl python-pip-whl python-requests-whl python-setuptools-whl python-six-whl python-urllib3-whl python2.7-dev python3-pkg-resources python3-virtualenv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-12-at-18.52.27.png&quot; alt=&quot;letsencrypt&quot; /&gt;&lt;/p&gt;
&lt;p&gt;初回は、メールアドレスを聞かれます。&lt;/p&gt;
&lt;p&gt;そして、最後にキーなどが生成されます。&lt;br /&gt;
以下に、2つ分の証明書を作った場合のファイル一覧を貼り付けます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/1__ssh.png&quot; alt=&quot;1__ssh&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;nginxに設置&lt;/h3&gt;
&lt;p&gt;nginxの設定を抜粋します。ほとんどコピペで行けると思います。&lt;/p&gt;
&lt;p&gt;重要な点は以下の2つを書き換えることだけです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ssl_certificate_key&lt;/code&gt;に秘密鍵のファイル&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ssl_certificate&lt;/code&gt;に証明書のファイル&lt;/li&gt;
&lt;li&gt;その他のSSLの設定は&lt;a href=&quot;http://qiita.com/dseg/items/bab80f6f14349fcd9c22&quot;&gt;Let&apos;s EncryptのSSL証明書で、Qualys SSLTestでA+評価を獲得するには&lt;/a&gt;を参照しました。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;server {
  listen       443 ssl;
  server_name  matsu.teraren.com ;

  ssl_certificate      /etc/letsencrypt/live/matsu.teraren.com/fullchain.pem;
  ssl_certificate_key  /etc/letsencrypt/live/matsu.teraren.com/privkey.pem;

  # 1. 暗号方式の設定
  # (デフォルト) ssl_ciphers  HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers  on;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers &apos;EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH&apos;;

  # 2. Logjam攻撃対策
  ssl_dhparam /etc/nginx/ssl/dhparam.pem;

  # 3. Enable OCSP (Online Certificate Status Protocol) Stapling
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.4.4 8.8.8.8 valid=300s;
  resolver_timeout 10s;

  ......

}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;証明書を確認&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;このブログ自体には、httpへの参照があり、画像が出なかったりするので検証はこちらで。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://matsu.teraren.com/static/spike-token-api/&quot;&gt;https://matsu.teraren.com/static/spike-token-api/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ちゃんとSSL緑のキーになっています！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-12-at-19.11.08.png&quot; alt=&quot;ssl certified&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-12-at-19.11.53.png&quot; alt=&quot;ssl certificate by letsencrypt&quot; /&gt;&lt;/p&gt;
&lt;p&gt;サーバ証明書を見てみましょう。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-12-at-19.12.06.png&quot; alt=&quot;ssl certificate by letsencrypt&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中間証明書を見てみましょう。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ルート証明書を見てみましょう。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;DST Root CA X3ですね。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-12-at-19.12.11.png&quot; alt=&quot;ssl certificate by letsencrypt&quot; /&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ブラウザ確認&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OK
&lt;ul&gt;
&lt;li&gt;Mac OS 10.11 (El Capitan) Google Chrome&lt;/li&gt;
&lt;li&gt;Mac OS 10.11 (El Capitan) Safari&lt;/li&gt;
&lt;li&gt;Mac OS 10.11 (El Capitan) Firefox 43.0.1&lt;/li&gt;
&lt;li&gt;iOS 9.2 Google Chrome&lt;/li&gt;
&lt;li&gt;Mac OS X 10.10 curl&lt;/li&gt;
&lt;li&gt;Mac OS X 10.11 curl&lt;/li&gt;
&lt;li&gt;iOS 9.2 safari&lt;/li&gt;
&lt;li&gt;Mac OS 10.10.5 (Yosemite) Firefox 43.0.1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;証明書の更新方法&lt;/h3&gt;
&lt;p&gt;自動化するなら、こんな感じになるかなと思います。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo brew services stop nginx-full
% sudo  ./letsencrypt-auto certonly
% sudo brew services start nginx-full
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;サンプル&lt;/h3&gt;
&lt;p&gt;この辺りのサービスもSSL化しました。（ついでに、HTTP2化も）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/&quot;&gt;金融機関コードAPI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/&quot;&gt;郵便番号API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;制限&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Rate limit on registrations per IP is currently 10 per 3 hours&lt;br /&gt;
Rate limit on certificates per Domain is currently 5 per 7 days&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;https://community.letsencrypt.org/t/public-beta-rate-limits/4772/3&lt;/p&gt;
&lt;h3&gt;SSL TESTの結果&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ssllabs.com/ssltest/analyze.html?d=matsu.teraren.com&quot;&gt;https://www.ssllabs.com/ssltest/analyze.html?d=matsu.teraren.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2016-01-10-at-11.22.21.png&quot; alt=&quot;ssl test matsu.teraren.com&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;自動更新&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/lets-encrypt-certbot/&quot;&gt;SSL証明書を自動で期限が切れそうになったら更新する方法&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これで、今日からあなたも快適なSSLライフを送れますね！&lt;/p&gt;
&lt;p&gt;Let&apos;s Encrypt!&lt;/p&gt;
&lt;h3&gt;更新履歴&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2016/1/4 &lt;code&gt;cert.pem&lt;/code&gt;を&lt;code&gt;fullchain.pem&lt;/code&gt;に変更&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>SPIKE API (Token API)を使ってみる</title><link>https://blog.teraren.com/posts/spike-api-token-api/</link><guid isPermaLink="true">https://blog.teraren.com/posts/spike-api-token-api/</guid><description>決済サービスSPIKEのToken APIを使い、マーチャントのページでクレジットカード番号を入力する方式の実装方法。サンドボックスでのデモコードと決済フローのシーケンス図を解説。</description><pubDate>Wed, 09 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/advent-calendar/2015/payment&quot;&gt;Payment Advent Calendar&lt;/a&gt; 12月8日分&lt;/li&gt;
&lt;li&gt;昨日書いた、&lt;a href=&quot;/posts/spike-api-spike-checkout/&quot;&gt;SPIKE Checkoutを使ってみる&lt;/a&gt;では、クレジットカード番号の入力を決済会社のオーバーレイで行っていました。&lt;/li&gt;
&lt;li&gt;今回は、クレジットカード番号の入力をマーチャントのページで行います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Token APIを使って、一切SPIKEのUIを見せずに、決済を行えます。&lt;/li&gt;
&lt;li&gt;サンドボックスでテストしてみます。&lt;/li&gt;
&lt;li&gt;本番環境は、ビジネスプレミアム（月額3000円）とフルAPI利用料（月額5000円）がかかります。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Token API利用時のシーケンス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/spike-api-spike-checkout/&quot;&gt;SPIKE Checkout&lt;/a&gt;の利用時と比べると、シンプルなので理解に問題は無いと思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/img_5666f3597d81e.png&quot; alt=&quot;SPIKE Token API Sequence Diagram&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;デモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;デモページ
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://matsu.teraren.com/spike-api-demo-php/token/&quot;&gt;https://matsu.teraren.com/spike-api-demo-php/token/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;github
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/spike-api-demo-php&quot;&gt;ソースコード&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1ページ目&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ページデザインはマーチャントが自由に表現できます。&lt;br /&gt;
&lt;img src=&quot;../../assets/uploads/2015/12/img_5666fd1bd28c9.png&quot; alt=&quot;SPIKE TOKEN API input page&quot; /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2ページ目&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;以下のような結果表示が出たら成功です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/img_5666fca9739b5.png&quot; alt=&quot;SPIKE TOKEN API result page&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;決済部分の主要コードは以下のようになります。&lt;/li&gt;
&lt;li&gt;入力値の検証は、デモなので行っていません。本番で行う場合はしっかりと行ってください。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;SPIKEで結果確認&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SPIKEの開発ダッシュボードからトランザクションの状態をリアルタイムに確認出来ます。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://spike.cc/dashboard/developer/analytics&quot;&gt;https://spike.cc/dashboard/developer/analytics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;取り消しなどもWeb上から行えます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-07-at-19.07.53.png&quot; alt=&quot;spike developer dashboard&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SPIKE Token APIを作ってみました&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>SPIKE REST APIで受注管理をしてみる</title><link>https://blog.teraren.com/posts/spike-rest-api-order-management/</link><guid isPermaLink="true">https://blog.teraren.com/posts/spike-rest-api-order-management/</guid><description>SPIKE REST APIを使って仮売上・実売上・キャンセルの受注管理をPHPで実装し、サンドボックスでテストする手順を紹介</description><pubDate>Wed, 09 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/advent-calendar/2015/payment&quot;&gt;Payment Advent Calendar&lt;/a&gt; 12月9日分&lt;/li&gt;
&lt;li&gt;今日までは、クレジットカードに対して課金したので、行った課金を管理します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;REST APIを使って、課金を管理します。&lt;/li&gt;
&lt;li&gt;管理するオペレーションは、仮売上の実売上、実売上キャンセル、仮売上キャンセルの3つ。&lt;/li&gt;
&lt;li&gt;サンドボックスでテストしてみます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;デモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;デモページ
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://matsu.teraren.com/spike-api-demo-php/charges/&quot;&gt;https://matsu.teraren.com/spike-api-demo-php/charges/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;github
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/spike-api-demo-php&quot;&gt;ソースコード&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;（SPIKE Checkout, Token APIのデモコードも1つにまとめました）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1ページ目&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;こんな感じで受注一覧が表示されます。&lt;/li&gt;
&lt;li&gt;今回はデモのため、ページングを行っていません。
&lt;ul&gt;
&lt;li&gt;そろそろModelとViewを分離しないと、コードを書くのが辛くなってきました。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-09-at-22.35.44.png&quot; alt=&quot;SPIKE REST API charges&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;2ページ目&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;以下のような結果表示が出たら成功です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/img_56682f46d8698.png&quot; alt=&quot;SPIKE API Result&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;決済部分の主要コードは以下のようになります。&lt;/li&gt;
&lt;li&gt;Viewとロジックが入り乱れてしまってすいません。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SPIKEのREST APIを作って、Webhookの受信ページを作ってみました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>SPIKE API (SPIKE Checkout)を使ってみる</title><link>https://blog.teraren.com/posts/spike-api-spike-checkout/</link><guid isPermaLink="true">https://blog.teraren.com/posts/spike-api-spike-checkout/</guid><description>決済サービスSPIKE CheckoutのサンドボックスAPIを使って仮売上・実売上・キャンセルを実装。PHPサンプルコードとシーケンス図付きで決済フローを解説。</description><pubDate>Mon, 07 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/advent-calendar/2015/payment&quot;&gt;Payment Advent Calendar&lt;/a&gt; 12月7日分&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/posts/yahoo-wallet-fastpay/&quot;&gt;Yahoo! ウォレット FastPayを使ってみる&lt;/a&gt;に関連して、同等のアーキテクチャで動くSPIKE Checkoutサービスを試してみる。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/img_5665505021f18.png&quot; alt=&quot;https://spike.cc/&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://spike.cc/&quot;&gt;SPIKE&lt;/a&gt;の特徴
&lt;ul&gt;
&lt;li&gt;サンドボックス環境はアカウントを作るだけで利用出来ます。&lt;/li&gt;
&lt;li&gt;本番環境でSPIKEのAPIを利用するためには月額3,000円のビジネスプレミアムに申し込む必要が有ります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;この記事ではサンドボックス環境でテストしてみます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;SPIKE開発ドキュメント&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;開発用ドキュメントは、ユーザ登録後に誰でも閲覧でき、Sandbox環境も利用出来ます。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://spike.cc/dashboard/developer/docs&quot;&gt;https://spike.cc/dashboard/developer/docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;SPIKE Checkout利用時のシーケンス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;単発決済の場合のシーケンスを書いてみました。
&lt;ul&gt;
&lt;li&gt;SPIKE Checkoutを利用しないで、Token APIを利用すれば、自分のサイト上でユーザがクレジットカード情報を入力させることもできます。その場合は、&lt;a href=&quot;https://support.spike.cc/hc/ja/articles/204660150-REST-eAPI%E3%81%AB%E3%82%88%E3%82%8B%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E5%8C%96%E6%A9%9F%E8%83%BD%E3%81%AE%E6%96%99%E9%87%91%E4%BD%93%E7%B3%BB%E3%81%A8%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E7%94%B3%E8%BE%BC%E6%96%B9%E6%B3%95%E3%82%92%E6%95%99%E3%81%88%E3%81%A6%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84-&quot;&gt;Full API&lt;/a&gt;に申し込む必要が有ります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;シーケンス図は、FastPayの時に書いた物を流用したので、FastPayをSPIKEに読み替えて頂ければと思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/img_5663208187886.png&quot; alt=&quot;fastpay_sequence&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;デモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;デモページ
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://matsu.teraren.com/spike-api-demo-php/checkout/&quot;&gt;https://matsu.teraren.com/spike-api-demo-php/checkout/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;github
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/spike-api-demo-php&quot;&gt;ソースコード&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1ページ目&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;FastPayと違い、ボタンや、処理をマーチャントが自由に書けます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-07-at-19.21.41.png&quot; alt=&quot;SPIKE Checkout demo&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2ページ目&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;以下のような結果表示が出たら成功です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-07-at-19.17.09.png&quot; alt=&quot;SPIKE API result&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;決済部分の主要コードは以下のようになります。&lt;/li&gt;
&lt;li&gt;FastPayとは、APIを作ってくれた方の設計思想の違いにより、呼び出し方はちょっと違います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;SPIKEで結果確認&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SPIKEの開発ダッシュボードからトランザクションの状態をリアルタイムに確認出来ます。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://spike.cc/dashboard/developer/analytics&quot;&gt;https://spike.cc/dashboard/developer/analytics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;取り消しなどもWeb上から行えます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-07-at-19.07.53.png&quot; alt=&quot;spike developer dashboard&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SPIKE Checkoutを使って、仮売上、実売上、実売上キャンセルを行いました。&lt;/li&gt;
&lt;li&gt;SPIKE APIのPHPライブラリに微妙に不具合があったので修正しました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Yahoo! ウォレット FastPayを使ってみる</title><link>https://blog.teraren.com/posts/yahoo-wallet-fastpay/</link><guid isPermaLink="true">https://blog.teraren.com/posts/yahoo-wallet-fastpay/</guid><description>Yahoo!ウォレットFastPayの特徴と決済シーケンスを整理し、サンドボックス環境でPHP実装した動作デモを解説</description><pubDate>Sun, 06 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/advent-calendar/2015/payment&quot;&gt;Payment Advent Calendar&lt;/a&gt; 12月6日分&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fastpay.yahoo.co.jp/&quot;&gt;Yahoo!ウォレットFastPay&lt;/a&gt;の特徴を整理します&lt;/li&gt;
&lt;li&gt;APIのドキュメントの不足部分を解説します。&lt;/li&gt;
&lt;li&gt;サンドボックスでテストしてみます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;FastPayの特徴&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;経済条件
&lt;ul&gt;
&lt;li&gt;決済手数料がやや高め&lt;/li&gt;
&lt;li&gt;決済手数料: 3.25%&lt;/li&gt;
&lt;li&gt;その代わり、月額費用が無料、トランザクションフィーが無料&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;メリット
&lt;ul&gt;
&lt;li&gt;クレジットカード番号をマーチャント側で保存しなくて良い（保存不可能）&lt;/li&gt;
&lt;li&gt;継続課金対応&lt;/li&gt;
&lt;li&gt;REST APIで提供されているので、クライアントを実装しやすい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;デメリット
&lt;ul&gt;
&lt;li&gt;決済を全てAPIで出来る分けでは無い（次のセクションで解説）&lt;/li&gt;
&lt;li&gt;決済ボタンのデザインが固定されてしまっている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;FastPay利用時のシーケンス&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;単発決済の場合のシーケンスを書いてみました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/img_5663208187886.png&quot; alt=&quot;fastpay_sequence&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;デモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;デモサイト
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://matsu.teraren.com/static/fast_pay/&quot;&gt;https://matsu.teraren.com/static/fast_pay/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;github
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/fast_pay&quot;&gt;ソースコード&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;1ページ目&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;サンドボックス環境で動作しています。&lt;/li&gt;
&lt;li&gt;カード番号に&lt;code&gt;4242 4242 4242 4242&lt;/code&gt;を入力し、他は適当に記入してsubmitします。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-06-at-02.37.51.png&quot; alt=&quot;Screen Shot 2015-12-06 at 02.37.51&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2ページ目&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;以下のような、FastPayのサーバからのレスポンスが表示されれば正常です。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-06-at-02.39.31.png&quot; alt=&quot;Screen Shot 2015-12-06 at 02.39.31&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;結果確認&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;FastPayにログインして、結果を確認出来ます（デモの場合は、私個人のアカウントに表示されます）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-06-at-02.42.04.png&quot; alt=&quot;Screen Shot 2015-12-06 at 02.42.04&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;要点解説&lt;/h2&gt;
&lt;h2&gt;1ページ目&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/fast_pay/blob/master/index.html&quot;&gt;概要ソースコード index.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;決済ボタンを設置したい箇所に、scriptタグを設置するだけです。
&lt;ul&gt;
&lt;li&gt;このscriptタグが自分自身を置き換えます。&lt;/li&gt;
&lt;li&gt;クレジットカードの入力を完了すると、自動的に親のformをsubmitします。その際に、&lt;code&gt;fastpayToken&lt;/code&gt;という名前でhiddenタグを生成し,valueにトークンの値が設定されます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2ページ目&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/fast_pay/blob/master/post.php&quot;&gt;該当ソースコード post.php&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;1ページ目から送信されたトークンを使って決済処理を行います。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要点&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;FastPayは、全てをAPIで決済出来るわけでは無い
&lt;ul&gt;
&lt;li&gt;クレジットカード番号の入力はFastPayの画面で行う。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;composerのクライアントライブラリが出ていてPHPの場合は実装が楽だった。&lt;/li&gt;
&lt;li&gt;楽天ID決済と同様に、クレジットカード以外の決済手段がある。
&lt;ul&gt;
&lt;li&gt;FastPayはTポイントの消費が出来るようになっている。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Railsで作ったREST APIをSwagger対応</title><link>https://blog.teraren.com/posts/rails-swagger-postcode-api/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-swagger-postcode-api/</guid><description>swagger-docsを使いRailsの郵便番号検索APIをSwagger UIで可視化する手順。ControllerへのAPI仕様記述からJSONファイル生成・デモ公開までの実装例を解説。</description><pubDate>Thu, 03 Dec 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/advent-calendar/2015/web_api&quot;&gt;Web API Advent Calendar&lt;/a&gt; 12月3日分&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/takuros&quot;&gt;@takuros&lt;/a&gt;さんの12月2日の&lt;a href=&quot;http://blog.takuros.net/entry/2015/12/02/082248&quot;&gt;Swaggerとは何か？&lt;/a&gt; を前提としています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/richhollis/swagger-docs&quot;&gt;swagger-docs&lt;/a&gt; を使ってRailsのREST APIをswaggerで表示出来るようにします。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;郵便番号検索API&lt;/a&gt;のAPIを表現してみます。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/Screen-Shot-2015-12-03-at-02.46.06.png&quot; alt=&quot;郵便番号検索API&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;手順&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Gemfile&lt;/code&gt;に&lt;code&gt;swagger-docs&lt;/code&gt;を追加します。
&lt;ul&gt;
&lt;li&gt;しかしながら、masterブランチにバグがあり、pathにスラッシュが付かないので、&lt;a href=&quot;https://github.com/richhollis/swagger-docs/pull/118&quot;&gt;forkされたgem&lt;/a&gt;を使います。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;gemをインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ bundle
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;swaggerの初期設定ファイルを作成します。&lt;br /&gt;
initializerを&lt;code&gt;config/initializers/swagger_docs.rb&lt;/code&gt;に作成して、以下のようにAPIサーバの基本情報を書いておきます。&lt;/p&gt;
&lt;p&gt;該当するControllerに、API仕様を追記します。&lt;br /&gt;
今回は、5行目から40行目を追記しました。&lt;/p&gt;
&lt;p&gt;swaggerの定義ファイルをJSON形式で出力します。&lt;br /&gt;
以下のrakeタスクが、controllerを全て読んで、先ほど書いた設定をパースしてくれます。&lt;br /&gt;
（もし、deploy時に生成したい場合は以下のrakeタスクをcapistranoなどで実行するようにしておきます。）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% rake swagger:docs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記のコマンドが実行されることにより、以下のファイルが出力されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;public/apidocs/api-docs.json&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://postcode.teraren.com/apidocs/api-docs.json&quot;&gt;https://postcode.teraren.com/apidocs/api-docs.json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public/apidocs/postcodes.json&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://postcode.teraren.com/apidocs/postcodes.json&quot;&gt;https://postcode.teraren.com/apidocs/postcodes.json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;デモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://petstore.swagger.io/&quot;&gt;http://petstore.swagger.io/&lt;/a&gt; の上部にあるテキストボックスに以下のSwaggerの設定ファイルであるJSONを入力すると、ドキュメント表示とREST APIをテスト出来ます。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://postcode.teraren.com/apidocs/postcodes.json&quot;&gt;https://postcode.teraren.com/apidocs/postcodes.json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;スクリーンショット&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/screencapture-localhost-3000-swagger-dist-index-html-1449077955013.png&quot; alt=&quot;swagger-doc&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;https://postcode.teraren.com/&lt;/a&gt;のAPIをswaggerで表現して、ローカルでテストしてみました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/richhollis/swagger-docs&quot;&gt;swagger-docs&lt;/a&gt;の最終更新日は1年以上前で、重要な不具合があるので利用はオススメ出来ません。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ruby-grape/grape-swagger&quot;&gt;grape-swagger&lt;/a&gt;は活発そうです。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>homebrew-file使い出した</title><link>https://blog.teraren.com/posts/homebrew-file/</link><guid isPermaLink="true">https://blog.teraren.com/posts/homebrew-file/</guid><description>homebrew-file使い出した</description><pubDate>Tue, 24 Nov 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;エンジニア同士での、開発ツールの共通化にちょうど良いツールだと思います。 それよりも、&lt;strong&gt;コマンド1発でMacにインストールされているアプリケーションを全部更新&lt;/strong&gt;できるというメリットの方が大きい！&lt;/p&gt;
&lt;h2&gt;設定例&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/matsubo/011ad118a8efd0a816b4#differential-install&quot;&gt;https://gist.github.com/matsubo/011ad118a8efd0a816b4#differential-install&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>URL一覧からタイトルタグを抜き出すツール</title><link>https://blog.teraren.com/posts/scrape-title-tag/</link><guid isPermaLink="true">https://blog.teraren.com/posts/scrape-title-tag/</guid><description>URL一覧からタイトルタグを抜き出すツール</description><pubDate>Tue, 24 Nov 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;URL一覧からタイトルタグを抜き出すツールを作ってみました。 &lt;a href=&quot;https://matsu.teraren.com/static/scrape_title/?urls=http://www.yahoo.co.jp&quot;&gt;https://matsu.teraren.com/static/scrape_title/&lt;/a&gt; &lt;img src=&quot;../../assets/uploads/2015/11/Title_tag_scraper.png&quot; alt=&quot;Title tag scraper&quot; /&gt; 作ってみてから気づいたけど、類似ツールがたくさんありますね。 せっかくなので、このサービスのメリットを列挙してみましょう。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;レスポンシブデザイン&lt;/li&gt;
&lt;li&gt;URL数の制限無し&lt;/li&gt;
&lt;li&gt;出力をそのままExcelへコピペできる。&lt;/li&gt;
&lt;li&gt;入力内容はサーバに記録していない。&lt;/li&gt;
&lt;li&gt;文字コードをちゃんと判定する&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>tmuxinator使い始めてみた</title><link>https://blog.teraren.com/posts/tmuxinator/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tmuxinator/</guid><description>tmuxinator使い始めてみた</description><pubDate>Tue, 24 Nov 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;普段の開発は、railsをvimでやってます。&lt;br /&gt;
iterm2のウィンドウ分割でペインを分けて開発していましたが、Macを再起動すると状態が全てリセットされてしまうことが難点でした。&lt;/p&gt;
&lt;p&gt;レンダリングが遅いという点と、コピペが行いづらいと言うデメリットはありますが、tmux + tmuxinatorに乗り換えることにしました。&lt;/p&gt;
&lt;p&gt;スクリーンキャストを撮ってみました&lt;/p&gt;
&lt;p&gt;mux rails&lt;/p&gt;
&lt;p&gt;と打つだけで、dockerコンテナの起動、&lt;code&gt;rails console&lt;/code&gt;の起動などを一通りやってくれます。&lt;br /&gt;
工夫ポイントとしては、立ち上がりが遅くて良いペインに関してはsleepを入れて、起動時間を面しています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/11/tmuxinator.png&quot; alt=&quot;tmuxinator&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上記の設定はこちら。&lt;br /&gt;
&lt;a href=&quot;https://gist.github.com/matsubo/8e9aa12c1ca9dcc7f0f3&quot;&gt;https://gist.github.com/matsubo/8e9aa12c1ca9dcc7f0f3&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>AWS QuickSight関連メモ</title><link>https://blog.teraren.com/posts/aws-quicksight-business-intelligence/</link><guid isPermaLink="true">https://blog.teraren.com/posts/aws-quicksight-business-intelligence/</guid><description>AWS QuickSight関連メモ</description><pubDate>Thu, 08 Oct 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;BIツールの会社まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.domo.com/&quot;&gt;Domo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.qlik.com/&quot;&gt;Qlik&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tableau.com/&quot;&gt;Tableau&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tibco.com/&quot;&gt;Tibco&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>nodejs (express) benchmark</title><link>https://blog.teraren.com/posts/nodejs-4-1-2-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nodejs-4-1-2-benchmark/</guid><description>nodejs (express) benchmark</description><pubDate>Thu, 08 Oct 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;expressのinit直後のアプリでベンチマーク取っていきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% npm install express-generator -g
% express init
% PORT=3001 bin/www
% ab -n 5000 -c 50 http://127.0.0.1:3001/
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;v5.0.0
&lt;ul&gt;
&lt;li&gt;Requests per second: 356.82 [#/sec] (mean)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;v4.1.2
&lt;ul&gt;
&lt;li&gt;Requests per second: 333.10 [#/sec] (mean)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;v0.12.7
&lt;ul&gt;
&lt;li&gt;Requests per second: 390.75 [#/sec] (mean)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hardware
&lt;ul&gt;
&lt;li&gt;2.6 GHz Intel Core i7&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;OS
&lt;ul&gt;
&lt;li&gt;Mac OS X 10.10.5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>LINE会話データ復元</title><link>https://blog.teraren.com/posts/line-chat-data-recovery/</link><guid isPermaLink="true">https://blog.teraren.com/posts/line-chat-data-recovery/</guid><description>MacのTimeMachineバックアップとLANケーブルを使い、削除したLINEの会話データを復元する具体的な手順を解説</description><pubDate>Tue, 06 Oct 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;LINEの会話データを削除してしまうと基本的には復元出来なくなります。&lt;/li&gt;
&lt;li&gt;以下の前提条件に当てはまっている場合は、会話内容を復元出来ます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;前提条件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;LINEのMacアプリを定期的に使っている。&lt;/li&gt;
&lt;li&gt;MacのTimemachineで定期的にバックアップを取っている。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;方法&lt;/h2&gt;
&lt;p&gt;準備&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Macにて&lt;strong&gt;有線LANをつなぎ、無線LANをOffにしておく&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;直感的に、すぐにネットワークを切る必要があるので有線LANを使う必要が有ります。&lt;/li&gt;
&lt;li&gt;OSの設定から無線LANをoffにする操作には最低でも0.5秒くらいかかってしまい、それでは遅すぎるためです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MacのLINEアプリを終了しておく&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;実行&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Timemachineにて、以下のディレクトリを、&lt;strong&gt;削除する前の日時の状態に復元する&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;~/Library/Containers/jp.naver.line.mac//Data/Library/Containers/jp.naver.line/Data/&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ここが重要&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;MacのLINEを起動。&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ログインをして会話データの一覧が表示された瞬間に、LANケーブルを抜く&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;サーバ側と会話データが同期される前にネットワークを切断すれば成功です。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;予備情報&lt;/h2&gt;
&lt;p&gt;LINEの会話データはsqliteで保存されているので、直接見ようと思いましたが、値がすべて暗号化されていて、暗号化ロジックが不明なので諦めました。&lt;br /&gt;
データは以下に有ります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ls -al ~/Library/Containers/jp.naver.line.mac/Data/Library/Containers/jp.naver.line/Data/*db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/09/6b03fb33115a72444057e1a52c02b4e3.png&quot; alt=&quot;DB Browser for SQLite&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/09/DB_Browser_for_SQLite_-__Users_yuki_matsukura_Library_Containers_jp_naver_line_mac_Data_Library_Containers_jp_naver_line_Data_qw9b5b3703e517ae43d0df6d757370b9_db_and_Data_and_Data.png&quot; alt=&quot;DB_Browser_for_SQLite_-__Users_yuki_matsukura_Library_Containers_jp_naver_line_mac_Data_Library_Containers_jp_naver_line_Data_qw9b5b3703e517ae43d0df6d757370b9_db_and_Data_and_Data&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>RequireJSってどうなん？</title><link>https://blog.teraren.com/posts/requirejs-thoughts/</link><guid isPermaLink="true">https://blog.teraren.com/posts/requirejs-thoughts/</guid><description>RequireJSってどうなん？</description><pubDate>Tue, 08 Sep 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;syntaxわかりづらいし、ビルドツールを使えばいらないような気もする。 webpackが伸びてる。 Google Trendの参考値&lt;/p&gt;
&lt;p&gt;RequireJS VS CommonJS&lt;/p&gt;
</content:encoded></item><item><title>tokboxのwebRTC録画機能の概要</title><link>https://blog.teraren.com/posts/tokbox-webrtc-archive/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tokbox-webrtc-archive/</guid><description>TokBox（OpenTok）のWebRTC録画APIの仕様を日本語で解説。最大90分・S3/Azure保存・個別または結合録画などの機能まとめ</description><pubDate>Sun, 21 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;原文&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://tokbox.com/developer/guides/archiving/&quot;&gt;https://tokbox.com/developer/guides/archiving/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;翻訳&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;OpenTok REST API または、OpenTok Server SDKから呼べる&lt;/li&gt;
&lt;li&gt;最低1クライアントが接続しているセッションを録画できる
&lt;ul&gt;
&lt;li&gt;クライアントは接続から1分以内に開始する必要があり、セッションが終わったら録画も止まる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;数字的な制約
&lt;ul&gt;
&lt;li&gt;ストリーム数：推奨5ストリーム。仕様は、ストリームまで可能。&lt;/li&gt;
&lt;li&gt;6ストリーム以上になると、画像のクオリティを下げる&lt;/li&gt;
&lt;li&gt;録画されたファイルの数は無制限&lt;/li&gt;
&lt;li&gt;1録画は90分まで。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;録画API概要
&lt;ul&gt;
&lt;li&gt;録画開始&lt;/li&gt;
&lt;li&gt;録画停止&lt;/li&gt;
&lt;li&gt;録画の一覧&lt;/li&gt;
&lt;li&gt;録画情報の取得&lt;/li&gt;
&lt;li&gt;録画の削除&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;録画が停止された直後に、MP4ファイル（またはZIPファイル）を作成される。&lt;/li&gt;
&lt;li&gt;ファイルを保管する場所を、ダッシュボードで指定する必要がある。
&lt;ul&gt;
&lt;li&gt;S3 bucket&lt;/li&gt;
&lt;li&gt;Windows Azure container&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;もし、上記のファイル保管場所が指定されていないか、エラーで保存ができなかった場合は、opentok側で72時間保持される。&lt;/li&gt;
&lt;li&gt;録画イベントは、&lt;code&gt;session&lt;/code&gt;オブジェクトの&lt;code&gt;archiveStarted&lt;/code&gt; &lt;code&gt;archiveStopped&lt;/code&gt;に来る。&lt;/li&gt;
&lt;li&gt;録画は、動画だけ、音声だけ、またはその両方を指定できる。&lt;/li&gt;
&lt;li&gt;録画は、個別（ストリームごとにファイルが別れる）か結合を選べる。
&lt;ul&gt;
&lt;li&gt;個別の場合は、JSONファイルが一緒に出力され、それぞれの開始時間、終了時間などのメタ情報が記録されている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;雑感&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;tokboxはAPIがシンプルで良い。サンプルコードがそのままでは動かないので、いろいろいじらないといけないのが大変。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://fivebestessaywritingservices.blogspot.com/&quot;&gt;http://fivebestessaywritingservices.blogspot.com&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Generate URL for password reset manually using devise</title><link>https://blog.teraren.com/posts/generate-url-for-password-reset-manually-using-devise/</link><guid isPermaLink="true">https://blog.teraren.com/posts/generate-url-for-password-reset-manually-using-devise/</guid><description>Generate URL for password reset manually using devise</description><pubDate>Fri, 19 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Assumptions&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Resource name is &lt;code&gt;User&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Resource ID is &lt;code&gt;1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Execute on &lt;code&gt;rails console&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;user = User.find(1)

raw, enc = Devise.token_generator.generate(user.class, :reset_password_token)

user.reset_password_token   = enc
user.reset_password_sent_at = Time.now.utc
user.save(:validate =&amp;gt; false)

def main_app
  Rails.application.class.routes.url_helpers
end

include Devise::Controllers::UrlHelpers

edit_password_path(user, :reset_password_token =&amp;gt; raw)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>auのiPhone6をSIM unlockしてみた→失敗</title><link>https://blog.teraren.com/posts/iphone-au-sim-unlock/</link><guid isPermaLink="true">https://blog.teraren.com/posts/iphone-au-sim-unlock/</guid><description>myimeiunlock.comにau iPhone 6のSIMロック解除を約2万円で依頼したが解除できず、PayPal経由で返金を受けるまでの顛末記</description><pubDate>Fri, 19 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://myimeiunlock.com/&quot;&gt;https://myimeiunlock.com/&lt;/a&gt;で、SIMロックが解除できるらしい&lt;/li&gt;
&lt;li&gt;解除できなかったら返金される。&lt;/li&gt;
&lt;li&gt;NEW &lt;a href=&quot;/posts/iphone6-au-sim/&quot;&gt;SIMロックを解除しないでも格安SIMを使えます&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実行結果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;今使っているiPhone6がauのSIMロック付き。&lt;/li&gt;
&lt;li&gt;99ポンド→約2万円をPayPalで払ってやってみました。&lt;/li&gt;
&lt;li&gt;（2日経過）&lt;/li&gt;
&lt;li&gt;48時間以内という表示があったから、どうなっているのか問い合わせ。&lt;/li&gt;
&lt;li&gt;直ぐに返事が来て、場合によっては10営業日かかるから待てと。&lt;/li&gt;
&lt;li&gt;（10営業日経過）&lt;/li&gt;
&lt;li&gt;一向に変化がないから、どうなっているのか問い合わせ&lt;/li&gt;
&lt;li&gt;（4日経過）&lt;/li&gt;
&lt;li&gt;返信が無いから、refundを要求&lt;/li&gt;
&lt;li&gt;（4日経過）&lt;/li&gt;
&lt;li&gt;返信がないのでPayPal経由で返金請求&lt;/li&gt;
&lt;li&gt;（5日経過）&lt;/li&gt;
&lt;li&gt;返金される。&lt;/li&gt;
&lt;li&gt;サイト上のメッセージのやり取りが一切消される。。。。↓&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/06/Order_Status___My_IMEI_Unlock_com.png&quot; alt=&quot;Order_Status___My_IMEI_Unlock_com&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SIMロック解除できませんでした。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://un-sim-lock.blogspot.jp/2014/11/au-iphone5-sim.html&quot;&gt;ここ&lt;/a&gt;には、できそうなことが書いてあったけど。当たり外れがあるのかなと。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://fivebestessaywritingservices.blogspot.com/&quot;&gt;fivebestessaywritingservices.blogspot.com&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2016/8/30 auのMVNOならSIMロックを解除しないで使えます！参照 → &lt;a href=&quot;/posts/iphone6-au-sim/&quot;&gt;iPhone6 au SIMロック付を格安SIMで使う&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>EIZO EV2736W-FSBK修理（2回目）</title><link>https://blog.teraren.com/posts/eizo-ev2736w-fsbk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/eizo-ev2736w-fsbk/</guid><description>EIZO EV2736W-FSBK修理（2回目）</description><pubDate>Thu, 21 May 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;型番：&lt;a href=&quot;https://amzn.to/2XW2wiE&quot;&gt;EV2736W-FSBK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;写真だとわかりづらいですが、色ムラがあったので修理。&lt;/li&gt;
&lt;li&gt;修理は2回目です。&lt;/li&gt;
&lt;li&gt;5年保証なので、安心して使えます。&lt;/li&gt;
&lt;li&gt;現象は、明るい色を表示した時に、一部が明るくなりすぎる状態になっていました。&lt;/li&gt;
&lt;li&gt;後ろにある光源がモニタに反射しているのだとずっと思っていたのですが、モニタの発色がおかしいことが分かりました。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/05/IMG_0163.jpg&quot; alt=&quot;IMG_0163&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/05/IMG_0162.jpg&quot; alt=&quot;IMG_0162&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/05/IMG_0161.jpg&quot; alt=&quot;IMG_0161&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;パネル交換だったようなので、パネルが新品になりました！（1つ、小さな傷があったのですが、それがなくなってるので分かりました）&lt;/li&gt;
&lt;li&gt;モニタ内部で持っている累計点灯時間の情報はリセットされていませんでしたorz&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;B008U06TYI&quot;}&lt;/p&gt;
</content:encoded></item><item><title>rubyでsprintfするときに注意！</title><link>https://blog.teraren.com/posts/ruby-sprintf-caution/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ruby-sprintf-caution/</guid><description>Rubyのsprintfにゼロ埋め文字列を渡すと8以降で例外や予期しない値が返る落とし穴を実験で確認。原因と安全な文字列フォーマットの書き方を解説します。</description><pubDate>Thu, 21 May 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ゼロ埋めされた文字列を、sprintfの第2引数に渡すと、正しい値、間違った値、例外が飛ぶ場合があるので、エラーの特定が困難になる&lt;/li&gt;
&lt;li&gt;静的解析も難しいから気をつけるしか無いのかな。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実験&lt;/h2&gt;
&lt;p&gt;Ruby 2.1 on Mac OS 10.0.3 で検証。&lt;/p&gt;
&lt;p&gt;7まで正しいけど、それ以降はエラーがでたり、予期しない値が返されたりします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ruby sp.rb
00000
00001
00002
00003
00004
00005
00006
00007
invalid value for Integer(): &quot;00008&quot;
invalid value for Integer(): &quot;00009&quot;
00008
00009
00010
00011
00012
00013
00014
00015
invalid value for Integer(): &quot;00018&quot;
invalid value for Integer(): &quot;00019&quot;
00016
00017
00018
00019
00020
00021
00022
00023
invalid value for Integer(): &quot;00028&quot;
invalid value for Integer(): &quot;00029&quot;
00024
00025
00026
00027
00028
00029
00030
00031
invalid value for Integer(): &quot;00038&quot;
invalid value for Integer(): &quot;00039&quot;
00032
00033
00034
00035
00036
00037
00038
00039
invalid value for Integer(): &quot;00048&quot;
invalid value for Integer(): &quot;00049&quot;
00040
00041
00042
00043
00044
00045
00046
00047
invalid value for Integer(): &quot;00058&quot;
invalid value for Integer(): &quot;00059&quot;
00048
00049
00050
00051
00052
00053
00054
00055
invalid value for Integer(): &quot;00068&quot;
invalid value for Integer(): &quot;00069&quot;
00056
00057
00058
00059
00060
00061
00062
00063
invalid value for Integer(): &quot;00078&quot;
invalid value for Integer(): &quot;00079&quot;
invalid value for Integer(): &quot;00080&quot;
invalid value for Integer(): &quot;00081&quot;
invalid value for Integer(): &quot;00082&quot;
invalid value for Integer(): &quot;00083&quot;
invalid value for Integer(): &quot;00084&quot;
invalid value for Integer(): &quot;00085&quot;
invalid value for Integer(): &quot;00086&quot;
invalid value for Integer(): &quot;00087&quot;
invalid value for Integer(): &quot;00088&quot;
invalid value for Integer(): &quot;00089&quot;
invalid value for Integer(): &quot;00090&quot;
invalid value for Integer(): &quot;00091&quot;
invalid value for Integer(): &quot;00092&quot;
invalid value for Integer(): &quot;00093&quot;
invalid value for Integer(): &quot;00094&quot;
invalid value for Integer(): &quot;00095&quot;
invalid value for Integer(): &quot;00096&quot;
invalid value for Integer(): &quot;00097&quot;
invalid value for Integer(): &quot;00098&quot;
invalid value for Integer(): &quot;00099&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;原因&lt;/h2&gt;
&lt;p&gt;Rubyのsprintf（および内部で呼び出される数値変換処理）が、「先頭に0がついた文字列」を8進数（Octal）として解釈しようとするためです。&lt;/p&gt;
&lt;p&gt;解決策は、sprintfに渡す前に明示的に10進数のIntegerへキャストすることです。&lt;/p&gt;
</content:encoded></item><item><title>Vagrant + Core OS + docker-compose</title><link>https://blog.teraren.com/posts/coreos-docker-compose/</link><guid isPermaLink="true">https://blog.teraren.com/posts/coreos-docker-compose/</guid><description>boot2dockerのファイルシステムが遅い問題をVagrant+CoreOS+docker-composeで解決し、各構成のI/Oベンチマーク結果を比較・解説します。</description><pubDate>Thu, 09 Apr 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;boot2docker + docker-compose&lt;/code&gt;でホストOSのファイルシステムをマウントしたところ、すごく重いので、&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Vagrant + Core OS + docker-compose&lt;/code&gt;にしてみた。&lt;/li&gt;
&lt;li&gt;ついでに、ベンチマークもとってみました。&lt;/li&gt;
&lt;li&gt;ベンチマークは、&lt;code&gt;% dbbench 4&lt;/code&gt;コマンドで行いました。（1回10分かかります）
&lt;ul&gt;
&lt;li&gt;ディスク：APPLE SSD SM0512F Media&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ベンチマーク内容&lt;/h2&gt;
&lt;h3&gt;boot2docker container file system&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt; Operation      Count    AvgLat    MaxLat
 ----------------------------------------
 NTCreateX     577918     0.236   134.954
 Close         424536     0.115    51.865
 Rename         24460     0.534    49.595
 Unlink        116657     0.463   133.928
 Deltree           16    10.550    42.714
 Mkdir              8     0.079     0.153
 Qpathinfo     523842     0.168    90.023
 Qfileinfo      91866     0.117    43.895
 Qfsinfo        95976     0.195    91.965
 Sfileinfo      47064     0.373   144.815
 Find          202459     0.199    45.888
 WriteX        288380     0.288    96.877
 ReadX         905642     0.127   350.554
 LockX           1884     0.050     8.381
 UnlockX         1884     0.117    36.129
 Flush          40486    17.493   538.779
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Throughput 30.1989 MB/sec  4 clients  4 procs  max_latency=539.087 ms&lt;/p&gt;
&lt;h3&gt;boot2docker container mount FS.&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt; Operation      Count    AvgLat    MaxLat
 ----------------------------------------
 NTCreateX      22882    42.118  1403.164
 Close          16734     2.903   172.245
 Rename           966    79.413   532.418
 Unlink          4714    30.432  1309.666
 Qpathinfo      20633    22.221  1145.030
 Qfileinfo       3549     2.625   189.255
 Qfsinfo         3811     4.645   123.918
 Sfileinfo       1902    29.595   303.404
 Find            7967    47.080   385.768
 WriteX         11228     5.105   152.099
 ReadX          35198     4.028   156.998
 LockX             72     0.075     1.783
 UnlockX           72     0.034     0.224
 Flush           1644     0.161    48.173
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Throughput 1.16189 MB/sec  4 clients  4 procs  max_latency=1403.268 ms&lt;/p&gt;
&lt;h3&gt;Vagrant + Core OS + container file system&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt; Operation      Count    AvgLat    MaxLat
 ----------------------------------------
 NTCreateX    3080745     0.021    88.055
 Close        2263045     0.001    10.429
 Rename        130446     0.050    38.538
 Unlink        622126     0.049    95.054
 Deltree           80     2.252    15.547
 Mkdir             40     0.002     0.017
 Qpathinfo    2792341     0.005    58.912
 Qfileinfo     489401     0.001     6.665
 Qfsinfo       512005     0.002     5.374
 Sfileinfo     250951     0.161    42.271
 Find         1079605     0.017    15.224
 WriteX       1536354     0.022    64.048
 ReadX        4828893     0.004    22.103
 LockX          10030     0.003     5.337
 UnlockX        10030     0.001     1.674
 Flush         215920     9.880   153.907
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Throughput 161.082 MB/sec  4 clients  4 procs  max_latency=153.910 ms&lt;/p&gt;
&lt;h3&gt;Vagrant + Core OS + container mount file system&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt; Operation      Count    AvgLat    MaxLat
 ----------------------------------------
 NTCreateX    1052858     0.959   299.335
 Close         773373     0.303   301.123
 Rename         44579     1.731    69.077
 Unlink        212595     0.665    49.638
 Deltree           24    35.710    95.080
 Mkdir             12     0.480     0.811
 Qpathinfo     954354     0.336   303.192
 Qfileinfo     167168     0.346    26.187
 Qfsinfo       174935     0.463    43.445
 Sfileinfo      85764     0.475    19.563
 Find          368931     0.955   302.416
 WriteX        524405     0.013    26.680
 ReadX        1650314     0.006    20.807
 LockX           3428     0.456    10.404
 UnlockX         3428     0.003     0.289
 Flush          73791     0.678    28.926
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Throughput 55.0096 MB/sec  4 clients  4 procs  max_latency=303.719 ms&lt;/p&gt;
&lt;h2&gt;ベンチマークまとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;なんとか、実用に耐えうるような速度になりました。&lt;/li&gt;
&lt;li&gt;なぜかcontainer内のファイルシステムは値が異なる。。。
&lt;ul&gt;
&lt;li&gt;boot2docker = Vagrant + CoreOS だと思っていたけど、違うのか？？&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Vagrant + Core OS + docker-composeのコードはこちら。&lt;a href=&quot;https://github.com/matsubo/coreos-vagrant&quot;&gt;https://github.com/matsubo/coreos-vagrant&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;% vagrant up&lt;/code&gt;するだけで、container内にnginxが立ち上がり、80番ポートで参照できます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/04/Screenshot_4_9_15__15_08.png&quot; alt=&quot;Screenshot_4_9_15__15_08&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>スタートアップのためのドキュメントSaaS比較</title><link>https://blog.teraren.com/posts/document-tool-comparison/</link><guid isPermaLink="true">https://blog.teraren.com/posts/document-tool-comparison/</guid><description>スタートアップがドキュメント管理に使えるSaaSツールを実際に試して比較した一覧表。料金・階層構造・多言語対応・画像アップロードなどの機能を網羅的に評価しています。</description><pubDate>Mon, 23 Mar 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;スタートアップがドキュメントをまとめる場所を選定する際に参考になるASPの機能比較表を作りました！&lt;/li&gt;
&lt;li&gt;調査表をまとめるために、登録やテストで5時間ぐらいかかりました。&lt;/li&gt;
&lt;li&gt;ドキュメントツールの比較表はあまり出回っていないので、公開しておきます！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;比較&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/03/Screen-Shot-2015-03-23-at-22.27.42.png&quot; alt=&quot;Screen Shot 2015-03-23 at 22.27.42&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上記のテキストデータ&lt;/p&gt;
&lt;p&gt;Product&lt;/p&gt;
&lt;p&gt;Fee (10 ppl)&lt;/p&gt;
&lt;p&gt;Fee (15 ppl)&lt;/p&gt;
&lt;p&gt;Markup&lt;/p&gt;
&lt;p&gt;Page hierarchy&lt;/p&gt;
&lt;p&gt;i18n menu&lt;/p&gt;
&lt;p&gt;ASP?&lt;/p&gt;
&lt;p&gt;User management?&lt;/p&gt;
&lt;p&gt;Image upload&lt;/p&gt;
&lt;p&gt;Revision&lt;/p&gt;
&lt;p&gt;Mac app&lt;/p&gt;
&lt;p&gt;Android/iOS app&lt;/p&gt;
&lt;p&gt;2-step-auth&lt;/p&gt;
&lt;p&gt;SSL&lt;/p&gt;
&lt;p&gt;Comment&lt;/p&gt;
&lt;p&gt;Fast response?&lt;/p&gt;
&lt;p&gt;Full text search&lt;/p&gt;
&lt;p&gt;Web API&lt;/p&gt;
&lt;p&gt;Memo&lt;/p&gt;
&lt;p&gt;Confluence&lt;/p&gt;
&lt;p&gt;10 USD / month (100 USD /year)&lt;/p&gt;
&lt;p&gt;50 USD / month&lt;/p&gt;
&lt;p&gt;WYSIWYG (GFM by plugin)&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;REST API endpoint&lt;br /&gt;
Via plugin.&lt;/p&gt;
&lt;p&gt;Takes time to get used to WYSWYG and shortcut key.&lt;/p&gt;
&lt;p&gt;Google Sites&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;p&gt;WYSIWYG&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;Google Sites API&lt;/p&gt;
&lt;p&gt;https://support.google.com/a/answer/90917?hl=ja&lt;br /&gt;
x Not comportable UI&lt;br /&gt;
x No plugin&lt;br /&gt;
x Not optimized for document platform.&lt;br /&gt;
o Google drive direct integration&lt;br /&gt;
o Google account direct integration&lt;/p&gt;
&lt;p&gt;Qiita Team&lt;/p&gt;
&lt;p&gt;6,900 JPY/month&lt;/p&gt;
&lt;p&gt;15000 JPY/month&lt;/p&gt;
&lt;p&gt;Markdown&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;Slack、HipChat、ChatWork&lt;/p&gt;
&lt;p&gt;Can&apos;t make page tree. It&apos;s critical for a large document base.&lt;/p&gt;
&lt;p&gt;Pukiwiki + Markdown plugin&lt;/p&gt;
&lt;p&gt;3000 JPY/month&lt;/p&gt;
&lt;p&gt;3000 JPY/month&lt;/p&gt;
&lt;p&gt;Pukiwiki (Markdown plugin)&lt;/p&gt;
&lt;p&gt;Yes&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Old and low editor and coding functionality. No user management.&lt;/p&gt;
&lt;p&gt;Zoho Wiki&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;WYSWYG&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;UI is old.&lt;/p&gt;
&lt;p&gt;IGLOO&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;yes&lt;/p&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Looks like blog.&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;**Confluenceにしました！**決め手は、高機能で細かいユーザ管理ができること。そして、お財布にやさしい。&lt;/li&gt;
&lt;li&gt;Google sitesは機能要件的には問題ないのですが、使いづらいし、見た目が美しくないというちょっと残念な感じです。&lt;/li&gt;
&lt;li&gt;Qiita Teamは、ドキュメントの構造化が弱い感じです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;※ 主観や、網羅されていないことがあるかもしれないのであしからず。&lt;/p&gt;
</content:encoded></item><item><title>Vagrant + Docker provisioning</title><link>https://blog.teraren.com/posts/vagrant-docker-provisioning/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vagrant-docker-provisioning/</guid><description>Vagrant + Docker provisioning</description><pubDate>Tue, 10 Mar 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Vagrantには、&lt;a href=&quot;https://developer.hashicorp.com/vagrant/docs/provisioning&quot;&gt;provisioning&lt;/a&gt;という仕組みがあり、Vagrant（VirtualBox）のVMライフサイクルとVMホスト上で動くVMやコンテナのライフサイクルを簡単に管理できる仕組みがある&lt;/li&gt;
&lt;li&gt;Provisioningを使わないでDockerを管理するとなると、VMのライフサイクル毎に、コンテナのビルドやスタート、クリーンナップを自分で書かなければいけない&lt;/li&gt;
&lt;li&gt;Provisioningを使うことで、必要最低限のコードを書くだけで済む。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;コードはこちらに置いてあります。 &lt;a href=&quot;https://github.com/matsubo/vagrant-docker-provisioning/&quot;&gt;https://github.com/matsubo/vagrant-docker-provisioning/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;デモ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;こんな感じで、2回目以降の起動は30秒でコンテナが起動します。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;おまけ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ほぼ同等のインフラを構築する、boot2docker + Docker composeも作ってみました。 -boo2dockerがNFSマウントに対応していないので、コンテナからローカルファイルシステムの参照が10倍遅いです。。。&lt;/li&gt;
&lt;li&gt;Vagrant + Docker provision の方が起動が速い感じです。 &lt;a href=&quot;https://github.com/matsubo/docker-compose&quot;&gt;https://github.com/matsubo/docker-compose&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>WordPressをcronで自動更新。1日おきに最新に！</title><link>https://blog.teraren.com/posts/wordpress-update-script/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-update-script/</guid><description>クラック被害をきっかけに、wp-cliを使ってWordPress本体・プラグイン・テーマをcronで自動更新するシェルスクリプトを作成。10サイトを一括管理する方法を紹介。</description><pubDate>Fri, 27 Feb 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;WordPressは&lt;a href=&quot;https://w3techs.com/technologies/overview/content_management&quot;&gt;世界で最も使われているCMS&lt;/a&gt;で、それゆえに攻撃対象にもなりやすい。プラグインやテーマは開発者が自由にコードを書けるので脆弱性を含みやすく、脆弱性を突かれるとOSレベルで乗っ取られる可能性もある。&lt;/p&gt;
&lt;p&gt;実際に自分のサイトもクラックされた経験がある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WordPressのプラグインか何かの脆弱性を突かれて、WordPressがクラックされてしまった
&lt;ul&gt;
&lt;li&gt;バックドアのファイルをあちこちに置かれた。&lt;/li&gt;
&lt;li&gt;アクセスログからの進入経路は特定できなかった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;もともと、WordPress管理画面からプラグインを簡単に更新できるように、WordPressのディレクトリ自体をwritableにして運用していた。
&lt;ul&gt;
&lt;li&gt;プラグインのインストールや、WordPress自体の更新をWebから出来るので便利だが、クラックされたら、バックドアを仕掛けられまくって大変！&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;なぜWordPress自体の自動更新機能を使わないか&lt;/h2&gt;
&lt;p&gt;WordPress自体にはプラグインやテーマを自動で更新する機能があるが、php-fpmまたはApacheが動いているユーザによる書き込み権限が必要になるので利用を避けたい。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP自体のセキュリティ脆弱性を突かれた場合、WordPressの書き込み権限があるディレクトリが多すぎて影響が広くなってしまう。&lt;/li&gt;
&lt;li&gt;経験上、WordPressのテーマやプラグインの脆弱性を突かれた場合はバックドアとなるファイルを設置しようとする傾向が多い。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;そこで、wp-cliを使ってコマンドラインから更新し、Webサーバのプロセスには必要最小限の書き込み権限だけを与えるアプローチを取る。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WordPressサイトを10個ぐらい運用しているので、手動で更新が大変だった。&lt;/li&gt;
&lt;li&gt;記事投稿に必要な &lt;code&gt;wp-content/uploads&lt;/code&gt; ディレクトリだけをwritableにして、プラグインとWordPressを最新状態にキープできるようにする。&lt;/li&gt;
&lt;li&gt;wp-cliを使ってcronで自動更新する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最新を使い続けることによって不安定なバージョンのプログラムを利用してしまう可能性がある。そこはトレードオフになるので、ダウンタイム無しで行いたければステージング環境を用意して、最新に更新してからサイトがちゃんと稼働しているかテストした後に本番環境に反映するワークフローにすることをおすすめする。&lt;/p&gt;
&lt;h2&gt;wp-cliのインストール&lt;/h2&gt;
&lt;p&gt;Mac OSの場合は以下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% brew install wp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Linux等の場合はcurlでインストールできる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
% chmod +x wp-cli.phar
% sudo mv wp-cli.phar /usr/local/bin/wp
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;動作確認&lt;/h3&gt;
&lt;p&gt;wpコマンドを実行して実際に更新が行われるかチェックする。
以下のコマンドを実行するとユーザへの確認無しにファイルが更新されるので注意。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cd /path/to/wordpress
% wp plugin update --all
% wp theme update --all
% wp core update &amp;amp;&amp;amp; wp core update-db
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;更新スクリプト&lt;/h2&gt;
&lt;p&gt;これを、cronで1日1回とか動かせば、WordPress本体、プラグイン、テーマを自動的に最新にできる。1ホストに複数のWordPressがホスティングされていても対応できるようになっているので、適宜ディレクトリを増減して調整する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/zsh
# -------------------------------------
# Usage: % ./wordpress_update.sh
# Author: Yuki Matsukura
# -------------------------------------

# to be strict syntax checker
set -e

# set low priority
renice -n 19 $

WPS=(
  &quot;/path/to/wordpress1/&quot;
  &quot;/path/to/wordpress2/&quot;
)

for i in $WPS
do
  echo &quot;Processing: $i&quot;
  cd $i

  echo &quot;Upgrading plugins.&quot;
  wp plugin update --all

  echo &quot;Upgrading themes.&quot;
  wp theme update --all

  echo &quot;Upgrading WordPress.&quot;
  wp core update &amp;amp;&amp;amp; wp core update-db
done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/matsubo/159ba160581ff53fce09#file-wordpress_update-sh&quot;&gt;https://gist.github.com/matsubo/159ba160581ff53fce09#file-wordpress_update-sh&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;cronの設定&lt;/h2&gt;
&lt;p&gt;自動でスクリプトが実行されるようにcronに登録する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% crontab -e
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;1日に1回、21時15分に更新する例。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;15 21 * * * /path/to/wordpress_update.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;8年間、10サイトの運用をしているが問題なく稼働している。&lt;/li&gt;
&lt;li&gt;この設定により、&lt;code&gt;wp-content/uploads&lt;/code&gt; のみにWebサーバの書き込み権限を与えるという限定的な設定にできる。WordPress管理画面からプラグインの削除やインストールはできなくなるが、安全性を考えれば許容範囲。&lt;/li&gt;
&lt;li&gt;脆弱性を突かれてバックドアを設置されるリスクを大幅に下げられる。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>郵便番号から住所をAPIで取得</title><link>https://blog.teraren.com/posts/postcode-api/</link><guid isPermaLink="true">https://blog.teraren.com/posts/postcode-api/</guid><description>郵便番号から住所をAPIで取得</description><pubDate>Wed, 11 Feb 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;郵便番号から住所コードを検索するREST APIサービス作りました。&lt;br /&gt;
&lt;a href=&quot;https://postcode.teraren.com/&quot;&gt;https://postcode.teraren.com/&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;サンプル&lt;/h3&gt;
&lt;p&gt;以下のようなURLで住所情報を取得出来ます。&lt;br /&gt;
JSON&lt;br /&gt;
&lt;a href=&quot;https://postcode.teraren.com/postcodes/1600023.json&quot;&gt;https://postcode.teraren.com/postcodes/1600023.json&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;HTML&lt;br /&gt;
&lt;a href=&quot;https://postcode.teraren.com/postcodes/1600023&quot;&gt;https://postcode.teraren.com/postcodes/1600023&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/02/Screen-Shot-2015-02-11-at-18.43.02.png&quot; alt=&quot;GTmatrix&quot; /&gt;&lt;/p&gt;
&lt;p&gt;GTmatrixにもA評価出るようにチューニングしました。評価が悪い指標は、外部サイトのスクリプト読み込みです。&lt;/p&gt;
</content:encoded></item><item><title>SSLサイト運営者は一度確認した方がいい事</title><link>https://blog.teraren.com/posts/openssl-sha1-csr-hash/</link><guid isPermaLink="true">https://blog.teraren.com/posts/openssl-sha1-csr-hash/</guid><description>opensslのCSRハッシュアルゴリズムがSHA1になっていないか確認する方法と、SHA-256でCSRを安全に作り直す手順を解説</description><pubDate>Fri, 06 Feb 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;こちらの件。世の中騒がれて居なさすぎだなぁと思ってます。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://postd.cc/why-google-is-hurrying-the-web-to-kill-sha-1/&quot;&gt;【翻訳】GoogleがWebでのSHA-1の利用停止を急ぐ理由&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;要約：CSRの一方向ハッシュのアルゴリズムが脆弱だと、偽証明書の偽造リスクが高いですよ。&lt;/li&gt;
&lt;li&gt;世の中の9割が未対応。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;opensslがデフォルトで作成するCSRはSHA1を使っています。そのため、Web上のほとんどのドキュメントはハッシュアルゴリズムオプションは指定していないので、デフォルトのSHA1が使われてしまっています。
&lt;ul&gt;
&lt;li&gt;特に、&lt;a href=&quot;http://www.ssl.ph/help/manual/contents01.html&quot;&gt;この&lt;/a&gt;CSR作成サービスとかは、MD5を使っていて、かなりやばいかも。&lt;/li&gt;
&lt;li&gt;そもそも、CSR作成してもらうと言うことは、秘密鍵の安全性の担保が自分の責任の範囲内で管理出来ないと思うけど。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;CSRハッシュアルゴリズム確認方法&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;ちょっと判定結果が怪しいけど、簡易的には以下で調べられます。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&quot;https://shaaaaaaaaaaaaa.com/&quot;&gt;https://shaaaaaaaaaaaaa.com/&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;CSRファイルから調べる&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;% openssl req -in server.csr -text | grep Signature
    Signature Algorithm: sha1WithRSAEncryption
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この結果が、sha1だったら、ちょっと危険。MD5なら、かなり危険。&lt;/p&gt;
&lt;h2&gt;SHA-256でCSRを作る方法&lt;/h2&gt;
&lt;p&gt;秘密鍵作って、CSR作る一通りの手順。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% openssl genrsa -rand /tmp/random -des3 2048 -o server.key
% openssl req -new -sha256 -key server.key -out server.csr
% openssl req -in server.csr -text | grep Signature
    Signature Algorithm: sha256WithRSAEncryption
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://news.netcraft.com/archives/2014/05/05/sha-2-very-cryptographic-so-secure-such-growth-wow.html&quot;&gt;http://news.netcraft.com/archives/2014/05/05/sha-2-very-cryptographic-so-secure-such-growth-wow.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://support.servertastic.com/deprecation-of-sha1-and-moving-to-sha2/&quot;&gt;https://support.servertastic.com/deprecation-of-sha1-and-moving-to-sha2/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>銀行コード、支店コードをAPIで取得</title><link>https://blog.teraren.com/posts/japanese-bank-code-branch-code-api/</link><guid isPermaLink="true">https://blog.teraren.com/posts/japanese-bank-code-branch-code-api/</guid><description>金融機関コードと支店コードをJSON形式で検索できるREST APIをRailsで自作し、公開するまでの背景と使い方を紹介</description><pubDate>Sun, 01 Feb 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/advent-calendar/2015/web_api&quot;&gt;Web API Advent Calendar&lt;/a&gt; 12月4日分です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;金融機関コードを検索できるWeb APIが存在していませんでした。&lt;/li&gt;
&lt;li&gt;金融機関コードを検索するREST APIをRailsで作りました。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/&quot;&gt;https://bank.teraren.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/02/Screenshot_2_1_15__19_48-2.png&quot; alt=&quot;Japanese bank code&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;サンプル&lt;/h2&gt;
&lt;p&gt;いくつかAPIの例を載せておきます。&lt;/p&gt;
&lt;h3&gt;銀行情報取得&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;JSON
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/banks/8457.json&quot;&gt;https://bank.teraren.com/banks/8457.json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTML
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/banks/8457&quot;&gt;https://bank.teraren.com/banks/8457&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;支店情報取得&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;JSON
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/banks/8457/branches/028.json&quot;&gt;https://bank.teraren.com/banks/8457/branches/028.json&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTML
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/banks/8457/branches/028&quot;&gt;https://bank.teraren.com/banks/8457/branches/028&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;銀行名称から銀行一覧を取得する&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;JSON
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/banks/search.json?name=%E6%9D%B1%E4%BA%AC&quot;&gt;https://bank.teraren.com/banks/search.json?name=東京&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/banks/search.json?kana=%E3%83%88%E3%82%A6%E3%82%AD%E3%83%A7%E3%82%A6&quot;&gt;https://bank.teraren.com/banks/search.json?kana=トウキョウ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTML
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/banks/search?name=%E6%9D%B1%E4%BA%AC&quot;&gt;https://bank.teraren.com/banks/search?name=東京&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/banks/search?kana=%E3%83%88%E3%82%A6%E3%82%AD%E3%83%A7%E3%82%A6&quot;&gt;https://bank.teraren.com/banks/search?kana=トウキョウ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;支店名称から支店名を取得する&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;JSON
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/banks/0001/branches/search.json?name=%E6%9D%B1%E4%BA%AC&quot;&gt;https://bank.teraren.com/banks/0001/branches/search.json?name=東京&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;HTML
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bank.teraren.com/banks/0001/branches/search?name=%E6%9D%B1%E4%BA%AC&quot;&gt;https://bank.teraren.com/banks/0001/branches/search?name=東京&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;詳しくは&lt;a href=&quot;https://bank.teraren.com/doc&quot;&gt;ドキュメント&lt;/a&gt;をご参照ください。&lt;/p&gt;
&lt;h2&gt;構成・工夫点とか&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ソフトウェア構成
&lt;ul&gt;
&lt;li&gt;Ruby 2.3 + Rails 4.2 + Unicorn + Capistrano&lt;/li&gt;
&lt;li&gt;開発環境にDocker (&lt;a href=&quot;/posts/docker-rails-vagrant/&quot;&gt;参考資料&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;サーバ
&lt;ul&gt;
&lt;li&gt;TLS&lt;/li&gt;
&lt;li&gt;HTTP2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GTMatrixで&lt;a href=&quot;https://gtmetrix.com/reports/bank.teraren.com/VtjqN4mX&quot;&gt;Grade A&lt;/a&gt;を取れるようにUI周りをチューニングしました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.google.co.jp/analytics/tag-manager/&quot;&gt;Google Tag Manager&lt;/a&gt;でタグ管理を外部化&lt;/li&gt;
&lt;li&gt;ROA, REST&lt;/li&gt;
&lt;li&gt;Responsive design&lt;/li&gt;
&lt;li&gt;I18n 国際化 (&lt;a href=&quot;https://bank.teraren.com/?lang=en&quot;&gt;en&lt;/a&gt;, &lt;a href=&quot;https://bank.teraren.com/?lang=ja&quot;&gt;ja&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;URLは昔ですが、2015年12月にリバイズや機能を追加しました。&lt;/li&gt;
&lt;li&gt;利用者がそこそこいらっしゃるようなので、データ更新機能作ります。&lt;/li&gt;
&lt;li&gt;ちなみに、この&lt;a href=&quot;https://ec.teraren.com/bank-code-rest-server/&quot;&gt;コードは販売中&lt;/a&gt;です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;TIPS: ブラウザでJSONを見やすくする&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/json-formatter/bcjindcccaagfpapjjmafapmmgkkhgoa?hl=en&quot;&gt;JSON Formatter&lt;/a&gt; などのJSON整形用プラグインを入れておくと動作確認しやすいです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/12/img_5660613492c64.png&quot; alt=&quot;json formatter&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2019/10/9 毎日、最新のマスタ情報で更新するようにしました。&lt;/p&gt;
</content:encoded></item><item><title>an unknown error occurred 54→新品交換</title><link>https://blog.teraren.com/posts/an-unknown-error-occurred-54/</link><guid isPermaLink="true">https://blog.teraren.com/posts/an-unknown-error-occurred-54/</guid><description>an unknown error occurred 54→新品交換</description><pubDate>Sat, 31 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;iOS 8.1.3にアップグレード中に、iPhone6が起動しなくなりました。&lt;/p&gt;
&lt;p&gt;iTunesには &lt;code&gt;an unknown error occurred 54&lt;/code&gt; と出てました。ググっても類似案件はありませんでした。&lt;/p&gt;
&lt;p&gt;DFUモードも試しましたが、駄目でした。&lt;/p&gt;
&lt;p&gt;Appleのサポートに持って行ったら、すんなりと新品交換になりました〜！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/01/Screenshot_1_29_15__00_19_1.png&quot; alt=&quot;restoring iphone firmware&quot; /&gt;&lt;/p&gt;
&lt;p&gt;restoring iphone firmware&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/01/Camera_1_28_15__23_10_1.jpg&quot; alt=&quot;Camera_1_28_15__23_10_1&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Dockerを使って、vagrant upするだけで面倒なRailsの開発環境を瞬時に構築</title><link>https://blog.teraren.com/posts/docker-rails-vagrant/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-rails-vagrant/</guid><description>VagrantとDockerを組み合わせてRuby on Rails開発環境を自動構築し、2回目以降は30秒で起動できる仕組みを解説</description><pubDate>Sun, 04 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vagrant up&lt;/code&gt; 一発でRuby on Railsの開発環境を構築出来るようにしました。&lt;/li&gt;
&lt;li&gt;ローカルのファイルシステムをDocker上のアプリケーションサーバから参照しているので好きなテキストエディタを使えます。&lt;/li&gt;
&lt;li&gt;すぐにRailsで開発を行えます。カスタマイズしたい場合はForkして頂くのがいいと思います。&lt;/li&gt;
&lt;li&gt;dockerあれば、chef使わなくて良いですね。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;初期設定&lt;/h2&gt;
&lt;p&gt;VirtualBox用のVMイメージをダウンロードします。（任意）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% vagrant box add precise64 http://files.vagrantup.com/precise64.box
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;あとは、サンプルコードをcloneして&lt;code&gt;vagrant up&lt;/code&gt;するだけです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;初回は30分程度かかります。
&lt;ul&gt;
&lt;li&gt;Docker imageのダウンロードとimageの構築があるので。&lt;/li&gt;
&lt;li&gt;これでも、Containerのベースは1つにしてあるので、ダウンロード時間は短くするようにしています。&lt;/li&gt;
&lt;li&gt;UbuntuのCDNが遅いというのも1つの要因ではあります。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2回目以降は30秒程度でコンテナが起動します。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% git clone git@github.com:matsubo/docker_rails_dev_env_example.git
% cd docker_rails_dev_env_example
% vagrant up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://localhost:3000/&quot;&gt;http://localhost:3000/&lt;/a&gt; へアクセスすると以下のような表示が出るはずです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/01/Screen-Shot-2015-01-04-at-00.14.55.png&quot; alt=&quot;Screen Shot 2015-01-04 at 00.14.55&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;主な使い方&lt;/h2&gt;
&lt;h3&gt;VMの停止&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% vagrant halt
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;VMの起動&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% vagrant up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2回目以降は、以下のように35秒でVM、コンテナが起動します。&lt;br /&gt;
(MacBook Pro (Retina, Mid 2012)で計測)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/01/Screen-Shot-2015-01-04-at-00.52.20.png&quot; alt=&quot;Screen Shot 2015-01-04 at 00.52.20&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;主なソフトウェアのバージョン&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ruby 2.2 + Ruby on Rails 4.2&lt;/li&gt;
&lt;li&gt;MySQL 5.6&lt;/li&gt;
&lt;li&gt;Redis 2.8&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;良い点・悪い点&lt;/h2&gt;
&lt;h3&gt;良い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;VirtualBoxとVagrantだけあれば、容易にプロジェクト毎に統一された開発環境を構築出来る。&lt;/li&gt;
&lt;li&gt;2回目以降の起動が高速&lt;/li&gt;
&lt;li&gt;ローカルのファイルシステム上のファイルを変更して、即時プレビュー出来るので好きなエディタで開発出来る。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;悪い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Gemfileを更新したら、
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;./d rebuild&lt;/code&gt;してrailsのイメージを再構築する必要があり、bundle installをゼロから行うため時間が4分ぐらいかかる。&lt;/li&gt;
&lt;li&gt;手元のホストでもコマンドを直接打つためにbundle installしないといけない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;開発者がDockerの使い方を知る必要がある&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;その他&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;レポジトリ： &lt;a href=&quot;https://github.com/matsubo/docker_rails_dev_env_example&quot;&gt;https://github.com/matsubo/docker_rails_dev_env_example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ドキュメントは&lt;a href=&quot;https://github.com/matsubo/docker_rails_dev_env_example#rails-development-using-docker&quot;&gt;README.md&lt;/a&gt;に細かく記載してあります。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/docker_rails_dev_env_example/blob/master/Vagrantfile&quot;&gt;Vagrantfile&lt;/a&gt;がエントリーポイントになるので、このファイルから追っていけると思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.talkingquickly.co.uk/2014/06/rails-development-environment-with-vagrant-and-docker/&quot;&gt;http://www.talkingquickly.co.uk/2014/06/rails-development-environment-with-vagrant-and-docker/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://qiita.com/cieux1@github/items/b2294f8adddefb357a37&quot;&gt;http://qiita.com/cieux1@github/items/b2294f8adddefb357a37&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;これを/etc/sudoersに入れれば、パスワードを聞いてこないように出来る
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mitchellh/vagrant/blob/master/contrib/sudoers/osx&quot;&gt;https://github.com/mitchellh/vagrant/blob/master/contrib/sudoers/osx&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>vagrant upだけでRailsの開発環境を構築</title><link>https://blog.teraren.com/posts/qiita-20150104-ee484f8a7e8b04083317/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20150104-ee484f8a7e8b04083317/</guid><description>（任意）VirtualBox 用のイメージをダウンロードします。</description><pubDate>Sun, 04 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;vagrant up&lt;/code&gt; 一発で Ruby on Rails の開発環境を構築出来るようにしました。&lt;/li&gt;
&lt;li&gt;ドキュメントは &lt;a href=&quot;https://github.com/matsubo/docker_rails_dev_env_example#rails-development-using-docker&quot;&gt;README.md&lt;/a&gt;に細かく記載してあります。&lt;/li&gt;
&lt;li&gt;&apos;&apos; 今は、docker-compose を使った方がスマートに出来ると思います &apos;&apos;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;初期設定&lt;/h2&gt;
&lt;p&gt;（任意）VirtualBox 用のイメージをダウンロードします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% vagrant box add precise64 http://files.vagrantup.com/precise64.box
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;サンプルコードをcloneして &lt;code&gt;vagrant up&lt;/code&gt; するだけです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;初回は30分程度かかります。
&lt;ul&gt;
&lt;li&gt;Docker imageのダウンロードとimageの構築があるので。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2回目以降は30秒程度でコンテナが起動します。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% git clone git@github.com:matsubo/docker_rails_dev_env_example.git
% cd docker_rails_dev_env_example
% vagrant up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;http://localhost:3000/へアクセスすると以下のような表示が出るはずです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/01/Screen-Shot-2015-01-04-at-00.14.55.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;主な使い方&lt;/h2&gt;
&lt;h3&gt;VMの停止&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% vagrant halt
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;VMの起動&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% vagrant up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2 回目以降は、以下のように 35 秒で VM、コンテナが起動します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2015/01/Screen-Shot-2015-01-04-at-00.52.20.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;主なソフトウェアのバージョン&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ruby 2.2 + Ruby on Rails 4.2&lt;/li&gt;
&lt;li&gt;MySQL 5.6&lt;/li&gt;
&lt;li&gt;Redis 2.8&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;良い点・悪い点&lt;/h2&gt;
&lt;h3&gt;良い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;VirtlaBox と Vagrant だけあれば、容易にプロジェクト毎に統一された開発環境を構築出来る。&lt;/li&gt;
&lt;li&gt;2 回目以降の起動が高速&lt;/li&gt;
&lt;li&gt;ローカルのファイルシステム上のファイルを変更して、即時プレビュー出来るので好きなエディタで開発出来る。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;悪い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;開発者が Docker の使い方を知る必要がある&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参考資料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;http://www.talkingquickly.co.uk/2014/06/rails-development-environment-with-vagrant-and-docker/&lt;/li&gt;
&lt;li&gt;http://qiita.com/cieux1@github/items/b2294f8adddefb357a37&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Quoted from: https://blog.teraren.com/2015/01/04/docker-rails-vagrant/&lt;/p&gt;
</content:encoded></item><item><title>Enable &quot;Ignore ownership on this volume&quot;</title><link>https://blog.teraren.com/posts/ignore-ownership/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ignore-ownership/</guid><description>Enable &quot;Ignore ownership on this volume&quot;</description><pubDate>Fri, 02 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;外付けのRAIDドライブのパーミッションが無効になっていて、全員がReadable/Writableな状態でした。&lt;/p&gt;
&lt;p&gt;問題は、マウントされているVolumeを右クリックして表示される&lt;br /&gt;
Ignore ownership on this volume&lt;br /&gt;
にチェックが入っていたためです。&lt;/p&gt;
&lt;p&gt;チェックを外したくても、項目が無効化されているので外せませんでした。&lt;/p&gt;
&lt;p&gt;結局は、&lt;a href=&quot;http://forums.macrumors.com/showthread.php?t=857092&quot;&gt;これ&lt;/a&gt;やったら、直りました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo /usr/sbin/vsdbutil -a /Volumes/LeslieMacBackup
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>launchctlでCould not find domain forエラー</title><link>https://blog.teraren.com/posts/launchctl-could-not-find-domain-for-error/</link><guid isPermaLink="true">https://blog.teraren.com/posts/launchctl-could-not-find-domain-for-error/</guid><description>launchctlでCould not find domain forエラー</description><pubDate>Mon, 03 Nov 2014 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;% launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
Could not find domain for
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yosemitaに上げたタイミングで無効にしていた無線LANが動き出してしまい、1ホストに2つのIPが振られた状態だと上記のエラーが出る模様。&lt;br /&gt;
再度無線LANを無効にしたら立ち上がった。&lt;/p&gt;
</content:encoded></item><item><title>IDC Frontierのクラウドを使ってみた</title><link>https://blog.teraren.com/posts/idc-frontier-cloud/</link><guid isPermaLink="true">https://blog.teraren.com/posts/idc-frontier-cloud/</guid><description>IDC FrontierのIaaS/PaaSサービスを実際に試し、Nginxを使ったHTTPベンチマーク結果やDockerを使った環境構築の所感をレポートします。</description><pubDate>Thu, 16 Oct 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.idcf.jp/cloud/&quot;&gt;IDC Frontierが新たなPaaSを開始しました。&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;とりあえず、インスタンスを2台立ち上げて、LBで振ってあります。数日間立ち上げておくので適当にテストしてもらってかまいません。&lt;br /&gt;
&lt;a href=&quot;http://210.140.168.217/&quot;&gt;http://210.140.168.217/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Nginxベンチマーク&lt;/h2&gt;
&lt;p&gt;Ubuntuを一番安いlight.S1で立ち上げて、nginxにリモートからabしてみました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/10/9f487004bec6f340abb717994e4f68251.png&quot; alt=&quot;IDCFクラウド&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[yuki_matsukura@matsukura ~]% ab -c 40 -n 1000 http://210.140.168.217/
This is ApacheBench, Version 2.3 &amp;lt;$Revision: 655654 $&amp;gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 210.140.168.217 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        nginx/1.4.6
Server Hostname:        210.140.168.217
Server Port:            80

Document Path:          /
Document Length:        612 bytes

Concurrency Level:      40
Time taken for tests:   2.528 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      853000 bytes
HTML transferred:       612000 bytes
Requests per second:    395.64 [#/sec] (mean)
Time per request:       101.103 [ms] (mean)
Time per request:       2.528 [ms] (mean, across all concurrent requests)
Transfer rate:          329.57 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       20   60 172.1     33    1189
Processing:    19   40  44.6     34     379
Waiting:       19   40  44.6     34     379
Total:         41  100 176.5     68    1221

Percentage of the requests served within a certain time (ms)
  50%     68
  66%     71
  75%     74
  80%     76
  90%     88
  95%    106
  98%   1196
  99%   1214
 100%   1221 (longest request)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/10/9f487004bec6f340abb717994e4f6825.png&quot; alt=&quot;IDCFクラウド&quot; /&gt;&lt;/p&gt;
&lt;p&gt;今度は、Cent OSも立ち上げて、ロードバランサで2台に振り分けてみました。&lt;br /&gt;
だいたい1.5倍になってます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[yuki_matsukura@matsukura ~]% ab -c 40 -n 1000 http://210.140.168.217/
This is ApacheBench, Version 2.3 &amp;lt;$Revision: 655654 $&amp;gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 210.140.168.217 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        nginx/1.4.6
Server Hostname:        210.140.168.217
Server Port:            80

Document Path:          /
Document Length:        612 bytes

Concurrency Level:      40
Time taken for tests:   1.653 seconds
Complete requests:      1000
Failed requests:        545
   (Connect: 0, Receive: 0, Length: 545, Exceptions: 0)
Write errors:           0
Total transferred:      851910 bytes
HTML transferred:       615815 bytes
Requests per second:    605.09 [#/sec] (mean)
Time per request:       66.106 [ms] (mean)
Time per request:       1.653 [ms] (mean, across all concurrent requests)
Transfer rate:          503.40 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       15   35   6.7     36      52
Processing:    17   30   5.8     28      54
Waiting:       17   30   5.8     28      54
Total:         32   65   9.5     64      90

Percentage of the requests served within a certain time (ms)
  50%     64
  66%     66
  75%     69
  80%     70
  90%     81
  95%     84
  98%     86
  99%     87
 100%     90 (longest request)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;今度は、&lt;a href=&quot;https://code.google.com/p/byte-unixbench/&quot;&gt;unixbench&lt;/a&gt;を走らせてみました。&lt;br /&gt;
まぁ、スコアは低いですね。一番安いインスタンスなので。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@ubuntu:~/UnixBench# ./Run
make all
make[1]: Entering directory `/root/UnixBench&apos;
Checking distribution of files
./pgms  exists
./src  exists
./testdir  exists
./tmp  exists
./results  exists
make[1]: Leaving directory `/root/UnixBench&apos;
sh: 1: 3dinfo: not found

   #    #  #    #  #  #    #          #####   ######  #    #   ####   #    #
   #    #  ##   #  #   #  #           #    #  #       ##   #  #    #  #    #
   #    #  # #  #  #    ##            #####   #####   # #  #  #       ######
   #    #  #  # #  #    ##            #    #  #       #  # #  #       #    #
   #    #  #   ##  #   #  #           #    #  #       #   ##  #    #  #    #
    ####   #    #  #  #    #          #####   ######  #    #   ####   #    #

   Version 5.1.3                      Based on the Byte Magazine Unix Benchmark

   Multi-CPU version                  Version 5 revisions by Ian Smith,
                                      Sunnyvale, CA, USA
   January 13, 2011                   johantheghost at yahoo period com

1 x Dhrystone 2 using register variables  1 2 3 4 5 6 7 8 9 10
1 x Double-Precision Whetstone  1 2 3 4 5 6 7 8 9 10
1 x Execl Throughput  1 2 3
1 x File Copy 1024 bufsize 2000 maxblocks  1 2 3
1 x File Copy 256 bufsize 500 maxblocks  1 2 3
1 x File Copy 4096 bufsize 8000 maxblocks  1 2 3
1 x Pipe Throughput  1 2 3 4 5 6 7 8 9 10
1 x Pipe-based Context Switching  1 2 3 4 5 6 7 8 9 10
1 x Process Creation  1 2 3
1 x System Call Overhead  1 2 3 4 5 6 7 8 9 10
1 x Shell Scripts (1 concurrent)  1 2 3
1 x Shell Scripts (8 concurrent)  1 2 3

========================================================================
   BYTE UNIX Benchmarks (Version 5.1.3)

   System: ubuntu.cs9bidcfcloud.internal: GNU/Linux
   OS: GNU/Linux -- 3.13.0-33-generic -- #58-Ubuntu SMP Tue Jul 29 16:45:05 UTC 2014
   Machine: x86_64 (x86_64)
   Language: en_US.utf8 (charmap=&quot;UTF-8&quot;, collate=&quot;UTF-8&quot;)
   CPU 0: Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz (5600.0 bogomips)
          x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET
   13:24:59 up 14 min,  1 user,  load average: 0.45, 0.32, 0.16; runlevel 2

------------------------------------------------------------------------
Benchmark Run: Thu Oct 16 2014 13:24:59 - 13:54:07
1 CPU in system; running 1 parallel copy of tests

Dhrystone 2 using register variables       11495081.0 lps   (10.1 s, 7 samples)
Double-Precision Whetstone                     1152.3 MWIPS (12.5 s, 7 samples)
Execl Throughput                                859.0 lps   (30.0 s, 2 samples)
File Copy 1024 bufsize 2000 maxblocks        190024.7 KBps  (30.0 s, 2 samples)
File Copy 256 bufsize 500 maxblocks           51179.9 KBps  (30.1 s, 2 samples)
File Copy 4096 bufsize 8000 maxblocks        607544.0 KBps  (30.1 s, 2 samples)
Pipe Throughput                              319353.0 lps   (10.1 s, 7 samples)
Pipe-based Context Switching                  79657.9 lps   (10.0 s, 7 samples)
Process Creation                               3534.8 lps   (30.1 s, 2 samples)
Shell Scripts (1 concurrent)                   1887.4 lpm   (60.1 s, 2 samples)
Shell Scripts (8 concurrent)                    252.3 lpm   (60.2 s, 2 samples)
System Call Overhead                         222390.2 lps   (10.1 s, 7 samples)

System Benchmarks Index Values               BASELINE       RESULT    INDEX
Dhrystone 2 using register variables         116700.0   11495081.0    985.0
Double-Precision Whetstone                       55.0       1152.3    209.5
Execl Throughput                                 43.0        859.0    199.8
File Copy 1024 bufsize 2000 maxblocks          3960.0     190024.7    479.9
File Copy 256 bufsize 500 maxblocks            1655.0      51179.9    309.2
File Copy 4096 bufsize 8000 maxblocks          5800.0     607544.0   1047.5
Pipe Throughput                               12440.0     319353.0    256.7
Pipe-based Context Switching                   4000.0      79657.9    199.1
Process Creation                                126.0       3534.8    280.5
Shell Scripts (1 concurrent)                     42.4       1887.4    445.1
Shell Scripts (8 concurrent)                      6.0        252.3    420.5
System Call Overhead                          15000.0     222390.2    148.3
                                                                   ========
System Benchmarks Index Score                                         341.9
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;注意&lt;/h2&gt;
&lt;p&gt;外からSSHするためにはfirwallとportfowardを設定する必要が有ります。&lt;br /&gt;
インスタンスは、デフォルトでVPC内に作られる様子。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/10/9f487004bec6f340abb717994e4f68252.png&quot; alt=&quot;IDCFクラウド&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Mackerel連携&lt;/h2&gt;
&lt;p&gt;インスタンスにエージェントを入れて、Mackerel連携してみました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/10/9ed81c22349094f79627062fe211d30d.png&quot; alt=&quot;web_·_IDC-Frontier_and_1__zsh&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/10/e1e55b8195391fbb9b65384db1a2005f.png&quot; alt=&quot;IDC-Frontier’s_Dashboard_·IDC-Frontier_and_1__root_ubuntu_____ssh&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1時間1円・月額500円～ は、安いっすね&lt;/li&gt;
&lt;li&gt;CloudStackAPIのUserAPI（Public）をベースとしたAPIも使えるので、連携出来そう。&lt;/li&gt;
&lt;li&gt;Core OSのインスタンスも用意されています。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Dockerで開発環境管理</title><link>https://blog.teraren.com/posts/docker-dev-server/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-dev-server/</guid><description>EC-CUBEの複数バージョン動作確認を目的にDockerfileで開発環境を構築し、Docker Hubで管理する方法を解説</description><pubDate>Tue, 07 Oct 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;様々なバージョンのEC-CUBEを動作確認出来るDocker imageを作りました。&lt;br /&gt;
&lt;a href=&quot;https://github.com/matsubo/eccube-docker&quot;&gt;https://github.com/matsubo/eccube-docker&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;仕事で作っているプロダクトが、様々な環境で動作することを確認でき、開発者が簡単に運用できる状態を作りたい。&lt;/p&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;ざっくりと以下の手法が考えられる。もちろん排他的では無く、一部は組み合わせも可能。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VirtualBoxのVMを共有
&lt;ul&gt;
&lt;li&gt;EC2のAMIで保持&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dockerイメージ&lt;/li&gt;
&lt;li&gt;Dockerfile&lt;/li&gt;
&lt;li&gt;Vagrant&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今回は、「LAMP + EC-CUBEダウンロード」と、「簡単に起動して捨てられるようにしておきたい事」を優先してDockerfileでの管理を選ぶ。&lt;br /&gt;
（&lt;a href=&quot;https://hub.docker.com/r/matsubo/eccube&quot;&gt;Docker hubにも登録済み&lt;/a&gt;）&lt;/p&gt;
&lt;h2&gt;使い方&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;README
&lt;ul&gt;
&lt;li&gt;Docker hubからpullするより、buildした方がCDNからかき集められるので速いかと思います。&lt;br /&gt;
&lt;a href=&quot;https://github.com/matsubo/eccube-docker/blob/master/README.md&quot;&gt;https://github.com/matsubo/eccube-docker/blob/master/README.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上記のREADMEを行うためのスクリーンキャスト作ってみました。(iMovieの練習のために)&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/watch?v=ki0bbfwqgSg&lt;/p&gt;
&lt;p&gt;もし、Docker Imageに変更を加えたければ、上記のImageにどんどん変更を加えていけば良いです。Docker hubでバージョン管理されますし、Imageに変更を加えた差分だけをpullすることが出来るので2回目以降は低コストに差分を取り込むことが出来ます。&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Dockerは概念がちょっと複雑なので、慣れるまで大変でした。&lt;/li&gt;
&lt;li&gt;Vagrant + Dockerfile + Serverspec + CIで将来的にはTDD出来そうな気がする&lt;/li&gt;
&lt;li&gt;Docker hubとの接続が遅い&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>手っ取り早くDockerを動かしてみる方法</title><link>https://blog.teraren.com/posts/docker-quick/</link><guid isPermaLink="true">https://blog.teraren.com/posts/docker-quick/</guid><description>Mac OS XでVagrantとCore OSを使ってboot2dockerなしでDockerを動かす最短手順。コマンド数回でUbuntuコンテナを起動しnginxまで立ち上げる入門チュートリアル。</description><pubDate>Thu, 18 Sep 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;コマンド数回で&lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt;を動かせます。&lt;/li&gt;
&lt;li&gt;検証環境がカンタンに作れます&lt;/li&gt;
&lt;li&gt;Mac OS Xの場合は、boot2dockerを入れ無くても大丈夫です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;前提条件&lt;/h2&gt;
&lt;p&gt;Mac OS Xにて以下のソフトがインストールされていること。&lt;br /&gt;
（エンジニアなら入っているはず）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.virtualbox.org/wiki/Downloads&quot;&gt;Virtualbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://brew.sh/&quot;&gt;homebrew&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://git-scm.com/&quot;&gt;git&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Core OSをインストールして起動&lt;/h2&gt;
&lt;p&gt;Core OSを起動するためのVagrantファイルは既に存在しているので、それを拝借してきます。&lt;br /&gt;
イメージは394MBあるのでご注意を。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% brew install docker
% git clone git@github.com:coreos/coreos-vagrant.git
% cd coreos-vagrant
% vagrant up 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;コンテナを上げてみる&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% vagrant ssh
$ docker pull ubuntu:latest （最新版のコンテナイメージを取得）
$ docker run -it --name ubuntu1 ubuntu /bin/bash　（ubuntu1という名前で、ubuntuというコンテナイメージを元にコンテナを起動し、シェルに入る）
# apt-get update
# apt-get install nginx
# service nginx start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ctrl+p Ctrl+q&lt;/p&gt;
&lt;h2&gt;シャットダウン&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% vagrant halt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;また使いたければ、vagrant up するだけです。&lt;/p&gt;
</content:encoded></item><item><title>shellでmatrix</title><link>https://blog.teraren.com/posts/cmatrix/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cmatrix/</guid><description>shellでmatrix</description><pubDate>Wed, 17 Sep 2014 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;% brew install cmatrix
% cmatrix
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;video controls&amp;gt;&amp;lt;source src=&quot;/uploads/2014/09/cmatrix.mp4&quot; type=&quot;video/mp4&quot; /&amp;gt;&amp;lt;/video&amp;gt;&lt;/p&gt;
</content:encoded></item><item><title>panamaxを使ってみた</title><link>https://blog.teraren.com/posts/panamax-usage/</link><guid isPermaLink="true">https://blog.teraren.com/posts/panamax-usage/</guid><description>DockerコンテナをGUI管理できるPanamaxをMacにインストールし、WordPressをワンクリックで構築するまでの手順を紹介</description><pubDate>Fri, 12 Sep 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/09/3f320fab545357f7d2138403ce25df3c.png&quot; alt=&quot;Panamax__Docker_Management_for_Humans_and_WordPress_›_Installation&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.docker.com/&quot;&gt;docker&lt;/a&gt;の良い感じの管理ツールがあると聞いて使ってみました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/CenturyLinkLabs/panamax-ui/wiki/Installing-Panamax&quot;&gt;チュートリアルの動画&lt;/a&gt;が非常にわかりやすいので、時間がかかりますが一通り見るのが良いです。（英語ですが、たぶんわかると思います）&lt;/li&gt;
&lt;li&gt;まだUIやdockerの挙動が怪しい時がありますが、まぁ使ってみましょう。Dockerfileをがんばって書いていくより非常に簡単に1システムを構築できますよ！&lt;/li&gt;
&lt;li&gt;11人で1ヶ月で構築されたらしい。すごい！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% brew install http://download.panamax.io/installer/brew/panamax.rb
######################################################################## 100.0%
==&amp;gt; Downloading http://download.panamax.io/installer/pmx-installer-0.2.0.zip
######################################################################## 100.0%
Warning: If upgrading the Panamax Installer, be sure to run &apos;panamax reinstall&apos; to ensure compatibility with other Panamax components.
/usr/local/Cellar/panamax/0.2.0: 5 files, 28K, built in 2 seconds
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;panamax 起動&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% panamax init
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;███████╗ ██████╗  █████████╗ ██████╗  ██████████╗ ██████╗  ██╗  ██╗
██╔══██║  ╚═══██╗ ███╗  ███║  ╚═══██╗ ██║ ██╔ ██║  ╚═══██╗ ╚██╗██╔╝
██   ██║ ███████║ ███║  ███║ ███████║ ██║╚██║ ██║ ███████║  ╚███╔╝
███████╝ ███████║ ███║  ███║ ███████║ ██║╚██║ ██║ ███████║  ██╔██╗
██║      ███████║ ███║  ███║ ███████║ ██║╚██║ ██║ ███████║ ██╔╝ ██╗
╚═╝      ╚══════╝ ╚══╝  ╚══╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝  ╚═╝

CenturyLink Labs - http://www.centurylinklabs.com/

Checking if required software is installed.

Vagrant 1.6 or newer installed.
Virtualbox 4.3 or newer installed.

Creating a new CoreOS VM...
Downloading images
######################################################################## 100.0%
Bringing machine &apos;panamax-vm&apos; up with &apos;virtualbox&apos; provider...
==&amp;gt; panamax-vm: Box &apos;panamax-coreos-box-410&apos; could not be found. Attempting to find and install...
    panamax-vm: Box Provider: virtualbox
    panamax-vm: Box Version: &amp;gt;= 0
==&amp;gt; panamax-vm: Adding box &apos;panamax-coreos-box-410&apos; (v0) for provider: virtualbox
    panamax-vm: Downloading: http://storage.core-os.net/coreos/amd64-usr/410.0.0/coreos_production_vagrant.box
==&amp;gt; panamax-vm: Successfully added box &apos;panamax-coreos-box-410&apos; (v0) for &apos;virtualbox&apos;!
==&amp;gt; panamax-vm: Importing base box &apos;panamax-coreos-box-410&apos;...
==&amp;gt; panamax-vm: Matching MAC address for NAT networking...
==&amp;gt; panamax-vm: Setting the name of the VM: panamax-vm
==&amp;gt; panamax-vm: Fixed port collision for 22 =&amp;gt; 2222. Now on port 2201.
==&amp;gt; panamax-vm: Clearing any previously set network interfaces...
==&amp;gt; panamax-vm: Preparing network interfaces based on configuration...
    panamax-vm: Adapter 1: nat
==&amp;gt; panamax-vm: Forwarding ports...
    panamax-vm: 3000 =&amp;gt; 8888 (adapter 1)
    panamax-vm: 3001 =&amp;gt; 8889 (adapter 1)
    panamax-vm: 22 =&amp;gt; 2201 (adapter 1)
==&amp;gt; panamax-vm: Running &apos;pre-boot&apos; VM customizations...
==&amp;gt; panamax-vm: Booting VM...
==&amp;gt; panamax-vm: Waiting for machine to boot. This may take a few minutes...
    panamax-vm: SSH address: 127.0.0.1:2201
    panamax-vm: SSH username: core
    panamax-vm: SSH auth method: private key
    panamax-vm: Warning: Connection timeout. Retrying...
==&amp;gt; panamax-vm: Machine booted and ready!
==&amp;gt; panamax-vm: Setting hostname...
==&amp;gt; panamax-vm: Rsyncing folder: /Users/yuki_matsukura/.panamax/ =&amp;gt; /var/panamax
==&amp;gt; panamax-vm:   - Exclude: [&quot;.vagrant/&quot;, &quot;images\*&quot;]
==&amp;gt; panamax-vm: Running provisioner: shell...
    panamax-vm: Running: inline script
==&amp;gt; panamax-vm: Created symlink from /etc/systemd/system/multi-user.target.wants/var-lib-docker.mount to /etc/systemd/system/var-lib-docker.mount.
==&amp;gt; panamax-vm: Running provisioner: shell...
    panamax-vm: Running: inline script
==&amp;gt; panamax-vm: Running provisioner: shell...
    panamax-vm: Running: inline script
==&amp;gt; panamax-vm: Installing Panamax...
==&amp;gt; panamax-vm: Failed to stop update-engine-reboot-manager.service: Unit update-engine-reboot-manager.service not loaded.
==&amp;gt; panamax-vm: Created symlink from /etc/systemd/system/update-engine-reboot-manager.service to /dev/null.
==&amp;gt; panamax-vm: Created symlink from /etc/systemd/system/update-engine.service to /dev/null.
==&amp;gt; panamax-vm: Created symlink from /etc/systemd/system/multi-user.target.wants/etcd.service to /usr/lib64/systemd/system/etcd.service.
==&amp;gt; panamax-vm: Created symlink from /etc/systemd/system/multi-user.target.wants/fleet.service to /usr/lib64/systemd/system/fleet.service.
==&amp;gt; panamax-vm: Created symlink from /etc/systemd/system/sockets.target.wants/systemd-journal-gatewayd.socket to /usr/lib64/systemd/system/systemd-journal-gatewayd.socket.
==&amp;gt; panamax-vm:
==&amp;gt; panamax-vm: docker pull centurylink/panamax-api:latest
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm:
==&amp;gt; panamax-vm: docker pull centurylink/panamax-ui:latest
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm:
==&amp;gt; panamax-vm:
==&amp;gt; panamax-vm: docker pull google/cadvisor:0.2.2
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm: .
==&amp;gt; panamax-vm: Created symlink from /etc/systemd/system/multi-user.target.wants/panamax-metrics.service to /etc/systemd/system/panamax-metrics.service.
==&amp;gt; panamax-vm: Created symlink from /etc/systemd/system/multi-user.target.wants/panamax-api.service to /etc/systemd/system/panamax-api.service.
==&amp;gt; panamax-vm: Created symlink from /etc/systemd/system/multi-user.target.wants/panamax-ui.service to /etc/systemd/system/panamax-ui.service.
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm systemd[1]: Starting Panamax Metrics...
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: 2014/09/12 11:13:14 DELETE /v1.13/containers/PMX_CADVISOR?force=1
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [01e50dc7] +job container_delete(PMX_CADVISOR)
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: No such container: PMX_CADVISOR
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [01e50dc7] -job container_delete(PMX_CADVISOR) = ERR (1)
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [error] server.go:1048 Error making handler: No such container: PMX_CADVISOR
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [error] server.go:90 HTTP Error: statusCode=404 No such container: PMX_CADVISOR
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1823]: Error response from daemon: No such container: PMX_CADVISOR
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm systemd[1]: Started Panamax Metrics.
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm systemd[1]: Starting Panamax API...
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: 2014/09/12 11:13:14 DELETE /v1.13/containers/PMX_API?force=1
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [01e50dc7] +job container_delete(PMX_API)
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: No such container: PMX_API
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [01e50dc7] -job container_delete(PMX_API) = ERR (1)
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [error] server.go:1048 Error making handler: No such container: PMX_API
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [error] server.go:90 HTTP Error: statusCode=404 No such container: PMX_API
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1837]: Error response from daemon: No such container: PMX_API
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm systemd[1]: Started Panamax API.
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm systemd[1]: Starting Panamax UI...
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: 2014/09/12 11:13:14 POST /v1.13/containers/create?name=PMX_API
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [01e50dc7] +job create(PMX_API)
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: 2014/09/12 11:13:14 DELETE /v1.13/containers/PMX_UI?force=1
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [01e50dc7] +job container_delete(PMX_UI)
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: No such container: PMX_UI
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [01e50dc7] -job container_delete(PMX_UI) = ERR (1)
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [error] server.go:1048 Error making handler: No such container: PMX_UI
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [error] server.go:90 HTTP Error: statusCode=404 No such container: PMX_UI
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1858]: Error response from daemon: No such container: PMX_UI
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm systemd[1]: Started Panamax UI.
==&amp;gt; panamax-vm: Sep 12 11:13:14 panamax-vm docker[1090]: [01e50dc7] -job create(PMX_API) = OK (0)
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm systemd[1]: Stopping Panamax UI...
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm systemd[1]: Starting Panamax UI...
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: 2014/09/12 11:13:15 DELETE /v1.13/containers/PMX_UI?force=1
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [01e50dc7] +job container_delete(PMX_UI)
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [01e50dc7] -job container_delete(PMX_UI) = OK (0)
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1932]: PMX_UI
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm systemd[1]: Started Panamax UI.
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: 2014/09/12 11:13:15 POST /v1.13/containers/create?name=PMX_UI
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [01e50dc7] +job create(PMX_UI)
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [01e50dc7] -job create(PMX_UI) = OK (0)
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: Could not find entity for PMX_CADVISOR
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [error] server.go:1048 Error making handler: Could not find entity for PMX_CADVISOR
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [error] server.go:90 HTTP Error: statusCode=500 Could not find entity for PMX_CADVISOR
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1944]: 2014/09/12 11:13:15 Error response from daemon: Could not find entity for PMX_CADVISOR
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: 2014/09/12 11:13:15 POST /v1.13/containers/PMX_UI/stop?t=10
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [01e50dc7] +job stop(PMX_UI)
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [01e50dc7] -job stop(PMX_UI) = ERR (1)
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1960]: PMX_UI
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm systemd[1]: Stopping Panamax UI...
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm systemd[1]: Starting Panamax UI...
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: 2014/09/12 11:13:15 DELETE /v1.13/containers/PMX_UI?force=1
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [01e50dc7] +job container_delete(PMX_UI)
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: 2014/09/12 11:13:15 POST /v1.13/containers/create?name=PMX_CADVISOR
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [01e50dc7] +job create(PMX_CADVISOR)
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1090]: [01e50dc7] -job container_delete(PMX_UI) = OK (0)
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm docker[1977]: PMX_UI
==&amp;gt; panamax-vm: Sep 12 11:13:15 panamax-vm systemd[1]: Started Panamax UI.
==&amp;gt; panamax-vm: Sep 12 11:13:16 panamax-vm docker[1090]: [01e50dc7] -job create(PMX_CADVISOR) = OK (0)
==&amp;gt; panamax-vm: Sep 12 11:13:16 panamax-vm docker[1090]: [01e50dc7] -job create(PMX_UI) = OK (0)
==&amp;gt; panamax-vm: Panamax install complete
waiting for panamax to start.....

Please go to http://localhost:8888 to access panamax.

panamax init  15.04s user 9.16s system 10% cpu 3:48.89 total
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;インストールすると以下のページが自動的に開きます。&lt;br /&gt;
とりあえず、WordPressのテンプレートを選んでみます。2 imagesとは、2つのコンテナが登録されていることを意味します。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/09/Screenshot_9_12_14__21_10.png&quot; alt=&quot;Screenshot_9_12_14__21_10&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/09/Panamax_and_Getting_Started_with_Panamax_-_YouTube.png&quot; alt=&quot;Panamax_and_Getting_Started_with_Panamax_-_YouTube&quot; /&gt;&lt;/p&gt;
&lt;p&gt;たとえば、Load Balancerカテゴリを追加して、3レイヤーのアーキテクチャを組んだりが直感的に行えます。&lt;/p&gt;
&lt;p&gt;CoreOSにsshで入って、ステータスを見てみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% panamax ssh
core@panamax-vm ~ $ docker ps
CONTAINER ID        IMAGE                             COMMAND                CREATED             STATUS              PORTS                     NAMES
e0ee9d960ae5        dockerfile/elasticsearch:latest   /elasticsearch/bin/e   2 minutes ago       Up 2 minutes        9200/tcp, 9300/tcp        dockerfile_elasticsearch
257b9678d54a        centurylink/mysql:5.5             /usr/local/bin/run     4 minutes ago       Up 4 minutes        0.0.0.0:3306-&amp;gt;3306/tcp    DB
6ffb13e1f851        nginx:latest                      nginx                  4 minutes ago       Up 4 minutes        80/tcp                    nginx
ddcf74ffe39e        centurylink/panamax-ui:latest     /bin/sh -c &apos;bundle e   51 minutes ago      Up 51 minutes       0.0.0.0:3000-&amp;gt;3000/tcp    PMX_UI
2502ccad3ee5        google/cadvisor:0.2.2             /usr/bin/cadvisor -l   51 minutes ago      Up 51 minutes       0.0.0.0:49153-&amp;gt;8080/tcp   PMX_CADVISOR,PMX_UI/CADVISOR
e95e4169d1e0        centurylink/panamax-api:latest    /bin/sh -c &apos;bundle e   51 minutes ago      Up 51 minutes       0.0.0.0:3001-&amp;gt;3000/tcp    PMX_API,PMX_UI/PMX_API
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ページの上の方にあるドキュメントに書いて有るとおりに設定するために、NATを設定します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% VBoxManage controlvm panamax-vm natpf1 wordpress,tcp,,8997,,8080
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;コンテナがダウンロードして起動するのを、ただひたすら待つ！&lt;br /&gt;
1時間とか。&lt;/p&gt;
&lt;p&gt;最後に、&lt;br /&gt;
&lt;a href=&quot;http://localhost:8997/&quot;&gt;http://localhost:8997/&lt;/a&gt;&lt;br /&gt;
へアクセスすればWordPressが見られます！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/09/9_12_14__23_07.png&quot; alt=&quot;9_12_14__23_07&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;コンテナ、クラスタの管理には&lt;a href=&quot;https://github.com/google/cadvisor&quot;&gt;cadvisor&lt;/a&gt;を使っています&lt;/li&gt;
&lt;li&gt;ログ表示や、コンテナの状態表示がいまいち分かりづらい&lt;/li&gt;
&lt;li&gt;コンテナのダウンロードにはとても時間がかかるので、セットアップは夜寝る前がお勧め&lt;/li&gt;
&lt;li&gt;Docker管理の1つの利用シナリオを作ったという意味では評価出来るので、今後もっと深く見て行こうと思います。&lt;/li&gt;
&lt;li&gt;たぶん、顧客へ開発環境や動作環境を提供するときには、Vagrant+Chefより、Container+Vagrant+Chefの方がうれしいと思う。（ディスク容量節約できるし起動時間が早いので）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ネクストアクション&lt;/h2&gt;
&lt;p&gt;開発環境や本番環境の管理ツールに使えるかを試すために&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;コンテナのデプロイ先をAWSとか別のホスティングサイトにできるか試す&lt;/li&gt;
&lt;li&gt;設定管理をどうやって居るか見てみる&lt;/li&gt;
&lt;li&gt;コンテナ間の連携をどうやって定義するか見てみる&lt;/li&gt;
&lt;li&gt;自分でテンプレを作ってみる。（あわよくばテンプレコンテストに出す）&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>WordPress 4.0 にアップグレードしてベンチマーク</title><link>https://blog.teraren.com/posts/wordpress-24-behcmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-24-behcmark/</guid><description>WordPress 4.0とPHP 5.5にアップグレードしApacheBenchで計測した結果、Quick Cacheと合わせて122req/secを達成</description><pubDate>Tue, 09 Sep 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wordpress.org/&quot;&gt;WordPress 4.0&lt;/a&gt;が2014年9月頭にリリースされたので早速インストールしてみました。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://core.trac.wordpress.org/ticket/21435&quot;&gt;約2年前に投稿したパッチ&lt;/a&gt;がWordPress 4.0に取り込まれました！
&lt;ul&gt;
&lt;li&gt;パッチの内容は、コメントが数万件以上あるサイトで激重クエリーが走って過負荷になってしまうのを0.00秒で終わらせるためのパッチです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ついでに、PHP5.5にアップグレードしました。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wordpress.org/plugins/quick-cache/&quot;&gt;Quick Cache&lt;/a&gt;を使っているので、そここそ高速です&lt;/li&gt;
&lt;li&gt;CPU: Core i7 2.3GHz (8 cores)&lt;/li&gt;
&lt;li&gt;Server: Mac OS X 10.9.4&lt;/li&gt;
&lt;li&gt;Apache/2.2.26&lt;/li&gt;
&lt;li&gt;PHP 5.5.16 + APCu&lt;/li&gt;
&lt;li&gt;並列数：10、リクエスト数1000。&lt;/li&gt;
&lt;li&gt;外部ネットワークから。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;結果：122.23 [#/sec]&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ab -n 1000 -c 100 -H &apos;Accept-Encoding: gzip&apos; https://blog.teraren.com/
This is ApacheBench, Version 2.3 &amp;lt;$Revision: 655654 $&amp;gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking matsu.teraren.com (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Completed 1000 requests
Finished 1000 requests

Server Software:        Apache/2.2
Server Hostname:        matsu.teraren.com
Server Port:            80

Document Path:          /blog/
Document Length:        15910 bytes

Concurrency Level:      100
Time taken for tests:   8.181 seconds
Complete requests:      1000
Failed requests:        645
   (Connect: 0, Receive: 0, Length: 645, Exceptions: 0)
Write errors:           0
Total transferred:      16304309 bytes
HTML transferred:       15909309 bytes
Requests per second:    122.23 [#/sec] (mean)
Time per request:       818.144 [ms] (mean)
Time per request:       8.181 [ms] (mean, across all concurrent requests)
Transfer rate:          1946.13 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        7   45  43.7     34     369
Processing:   101  726 204.0    722    1956
Waiting:       53  610 169.1    630    1057
Total:        139  772 205.1    760    2006

Percentage of the requests served within a certain time (ms)
  50%    760
  66%    800
  75%    848
  80%    905
  90%   1061
  95%   1103
  98%   1209
  99%   1274
 100%   2006 (longest request)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;GTmetrix&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/09/Latest_Performance_Report_for__http___matsu_teraren_com_blog____GTmetrix.png&quot; alt=&quot;Latest_Performance_Report_for__http___matsu_teraren_com_blog____GTmetrix&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ちなみに、GTmetrixはCです。&lt;br /&gt;
サードパーティプラグインにおいて評価が悪いので、これ以上スコアを上げるためにはウィジェットを削除するしかないかな。。&lt;/p&gt;
</content:encoded></item><item><title>クレジットカードのBINコードとは？ 番号体系とイシュアー検索方法</title><link>https://blog.teraren.com/posts/credit-card-bin-code/</link><guid isPermaLink="true">https://blog.teraren.com/posts/credit-card-bin-code/</guid><description>クレジットカード番号の先頭6桁であるBINコード（Bank Identification Number）の仕組みと、BINコードからカード発行会社を特定する方法を解説</description><pubDate>Wed, 06 Aug 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;BINコードとは&lt;/h2&gt;
&lt;p&gt;BINコードとはクレジットカード番号の先頭6桁の数字。&lt;strong&gt;BIN = Bank Identification Number&lt;/strong&gt;の略で、この6桁からカード発行会社（イシュアー）を特定できる。&lt;/p&gt;
&lt;p&gt;例えば、カード番号が &lt;code&gt;4980-XXXX-XXXX-XXXX&lt;/code&gt; であれば、BINコードは &lt;code&gt;498000&lt;/code&gt; ～ &lt;code&gt;498099&lt;/code&gt; の範囲に該当し、特定のイシュアーに紐づく。&lt;/p&gt;
&lt;h2&gt;カード番号の構造&lt;/h2&gt;
&lt;p&gt;クレジットカード番号は通常16桁で、以下の構造になっている。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;桁&lt;/th&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1桁目&lt;/td&gt;
&lt;td&gt;MII (Major Industry Identifier)&lt;/td&gt;
&lt;td&gt;業界識別。4=Visa、5=Mastercard、3=Amex/JCB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1〜6桁目&lt;/td&gt;
&lt;td&gt;BIN / IIN&lt;/td&gt;
&lt;td&gt;発行会社の識別番号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7〜15桁目&lt;/td&gt;
&lt;td&gt;口座番号&lt;/td&gt;
&lt;td&gt;個人を識別する番号&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16桁目&lt;/td&gt;
&lt;td&gt;チェックディジット&lt;/td&gt;
&lt;td&gt;Luhnアルゴリズムによる検証用&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;BINコードの検索&lt;/h2&gt;
&lt;h3&gt;海外&lt;/h3&gt;
&lt;p&gt;BINコードは一元管理されておらず、複数のサービスがBINコードからイシュアーを検索するAPIやデータベースを提供している。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.bincodes.com/&quot;&gt;bincodes.com&lt;/a&gt; — BINコード検索、カードブランド・発行国・カードタイプの判定&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.bindb.com/bin-list.html&quot;&gt;bindb.com&lt;/a&gt; — BINリストのダウンロードとAPI提供&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;日本国内&lt;/h3&gt;
&lt;p&gt;日本国内のBINコードも一元管理されていない。以前、国内のBINコードリストを掲載していたサイトがあったが消滅してしまった。&lt;/p&gt;
&lt;p&gt;当時のデータをGistにまとめている: &lt;a href=&quot;https://gist.github.com/matsubo/2c91c9cbedf17a490dca#file-credit_card_bin_codes-md&quot;&gt;日本国内のクレジットカードBINコード一覧&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;用途&lt;/h2&gt;
&lt;p&gt;BINコードは以下のような場面で活用される。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;決済フォームのUX改善&lt;/strong&gt;: カード番号入力時にブランドロゴを自動表示&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不正検知&lt;/strong&gt;: カード発行国と利用者の所在国の不一致を検出&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;手数料計算&lt;/strong&gt;: カードブランドやカードタイプ（デビット/クレジット）による手数料率の判定&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>LINEのWebMoney詐欺師のIPアドレスを割り出してみた【その2】</title><link>https://blog.teraren.com/posts/line-webmoney-fraud-part2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/line-webmoney-fraud-part2/</guid><description>LINEアカウント乗っ取り詐欺師と実際にやり取りし、天安門事件のURLを踏ませてIPアドレスを特定。グレートファイアウォールで中国発とほぼ確定した調査録その2。</description><pubDate>Thu, 17 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;/posts/line-fraud/&quot;&gt;前回&lt;/a&gt;に続き、知り合いのLINEアカウントが乗っ取られ、楽天のスーパーポイントカードを要求されたので、相手をしてみました。&lt;/p&gt;
&lt;h2&gt;会話&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3789.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;今回はWebmoneyでは無く、楽天のカードです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3790.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;控えめに、5000円を要求されました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3791.png&quot; alt=&quot;IMG_3791&quot; /&gt;&lt;/p&gt;
&lt;p&gt;アホなフリをしてみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3792.png&quot; alt=&quot;IMG_3792&quot; /&gt;&lt;/p&gt;
&lt;p&gt;そして、天安門事件を表示するページのURLを踏ませます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3793.png&quot; alt=&quot;IMG_3793&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本気で、グレートファイアーウォールに引っかかっている様子なので、別のURLを送ります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3794.png&quot; alt=&quot;IMG_3794&quot; /&gt;&lt;/p&gt;
&lt;p&gt;天安門事件に対して、反応してきました！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3795.png&quot; alt=&quot;IMG_3795&quot; /&gt;&lt;/p&gt;
&lt;p&gt;よく分かりませんが、自分の正当性を主張してきました。&lt;br /&gt;
ずいぶんと、上から目線です。このような人は、私欲が強く、思い通りにならないとストレスが溜まる、感情的な人だとプロファイリングしました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3797.png&quot; alt=&quot;IMG_3797&quot; /&gt;&lt;/p&gt;
&lt;p&gt;なかなか返信が来ないので、スタンプを送りつけまくりました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3798.png&quot; alt=&quot;IMG_3798&quot; /&gt;&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair &lt;em&gt;/}
なぜか、私が警察に通報されました（w
{/&lt;/em&gt; textlint-enable */}
知り合いの、のび太君似のベトナム人と同じ口調です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3799.png&quot; alt=&quot;IMG_3799&quot; /&gt;&lt;/p&gt;
&lt;p&gt;まだ、諦めていない模様です。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3800.png&quot; alt=&quot;IMG_3800&quot; /&gt;&lt;/p&gt;
&lt;p&gt;なぜか、こちらが複数人と思っているようです。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/IMG_3801.png&quot; alt=&quot;IMG_3801&quot; /&gt;&lt;/p&gt;
&lt;p&gt;飽きたので、オウム返しをしてみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/Pasted_Image_7_17_14__20_08.png&quot; alt=&quot;Pasted_Image_7_17_14__20_08&quot; /&gt;&lt;/p&gt;
&lt;p&gt;キれたようです。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;きれいずきん&lt;/strong&gt;は、今日も大活躍です。&lt;/p&gt;
&lt;h3&gt;IPアドレス&lt;/h3&gt;
&lt;p&gt;今回もURLを踏んでくれたので、IPアドレスを取得出来ました。&lt;br /&gt;
相変わらずYahoo BBのようです。&lt;br /&gt;
踏み台っぽいです。&lt;/p&gt;
&lt;h4&gt;アクセスログ&lt;/h4&gt;
&lt;p&gt;同じIPアドレスから、複数の端末でアクセスしてきました。&lt;br /&gt;
ブラウザの言語がzh-cnなので、中国人のようです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;126.15.164.217 - - [16/Jul/2014:17:57:09 +0900] &quot;GET /static/webmoney.html HTTP/1.1&quot; 200 272 &quot;-&quot; &quot;Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)&quot;
126.15.164.217 - - [16/Jul/2014:17:59:15 +0900] &quot;GET /static/webmoney.html HTTP/1.1&quot; 200 272 &quot;-&quot; &quot;Mozilla/5.0 (Linux; U; Android 4.0.4; zh-cn; GT-I9100 Build/IMM76L) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;ポートスキャン&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;% host 126.15.164.217
217.164.15.126.in-addr.arpa domain name pointer softbank126015164217.bbtec.net.
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;% nmap 126.15.164.217
Starting Nmap 6.46 ( http://nmap.org ) at 2014-07-17 14:34 JST
Nmap scan report for softbank126015164217.bbtec.net (126.15.164.217)
Host is up (0.018s latency).
Not shown: 995 closed ports
PORT     STATE SERVICE
88/tcp   open  kerberos-sec
135/tcp  open  msrpc
1025/tcp open  NFS-or-IIS
1723/tcp open  pptp
8888/tcp open  sun-answerbook

Nmap done: 1 IP address (1 host up) scanned in 1.70 seconds
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>WordPress 4.0に送ったpatchがmergeされました</title><link>https://blog.teraren.com/posts/wordpress4-patch-merged/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress4-patch-merged/</guid><description>WordPress 4.0に送ったpatchがmergeされました</description><pubDate>Thu, 17 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WordPress 3.4.1で起きていた、&lt;a href=&quot;/posts/wordpress-3-4-1-database-lock/&quot;&gt;この問題&lt;/a&gt;を解決するために、WordPress coreにpatchを送りました。&lt;/li&gt;
&lt;li&gt;これにより、&lt;strong&gt;世界中で運用されているWordPressのDBサーバ負荷を減らせました！&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;問題が発生するケースが希なのでmergeされるまで2年かかりました。
&lt;ul&gt;
&lt;li&gt;遅れた理由は、変な人がディスカッションに入ってきて、議論が長くなってしまった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ずっと利用しているWordPressに対して貢献できてうれしく思います。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;変更内容&lt;/h2&gt;
&lt;p&gt;これだけだけど、これでDBが刺さらなくなる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/Screen-Shot-2018-05-26-at-12.10.01.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;長いやりとり&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>multitailコマンド使ってみた</title><link>https://blog.teraren.com/posts/multitail-command-usage/</link><guid isPermaLink="true">https://blog.teraren.com/posts/multitail-command-usage/</guid><description>multitailコマンド使ってみた</description><pubDate>Tue, 15 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;multitailが便利だった。&lt;/p&gt;
&lt;p&gt;インストール&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% brew install multitail
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使い方。パラメータにファイル名を渡すだけ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% multitail *.log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;縦に3分割して、それぞれに適当に割り当てる場合は、-sオプションを付ける。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% multitail -s 3 *.log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;デモ&lt;/p&gt;
</content:encoded></item><item><title>LINEのWebMoney詐欺師のIPアドレス判明。なんと日本！</title><link>https://blog.teraren.com/posts/line-fraud/</link><guid isPermaLink="true">https://blog.teraren.com/posts/line-fraud/</guid><description>知人のLINEアカウントを乗っ取りWebMoneyを要求してきた詐欺師に対し、偽のURLを踏ませてIPアドレスを特定した経緯と、驚きの結果を公開します。</description><pubDate>Sun, 06 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;知り合いのLINEアカウントがクラックされて、WebMoneyを要求してきたので、&lt;strong&gt;犯人のIPアドレス&lt;/strong&gt;を割り出して見ました。&lt;/p&gt;
&lt;p&gt;とりあえずは、WebMoneyを買いたい人を装って、ノリノリでリプライしていきます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/10003830_511691137808_7870701808275815748_o.jpg&quot; alt=&quot;10003830_511691137808_7870701808275815748_o&quot; /&gt;&lt;/p&gt;
&lt;p&gt;相手は、中国人らしく、&lt;a href=&quot;http://alfalfalfa.com/archives/7365118.html&quot;&gt;天安門事件&lt;/a&gt;と返信すると退席するという事例があるらしいので、&lt;strong&gt;IPアドレスを割り出したら、天安門事件とリプライ&lt;/strong&gt;しようと思ってました。&lt;/p&gt;
&lt;h2&gt;会話&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/10368391_511691227628_6793328312200426418_n.jpg&quot; alt=&quot;10368391_511691227628_6793328312200426418_n&quot; /&gt;&lt;/p&gt;
&lt;p&gt;LINE電話したら、相手が操作を間違って取ることを願って、かけてみましたが、応答ありませんでした。（´・ω・｀）&lt;br /&gt;
（しかも、ふざけてたら、「頼みます」と怒られた。。。）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/10489672_511691382318_8847995553511807141_n.jpg&quot; alt=&quot;10489672_511691382318_8847995553511807141_n&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WebMoneyを買ったふりをして、写メをWebにアップロードしたと報告します。もちろん、それは嘘で&lt;strong&gt;IPアドレスを抜くためのWebページ&lt;/strong&gt;です。しかし、なかなか開いてくれません。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/1932694_511691447188_2162515012321360227_o.jpg&quot; alt=&quot;1932694_511691447188_2162515012321360227_o&quot; /&gt;&lt;/p&gt;
&lt;p&gt;まだ開きません。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/10430478_511691586908_3830463912418740578_n.jpg&quot; alt=&quot;10430478_511691586908_3830463912418740578_n&quot; /&gt;&lt;/p&gt;
&lt;p&gt;**やっと開きました！**しかし、開いてくれた途端、退出されました。&lt;br /&gt;
LINEの運営がアカウントを無効化したためです。ぎりぎり間に合って良かった！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/07/Screenshot_7_6_14__0_38.png&quot; alt=&quot;Screenshot_7_6_14__0_38&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最後の〆のために作った、&lt;a href=&quot;https://matsu.teraren.com/static/t.html&quot;&gt;天安門のページ&lt;/a&gt;がお蔵入りになってしまって残念です。&lt;/p&gt;
&lt;h3&gt;IPを調べる&lt;/h3&gt;
&lt;p&gt;こちらが、犯人がアクセスしたアクセスログ。&lt;br /&gt;
IPアドレスは&lt;strong&gt;126.7.173.196&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;Windows7で、Chrome&lt;/strong&gt;を使っている模様。&lt;br /&gt;
（HTTPヘッダも取っておけば良かったなぁと反省）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;126.7.173.196 - - [02/Jul/2014:22:43:48 +0900] &quot;GET /static/webmoney.html HTTP/1.1&quot; 200 272 &quot;-&quot; &quot;Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1&quot;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;プロバイダはYahoo BBの様子。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% host 126.7.173.196
196.173.7.126.in-addr.arpa domain name pointer softbank126007173196.bbtec.net.

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;軽くポートスキャンしてみると、&lt;strong&gt;VNCのポートが空いてる&lt;/strong&gt;！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% nmap 126.7.173.196

Starting Nmap 6.46 ( http://nmap.org ) at 2014-07-02 22:50 JST
Nmap scan report for softbank126007173196.bbtec.net (126.7.173.196)
Host is up (0.065s latency).
Not shown: 995 closed ports
PORT STATE SERVICE
135/tcp open msrpc
1025/tcp open NFS-or-IIS
1723/tcp open pptp
5800/tcp open vnc-http
5900/tcp open vnc

Nmap done: 1 IP address (1 host up) scanned in 5.36 seconds

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そして、VNCのパスワードをクラックするためにncrackをしばらく動かしていたんだけど、どうやらVNCの時はちゃんと動いてくれない模様。&lt;/p&gt;
&lt;p&gt;次に、hydra使って、&lt;a href=&quot;https://wiki.skullsecurity.org/Passwords&quot;&gt;有名どころのパスワードを一通り試してみましたが、一致せず。。。。&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% hydra -t 1 -P john.txt 126.7.173.196 vnc
Hydra v7.6 (c)2013 by van Hauser/THC &amp;amp; David Maciejak - for legal purposes only
Hydra (http://www.thc.org/thc-hydra) starting at 2014-07-05 16:20:39
[DATA] 1 task, 1 server, 3107 login tries (l:1/p:3107), ~3107 tries per task
[DATA] attacking service vnc on port 5900
[ERROR] VNC server connection failed
[ERROR] VNC server connection failed
[ERROR] VNC server connection failed
[ERROR] VNC server connection failed
....
[ERROR] VNC server connection failed
[ERROR] VNC server connection failed
[ERROR] Not a VNC protocol or service shutdown: (null)
[ERROR] Too many connect errors to target, disabling vnc://126.7.173.196:5900
0 of 1 target completed, 0 valid passwords found
[ERROR] 1 target did not resolve or could not be connected
Hydra (http://www.thc.org/thc-hydra) finished at 2014-07-05 16:38:16
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;BruteForceかけるのもだるいので、これにておわり。&lt;/p&gt;
&lt;h3&gt;7月7日 追記&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://law.e-gov.go.jp/htmldata/H11/H11HO128.html&quot;&gt;不正アクセス禁止法&lt;/a&gt;に該当するのでは？という指摘がありましたが、グレーなかんじ。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;４ 　この法律において「不正アクセス行為」とは、次の各号のいずれかに該当する行為をいう。&lt;/p&gt;
&lt;p&gt;一 　アクセス制御機能を有する特定電子計算機に電気通信回線を通じて当該アクセス制御機能に係る他人の識別符号を入力して当該特定電子計算機を作動させ、当該アクセス制御機能により制限されている特定利用をし得る状態にさせる行為（当該アクセス制御機能を付加したアクセス管理者がするもの及び当該アクセス管理者又は当該識別符号に係る利用権者の承諾を得てするものを除く。）&lt;/p&gt;
&lt;p&gt;二 　アクセス制御機能を有する特定電子計算機に電気通信回線を通じて当該アクセス制御機能による特定利用の制限を免れることができる情報（識別符号であるものを除く。）又は指令を入力して当該特定電子計算機を作動させ、その制限されている特定利用をし得る状態にさせる行為（当該アクセス制御機能を付加したアクセス管理者がするもの及び当該アクセス管理者の承諾を得てするものを除く。次号において同じ。）&lt;/p&gt;
&lt;p&gt;三 　電気通信回線を介して接続された他の特定電子計算機が有するアクセス制御機能によりその特定利用を制限されている特定電子計算機に電気通信回線を通じてその制限を免れることができる情報又は指令を入力して当該特定電子計算機を作動させ、その制限されている特定利用をし得る状態にさせる行為&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;第四条 　何人も、不正アクセス行為（第二条第四項第一号に該当するものに限る。第六条及び第十二条第二号において同じ。）の用に供する目的で、アクセス制御機能に係る他人の識別符号を取得してはならない。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;東北大学のレポーティングでは、調査だけでは不正アクセスにならないようなことが書いてあります。&lt;br /&gt;
see: 4.1 ポートスキャン攻撃&lt;br /&gt;
&lt;a href=&quot;http://www.tains.tohoku.ac.jp/news/st-news-21/2640.html&quot;&gt;http://www.tains.tohoku.ac.jp/news/st-news-21/2640.html&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;9月22日 追記&lt;/h3&gt;
&lt;p&gt;IPAのFAQによると、ポートスキャン自体は問題有りません。&lt;br /&gt;
&lt;a href=&quot;http://www.ipa.go.jp/security/ciadr/faq01.html#Q0-12&quot;&gt;http://www.ipa.go.jp/security/ciadr/faq01.html#Q0-12&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Q0-12: ポートスキャンのような事前調査行為は法律に触れるでしょうか？&lt;br /&gt;
A0-12: 「不正アクセス行為の禁止等に関する法律」の施行によりポートスキャンが犯罪に相当することになるかどうかは微妙なところですが、スキャンそれ自体は該当しない可能性が大です。ポートスキャンやDoS攻撃によりマシンやネットワークへの障害が発生しているような場合には、別の法律に該当(威力業務妨害等)の可能性があります。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;続編&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;/posts/line-webmoney-fraud-part2/&quot;&gt;LINEのWebMoney詐欺師のIPアドレスを割り出してみた【その2】&lt;/a&gt;へ&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B01DIKO068&quot;}&lt;/p&gt;
</content:encoded></item><item><title>zncをMac OS Xに入れてみた</title><link>https://blog.teraren.com/posts/znc-mac-limechat/</link><guid isPermaLink="true">https://blog.teraren.com/posts/znc-mac-limechat/</guid><description>IRCのログを常時記録するためにZNCをMac OS XにHomebrewでインストールし、自動起動設定からLimeChatとの接続設定までをまとめた手順書</description><pubDate>Fri, 04 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;概要&lt;/h3&gt;
&lt;p&gt;今更ながら、IRCのロギングのために&lt;a href=&quot;http://wiki.znc.in/ZNC&quot;&gt;znc&lt;/a&gt;を入れてみました。&lt;br /&gt;
本家のドキュメントのトップに、「This is outdated!」と書いてあって、何を信じれば良いのかよく分からない中、ある程度出来たのでまとめておきます。&lt;/p&gt;
&lt;h3&gt;インストール&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% brew install znc
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# 初期設定作る。基本的にデフォルトを突き進めばOK。
% znc --makeconf

# 自動起動設定
% ln -sfv /usr/local/opt/znc/*.plist  ~/Library/LaunchAgents

# 起動
% launchctl load ~/Library/LaunchAgents/homebrew.mxcl.znc.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;設定&lt;/h3&gt;
&lt;p&gt;IRCクライアントで、自分で指定したポートに接続して、サーバのコンソールへメッセージを送って設定していく。&lt;/p&gt;
&lt;p&gt;重要なコマンドたち&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 困ったら、
/znc help

# まず、ネットワークを追加
/znc AddNetwork
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一度、zncへの接続を切り、再接続する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# zncが接続するIRCサーバを登録する
/znc AddServer &amp;lt;host&amp;gt; &amp;lt;port&amp;gt;

# 接続する
/znc connect
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これで、普通のIRCサーバに繫いだときと同じような感じで操作できるようになります。&lt;/p&gt;
&lt;p&gt;次に、テキストファイルにログを落とします。&lt;br /&gt;
ログファイルは、&lt;code&gt;.znc/moddata/log&lt;/code&gt;に保存されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# logモジュールをロードする
/znc loadmod --type=global log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最後に、設定を保存しておわり。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 設定を保存
/znc SaveConfig
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最終的な設定ファイルの中身はこちら。（パスワードなどは適当なhashに変えてあります）
.znc/configs/znc.conf&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// WARNING
//
// Do NOT edit this file while ZNC is running!
// Use webadmin or *controlpanel instead.
//
// Altering this file by hand will forfeit all support.
//
// But if you feel risky, you might want to read help on /znc saveconfig and /znc rehash.
// Also check http://en.znc.in/wiki/Configuration

AnonIPLimit = 10
ConnectDelay = 5
LoadModule = log
MaxBufferSize = 500
ProtectWebSessions = true
SSLCertFile = /Users/matsu/.znc/znc.pem
ServerThrottle = 30
Version = 1.2

&amp;lt;Listener listener0&amp;gt;
 AllowIRC = true
 AllowWeb = true
 IPv4 = true
 IPv6 = false
 Port = 6667
 SSL = true
&amp;lt;/Listener&amp;gt;

&amp;lt;User matsukura&amp;gt;
 Admin = true
 AltNick = matsukura_
 AppendTimestamp = false
 AutoClearChanBuffer = false
 Buffer = 50
 ChanModes = +stn
 DenyLoadMod = false
 DenySetBindHost = false
 Ident = matsukura
 JoinTries = 10
 MaxJoins = 0
 MaxNetworks = 1
 MultiClients = true
 Nick = matsukura
 PrependTimestamp = true
 QuitMsg = ZNC - http://znc.in
 RealName = Yuki Matsukura
 StatusPrefix = *
 TimestampFormat = [%H:%M:%S]

 &amp;lt;Network metaps&amp;gt;
 FloodBurst = 4
 FloodRate = 1.00
 IRCConnectEnabled = true
 Server =
 &amp;lt;/Network&amp;gt;

 &amp;lt;Pass password&amp;gt;
 Hash = 4ae2f81c13fbfe43a68a11af24ee0aa5b0cccd276051af97c03a196546f8ce6b
 Method = SHA256
 Salt = b7Xd48c?0l2sVeLMz6Da
 &amp;lt;/Pass&amp;gt;
&amp;lt;/User&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;まとめ&lt;/h3&gt;
&lt;p&gt;便利。&lt;/p&gt;
&lt;h3&gt;おまけ&lt;/h3&gt;
&lt;p&gt;awayしたときのニックネーム変更。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/znc loadmod awaynick
/msg *awaynick set %nick%_off
/znc saveconfig
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;モジュール毎の環境変数はここに置かれます。&lt;br /&gt;
&lt;code&gt;.znc/users/matsukura/networks/metaps/moddata/awaynick&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>AWSのElastiCacheはPCI DSS非対応</title><link>https://blog.teraren.com/posts/elasticache-pci-dss/</link><guid isPermaLink="true">https://blog.teraren.com/posts/elasticache-pci-dss/</guid><description>AWSのElastiCacheはPCI DSS非対応</description><pubDate>Mon, 16 Jun 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;いつ対応するか未定とのこと。&lt;br /&gt;
とりあえず、要求は上げてもらった。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;7/7 追記&lt;br /&gt;
AWSのソリューションアーキテクトに聞いたところ、ElastiCacheに対してどのような要件が足りていないかを相談してもらうのが良いとのこと。&lt;/p&gt;
&lt;p&gt;物理レベルではElastiCacheもPCI DSS対応しているとのこと。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;2018/7 追記 PCI DSS対応したとのこと&lt;/p&gt;
&lt;p&gt;https://aws.amazon.com/about-aws/whats-new/2018/07/amazon-elasticache-for-redis-is-now-pcidss-compliant/?fbclid=IwAR3Ji9J6r48HvB8fR8c838Q0cW7_ATIek0aA1Ud8tDR9f0TB68O5K0Ni5YA&lt;/p&gt;
</content:encoded></item><item><title>AirPi Kit v1.4 - Raspberry Pi weather station shield</title><link>https://blog.teraren.com/posts/airpi-kit-v1-4-raspberry-pi-weather-station-shield/</link><guid isPermaLink="true">https://blog.teraren.com/posts/airpi-kit-v1-4-raspberry-pi-weather-station-shield/</guid><description>Raspberry Pi用の気象センサーシールドAirPi Kit v1.4を組み立て、温度・気圧・湿度・一酸化炭素などのデータを取得した実験記録</description><pubDate>Sun, 08 Jun 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/06/IMG_3629.jpg&quot; alt=&quot;IMG_3629&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;概要&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://gigazine.net/news/20140508-tindie/&quot;&gt;Gigazineでも紹介されている&lt;/a&gt;、2013年12月からずっと待ちに待った&lt;a href=&quot;http://airpi.es/&quot;&gt;AirPi&lt;/a&gt;が届いたので、作りました。&lt;/p&gt;
&lt;p&gt;AirPiは、Raspberry PiのI/Oにあわせて作られた気象センサー（Weather Station）です。&lt;br /&gt;
Weather Stationがこの値段で手に入るのはかなりお得です。普通、3万とか4万とかしちゃうので。しかも、Raspberry Piでデータが取れるのでLinux上でプログラミング言語を使用してデータの加工が可能になります。&lt;/p&gt;
&lt;p&gt;緑のLEDを手元にあった、青色LEDに交換してあります。&lt;/p&gt;
&lt;p&gt;実装自体は1時間ぐらいで終わります。&lt;/p&gt;
&lt;h3&gt;実験&lt;/h3&gt;
&lt;p&gt;以下、実行例。まだ、&lt;a href=&quot;http://airpi.freeforums.net/thread/135/air-quality-co2&quot;&gt;v1.4のセンサーにソフトウェアが対応していない&lt;/a&gt;けど、こんな感じでデータを取得出来ます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;matsu@raspberrypi ~/AirPi $ sudo python airpi.py

[sudo] password for matsu:
Success: Loaded sensor plugin BMP085-temp
Success: Loaded sensor plugin BMP085-pres
Success: Loaded sensor plugin MCP3008
Success: Loaded sensor plugin DHT22
Success: Loaded sensor plugin LDR
Success: Loaded sensor plugin MiCS-2710
Success: Loaded sensor plugin MiCS-5525
Success: Loaded sensor plugin Mic
Success: Loaded output plugin Print
Check wiring for the MiCS-2710 measurement, no voltage detected on ADC input 2
Check wiring for the ABM_713_RC measurement, no voltage detected on ADC input 4

Time: 2014-06-08 14:05:34.196998
Temperature: 31.0 C
Pressure: 998.65 hPa
Relative_Humidity: 56.9000015259 %
Light_Level: 2819.54887218 Ohms
Carbon_Monoxide: 102200000.0 Ohms
Uploaded successfully
Check wiring for the MiCS-2710 measurement, no voltage detected on ADC input 2
Check wiring for the MiCS-5525 measurement, no voltage detected on ADC input 3
Check wiring for the ABM_713_RC measurement, no voltage detected on ADC input 4

Time: 2014-06-08 14:05:39.197454
Temperature: 31.0 C
Pressure: 998.68 hPa
Relative_Humidity: 56.7999992371 %
Light_Level: 6770.49180328 Ohms
Carbon_Monoxide: None Ohms
Uploaded successfully
Check wiring for the MiCS-2710 measurement, no voltage detected on ADC input 2
Check wiring for the ABM_713_RC measurement, no voltage detected on ADC input 4

Time: 2014-06-08 14:05:44.196216
Temperature: 31.0 C
Pressure: 998.71 hPa
Relative_Humidity: 56.0 %
Light_Level: 3621.83754993 Ohms
Carbon_Monoxide: 102200000.0 Ohms
Uploaded successfully
Check wiring for the MiCS-2710 measurement, no voltage detected on ADC input 2
Check wiring for the ABM_713_RC measurement, no voltage detected on ADC input 4

Time: 2014-06-08 14:05:49.196660
Temperature: 31.1 C
Pressure: 998.73 hPa
Relative_Humidity: 56.0 %
Light_Level: 3513.87054161 Ohms
Carbon_Monoxide: 102200000.0 Ohms
Uploaded successfully
Check wiring for the MiCS-2710 measurement, no voltage detected on ADC input 2
Check wiring for the ABM_713_RC measurement, no voltage detected on ADC input 4

Time: 2014-06-08 14:05:54.196689
Temperature: 31.1 C
Pressure: 998.68 hPa
Relative_Humidity: 56.0 %
Light_Level: 3149.10025707 Ohms
Carbon_Monoxide: 102200000.0 Ohms
Uploaded successfully
Check wiring for the MiCS-2710 measurement, no voltage detected on ADC input 2
Check wiring for the ABM_713_RC measurement, no voltage detected on ADC input 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;雨が降っていたので気圧が低いですね。温度は、基板上での実装なので数度高く出ますね。Ohmsで出ているのは、自分でセンサの仕様見て変換しろって事でしょうか・・・&lt;/p&gt;
</content:encoded></item><item><title>Rubyで半角カナへ変換</title><link>https://blog.teraren.com/posts/ruby-hankaku-kana/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ruby-hankaku-kana/</guid><description>Rubyで半角カナへ変換</description><pubDate>Wed, 21 May 2014 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;&amp;gt; require &apos;nkf&apos;
&amp;gt; NKF.nkf(&apos;-w -Z4 -Z1 -x&apos;, &apos;ゼンカク&apos;)
&amp;gt; ｾﾞﾝｶｸ
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;オプション説明。nkfコマンドと同じ。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-w&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;UTF8の出力なので。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-Z4&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;全角カナを半角カナにするオプション&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-Z1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;全角スペースを半角スペースに変換するオプション&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-x&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;このオプションを指定しないと、半角カナが全角カナになってしまう。-Z4だけだと、相互変換が勝手にかかってしまうので、-xを指定して一方向にする。&lt;/p&gt;
</content:encoded></item><item><title>AWS EC2 IP address range</title><link>https://blog.teraren.com/posts/aws-ec2-ip-address-range/</link><guid isPermaLink="true">https://blog.teraren.com/posts/aws-ec2-ip-address-range/</guid><description>米国東西・EU・アジア太平洋・南米など各リージョンのAWS EC2 IPアドレスレンジ一覧（2014年時点のCIDRブロック参照用まとめ）</description><pubDate>Wed, 26 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最新をどこかでちゃんと管理して欲しいんですけどね。。。 &lt;a href=&quot;https://forums.aws.amazon.com/ann.jspa?annID=1701&quot;&gt;https://forums.aws.amazon.com/ann.jspa?annID=1701&lt;/a&gt; US East (Northern Virginia):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;72.44.32.0/19 (72.44.32.0 - 72.44.63.255) 67.202.0.0/18 (67.202.0.0 - 67.202.63.255) 75.101.128.0/17 (75.101.128.0 - 75.101.255.255) 174.129.0.0/16 (174.129.0.0 - 174.129.255.255) 204.236.192.0/18 (204.236.192.0 - 204.236.255.255) 184.73.0.0/16 (184.73.0.0 - 184.73.255.255) 184.72.128.0/17 (184.72.128.0 - 184.72.255.255) 184.72.64.0/18 (184.72.64.0 - 184.72.127.255) 50.16.0.0/15 (50.16.0.0 - 50.17.255.255) 50.19.0.0/16 (50.19.0.0 - 50.19.255.255) 107.20.0.0/14 (107.20.0.0 - 107.23.255.255) 23.20.0.0/14 (23.20.0.0 - 23.23.255.255) 54.242.0.0/15 (54.242.0.0 - 54.243.255.255) 54.234.0.0/15 (54.234.0.0 - 54.235.255.255) 54.236.0.0/15 (54.236.0.0 - 54.237.255.255) 54.224.0.0/15 (54.224.0.0 - 54.225.255.255) 54.226.0.0/15 (54.226.0.0 - 54.227.255.255) 54.208.0.0/15 (54.208.0.0 - 54.209.255.255) 54.210.0.0/15 (54.210.0.0 - 54.211.255.255) 54.221.0.0/16 (54.221.0.0 - 54.221.255.255) 54.204.0.0/15 (54.204.0.0 - 54.205.255.255) 54.196.0.0/15 (54.196.0.0 - 54.197.255.255) 54.198.0.0/16 (54.198.0.0 - 54.198.255.255) 54.80.0.0/13 (54.80.0.0 - 54.87.255.255)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;US West (Oregon):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;50.112.0.0/16 (50.112.0.0 - 50.112.255.255) 54.245.0.0/16 (54.245.0.0 - 54.245.255.255) 54.244.0.0/16 (54.244.0.0 - 54.244.255.255) 54.214.0.0/16 (54.214.0.0 - 54.214.255.255) 54.212.0.0/15 (54.212.0.0 - 54.213.255.255) 54.218.0.0/16 (54.218.0.0 - 54.218.255.255) 54.200.0.0/15 (54.200.0.0 - 54.201.255.255) 54.202.0.0/15 (54.202.0.0 - 54.203.255.255) 54.184.0.0/13 (54.184.0.0 - 54.191.255.255)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;US West (Northern California):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;204.236.128.0/18 (204.236.128.0 - 204.236.191.255) 184.72.0.0/18 (184.72.0.0 - 184.72.63.255) 50.18.0.0/16 (50.18.0.0 - 50.18.255.255) 184.169.128.0/17 (184.169.128.0 - 184.169.255.255) 54.241.0.0/16 (54.241.0.0 - 54.241.255.255) 54.215.0.0/16 (54.215.0.0 - 54.215.255.255) 54.219.0.0/16 (54.219.0.0 - 54.219.255.255) 54.193.0.0/16 (54.193.0.0 - 54.193.255.255) 54.176.0.0/15 (54.176.0.0 - 54.177.255.255) NEW 54.183.0.0/16 (54.183.0.0 - 54.183.255.255) NEW&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;EU (Ireland):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;79.125.0.0/17 (79.125.0.0 - 79.125.127.255) 46.51.128.0/18 (46.51.128.0 - 46.51.191.255) 46.51.192.0/20 (46.51.192.0 - 46.51.207.255) 46.137.0.0/17 (46.137.0.0 - 46.137.127.255) 46.137.128.0/18 (46.137.128.0 - 46.137.191.255) 176.34.128.0/17 (176.34.128.0 - 176.34.255.255) 176.34.64.0/18 (176.34.64.0 - 176.34.127.255) 54.247.0.0/16 (54.247.0.0 - 54.247.255.255) 54.246.0.0/16 (54.246.0.0 - 54.246.255.255) 54.228.0.0/16 (54.228.0.0 - 54.228.255.255) 54.216.0.0/15 (54.216.0.0 - 54.217.255.255) 54.229.0.0/16 (54.229.0.0 - 54.229.255.255) 54.220.0.0/16 (54.220.0.0 - 54.220.255.255) 54.194.0.0/15 (54.194.0.0 - 54.195.255.255) 54.72.0.0/14 (54.72.0.0 - 54.75.255.255) 54.76.0.0/15 (54.76.0.0 - 54.77.255.255) NEW 54.78.0.0/16 (54.78.0.0 - 54.78.255.255) NEW&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Asia Pacific (Singapore)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;175.41.128.0/18 (175.41.128.0 - 175.41.191.255) 122.248.192.0/18 (122.248.192.0 - 122.248.255.255) 46.137.192.0/18 (46.137.192.0 - 46.137.255.255) 46.51.216.0/21 (46.51.216.0 - 46.51.223.255) 54.251.0.0/16 (54.251.0.0 - 54.251.255.255) 54.254.0.0/16 (54.254.0.0 - 54.254.255.255) 54.255.0.0/16 (54.255.0.0 - 54.255.255.255) 54.179.0.0/16 (54.179.0.0 - 54.179.255.255) NEW&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Asia Pacific (Sydney)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;54.252.0.0/16 (54.252.0.0 - 54.252.255.255) 54.253.0.0/16 (54.253.0.0 - 54.253.255.255) 54.206.0.0/16 (54.206.0.0 - 54.206.255.255) 54.79.0.0/16 (54.79.0.0 - 54.79.255.255)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Asia Pacific (Tokyo)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;175.41.192.0/18 (175.41.192.0 - 175.41.255.255) 46.51.224.0/19 (46.51.224.0 - 46.51.255.255) 176.32.64.0/19 (176.32.64.0 - 176.32.95.255) 103.4.8.0/21 (103.4.8.0 - 103.4.15.255) 176.34.0.0/18 (176.34.0.0 - 176.34.63.255) 54.248.0.0/15 (54.248.0.0 - 54.249.255.255) 54.250.0.0/16 (54.250.0.0 - 54.250.255.255) 54.238.0.0/16 (54.238.0.0 - 54.238.255.255) 54.199.0.0/16 (54.199.0.0 - 54.199.255.255) 54.178.0.0/16 (54.178.0.0 - 54.178.255.255) NEW&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;South America (Sao Paulo)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;177.71.128.0/17 (177.71.128.0 - 177.71.255.255) 54.232.0.0/16 (54.232.0.0 - 54.232.255.255) 54.233.0.0/18 (54.233.0.0 - 54.233.63.255) 54.207.0.0/16 (54.207.0.0 - 54.207.255.255)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;GovCloud&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;96.127.0.0/18 (96.127.0.0 - 96.127.63.255)&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>Ruby ActiveMerchant sample code for WorldPay</title><link>https://blog.teraren.com/posts/qiita-20140226-66a5eb548386e70f519b/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20140226-66a5eb548386e70f519b/</guid><description>RubyのActiveMerchant gemを使ったWorldPay決済（認証・キャプチャ・継続課金）のサンプルコード。</description><pubDate>Wed, 26 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;
require &apos;active_merchant&apos;
require &apos;pp&apos;
 
currency = &apos;USD&apos;
 
gateway = ActiveMerchant::Billing::WorldpayGateway.new(
  :login =&amp;gt; &apos;YOUR_MERCHANT_ID&apos;,
  :password =&amp;gt; &apos;YOUR_XML_PASSWORD&apos;,
  :test =&amp;gt; true,
)
 
money = 100
 
 
credit_card = ActiveMerchant::Billing::CreditCard.new(
  :number             =&amp;gt; &quot;4444333322221111&quot;,
  :month              =&amp;gt; &quot;12&quot;,
  :year               =&amp;gt; Time.now.year + 1,
  :brand              =&amp;gt; :visa,
  :first_name         =&amp;gt; &apos;first&apos;,
  :last_name          =&amp;gt; &apos;last&apos;,
)
 
order_id = &apos;label-&apos; + Time.now.to_i.to_s
 
 
 
# 1. authorization
response1 = gateway.authorize(money, credit_card, {
  :order_id =&amp;gt; order_id,
  :currency =&amp;gt; currency,
})
 
pp response1
 
 
# 2. capture
#response2 = gateway.capture(money, response1.authorization, {
#  :authorization_validated =&amp;gt; true, # avoid order status query
#})
#pp response2
 
# 3. void
#response3 = gateway.void(response1.authorization)
#pp response3
 
 
# 4. Reccuring payment (payAsOrder)
# Specify initial order_id instead of credit card comparing to the 1st payment.
subsequent_order_id = &apos;label-subsequent-&apos; + Time.now.to_i.to_s
response4 = gateway.authorize(money, order_id, {
  :order_id =&amp;gt; subsequent_order_id,
  :currency =&amp;gt; currency,
})
 
pp response4


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;quoted from
https://blog.teraren.com/2014/02/25/worldpay-activemerchant/&lt;/p&gt;
</content:encoded></item><item><title>Tmuxのバージョンを上げたらアタッチできなくなった場合の対処（Macのhomebrew版)</title><link>https://blog.teraren.com/posts/qiita-20140226-e7a77a0ca393d4dfdce6/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20140226-e7a77a0ca393d4dfdce6/</guid><description>`brew upgrade` して、`tmux a` したけど、以下のエラーが表示されてしまい、attach 出来なくなった。</description><pubDate>Wed, 26 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;brew upgrade&lt;/code&gt; して、&lt;code&gt;tmux a&lt;/code&gt; したけど、以下のエラーが表示されてしまい、attach 出来なくなった。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% tmux a
protocol version mismatch (client 8, server 7)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;解決方法&lt;/h2&gt;
&lt;p&gt;homebrewの場合は、cleanupしていなければ過去のバイナリが存在しているので、それを使えば解決。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/usr/local/Cellar/tmux/1.8/bin/tmux a
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;ちゃんとセッションを全て落としてから新しいバージョンにしましょう。&lt;/p&gt;
</content:encoded></item><item><title>WorldPayのActiveMerchantサンプルコード</title><link>https://blog.teraren.com/posts/worldpay-activemerchant/</link><guid isPermaLink="true">https://blog.teraren.com/posts/worldpay-activemerchant/</guid><description>WorldPayのActiveMerchantサンプルコード</description><pubDate>Tue, 25 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ドキュメント無さ過ぎて困るのでAPI呼び出しのサンプルコードを書いておきます。&lt;/p&gt;
&lt;p&gt;ruby2.0.0で検証&lt;/p&gt;
</content:encoded></item><item><title>Google driveのマイドライブに共有フォルダへのショートカットを作る方法</title><link>https://blog.teraren.com/posts/google-docs-my-drive-shortcut/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-docs-my-drive-shortcut/</guid><description>Google driveのマイドライブに共有フォルダへのショートカットを作る方法</description><pubDate>Mon, 24 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;macosの場合、Google DriveのWeb上でショートカットを作成したいフォルダを&lt;strong&gt;ドラッグしている間に、Option(Alt)キーを押す&lt;/strong&gt;と、ドラッグ中のカーソルが変わり、その状態でマイドライブへドロップ。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/07/image-2.png&quot; alt=&quot;Google driveのフォルダをマイドライブにショートカットとして登録&quot; /&gt;&lt;/p&gt;
&lt;p&gt;https://youtu.be/p1aywmQB5Ps&lt;/p&gt;
&lt;h2&gt;マイドライブから削除したい場合&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;マイドライブ上で、ショートカットを削除する意識で削除してしまうと元々あったフォルダも消えてしまう。なぜなら、マイドライブに移した時点でハードリンクのような扱いになっているからです。&lt;/li&gt;
&lt;li&gt;マイドライブから削除したい場合は元々あったところに、マイドライブからドラッグ＆ドロップすれば消えます。元のフォルダは消えないです。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>最短でRails4をherokuで動かす方法</title><link>https://blog.teraren.com/posts/rails4-heroku/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails4-heroku/</guid><description>最短でRails4をherokuで動かす方法</description><pubDate>Sun, 23 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://devcenter.heroku.com/articles/sqlite3&quot;&gt;herokuでSQLiteが無効化&lt;/a&gt;され、簡単にherokuでRailsプロジェクトを公開出来なくなってしまいました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;       An error occurred while installing sqlite3 (1.3.8), and Bundler cannot continue.
       Make sure that `gem install sqlite3 -v &apos;1.3.8&apos;` succeeds before bundling.
 !
 !     Failed to install gems via Bundler.
 !
 !     Detected sqlite3 gem which is not supported on Heroku.
 !     https://devcenter.heroku.com/articles/sqlite3
 !

 !     Push rejected, failed to compile Ruby app
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そこで、最低限必要な設定をドキュメントにまとめました。&lt;br /&gt;
&lt;a href=&quot;https://github.com/matsubo/rails4heroku/blob/master/README.md&quot;&gt;https://github.com/matsubo/rails4heroku/blob/master/README.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ソースコードもあります。&lt;br /&gt;
&lt;a href=&quot;https://github.com/matsubo/rails4heroku&quot;&gt;https://github.com/matsubo/rails4heroku&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Yahoo!のFastPayまとめ</title><link>https://blog.teraren.com/posts/yahoo-fastpay/</link><guid isPermaLink="true">https://blog.teraren.com/posts/yahoo-fastpay/</guid><description>Yahoo!が2014年春にリリースしたクレジット決済サービスFastPayのビジネスモデル・API仕様・PHPサンプルコードをまとめた解説記事</description><pubDate>Mon, 17 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;概要&lt;/h3&gt;
&lt;p&gt;Yahoo!が春にリリース予定の&lt;a href=&quot;https://fastpay.yahoo.co.jp/&quot;&gt;FastPay&lt;/a&gt;を簡単にまとめてみます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/02/Screen-Shot-2014-02-17-at-1.22.48-AM.png&quot; alt=&quot;fastpay&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;ビジネス関連&lt;/h3&gt;
&lt;p&gt;普通、日本国内でオンライン決済をするために、クレジットカード決済を導入しようとなると以下の手数料がかかる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;初期費用&lt;/li&gt;
&lt;li&gt;月額費用&lt;/li&gt;
&lt;li&gt;トランザクション費用（/件）&lt;/li&gt;
&lt;li&gt;決済手数料(売上金額に対するパーセンテージ)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;FastPayでは上の3つは無料。一番下の項目は2014/3/3発表予定となっている。&lt;/p&gt;
&lt;p&gt;Yahooショッピング無料化の流れで考えると、業界最安値を出すと思われる。&lt;/p&gt;
&lt;h3&gt;利用方法&lt;/h3&gt;
&lt;p&gt;当初のサンプルコードから、&lt;a href=&quot;https://stripe.com/&quot;&gt;Stripe&lt;/a&gt;互換のREST APIを提供するかと思いきや、ちょっと違うAPIを提供しました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/02/Screen-Shot-2014-02-17-at-1.21.51-AM.png&quot; alt=&quot;Screen Shot 2014-02-17 at 1.21.51 AM&quot; /&gt;&lt;/p&gt;
&lt;p&gt;シーケンス図を書くのが面倒なので、デモ決済でUXを確認してみてください。&lt;br /&gt;
&lt;a href=&quot;https://matsu.teraren.com/static/fast_pay/&quot;&gt;https://matsu.teraren.com/static/fast_pay/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;（&lt;a href=&quot;https://github.com/matsubo/fast_pay&quot;&gt;ソースコード&lt;/a&gt;）&lt;/p&gt;
&lt;p&gt;要は、決済導入サイトにYahoo決済ボタンを設置し、ユーザはYahooのモーダルウィンドウでクレジットカード情報を入力し、トークンを取得。そのトークンを利用して決済します。&lt;/p&gt;
&lt;h4&gt;良い点&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;クレジットカード情報はユーザサイトに一切保存されない&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;悪い点・改善点&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;token取得タイミングと、決済タイミングが異なるので、カード情報入力タイミングで見せる値段と、実際に決済される金額が異なっても決済出来てしまう。これは大問題なので公式リリースまでに改善されるだろう。&lt;/li&gt;
&lt;li&gt;設置サイトには必ずYahoo決済ボタンを表示する必要がある&lt;/li&gt;
&lt;li&gt;フィーチャーフォンには対応出来ない&lt;/li&gt;
&lt;li&gt;サンプルで提供されているコードがいまいち。&lt;a href=&quot;/posts/composer/&quot;&gt;composer&lt;/a&gt;対応して欲しい。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;まとめ&lt;/h3&gt;
&lt;p&gt;既存の決済代行会社が提供しているAPIのリプレイスにはならず、かといって、gumroadなどのように簡単に商品を販売するような機能ではないので、どんなマーケットを狙っているのかが不明瞭なので、現時点では既存マーケットの驚異的な存在にはなり得ないかと思っています。&lt;/p&gt;
&lt;p&gt;現時点、APIにクリティカルな欠陥があります。&lt;/p&gt;
&lt;p&gt;とりあえず、もうすこし具体的な発表を待つために、3月3日に期待します。&lt;/p&gt;
&lt;p&gt;いづれにせよ、日本の決済代行手数料は高すぎなので、Yahoo BBの時のような既存マーケットの価格破壊を起こして、決済業界に一石を投じて欲しいです。&lt;/p&gt;
</content:encoded></item><item><title>Webサイトの更新を逐一知るためのスクリプト</title><link>https://blog.teraren.com/posts/gem/</link><guid isPermaLink="true">https://blog.teraren.com/posts/gem/</guid><description>RubyのWebサイト更新チェッカーgemを自作・公開。指定URLの変化を検知してメール通知するツールの作成方法とgem公開手順を解説。</description><pubDate>Sun, 16 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Rubyを仕事で書き始めて1ヶ月半が経過しました。&lt;/li&gt;
&lt;li&gt;ほんと、gemのおかげで書くコードが少なくて大変助かっております。&lt;/li&gt;
&lt;li&gt;ということで、そのgemに貢献するためにも、ある程度汎用性のある機能が出来たらgem作っていこうと思っています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;作ったもの&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;まず、第1弾として、&lt;a href=&quot;http://ja.asciicasts.com/episodes/245-new-gem-with-bundler&quot;&gt;Webサイトチェッカー&lt;/a&gt;を作りました。&lt;/li&gt;
&lt;li&gt;あるページが更新されたあとすぐに更新を知るためのスクリプトです。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/web_update_checker&quot;&gt;ソースコード&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;gemの作成に関しては&lt;a href=&quot;http://morizyun.github.io/blog/ruby-gem-easy-publish-library-rails/&quot;&gt;こちらのサイト通り&lt;/a&gt;に作れば問題無かったです。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/02/gem.png&quot; alt=&quot;gem&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;使い方&lt;/h2&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;Add this line to your application&apos;s Gemfile:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gem &apos;web_update_checker&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And then execute:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ bundle
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or install it yourself as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gem install web_update_checker
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Usage&lt;/h3&gt;
&lt;p&gt;main.rb&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;regex = /&amp;lt;h1&amp;gt;(.*)&amp;lt;\/h1&amp;gt;/

mail = Mail.new do
from    &apos;TODO@example.com&apos;
to      &apos;TODO@example.com&apos;
subject &apos;Web site is updated!&apos;
body     @url
end

mail.delivery_method :smtp, {
address:   &apos;localhost&apos;,
             port:      25,
}

url = &apos;http://example.com/&apos;
WebUpdateChecker::Checker.new(url, regex, mail).execute
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Execute like a following CLI&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% while [ true ]; do; ruby main.rb; sleep 30; done
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Railsでcontroller名、action名に対応したjsファイルを読み込む</title><link>https://blog.teraren.com/posts/rails-javascript-corresponding-to-controller-action/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rails-javascript-corresponding-to-controller-action/</guid><description>Railsでcontroller名、action名に対応したjsファイルを読み込む</description><pubDate>Wed, 12 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;個別actionごとにjsファイルを定義したいとき。&lt;/p&gt;
&lt;p&gt;たとえば、&lt;/p&gt;
&lt;p&gt;&lt;code&gt;app/assets/[コントローラ名]/[アクション名].js&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;を対応したテンプレで読み込む。&lt;/p&gt;
&lt;p&gt;app/views/layout/application.htmlなどのレイアウトファイルに以下のように記述。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;%= javascript_include_tag params[:controller] if AppName::Application.assets.find_asset(&apos;#{params[:controller]}.js&apos;) %&amp;gt;
&amp;lt;%= javascript_include_tag &apos;#{params[:controller]}/#{params[:action]}&apos;  if AppName::Application.assets.find_asset(&apos;#{params[:controller]}/#{params[:action]}.js&apos;) %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Rails 4.0.xで検証。Rails 3でも動くっぽい。&lt;/p&gt;
&lt;h3&gt;参考&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://stackoverflow.com/questions/6571753/rails-3-1-asset-pipeline-how-to-load-controller-specific-scripts&quot;&gt;http://stackoverflow.com/questions/6571753/rails-3-1-asset-pipeline-how-to-load-controller-specific-scripts&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>herokuでPostGIS</title><link>https://blog.teraren.com/posts/heroku-postgis/</link><guid isPermaLink="true">https://blog.teraren.com/posts/heroku-postgis/</guid><description>HerokuでPostGISを使うにはStandardプラン以上が必要。エクステンションの有効化から空間クエリの実行まで、公式ドキュメントに載っていない手順を補足</description><pubDate>Mon, 10 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Herokuでβですが、Postgisが使えます。&lt;/p&gt;
&lt;p&gt;マニュアルはこちらに載っていますが、&lt;strong&gt;あまり詳しく載っていないので、ちょっと調べないとわからないことを書いておきます&lt;/strong&gt;。&lt;br /&gt;
&lt;a href=&quot;https://devcenter.heroku.com/articles/postgis&quot;&gt;https://devcenter.heroku.com/articles/postgis&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;料金&lt;/h3&gt;
&lt;p&gt;Hobbyプランの中にある、&lt;strong&gt;Dev(Free)と Basic($9/month)では、利用出来ません。&lt;/strong&gt;&lt;br /&gt;
Standard以降のプランで利用出来ます。Standardの&lt;strong&gt;最低料金は$50/month&lt;/strong&gt;となっています。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/02/Screenshot_2_10_14__1_23_AM.png&quot; alt=&quot;heroku plan postgis&quot; /&gt;&lt;/p&gt;
&lt;p&gt;おそらく、Hobbyプランは共有DBインスタンスなのに対し、Standard以降は個別インスタンスで提供されています。&lt;/p&gt;
&lt;h3&gt;使えるバージョン&lt;/h3&gt;
&lt;p&gt;2014/2/10時点&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;db82f4u7e5dee4=&amp;gt; SELECT PostGIS_full_version();
                                                                             postgis_full_version
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 POSTGIS=&quot;2.1.1 r12113&quot; GEOS=&quot;3.4.2-CAPI-1.8.2 r3921&quot; PROJ=&quot;Rel. 4.8.0, 6 March 2012&quot; GDAL=&quot;GDAL 1.10.0, released 2013/04/24&quot; LIBXML=&quot;2.7.8&quot; LIBJSON=&quot;UNKNOWN&quot; TOPOLOGY RASTER
(1 row)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;% heroku pg:psql
db82f4u7e5dee4=&amp;gt; SELECT version();
                                                  version
------------------------------------------------------------------------------------------------------------
 PostgreSQL 9.3.2 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit
(1 row)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;PostGISの有効化の方法&lt;/h3&gt;
&lt;p&gt;まず、StandardプランのDBインスタンスを追加します。インスタンスが用意されるので、&lt;strong&gt;10分ぐらいかかります&lt;/strong&gt;。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% heroku addons:add heroku-postgresql:standard-yanari
% heroku pg:wait
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;おそらく、デフォルトはDevのDBサーバになっているので、新しく追加したDBを&lt;strong&gt;デフォルトのDBサーバに昇格&lt;/strong&gt;しておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% heroku pg:promote HEROKU_POSTGRESQL_BLUE_URL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そして、やっとPostGISを有効化できます。これで準備完了。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% heroku pg:psql
&amp;gt; CREATE EXTENSION postgis;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2014/02/create.png&quot; alt=&quot;create&quot; /&gt;&lt;/p&gt;
&lt;p&gt;あとは、手元にあるPostgresのdumpを流しこんだりするだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% pg_dump |heroku pg:psql
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>MySQL 5.6 minor query optimizer tips</title><link>https://blog.teraren.com/posts/mysql-5-6-minor-query-optimizer-tips/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-5-6-minor-query-optimizer-tips/</guid><description>MySQL 5.6 minor query optimizer tips</description><pubDate>Mon, 20 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;... date_add(NOW(), interval -60 day) &amp;lt; column
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当たり前と言えば当たり前ですが、上記の検索はfull scanになっちゃうんですね。&lt;/p&gt;
&lt;p&gt;左辺が変数に展開されるのかと思いきや、展開されないです。なので、一度変数に入れてから実行するなり、プログラム側で計算してから発行しないとだめです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set @date_restriction = date_add(NOW(), interval -60 day);
... @date_restriction &amp;lt; column
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;おそらく、binlogとかの関係でこうなっちゃっているのかなーと思う。&lt;br /&gt;
これを踏まえて、SQLをできるだけ静的に書かないといけませんねぇ。。。&lt;br /&gt;
今までコードレビューでも見逃している疑惑が。。。。&lt;/p&gt;
</content:encoded></item><item><title>Wrote sample code for gioco</title><link>https://blog.teraren.com/posts/wrote-sample-code-for-gioco/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wrote-sample-code-for-gioco/</guid><description>Wrote sample code for gioco</description><pubDate>Tue, 07 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;railsにおいて、ゲーミフィケーション要素を追加するためのgemがあります。 主な機能は以下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;バッジ&lt;/li&gt;
&lt;li&gt;ポイント （1モデルに対して1カレンシー）&lt;/li&gt;
&lt;li&gt;上2つのバッジとポイントを組み合わせて、あるポイントに達成したらバッジを自動付与&lt;/li&gt;
&lt;li&gt;ポイントランキング&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ドキュメントがわかりづらかったので、サンプルコード書きました。 &lt;a href=&quot;https://github.com/matsubo/gioco_sample&quot;&gt;https://github.com/matsubo/gioco_sample&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>GrowthForecastでOS監視</title><link>https://blog.teraren.com/posts/growthforecast-macos/</link><guid isPermaLink="true">https://blog.teraren.com/posts/growthforecast-macos/</guid><description>kazeburo製のグラフ描画ツールGrowthForecastをMac OS X MavericksにインストールしてCPUやメモリ使用率を可視化する手順</description><pubDate>Wed, 25 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;概要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Adventに空きがあったので、&lt;a href=&quot;http://qiita.com/advent-calendar/2013/perl&quot;&gt;Perl Advent Calendar 2013&lt;/a&gt;の22日目を書きます。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://x.com/kazeburo&quot;&gt;@kazeburo&lt;/a&gt;さんの&lt;a href=&quot;http://kazeburo.github.io/GrowthForecast/&quot;&gt;GrowthForecast&lt;/a&gt;でMac OS X 10.9 (Mavericks)のリソース監視をする方法を書きます。&lt;/li&gt;
&lt;li&gt;結果としては以下のようになります。
&lt;ul&gt;
&lt;li&gt;デモ（リソース監視）: &lt;a href=&quot;https://matsu.teraren.com/GrowthForecast/list/host/teraren&quot;&gt;https://matsu.teraren.com/GrowthForecast/list/host/teraren&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;デモ（通貨ログ）: &lt;a href=&quot;https://matsu.teraren.com/GrowthForecast//list/currency/rate-exchange?t=sh&quot;&gt;https://matsu.teraren.com/GrowthForecast//list/currency/rate-exchange?t=sh&lt;br /&gt;
&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/12/Screen-Shot-2013-12-25-at-9.11.18-AM.png&quot; alt=&quot;GrowthForecast&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;GrowthForecastのインストール&lt;/h3&gt;
&lt;p&gt;こちらを参考に行います。Mac OS Xでもほとんどこれの通りにインストール出来ました。&lt;/p&gt;
&lt;p&gt;http://qiita.com/harukasan/items/9f37df54ca5700d5de77&lt;/p&gt;
&lt;p&gt;起動オプションはこちら。&lt;/p&gt;
&lt;p&gt;perl growthforecast.pl  --front-proxy=127.0.0.1&lt;/p&gt;
&lt;p&gt;自動起動用&lt;a href=&quot;https://gist.github.com/matsubo/8177644&quot;&gt;.plist&lt;/a&gt;ファイルのサンプル&lt;/p&gt;
&lt;h3&gt;監視Agentの設定&lt;/h3&gt;
&lt;p&gt;監視Agentは、PHPで書きました。&lt;/p&gt;
&lt;p&gt;こちらのREADMEを参考にしてインストールします。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/matsubo/growth_forecast_agent/blob/master/README.md&quot;&gt;https://github.com/matsubo/growth_forecast_agent/blob/master/README.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;私は、1分ごとにcronで起動するように設定してあります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*  *    * * * cd /path/to/bin/ &amp;amp;&amp;amp; php main.php &amp;gt; /tmp/growthforecast.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mac OS XでCLIから温度を取得するために、&lt;a href=&quot;http://www.bresink.com/osx/0TemperatureMonitor/download.php&quot;&gt;Temperture Monitor&lt;/a&gt;をインストールしておきます。&lt;/p&gt;
&lt;h3&gt;GrowthForecastの設定&lt;/h3&gt;
&lt;p&gt;グラフはごとに、単位や係数を設定します。たとえば、小数は扱えないようなので、ロードアベレージは100倍して整数で数字を送っているので÷100します。&lt;/p&gt;
&lt;p&gt;複数の指標を含めたグラフも作成できるので、ロードアベレージやディスク容量などの1つのグラフにまとめられる指標はまとめておきます。&lt;/p&gt;
&lt;h3&gt;Reverse Proxyの設定&lt;/h3&gt;
&lt;p&gt;Apacheの場合の設定はこちら。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;LocationMatch &quot;/GrowthForecast/.*(edit|delete|add_complex)&quot;&amp;gt;
  order allow,deny
  deny from allow
&amp;lt;/LocationMatch&amp;gt;
RequestHeader set Host matsu.teraren.com/GrowthForecast
ProxyPass /GrowthForecast/ http://localhost:5125/ retry=1
ProxyPassReverse /GrowthForecast/ http://localhost:5125/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;アプリケーション側で、Host環境変数を参考にpathを生成しているので、Host環境変数を適宜変更します。&lt;/p&gt;
&lt;h3&gt;まとめ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ハードコードが多くて恐縮ですが、GrowthForecastを利用してサーバ監視を簡単に行えます。&lt;/li&gt;
&lt;li&gt;デモ: &lt;a href=&quot;https://matsu.teraren.com/GrowthForecast/list/host/teraren&quot;&gt;https://matsu.teraren.com/GrowthForecast/list/host/teraren&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GrowthForecastはかなり簡単にグラフ作成できるので、任意の数値を監視するのにとても便利なので1つ立ち上げておくと重宝するかと思います。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>CPIの稼働率低い。SLA返金してくれない。</title><link>https://blog.teraren.com/posts/cpi-sla/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cpi-sla/</guid><description>CPIの稼働率低い。SLA返金してくれない。</description><pubDate>Fri, 20 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.cpi.ad.jp/&quot;&gt;CPI&lt;/a&gt;が100%稼働保証と謳っているのに、返金対応してくれない。&lt;br /&gt;
なんなんだか。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/11/trend.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;KDDIってそんなもんなんだろうな。&lt;/p&gt;
&lt;p&gt;名ばかりのSLA。契約違反で返金のはずなのになー。ひどい対応。&lt;/p&gt;
</content:encoded></item><item><title>MySQLでindexが効いていないクエリーを調査</title><link>https://blog.teraren.com/posts/mysql-optimize-query/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-optimize-query/</guid><description>MySQLでindexが効いていないクエリーを調査</description><pubDate>Fri, 20 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;以下で現在の設定を確認&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; show variables like &apos;log_queries_not_using_indexes&apos;;
mysql&amp;gt; show variables like &apos;query_cache_type&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;index効いていないクエリーをログに出す&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; set global log_queries_not_using_indexes = 1;
mysql&amp;gt; SET GLOBAL query_cache_type = OFF;
mysql&amp;gt; FLUSH QUERY CACHE;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記を実行した後に、以下のコマンドでindexが効いていないクエリーの集計。&lt;br /&gt;
（実行回数順で、トップ20を表示）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% mysqldumpslow  -s c -t 20 /var/log/mysql/slow.log
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>メーカーによって20％違う。SDカードベンチマーク</title><link>https://blog.teraren.com/posts/sd-benchmark-32gb/</link><guid isPermaLink="true">https://blog.teraren.com/posts/sd-benchmark-32gb/</guid><description>メーカーによって20％違う。SDカードベンチマーク</description><pubDate>Fri, 13 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2種類のSDカードをベンチマークしてみました。SDカードにも特性があることがわかります。&lt;/p&gt;
&lt;h2&gt;東芝 SDHC カード 32GB クラス10 UHS-I 30MB/s 並行輸入品&lt;/h2&gt;
&lt;p&gt;::amazon{asin=&quot;B00DGQXQ42&quot;}&lt;/p&gt;
&lt;p&gt;ちなみに、こちらは5年保証&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-2.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Kingston SDHCカード 32GB Class10 Generation 2 SD10G2/32GB KF-C1732-4R&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://amzn.to/3lYQ0ap&quot;&gt;Kingston SDHCカード 32GB Class10 Generation 2 SD10G2/32GB KF-C1732-4R&lt;/a&gt;こちらは永久保証。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00EU7Q0YY&quot;}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>コピペで出来るComposer導入</title><link>https://blog.teraren.com/posts/composer/</link><guid isPermaLink="true">https://blog.teraren.com/posts/composer/</guid><description>PHPのパッケージ管理ツールComposerをコピペだけで導入できるよう、インストールからライブラリの追加まで手順をステップごとに解説します。</description><pubDate>Tue, 03 Dec 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;概要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.toshimaru.net/php-force-property/&quot;&gt;1日目の「PHPのプロパティをStrictに定義する」&lt;/a&gt;に続きまして、&lt;a href=&quot;http://www.adventar.org/calendars/101&quot;&gt;PHP Advent Calendar 2013 2日目&lt;/a&gt;です&lt;/li&gt;
&lt;li&gt;今後、&lt;a href=&quot;http://getcomposer.org/&quot;&gt;Composer&lt;/a&gt;ベースでの記事が出来ると思うので、早めに解説しておきます！&lt;/li&gt;
&lt;li&gt;コピペで導入できるように心がけます。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Composerとは&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;PHPのライブラリ依存管理のデファクトスタンダードなパッケージ管理ツールです。Rubyのgem,PerlのCPANにあたるツールです。&lt;/li&gt;
&lt;li&gt;PHPのライブラリ管理ツールとして、&lt;a href=&quot;http://pear.php.net/&quot;&gt;PEAR&lt;/a&gt;や&lt;a href=&quot;http://pear2.php.net/&quot;&gt;PEAR2&lt;/a&gt;などがありますが、昨今のライブラリの管理はComposerに統一されつつあります。&lt;/li&gt;
&lt;li&gt;また、PHPで自作したライブラリを他の開発者に利用してもらうためにも、Composerで導入出来るようにしておくと利用されやすくなります。&lt;/li&gt;
&lt;li&gt;対応環境は PHP 5.3.2+です&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;導入&lt;/h3&gt;
&lt;p&gt;Composerは、既存のプロジェクトなどにも簡単に導入できます。&lt;/p&gt;
&lt;h4&gt;アプリを構築するディレクトリを作ります&lt;/h4&gt;
&lt;p&gt;今回はスクラッチからアプリを作成することを想定します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% mkdir app
% cd app
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Composerをインストールします&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;% curl -sS https://getcomposer.org/installer | php
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;composer.pharというファイルが作成されます。&lt;br /&gt;
composer.pharはPHPプログラムのアーカイブです。&lt;/p&gt;
&lt;h4&gt;ライブラリをインストールします&lt;/h4&gt;
&lt;p&gt;guzzleという、HTTPクライアントをインストールしてみます。&lt;br /&gt;
composer.jsonに利用するライブラリの設定を書き込みます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% echo &apos;{
    &quot;require&quot;: {
        &quot;guzzle/guzzle&quot;: &quot;~3.7&quot;
    }
}&apos; &amp;gt; composer.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;requireキーに、ライブラリ名とそのバージョン指定を記載します。ライブラリ名は&lt;a href=&quot;https://github.com/guzzle/guzzle&quot;&gt;packagist&lt;/a&gt;で検索できます。&lt;/p&gt;
&lt;p&gt;composerのupdateサブコマンドで、必要ファイルをダウンロードします。この際、依存するパッケージがある場合は自動的に依存するファイルもダウンロードされます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% php composer.phar update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;初めてupdateコマンドを実行すると、composer.lockとvendorディレクトリが作成されます。&lt;br /&gt;
composer.lockには、現在利用しているライブラリの名前とバージョンが記載されます。vendorディレクトリには、ライブラリ自体のファイルなどが保存されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ls
composer.json  composer.lock  composer.phar  vendor/
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;ライブラリを利用する&lt;/h4&gt;
&lt;p&gt;Yahoo! Japanへ接続して、コードを表示するスクリプトを書いてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% vi test.php
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ファイルの中身&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
// クラスローダーを読み込む
require &apos;vendor/autoload.php&apos;;

// ヤフーへ接続するHTTPクライアントのインスタンスを作成
$client = new \Guzzle\Http\Client(&apos;http://www.yahoo.co.jp/&apos;);

// GETリクエストを送る準備
$request = $client-&amp;gt;get(&apos;/&apos;);

// HTTPリクエストを送信
$response = $request-&amp;gt;send();

// レスポンスを表示
print_r($response);
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;実行してみます&lt;/h4&gt;
&lt;p&gt;とりあえず、HTTPレスポンスが出力されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% php test.php | head
HTTP/1.1 200 OK
Date: Mon, 02 Dec 2013 15:22:10 GMT
P3P: policyref=&quot;http://privacy.yahoo.co.jp/w3c/p3p.xml&quot;, CP=&quot;CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV&quot;
Expires: -1
Pragma: no-cache
Cache-Control: private, no-cache, no-store, must-revalidate
X-XRDS-Location: http://open.login.yahoo.co.jp/openid20/www.yahoo.co.jp/xrds
Vary: Accept-Encoding
Connection: close
Transfer-Encoding: chunked
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;まとめ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Composerをインストールし、guzzleライブラリをインストールしました&lt;/li&gt;
&lt;li&gt;guzzleを使ってPHPスクリプトを作成しました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Facebook pageのlike数をトラッキングするサービス</title><link>https://blog.teraren.com/posts/facebook-page-like-tracking/</link><guid isPermaLink="true">https://blog.teraren.com/posts/facebook-page-like-tracking/</guid><description>Facebook公式が公開しないLike数の推移を記録するトラッキングサービスを自作。Redis・Slim・Twigで構築し5年間運営した後、アクセス伸び悩みで2018年に停止。</description><pubDate>Sun, 17 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Facebook自体はlike数の履歴を公開していないので、Facebookのlike数をトラッキングするサービスを作りました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://matsu.teraren.com/facebook_page_tracking/&quot;&gt;https://matsu.teraren.com/facebook_page_tracking/&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TSV生データも提供しています。&lt;/li&gt;
&lt;li&gt;AM2時にクロールしています&lt;/li&gt;
&lt;li&gt;オープンソースです&lt;/li&gt;
&lt;li&gt;ソースコード：&lt;a href=&quot;https://github.com/matsubo/facebook_page_tracking&quot;&gt;https://github.com/matsubo/facebook_page_tracking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2年前に数時間で作った適当なサービスです&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2013/11/20 追記&lt;/h3&gt;
&lt;p&gt;いろいろ機能変更しました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ソースコードはクローズドにしました。&lt;/li&gt;
&lt;li&gt;ストレージはRedisを利用&lt;/li&gt;
&lt;li&gt;ミドルウェア：Slim + Twig + phpredis&lt;/li&gt;
&lt;li&gt;TSVによる生データではなく、JSONで提供&lt;/li&gt;
&lt;li&gt;URLは変更なし。&lt;a href=&quot;http://facebook-page.teraren.com/&quot;&gt;http://facebook-page.teraren.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2015/11/15 追記&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;URLを変更&lt;/li&gt;
&lt;li&gt;パフォーマンス改善、API仕様変更&lt;/li&gt;
&lt;li&gt;グラフ表示速度改善&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2018/3/1 サービス停止&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;アクセスが思ったより伸びなかったのと、メンテナンスが面倒なので停止しました。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Macでcrontab -e がエラーになる</title><link>https://blog.teraren.com/posts/mac-crontab/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-crontab/</guid><description>Macでcrontab -e がエラーになる</description><pubDate>Sun, 17 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Mac OS X 10.5あたりから、crontabが保存出来ない。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% crontab -e
crontab: &quot;vi&quot; exited with status 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;おそらく問題はvimをbrew経由で入れているから。OS付属のvimを使えば大丈夫。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% EDITOR=/usr/bin/vim crontab -e
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>DMM Affiliate APIをPHPから呼び出すライブラリ作りました</title><link>https://blog.teraren.com/posts/dmm-affiliate-api-php/</link><guid isPermaLink="true">https://blog.teraren.com/posts/dmm-affiliate-api-php/</guid><description>DMM Affiliate APIをPHPから呼び出すライブラリ作りました</description><pubDate>Sat, 02 Nov 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;composer対応です。&lt;br /&gt;
&lt;a href=&quot;https://github.com/matsubo/dmm&quot;&gt;https://github.com/matsubo/dmm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://getcomposer.org/&quot;&gt;Composer&lt;/a&gt;を使っている場合は、以下でインストール&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% php composer.phar install
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;サンプルコード&lt;/h2&gt;
</content:encoded></item><item><title>SSH login is refused after upgrading to Mac OS X Mavericks (10.9)</title><link>https://blog.teraren.com/posts/ssh-login-is-refused-after-upgraded-to-mac-marvericks/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ssh-login-is-refused-after-upgraded-to-mac-marvericks/</guid><description>SSH login is refused after upgrading to Mac OS X Mavericks (10.9)</description><pubDate>Mon, 28 Oct 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;I&apos;m using Mac OS X as a internet hosting server. The server provides ssh remote login, apache, mysql and so on.&lt;/p&gt;
&lt;h2&gt;Issue&lt;/h2&gt;
&lt;p&gt;After I upgraded my Mac OS X from 10.8 to 10.9, sshd does not accept all users&apos; remove login via ssh.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;To resolve this issue, hit the following command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dscl . change /Groups/com.apple.access_ssh RecordName com.apple.access_ssh com.apple.access_ssh-disabled
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I found this here.&lt;br /&gt;
&lt;a href=&quot;http://superuser.com/questions/166179/how-to-enable-remote-access-for-another-account-on-mac-remotely-via-ssh&quot;&gt;http://superuser.com/questions/166179/how-to-enable-remote-access-for-another-account-on-mac-remotely-via-ssh&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Syntax Error出て欲しいけど出ない</title><link>https://blog.teraren.com/posts/expecting-syntax-error-but-not/</link><guid isPermaLink="true">https://blog.teraren.com/posts/expecting-syntax-error-but-not/</guid><description>Syntax Error出て欲しいけど出ない</description><pubDate>Fri, 25 Oct 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;これ、syntax error出て欲しいけど、通っちゃう。
8行目&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
class Sample
{
    const HOGE = &apos;hoge&apos;;
    public function execute()
    {
        switch (true) {
        case self:HOGE:
            return 1;
        }
    }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PHP5.3.10&lt;/p&gt;
</content:encoded></item><item><title>tloadコマンド</title><link>https://blog.teraren.com/posts/tload-command/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tload-command/</guid><description>tloadコマンド</description><pubDate>Thu, 03 Oct 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Load AverageをCLIでグラフィカルに表示。&lt;/p&gt;
&lt;p&gt;いつもは、dstat垂れ流しているけど、視覚的にすぐわかるから便利。&lt;/p&gt;
&lt;p&gt;スケールがデフォルトだとload average 2 = 100% なので、CPU数に応じてスケールを100％表示にするコマンド&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% tload -d 1 -s `cat  /proc/cpuinfo|grep processor|wc -l`
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;追記: ttyload&lt;/h2&gt;
&lt;p&gt;色が付いたやつを見つけた。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/10/Screen-Shot-2013-10-08-at-16.27.10.png&quot; alt=&quot;ttyload&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>awkでアクセスログ集計</title><link>https://blog.teraren.com/posts/awk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/awk/</guid><description>awkでアクセスログ集計</description><pubDate>Wed, 25 Sep 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;アクセスログ集計するときのawkワンライナーメモ&lt;/p&gt;
&lt;p&gt;前提となるデータ。access.tsv&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;アクション名 レスポンスタイム
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;アクション毎の平均レスポンスタイムを遅い順で表示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% awk &apos; { total[$1] += $2 } { count[$4]++ } END { for (x in total) { printf &quot;%s\t%f sec\n&quot;, x, total[x]/count[x] } } &apos; access.tsv | expand -t 50 | sort -k2 -nr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;アクション毎の最も遅いレスポンスタイムを遅い順で表示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% awk &apos; max[$1] &amp;lt; $2 { max[$1] = $2 } END { for (x in max) { printf &quot;%s\t%f sec\n&quot;, x, max[x] } } &apos; access.tsv | expand -t 50 | sort -k 2 -nr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;レスポンスタイムとアクセス数を乗算することで、ユーザへの不快度をスコア化&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% awk &apos; { total[$1] += $2 } { count[$1]++ } END { for (x in total) { printf &quot;%s\t%f\n&quot;, x, total[x]*count[x] } } &apos; access.tsv | expand -t 50 | sort -k 2 -nr
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Macでionice</title><link>https://blog.teraren.com/posts/mac-ionice/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-ionice/</guid><description>Macでionice</description><pubDate>Tue, 17 Sep 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;以下をコピペすれば、ioniceコマンドをインストール出来ます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget https://raw.github.com/elmarb/ionice/master/ionice.c
gcc ionice.c -o ionice
sudo install -o root -g wheel ionice  /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;参考：&lt;br /&gt;
&lt;a href=&quot;https://github.com/elmarb/ionice&quot;&gt;https://github.com/elmarb/ionice&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>rbenvインストール</title><link>https://blog.teraren.com/posts/rbenv/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rbenv/</guid><description>rbenvインストール</description><pubDate>Sun, 11 Aug 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;rvmを2つのシェルから同時に実行してしまい、壊れてしまいました。&lt;br /&gt;
ついでに、rbenvに乗り換えました。&lt;/p&gt;
&lt;p&gt;Mac OSなら以下のコピペでいけます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;brew update
brew install openssl
brew install readline
brew install rbenv
brew install ruby-build
echo &apos;eval &quot;$(rbenv init -)&quot; &apos; &amp;gt;&amp;gt; ~/.zshrc
rbenv install --list
rbenv install 2.0.0-p247
rbenv global 2.0.0-p247
rbenv exec gem install bundler
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>rsyncのスラッシュの扱い</title><link>https://blog.teraren.com/posts/rsync-slash/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rsync-slash/</guid><description>rsyncのコピー元パスにスラッシュを付けるか否かでディレクトリ構造がどう変わるか、実行例を交えてわかりやすく解説</description><pubDate>Tue, 06 Aug 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;fromのディレクトリにスラッシュ付けるときと付けないときで挙動がかわるのですが、挙動が直感的じゃなくて、はまるんですよね。&lt;/p&gt;
&lt;p&gt;まとめ&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;スラッシュを付けないと:そのディレクトリがdestinationに作成される&lt;/li&gt;
&lt;li&gt;スラッシュを付けると:そのディレクトリの中身がdestinationに作成される&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% mkdir from
% mkdir -p from/001/010/100
% mkdir -p from/002/010/100
% rsync -aru from /tmp/dest/
% tree /tmp/dest
/tmp/dest
└── from
    ├── 001
    │   └── 010
    │       └── 100
    └── 002
        └── 010
            └── 100

7 directories, 0 files
% rm -rf /tmp/dest
% rsync -aru from/ /tmp/dest/
% tree /tmp/dest
/tmp/dest
├── 001
│   └── 010
│       └── 100
└── 002
    └── 010
        └── 100

6 directories, 0 files
%
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>やっと公式コーディングルールができた！PHPのコーディングルール</title><link>https://blog.teraren.com/posts/php-coding-rule/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-coding-rule/</guid><description>PHP-FIGが定めたPSR標準コーディング規約と、自動修正ツールPHP-CS-Fixerの使い方を解説。composerでインストールしてドライランで差分確認、Vimプラグインとの連携も紹介。</description><pubDate>Tue, 04 Jun 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;PHPの標準コーディングルール（コーディング規約）は、&lt;a href=&quot;http://www.php-fig.org/&quot;&gt;http://www.php-fig.org/&lt;/a&gt;によって、PSR-0からPSR-3までのドキュメントによって細かく決められています。&lt;/p&gt;
&lt;p&gt;そのコーディングルールに準拠するように自動的にソースコードを修正してくれるスクリプトが以下です。&lt;br /&gt;
&lt;a href=&quot;https://github.com/fabpot/PHP-CS-Fixer&quot;&gt;https://github.com/fabpot/PHP-CS-Fixer&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;使い方&lt;/h2&gt;
&lt;p&gt;composerの場合、composer.jsonへ以下を追記する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;+        &quot;fabpot/php-cs-fixer&quot;: &quot;0.3.*@dev&quot;
+        &quot;sebastian/diff&quot;: &quot;1.0.*@dev&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;% php composer.phar update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;して、&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% vendor/bin/php-cs-fixer fix &amp;lt;target dirctory&amp;gt; --dry-run &amp;lt;/target&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;すると、どのように変更されるかが表示される。--dry-runを外すとソースコードが書き換えられる。&lt;/p&gt;
&lt;p&gt;デフォルトオプションだと16個ぐらいのルールを適用しています。一部のルールを適用したい場合は個別オプションを指定して実行します。マイナスを付けることにより、ブラックリスト指定も個可能です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% vendor/bin/php-cs-fixer fix &amp;lt;target directory&amp;gt; --dry-run --fixers=short_tag,-indentation &amp;lt;/target&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;サンプル&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/matsubo/redis-ranking/commit/b736d39754f576f86b6eb6a42f7cb2b27dc32b8d&quot;&gt;https://github.com/matsubo/redis-ranking/commit/b736d39754f576f86b6eb6a42f7cb2b27dc32b8d&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;vimプラグイン&lt;/h2&gt;
&lt;p&gt;vimからphp-cs-fixerを実行するプラグイン。&lt;br /&gt;
&lt;a href=&quot;https://github.com/stephpy/vim-php-cs-fixer&quot;&gt;https://github.com/stephpy/vim-php-cs-fixer&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>JSON-RPC 2.0のススメ</title><link>https://blog.teraren.com/posts/json-rpc/</link><guid isPermaLink="true">https://blog.teraren.com/posts/json-rpc/</guid><description>JSON-RPC 2.0のススメ</description><pubDate>Thu, 23 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;RESTfulなHTTPリクエストでは、JSONでデータを返すのが一般的ですよね。&lt;br /&gt;
そんなJSONのスキーマが各社ばらばらで、統一感が無いけど、何かしらの仕様があるかと思って探したら、ありました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.jsonrpc.org/specification&quot;&gt;JSON RPC 2.0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;正常系なら、意識しないでデータを直接表現してしまえば良いと思いますが、エラーを表現するときにはある程度仕様に則っておいた方がクライアント・サーバの相互運用性が高まります。&lt;/p&gt;
&lt;p&gt;2.0の仕様は2010-03-26に出ているし、1.0から長く運用されているようだし、様々なユースケースをカバーしているので、JSONをやりとりする場合は、使わない手は無いかと思います。&lt;/p&gt;
&lt;p&gt;プロトコルの内容は以下のような感じで、すごい大枠だけ決まっているので、2分もあれば理解できるでしょう。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--&amp;gt; {&quot;jsonrpc&quot;: &quot;2.0&quot;, &quot;method&quot;: &quot;foobar&quot;, &quot;id&quot;: &quot;1&quot;}
&amp;lt;-- {&quot;jsonrpc&quot;: &quot;2.0&quot;, &quot;error&quot;: {&quot;code&quot;: -32601, &quot;message&quot;: &quot;Method not found&quot;}, &quot;id&quot;: &quot;1&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/JSON-RPC#Implementations&quot;&gt;さまざまな言語のサーバ、クライアントの実装&lt;/a&gt;があるので導入も簡単でしょう。&lt;/p&gt;
</content:encoded></item><item><title>FULCRUM RACING QUATTROを買った</title><link>https://blog.teraren.com/posts/fulcrum-racing-quattro/</link><guid isPermaLink="true">https://blog.teraren.com/posts/fulcrum-racing-quattro/</guid><description>デュアスロン出場のためFULCRUM RACING QUATTRO 2013モデルを購入。直進安定性と剛性の高さ、走り出しの重さの評価と1年後のメンテナンス記録。</description><pubDate>Sun, 19 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.mspo.jp/entry/?evcode=CC13&quot;&gt;6月9日のデュアスロン&lt;/a&gt;に出るために、ちょっとまともなホイール買いました。&lt;/p&gt;
&lt;p&gt;FULCRUM RACING QUATTRO 2013モデル買った。新品で、32k円で、4k円のクーポン付き。1725g&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00FKPELH8&quot;}&lt;/p&gt;
&lt;p&gt;数キロ乗った感じで、今までと比べた感じ：&lt;br /&gt;
いい点：&lt;br /&gt;
直進性能高い。スピードが上がってくると安定する。&lt;br /&gt;
風きり音が少ない。静か。＝エアロダイナミクス性高い。&lt;br /&gt;
剛性は高い。しっかり踏んでもしっかり伝わる。&lt;/p&gt;
&lt;p&gt;悪い点：&lt;br /&gt;
走り出し遅い。重い。&lt;/p&gt;
&lt;p&gt;なにげに、今までは7年前に買った、&lt;a href=&quot;http://www.cbnanashi.com/parts/1489.html&quot;&gt;WH-R550&lt;/a&gt;。1845g(F793g R1052g)。メーターの読みでは15,000kmぐらい乗ってた。&lt;/p&gt;
&lt;h2&gt;追記：2014/8/18&lt;/h2&gt;
&lt;p&gt;1年乗ったので、Y&apos;sロード新宿のカスタム館メンテナンスに出しました。&lt;/p&gt;
&lt;p&gt;メンテナンス結果：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;フロントのハブにガタが来ているので、分解、注油。ほんと、全然回らなかったらしいです。。&lt;/li&gt;
&lt;li&gt;多少の振れ取り&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;雨の日は5回ぐらいしか経験していないはずなのに！リアのハブはスプロケがあるからあまり水の浸入は無いようです。&lt;br /&gt;
自分で分解、組み立てが出来るっぽいので今度は自分でやります。玉当たりも厳しくないらしいです。&lt;/p&gt;
&lt;p&gt;その結果：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数% 回転がスムーズになっている！&lt;/li&gt;
&lt;li&gt;フリーハブのラチェット音が静かになった！&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;1年でこんなに劣化すると言うことがわかった。メンテナンスに出して良かった！&lt;/p&gt;
</content:encoded></item><item><title>RedisのSortedSetベンチマーク</title><link>https://blog.teraren.com/posts/redis-sortedset-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/redis-sortedset-benchmark/</guid><description>RedisのSortedSetベンチマーク</description><pubDate>Wed, 08 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;5,000,000ユーザ分のデータを作成してテストしました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Add: 18,483 queries/s
Update: 17,065 queries/s
Get score: 21,520 queries/s
Get rank: 19,632 queries/s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;測定環境&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;クライアントプロセス数：1 （普通はマルチコアで動かすのでxコア数分ぐらい出るのかなーと思います）&lt;/li&gt;
&lt;li&gt;PHP 5.3.15 + Redis 2.6.12&lt;/li&gt;
&lt;li&gt;Core i7 2.3GHz&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matsubo/redis-ranking/blob/master/sample/benchmark.php&quot;&gt;使ったスクリプト&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Doctrine2はPDOの3倍以上遅い - Benchmarking PDO, mysqli, Doctrine2</title><link>https://blog.teraren.com/posts/benchmarking-pdo-mysqli-doctrine2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/benchmarking-pdo-mysqli-doctrine2/</guid><description>PHP+MySQLのデータアクセス層としてPDO・mysqli・Doctrine2のSELECT速度をベンチマークし、Doctrine2がPDOより3倍以上遅いことを実測で確認</description><pubDate>Sat, 04 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;概要&lt;/h3&gt;
&lt;p&gt;背景：&lt;br /&gt;
&lt;a href=&quot;http://docs.doctrine-project.org/en/latest/reference/improving-performance.html&quot;&gt;Doctrine2のパフォーマンスが良くなったらしい&lt;/a&gt;ので、ベンチマークしてみた。&lt;br /&gt;
ちなみに、2年前にベンチマークを取ったときには、Doctrine1はPDOの&lt;a href=&quot;http://codezine.jp/article/detail/5858?p=4&quot;&gt;約3倍遅かった&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;結論：&lt;br /&gt;
今もなお、Doctrine2はPDOに比べて3倍以上遅かった。&lt;/p&gt;
&lt;h2&gt;ベンチマーク結果&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/05/Screen-Shot-2013-05-04-at-17.49.41.png&quot; alt=&quot;doctrine_pdo_benchmark&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;測定環境&lt;/h2&gt;
&lt;p&gt;Debian6.0 + PHP5.4 + MySQL5.5 localhost&lt;/p&gt;
&lt;p&gt;スキーマ&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;desc item;
+---------+----------------------+------+-----+---------------------+-----------------------------+
| Field   | Type                 | Null | Key | Default             | Extra                       |
+---------+----------------------+------+-----+---------------------+-----------------------------+
| id      | int(10) unsigned     | NO   | PRI | NULL                | auto_increment              |
| user_id | int(10) unsigned     | NO   | MUL | NULL                |                             |
| item_id | smallint(5) unsigned | NO   |     | NULL                |                             |
| num     | int(11)              | NO   |     | 0                   |                             |
| mtime   | timestamp            | NO   |     | CURRENT_TIMESTAMP   | on update CURRENT_TIMESTAMP |
| ctime   | datetime             | NO   |     | 0000-00-00 00:00:00 |                             |
+---------+----------------------+------+-----+---------------------+-----------------------------+
6 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;発行しているクエリーはこちら。&lt;br /&gt;
業務上、Selectが重要なので、シンプルなSelectだけ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
require_once &quot;bootstrap.php&quot;;

class Doctrine2Benchmarks
{
    public function selectByPrimaryKey()
    {
        global $entityManager;
        $dql = &quot;SELECT i FROM Item i WHERE i.id = 1&quot;;
        $items = $entityManager-&amp;gt;createQuery($dql)-&amp;gt;getScalarResult();
   }

    public function selectByMultiplePrimaryKey()
    {
        global $entityManager;
        $dql = &quot;SELECT i FROM Item i WHERE i.id in (1,2,3)&quot;;
        $items = $entityManager-&amp;gt;createQuery($dql)-&amp;gt;getScalarResult();
    }

    public function selectByIndex()
    {
        global $entityManager;
        $dql = &quot;SELECT i FROM Item i WHERE i.user_id = 100&quot;;
        $items = $entityManager-&amp;gt;createQuery($dql)-&amp;gt;getScalarResult();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;まとめ&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Doctrine2はPDOに比べて3倍以上遅かった。&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>Travis CIでPHP Extensionをインストールする方法</title><link>https://blog.teraren.com/posts/travis-ci-php-extension/</link><guid isPermaLink="true">https://blog.teraren.com/posts/travis-ci-php-extension/</guid><description>Travis CIのビルド環境にデフォルト未搭載のPHP拡張（例：redis.so）をbefore_installでソースからビルドしてインストールする.travis.yml設定方法。</description><pubDate>Sat, 04 May 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://travis-ci.org/&quot;&gt;Travis CI&lt;/a&gt;でPHPのextension （拡張）を使ったテストをする際に、自分でextensionをインストールする方法です。&lt;/p&gt;
&lt;p&gt;前提として、すでに導入されているextensionはこちら。これらに依存しているだけの場合は問題なし。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apc.so
memcache.so
memcached.so
mongo.so
amqp.so
zmq.so
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;たとえば、Redisクラスを使うために、redis.soを導入する場合は、&lt;code&gt;.travis.yml&lt;/code&gt;に以下を追記する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;before_install:
  # install phpredis extension.
  - wget -O phpredis.tar.gz --no-check-certificate https://github.com/nicolasff/phpredis/tarball/master
  - tar -xzf phpredis.tar.gz
  - sh -c &quot;cd nicolasff-phpredis-* &amp;amp;&amp;amp; phpize &amp;amp;&amp;amp; ./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; sudo make install&quot;
  - echo &quot;extension=redis.so&quot; &amp;gt; redis.ini &amp;amp;&amp;amp; phpenv config-add redis.ini
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/matsubo/redis-ranking/&quot;&gt;Redis-Ranking&lt;/a&gt;の例：&lt;a href=&quot;https://github.com/matsubo/redis-ranking/blob/master/.travis.yml&quot;&gt;https://github.com/matsubo/redis-ranking/blob/master/.travis.yml&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/05/Screenshot_5_4_13_2_17_AM.png&quot; alt=&quot;Travis CI&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Travis CIでの出力は以下のようになる。&lt;/p&gt;
</content:encoded></item><item><title>Redisのランキング管理API作りました</title><link>https://blog.teraren.com/posts/redis-ranking-api/</link><guid isPermaLink="true">https://blog.teraren.com/posts/redis-ranking-api/</guid><description>RedisのSorted Setをラップしてソーシャルゲームのユースケースに特化したランキング管理PHPライブラリを作成。ComposerとAPIの使い方を解説</description><pubDate>Sun, 28 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;RedisのSort SetのAPIが若干使いづらいので、ソーシャルゲームでのユースケースに即したAPIでラップしました。&lt;br /&gt;
&lt;a href=&quot;https://github.com/matsubo/redis-ranking&quot;&gt;https://github.com/matsubo/redis-ranking&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coveralls.io/repos/matsubo/redis-ranking/badge.png?branch=master&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;p&gt;Composer対応してあります。
composer.jsonに以下を書いて、&lt;code&gt;php composer.phar update&lt;/code&gt;してください。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;require&quot;: {
       &quot;redis/ranking&quot;: &quot;1.0.*&quot;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;サンプルコード&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
require __DIR__ . &apos;/../vendor/autoload.php&apos;;

use Matsubo\Redis\Ranking;

$redis = new \Redis();
$redis-&amp;gt;connect(&apos;127.0.0.1&apos;, 6379);

$ranking = new Ranking($key = &apos;usecase&apos;, $redis);

// Add score
$ranking-&amp;gt;setUserScore(&apos;kanako&apos;, 1);
$ranking-&amp;gt;setUserScore(&apos;ayaka&apos;, 50);
$ranking-&amp;gt;setUserScore(&apos;shiori&apos;, 100);

// get score
var_dump($ranking-&amp;gt;getScore(&apos;kanako&apos;));   // float(1)
var_dump($ranking-&amp;gt;getScore(&apos;ayaka&apos;));    // float(50)
var_dump($ranking-&amp;gt;getScore(&apos;shiori&apos;));   // float(100)

// get rank
var_dump($ranking-&amp;gt;getRank(&apos;kanako&apos;));  // int(0)
var_dump($ranking-&amp;gt;getRank(&apos;ayaka&apos;));   // int(1)
var_dump($ranking-&amp;gt;getRank(&apos;shiori&apos;));  // int(2)

/*
 * Show top 2
 * array(3) {
 *   [&quot;kanako&quot;]=&amp;gt;
 *   string(1) &quot;1&quot;;
 *   [&quot;ayaka&quot;]=&amp;gt;
 *   string(2) &quot;50&quot;
 */
var_dump($ranking-&amp;gt;getRange(0, 1, true));

// Cleanup
$redis-&amp;gt;del($key);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;redis-benchmark&lt;/code&gt;コマンドではSorted Keyのベンチマークが出てこないので、ベンチマーク取ってみました。&lt;br /&gt;
Redis自体のベンチマークはこちらに細かくまとまっている。&lt;a href=&quot;http://redis.io/topics/benchmarks&quot;&gt;http://redis.io/topics/benchmarks&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP 5.3.15 + Redis 2.6.12&lt;/li&gt;
&lt;li&gt;Core i7 2.3GHz&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% php sample/benchmark.php
Add: 18,350 queries/s
Update: 17,876 queries/s
Get score: 21,361 queries/s
Get rank: 22,123 queries/s
php sample/benchmark.php  1.50s user 2.96s system 43% cpu 10.203 total
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;サンプルアプリケーション&lt;/h2&gt;
&lt;p&gt;**サンプルアプリケーション：&lt;a href=&quot;https://matsu.teraren.com/ranking/&quot;&gt;AKB勝手に総選挙&lt;/a&gt;**を作ってみました。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ほぼ生のPHPで書いています。更新時にはHTTPリクエストが約10msで返ってきます（有線LAN -&amp;gt; AP -&amp;gt; 無線LAN 環境）。&lt;/li&gt;
&lt;li&gt;bowerとcomposerで構築しているので実質1ファイルだけ書きました&lt;/li&gt;
&lt;li&gt;ソースコード：&lt;a href=&quot;https://github.com/matsubo/redis-ranking-sample&quot;&gt;https://github.com/matsubo/redis-ranking-sample&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;コメント&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://jp.apps.gree.net/ja/58737?ent_code=PCSEGG00&quot;&gt;アイドルマスター ミリオンライブ！&lt;/a&gt;のイベントランキングがリアルタイムじゃないのが残念なので、これを使って対応していただけるとうれしいです。&lt;/li&gt;
&lt;li&gt;ソートの順番はAscendingで固定のようなので、Descendingにしたければ、不等号を逆にすれば良いです。&lt;/li&gt;
&lt;li&gt;同点の扱いに関して：&lt;a href=&quot;http://blog.nekokak.org/show?guid=iIz4tOKF4hG-rirtGCByNQ&quot;&gt;http://blog.nekokak.org/show?guid=iIz4tOKF4hG-rirtGCByNQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/matsubo/redis-ranking&quot;&gt;redis-ranking&lt;/a&gt;作りました。&lt;/p&gt;
</content:encoded></item><item><title>Debian Squeeze 6.0 (Ubuntu12)でPHP5.4やMySQL5.5</title><link>https://blog.teraren.com/posts/debian-squeeze-php54-mysql/</link><guid isPermaLink="true">https://blog.teraren.com/posts/debian-squeeze-php54-mysql/</guid><description>Debian安定版にdotdebリポジトリを追加することでPHP 5.4やMySQL 5.5など最新サーバアプリケーションをインストールする手順</description><pubDate>Fri, 19 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Debianの安定版は、その名の通り安定している替わりに、サーバアプリケーションが古い。&lt;br /&gt;
そんな安定している環境で、サーバアプリケーションだけ最新を使いたいという矛盾した要望をかなえてくれるのが&lt;a href=&quot;http://www.dotdeb.org&quot;&gt;dotdeb&lt;/a&gt;です。&lt;/p&gt;
&lt;p&gt;最新の安定版Linuxで稼働するようにコンパイルされたパッケージを配布してくれています。&lt;/p&gt;
&lt;h3&gt;設定&lt;/h3&gt;
&lt;p&gt;まずは、gpgの公開鍵を登録するために、以下をrootで実行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gpg --keyserver keys.gnupg.net --recv-key 89DF5277
gpg -a --export 89DF5277 | sudo apt-key add -
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下をコピペで実行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /tmp
wget https://gist.github.com/matsubo/5420603/raw/f05f584a7cd22688c5f8c1b1990581bddc5b343f/dotdeb.list
sudo mv dotdeb.list /etc/apt/sources.list.d/

wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | sudo apt-key add -
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;インストール&lt;/h3&gt;
&lt;p&gt;以下もコピペで実行。下2行は任意で実行していただければと思います。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install php5
sudo apt-get install mysql-server-5.5
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>qmailの日本ミラーサーバを提供し始めました。</title><link>https://blog.teraren.com/posts/qmail-japan-mirror/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qmail-japan-mirror/</guid><description>qmailの日本ミラーサーバを提供し始めました。</description><pubDate>Thu, 11 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;テラレン！では様々オープンソースソフトウェアにお世話になっています。&lt;/p&gt;
&lt;p&gt;オープンソースコミュニティに貢献するために、軽量で安定したメールサーバであるqmailのミラーリングを行い始めました。&lt;br /&gt;
&lt;a href=&quot;Http://qmail.org/&quot;&gt;qmail.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;qmailをご利用の際は、是非ご利用くださいませ。&lt;br /&gt;
ミラーサーバのURLはこちらになります。&lt;br /&gt;
&lt;a href=&quot;http://qmail.teraren.com/&quot;&gt;qmail.teraren.com/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>JSONのvalidation</title><link>https://blog.teraren.com/posts/json-validatio/</link><guid isPermaLink="true">https://blog.teraren.com/posts/json-validatio/</guid><description>JSONのvalidation</description><pubDate>Mon, 08 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;CLIで使えるJSONのlinter。&lt;/p&gt;
&lt;p&gt;npmのがよさげ。&lt;/p&gt;
&lt;p&gt;JSON.parse();してるときに表示されるエラーが分かりづらすぎるので。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install jsonlint -g
cat json | jsonlint
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>sshの接続を高速化</title><link>https://blog.teraren.com/posts/speedup-ssh-connect/</link><guid isPermaLink="true">https://blog.teraren.com/posts/speedup-ssh-connect/</guid><description>sshの接続を高速化</description><pubDate>Mon, 08 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;まぁ、いろいろ説明は省きますが、こんな感じで。&lt;/p&gt;
&lt;p&gt;gitへの接続が速くなるし、いろいろちょっと速くなった気がするし、あまり切れなくもなった気がする。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.ssh/config&lt;/code&gt;へ以下を設定。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host *
    ControlMaster auto
    ControlPath ~/.ssh/mux-%r@%h:%p
    GSSAPIAuthentication no
    Compression yes
    CompressionLevel 9
    Cipher arcfour256
    ForwardAgent yes
    TCPKeepAlive               yes
    ServerAliveInterval        15
    ServerAliveCountMax        3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/matsubo/matsu-shell-setting/blob/master/.ssh/config&quot;&gt;https://github.com/matsubo/matsu-shell-setting/blob/master/.ssh/config&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>dotdebのミラーリングを開始</title><link>https://blog.teraren.com/posts/post-0/</link><guid isPermaLink="true">https://blog.teraren.com/posts/post-0/</guid><description>dotdebのミラーリングを開始</description><pubDate>Sun, 07 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;オープンソースコミュニティへの貢献の一環として、&lt;a href=&quot;http://www.dotdeb.org/&quot;&gt;dotdeb&lt;/a&gt;のミラーサイトを提供し始めました。&lt;/p&gt;
&lt;p&gt;dotdebはDebian Linuxにおいて、最新のLAMPアプリケーションを提供するためのコミュニティです。テラレン！が、dotdebにおける初めてのミラーサイトです。&lt;/p&gt;
&lt;p&gt;Debianユーザの方は是非ご利用ください。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deb http://mirrors.teraren.com/dotdeb/ stable all
deb-src http://mirrors.teraren.com/dotdeb/ stable all
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使い方&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ cd /tmp
$ wget https://gist.github.com/matsubo/5291333/raw/f62ce9f4dce0dbb00cf94e28bcb439aefbca88c6/dotdeb.list
$ sudo mv dotdeb.list /etc/apt/sources.list.d
$ sudo apt-get update
$ sudo apt-get upgrade
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Mac OS Xでコマンドラインからユーザ追加</title><link>https://blog.teraren.com/posts/qiita-20130406-50a2530e6d6f9ac0645e/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qiita-20130406-50a2530e6d6f9ac0645e/</guid><description>macOSでdsclコマンドを使い、コマンドラインからユーザを作成するスクリプトの紹介。</description><pubDate>Sat, 06 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;CLIでユーザ追加する&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Mac でのユーザ管理はディレクトリサービスによって管理されているので、dscl コマンドによって操作します。&lt;/li&gt;
&lt;li&gt;Web 上に記載されているサンプルでは、UID や GID は自動的に採番するようになっています。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;サンプルスクリプト&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;TARGETUSER&lt;/code&gt; と &lt;code&gt;PASSWORD&lt;/code&gt; を変更してご利用ください。&lt;/li&gt;
&lt;li&gt;root 権限で実行してください&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;##!/bin/zsh

TARGETUSER=newuser
PASSWORD=&quot;newpassword&quot;

GID=`dscl . list groups gid|grep \^staff | tail  -1  | awk &apos;{print $2}&apos;`

dscl . -create /Users/$TARGETUSER
dscl . -create /Users/$TARGETUSER UserShell /bin/bash
dscl . -create /Users/$TARGETUSER RealName $TARGETUSER

maxid=$(dscl . -list /Users UniqueID | awk &apos;{print $2}&apos; | sort -ug | tail -1)
newid=$((maxid+1))

dscl . -create /Users/$TARGETUSER UniqueID         $newid
dscl . -create /Users/$TARGETUSER PrimaryGroupID   $GID
dscl . -create /Users/$TARGETUSER NFSHomeDirectory /Users/$TARGETUSER

cp -a /System/Library/User\ Template/English.lproj /Users/$TARGETUSER
chown -R $TARGETUSER\:staff /Users/$TARGETUSER
chmod 701 /Users/$TARGETUSER
dscl . -passwd /Users/$TARGETUSER $PASSWORD
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>自分のグローバルIPアドレスを1秒で求める方法 (IPv4, IPv6対応)</title><link>https://blog.teraren.com/posts/external-ip-address/</link><guid isPermaLink="true">https://blog.teraren.com/posts/external-ip-address/</guid><description>curlコマンド一発でグローバルIPアドレスを取得できるサービスの紹介と、PHP・Ruby・Python・Shellなど各言語からの利用サンプルコードをまとめています。</description><pubDate>Fri, 05 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;button.css3button {
  font-family: &apos;Droid Sans Mono&apos;, monospace;
  font-size: 25pt;
  color: #333333;
  padding: 10px 30px;
  background: -moz-linear-gradient(
    top,
    #cccccc 0%,
    #cccccc);
  background: -webkit-gradient(
    linear, left top, left bottom,
    from(#cccccc),
    to(#cccccc));
  -moz-border-radius: 30px;
  -webkit-border-radius: 30px;
  border-radius: 30px;
  border: 8px solid #1e2424;
  -moz-box-shadow:
    0px 0px 0px rgba(000,000,000,0),
    inset 0px 0px 0px rgba(255,255,255,0);
  -webkit-box-shadow:
    0px 0px 0px rgba(000,000,000,0),
    inset 0px 0px 0px rgba(255,255,255,0);
  box-shadow:
    0px 0px 0px rgba(000,000,000,0),
    inset 0px 0px 0px rgba(255,255,255,0);
  text-shadow:
    0px 0px 0px rgba(000,000,000,0),
    0px 0px 0px rgba(255,255,255,0.3);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;自分の外部IPアドレスを求めるサービスを発見！&lt;br /&gt;
&lt;a href=&quot;http://ifconfig.me/&quot;&gt;http://ifconfig.me/&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl ifconfig.me
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/04/Screenshot-20130405-1457-4.png&quot; alt=&quot;Screenshot 2013:04:05 14:57-4&quot; /&gt;&lt;/p&gt;
&lt;p&gt;しかし、&lt;strong&gt;ifconfig.meがめちゃくちゃ遅い&lt;/strong&gt;（10秒ぐらいかかる）ので、とりあえず自前で作りました。東京で運用しているので速いです。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://kakunin.teraren.com/&quot;&gt;&lt;strong&gt;http://kakunin.teraren.com/&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;IPv4とIPv6に対応しています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% curl -4 kakunin.teraren.com
222.230.108.57
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;% curl -6 kakunin.teraren.com
240b:10:2120:f400:e895:161e:8622:1821
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;RESTfulで、いろいろな情報を取得できる。使い方は至って簡単。&lt;/p&gt;
&lt;p&gt;単純に、curlでGETするだけで返してくれます。&lt;/p&gt;
&lt;p&gt;サンプルコードはこんな感じで。&lt;/p&gt;
&lt;h3&gt;PHPでグローバルIPアドレスを取得&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$ip = trim(file_get_contents(&apos;http://kakunin.teraren.com/&apos;));
var_dump($ip);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;RubyでグローバルIPアドレスを取得&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;require &apos;net/http&apos;
p Net::HTTP.get(&apos;kakunin.teraren.com&apos;).strip!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Python2でグローバルIPアドレスを取得&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;import httplib

conn = httplib.HTTPConnection(&apos;kakunin.teraren.com&apos;)
conn.request( &quot;GET&quot;, &quot;/ip&quot; )
print  conn.getresponse().read().strip()
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;shell scriptでグローバルIPアドレスを取得&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;IP=`curl -s kakunin.teraren.com`
echo $IP
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;perlでグローバルIPアドレスを取得&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;use LWP::Simple;
$ip = get(&apos;http://kakunin.teraren.com/&apos;);
$ip =~ s/(^\s+|\s+$)//;

print $ip;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>日本なら超速！dotdebのミラーサイト</title><link>https://blog.teraren.com/posts/dotdeb-mirror-site/</link><guid isPermaLink="true">https://blog.teraren.com/posts/dotdeb-mirror-site/</guid><description>日本なら超速！dotdebのミラーサイト</description><pubDate>Tue, 02 Apr 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;この記事は古いです。&lt;br /&gt;
dotdebのoriginがサービスの提供を終了したことに伴い、ミラーリングも終了しました。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.dotdeb.org/&quot;&gt;dotdeb&lt;/a&gt;のミラーサイトが日本に無いので、ミラーサイトを作ってみました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;deb http://mirrors.teraren.com/dotdeb/ stable all
deb-src http://mirrors.teraren.com/dotdeb/ stable all
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使い方&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;cd /tmp
wget https://gist.github.com/matsubo/5291333/raw/f62ce9f4dce0dbb00cf94e28bcb439aefbca88c6/dotdeb.list
sudo mv dotdeb.list /etc/apt/sources.list.d
sudo apt-get update
sudo apt-get upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;dotdebとは&lt;/h3&gt;
&lt;p&gt;dotdebはDebianのstable環境で、最新のLAMPアプリケーションを利用するためのパッケージを配布しているサイトです。&lt;/p&gt;
&lt;p&gt;Debianは安定性を求めるが故、パッケージが結構古いのが逆にデメリットになりますが、dotdebを使えばよく利用するパッケージは最新を使うことが出来ます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/04/openlogo-100.jpg&quot; alt=&quot;Debian logo&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>MySQLはデータベースをまたぐトランザクションを行える</title><link>https://blog.teraren.com/posts/mysql-transaction/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-transaction/</guid><description>MySQLでBEGIN〜ROLLBACKを使い、異なるデータベース（test・test2）をまたいだトランザクションが正常に動作することをSQL実行例で検証</description><pubDate>Fri, 29 Mar 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;以下に検証結果&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; create table test.aaa (bbb int(11));
mysql&amp;gt; create table test2.aaa (bbb int(11));
mysql&amp;gt; begin;
Query OK, 0 rows affected (0.00 sec)

mysql&amp;gt; insert into test.aaa values(1);
Query OK, 1 row affected (0.00 sec)

mysql&amp;gt; insert into test.aaa values(1);
Query OK, 1 row affected (0.00 sec)

mysql&amp;gt; insert into test.aaa values(1);
Query OK, 1 row affected (0.00 sec)

mysql&amp;gt; insert into test.aaa values(1);
Query OK, 1 row affected (0.00 sec)

mysql&amp;gt; insert into test2.aaa values(1);
Query OK, 1 row affected (0.00 sec)

mysql&amp;gt; insert into test2.aaa values(1);
Query OK, 1 row affected (0.00 sec)

mysql&amp;gt; insert into test2.aaa values(1);
Query OK, 1 row affected (0.00 sec)

mysql&amp;gt; select count(*) from test.aaa;
+----------+
| count(*) |
+----------+
|        4 |
+----------+
1 row in set (0.00 sec)

mysql&amp;gt; select count(*) from test2.aaa;
+----------+
| count(*) |
+----------+
|        3 |
+----------+
1 row in set (0.00 sec)

mysql&amp;gt; rollback;
Query OK, 0 rows affected (0.00 sec)

mysql&amp;gt; select count(*) from test.aaa;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.01 sec)

mysql&amp;gt; select count(*) from test2.aaa;
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

mysql&amp;gt; show variables like &apos;version&apos;;
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| version       | 5.5.8-log |
+---------------+-----------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Win, Mac対応のソフトウェアでブルーライト対策</title><link>https://blog.teraren.com/posts/flux/</link><guid isPermaLink="true">https://blog.teraren.com/posts/flux/</guid><description>Win, Mac対応のソフトウェアでブルーライト対策</description><pubDate>Thu, 28 Mar 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;f.lux &lt;a href=&quot;http://stereopsis.com/flux/&quot;&gt;http://stereopsis.com/flux/&lt;/a&gt; これを使えば、JINS PC要りません！ ソフトウェアでディスプレイの&lt;strong&gt;青色成分を減らしてくれます&lt;/strong&gt;。 設定はこんな感じで、任意のホワイトバランスに設定出来ます。↓ &lt;img src=&quot;../../assets/uploads/2013/03/Screen-Shot-2013-03-28-at-13.35.01.png&quot; alt=&quot;Screen Shot 2013-03-28 at 13.35.01&quot; /&gt; f.lux &lt;a href=&quot;http://stereopsis.com/flux/&quot;&gt;http://stereopsis.com/flux/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>PHPのmicrotimeの精度によるmt_srandへの影響</title><link>https://blog.teraren.com/posts/php-mt-rand-microtime/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-mt-rand-microtime/</guid><description>PHP5.3以下でmicrotime()を乱数シードに使う公式サンプルコードには重大な欠陥があり、シードが固定値になってしまう問題の原因と正しい実装方法を解説します。</description><pubDate>Wed, 27 Mar 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;PHP5.3以下を使っていて、microtime()を元に乱数を生成している人は注意！&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;オフィシャルサイトのサンプルコード通りだとシードがランダムになりません。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;PHPのユニットテストで確率を計算しているときに、「&lt;strong&gt;なかなか数字が分散しない&lt;/strong&gt;」と思って調べました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
// seed with microseconds
function make_seed()
{
    list($usec, $sec) = explode(&apos; &apos;, microtime());
    return (float) $sec + ((float) $usec * 100000);
}

while (true) {
    var_dump(make_seed());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;PHP5.2.14&lt;/h2&gt;
&lt;p&gt;これはやばい。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)　　　
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)　
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(54)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
int(52)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;PHP5.3.15&lt;/h2&gt;
&lt;p&gt;あんまり分散しない。。。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int(30)
int(52)
int(14)
int(4)
int(32)
int(32)
int(41)
int(17)
int(17)
int(86)
int(26)
int(26)
int(32)
int(32)
int(40)
int(37)
int(37)
int(17)
int(59)
int(59)
int(38)
int(38)
int(92)
int(26)
int(26)
int(21)
int(74)
int(74)
int(13)
int(13)
int(24)
int(12)
int(12)
int(86)
int(88)
int(88)
int(82)
int(92)
int(92)
int(21)
int(21)
int(32)
int(26)
int(26)
int(13)
int(96)
int(96)
int(53)
int(53)
int(65)
int(74)
int(74)
int(21)
int(21)
int(2)
int(52)
int(52)
int(29)
int(45)
int(45)
int(85)
int(85)
int(95)
int(38)
int(38)
int(90)
int(90)
int(90)
int(2)
int(2)
int(38)
int(33)
int(33)
int(96)
int(2)
int(2)
int(32)
int(15)
int(15)
int(7)
int(7)
int(83)
int(16)
int(16)
int(2)
int(50)
int(50)
int(20)
int(20)
int(85)
int(30)
int(30)
int(40)
int(19)
int(19)
int(3)
int(3)
int(13)
int(52)
int(52)
int(95)
int(50)
int(50)
int(79)
int(83)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;PHP5.4.12&lt;/h2&gt;
&lt;p&gt;これは良い。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;int(13)
int(62)
int(10)
int(35)
int(60)
int(62)
int(59)
int(20)
int(99)
int(46)
int(88)
int(99)
int(15)
int(75)
int(43)
int(79)
int(47)
int(96)
int(39)
int(28)
int(29)
int(32)
int(22)
int(1)
int(77)
int(70)
int(6)
int(36)
int(74)
int(84)
int(87)
int(65)
int(77)
int(34)
int(15)
int(47)
int(22)
int(84)
int(40)
int(19)
int(8)
int(91)
int(5)
int(67)
int(89)
int(79)
int(40)
int(91)
int(17)
int(95)
int(72)
int(59)
int(14)
int(85)
int(25)
int(50)
int(51)
int(46)
int(18)
int(46)
int(79)
int(73)
int(3)
int(78)
int(17)
int(51)
int(86)
int(19)
int(48)
int(34)
int(41)
int(6)
int(20)
int(71)
int(79)
int(49)
int(30)
int(87)
int(30)
int(57)
int(53)
int(90)
int(43)
int(54)
int(80)
int(46)
int(90)
int(44)
int(33)
int(55)
int(10)
int(9)
int(84)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;microtime関数のμタイム部分の精度が悪いのが原因ですなー。たぶん。&lt;br /&gt;
でも、PHPのソースコードは差分無かった。なので、実行環境の違いかも知れないなー。&lt;/p&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;PHPでは乱数発生に置いて以下のような問題がある。&lt;a href=&quot;https://codezine.jp/article/detail/17485?p=3&quot;&gt;参考記事&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PHPにおける乱数発生の実装は、長らく問題とされてきました。例えば、以下のような問題です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;メルセンヌツイスタ（1996年に発表された疑似乱数発生器）がいまだに利用されている&lt;/li&gt;
&lt;li&gt;状態がグローバルな領域に保持されている（メルセンヌツイスタの利用に由来）&lt;/li&gt;
&lt;li&gt;奇数ばかりが出るなどランダム性が不完全である&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;最後のはやばいような気がするので検証するコードを書いてみましたが、顕著ではないのかもしれません。&lt;/p&gt;
&lt;p&gt;https://gist.github.com/matsubo/516201c7a7e8973a55f18825500e2929&lt;/p&gt;
&lt;p&gt;乱数生成機に偏りがあるとなると、プログラム上で表現されるバランスにクリティカルな影響が出てしまいます。特に、ゲームやカジノなどの確率がビジネスロジックの根底の要素として存在する場合。&lt;/p&gt;
&lt;p&gt;PHPの乱数処理に関してより詳細な記事がありました。&lt;/p&gt;
&lt;p&gt;https://zenn.dev/zeriyoshi/articles/abd808d1c6d31b&lt;/p&gt;
&lt;p&gt;参考までに、GPTの回答。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2023/04/image.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed</title><link>https://blog.teraren.com/posts/ssl-connect-returned1/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ssl-connect-returned1/</guid><description>Rails newコマンド実行時にSSL証明書検証エラーが発生する原因と、opensslの設定やCA証明書を更新して解決する方法</description><pubDate>Fri, 08 Mar 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;rails newしたら、エラー。。。。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[matsu@Yukis-MacBook-Pro ~]% rails new cancantest
      create
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/assets/images/rails.png
      create  app/assets/javascripts/application.js
      create  app/assets/stylesheets/application.css
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      create  app/views/layouts/application.html.erb
      create  app/mailers/.gitkeep
      create  app/models/.gitkeep
      create  config
      create  config/routes.rb
      create  config/application.rb
      create  config/environment.rb
      create  config/environments
      create  config/environments/development.rb
      create  config/environments/production.rb
      create  config/environments/test.rb
      create  config/initializers
      create  config/initializers/backtrace_silencers.rb
      create  config/initializers/inflections.rb
      create  config/initializers/mime_types.rb
      create  config/initializers/secret_token.rb
      create  config/initializers/session_store.rb
      create  config/initializers/wrap_parameters.rb
      create  config/locales
      create  config/locales/en.yml
      create  config/boot.rb
      create  config/database.yml
      create  db
      create  db/seeds.rb
      create  doc
      create  doc/README_FOR_APP
      create  lib
      create  lib/tasks
      create  lib/tasks/.gitkeep
      create  lib/assets
      create  lib/assets/.gitkeep
      create  log
      create  log/.gitkeep
      create  public
      create  public/404.html
      create  public/422.html
      create  public/500.html
      create  public/favicon.ico
      create  public/index.html
      create  public/robots.txt
      create  script
      create  script/rails
      create  test/fixtures
      create  test/fixtures/.gitkeep
      create  test/functional
      create  test/functional/.gitkeep
      create  test/integration
      create  test/integration/.gitkeep
      create  test/unit
      create  test/unit/.gitkeep
      create  test/performance/browsing_test.rb
      create  test/test_helper.rb
      create  tmp/cache
      create  tmp/cache/assets
      create  vendor/assets/javascripts
      create  vendor/assets/javascripts/.gitkeep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.gitkeep
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
         run  bundle install
/Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/vendor/net/http/persistent/ssl_reuse.rb:70:in `connect&apos;: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (OpenSSL::SSL::SSLError)
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/vendor/net/http/persistent/ssl_reuse.rb:70:in `block in connect&apos;
    from /Users/matsu/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/timeout.rb:54:in `timeout&apos;
    from /Users/matsu/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/timeout.rb:99:in `timeout&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/vendor/net/http/persistent/ssl_reuse.rb:70:in `connect&apos;
    from /Users/matsu/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/net/http.rb:755:in `do_start&apos;
    from /Users/matsu/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/net/http.rb:750:in `start&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/vendor/net/http/persistent.rb:628:in `start&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/vendor/net/http/persistent.rb:570:in `connection_for&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/vendor/net/http/persistent.rb:930:in `request&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/fetcher.rb:195:in `fetch&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/fetcher.rb:169:in `use_api&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/source/rubygems.rb:223:in `block in remote_specs&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/source/rubygems.rb:223:in `select&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/source/rubygems.rb:223:in `remote_specs&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/source/rubygems.rb:162:in `fetch_specs&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/source/rubygems.rb:66:in `specs&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/definition.rb:192:in `block (2 levels) in index&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/definition.rb:189:in `each&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/definition.rb:189:in `block in index&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/index.rb:9:in `build&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/definition.rb:185:in `index&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/definition.rb:179:in `resolve&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/definition.rb:114:in `specs&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/definition.rb:109:in `resolve_remotely!&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/installer.rb:83:in `run&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/installer.rb:14:in `install&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/cli.rb:247:in `install&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/vendor/thor/task.rb:27:in `run&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/vendor/thor/invocation.rb:120:in `invoke_task&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/vendor/thor.rb:344:in `dispatch&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/vendor/thor/base.rb:434:in `start&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/bin/bundle:20:in `block in &amp;lt;main&amp;gt;&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/lib/bundler/friendly_errors.rb:4:in `with_friendly_errors&apos;
    from /Users/matsu/.rvm/gems/ruby-1.9.3-p327/gems/bundler-1.3.0/bin/bundle:20:in `&amp;lt;main&amp;gt;&apos;
        Unfortunately, a fatal error has occurred. Please see the Bundler
        troubleshooting documentation at http://bit.ly/bundler-issues. Thanks!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SSL証明書がよくないようです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget http://curl.haxx.se/ca/cacert.pem
% export SSL_CERT_FILE=~/cacert.pem
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ほんと、railsの環境をメンテナンスするの大変。&lt;/p&gt;
</content:encoded></item><item><title>Rubyでマルチスレッドプログラミング</title><link>https://blog.teraren.com/posts/ruby-multi-thread-programming/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ruby-multi-thread-programming/</guid><description>Rubyでマルチスレッドプログラミング</description><pubDate>Sun, 24 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;rubyでマルチスレッドプログラミング&lt;/p&gt;
&lt;p&gt;簡単！&lt;/p&gt;
&lt;h3&gt;サンプル&lt;/h3&gt;
&lt;p&gt;このブログのページを10スレッドで5ページずつ取得するだけのサンプルスクリプトです。&lt;/p&gt;
&lt;h3&gt;応用&lt;/h3&gt;
&lt;p&gt;応用すると、こんな感じで、画像をマルチスレッドでダウンロードするクローラーを作れます。&lt;br /&gt;
&lt;a href=&quot;https://github.com/matsubo/multi-thread-image-downloader/blob/master/Downloader.rb&quot;&gt;https://github.com/matsubo/multi-thread-image-downloader/blob/master/Downloader.rb&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>ファイルを保存した瞬間ユニットテストを実行</title><link>https://blog.teraren.com/posts/unit-test/</link><guid isPermaLink="true">https://blog.teraren.com/posts/unit-test/</guid><description>ファイルを保存した瞬間ユニットテストを実行</description><pubDate>Sun, 24 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;概要&lt;/h3&gt;
&lt;p&gt;いままで、vimでコーディングするときは「コードを書く、→ユニットテストを実行する」の繰り返しばかりで同じような操作をしていましたが、ファイルを保存した瞬間にユニットテストを実行できるようにしました。&lt;/p&gt;
&lt;p&gt;上記のスクリーンショットのように、別の&lt;a href=&quot;/posts/moteru-tmux-powerline/&quot;&gt;tmux&lt;/a&gt;などの別ペインに表示しておけば保存した瞬間にユニットテストの実行結果が見られます。&lt;/p&gt;
&lt;h3&gt;設置例&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% wget https://gist.github.com/matsubo/4992894/raw/36c0c4a08953effabfa2731ccd5186f2d6c92347/dirwatch.py
% chmod 755 dirwatch.py
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;引数&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% ./dirwatch.py [ファイル監視先ディレクトリ] [ファイルが変更されたら実行するコマンド] [監視対象のファイル拡張子]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;実行例&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% ./dirwatch.py /path/to/sourcecode/ phpunit php
% ./dirwatch.py /path/to/sourcecode/ &quot;phpunit Tests/UserRegistrationTest.php&quot; php
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>deviseチュートリアル作りました</title><link>https://blog.teraren.com/posts/devise-tutorial/</link><guid isPermaLink="true">https://blog.teraren.com/posts/devise-tutorial/</guid><description>Rails用認証gemのdeviseを使ってシンプルなログイン機能を実装するチュートリアル。公式ドキュメントを補完する形で手順ごとにコミットを分けて解説します。</description><pubDate>Tue, 19 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;**コードはこちら：&lt;a href=&quot;https://github.com/matsubo/devise_sample&quot;&gt;https://github.com/matsubo/devise_sample&lt;/a&gt;&lt;br /&gt;
**&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/plataformatec/devise&quot;&gt;devise&lt;/a&gt;の公式の手順書が分かりづらいので、シンプルな認証を実現するための要点を整理してみました！&lt;/li&gt;
&lt;li&gt;細かい設定とか、自分のサイトにあった設定はこれを元にオプションを変更していただければと思います。&lt;/li&gt;
&lt;li&gt;1手順ごとにコミットを分けてあるので、変更点が明確に分かるようになっています。
&lt;ul&gt;
&lt;li&gt;一部、手順が前後しても大丈夫なところがあるので間あり神経質にならなくても大丈夫です。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;railsアプリケーション作成&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% rails new devise_smaple
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;scaffoldで適当なページを作る&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% rails generate scaffold Post name:string title:string content:text
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;テーブルを作成しておく&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% rake db:migrate
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;deviseモジュールをインストール&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% echo &quot;gem &apos;devise&apos;&quot; &amp;gt;&amp;gt; Gemfile
% bundle install
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;deviseの設定をインストール&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% rails generate devise:install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;これを実行すると、いろいろ設定する事項が表示されるので次のように1つずつ設定していく。&lt;/p&gt;
&lt;h3&gt;デフォルトのリダイレクト先を追加&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;vi config/environments/development.rb&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;以下の行を追加&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  + config.action_mailer.default_url_options = { :host =&amp;gt; &apos;localhost:3000&apos; }
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;トップページがPostの一覧になるように設定&lt;/h3&gt;
&lt;p&gt;rootを以下のように設定&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  + root :to =&amp;gt; &apos;posts#index&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;メッセージ表示領域を追加&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% vi app/views/layouts/application.html.erb
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;+    &amp;lt;p&amp;gt;&amp;lt;%= notice %&amp;gt;&amp;lt;/p&amp;gt;
+    &amp;lt;p&amp;gt;&amp;lt;%= alert %&amp;gt;&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;herokuを使っている場合にはこの設定を行う&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% vi config/application.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;     +    # devise setting for heroku
     +    config.assets.initialize_on_precompile = false
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;deviseで追加されるページのviewだけを作成&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% rails g devise:views users
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;デフォルトのトップページを削除&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% rm public/index.html
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;deviseのmodelやrouteを追加する&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% rails generate devise users
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;devise用のテーブルを作成する&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% rake db:migrate
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;アクセスを制限したいコントローラに以下を追加する&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% vi app/controllers/posts_controller.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;+ before_filter :authenticate_user!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;動作テスト&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;開いてみると、ログイン画面が表示されるはず。
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://127.0.0.1:3000/&quot;&gt;http://127.0.0.1:3000/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/02/Screen-Shot-2015-11-27-at-11.55.18.png&quot; alt=&quot;Screen Shot 2015-11-27 at 11.55.18&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>GNU screen, byobu, tmux benchmark</title><link>https://blog.teraren.com/posts/gnu-screen-byobu-tmux-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/gnu-screen-byobu-tmux-benchmark/</guid><description>GNU screen, byobu, tmux benchmark</description><pubDate>Tue, 19 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2年間愛用したGNU screenからtmuxへ移行して1週間経ちました。一番変わったのは、描画の速さです。 上記の画像はベンチマーク結果です。11MBのシステムログをcatしてみて、計測した時間です。 使うアプリによって結構差が大きいです。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;screen multiplexer&lt;/th&gt;
&lt;th&gt;time(s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;http://www.gnu.org/software/screen/&quot;&gt;GNU screen&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://launchpad.net/byobu&quot;&gt;byobu&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;20.4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;http://tmux.sourceforge.net&quot;&gt;tmux&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;raw&lt;/td&gt;
&lt;td&gt;2.8&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
</content:encoded></item><item><title>vimの最近見つけた便利コマンド</title><link>https://blog.teraren.com/posts/vim-save-and-open/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vim-save-and-open/</guid><description>vimで別名保存と同時に開く:saveasコマンドと、全バッファを一括で閉じる:qaコマンドの使い方を紹介</description><pubDate>Thu, 14 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;あまり日本語で紹介されていない、vimデフォルトの便利コマンドを2つ。&lt;/p&gt;
&lt;h3&gt;:saveas {file}&lt;/h3&gt;
&lt;p&gt;保存して開く。&lt;/p&gt;
&lt;p&gt;今までは、:w newfileしてから、:e newfileしていたけど、一発で出来る。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:sav newfile
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;:sav :saveas
:sav[eas][!] [++opt] {file}
                        Save the current buffer under the name {file} and set
                        the filename of the current buffer to {file}.  The
                        previous name is used for the alternate file name.
                        The [!] is needed to overwrite an existing file.
                        When &apos;filetype&apos; is empty filetype detection is done
                        with the new name, before the file is written.
                        When the write was successful &apos;readonly&apos; is reset.
                        {not in Vi}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;:qa&lt;/h3&gt;
&lt;p&gt;全バッファーを閉じる。&lt;/p&gt;
&lt;p&gt;最近は、1ウィンドウに6ペイン x 5タブ くらい開いていて、コーディングがおわったら一気に閉じたいけど、:qを20回ぐらいやってましたが、これで一発で終わる！&lt;/p&gt;
&lt;p&gt;もし、未保存があったら途中で止まります。!つけると未保存関係無しに閉じます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;:qa :qall
:qa[ll]         Exit Vim, unless there are some buffers which have been
                changed.  (Use &quot;:bmod&quot; to go to the next modified buffer).
                When &apos;autowriteall&apos; is set all changed buffers will be
                written, like :wqall. {not in Vi}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>embody chairの肘掛けのねじはT30</title><link>https://blog.teraren.com/posts/embody-chair-t30/</link><guid isPermaLink="true">https://blog.teraren.com/posts/embody-chair-t30/</guid><description>embody chairの肘掛けのねじはT30</description><pubDate>Mon, 11 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;embody chairの肘掛けがしばらく使っていると根本のねじが緩んで来てしまうので締め直す必要がある。&lt;/p&gt;
&lt;p&gt;ねじは、&lt;strong&gt;T30&lt;/strong&gt;です。トルクスレンチの太さ30mmです。&lt;/p&gt;
&lt;p&gt;ねじがなめやすいので、けちらずに、押す力を入れながら絞めやすい工具を買った方が良いです。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07RWML1F8&quot;}&lt;/p&gt;
</content:encoded></item><item><title>tmuxとtmux-powerlineの設定でかっこよくする</title><link>https://blog.teraren.com/posts/moteru-tmux-powerline/</link><guid isPermaLink="true">https://blog.teraren.com/posts/moteru-tmux-powerline/</guid><description>tmuxにtmux-powerlineとPowerlineフォントを導入してステータスバーをおしゃれにカスタマイズするインストール手順と設定ガイド</description><pubDate>Sun, 10 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;とりあえず、こちらをご覧ください。&lt;strong&gt;一番下の行に注目！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/02/description.png&quot; alt=&quot;tmux-powerline&quot; /&gt;&lt;/p&gt;
&lt;p&gt;解像度は2560x1440の全画面で表示&lt;/p&gt;
&lt;p&gt;これは、&lt;a href=&quot;http://tmux.sourceforge.net/&quot;&gt;tmux&lt;/a&gt;と&lt;a href=&quot;https://github.com/erikw/tmux-powerline&quot;&gt;tmux-powerline&lt;/a&gt;を使って実現しています。&lt;/p&gt;
&lt;p&gt;以下に、導入方法を書きます。&lt;/p&gt;
&lt;h3&gt;0. (強く推奨）powerline用のフォントをインストール&lt;/h3&gt;
&lt;p&gt;まず、大なり、小なりのフォントを使うための設定をします。これをインストールした方が、すごい見栄えがかっこよくなります！&lt;/p&gt;
&lt;p&gt;パッチを当てたフォントをインストールして、ターミナルなどでそのフォントを使って表示するようにします。&lt;br /&gt;
この記事で使われているスクリーンショットのフォントは、&lt;a href=&quot;https://github.com/fncll/vimstuff/raw/master/powerline-fonts/SourceCodePro-Regular-Powerline.otf&quot;&gt;AdobeのSource code pro&lt;/a&gt;にパッチを当てたフォントを使っています。&lt;/p&gt;
&lt;p&gt;その他のフォントはこちら。&lt;br /&gt;
&lt;a href=&quot;https://gist.github.com/qrush/1595572&quot;&gt;https://gist.github.com/qrush/1595572&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;自分でパッチを当てる場合はこちら。&lt;br /&gt;
&lt;a href=&quot;https://github.com/fncll/vimstuff/tree/master/powerline-fonts&quot;&gt;https://github.com/fncll/vimstuff/tree/master/powerline-fonts&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;1.tmuxのインストール&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;パッケージ又はソースコード&lt;/strong&gt;からインストールします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;brew install tmux
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. tmux-powerlineのインストール&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/erikw/tmux-powerline&quot;&gt;tmux-powerline&lt;/a&gt;をダウンロード&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd
git clone git://github.com/erikw/tmux-powerline.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;~/.tmux.conf に以下を追加&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set-option -g status on
set-option -g status-interval 2
set-option -g status-utf8 on
set-option -g status-justify &quot;left&quot;
set-option -g status-left-length 60
set-option -g status-right-length 90
set-option -g status-left &quot;#(~/tmux-powerline/powerline.sh left)&quot;
set-option -g status-right &quot;#(~/tmux-powerline/powerline.sh right)&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;※サンプルには &lt;code&gt;set-option -g status-justify &quot;center&quot;&lt;/code&gt; とありますが、&lt;strong&gt;leftの方が綺麗です&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;この状態でtmuxを起動すれば、それっぽい表示になると思います。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tmux
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/02/clean.png&quot; alt=&quot;clean&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;3. tmux-powerlineの設定&lt;/h3&gt;
&lt;p&gt;tmux-powerlineの設定は多種多様なので、&lt;strong&gt;費用対効果が高い設定&lt;/strong&gt;を紹介します。&lt;br /&gt;
（詳細は、&lt;a href=&quot;https://github.com/erikw/tmux-powerline/blob/master/README.md&quot;&gt;README&lt;/a&gt;（英語）にとても良くまとまっています。）&lt;/p&gt;
&lt;h4&gt;3.1 色を統一する&lt;/h4&gt;
&lt;p&gt;デフォルトだとtmuxの背景とpowerlineの背景が合っていないので、色を変更します。&lt;br /&gt;
~/.tmux.confへ、&lt;strong&gt;背景色をグレー&lt;/strong&gt;にするために、以下の設定を追加します。&lt;br /&gt;
また、左右の表示が途中で切れないように&lt;strong&gt;表示文字数をデフォルトより多め&lt;/strong&gt;に設定します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set -g status-bg colour235
set-option -g status-left-length 100
set-option -g status-right-length 120
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3.2 ウィンドウリストを左寄せにする。&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;set-window-option -g window-status-current-format &quot;#[fg=colour235, bg=colour27]⮀#[fg=colour255, bg=colour27] #I ⮁ #W #[fg=colour27, bg=colour235]⮀&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3.3 現在のブランチ名を表示する&lt;/h4&gt;
&lt;p&gt;以下のコードを、.bashrcまたは.zshrcなどのシェルの設定ファイルの&lt;strong&gt;後ろの方&lt;/strong&gt;へ追加します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;PS1=&quot;$PS1&quot;&apos;$([ -n &quot;$TMUX&quot; ] &amp;amp;&amp;amp; tmux setenv TMUXPWD_$(tmux display -p &quot;#D&quot; | tr -d %) &quot;$PWD&quot;)&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再読み込みします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;あとは、レポジトリのディレクトリへ移動すれば、情報が表示されるはずです。&lt;/p&gt;
&lt;h3&gt;4. tmux-powerlineの応用設定&lt;/h3&gt;
&lt;h4&gt;4.1 オリジナル設定の準備&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;自分用の設定を記述するためのファイル&lt;/strong&gt;を準備します。&lt;br /&gt;
まずは、tmux-powerlineの表示項目を設定するためのファイルであるtmux-powerline/mytheme.shを作成します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd tmux-powerline/
cp themes/default.sh themes/mytheme.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、環境変数や&lt;strong&gt;ユーザ設定を記述するため&lt;/strong&gt;の~/.tmux-powerlinercを作成します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd tmux-powerline/
./generate_rc.sh
mv ~/.tmux-powerlinerc.default ~/.tmux-powerlinerc
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.2 天気を表示する&lt;/h4&gt;
&lt;p&gt;~/.tmux-powerlinerc を開き、TMUX_POWERLINE_SEG_WEATHER_LOCATIONに表示したい場所のコードを入れます。&lt;br /&gt;
東京なら、以下のコードになります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export TMUX_POWERLINE_SEG_WEATHER_LOCATION=&quot;26237038&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;場所のコードは、yahoo.comの天気ページにて、&lt;strong&gt;URLの一番右にある数字&lt;/strong&gt;を利用します。&lt;br /&gt;
http://weather.yahoo.com/japan/tokyo-prefecture/tokyo-26237038/&lt;/p&gt;
&lt;h4&gt;4.3 ネットワーク情報を表示する&lt;/h4&gt;
&lt;p&gt;tmux-powerline/segments/ifstat_sys.shを開き、モニタリングしたいネットワークの&lt;strong&gt;インターフェイス名に変更&lt;/strong&gt;します。&lt;br /&gt;
デフォルトではwlan0となっています。インターフェイス名は、ifconfigコマンドなどで確認出来ます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;iface=&quot;eth&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;bcコマンドが必要になるため、bcコマンドが無い場合はインストールする必要があります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo aptitude install bc -y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そして、tmux-powerline/themes/mytheme.shを開き、以下の行のコメントアウトを外します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&quot;ifstat_sys 30 255&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.4 色の変更&lt;/h4&gt;
&lt;p&gt;GNU screenでは色の変更がすごい大変でしたが、tmuxではとても簡単です。&lt;/p&gt;
&lt;p&gt;まず、オリジナルの設定を用いるために、 ~/.tmux-powerlinerc のTMUX_POWERLINE_THEMEをmythemeに設定します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export TMUX_POWERLINE_THEME=&quot;mytheme&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のコマンドを実行すると&lt;strong&gt;カラーコード&lt;/strong&gt;が表示されます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;~/tmux-powerline/color_palette.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ブランチの記号のコントラストが変なので、tmux-powerline/themes/mytheme.shを開き、&lt;strong&gt;88から253&lt;/strong&gt;へ変更します。&lt;br /&gt;
第1引数が背景で、第2引数が文字色です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                &quot;vcs_branch 29 253&quot; \
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;また、~/tmux-powerline/segments/vcs_branch.shを開き、こちらにも設定があるので&lt;strong&gt;5を253&lt;/strong&gt;に変更します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git_colour=&quot;253&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;4.5 地震情報を表示する&lt;/h4&gt;
&lt;p&gt;.tmux-powerlinercを開き、地震情報のコメントアウトを外します。デフォルトでは日本中の地震情報から拾ってきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;                &quot;earthquake 3 0&quot; \
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/02/Screenshot_2013_02_16_11_22.png&quot; alt=&quot;Screenshot_2013_02_16_11_22&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;4.6 その他&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;gmailの未読数&lt;/strong&gt;や、macの場合は&lt;strong&gt;itunesの再生中の曲&lt;/strong&gt;などを取得できます。&lt;/p&gt;
&lt;h3&gt;5 まとめ&lt;/h3&gt;
&lt;h4&gt;5.1 やったこと&lt;/h4&gt;
&lt;p&gt;tmux-powerlineを使ってかっこよくて使い勝手の良いシェルを作りました。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/02/setting_done.png&quot; alt=&quot;setting_done&quot; /&gt;&lt;/p&gt;
&lt;h5&gt;良い点&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;**tmux-powerlineを使えば、シェルスクリプトさえ用意すれば自分の欲しい情報が簡単に表示できる。(**アイディアとしては、株価や、為替表示とか、1時間前の売り上げ情報とか)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tmuxのパフォーマンスは良い。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;11MBのテキストをcatした時間をベンチマーク&lt;/li&gt;
&lt;li&gt;GNU screen: 50s&lt;/li&gt;
&lt;li&gt;byobu: 25s&lt;/li&gt;
&lt;li&gt;tmux: 15s&lt;/li&gt;
&lt;li&gt;無し: 3s&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;悪い点&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;シェルスクリプトが頻繁に動いているので、計算リソースを多少食う&lt;/li&gt;
&lt;li&gt;tmux-powerlineプログラム自体と設定が明確に分かれていない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;5.2 補足資料&lt;/h4&gt;
&lt;p&gt;4まで行った設定ファイルの結果&lt;br /&gt;
&lt;a href=&quot;https://gist.github.com/matsubo/4746629&quot;&gt;https://gist.github.com/matsubo/4746629&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;tmuxの基本操作はこちら&lt;br /&gt;
「screen(だけ)の時代は終わり。tmuxでリモートコンソールを便利に使うTips」&lt;br /&gt;
&lt;a href=&quot;http://blog.asial.co.jp/881&quot;&gt;http://blog.asial.co.jp/881&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;一番最初にあるスクリーンショットに掲載してある設定をしてある私の設定ファイル達&lt;br /&gt;
&lt;a href=&quot;https://github.com/matsubo/matsu-shell-setting&quot;&gt;https://github.com/matsubo/matsu-shell-setting&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;//b.hatena.ne.jp/entry//posts/moteru-tmux-powerline/&quot;&gt;&lt;img src=&quot;//b.st-hatena.com/images/entry-button/button-only.gif&quot; alt=&quot;このエントリーをはてなブックマークに追加&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Mac OS X Serverのnamedが起動しない</title><link>https://blog.teraren.com/posts/mac-os-x-server-named-not-starting/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-os-x-server-named-not-starting/</guid><description>Mac OS X Serverのnamedが起動しない</description><pubDate>Sat, 02 Feb 2013 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;Feb  2 19:13:48 localdomain org.isc.named[98541]: named: number of cpus &apos;ofork&apos; must be numeric
Feb  2 19:13:48 localdomain com.apple.launchd[1] (org.isc.named[98541]): Exited with code: 1
Feb  2 19:13:48 localdomain com.apple.launchd[1] (org.isc.named): Throttling respawn: Will start in 10 seconds
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;bindが起動しなくなった。。。。&lt;/p&gt;
&lt;p&gt;namedのオプションが変わったか、設定ファイルが書き換わったらしい。
/System/Library/LaunchDaemons/org.isc.named.plistにある、&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-nofork&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;を削除して、以下のように再起動すれば良い。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;launchctl stop  /System/Library/LaunchDaemons/org.isc.named.plist
launchctl start /System/Library/LaunchDaemons/org.isc.named.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2013/02/Screen-Shot-2013-02-02-at-21.36.57.png&quot; alt=&quot;Screen Shot 2013-02-02 at 21.36.57&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最終結果。&lt;/p&gt;
&lt;p&gt;ほんと、OS X Serverの運用って手がかかるわー&lt;/p&gt;
</content:encoded></item><item><title>ioniceとniceでもっとも優先度を下げて実行</title><link>https://blog.teraren.com/posts/ionice-nice/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ionice-nice/</guid><description>ioniceとniceでもっとも優先度を下げて実行</description><pubDate>Sat, 26 Jan 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最強にプライオリティを落としてプロセスを実行。
とりあえず、.zshrcに入れておきましょう。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alias allnice=&quot;ionice -c2 -n7 nice -n19&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;こんな感じで。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;allnice bzip2 access.log
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Time Sinkでアプリケーション利用時間計測</title><link>https://blog.teraren.com/posts/time-sink/</link><guid isPermaLink="true">https://blog.teraren.com/posts/time-sink/</guid><description>Time Sinkでアプリケーション利用時間計測</description><pubDate>Tue, 15 Jan 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://manytricks.com/timesink/&quot;&gt;Time Sink&lt;/a&gt;は、アプリケーションの稼働時間を記録するソフトウェアです。 シェアウェアで金額は$5ですが、価格以上の気づきを与えてくれます。 自分の想定と、実際に使っている記録を比較するといろいろ気づかされます。 上記のスクリーンショットはサマリーが出ますが、内部ではしっかり開始時間、終了時間、アプリ名、アプリ内の状態（ブラウザなら見ているサイト）が記録されるので自分がどれだけfacebookやgmailを見ていたかも計測出来ます。 2013年やらないことリストを作るために役立つかなーと思います。&lt;/p&gt;
</content:encoded></item><item><title>Skypeが重くなる問題を解決！会話ログを最適化</title><link>https://blog.teraren.com/posts/skype-sqlite-optimization/</link><guid isPermaLink="true">https://blog.teraren.com/posts/skype-sqlite-optimization/</guid><description>SkypeのSQLiteデータベースにVACUUMコマンドを実行するだけで会話ログを最適化し動作を軽くする方法。Macでのコマンド一発実行手順とテーブル構造も紹介。</description><pubDate>Thu, 10 Jan 2013 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;会話ログはsqliteで保存されているので、terminalで以下のコマンドを一発打つだけで最適化。&lt;br /&gt;
過去ログの検索がちょっと早くなったりする。かも。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;vacuum;&quot; | sqlite3 /Users/matsu/Library/Application\ Support/Skype/*/main.db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;補足&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sqlite3 &quot;./Library/Application Support/Skype/matsugree/main.db&quot; 
SQLite version 3.7.12 2012-04-03 19:43:07
Enter &quot;.help&quot; for instructions
Enter SQL statements terminated with a &quot;;&quot;
sqlite&amp;gt; .tables
Accounts        ChatMembers     Conversations   Participants    Videos        
Alerts          Chats           DbMeta          SMSes           Voicemails    
CallMembers     ContactGroups   LegacyMessages  Transfers     
Calls           Contacts        Messages        VideoMessages 
sqlite&amp;gt; .schema Messages
CREATE TABLE &quot;Messages&quot; (id INTEGER NOT NULL PRIMARY KEY, is_permanent INTEGER, convo_id INTEGER, chatname TEXT, author TEXT, from_dispname TEXT, author_was_live INTEGER, guid BLOB, dialog_partner TEXT, timestamp INTEGER, type INTEGER, sending_status INTEGER, consumption_status INTEGER, edited_by TEXT, edited_timestamp INTEGER, param_key INTEGER, param_value INTEGER, body_xml TEXT, identities TEXT, reason TEXT, leavereason INTEGER, participant_count INTEGER, error_code INTEGER, chatmsg_type INTEGER, chatmsg_status INTEGER, body_is_rawxml INTEGER, oldoptions INTEGER, newoptions INTEGER, newrole INTEGER, pk_id INTEGER, crc INTEGER, remote_id INTEGER, call_guid TEXT, extprop_chatmsg_ft_index_timestamp INTEGER, extprop_chatmsg_is_pending INTEGER);
CREATE INDEX IX_Messages_call_guid ON Messages (call_guid);
CREATE INDEX IX_Messages_convo_id_timestamp_consumption_status_sending_status ON Messages (convo_id, timestamp, consumption_status, sending_status);
CREATE INDEX IX_Messages_remote_id ON Messages (remote_id);
CREATE INDEX IX_Messages_timestamp_chatname ON Messages (timestamp, chatname);
CREATE INDEX IX_Messages_timestamp_convo_id_type ON Messages (timestamp, convo_id, type);
sqlite&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>git の便利なサブコマンド</title><link>https://blog.teraren.com/posts/git-usuful-subcommand/</link><guid isPermaLink="true">https://blog.teraren.com/posts/git-usuful-subcommand/</guid><description>git-extrasで追加されるgit undo・git obliterate・git changelogなど、生のgitを拡張する便利なサブコマンドを紹介</description><pubDate>Wed, 26 Dec 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://github.com/visionmedia/git-extras&quot;&gt;https://github.com/visionmedia/git-extras&lt;/a&gt; 生のgitをより便利にするためのサブコマンド集。&lt;/p&gt;
&lt;p&gt;リリース管理も出来ちゃう。&lt;/p&gt;
&lt;p&gt;いっぱいあるので抜粋。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;reset --hard HEAD~x&lt;/code&gt;のalias&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git undo
% git undo 3
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;容量の大きいファイルを間違って追加してしまった際に、過去のリビジョンからも存在を消去したいとき。&lt;/h3&gt;
&lt;p&gt;過去のリビジョンIDが書き換わるので要注意。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git obliterate secrets.json
Rewrite e814bdf6e24c3468fba1b7185a135d5bb9273758 (125/126)rm &apos;History.md&apos;
Rewrite 8e4a332bbea3aa890c2d4fdc1528e082e13dc54f (126/126)rm &apos;History.md&apos;

Ref &apos;refs/heads/master&apos; was rewritten
WARNING: Ref &apos;refs/remotes/origin/master&apos; is unchanged
WARNING: Ref &apos;refs/remotes/origin/master&apos; is unchanged
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;半自動で、CHANGELOGファイルを作ってくれる。リリース管理系のコマンドと組み合わせて使うとかなり楽。&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% git-changelog
n.n.n / 2012-12-27_
==================

  * updated
  * added SmartyJump
  * matsubo01
  * updated according to famous option
  * deleted dstat directory due to the curious error
  * .vimrc maintenance.
  * updated on matsubo01
  * added pdv and nerd tree
  * updated
  * formatted
  * updated readme
  * matsubo01
  * Merge branch &apos;master&apos; of github.com:matsubo/matsu-shell-setting
  * added syntax check
  * minor chnage
  * Merge branch &apos;master&apos; of git://github.com/matsubo/matsu-shell-setting
....
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Author毎のコミット数と割合を表示してくれる。&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% git summary

 project  : .setting
 repo age : 1 year, 9 months
 active   : 63 days
 commits  : 124
 files    : 11287
 authors  :
   124  Yuki Matsukura          100.0%
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Packfire Framework</title><link>https://blog.teraren.com/posts/packfire-framework/</link><guid isPermaLink="true">https://blog.teraren.com/posts/packfire-framework/</guid><description>Packfire Framework</description><pubDate>Wed, 26 Dec 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Githubをぶらぶらしていたら、&lt;a href=&quot;http://mauris.sg/packfire/&quot;&gt;Packfire&lt;/a&gt;というPHP Web Application Frameworkを偶然見つけた。&lt;/p&gt;
&lt;p&gt;Official Siteがかっこいい。また、使っている要素技術が、PHP5.3 + &lt;a href=&quot;http://php.net/manual/en/language.namespaces.php&quot;&gt;Namespace&lt;/a&gt; + &lt;a href=&quot;http://www.phpunit.de/manual/3.6/en/index.html&quot;&gt;PHPUnit&lt;/a&gt; + &lt;a href=&quot;http://about.travis-ci.org/docs/user/languages/php/&quot;&gt;Composer&lt;/a&gt; + &lt;a href=&quot;https://travis-ci.org&quot;&gt;Travis&lt;/a&gt; とあり、今風の組み合わせなので、動かしてみた。&lt;/p&gt;
&lt;p&gt;デモ：&lt;a href=&quot;https://matsu.teraren.com/app-structure/&quot;&gt;https://matsu.teraren.com/app-structure/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Composerが入っている前提で。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone git://github.com/packfire/packfire-framework.git
cd packfire-framework
composer install

cd ..

git clone git://github.com/packfire/app-structure.git
cd app-structure/src
composer install
chmod 777  pack/storage/
vi pack/config/app.yml
cp pack/constants.php.dist pack/constants.php
vi pack/constants.php
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2012/12/Screen-Shot-2012-12-26-at-10.30.31.png&quot; alt=&quot;Screen Shot 2012-12-26 at 10.30.31&quot; /&gt;&lt;/p&gt;
&lt;p&gt;app-structure/index.phpをブラウザ経由で開くと以下の画面が表示される。&lt;/p&gt;
</content:encoded></item><item><title>手元のrvm環境を最新にする</title><link>https://blog.teraren.com/posts/update-local-rvm-environment/</link><guid isPermaLink="true">https://blog.teraren.com/posts/update-local-rvm-environment/</guid><description>手元のrvm環境を最新にする</description><pubDate>Sun, 16 Dec 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;手元のRuby環境を最新に更新する方法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl https://gist.github.com/raw/4305911/update.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/4305911&quot;&gt;https://gist.github.com/4305911&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;（すぐ古くなってしまうんですよねぇ。。）&lt;/p&gt;
</content:encoded></item><item><title>シングルトンが邪悪な理由</title><link>https://blog.teraren.com/posts/evil-singleton/</link><guid isPermaLink="true">https://blog.teraren.com/posts/evil-singleton/</guid><description>グローバル変数化・単一責務違反・テスト困難という3つの観点からSingletonパターンが設計上有害な理由を、コード例と代替パターンを交えて解説</description><pubDate>Tue, 20 Nov 2012 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Singletonが多用されたコードベースをメンテナンスする機会があり、非常に残念な思いをしたので書きます。&lt;/li&gt;
&lt;li&gt;海外では&lt;a href=&quot;https://wiki.c2.com/?SingletonsAreEvil&quot;&gt;Singletons Are Evil&lt;/a&gt;としてWikiWikiWebでも議論されていた。20年以上経った今でもこの問題は解決されていない。&lt;/li&gt;
&lt;li&gt;Singletonパターンはデザパタの中でも理解しやすいので、「&lt;strong&gt;デザパタ使ってる俺かっこいい&lt;/strong&gt;」みたいなノリで多用されがち。&lt;strong&gt;初心者が最初に覚えて、最初に乱用するパターン&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;何が問題なのか&lt;/h2&gt;
&lt;h3&gt;1. グローバル変数と何が違うの？&lt;/h3&gt;
&lt;p&gt;Singletonパターンはシステム上で1つだけのインスタンスを提供する。よって、サービス内でオブジェクトの参照を持ち回る必要がなくなる。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;で、それってグローバル変数と何が違うの？&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Singleton経由のアクセス。グローバル変数と本質的に同じ。
class OrderService {
    public function process(Order $order): void {
        $db = Database::getInstance();      // どこからでもアクセス可能
        $logger = Logger::getInstance();    // 隠れた依存関係
        $cache = Cache::getInstance();      // クラスの外から見えない

        $db-&amp;gt;save($order);
        $logger-&amp;gt;info(&quot;Order processed&quot;);
        $cache-&amp;gt;invalidate(&quot;orders&quot;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この&lt;code&gt;OrderService&lt;/code&gt;のコンストラクタやメソッドシグネチャを見ても、&lt;code&gt;Database&lt;/code&gt;、&lt;code&gt;Logger&lt;/code&gt;、&lt;code&gt;Cache&lt;/code&gt;に依存していることが&lt;strong&gt;わからない&lt;/strong&gt;。コードを読まないと依存関係が見えない。&lt;/p&gt;
&lt;p&gt;参照を持ち回らなくて良くなる代わりに、微妙なシステムデザインになってしまう。&lt;strong&gt;システムデザインを深く考えると、ほとんどの場合、グローバル変数を使わなくて済む&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;2. 単一責任原則に違反する&lt;/h3&gt;
&lt;p&gt;Singletonを使うと、1つのクラスに「ビジネスロジック」と「インスタンスの生成管理」という2つの責務を課してしまう。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// BAD: クラスが自分のインスタンス管理まで担当してしまう
class Database {
    private static ?Database $instance = null;

    private function __construct() { /* ... */ }

    // ビジネス要件とは無関係な責務
    public static function getInstance(): Database {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    public function query(string $sql): array { /* ... */ }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;クラス自身は、Singletonかどうかを気にする必要は無い。&lt;strong&gt;クラスはビジネス要件のみを考えるべき。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;生成方法を制限したければ、FactoryパターンやDIコンテナでオブジェクトの生成をカプセル化し、そこで制約を設ければよい。&lt;/p&gt;
&lt;h3&gt;3. テストが地獄になる&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;一番つらいのがこれ。&lt;/strong&gt; Singletonのせいでユニットテストが非常に困難になる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// テストでDBをモックに差し替えたいが、Singletonだと不可能
class OrderServiceTest extends TestCase {
    public function testProcess(): void {
        // Database::getInstance() が実際のDBを返してしまう。
        // テストが本番DBに依存してしまう。。。
        $service = new OrderService();
        $service-&amp;gt;process(new Order());
        // DBの状態が前のテストから引き継がれてしまう。。。
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;テストは1つ1つが独立していなければならない。Singletonは状態を持ち続けるので、テスト間で状態がリークする。テストの実行順序によって結果が変わるとか、もう最悪。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Singletonを使わないことは、テストドリブンな開発の基本。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;4. 結合度が上がってモック不可能になる&lt;/h3&gt;
&lt;p&gt;Singletonを使うと、クラス間の結合度が高くなり、ポリモーフィズムやモックへの差し替えが難しくなる。&lt;/p&gt;
&lt;p&gt;結合度が高いコードは変更に弱い。Singletonの実装を変えたら、それを使っている全クラスに影響が波及する。&lt;/p&gt;
&lt;h2&gt;代わりにどうすればいいのか&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Dependency Injection (DI) を使う。&lt;/strong&gt; これだけ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// GOOD: 依存関係がコンストラクタで明示される
class OrderService {
    public function __construct(
        private DatabaseInterface $db,
        private LoggerInterface $logger,
        private CacheInterface $cache,
    ) {}

    public function process(Order $order): void {
        $this-&amp;gt;db-&amp;gt;save($order);
        $this-&amp;gt;logger-&amp;gt;info(&quot;Order processed&quot;);
        $this-&amp;gt;cache-&amp;gt;invalidate(&quot;orders&quot;);
    }
}

// テストでモックに差し替え可能
class OrderServiceTest extends TestCase {
    public function testProcess(): void {
        $mockDb = $this-&amp;gt;createMock(DatabaseInterface::class);
        $mockDb-&amp;gt;expects($this-&amp;gt;once())
               -&amp;gt;method(&apos;save&apos;);

        $service = new OrderService(
            $mockDb,
            new NullLogger(),
            new ArrayCache(),
        );
        $service-&amp;gt;process(new Order());
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;比較項目&lt;/th&gt;
&lt;th&gt;Singleton&lt;/th&gt;
&lt;th&gt;DI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;依存関係の可視性&lt;/td&gt;
&lt;td&gt;隠蔽される&lt;/td&gt;
&lt;td&gt;コンストラクタで明示&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;テスト容易性&lt;/td&gt;
&lt;td&gt;モック困難&lt;/td&gt;
&lt;td&gt;モック容易&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;結合度&lt;/td&gt;
&lt;td&gt;高い（具象クラス直結）&lt;/td&gt;
&lt;td&gt;低い（インターフェース経由）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;単一責任原則&lt;/td&gt;
&lt;td&gt;違反（生成+ロジック）&lt;/td&gt;
&lt;td&gt;準拠（生成は外部で）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;状態管理&lt;/td&gt;
&lt;td&gt;グローバルで状態保持&lt;/td&gt;
&lt;td&gt;スコープで制御可能&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;インスタンスを1つに制限したければ、DIコンテナ側で制御すればよい。クラス自身がSingletonである必要はない。&lt;/p&gt;
&lt;h2&gt;引用元&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.c2.com/?SingletonsAreEvil&quot;&gt;Singletons Are Evil - WikiWikiWeb (C2 Wiki)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;所感&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ミドルウェアレベルでSingletonが多用されたコードをDevOpsする仕事がありましたが、テストコードが書けなくて苦しかった。書けることは書けるけど、コンテクストを意識したテストになり、正当性を機械的にチェック出来ない。&lt;/li&gt;
&lt;li&gt;理想のオブジェクト指向で書かれたアプリケーションは、利用者が&lt;code&gt;new&lt;/code&gt;を呼ぶことで初めてオブジェクトが生成されることが理想。Singletonだと誰がいつ作ったかよくわからないオブジェクトが漂っている状態になる。&lt;/li&gt;
&lt;li&gt;メモリ節約の利点はあるが、それ以上にデメリットが大きすぎる。Pro/Conを整理して判断すべきだけど、ほとんどの場合はDIで代替できる。&lt;/li&gt;
&lt;li&gt;Singletonで書かれたコードを見つけたら&lt;code&gt;git blame&lt;/code&gt;して、作者にこの記事のURLを送りつけるなどして頂ければと思います。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>コマンドラインで集合演算</title><link>https://blog.teraren.com/posts/element-calculation/</link><guid isPermaLink="true">https://blog.teraren.com/posts/element-calculation/</guid><description>sortとuniqコマンドを組み合わせてCSVファイルの積集合・和集合・差集合をコマンドラインで手軽に計算する方法</description><pubDate>Fri, 09 Nov 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Retention Rateの計算ってめんどくさいですよね。&lt;br /&gt;
自分でプログラム書いてもいいけど、メモリ食うからちゃんと書かないといけないから、長くなっちゃうし。&lt;br /&gt;
Map Reduce使えばすぐだけど、そんなの手元にない場合が多いよね。&lt;/p&gt;
&lt;p&gt;でも、手元にある大量のレコードがあるCSVファイルなどを簡単に集計したいときにコマンドによる処理が便利です。&lt;/p&gt;
&lt;h2&gt;前提&lt;/h2&gt;
&lt;p&gt;A={1,2,3}&lt;br /&gt;
B={3,4,5}&lt;/p&gt;
&lt;h2&gt;A∩B&lt;/h2&gt;
&lt;p&gt;積集合。AとB両方にある。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat A B | sort | uniq -d
3
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;A∪B&lt;/h2&gt;
&lt;p&gt;和集合。AかBに含まれる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat A B | sort | uniq
1
2
3
4
5
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;A∪B - A∩B&lt;/h2&gt;
&lt;p&gt;排他。AまたはBに存在する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat A B | sort | uniq -u
1
2
4
5
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Google ReaderのstarredをInstapaperに自動送信</title><link>https://blog.teraren.com/posts/ifttt/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ifttt/</guid><description>Google ReaderのstarredをInstapaperに自動送信</description><pubDate>Fri, 02 Nov 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;InstaReaderがサービス停止してしまっているので、新しいの見つけた。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://ifttt.com/&quot;&gt;http://ifttt.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;設定は簡単。説明いらず。&lt;/p&gt;
&lt;p&gt;このサービスを使えば、「iPhoneで気になる記事にどんどんstarつけていって、暇なときにinstapaperでざーっと読む」ことができるようになる。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://ifttt.com/recipes/64823&quot;&gt;これが作ったレシピ&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>最新版GNU Screenインストール方法</title><link>https://blog.teraren.com/posts/how-to-install-the-newest-screen/</link><guid isPermaLink="true">https://blog.teraren.com/posts/how-to-install-the-newest-screen/</guid><description>最新版GNU Screenインストール方法</description><pubDate>Sun, 16 Sep 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;備忘録&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone git://git.savannah.gnu.org/screen.git
cd screen/src
./configure --prefix=/usr/local --enable-colors256
make
sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;--enable-colors256&lt;/code&gt; を忘れると残念なことになる。&lt;/p&gt;
</content:encoded></item><item><title>Mac Book Airのディスク容量をお手軽に増やす</title><link>https://blog.teraren.com/posts/mac-disk/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-disk/</guid><description>Mac Book Airのディスク容量をお手軽に増やす</description><pubDate>Sun, 12 Aug 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;内蔵のSSDは高速だけど、高価なので利用頻度が低く、低速な読み書きで良いデータを保管しておくにはもったいない。&lt;br /&gt;
最近のmicro SDリーダーはすごく小さいので、micro SDにMP3を30GB移動しました。&lt;/p&gt;
&lt;p&gt;おそらく、XMLの読み書きが遅いせいか、itunesの反応が遅いけど、まぁ音楽だから許す。&lt;/p&gt;
&lt;p&gt;たった2000円で32GB増えるならお得かな。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2012/08/2012-08-11-21.41.33.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0056TYX8U&quot;}
::amazon{asin=&quot;B001MQBRJE&quot;}&lt;/p&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;3ヶ月使って、SDカードが読み取り不能になりました。&lt;br /&gt;
外部メディアは信頼性低いなぁ。。。&lt;/p&gt;
</content:encoded></item><item><title>WordPress 3.4.1にしてからDBが刺さる</title><link>https://blog.teraren.com/posts/wordpress-3-4-1-database-lock/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-3-4-1-database-lock/</guid><description>WordPress 3.4.1にしてからDBが刺さる</description><pubDate>Wed, 01 Aug 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;show full processlistしてみると、以下のクエリーがテーブルレベルのロックを取得しているようで、他のスレッドをブロックしていると。ストレージがなぜだかMyISAMなのがいけないのだろうけど、66万件のindex貼ってないカラムへの問い合わせなので遅い。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT comment_approved FROM wp_comments WHERE comment_author = &apos;rfwphcrtfzz&apos; AND comment_author_email = &apos;m.o.r.pow.a.ll.fo@gmail.com&apos; and comment_approved = &apos;1&apos; LIMIT 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しょうがないので、ツリーが綺麗に出来そうなカラムにindex貼る。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;create index comment_author  on wp_comments (comment_author(2));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;1分以上返ってこなかったクエリーが、0.00秒で返るようになった。&lt;/p&gt;
&lt;p&gt;これのせいで、アフィリエイト収入が前月より数万円ダウン。。。。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://core.trac.wordpress.org/ticket/21435&quot;&gt;バグレポート&lt;/a&gt;送ったった。&lt;/p&gt;
&lt;h2&gt;追記(2014/7/20)&lt;/h2&gt;
&lt;p&gt;修正用patchを投稿して2年が経過し、WordPress4.0で修正されることになりました！&lt;br /&gt;
&lt;a href=&quot;https://core.trac.wordpress.org/ticket/21435&quot;&gt;https://core.trac.wordpress.org/ticket/21435&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>ファーストサーバー報告書から考えるエンジニアの仕事のあり方</title><link>https://blog.teraren.com/posts/first-server-accident/</link><guid isPermaLink="true">https://blog.teraren.com/posts/first-server-accident/</guid><description>ファーストサーバー大規模障害の報告書を読んで考察。優秀なエンジニアほど起こしやすいミスのパターン、安全性とパフォーマンスのバランス、防御的プログラミングの重要性を論じる。</description><pubDate>Tue, 31 Jul 2012 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;ファーストサーバーの障害報告&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://support.fsv.jp/urgent/pdf/fs-report.pdf&quot;&gt;http://support.fsv.jp/urgent/pdf/fs-report.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;月末だし、月初へ向けてファーストサーバーの障害報告を読んで、エンジニアの仕事のあり方に関して思ったことを書く。&lt;/p&gt;
&lt;h3&gt;上記のPDFから得られる知見&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;周りに比べて、優秀な人がこのような問題を起こす可能性が高い。&lt;/li&gt;
&lt;li&gt;どんな人でもミスを起こすことの証明。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;レースで例えると&lt;/h3&gt;
&lt;p&gt;サーキットでカローラを与えられて、100周しろ！と言われたときに、エアバッグなどの重い安全装置を取っ払い、ターボ付けたりサスペンション変えたりして改造し、より早いラップタイムを目指した結果、コースアウトしてマシンが大破した状態。&lt;/p&gt;
&lt;p&gt;与えられた車。&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2012/07/3449571798_413eb8ca6f_m.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2012/07/3449571798_413eb8ca6f_m.jpg&quot; alt=&quot;&quot; title=&quot;3449571798_413eb8ca6f_m&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;高いパフォーマンスを出したい人の車。&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2012/07/4105562538_1d41589027_m.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2012/07/4105562538_1d41589027_m.jpg&quot; alt=&quot;&quot; title=&quot;4105562538_1d41589027_m&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;安全性vsパフォーマンス理論&lt;/h3&gt;
&lt;p&gt;いくら仕事のパフォーマンスが高くても、安全に仕事を行えていないとこのような大障害になってしまう可能性がある。よって、安全対策とパフォーマンスの理想はバランスが取れていなければ行けないので、関係性は1次関数で有るべき。安全対策をy、パフォーマンスをxとするとy=xが理想の関数だと思う。(一番上のグラフ)故に、仕事のパフォーマンスを高くしたい場合は、より安全なプログラミングスキルを身につける必要があると考える。&lt;/p&gt;
&lt;p&gt;仕事のパフォーマンスを上げるためには、正確性や安全性を考慮した仕組みやプログラムを書く必要がある。今回はy=x/a(a&amp;lt;1)ぐらいにポジショニングされるような運用をしていたから起きた事故と考えられる。&lt;/p&gt;
&lt;h3&gt;防御的プログラミング&lt;/h3&gt;
&lt;p&gt;9年前に、大学の先輩が「OOPで例外ハンドリングを見ればその人のスキルがわかる」と言っているのを聞いて以来、面接やコードレビューの度に、その通りだなぁと感じていた。まさに、上記のy=x理論に当てはまる。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;自分のポジショニングはどこ？理想のポジショニングはどこ？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;と考えさせられる報告書でした。&lt;/p&gt;
&lt;h3&gt;どうやってそれぞれを上げるか&lt;/h3&gt;
&lt;h4&gt;performanceの上げ方&lt;/h4&gt;
&lt;p&gt;いわゆる攻め。日々の勉強、研究、並列化、フレームワークやライブラリなどを使う。&lt;/p&gt;
&lt;h4&gt;safety levelの上げ方&lt;/h4&gt;
&lt;p&gt;守り。コードを書かないことが一番。フレームワークを使ったり、ライブラリを使ったりすでに安全性が保証されたツールを使うのが一番。もし存在しなかったら、防御的プログラミングスキルやテスト、QAなどを用いる。&lt;/p&gt;
&lt;h3&gt;写真&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/a7design1/4105562538/&quot;&gt;http://www.flickr.com/photos/a7design1/4105562538/&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.flickr.com/photos/viriyincy/3449571798/&quot;&gt;http://www.flickr.com/photos/viriyincy/3449571798/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Nexus S（Android 4.1）でスクリーンショット</title><link>https://blog.teraren.com/posts/android-screenshot/</link><guid isPermaLink="true">https://blog.teraren.com/posts/android-screenshot/</guid><description>Nexus S（Android 4.1）でスクリーンショット</description><pubDate>Sun, 29 Jul 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2012/07/2012-07-29-01.14.47.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2012/07/2012-07-29-01.14.47.png&quot; alt=&quot;&quot; title=&quot;screenshot&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;電源ボタンとボリュームダウンボタンを同時に押して、2秒ぐらい待つ。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Android 4.0から上記の方法でスクリーンショットを撮れる。タイミングが難しいけど、慣れれば大丈夫かな。携帯を挟み込むようにして強く持てば同時に押せる。&lt;/p&gt;
</content:encoded></item><item><title>マルチスレッド○○画像ダウンローダー</title><link>https://blog.teraren.com/posts/multithread-image-downloader/</link><guid isPermaLink="true">https://blog.teraren.com/posts/multithread-image-downloader/</guid><description>マルチスレッド○○画像ダウンローダー</description><pubDate>Sat, 28 Jul 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;rubyの勉強を兼ねて、マルチスレッドで「炎のアップローダー」から○○画像をダウンロードするスクリプトを書きました。 &lt;a href=&quot;https://github.com/matsubo/multi-thread-image-downloader&quot;&gt;https://github.com/matsubo/multi-thread-image-downloader&lt;/a&gt; 使い方。Macの人はTerminalにコピペすると動くと思う。（bundleにsudo必要かも） 主な機能&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重複ファイルダウンロードしない&lt;/li&gt;
&lt;li&gt;ファイル名をmd5のhashで保存&lt;/li&gt;
&lt;li&gt;マルチスレッド&lt;/li&gt;
&lt;li&gt;オプションでproxy経由できる&lt;/li&gt;
&lt;li&gt;User-Agent偽装&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;詳しくは、こちらのマニュアルをご参照ください。forkお待ちしています。 &lt;a href=&quot;https://github.com/matsubo/multi-thread-image-downloader/blob/master/README.md&quot;&gt;https://github.com/matsubo/multi-thread-image-downloader/blob/master/README.md&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Mac OS X Serverデフォルトシェル変更</title><link>https://blog.teraren.com/posts/mac-os-x-server-default-shell/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-os-x-server-default-shell/</guid><description>Mac OS X Serverデフォルトシェル変更</description><pubDate>Tue, 24 Jul 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;chshはローカルのUNIXアカウントしか使えないので、Open Directoryの設定を変える必要がある。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dscl . -create /Users/&amp;lt;ユーザ名&amp;gt; UserShell /bin/zsh
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Googleの検索結果にアイコンを表示する方法</title><link>https://blog.teraren.com/posts/google-result-icon/</link><guid isPermaLink="true">https://blog.teraren.com/posts/google-result-icon/</guid><description>Googleの検索結果にアイコンを表示する方法</description><pubDate>Sun, 15 Jul 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2012/07/Screen-Shot-2012-07-15-at-5.13.31.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2012/07/Screen-Shot-2012-07-15-at-5.13.31.png&quot; alt=&quot;&quot; title=&quot;Screen Shot 2012-07-15 at 5.13.31&quot; /&gt;&lt;/a&gt; 最近、Googleの検索結果にgoogle plusの画像が表示されるのを目にする。 CTR高そうなので試してみる。 WordPressだと&lt;a href=&quot;http://wordpress.org/extend/plugins/wordpress-seo/&quot;&gt;YOAST&lt;/a&gt;を使っているケースが多く紹介されているが、このプラグインはいろいろなことをしすぎて管理画面が煩雑になったり、余計なことをいろいろするので、お勧め出来ない。（元から使っていれば問題無いけど） そこで、みんなだいすき&lt;a href=&quot;http://wordpress.org/extend/plugins/all-in-one-seo-pack/&quot;&gt;All in one SEO&lt;/a&gt;でも出来ます。 デフォルトの項目はこちら。ここに入力するか、WordPress自体のユーザプロフィールページから、Google+のURLを設定する。↓ &lt;a href=&quot;../../assets/uploads/2012/07/Screen-Shot-2012-07-15-at-5.12.51.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2012/07/Screen-Shot-2012-07-15-at-5.12.51.png&quot; alt=&quot;&quot; title=&quot;Screen Shot 2012-07-15 at 5.12.51&quot; /&gt;&lt;/a&gt; 正しく出来ているかテストするツールはこちら。 &lt;a href=&quot;http://www.google.com/webmasters/tools/richsnippets?&quot;&gt;http://www.google.com/webmasters/tools/richsnippets?&lt;/a&gt; エラーが起きても、内容によっては問題無いみたい。→正常に設定されていればちゃんと表示されます。 &lt;a href=&quot;http://productforums.google.com/forum/#!topic/webmasters/SkO5Nd8tQ9w&quot;&gt;http://productforums.google.com/forum/#!topic/webmasters/SkO5Nd8tQ9w&lt;/a&gt; ------------------ なかなか検索結果に出てこなかったのでがっつりトラブルシューティングした。その結果、プレビューツールでアイコンが正常に表示されるようになった。 以下、わかったこと。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自分のプロフィールにリンクしてはうまくいかなかった。新しくGoogle Plusのページを作った上で、そのページのURLを記述する必要がある。 &lt;a href=&quot;https://plus.google.com/116053332519363476408&quot;&gt;自分&lt;/a&gt; &lt;a href=&quot;https://plus.google.com/111854646127166312894/&quot;&gt;ページ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ページ内に、rel=&quot;me&quot;のリンクが存在してはいけない。WordPressの「リンク」機能で、「自分」を設定したリンクがあるとそっちを見に行ってしまう見たいなので、「自分」属性は全て無くす必要がある。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>gangliaをMac OS X Serverにインストール</title><link>https://blog.teraren.com/posts/ganglia-mac/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ganglia-mac/</guid><description>HomebrewでGangliaをMac OS X Serverにインストールし、gmetadとgmondを自動起動させるまでの手順をコマンド付きで解説</description><pubDate>Thu, 12 Jul 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;超簡単でした。&lt;/p&gt;
&lt;p&gt;インストール&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% brew install ganglia
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;テストのために、設定をコピー&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cp /usr/local/etc/gmetad.conf .
% gmond --default_config &amp;gt; gmond.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;シェルを2つ立ち上げて、テスト起動&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo gmetad --conf=./gmetad.conf --debug=1
% sudo gmond --conf=./gmond.conf --debug=3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;文字が出力されているようだったら、Ctrl-Cでkillして大丈夫。&lt;/p&gt;
&lt;p&gt;自動起動の設定&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo vi  /Library/LaunchDaemons/org.ganglia.gmetad.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&apos;1.0&apos; encoding=&apos;UTF-8&apos;?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple Computer//DTD PLIST 1.0//EN&quot;
&quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;
&amp;lt;plist version=&apos;1.0&apos;&amp;gt;
&amp;lt;dict&amp;gt;
&amp;lt;key&amp;gt;Label&amp;lt;/key&amp;gt;&amp;lt;string&amp;gt;org.ganglia.gmetad&amp;lt;/string&amp;gt;
&amp;lt;key&amp;gt;ProgramArguments&amp;lt;/key&amp;gt;
&amp;lt;array&amp;gt;
&amp;lt;string&amp;gt;/usr/local/bin/gmetad&amp;lt;/string&amp;gt;
&amp;lt;string&amp;gt;-d&amp;lt;/string&amp;gt;
&amp;lt;string&amp;gt;1&amp;lt;/string&amp;gt;
&amp;lt;/array&amp;gt;
&amp;lt;key&amp;gt;RunAtLoad&amp;lt;/key&amp;gt;
&amp;lt;true/&amp;gt;
&amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;% sudo vi  /Library/LaunchDaemons/org.ganglia.gmond.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&apos;1.0&apos; encoding=&apos;UTF-8&apos;?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple Computer//DTD PLIST 1.0//EN&quot;
&quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;
&amp;lt;plist version=&apos;1.0&apos;&amp;gt;
&amp;lt;dict&amp;gt;
&amp;lt;key&amp;gt;Label&amp;lt;/key&amp;gt;&amp;lt;string&amp;gt;org.ganglia.gmond&amp;lt;/string&amp;gt;
&amp;lt;key&amp;gt;ProgramArguments&amp;lt;/key&amp;gt;
&amp;lt;array&amp;gt;
&amp;lt;string&amp;gt;/usr/local/bin/gmond&amp;lt;/string&amp;gt;
&amp;lt;string&amp;gt;-d&amp;lt;/string&amp;gt;
&amp;lt;string&amp;gt;1&amp;lt;/string&amp;gt;
&amp;lt;/array&amp;gt;
&amp;lt;key&amp;gt;RunAtLoad&amp;lt;/key&amp;gt; &amp;lt;true/&amp;gt;
&amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ロードして、自動起動に設定する&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo launchctl load -w /Library/LaunchDaemons/org.ganglia.gmond.plist
% sudo launchctl load -w /Library/LaunchDaemons/org.ganglia.gmetad.plist
% sudo launchctl list|grep ganglia
54 - org.ganglia.gmond
55 - org.ganglia.gmetad
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Webのフロントエンドを設定する。&lt;br /&gt;
&lt;a href=&quot;http://sourceforge.net/projects/ganglia/files/ganglia-web/&quot;&gt;Webのフロントエンドはここから最新をダウンロードする。&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cd public_html
% wget &apos;http://downloads.sourceforge.net/project/ganglia/ganglia-web/3.5.0/ganglia-web-3.5.0.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fganglia%2Ffiles%2Fganglia-web%2F3.5.0%2F&amp;amp;ts=1342027177&amp;amp;use_mirror=jaist&apos;
% tar xf ganglia-web*
% mv ganglia-web-3.5.0.tar.gz ganglia-web
% cd ganglia-web
% sudo mkdir /var/lib/ganglia/conf
% sudo chmod 777  /var/lib/ganglia/conf
% sudo mkdir /var/lib/ganglia/dwoo/compiled
% sudo mkdir -p /var/lib/ganglia/dwoo/compiled
% sudo chmod 777 /var/lib/ganglia/dwoo/compiled
% sudo mkdir -p /var/lib/ganglia/dwoo/cache
% sudo chmod 777 /var/lib/ganglia/dwoo/cache
% make
% vi conf_default.php
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;rrdtoolのpathを変更して保存&lt;br /&gt;
→/opt/local/bin/rrdtool&lt;/p&gt;
&lt;p&gt;(1つのグラフで複数の変数が色分けされて出ないのはなぜだろう・・・)&lt;/p&gt;
</content:encoded></item><item><title>MySQL5.5をportでインストール</title><link>https://blog.teraren.com/posts/mysql5-5-port/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql5-5-port/</guid><description>MacPortsを使ってMySQL5.5をmacOSにインストールする手順。シンボリックリンクの作成から初期DB設定、launchctlによるサービス起動管理まで解説。</description><pubDate>Sat, 07 Jul 2012 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Install&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo port install mysql55 mysql55-server
sudo port load mysql55-server
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Setting&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ cd /opt/local/bin/
$ sudo ln -s /opt/local/lib/mysql55/bin/mysql mysql
$ sudo ln -s /opt/local/lib/mysql55/bin/mysql_config mysql_config
$ sudo cp my.cnf /etc/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;initial db&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ sudo -u _mysql /opt/local/lib/mysql55/bin/mysql_install_db
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;launch&lt;/h3&gt;
&lt;h4&gt;register&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ sudo launchctl load -w /Library/LaunchDaemons/org.macports.mysql55-server.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;stop&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ sudo launchctl unload /Library/LaunchDaemons/org.macports.mysql55-server.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;start&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ sudo launchctl load /Library/LaunchDaemons/org.macports.mysql55-server.plist
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;set the password&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ /opt/local/lib/mysql55/bin/mysqladmin -u root password &apos;111111&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;設定ファイルは以下の場所が参照されるようになっている。優先度高いっぽい。コンパイル時に指定されているような気がします。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/opt/local/etc/mysql55/my.cnf
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Disabling local timemachine cache</title><link>https://blog.teraren.com/posts/disabling-local-timemachine-cache/</link><guid isPermaLink="true">https://blog.teraren.com/posts/disabling-local-timemachine-cache/</guid><description>Disabling local timemachine cache</description><pubDate>Wed, 23 May 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Macを使っていると、だんだんとハードディスク容量が減ってくる。ハードディスクの空き容量を増やすための1つの手法は、&lt;a href=&quot;http://blog.livedoor.jp/dankogai/archives/51710148.html&quot;&gt;Timemachineに同期する前の一時的なデータ保存を無効化する&lt;/a&gt;。 Macは /.MobileBackups にTimemachineに繋がっていなくてもTimemachineを実行できるようにスナップショットをローカルディスクに保存している。そんなに頻繁にTimemachineにお世話になることはないので無効化する。 このコマンドを打った瞬間に消えるので注意。&lt;/p&gt;
</content:encoded></item><item><title>(Xcode 4.3)  Codesign operation failed Check that the identity you selected is valid</title><link>https://blog.teraren.com/posts/xcode-4-3-codesign-operation-failed-check-that-the-identity-you-selected-is-valid/</link><guid isPermaLink="true">https://blog.teraren.com/posts/xcode-4-3-codesign-operation-failed-check-that-the-identity-you-selected-is-valid/</guid><description>(Xcode 4.3)  Codesign operation failed Check that the identity you selected is valid</description><pubDate>Wed, 28 Mar 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2012/03/Screen-Shot-2012-03-28-at-13.44.01.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2012/03/Screen-Shot-2012-03-28-at-13.44.01.png&quot; alt=&quot;&quot; title=&quot;Screen Shot 2012-03-28 at 13.44.01&quot; /&gt;&lt;/a&gt; Version 4.3.2で、adhocビルドを行うと以下のエラーが起きる。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Codesign operation failed Check that the identity you selected is valid&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;証明書はちゃんとしているのに、なぜか失敗する。 英語圏では、かなり盛り上がってる。 &lt;a href=&quot;http://stackoverflow.com/questions/9386925/xcode-4-3-codesign-operation-failed-check-that-the-identity-you-selected-is-va/9649804#9649804&quot;&gt;http://stackoverflow.com/questions/9386925/xcode-4-3-codesign-operation-failed-check-that-the-identity-you-selected-is-va/9649804#9649804&lt;/a&gt; まとめると、諸説ある。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;4.3.1以降にはバージョンアップするな&lt;/li&gt;
&lt;li&gt;プログラムと同じディレクトリが含まれているとNG&lt;/li&gt;
&lt;li&gt;xarchiveのディレクトリ内を手動で移動してzipする&lt;/li&gt;
&lt;li&gt;とあるSDKを入れるとだめ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;試せる手法は一通り試してみましたが、未解決。。。&lt;/p&gt;
</content:encoded></item><item><title>git config --global push.default tracking</title><link>https://blog.teraren.com/posts/git-config-global-push-default-tracking/</link><guid isPermaLink="true">https://blog.teraren.com/posts/git-config-global-push-default-tracking/</guid><description>git config --global push.default tracking</description><pubDate>Fri, 16 Mar 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;git pushのデフォルトの挙動はtracking branchを全てpushしようとしてしまう。。。。&lt;br /&gt;
もし、pushしたくなくてローカルブランチでテスト中のコミットがあったら、不都合が起きてしまう。&lt;/p&gt;
&lt;p&gt;なので、ワークツリーにあるブランチだけpushするためのオプション。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git config --global push.default tracking
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>gitv便利</title><link>https://blog.teraren.com/posts/gitv/</link><guid isPermaLink="true">https://blog.teraren.com/posts/gitv/</guid><description>gitv便利</description><pubDate>Fri, 16 Mar 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2012/03/Screen-Shot-2012-03-16-at-1.23.51.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2012/03/Screen-Shot-2012-03-16-at-1.23.51.png&quot; alt=&quot;&quot; title=&quot;gitv&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;fugitiveの拡張の&lt;a href=&quot;http://www.gregsexton.org/portfolio/gitv/&quot;&gt;gitv&lt;/a&gt;便利。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2012/03/Screen-Shot-2012-03-16-at-1.32.051.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;fugitive自体も便利！！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2012/03/Screen-Shot-2012-03-16-at-3.13.38-e1331835455188.png&quot; alt=&quot;&quot; title=&quot;powerline&quot; /&gt;&lt;/p&gt;
&lt;p&gt;powerlineすげー！&lt;/p&gt;
</content:encoded></item><item><title>作業がはかどるヘッドフォン - ATH-ANC9</title><link>https://blog.teraren.com/posts/ath-anc9/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ath-anc9/</guid><description>ATH-ANC7の後継としてaudio-technica ATH-ANC9を購入。95%ノイズカットの実力、ATH-ANC7との比較、飛行機での使用感、イヤーパッド交換のメンテナンス体験談。</description><pubDate>Sun, 11 Mar 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ATH-ANC9&lt;/p&gt;
&lt;p&gt;今まで4年と2ヶ月間、週5回ぐらい利用していた&lt;a href=&quot;https://amzn.to/3m4OraH&quot;&gt;ATH-ANC7&lt;/a&gt;が壊れてしまった。&lt;/p&gt;
&lt;p&gt;次に買うのもやはりノイズキャンセリングヘッドフォンが欲しかったので&lt;br /&gt;
&lt;a href=&quot;https://amzn.to/3m80apk&quot;&gt;ATH-ANC9&lt;/a&gt;を買いました。&lt;/p&gt;
&lt;p&gt;ノイズキャンセリングヘッドフォンを選ぶ理由は、&lt;br /&gt;
・小さい音量で音楽が聴けるので難聴になりづらい&lt;br /&gt;
・飛行機で、疲れの原因となるエンジン音が軽減する&lt;br /&gt;
・集中したいときに、周りの騒音を減らせる&lt;/p&gt;
&lt;p&gt;今回、ノイズキャンセリングヘッドフォンを物色して主に、5000、1万、2万、3万のグレードがあることが分かりました。&lt;br /&gt;
今までは、2万円のグレードでしたが、低音に物足りなさがあるので3万円レベルのにしてみました。&lt;/p&gt;
&lt;p&gt;ATH-ANC9は再生周波数帯域は10～25,000Hz、出力音圧レベルも100dB/mWと充分です。&lt;br /&gt;
（BOSEのノイズキャンセリングは人の話し声の周波数はキャンセリングしないのであまり魅力的に感じませんでした）&lt;/p&gt;
&lt;p&gt;良い点：&lt;br /&gt;
・ATH-ANC7と比べて遮音性が優れている&lt;br /&gt;
・ATH-ANC7より大きめで、ドライバが大きいため重低音が綺麗に出る。&lt;br /&gt;
・全体的な音域がちゃんと出ていてかぶりが少ない&lt;br /&gt;
・さすが95％ノイズカットというだけあって、周りの話し声がかなり聞こえなくなる！&lt;/p&gt;
&lt;p&gt;悪い点：&lt;br /&gt;
・音楽を再生しないときのホワイトノイズが若干うるさい。ATH-ANC7よりホワイトノイズ大きい。&lt;br /&gt;
　（音楽を再生していれば気にならないけど、ただの騒音を消すためだけに使うには不向き）&lt;br /&gt;
・ATH-ANC7から比べると一回り大きい&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair &lt;em&gt;/}
FYI:エイジング用のMP3を発見した。普通に聞いたら、頭おかしくなりそうだった（w
{/&lt;/em&gt; textlint-enable ja-technical-writing/no-unmatched-pair */}
&lt;a href=&quot;http://www.vector.co.jp/soft/data/art/se415019.html&quot;&gt;http://www.vector.co.jp/soft/data/art/se415019.html&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;2012/6/4 追記&lt;br /&gt;
10時間越えのフライトを何回か使いました。On/Offをやってみるとかなりノイズカットしていることが分かります。&lt;br /&gt;
これのおかげで飛行機でも騒音を気にせずに寝られます。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;2014/6/17 追記&lt;br /&gt;
買って2年と3ヶ月経過。&lt;br /&gt;
イヤーパッドの根元が折れた。。。&lt;br /&gt;
保守部品が無いため、1万円払って、新品交換してもらった。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;2015/07/30 追記&lt;br /&gt;
イヤーパッドが崩壊しかけているので、&lt;a href=&quot;http://www.soundhouse.co.jp/products/detail/item/179323/&quot;&gt;交換用イヤーパッド&lt;/a&gt;を購入。&lt;br /&gt;
4000円ぐらい。&lt;br /&gt;
すごい取り付けづらいのですが、頑張ってはめれば綺麗にハマりました。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0077YTFPS&quot;}&lt;/p&gt;
</content:encoded></item><item><title>さくらVPSから1TBディスクをマウント</title><link>https://blog.teraren.com/posts/sakura-vps-sshfs-1tb/</link><guid isPermaLink="true">https://blog.teraren.com/posts/sakura-vps-sshfs-1tb/</guid><description>CentOS 6のさくらVPSから外部の1TBディスクをsshfsで5分でマウントする手順。fuse-sshfsのインストールから自動マウント設定まで、コピペで使えるコマンドで解説。</description><pubDate>Sun, 11 Mar 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;5分でさくらVPSから、外部にある1TBのディスクをマウントする方法を紹介します。&lt;/p&gt;
&lt;p&gt;現時点で最新のCentOS 6で実行しています。&lt;/p&gt;
&lt;h3&gt;初期設定&lt;/h3&gt;
&lt;p&gt;必要なパッケージをインストールし、権限を設定します。コピペでOK。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo yum install fuse-sshfs -y  
% sudo modprobe fuse  
% sudo chmod o+rw /dev/fuse  
% sudo chmod 4755 /bin/fusermount
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;マウント&lt;/h3&gt;
&lt;p&gt;マウントしてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sshfs teraren.com:/Volumes/disk3/matsu /mnt/teraren
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;dfコマンドを打つと、一番上にあるスクリーンショットのようになるはずです。&lt;/p&gt;
&lt;h3&gt;アンマウント&lt;/h3&gt;
&lt;p&gt;アンマウントしてみます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% fusermount -u /mnt/teraren
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;自動マウント&lt;/h3&gt;
&lt;p&gt;毎回コマンドを打ってマウントするのは大変なので、OS起動と同時にマウントできるように設定します。&lt;br /&gt;
(&lt;a href=&quot;http://webos-goodies.jp/archives/50672669.html&quot;&gt;こちら&lt;/a&gt;などを参考に、rootユーザパスフレーズ無しでssh接続できる前提です)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo -s  
# echo &apos;sshfs#matsu@teraren.com:/Volumes/disk3/matsu   /mnt/teraren  fuse    rw,nodev,nonempty,user,auto,noatime  0 0&apos; &amp;gt;&amp;gt; /etc/fstab  
# exit  
% mount /mnt/teraren
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>gitでSSLエラーが出たときの対処法</title><link>https://blog.teraren.com/posts/git-ssl/</link><guid isPermaLink="true">https://blog.teraren.com/posts/git-ssl/</guid><description>gitでSSLエラーが出たときの対処法</description><pubDate>Thu, 01 Mar 2012 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;vimのBundle installするとエラーが出て困った。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;error: SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed while accessing https://github.com/goodpic/hoge.git/info/refs
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;原因はgithubのレポジトリURLがSSLで指定されていて、CA証明書がローカルにインストールされていない場合に起きる。&lt;/p&gt;
&lt;p&gt;~/.gitconfigに以下を追加すると証明書のチェックをスキップできる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[http]
  sslVerify = false
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>PHP&apos;s MessageFormatter benchmark</title><link>https://blog.teraren.com/posts/phps-messageformatter-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/phps-messageformatter-benchmark/</guid><description>PHP&apos;s MessageFormatter benchmark</description><pubDate>Fri, 16 Dec 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2011/12/Screen-Shot-2011-12-16-at-19.13.22.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/12/Screen-Shot-2011-12-16-at-19.13.22.png&quot; alt=&quot;&quot; title=&quot;benchmak&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;../../assets/uploads/2011/12/Screen-Shot-2011-12-16-at-19.16.58.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/12/Screen-Shot-2011-12-16-at-19.16.58.png&quot; alt=&quot;&quot; title=&quot;graph&quot; /&gt;&lt;/a&gt; 測定環境は、PHP 5.3.8で、ab -n 500です。 数字は[#/sec]です。 &lt;a href=&quot;https://matsu.teraren.com/static/benchmark.tar.bz2&quot;&gt;ベンチマークプログラムダウンロード&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>テラレンの実測値</title><link>https://blog.teraren.com/posts/speed/</link><guid isPermaLink="true">https://blog.teraren.com/posts/speed/</guid><description>テラレンの実測値</description><pubDate>Thu, 15 Dec 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2011/12/sv1-1.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/12/sv1-1.png&quot; alt=&quot;&quot; title=&quot;回線速度&quot; /&gt;&lt;/a&gt; 回線速度は理論値通り、100Mbps出ています。 帯域にも余裕があります。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://teraren.com/?utm_source=blog&amp;amp;utm_medium=free&amp;amp;utm_campaign=speed&quot;&gt;いますぐこちらからお申し込みいただけます!&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>ID3タグをUNICODEへ変換</title><link>https://blog.teraren.com/posts/id3-convert/</link><guid isPermaLink="true">https://blog.teraren.com/posts/id3-convert/</guid><description>ID3タグをUNICODEへ変換</description><pubDate>Wed, 14 Dec 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;WindowsでID3タグを付けたmp3ファイルをmacのitunesでimportすると文字化けしてしまいます。&lt;/p&gt;
&lt;p&gt;WindowsでID3タグを付けるとShift−JISで付けられますが、MacのitunesではUNICODEとして扱っているため文字化けが発生してしまいます。&lt;/p&gt;
&lt;p&gt;ID3タグをUNICODEに変換するWindowsのアプリケーションは多数あるのですが、どれも大量のファイルの一括変換中に強制終了してしまう物ばかりでした。&lt;/p&gt;
&lt;p&gt;いろいろ試した結果、ID3iocnvというjavaプログラムが一番良かったです。&lt;/p&gt;
&lt;p&gt;ファイルの引数にmp3ファイルを指定するだけです。ファイルが多い場合は、何回かに分けて実行すれば大丈夫です。&lt;br /&gt;
&lt;a href=&quot;http://www.zhoufeng.net/eng/id3iconv/&quot;&gt;ID3iconv&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget http://www.zhoufeng.net/eng/id3iconv/download/id3iconv-0.2.1.jar
% java -jar id3iconv-0.2.1.jar file.mp3
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>効率の良いテスト手法の1つを紹介します - Pairwise testing</title><link>https://blog.teraren.com/posts/pairwise-testing/</link><guid isPermaLink="true">https://blog.teraren.com/posts/pairwise-testing/</guid><description>テストパターンの組合せ爆発を防ぐPairwise（All-pairs）テストの概念と、Javaツール・HEXAWISEを使った直交表生成の実践方法を紹介。</description><pubDate>Mon, 12 Dec 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;ソフトウェアテストのテストパターンについてです。&lt;/p&gt;
&lt;p&gt;条件網羅のテストケースを作成すると、テストパターンはO(nm)　n=項目数 m=各項目のパターン数 となり、指数的にパターンが増えてしまい、複雑な条件判定のテストが困難になります。&lt;/p&gt;
&lt;p&gt;その問題を解決するために、一般的には特徴のあるパターンを抽出してテストをする方法が一般的です。&lt;/p&gt;
&lt;p&gt;項目が少なければ人間の頭の中である程度特徴のあるパターン出しが行えますが、数が多くなると網羅できません。&lt;/p&gt;
&lt;p&gt;パターン抽出には様々な手法があり、論文が発表されています。&lt;br /&gt;
&lt;a href=&quot;http://en.wikipedia.org/wiki/All-pairs_testing&quot;&gt;http://en.wikipedia.org/wiki/All-pairs_testing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;商用プロダクトも数多く出回っています。無料で有名なのはMicrosoftが提供している&lt;a href=&quot;http://msdn.microsoft.com/en-us/testing/bb980925.aspx&quot;&gt;PICT&lt;/a&gt;です。しかし、Windowsのみ。。。。&lt;/p&gt;
&lt;p&gt;ってことで、今回はJavaで書かれたコマンドラインツールと、無料で使えるWebアプリケーションを紹介します。&lt;/p&gt;
&lt;h2&gt;1．mcdowella&apos;s program&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2011/12/Screen-Shot-2011-12-12-at-22.27.09.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/12/Screen-Shot-2011-12-12-at-22.27.09.png&quot; alt=&quot;&quot; title=&quot;all-pair-testing&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;実行結果は以下のようになります。パラメータもいくつか取れます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2011/12/Screen-Shot-2011-12-12-at-23.16.37.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/12/Screen-Shot-2011-12-12-at-23.16.37.png&quot; alt=&quot;&quot; title=&quot;HEXAWISE&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;2．HEXAWISE&lt;/h2&gt;
&lt;p&gt;同じテストデータを食わせてみました。&lt;/p&gt;
&lt;p&gt;どちらもかなり楽に直行表を作れます。&lt;br /&gt;
HEXAWISEの方がオススメです。パターン数に対するカバレッジをグラフ化できます。&lt;/p&gt;
</content:encoded></item><item><title>【Mac】SSH経由でディスクをマウント</title><link>https://blog.teraren.com/posts/mac-sshfs/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-sshfs/</guid><description>MacでSSHFS+Macfusionを使いリモートサーバのディスクをローカルのようにマウントする方法。Xcode・FUSE・homebrew・sshfsのインストール手順を丁寧に解説。</description><pubDate>Sun, 20 Nov 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;SSHで接続できるホストのディスクをmacでローカルディスクのように扱える方法を紹介します。&lt;br /&gt;
&lt;a href=&quot;https://teraren.com/&quot;&gt;テラレン！&lt;/a&gt;のような1TBのレンタルサーバを申し込んでおくと、外出先でもNASをマウントして使っているように利用できます。&lt;/p&gt;
&lt;p&gt;手順の概要はこちら。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Xcodeのインストール&lt;/li&gt;
&lt;li&gt;FUSE for OS X&lt;/li&gt;
&lt;li&gt;homebrewのインストール&lt;/li&gt;
&lt;li&gt;sshfsのインストール&lt;/li&gt;
&lt;li&gt;Macfusionのインストールと設定&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;1. Xcodeのインストール&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://itunes.apple.com/jp/app/xcode/id448457090?mt=12&quot;&gt;こちらのURL&lt;/a&gt;からXcodeをインストールしてください。glibcなどmacで便利なアプリケーションを使うときには必要になるアプリケーションなので入れておきましょう。&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-1.28.43.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-1.28.43.png&quot; alt=&quot;&quot; title=&quot;Screen Shot 2011-11-20 at 1.28.43&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;2. FUSE for Xのインストール&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/osxfuse/osxfuse/downloads&quot;&gt;こちら&lt;/a&gt;から最新をダウンロードしてインストールしてください。&lt;br /&gt;
これはkernelモジュールなので、念のため再起動した方が良いです。&lt;/p&gt;
&lt;h2&gt;3. homebrewのインストール&lt;/h2&gt;
&lt;p&gt;mac向けのアプリケーション管理用ソフトウェアです。&lt;br /&gt;
ターミナルを立ち上げて、以下のコマンドをコピー＆ペーストして、Enterキーを押すだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/usr/bin/ruby -e &quot;$(curl -fsSL https://raw.github.com/gist/323731)&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;4. sshfsのインストール&lt;/h2&gt;
&lt;p&gt;brewを利用してsshfsをインストールします。&lt;br /&gt;
以下のコマンドをターミナルにコピペしてEnterキーを押すだけです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;brew install sshfs
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;5. Macfusionのインストールと設定&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://macfusionapp.org/&quot;&gt;macfusion&lt;/a&gt;をダウンロードして、アプリケーションフォルダに移動してインストールしてください。&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2011/11/Macfusion.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/11/Macfusion.png&quot; alt=&quot;&quot; title=&quot;Macfusion&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Macfusionを立ち上げて、左下のプラスボタンを押します。&lt;br /&gt;
以下のような設定ダイアログが表示されるので、接続先の情報を入力します。一番右のタブのMacfusionに自分のMacのどこへマウントするかを入力しておきます。何も入力しない状態ですと、/Volumes以下にマウントされてしまって、Finderから見られなくなってしまって少し不便になってしまうからです。&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-1.42.48.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-1.42.48.png&quot; alt=&quot;&quot; title=&quot;macfusion&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-1.54.54.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-1.54.54.png&quot; alt=&quot;&quot; title=&quot;macfusion&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;そして、メインウィンドウに表示されている項目の「Mount」ボタンを押すと&lt;br /&gt;
そうすると、ホームディレクトリにteraren.comという名前でリモートのファイルシステムがマウントされます。&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-1.50.09.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-1.50.09.png&quot; alt=&quot;&quot; title=&quot;mount&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2011/11/1.-Shell.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/11/1.-Shell.png&quot; alt=&quot;&quot; title=&quot;1. Shell&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;dfコマンドで1TBのファイルシステムがマウントされていることを確認すると、1TBのリモートにあるファイルシステムがマウントできていることが分かります！&lt;/p&gt;
</content:encoded></item><item><title>Mac OS Xでファイルを転送する方法</title><link>https://blog.teraren.com/posts/mac-cyber-duc/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-cyber-duc/</guid><description>Mac OS Xでファイルを転送する方法</description><pubDate>Sat, 19 Nov 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Macの利用者向けのドキュメントです&lt;/li&gt;
&lt;li&gt;あらかじめ&lt;a href=&quot;http://cyberduck.ch/&quot;&gt;Cyberduck&lt;/a&gt;をインストールしておい てください&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://cyberduck.ch/&quot;&gt;Cyberduck&lt;/a&gt;はFTPやSSH経由でファイルをアップ ロード、ダウンロードできるアプリケーションです&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;起動する&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-2.41.47.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-2.41.47.png&quot; alt=&quot;&quot; title=&quot;cyberduck&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;サーバへ接続&lt;/h2&gt;
&lt;p&gt;以下は、&lt;a href=&quot;https://teraren.com/&quot;&gt;テラレン！&lt;/a&gt;の例です。 接続に必要な事項を入力します。 &lt;a href=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-2.42.30.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-2.42.30.png&quot; alt=&quot;&quot; title=&quot;cyberduck server&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;ファイルの転送&lt;/h2&gt;
&lt;p&gt;転送したいファイルをCyberduckのウィンドウへドラッグアンドドロップするとファイルがリモートへ転送されます。 &lt;a href=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-3.09.01.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/11/Screen-Shot-2011-11-20-at-3.09.01.png&quot; alt=&quot;&quot; title=&quot;cyberduck&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>vim compile</title><link>https://blog.teraren.com/posts/vim-compile/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vim-compile/</guid><description>vim compile</description><pubDate>Thu, 20 Oct 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;vim 7.3が2011年8月にリリースされていたので、ソースからコンパイルし直してみましたが以下のエラーが発生。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ hg clone https://vim.googlecode.com/hg/ vim
$ cd vim/src
$ ./configure --enable-multibyte --enable-xim --enable-fontset --disable-selinux --with-features=huge
$ make
.......
checking for tgetent()... configure: error: NOT FOUND!
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Debianは以下で解決。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# aptitude install libncurses5-dev
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>linuxコンソールのバイナリエディタ</title><link>https://blog.teraren.com/posts/linux-console-binary-editor/</link><guid isPermaLink="true">https://blog.teraren.com/posts/linux-console-binary-editor/</guid><description>linuxコンソールのバイナリエディタ</description><pubDate>Wed, 19 Oct 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;コンソールのバイナリエディタ。&lt;br /&gt;
かなり軽量で便利。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# aptitude install bvi -y
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Nexus S テザリング</title><link>https://blog.teraren.com/posts/nexus-s-tethering-2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nexus-s-tethering-2/</guid><description>Nexus S テザリング</description><pubDate>Tue, 04 Oct 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/10/5246590684_7ee0809ffa_b.jpg&quot; alt=&quot;&quot; title=&quot;nexus s&quot; /&gt; DoCoMoでSIMフリー端末を使うときの料金プランをまとめておきます。 私は後者の速くて高いopen.mopera.netを使っています。&lt;/p&gt;
&lt;h2&gt;契約タイプ&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;基本プラン + パケホ + APN:mpr.ex-pkt.net
&lt;ul&gt;
&lt;li&gt;全体の特徴: 下り128kbps, フィルタリング有り&lt;/li&gt;
&lt;li&gt;パケホ上限: 5985円&lt;/li&gt;
&lt;li&gt;プラン総額: 基本プラン料+プロパイダ料+5985円&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;基本プラン + パケホ + APN:open.mopera.net
&lt;ul&gt;
&lt;li&gt;全体の特徴: 下り7.2Mbps, フィルタリング無し&lt;/li&gt;
&lt;li&gt;パケホ上限: 10395円&lt;/li&gt;
&lt;li&gt;プラン総額: 基本プラン料+プロパイダ料+10395円&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;プロパイダ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;mopera U スタンダード
&lt;ul&gt;
&lt;li&gt;月額: 525円&lt;/li&gt;
&lt;li&gt;特徴: メールアドレスが付与される&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;mopera U ライト
&lt;ul&gt;
&lt;li&gt;月額: 315円&lt;/li&gt;
&lt;li&gt;特徴: 特になし&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>[PHP]変数vs文字列</title><link>https://blog.teraren.com/posts/php-variable-vs-static/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-variable-vs-static/</guid><description>PHPでdefineによる定数と文字列直書きのパフォーマンスを100万回実行して比較した結果、約2割程度の差しかなかった検証記録</description><pubDate>Wed, 21 Sep 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;文字列を共通化するために、変数で定義する方法と文字を直接書く方法どちらが速いか検証してみたら、ほぼ同じだった。&lt;br /&gt;
どっちもどっち。&lt;/p&gt;
&lt;p&gt;define.php&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
define(&apos;word&apos;, &apos;hogehoge&apos;);

$start = microtime(true);
for ($i=0;$i&amp;lt;1000000;$i++) {
?&amp;gt;
&amp;lt;?php print word; ?&amp;gt;
&amp;lt;?php
}

print &quot;\n\n&quot;;
print microtime(true) - $start;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;static.php&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php

$start = microtime(true);
for ($i=0;$i&amp;lt;1000000;$i++) {
?&amp;gt;
hogehoge
&amp;lt;?php
}

print &quot;\n\n&quot;;
print microtime(true) - $start;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;100万回実行した結果、2割程度しか差が無かった。&lt;br /&gt;
define.php: 1.9965279102325&lt;br /&gt;
static.php: 1.7039070129395&lt;/p&gt;
</content:encoded></item><item><title>Webアプリケーションでのパスワード保存方法</title><link>https://blog.teraren.com/posts/key-streatching/</link><guid isPermaLink="true">https://blog.teraren.com/posts/key-streatching/</guid><description>Webアプリケーションでのパスワード保存方法</description><pubDate>Mon, 12 Sep 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;{/* textlint-disable ja-technical-writing/no-doubled-joshi &lt;em&gt;/}
&lt;img src=&quot;../../assets/uploads/2011/09/e02f03aea85580315575e82bd608d86e.png&quot; alt=&quot;&quot; title=&quot;rainbow crack&quot; /&gt; 自分的メモ。 ネタもと： &lt;a href=&quot;http://www.ustream.tv/recorded/17178653&quot;&gt;http://www.ustream.tv/recorded/17178653&lt;/a&gt; &lt;a href=&quot;http://project-rainbowcrack.com/&quot;&gt;Rainbow Crack&lt;/a&gt;みたいなツール使うと一方向hashした値はすぐにクラックできちゃうよ。 md5もsha1も同じ。Rainbow Crackの準備は時間かかるけど、これならターゲットの文字を入手したら数秒でクラックできちゃう！やばいね。 Rainbow Crackによるクラックを防ぐためにはパスワードの照合自体を遅くしてあげて対処するのがいい。 &lt;a href=&quot;http://en.wikipedia.org/wiki/Key_stretching&quot;&gt;http://en.wikipedia.org/wiki/Key_stretching&lt;/a&gt; おまけとして、saltも付け加えるとより良い。
{/&lt;/em&gt; textlint-enable ja-technical-writing/no-doubled-joshi */}&lt;/p&gt;
</content:encoded></item><item><title>Xperiaでpalceholder使っちゃだめ</title><link>https://blog.teraren.com/posts/placeholder/</link><guid isPermaLink="true">https://blog.teraren.com/posts/placeholder/</guid><description>Xperiaでpalceholder使っちゃだめ</description><pubDate>Mon, 22 Aug 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/08/231254b6523d20ef0778f6d0d516607b.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;HTML5で便利なplaceholderですが、xperiaの標準ブラウザで挙動が怪しくなります。&lt;br /&gt;
IMEとの相性が良くないみたいです。&lt;/p&gt;
&lt;p&gt;↓サンプル&lt;/p&gt;
&lt;p&gt;↓コード&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;input type=&quot;text&quot; size=&quot;30&quot; placeholder=&quot;コメントを入れてね&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Macで無料スクリーンキャスト</title><link>https://blog.teraren.com/posts/mac-free-screen-capture/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-free-screen-capture/</guid><description>Macで無料スクリーンキャスト</description><pubDate>Sun, 21 Aug 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今日、知人に教えてもらって目から鱗。&lt;br /&gt;
この手のソフトで有名どころは、ScreenFlowだが、なんとMacデフォルトで入っているQuickTimeでスクリーンキャストできちゃいます！！&lt;/p&gt;
&lt;p&gt;操作は簡単で、QuickTimeを立ち上げて、ファイルメニューから新規画面収録を選ぶと録画用のコントロールが表示されます。そして、録画ボタンを押すだけ。&lt;/p&gt;
&lt;p&gt;スクリーン全体も撮れるし、画面の一部も撮れる。&lt;/p&gt;
&lt;p&gt;試しにQuickTimeでスクリーンショットの動画を録画して、iMovieで編集してみました↓&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/watch?v=96Ek5PpHFJw&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=96Ek5PpHFJw&quot;&gt;http://youtu.be/96Ek5PpHFJw&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;追記：2013/12/1&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Mac OS X 10.9 Marvericksでは、この方法が使えなくなりました。
&lt;ul&gt;
&lt;li&gt;QuickTime Pro（2200円ぐらい）を購入する必要が有ります。。。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;追記：2015/12/15&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Mac OS X 10.10から、復活して使えるようになりました！&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>超お手軽ネットワークモニタリングコマンド</title><link>https://blog.teraren.com/posts/ftop-network-monitoring/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ftop-network-monitoring/</guid><description>Linux/macでリアルタイムにホストごとのネットワークトラフィックを可視化するiftopのインストール方法と主要オプションを解説</description><pubDate>Sat, 11 Jun 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;LinuxやUNIXシステムにおいてリソースをモニタリングするためには、topコマンドやiotopを使います。ネットワークのトラフィックはこれらのコマンドではわかりません。kernelの累計トラフィック数などの数値は簡単に表示できますが視覚的に分かりづらいです。そこで紹介するのがiftopです。&lt;/p&gt;
&lt;p&gt;この記事では、インストール方法と代表的なオプションを簡単に紹介します。&lt;/p&gt;
&lt;h2&gt;インストールと起動&lt;/h2&gt;
&lt;p&gt;Debian, Ubuntu&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# aptitude install -y iftop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mac&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# port install iftop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;起動&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# iftop
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;表示オプション&lt;/h2&gt;
&lt;h3&gt;t スイッチ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/06/Skitch-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;トラフィックの表示方式を変えられます。デフォルトだと1ホストに対して送受信それぞれを1行で表示していますが、1行にまとめたりできます。&lt;/p&gt;
&lt;h3&gt;p スイッチ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/06/1.-Shell-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ポート番号に対応したサービス名が表示されます。どんなサービスのトラフィックが多いのかが一目瞭然です。&lt;/p&gt;
&lt;h3&gt;数字スイッチ&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/06/1.-Shell.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;並べ替え方法を選択できます。デフォルトでは1です。&lt;/p&gt;
&lt;p&gt;オプション一覧&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Host display:                          General:
 n - toggle DNS host resolution         P - pause display
 s - toggle show source host            h - toggle this help display
 d - toggle show destination host       b - toggle bar graph display
 t - cycle line display mode            B - cycle bar graph average
                                        T - toggle cummulative line totals
Port display:                           j/k - scroll display
 N - toggle service resolution          f - edit filter code
 S - toggle show source port            l - set screen filter
 D - toggle show destination port       L - lin/log scales
 p - toggle port display                ! - shell command
                                        q - quit
Sorting:
 1/2/3 - sort by 1st/2nd/3rd column
 &amp;lt; - sort by source name
 &amp;gt; - sort by dest name
 o - freeze current order
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
</content:encoded></item><item><title>コマンドラインで合計、平均などの集計処理　</title><link>https://blog.teraren.com/posts/awk-sum-average/</link><guid isPermaLink="true">https://blog.teraren.com/posts/awk-sum-average/</guid><description>awkコマンドを使ってコマンドラインでデータの合計・平均・最大値などを集計する方法。Apacheアクセスログの平均レスポンスサイズ計算など実用例も紹介。</description><pubDate>Tue, 07 Jun 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;コマンドラインで簡単に数字を集約する方法。&lt;br /&gt;
SQLのsum()やaverage()をコマンドラインで行います。&lt;/p&gt;
&lt;h2&gt;平均値を求めてみる&lt;/h2&gt;
&lt;p&gt;数字の羅列。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat sample.txt
1000
34
1
124312
31234
1234
2314
1234
1234
23.33
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;平均値を求める。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat sample.txt | awk  &apos;BEGIN {total=0} {total += $1} END {print total/NR}&apos;
16262
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;平均コンテンツ容量&lt;/h2&gt;
&lt;p&gt;Apacheがレスポンスしている平均ページ容量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ grep &apos; 200 &apos; access.log | awk  &apos;BEGIN {total=0} {total += $10} END {print total/NR}&apos; 
15185.5
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;総合コンテンツ量&lt;/h2&gt;
&lt;p&gt;Apacheがレスポンスしたページ容量の合計 (単位：GB)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% grep &apos; 200 &apos; access.log | awk  &apos;BEGIN {total=0} {total += $10} END {print total/1000000000}&apos; 
1.40969
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Debian 複数 IPアドレス</title><link>https://blog.teraren.com/posts/debian-ip-alias/</link><guid isPermaLink="true">https://blog.teraren.com/posts/debian-ip-alias/</guid><description>Debian 5でeth0:0のIPエイリアスを使い、1枚のNICに複数のIPアドレスを/etc/network/interfacesで静的割り当てする設定例</description><pubDate>Mon, 06 Jun 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Debian 5.0.7 にて1枚のNICに複数のIPアドレスを割り当てるメモ&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@dev2 /etc/network]# cat /etc/network/interfaces
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug eth0

auto eth0
iface eth0 inet static
  address  192.168.0.41
  network  192.168.0.0
  netmask  255.255.255.0
  broadcast 192.168.0.255
  gateway  192.168.0.1
  dns-nameservers 192.168.0.1

auto eth0:0
iface eth0:0 inet static
  address  192.168.0.42
  network  192.168.0.0
  netmask  255.255.255.0
  broadcast 192.168.0.255
  gateway  192.168.0.1
  dns-nameservers 192.168.0.1
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>tig = gitをaptitudeのように使えるラッパー</title><link>https://blog.teraren.com/posts/tig-git/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tig-git/</guid><description>Gitの操作をVimライクなTUIで行えるtigのインストール方法と基本操作を紹介。ログ閲覧・cherry-pickなどをキー操作で素早く実行できる使い方を解説</description><pubDate>Mon, 06 Jun 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;tig概要&lt;/h2&gt;
&lt;p&gt;gitのCLIラッパー。&lt;br /&gt;
gitコマンドをdpkgだとすると、tigはaptitudeというかんじ。&lt;br /&gt;
コマンド名の覚え方は、gitを逆から読む。&lt;/p&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;p&gt;mac&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# port install tig
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;debian&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# aptitude install -y tig
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;使い方&lt;/h2&gt;
&lt;p&gt;gitレポジトリ内でtigコマンドを打つ。&lt;/p&gt;
&lt;p&gt;基本的にはvimと同じような操作感で扱える。かなり豊富なコマンドがあるので一歩一歩覚えていくのが良いと思う。&lt;/p&gt;
&lt;p&gt;まず、覚えなきゃいけないのは「h」これでヘルプが出せるので、適宜調べていく。&lt;/p&gt;
&lt;p&gt;以下にヘルプページを掲載する。特筆すべきは一番下の方にある、gitコマンドを直接呼び出せる便利なコマンド。&lt;br /&gt;
たとえば、「C」を打つだけでcherry-pickできる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[-] generic bindings
View switching                                                                                                                                                           
    &apos;m&apos;                       view-main            Show main view                                                                                                        
    &apos;d&apos;                       view-diff            Show diff view                                                                                                        
    &apos;l&apos;                       view-log             Show log view                                                                                                         
    &apos;t&apos;                       view-tree            Show tree view                                                                                                        
    &apos;f&apos;                       view-blob            Show blob view                                                                                                        
    &apos;B&apos;                       view-blame           Show blame view                                                                                                       
    &apos;H&apos;                       view-branch          Show branch view                                                                                                      
    &apos;h&apos;                       view-help            Show help page                                                                                                        
    &apos;p&apos;                       view-pager           Show pager view                                                                                                       
    &apos;S&apos;                       view-status          Show status view                                                                                                      
    &apos;c&apos;                       view-stage           Show stage view                                                                                                       
View manipulation                                                                                                                                                        
    Enter                     enter                Enter current line and scroll                                                                                         
    Down, &apos;^N&apos;                next                 Move to next                                                                                                          
    Up, &apos;^P&apos;                  previous             Move to previous                                                                                                      
    &apos;,&apos;                       parent               Move to parent                                                                                                        
    Tab                       view-next            Move focus to next view                                                                                               
    &apos;R&apos;, F5                   refresh              Reload and refresh                                                                                                    
    &apos;O&apos;                       maximize             Maximize the current view                                                                                             
    &apos;q&apos;                       view-close           Close the current view                                                                                                
    &apos;Q&apos;                       quit                 Close all views and quit                                                                                              
View specific requests                                                                                                                                                   
    &apos;u&apos;                       status-update        Update file status                                                                                                    
    &apos;!&apos;                       status-revert        Revert file changes                                                                                                   
    &apos;M&apos;                       status-merge         Merge file using external tool                                                                                        
    &apos;@&apos;                       stage-next           Find next chunk to stage                                                                                              
Cursor navigation                                                                                                                                                        
    &apos;k&apos;                       move-up              Move cursor one line up                                                                                               
    &apos;j&apos;                       move-down            Move cursor one line down                                                                                             
    PageDown, &apos;^D&apos;, Space     move-page-down       Move cursor one page down                                                                                             
    PageUp, &apos;^U&apos;, &apos;b&apos;, &apos;-&apos;    move-page-up         Move cursor one page up                                                                                               
    Home                      move-first-line      Move cursor to first line                                                                                             
    End                       move-last-line       Move cursor to last line                                                                                              
Scrolling                                                                                                                                                                
    &apos;|&apos;                       scroll-first-col     Scroll to the first line columns                                                                                      
    Left                      scroll-left          Scroll two columns left                                                                                               
    Right                     scroll-right         Scroll two columns right                                                                                              
    Insert, &apos;^Y&apos;              scroll-line-up       Scroll one line up                                                                                                    
    Delete, &apos;^E&apos;              scroll-line-down     Scroll one line down                                                                                                  
    &apos;w&apos;                       scroll-page-up       Scroll one page up                                                                                                    
    &apos;s&apos;                       scroll-page-down     Scroll one page down                                                                                                  
Searching                                                                                                                                                                
    &apos;/&apos;                       search               Search the view                                                                                                       
    &apos;?&apos;                       search-back          Search backwards in the view                                                                                          
    &apos;n&apos;                       find-next            Find next search match                                                                                                
    &apos;N&apos;                       find-prev            Find previous search match                                                                                            
Option manipulation                                                                                                                                                      
    &apos;o&apos;                       options              Open option menu                                                                                                      
    &apos;.&apos;                       toggle-lineno        Toggle line numbers                                                                                                   
    &apos;D&apos;                       toggle-date          Toggle date display                                                                                                   
    &apos;A&apos;                       toggle-author        Toggle author display                                                                                                 
    &apos;g&apos;                       toggle-rev-graph     Toggle revision graph visualization                                                                                   
    &apos;~&apos;                       toggle-graphic       Toggle (line) graphics mode                                                                                           
    &apos;F&apos;                       toggle-refs          Toggle reference display (tags/branches)                                                                              
    &apos;I&apos;                       toggle-sort-order    Toggle ascending/descending sort order                                                                                
    &apos;i&apos;                       toggle-sort-field    Toggle field to sort by                                                                                               
Misc                                                                                                                                                                     
    &apos;:&apos;                       prompt               Bring up the prompt                                                                                                   
    &apos;r&apos;, &apos;^L&apos;                 screen-redraw        Redraw the screen                                                                                                     
    &apos;v&apos;                       show-version         Show version information                                                                                              
    &apos;z&apos;                       stop-loading         Stop all loading views                                                                                                
    &apos;e&apos;                       edit                 Open in editor                                                                                                        
External commands:                                                                                                                                                       
    &apos;G&apos;                       `git gc`                                                                                                                                   
[-] main bindings                                                                                                                                                        
External commands:                                                                                                                                                       
    &apos;C&apos;                       `git cherry-pick %(commit)`                                                                                                                
[-] branch bindings                                                                                                                                                      
External commands:                                                                                                                                                       
    &apos;C&apos;                       `git checkout %(branch)`                                                                                                                   
[-] status bindings                                                                                                                                                      
External commands:                                                                                                                                                       
    &apos;C&apos;                       `git commit`
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Ruby on Rails 3 アプリケーションプログラミング 書評</title><link>https://blog.teraren.com/posts/ruby-on-rails3/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ruby-on-rails3/</guid><description>「Ruby on Rails 3 アプリケーションプログラミング」書評。MVC・ORM・テスト・国際化まで網羅した内容の濃さを高評価。Ruby初心者がRoRアプリを正しく構築できる知識を体系的に習得できる一冊。</description><pubDate>Sun, 05 Jun 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;::amazon{asin=&quot;4774146633&quot;}&lt;/p&gt;
&lt;h2&gt;対象読者&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ruby初心者だけど、Ruby on Railsのモデルやプラクティスを理解したい方。&lt;/li&gt;
&lt;li&gt;Ruby on Railsでアプリケーション構築をしたことがないけど、趣味や業務でRoRアプリケーション構築をしようとしている人&lt;/li&gt;
&lt;li&gt;RoR3の新機能やRoRの方向性をキャッチアップしたい方&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;感想&lt;/h2&gt;
&lt;p&gt;かなり内容が濃い本になっています。&lt;br /&gt;
上記の対象読者に当たる方なら手元にあった方が良いでしょう。&lt;/p&gt;
&lt;p&gt;この本を読むと、Ruby初心者が小・中規模のアプリケーションを正しく構築できる知識を得られます。&lt;/p&gt;
&lt;p&gt;Webアプリケーションを作る上でのMVC、ORM、Activity Record、XSSなどの基礎概念についてもしっかりと、そしてわかりやすい解説がなされていて初心者にとっても満足できる内容でした。&lt;/p&gt;
&lt;p&gt;文字と図版のバランスが良く、飽きずにどんどん読み進めていけます。私は技術書は基本的にかいつまんで読むのですが、この本は内容が濃いので全部通して読んでしまいました。&lt;/p&gt;
&lt;p&gt;ユニットテストや国際化対応についての実装例も書かれていて、昨今のWebアプリケーションに求められる機能についてしっかりと網羅しています。&lt;/p&gt;
&lt;h2&gt;価格について&lt;/h2&gt;
&lt;p&gt;読む前は、値段がちょっと高いと思いましたが、読み終わったときにはこの内容でこの値段は&lt;strong&gt;安すぎる&lt;/strong&gt;と思いました。&lt;/p&gt;
&lt;p&gt;細かいところまでよく説明を書いてくれていて、分からない単語をWebで調べたりすることなくスムーズに読み進められます。&lt;/p&gt;
&lt;h2&gt;目次&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;第1章　イントロダクション&lt;br /&gt;
第2章　Ruby on Railsの基本&lt;br /&gt;
第3章　Scaffolding機能によるRails開発の基礎&lt;br /&gt;
第4章　ビュー開発&lt;br /&gt;
第5章　モデル開発&lt;br /&gt;
第6章　コントローラ開発&lt;br /&gt;
第7章　ルーティング&lt;br /&gt;
第8章　テスト&lt;br /&gt;
第9章　Railsの高度な機能&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;作者について&lt;/h2&gt;
&lt;p&gt;Windows、Linux、データベース、各種プログラミング言語に精通した&lt;a href=&quot;http://codezine.jp/author/33&quot;&gt;山田さん&lt;/a&gt;の書かれた本なので要点がとても綺麗に整理されています。&lt;br /&gt;
Codezineの記事を見てみると、知識の深さと広さが理解できると思います。&lt;/p&gt;
&lt;h2&gt;謝辞&lt;/h2&gt;
&lt;p&gt;このたびは献本して頂きありがとうございます。&lt;br /&gt;
勉強会や授業などで教科書として紹介します。&lt;/p&gt;
</content:encoded></item><item><title>Mac Ports</title><link>https://blog.teraren.com/posts/mac-ports/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-ports/</guid><description>MacPortsの日常的なアップデートコマンドと古いパッケージ削除方法、さらにRuby 1.9とRails 3.xをインストールする手順をまとめたメモ</description><pubDate>Sun, 08 May 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;常用&lt;/h2&gt;
&lt;p&gt;最新のレポジトリを取得&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# port selfupdate
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;古いパッケージのアップグレード&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# port -u upgrade outdated
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;メンテナンス&lt;/h2&gt;
&lt;p&gt;port upgrade outdatedしただけだと、古いパッケージが削除されずに残ってしまうので以下のコマンドで古いパッケージを消す。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# port uninstall inactive
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;おまけ&lt;/h2&gt;
&lt;p&gt;ruby1.9 + rails3.xをインストールする方法。&lt;br /&gt;
結構はまった。2時間ぐらい。gem周りが結構大変だった。&lt;br /&gt;
普通にruby19をインストールすると、rubyコマンドはruby1.8になるのでrubyコマンドが1.9になるようにする。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# port install ruby19 +nosuffix
# gem pristine --all --no-extensions
# gem update --system
# gem install sqlite3
# gem install rails
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>MacでEvernoteにテキストファイルを一括インポート</title><link>https://blog.teraren.com/posts/mac-evernote-import/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-evernote-import/</guid><description>AppleScriptを使ってMacのテキストファイルをEvernoteへ一括移行する手順。ノートブック名やファイル作成日を維持しつつ、Shift-JISファイルのUTF-8変換方法も解説。</description><pubDate>Sun, 17 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;Windowsでは、紙とDropboxでテキストファイルを管理していましたが、Evernoteにこれらのテキストファイルを移行する方法を掲載します。&lt;/p&gt;
&lt;h2&gt;移行方法&lt;/h2&gt;
&lt;p&gt;以下のスクリプトを「アップルスクリプトエディタ」にペーストします。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/2543898&quot;&gt;https://gist.github.com/2543898&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/04/bike.scpt_.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;実行ボタンを押します。そうすると、どこのフォルダからファイルをインポートするかを聞かれるのでファイルが保管されたフォルダを指定してください。&lt;/p&gt;
&lt;h2&gt;仕様&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;ファイル作成日は維持されます&lt;/li&gt;
&lt;li&gt;ノートブック名はディレクトリ名と同じです&lt;/li&gt;
&lt;li&gt;ノート名タイトルはファイル名と同じです&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;注意&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;テキストファイルのインポートは有料アカウントが必要です。&lt;/li&gt;
&lt;li&gt;テキストファイルはUTF-8のみ対応。もし、Shift-JISで保存されていたらEvernoteに取り込んだ時に、「あるノートの添付ファイル」として扱われてしまいます。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# 全部UTF-8にするコマンド
% nkf -w --overwrite **/*.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ソースはこちら。&lt;br /&gt;
&lt;a href=&quot;http://veritrope.com/code/date-sensitive-file-importer/&quot;&gt;http://veritrope.com/code/date-sensitive-file-importer/&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Nexus Sテザリング</title><link>https://blog.teraren.com/posts/nexus-s-tethering/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nexus-s-tethering/</guid><description>Nexus Sテザリング</description><pubDate>Sat, 16 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/03/86df8db052407f04753e0e80a2b068dc.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/03/86df8db052407f04753e0e80a2b068dc.png&quot; alt=&quot;&quot; title=&quot;speed test&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;DoCoMo回線でテザリングしたときのベンチマーク。2.07Mbps。普通にWebブラウジングやメールではストレス無し。&lt;/p&gt;
&lt;p&gt;海外から輸入したNexus SはAndroid 2.3.3を搭載して、SIMフリー。DoCoMo回線でテザリングもできちゃう。本体価格は高いけど、テザリングができるからわざわざe-mobileとかに加入しなくてもいいので、ランニングコストがかなり安くなるのですぐにペイしちゃう！&lt;/p&gt;
&lt;p&gt;動作クロックも速いし、使っていてストレスは全然無い。&lt;/p&gt;
&lt;p&gt;買うなら、アマゾンが一番安いみたいです。私はアマゾンで買いました−！&lt;/p&gt;
&lt;p&gt;2011/5/7 追記 すごい安くなってるー。63,390円で買ったのに・・・&lt;/p&gt;
</content:encoded></item><item><title>rawler - 再帰リンクチェッカー</title><link>https://blog.teraren.com/posts/recursive-link-checker/</link><guid isPermaLink="true">https://blog.teraren.com/posts/recursive-link-checker/</guid><description>rawler - 再帰リンクチェッカー</description><pubDate>Tue, 12 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/oscardelben/rawler&quot;&gt;rawler&lt;/a&gt;&lt;br /&gt;
ruby製の再帰リンクチェッカー。&lt;br /&gt;
お手軽だけど精度高くて良い。シングルスレッドなので遅い。&lt;/p&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;gem install rawler
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;実行&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;~/.gem/ruby/1.8/bin/rawler  --wait=0  https://blog.teraren.com/
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>GNU screenのウィンドウタイトル変更</title><link>https://blog.teraren.com/posts/gnu-screen-window-title-change/</link><guid isPermaLink="true">https://blog.teraren.com/posts/gnu-screen-window-title-change/</guid><description>GNU screenのウィンドウタイトル変更</description><pubDate>Tue, 05 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;screenでウィンドウタイトル（セッション名）を変更する方法を紹介します。screenのエスケープキーはCtrl + a と仮定します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Ctrl + a
Ctrl + A
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;emacsキーバインドで変更できます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/04/1.-Shell-1.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ちなみに、[Ctrl + a] [:sessionname hogehoge]で変更するのは、screenのセッション名であって、タイトルではありません。&lt;/p&gt;
</content:encoded></item><item><title>WordPressを5分で5倍速くするQuick Cacheの設定</title><link>https://blog.teraren.com/posts/quick-cache/</link><guid isPermaLink="true">https://blog.teraren.com/posts/quick-cache/</guid><description>WP Super Cacheに代わるWordPressキャッシュプラグイン「Quick Cache」の導入手順と設定方法。5分の作業でリクエスト処理速度が4.5倍に向上したベンチマーク結果も紹介。</description><pubDate>Sun, 03 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;WP Super Cacheに置き換わる最近の主流キャッシュプラグインを紹介します！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://wordpress.org/extend/plugins/quick-cache/stats/&quot;&gt;Quick Cache ( A WP Super Cache Alternative )&lt;/a&gt;&lt;br /&gt;
訳：サイト高速化プラグイン。WordPressサイトを高速化したいなら、必ずインストールすべき！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;インストールと設定&lt;/h2&gt;
&lt;p&gt;動画でもご覧いただけます。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/04/01.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/04/02.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/04/03.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/04/04.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/04/05.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/04/06.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/04/100b2be016851667ef84dba117974db4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;w3c_validator
DoCoMo
SoftBank
WILLCOM
mixi-mobile-converter
UP.Browser
Playstation
PDA
iPhone
iPad
Android
BlackBerry&lt;/p&gt;
&lt;p&gt;※本来ならMD5 Version Saltでキャッシュキーを振り分ければいいのですが、挙動が安定していないので携帯、スマフォでアクセスされたときにはキャッシュを無効にします。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/04/07.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;検証&lt;/h2&gt;
&lt;p&gt;ベンチマークの測定方法。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ab -n 1000 -c 10 https://blog.teraren.com/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;測定環境は、IEEE802.11nのLANです。たった5分で4.5倍の高速化をできればすごいコストパフォーマンス高いですよー。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://b.hatena.ne.jp/entry//posts/quick-cache/&quot;&gt;&lt;img src=&quot;https://b.st-hatena.com/images/entry-button/button-only.gif&quot; alt=&quot;このエントリーをはてなブックマークに追加&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;はてブお願いします！&lt;/p&gt;
</content:encoded></item><item><title>REPLACE INTOとINSERT ON DUPLICATE KEY UPDATEの違い</title><link>https://blog.teraren.com/posts/replace-into-insert-on-duplicate-key-update/</link><guid isPermaLink="true">https://blog.teraren.com/posts/replace-into-insert-on-duplicate-key-update/</guid><description>MySQLのREPLACE INTOとINSERT ... ON DUPLICATE KEY UPDATEはどう違うのか、実際のSQL実行例でAUTO_INCREMENTの挙動の違いなどを詳しく比較・検証します。</description><pubDate>Fri, 01 Apr 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h3&gt;概要&lt;/h3&gt;
&lt;p&gt;MySQLの独自拡張であるREPLACE INTOとINSERT ... ON DUPLICATE KEY UPDATEが似ている挙動しているので実験してみた。on MySQL 5.1&lt;/p&gt;
&lt;h3&gt;参考資料&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/ja/replace.html&quot;&gt;12.2.6. REPLACE 構文&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/ja/insert-on-duplicate.html&quot;&gt;12.2.4.3. INSERT ... ON DUPLICATE KEY UPDATE 構文&lt;br /&gt;
&lt;/a&gt;&lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/ja/insert.html&quot;&gt;INSERT IGNORE&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://d.hatena.ne.jp/IT7C/20100715/1279148768&quot;&gt;http://d.hatena.ne.jp/IT7C/20100715/1279148768&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;実行例&lt;/h3&gt;
&lt;p&gt;テーブル作成＆初期データ投入&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; CREATE TABLE IF NOT EXISTS `color` (
    -&amp;gt;   `id` int(11) NOT NULL AUTO_INCREMENT,
    -&amp;gt;   `value` varchar(255) NOT NULL,
    -&amp;gt;   PRIMARY KEY (`id`),
    -&amp;gt;   UNIQUE KEY `value` (`value`)
    -&amp;gt; ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Query OK, 0 rows affected (0.06 sec)

mysql&amp;gt; INSERT INTO `color` (`id`, `value`) VALUES
    -&amp;gt; (1, &apos;FF0000&apos;),
    -&amp;gt; (2, &apos;00FF00&apos;);
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql&amp;gt; select * from color;
+----+--------+
| id | value  |
+----+--------+
|  1 | FF0000 |
|  2 | 00FF00 |
+----+--------+
2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;insert intoで更新。行は追加されない。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; INSERT INTO `color` (`value`) VALUES (&apos;FF0000&apos;)
    -&amp;gt; on duplicate key update value=&apos;FF0000&apos;;
Query OK, 0 rows affected (0.00 sec)

mysql&amp;gt; select * from color;
+----+--------+
| id | value  |
+----+--------+
|  1 | FF0000 |
|  2 | 00FF00 |
+----+--------+
2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;replace intoで更新。キー指定されているカラムが重複すると行が追加される。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; replace into color (value) values(&apos;FF0000&apos;);
Query OK, 2 rows affected (0.00 sec)

mysql&amp;gt; select * from color;
+----+--------+
| id | value  |
+----+--------+
|  3 | FF0000 |
|  2 | 00FF00 |
+----+--------+
2 rows in set (0.00 sec)

mysql&amp;gt; replace into color (value) values(&apos;FF0000&apos;);
Query OK, 2 rows affected (0.00 sec)

mysql&amp;gt; select * from color;
+----+--------+
| id | value  |
+----+--------+
|  4 | FF0000 |
|  2 | 00FF00 |
+----+--------+
2 rows in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;まとめ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;既に重複するカラムのレコードがあった場合の挙動が違う&lt;/li&gt;
&lt;li&gt;insert ... on duplicate key: 行がupdateされる&lt;/li&gt;
&lt;li&gt;replace into ... : 行がdeleteされて、insertされる&lt;/li&gt;
&lt;li&gt;マスタデータの更新にこれらの構文が使ったら便利な構文みたい。&lt;/li&gt;
&lt;li&gt;振る舞いが違うから、設計方針に合った構文を使うこと。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Android版 FirefoxのUser-Agent</title><link>https://blog.teraren.com/posts/android-firefox/</link><guid isPermaLink="true">https://blog.teraren.com/posts/android-firefox/</guid><description>Android版 FirefoxのUser-Agent</description><pubDate>Thu, 31 Mar 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Firefox for Android&lt;/h2&gt;
&lt;p&gt;ついにリリースされましたね。&lt;br /&gt;
いつもFirefoxの新しいバージョンはプラグインの対応が追いついていないのでインストールしたくないのですが、 &lt;a href=&quot;http://mozilla.jp/firefox/mobile/sync/&quot;&gt;Firefox Sync&lt;/a&gt;が便利なのでインストールしちゃいました。&lt;/p&gt;
&lt;h2&gt;雑感&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;パスワード、開いているタブを同期してくれるのはかなり楽。
{/* textlint-disable ja-technical-writing/ja-no-successive-word */}&lt;/li&gt;
&lt;li&gt;相変わらずアニメーション周りの機能はだめだめ。
{/* textlint-enable */}&lt;/li&gt;
&lt;li&gt;超早い！っていうか、最近Chromeが遅くなってきた。&lt;/li&gt;
&lt;li&gt;ChromeとAndroidのブラウザもこのぐらい親和性高ければいいのになぁ。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://mozilla.jp/blog/entry/6541/&quot;&gt;AndroidとFirefoxがすごい便利そうなUXを提供してくれることがわかる動画はこちら。&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;一部のスマートフォン向けWebサイトではじかれる
{/* textlint-disable ja-technical-writing/ja-no-successive-word */}&lt;/li&gt;
&lt;li&gt;CSS3がだめだめ。grandient汚い。roundも。
{/* textlint-enable */}&lt;/li&gt;
&lt;li&gt;グラデーションを劣化させて表示してる&lt;/li&gt;
&lt;li&gt;レンダリングは早い。なんかまだまだ。&lt;/li&gt;
&lt;li&gt;PCとPCで同期はできないみたい。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Android版Firefoxのユーザエージェント&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Mozilla/5.0 (Android; Linux armv7l; rv:2.1) Gecko/20110318 Firefox/4.0b13pre Fennec/4.0
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>スマートフォン用画像チェックプログラム</title><link>https://blog.teraren.com/posts/image-check/</link><guid isPermaLink="true">https://blog.teraren.com/posts/image-check/</guid><description>Android・iPhone・iPadなど異なる解像度のスマートフォン向けに、GIF画像のファイルサイズと色数を様々な書き出し条件で比較検討できるWebアプリを作成。</description><pubDate>Fri, 11 Mar 2011 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;スマートフォン向けWebサイトを構築する際にはAndroid, iPhone3GS, iPhone4, iPad, Android tabletなどの解像度やディスプレイの大きさが異なったデバイスにて最適に表示されなければなりません。&lt;/p&gt;
&lt;p&gt;特に画像は「クオリティVS表示速度」のトレードオフになるのでトップビジュアルなどの大きな画像は綿密な動作確認が必要です。&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;トップビジュアルのクオリティを様々な書き出しオプションにて出力した画像から比較検討するためのプログラム作りました。今のところ、GIF画像のみを想定しています。&lt;/p&gt;
&lt;h2&gt;ダウンロード&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/matsubo/Image-checker-for-smart-phone&quot;&gt;https://github.com/matsubo/Image-checker-for-smart-phone&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;デモ&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://matsu.teraren.com/static/Image-checker-for-smart-phone/&quot;&gt;https://matsu.teraren.com/static/Image-checker-for-smart-phone/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;スクリーンショット&lt;/h2&gt;
&lt;h3&gt;横幅ごとに一覧ページが作成され、色数ごとに画像が出力されます&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/03/5244da7f7a88bd273fa20796e6664732.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;各画像の下にある「Detail」ボタンを押すと色数と重さが表示されます&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/03/f776a25cb2719a34a5811de7b02f56dc.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;おまけ：iPadで確認してみたり&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2011/03/9b28dccee065b1565cb4526f10cb952b.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>mac eclipseでタブ切替</title><link>https://blog.teraren.com/posts/mac-eclipse-tab-shortcut/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-eclipse-tab-shortcut/</guid><description>mac eclipseでタブ切替</description><pubDate>Wed, 09 Feb 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2011/02/eclipse-mac-preferences.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/02/eclipse-mac-preferences.png&quot; alt=&quot;&quot; title=&quot;eclipse-mac-preferences&quot; /&gt;&lt;/a&gt; プライベートも仕事環境もすべてMacにしました！体が10年間使ってきたWindowsも離れてみれば、すばらしいUIだったなぁと思っております。（もちろんクラシックテーマ） さて、Eclipseでよく使うタブ切り替えはWindowsではCtrl+Page Down / UPにデフォルトでバインドされていましたが、Macではありません。 だから、自分で定義しましょう。next tab, previous tabのショートカットに割り当てます。自分はWindowsを継承してCommand + Shift + UP / DOWNってかんじです。&lt;/p&gt;
</content:encoded></item><item><title>HTML5のcanvasでランキング描画</title><link>https://blog.teraren.com/posts/html5-canvas/</link><guid isPermaLink="true">https://blog.teraren.com/posts/html5-canvas/</guid><description>HTML5のcanvasでランキング描画</description><pubDate>Sat, 22 Jan 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2011/01/2011-01-22-17h17_28.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2011/01/2011-01-22-17h17_28.png&quot; alt=&quot;&quot; title=&quot;html5-canvas&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Canvasのグラフ描画は楽。SVGよりかなり手軽。HTML5＋CSS＋jQueryでランキングページを作ってみました。&lt;/p&gt;
&lt;p&gt;Canvasの座標系において、最大が横300 縦150なのは仕様なのかなー？CSSでcanvasの大きさを指定しても、描画する座標系はピクセルとは違うみたい。&lt;/p&gt;
</content:encoded></item><item><title>Zend_Mailでマルチバイトメール</title><link>https://blog.teraren.com/posts/zend-mail-multibyte-mail/</link><guid isPermaLink="true">https://blog.teraren.com/posts/zend-mail-multibyte-mail/</guid><description>Zend_Mailでマルチバイトメール</description><pubDate>Thu, 13 Jan 2011 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;まともなコードが掲載されていなかったので、汚いですが掲載。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$mail = new Zend_Mail(&apos;ISO-2022-JP&apos;);
$mail-&amp;gt;setHeaderEncoding(Zend_Mime::ENCODING_BASE64);
$mail-&amp;gt;setFrom(&apos;y_matsukura@example.com&apos;, mb_convert_encoding(&apos;ふろむ&apos;, &apos;ISO-2022-JP&apos;, &apos;UTF-8&apos;));
$mail-&amp;gt;addTo(&apos;y_matsukura@example.com&apos;, mb_convert_encoding(&apos;とぅ&apos;, &apos;ISO-2022-JP&apos;, &apos;UTF-8&apos;));

$mail-&amp;gt;setSubject(mb_convert_encoding(&apos;化けません&apos;, &apos;ISO-2022-JP&apos;, &apos;UTF-8&apos;));
$mail-&amp;gt;setBodyText(mb_convert_encoding(&apos;日本語&apos;,&apos;ISO-2022-JP&apos;, &apos;UTF-8&apos;), null, Zend_Mime::ENCODING_7BIT);
$mail-&amp;gt;send();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;参照：&lt;br /&gt;
&lt;a href=&quot;http://framework.zend.com/manual/ja/zend.mail.character-sets.html&quot;&gt;http://framework.zend.com/manual/ja/zend.mail.character-sets.html&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>ServerMan@DTIにやられたこと</title><link>https://blog.teraren.com/posts/serversman/</link><guid isPermaLink="true">https://blog.teraren.com/posts/serversman/</guid><description>ServerMan@DTIのメンテナンスでSSHポート変更だけでなくapache・ajaxterm等が無断インストールされ、対象外のサーバにも10時間超のダウンタイムが発生した障害報告。</description><pubDate>Thu, 30 Dec 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;29日は、SSHのポートがデフォルトの22になっているホストに対して、サーバ運営者が強制的に別のポートに設定する日であった。&lt;br /&gt;
しかし、実際にはSSHのポート変更だけではなく、ajaxtermやapache、mod_sslなどのパッケージを強制的にインストールしていることが分かった。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/12/Munin-__-school2.jp-__-sv4.school2.jp_.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;メンテナンス対象ではない自サーバに対しても約10.5時間のダウンタイムがあった。&lt;/p&gt;
&lt;p&gt;Debianを使っている場合の状況を以下にレポートする。&lt;/p&gt;
&lt;h2&gt;インストールされたパッケージ&lt;/h2&gt;
&lt;p&gt;aptのログを確認してみると以下のパッケージが&lt;strong&gt;勝手に&lt;/strong&gt;インストールされていた。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;python2.5
python-minimal
python
openssl-blacklist
python-support
ajaxterm
apache2-utils
apache2.2-common
apace2-mpm-worker
apache2
ssl-cert
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/12/1.-screen-ssh-3.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/12/1.-screen-ssh-2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;プロセス&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/12/1.-screen-ssh-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ajaxtermサービスが走っている。ajaxtermとはWeb上からサーバのコンソールを利用できるようにするサービス。&lt;/p&gt;
&lt;h2&gt;ポート&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/12/1.-screen-ssh.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;赤く印をつけたところが、今回のメンテナンスによって起動されたサービスのポート。&lt;/p&gt;
&lt;h2&gt;対処&lt;/h2&gt;
&lt;p&gt;このホストは、バックアップサーバにしか利用していないので、新しくインストールされたパッケージはすべて削除して元通りにした。&lt;br /&gt;
手順は以下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# aptitude remove python2.5 python--minimal python openssl-blacklist python-support ajaxterm apache2-utils apache2.2-common apace2-mpm-worker apache2 ssl-cert
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>コピペでredmineサーバセットアップ</title><link>https://blog.teraren.com/posts/ruby-for-redmine/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ruby-for-redmine/</guid><description>Debian上でRuby・RubyGems・Passangerをソースからインストールし、SQLite3を使ってRedmineを動かすコピペ対応手順</description><pubDate>Mon, 20 Dec 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;redmineの最新版を動かすためには、&lt;br /&gt;
ruby 1.8.6, 1.8.7 Rails 2.3.5 Rack 1.0.1 rake 0.8.3以上&lt;br /&gt;
が必要です。&lt;/p&gt;
&lt;p&gt;この環境をコピペで作れるようにドキュメントを作りました。&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;きっちりバージョンをあわせないと動かないので、rpmやdpkgのパッケージでは環境をセットアップするのが大変です。&lt;/p&gt;
&lt;p&gt;例えば、debianで提供されているrakeが0.8.1であり、0.8.3を入れるためにはruby 1.9をインストールしなければならない。よって、rubyが1.8,1.9混在させなければならず管理が煩雑になってしまいます。&lt;/p&gt;
&lt;h2&gt;セットアップ&lt;/h2&gt;
&lt;p&gt;ここは、パッケージの利便性を捨ててより細かくセットアップするためにソースからインストール。&lt;/p&gt;
&lt;h3&gt;前提&lt;/h3&gt;
&lt;p&gt;Debian 5.0 stable&lt;br /&gt;
apache 2.2.17&lt;/p&gt;
&lt;h3&gt;sqlite3をインストール&lt;/h3&gt;
&lt;p&gt;ストレージエンジンをsqliteにする場合はインストール。
複雑な問い合わせは無いし、MySQLのメンテナンスを増やしたくないので、中小規模の開発ならsqlite3がおすすめです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ wget http://www.sqlite.org/sqlite-autoconf-3070400.tar.gz
$ unzip sqlite-autoconf-3070400.tar.gz
$ tar zxvf  sqlite-autoconf-3070400.tar.gz
$ cd sqlite-autoconf-3070400
$ ./configure
$ make
$ sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ruby本体をインストール&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p302.tar.bz2
$ tar jxf ruby-1.8.7-p302.tar.bz2
$ cd ruby-1.8.7-p302
$ ./configure
$ make
$ sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;gemをインストール&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ wget http://rubyforge.org/frs/download.php/70696/rubygems-1.3.7.tgz
$ tar zxvf rubygems-1.3.7.tgz
$ cd rubygems-1.3.7
$ sudo ruby setup.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;gemのライブラリをインストール&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ sudo gem install rails -v=2.3.5
$ sudo gem install rack -v=1.0.1
$ sudo gem install sqlite3-ruby
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Passengerをインストール&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ export PATH=$PATH:/usr/local/apache2/bin
$ export APXS2=/usr/local/apache2/bin/apxs
$ sudo passenger-install-apache2-module
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;あとは、自分の環境に合わせてhttpd.confを編集する。&lt;br /&gt;
参考：&lt;a href=&quot;http://redmine.jp/tech_note/apache-passenger/&quot;&gt;http://redmine.jp/tech_note/apache-passenger/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Missing trailing-&apos; in remote-shell command.</title><link>https://blog.teraren.com/posts/missing-trailing-in-remote-shell-command/</link><guid isPermaLink="true">https://blog.teraren.com/posts/missing-trailing-in-remote-shell-command/</guid><description>rsyncでSSHポート変更時に発生する「Missing trailing-&apos; in remote-shell command」エラーをRSYNC_RSH環境変数で解決する方法</description><pubDate>Fri, 17 Dec 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;rsyncでバックアップを行っていて、バックアップ先のSSHポートが変更されたのでそれにあわせて対応したら以下のエラーが出た。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Missing trailing-&apos; in remote-shell command.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;バックアップの内容はシェルスクリプトで書いていて、SSHのオプションを以下のように渡していた。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;OP=&quot;\&quot;ssh -p 3843&apos;\&quot;&apos;
RSYNC_COMMAND=&quot;nice -n 19 rsync -arRuz -e $OP --delete-excluded --bwlimit=200&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;この書き方では、RSYNC_COMMANDに代入する段階でOP変数に設定した文字が展開されてしまう。&lt;/p&gt;
&lt;h2&gt;解決方法&lt;/h2&gt;
&lt;p&gt;man rsyncに以下のような記述がある。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can also specify any remote shell you like, either by using the -e command line option, or by setting the
RSYNC_RSH environment variable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;よって、sshのポート指定のオプションを以下のように環境変数で与えるようにする。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export RSYNC_RSH=&quot;ssh -p3843&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;その結果、バックアップスクリプトは以下のようになる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export RSYNC_RSH=&quot;ssh -p3843&quot;
RSYNC_COMMAND=&quot;nice -n 19 rsync -arRuz --delete-excluded --bwlimit=200&quot;

$RSYNC_COMMAND &amp;lt;source1&amp;gt; &amp;lt;destination1&amp;gt;;
$RSYNC_COMMAND &amp;lt;source2&amp;gt; &amp;lt;destination2&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>iterm2でDeleteを押したらBackSpaceを送信</title><link>https://blog.teraren.com/posts/iterm2-delete-backspac/</link><guid isPermaLink="true">https://blog.teraren.com/posts/iterm2-delete-backspac/</guid><description>iterm2でDeleteを押したらBackSpaceを送信</description><pubDate>Wed, 15 Dec 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/12/Preferences.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/12/Preferences.png&quot; alt=&quot;&quot; title=&quot;Preferences&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;付属のターミナルよりカスタマイズ性が高い、&lt;a href=&quot;https://iterm2.com/&quot;&gt;iterm2&lt;/a&gt;を使い出しました。しかし、Deleteキーを押すと^hが送出されてしまって、リモートサーバでvimを使っているときに不便でした。&lt;/p&gt;
&lt;h2&gt;解決方法&lt;/h2&gt;
&lt;p&gt;設定画面にて、Deleteキーの振る舞いを変更します。 Preferences -&amp;gt; Keyboard -&amp;gt; Delete Key にチェックします。&lt;/p&gt;
</content:encoded></item><item><title>ロリポップでWordPress文字化け</title><link>https://blog.teraren.com/posts/lolipop-wordpress-encoding/</link><guid isPermaLink="true">https://blog.teraren.com/posts/lolipop-wordpress-encoding/</guid><description>ロリポップでWordPress文字化け</description><pubDate>Sat, 11 Dec 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;問題&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/12/1d5906dba9c833833e3b07369e4d32ce.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2010年6月頃に行われたロリポップサーバのアップグレード後、WordPressを普通にインストールするとこんな感じで文字化けしてしまいます↓&lt;br /&gt;
ソースコードもデータベースの文字コードはUTF-8.&lt;/p&gt;
&lt;h2&gt;対処方法&lt;/h2&gt;
&lt;p&gt;どうやら、DB周りの文字コード設定がおかしいみたいなのでDBの接続時の文字コードを明示的に指定するコードをwp-config.phpに書き込みます。&lt;br /&gt;
解説サイトでは、wp-includes/wp-db.phpに書き込む趣旨が書いてありますが、WordPressをアップグレードすると上書きされてその書き込んだ行が消えてしまうので、WordPressをアップグレードしても変更されないファイルであるwp-config.phpへ書く方が適切です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;define(&apos;DB_CHARSET&apos;, &apos;utf8&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/12/b39e1885119be8e6f6d39f51302cae83.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/12/a131928a3023e4d14607fc023e6cb412.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こんな感じで、文字化け直ります。&lt;/p&gt;
</content:encoded></item><item><title>Memcached Object Cache+batcache</title><link>https://blog.teraren.com/posts/memcached-object-cache-batcache/</link><guid isPermaLink="true">https://blog.teraren.com/posts/memcached-object-cache-batcache/</guid><description>WordPressにMemcached Object CacheとBatcacheを導入してページ表示速度を35倍に高速化。キャリア別キャッシュのカスタマイズ方法とベンチマーク結果を紹介。</description><pubDate>Sat, 11 Dec 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;mystiqueテーマを使った、WordPressのページ表示に1，2秒かかるのでキャッシュを導入し、&lt;strong&gt;レスポンスが35．6倍速くなりました！&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;インストール&lt;/h2&gt;
&lt;p&gt;以前、WP-SuperCacheというプラグインを試したが、マルチブログで正常に動作しないし、携帯のキャリアごとにキャッシュできないといった不便さがあったので導入しないでいました。&lt;/p&gt;
&lt;p&gt;しばらく放置していましたが、いかんせんページ表示が重くて、10秒間HTTPの応答が無いというアラートメールが飛んでくるようになったので対策しました。&lt;/p&gt;
&lt;p&gt;どうせ早くするなら、KVSにしてアプリケーションサーバをスケールアウトできるようにします。&lt;/p&gt;
&lt;p&gt;導入したのは以下の3つ。&lt;br /&gt;
導入方法はそれぞれのページにわかりやすく書いてあるので割愛します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://memcached.org/&quot;&gt;memcached&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wordpress.org/extend/plugins/memcached/&quot;&gt;Memcached Object Cache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wordpress.org/extend/plugins/batcache/&quot;&gt;Batcache&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;カスタマイズ&lt;/h2&gt;
&lt;p&gt;batcacheに関しては、自分でキャッシュのキーを選択できるので、キャリアごとにキャッシュを作るようにするために以下のブロックを追加しました。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function is_mobile_user_agent()
{
  require_once(&apos;Net/UserAgent/Mobile.php&apos;);

  $agent = Net_UserAgent_Mobile::singleton();

  if ($agent-&amp;gt;isDoCoMo()) {
    return 1;
  } else if ($agent-&amp;gt;isEZweb()) {
    return 2;
  } else if ($agent-&amp;gt;isSoftBank()) {
    return 3;
  } else if ($agent-&amp;gt;isWillcom()) {
    return 4;
  } else if(strpos(&apos;iPhone&apos;, $_SERVER[&apos;HTTP_USER_AGENT&apos;]) !== false ){
    return 6;
  }
  return 5;
}
$batcache-&amp;gt;unique[&apos;mobile&apos;] = is_mobile_user_agent();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;どちらのプラグインもソースコードがとても汚いので書き直したくなりますが、動くので良しとしよう。&lt;/p&gt;
&lt;h2&gt;ベンチマーク&lt;/h2&gt;
&lt;p&gt;測定は、インターネット越しに以下のコマンドを実行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% /usr/local/apache2/bin/ab -c 10 -n 500 https://blog.teraren.com/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;前：1.47 [#/sec] (mean)&lt;br /&gt;
後： 52.38 [#/sec] (mean)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;35.6倍速くなりました！&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;更新履歴&lt;/h2&gt;
&lt;p&gt;2010/12/19 WP-Touchを使っている場合にPCとキャッシュが共有されてしまう問題があったのでコードを修正。&lt;/p&gt;
</content:encoded></item><item><title>再帰置換するシェルスクリプト - ファイル名 と 中身</title><link>https://blog.teraren.com/posts/recursive-replace-shell-script-filename-and-content/</link><guid isPermaLink="true">https://blog.teraren.com/posts/recursive-replace-shell-script-filename-and-content/</guid><description>ディレクトリを再帰的に処理してファイルの中身とファイル名を一括置換できるシェルスクリプト2本を紹介</description><pubDate>Thu, 09 Dec 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;再帰的処理を行い、置換をするプログラムを2つ作りました。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ファイルの中身を変更&lt;/li&gt;
&lt;li&gt;ファイル名を変更&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;0. ワンライナーあった&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;find . -name &quot;*.html&quot; -type f -exec sed -i &apos;&apos; -e &apos;s/TextToReplace/ReplacementText/&apos; {} \;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;1. ファイルの中身を変更&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://matsu.teraren.com/static/replace_contents.sh&quot;&gt;https://matsu.teraren.com/static/replace_contents.sh&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

#-----------------------------------------------
# Replace SEARCH string with REPLACEMENT string for the contents.
USAGE=&quot;Usage: % ./replace_contents.sh search replacement&quot;
#
# @author Yuki Matsukura
# @version $Id:$
#-----------------------------------------------

# String of partical match
FILEMATCH=&quot;*&quot;

# String of partical match
SEARCH=$1

# String of replacement
REPLACEMENT=$2

if [ $# -ne 2 ]; then
  echo &quot;Insufficient parameter error&quot; 1&amp;gt;&amp;amp;2
  echo $USAGE 1&amp;gt;&amp;amp;2
  exit 1
fi

for i in `find . -type f -name &quot;*$FILEMATCH*&quot;`
do
  # contents replacement
  TEMPFILE=`mktemp`
  sed &quot;s/$SEARCH/$REPLACEMENT/g&quot; $i &amp;gt; $TEMPFILE
  mv $TEMPFILE $i

done
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. ファイル名を変更&lt;/h2&gt;
&lt;p&gt;https://matsu.teraren.com/static/replace_filename.sh&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

#-----------------------------------------------
# Replace SEARCH string with REPLACEMENT string for filename.
USAGE=&quot;Usage: % ./replace_filename.sh search replacement&quot;
#
# @author Yuki Matsukura
# @version $Id:$
#-----------------------------------------------

# String of partical match
SEARCH=$1

# String of replacement
REPLACEMENT=$2

if [ $# -ne 2 ]; then
  echo &quot;Insufficient parameter error&quot; 1&amp;gt;&amp;amp;2
  echo $USAGE 1&amp;gt;&amp;amp;2
  exit 1
fi

for i in `find . -type f -name &quot;*$SEARCH*&quot;`
do
  # file name replacement
  REPLACEMENT_FILE=`echo $i | sed &quot;s/$SEARCH/$REPLACEMENT/g&quot;`
  mv $i $REPLACEMENT_FILE

done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;::amazon{asin=&quot;4774186945&quot;}&lt;/p&gt;
</content:encoded></item><item><title>Windows Updateの履歴を消すbatch</title><link>https://blog.teraren.com/posts/windows-update-log-cleanup/</link><guid isPermaLink="true">https://blog.teraren.com/posts/windows-update-log-cleanup/</guid><description>Windows Updateの履歴を消すbatch</description><pubDate>Thu, 09 Dec 2010 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Windows XPの起動時の長いディスクアクセスは、Windows Updateの履歴が溜まりすぎていたせいだった？！ &lt;a href=&quot;http://zenryokuhp.com/blog/archives/2010/11/windows_xpwindo.php&quot;&gt;http://zenryokuhp.com/blog/archives/2010/11/windows_xpwindo.php&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;バッチファイル&lt;/h2&gt;
&lt;p&gt;上記の設定をクリック一発で行えるようにバッチプログラムを作成しました。 &lt;a href=&quot;https://github.com/matsubo/windows-useful-batch/raw/master/cleanup-windows-update-log.bat&quot;&gt;&lt;em&gt;cleanup-windows-update-log.bat&lt;/em&gt;&lt;/a&gt; ダウンロードして実行するだけで、起動が速くなる（ハズ）。&lt;/p&gt;
&lt;h2&gt;実行例&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/12/WS0868.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/12/WS0868.jpg&quot; alt=&quot;&quot; title=&quot;windows update log cleanup&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;定期的に実行&lt;/h2&gt;
&lt;p&gt;定期的に、上記のバッチを実行したい場合は、以下のいずれかの方法でタスクスケジューラに登録します。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同封の&lt;a href=&quot;https://github.com/matsubo/windows-useful-batch/raw/master/add-task-scheduler.bat&quot;&gt;&lt;em&gt;add-task-scheduler.bat&lt;/em&gt;&lt;/a&gt;を実行してタスクスケジューラに登録。（毎月 12時）&lt;/li&gt;
&lt;li&gt;スタート＞プログラム＞アクセサリ＞システムツール＞タスク&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;その他&lt;/h2&gt;
&lt;p&gt;ソースコードはgithubに登録してあります。 &lt;a href=&quot;https://github.com/matsubo/windows-useful-batch&quot;&gt;https://github.com/matsubo/windows-useful-batch&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>htopコマンドで見やすいリソースモニタリング</title><link>https://blog.teraren.com/posts/htop/</link><guid isPermaLink="true">https://blog.teraren.com/posts/htop/</guid><description>htopコマンドで見やすいリソースモニタリング</description><pubDate>Thu, 02 Dec 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://htop.sourceforge.net/&quot;&gt;htop&lt;/a&gt;とは、topコマンドの進化したバージョン。topコマンドはすべてキーボードショートカットを覚えた上で利用しなければなりませんが、htopではわかりやすいインターフェイスを備えています。&lt;/p&gt;
&lt;h2&gt;追記&lt;/h2&gt;
&lt;p&gt;macにもportで入れてみた。homebrewでも同じです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# port install htop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/12/htop-mac.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Jet Profiler for MySQL</title><link>https://blog.teraren.com/posts/jet-profiler-for-mysql/</link><guid isPermaLink="true">https://blog.teraren.com/posts/jet-profiler-for-mysql/</guid><description>Jet Profiler for MySQL</description><pubDate>Fri, 26 Nov 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/11/jet-profiler.png&quot; alt=&quot;jet profiler&quot; /&gt;&lt;/p&gt;
&lt;p&gt;MySQLのクエリアナライザを使ってみた。昔も使ったことあるけど、ちょっとグレードアップして便利になった。 特に、slow queryの分析がめちゃくちゃ楽。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/11/WS0852.jpg&quot; alt=&quot;query cache hitrate&quot; /&gt;&lt;/p&gt;
&lt;p&gt;↑こんな感じでリアルタイムにグラフ化してくれる。 注目すべき点は、下の半分。 Explainを押すと、どのぐらいクエリが重いかを視覚的に表示してくれる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/11/WS0853.jpg&quot; alt=&quot;slow query visualization&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Explainボタンを押すと↑のウィンドウが表示され、どの結合が重いかや、indexを使っていない結合を表示してくれる。 このプログラムは、裏で「show processlist」などのステータス表示クエリーを1秒ごとに発行しているだけだから、MySQLサーバへソケット接続するだけで使えるからお手軽。 無料版でも充分便利。&lt;/p&gt;
</content:encoded></item><item><title>SQLで期間の重複チェック</title><link>https://blog.teraren.com/posts/sql-term-duplicate-check/</link><guid isPermaLink="true">https://blog.teraren.com/posts/sql-term-duplicate-check/</guid><description>SQLで期間の重複チェック</description><pubDate>Fri, 05 Nov 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;キャンペーン追加時に、登録済みのキャンペーンと重複あるかチェックするためのクエリ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sprintf(&apos;((campaign_case_from BETWEEN %s AND %s) OR (campaign_case_to BETWEEN %s AND %s) OR (campaign_case_from &amp;lt;= %s AND %s &amp;lt;= campaign_case_to)) &apos;
    , $conn-&amp;gt;quote($campaign_case_from)
    , $conn-&amp;gt;quote($campaign_case_to)
    , $conn-&amp;gt;quote($campaign_case_from)
    , $conn-&amp;gt;quote($campaign_case_to)
    , $conn-&amp;gt;quote($campaign_case_from)
    , $conn-&amp;gt;quote($campaign_case_to))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;解説：&lt;br /&gt;
いずれかの条件がtrueになれば、重複している。&lt;br /&gt;
条件1：登録済みキャンペーンの開始日が、これから登録するキャンペーン期間に包含されていないか？&lt;br /&gt;
条件2：登録済みキャンペーンの終了日が、これから登録するキャンペーン期間に包含されていないか？&lt;br /&gt;
条件3：登録済みキャンペーンの開始日と終了日の間に、これから登録するキャンペーン期間が包含されているか？&lt;/p&gt;
</content:encoded></item><item><title>rsyncで帯域制限！ネットワークに負荷をかけないbwlimitオプション</title><link>https://blog.teraren.com/posts/rsync-bwlimit/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rsync-bwlimit/</guid><description>rsyncのbwlimitオプションでKBPS単位の帯域制限をかける方法と、Mbps換算表およびniceと組み合わせた低負荷バックアップ設定</description><pubDate>Thu, 28 Oct 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/10/WS0828.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://amzn.to/3iuiAzB&quot;&gt;ディザスターリカバリ&lt;/a&gt;対策に、1時間ごとに社内の重要データをリモートへrsyncを使って転送しています。&lt;/li&gt;
&lt;li&gt;rsyncを普通に実行すると可能な限り高速に転送するため、CPUやネットワークがボトルネックになります。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bwlimit&lt;/code&gt;オプションを使って帯域制限をします。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;bwlimit&lt;/code&gt;に指定する値の単位がKBPS（キロバイト/秒）です。普通、ネットワークはMbps（メガビット/秒）で表記するので変換に注意する必要があります。&lt;/p&gt;
&lt;p&gt;以下に簡単に変換表です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;100Mbpsなら、12500KBps&lt;/li&gt;
&lt;li&gt;10Mbpsなら、1250KBps&lt;/li&gt;
&lt;li&gt;1Mbpsなら、125KBps&lt;/li&gt;
&lt;li&gt;500kbpsなら、62.5KBps&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実行例&lt;/h2&gt;
&lt;h3&gt;bwlimit指定無し&lt;/h3&gt;
&lt;p&gt;1.3MBps(約10Mbps)で転送。100BaseTで構築されたLANでの転送の場合とか。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[matsu@dev1 ~]% rsync -vau  -e ssh sv2.tar.bz2 www.tymy.net:/home/matsu/test1.tar.bz2
Enter passphrase for key &apos;/home/matsu/.ssh/id_rsa&apos;:
building file list ... done
sv2.tar.bz2

sent 25806946 bytes  received 36 bytes  1323434.97 bytes/sec
total size is 25803676  speedup is 1.00
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;bwlimit指定有り&lt;/h3&gt;
&lt;p&gt;62KBps（約500kbps）で転送。少量のデータをインターネット上にバックアップするときとか。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[matsu@dev1 ~]% rsync -vau --bwlimit=62  -e ssh sv2.tar.bz2 www.tymy.net:/home/matsu/test2.tar.bz2
Enter passphrase for key &apos;/home/matsu/.ssh/id_rsa&apos;:
building file list ... done
sv2.tar.bz2

sent 25806946 bytes  received 36 bytes  62562.38 bytes/sec
total size is 25803676  speedup is 1.00
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;bwlimitオプションの詳細&lt;/h2&gt;
&lt;p&gt;man rsyncには以下のようにかいてあります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;       --bwlimit=KBPS
              This option allows you to specify a maximum transfer rate in kilobytes per second. This option is most effective when using rsync with large files (several megabytes  and
              up).  Due  to the nature of rsync transfers, blocks of data are sent, then if rsync determines the transfer was too fast, it will wait before sending the next data block.
              The result is an average transfer rate equaling the specified limit. A value of zero specifies no limit.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;応用&lt;/h2&gt;
&lt;p&gt;さらに、rsyncを実行しているホスト上で、実行プライオリティを下げるために、niceを併用すると他のサービスに影響が少なくなる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% nice -n 19 rsync -aruz --bwlimit=125 -e ssh [local] [remote]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;おまけ&lt;/h2&gt;
&lt;p&gt;このようなサービスにバックアップを取るときに使えます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://server.teraren.com/&quot;&gt;業界最安値の1TBのレンタルサーバ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;::amazon{asin=&quot;4802610327&quot;}&lt;/p&gt;
</content:encoded></item><item><title>Android カスタムROM 導入手順 HT-03a</title><link>https://blog.teraren.com/posts/android-ht-03a-root/</link><guid isPermaLink="true">https://blog.teraren.com/posts/android-ht-03a-root/</guid><description>HT-03aにCyanogenMod 6.0のカスタムROMを導入する手順。root取得からflash_image設置、ROMのフラッシュまでの一連の作業を手順書形式で解説。</description><pubDate>Tue, 26 Oct 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/10/DSC_3685.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;準備&lt;/h2&gt;
&lt;p&gt;■HT-03a本体準備&lt;br /&gt;
「USBデバッグ」を有効にしておく。&lt;/p&gt;
&lt;p&gt;■Android SDKのインストール&lt;br /&gt;
&lt;a href=&quot;http://developer.android.com/sdk/index.html&quot;&gt;http://developer.android.com/sdk/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;■ドライバのインストール&lt;br /&gt;
SDKのusb_driverに入ってるので、HT-03aを接続してインストールする。&lt;/p&gt;
&lt;p&gt;■アプリケーションのバックアップ&lt;br /&gt;
以下を参考に&lt;br /&gt;
&lt;a href=&quot;http://acc.komugi.net/?%E3%83%84%E3%83%BC%E3%83%AB/Backapps&quot;&gt;http://acc.komugi.net/?%E3%83%84%E3%83%BC%E3%83%AB/Backapps&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;■Android 1.6でRootを取る&lt;br /&gt;
昔は、1.5に落としてからじゃなきゃできなかったけど今はクリックだけで取れる。&lt;br /&gt;
&lt;a href=&quot;http://taiseiko.blog.so-net.ne.jp/2010-08-22-1&quot;&gt;http://taiseiko.blog.so-net.ne.jp/2010-08-22-1&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;カスタムROMインストール&lt;/h2&gt;
&lt;p&gt;■flash_imageを導入&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;D:\temp\android-sdk-windows\tools&amp;gt; adb shell
su
mount -o remount,rw /dev/block/mtdblock3 /system
cat /sdcard/flash_image &amp;gt; /system/xbin/flash_image
chmod 755 /system/bin/flash_image
sync
mount -o remount,ro /dev/block/mtdblock3 /system
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;■ROMダウンロード&lt;br /&gt;
update-cm-6.0.0-DS-signed.zip&lt;br /&gt;
&lt;a href=&quot;http://forum.cyanogenmod.com/files/file/95-update-cm-600-ds-signedzip/&quot;&gt;http://forum.cyanogenmod.com/files/file/95-update-cm-600-ds-signedzip/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;■googleアプリが詰まったROMをダウンロード&lt;br /&gt;
gapps-mdpi-FRF91-3-signed.zip&lt;br /&gt;
&lt;a href=&quot;http://www.mediafire.com/?gb99xl93748mqto&quot;&gt;http://www.mediafire.com/?gb99xl93748mqto&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;■SDカードへ転送&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;D:\temp\android-sdk-windows\tools&amp;gt;adb push update-cm-6.0.0-DS-signed.zip /sdcard/
D:\temp\android-sdk-windows\tools&amp;gt;adb push gapps-mdpi-FRF91-3-signed.zip /sdcard/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;■カスタムROMのインストーラで起動する&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# flash_image recovery /sdcard/recovery-RA-sapphire-v1.7.0G.img  
# reboot recovery
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;■初期化＆読み込む＆起動&lt;br /&gt;
Wipe -&amp;gt; Wipe data/factory reset&lt;br /&gt;
Flash zip from sdcard -&amp;gt; update-cm-6.0.0-DS-signed.zip&lt;br /&gt;
Flash zip from sdcard -&amp;gt; gapps-mdpi-FRF91-3-signed.zip&lt;br /&gt;
Reboot system now&lt;/p&gt;
&lt;h2&gt;参考ページ&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://komugi.net/archives/2010/07/11193757.phphttp://d.hatena.ne.jp/planetsquare/20100116/1263572254&quot;&gt;http://komugi.net/archives/2010/07/11193757.phphttp://d.hatena.ne.jp/planetsquare/20100116/1263572254&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>TELECOM 0570-099-922</title><link>https://blog.teraren.com/posts/telecom-0570-099-922/</link><guid isPermaLink="true">https://blog.teraren.com/posts/telecom-0570-099-922/</guid><description>TELECOM 0570-099-922</description><pubDate>Thu, 07 Oct 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/10/WS0807.png&quot; alt=&quot;telecom 0570-099-922&quot; /&gt;&lt;/p&gt;
&lt;p&gt;カードの請求を見ていたら、「TELECOM 0570-099-922」とあったので、電話してみたら「&lt;a href=&quot;http://tten.jp/tokyo/&quot;&gt;トクテン&lt;/a&gt;」で利用した決済だった。 「海外利用」とか書いてあるし、とても怪しい感じだったけどコールセンターの人は丁寧な対応だった。&lt;/p&gt;
</content:encoded></item><item><title>サーファス（SERFAS） ライト SL-30WP フロント 3LED</title><link>https://blog.teraren.com/posts/serfas-light-sl-30wp-front-3led/</link><guid isPermaLink="true">https://blog.teraren.com/posts/serfas-light-sl-30wp-front-3led/</guid><description>サーファス（SERFAS） ライト SL-30WP フロント 3LED</description><pubDate>Thu, 30 Sep 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;これの続き。&lt;br /&gt;
&lt;a href=&quot;/posts/itp-sa2-eluma-2xaa/&quot;&gt;iTP SA2 Eluma (2xAA)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;結局、これにした↓&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07JMFY2RN&quot;}&lt;/p&gt;
&lt;p&gt;iTP SA2は明るくていいんだけど、以下の欠点が大きいのでやっぱり利用はやめた。&lt;br /&gt;
・重い：金属でできているからずっしり重い&lt;br /&gt;
・長い：ハンドルに取り付けるとスタンディングしたときに足にちょっと当たる&lt;br /&gt;
・明るすぎる：highにすると2時間しか電池が持たない。&lt;br /&gt;
・高い：マウントとか合わせると5000円ぐらいいってしまうので、パくられると痛い。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://amzn.to/39CHxE5&quot;&gt;SERFASのSL-30WP&lt;/a&gt;は十分明るいし、安いし、軽い、マウントもしっかりしている。&lt;br /&gt;
マイナーなブランドだけどこのライトはもっと広まってもいいと思う。&lt;/p&gt;
&lt;p&gt;高価なLED1灯より、そこそこのLED3灯の方がコストパフォーマンスいいのではないか。&lt;/p&gt;
</content:encoded></item><item><title>The Share-Nothing Architecture</title><link>https://blog.teraren.com/posts/the-share-nothing-architecture/</link><guid isPermaLink="true">https://blog.teraren.com/posts/the-share-nothing-architecture/</guid><description>The Share-Nothing Architecture</description><pubDate>Fri, 24 Sep 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;半年前に何かで話題になっていて、執筆中だった記事。。。。 &lt;strong&gt;The Share-Nothing Architecture&lt;/strong&gt; &lt;a href=&quot;http://zef.me/883/the-share-nothing-architecture&quot;&gt;http://zef.me/883/the-share-nothing-architecture&lt;/a&gt; 著者の主張はキャッシュを使わずに、各レイヤーでスケールアウトすればいい。 ファイルシステム、データベース、フロントエンドそれぞれのレイヤでスケールするソリューションがあるから組み合わせて使えばキャッシュしなくてもいいとのこと。 なんか、無理矢理なロジック。それができていればみんな悩まないと思うし、大規模サイトを運用している会社がそれぞれ違ったアーキテクチャを作っている理由は簡単に解決できないからだ。 この主張の穴は、 1．「ボトルネックは必ず発生する」 2．「非リアルタイム」 1． 各レイヤではボトルネックを発生しないようにできるだろうが、レイヤ同士の通信や、マスタサーバへのトラフィックではボトルネックが発生する。 2． ファイルを更新したら、デプロイ時間がかかる。よって、リアルタイム性とレスポンススピードのトレードオフになる。 どんなアーキテクチャでも結局はリアルタイム性とレスポンススピードのトレードオフになるんだろうなぁ。このトレードオフを解決するために各社が自社サービスに最適化したアーキテクチャを考えているのだろう。 PS: 俺も昔は同じ事かんがえてたよなぁ。。。理想論だよ！&lt;/p&gt;
</content:encoded></item><item><title>git-archive使い方</title><link>https://blog.teraren.com/posts/git-archive/</link><guid isPermaLink="true">https://blog.teraren.com/posts/git-archive/</guid><description>git-archive使い方</description><pubDate>Thu, 23 Sep 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;gitにはarchiveオプションがあり、任意のリビジョンを圧縮できるコマンドがある。&lt;br /&gt;
これを使うことによって、コマンド1発でダウンロード用のファイルを作成できる。&lt;/p&gt;
&lt;p&gt;納品の時とか、Webにファイルを公開する際に便利！&lt;/p&gt;
&lt;h2&gt;実行例&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;% git archive --format=tar --prefix=phase-2 HEAD | gzip &amp;gt; phase-2.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;参考サイト&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://at-aka.blogspot.com/2009/02/git-archive.html&quot;&gt;http://at-aka.blogspot.com/2009/02/git-archive.html&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>iTP SA2 Eluma (2xAA)</title><link>https://blog.teraren.com/posts/itp-sa2-eluma-2xaa/</link><guid isPermaLink="true">https://blog.teraren.com/posts/itp-sa2-eluma-2xaa/</guid><description>iTP SA2 Eluma (2xAA)</description><pubDate>Thu, 23 Sep 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;ロードバイクのライトのマウントが壊れてしまったので新しいライトを買った。 ライトってWebで探すには難しい商材だった。結局iTP SA2と自転車用マウントを買った。 今日は雨なので、晴れたときに再度、動画で使用レポートします。 クウォリティが高いモノやサービスに触れられるとwktkします！&lt;/p&gt;
&lt;h2&gt;良い点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;highモードは超明るい。自転車には明るすぎる気がする。190ルーメンはすごいぞー。&lt;/li&gt;
&lt;li&gt;コストパフォーマンス高い！この値段でこの明るさはすごい。&lt;/li&gt;
&lt;li&gt;アウトドアにも使える。&lt;/li&gt;
&lt;li&gt;質感が安っぽいとレビューにあったが、全然問題ない。&lt;/li&gt;
&lt;li&gt;防水&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;悪い点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;フラッシュモードでの明るさはhighだけ。midでフラッシュモードにしたいけどできない。&lt;/li&gt;
&lt;li&gt;ちょっとでかい。自転車に2AAの縦つなぎは自転車にマウントすると安定しない。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>libaio.so.1: cannot open shared object file</title><link>https://blog.teraren.com/posts/libaio-so-1-cannot-open-shared-object-file/</link><guid isPermaLink="true">https://blog.teraren.com/posts/libaio-so-1-cannot-open-shared-object-file/</guid><description>libaio.so.1: cannot open shared object file</description><pubDate>Sat, 11 Sep 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;このブログのMySQLをmysql 5.5.5-m3へアップグレード。理由は、mysql 5.5.3にはdatetimeにindexが使われないというバグがあったため。&lt;/p&gt;
&lt;p&gt;インストールしたら、以下のエラーが出て立ち上がらなかった。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;100911 13:26:13 mysqld_safe mysqld from pid file /usr/local/mysql/data/dns.tymy.net.pid ended
100911 13:28:36 mysqld_safe Starting mysqld daemon with databases from /usr/local/mysql/data
/usr/local/mysql/bin/mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;libaio入れて解決。libaioはoracleで利用されているライブラリ。MySQLでも必要になった。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# yum install libaio-devel -y
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Meeting with Twitter engineer</title><link>https://blog.teraren.com/posts/twitter-meeting/</link><guid isPermaLink="true">https://blog.teraren.com/posts/twitter-meeting/</guid><description>Meeting with Twitter engineer</description><pubDate>Fri, 10 Sep 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://x.com/a_kodama&quot;&gt;@a_kodama&lt;/a&gt; &lt;a href=&quot;http://x.com/niyalist&quot;&gt;@niyalist&lt;/a&gt; &lt;a href=&quot;http://x.com/niw&quot;&gt;@niw&lt;/a&gt; さんとミッドタウンで食事。&lt;/p&gt;
&lt;p&gt;思ったことメモ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Twitterを&lt;a href=&quot;http://ja.aprs.fi/&quot;&gt;APRS&lt;/a&gt;みたいに使えるかも。天気とか地理情報のインフラとして。人間が読めなくてもいいかも。例→e6 9c ac e6 97 a5 e3 81 af e6 99 b4 e5 a4 a9 e3 81 aa e3 82 8a。　無線で言えば、アナログ通信とデジタル通信が混在している状態。&lt;/li&gt;
&lt;li&gt;アルファベットと日本語では1文字の情報量が違うからtweetの内容が違う。&lt;/li&gt;
&lt;li&gt;followingが100～200を超えたらリストを使わないと厳しい。→タグ付け面倒。ページ遷移面倒。&lt;/li&gt;
&lt;li&gt;Twitterアカウントごとにクラスタができる。（例：地理情報に詳しい人）。専門性が高い場合は濃いクラスタができるっぽい。（mixiがオープンになってればできた気がする）&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>営業利益÷従業員</title><link>https://blog.teraren.com/posts/sns-profit-per-employee/</link><guid isPermaLink="true">https://blog.teraren.com/posts/sns-profit-per-employee/</guid><description>GREE・DeNA・mixi・Googleなど主要IT企業の従業員1人当たり営業利益を比較。任天堂1億円以上、Appleが4400万円など各社の生産性の違いを数字で可視化。</description><pubDate>Fri, 03 Sep 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;最近、良く話題になるIT会社の一人あたりの営業利益額をだしてみた。&lt;/p&gt;
&lt;p&gt;gree&lt;br /&gt;
102人で、57億円&lt;br /&gt;
&lt;strong&gt;5,580万円/人&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;DeNA&lt;br /&gt;
624人で、130億円&lt;br /&gt;
&lt;strong&gt;2,080万円/人&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;mixi&lt;br /&gt;
300人18億円&lt;br /&gt;
&lt;strong&gt;600万円/人&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;google&lt;br /&gt;
推定25000人 2,365M USD&lt;br /&gt;
&lt;strong&gt;800万円/人&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;reference: &lt;a href=&quot;http://x.com/studySingapore/status/22577575113&quot;&gt;http://x.com/studySingapore/status/22577575113&lt;/a&gt;&lt;br /&gt;
パナソニック&lt;br /&gt;
&lt;strong&gt;50万円&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ソニー&lt;br /&gt;
&lt;strong&gt;19万円&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;アップル&lt;br /&gt;
&lt;strong&gt;4400万円&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;任天堂&lt;br /&gt;
&lt;strong&gt;1億円以上&lt;/strong&gt;&lt;/p&gt;
</content:encoded></item><item><title>文字コードを再帰で置換</title><link>https://blog.teraren.com/posts/recursive-file-encoding-chang/</link><guid isPermaLink="true">https://blog.teraren.com/posts/recursive-file-encoding-chang/</guid><description>文字コードを再帰で置換</description><pubDate>Thu, 02 Sep 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;コマンドメモ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% find . -type f -name &quot;*.php&quot; -exec nkf -s --overwrite {} \;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;nkfの引数を変えれば任意の文字コードへ変換できる。前は、シェルスクリプトを書いていたけど、nkfのオプションにoverwriteがあることを知ったのでコマンド一発でできるようになった。&lt;/p&gt;
</content:encoded></item><item><title>e-learning系参考サイト</title><link>https://blog.teraren.com/posts/e-learning-reference-sites/</link><guid isPermaLink="true">https://blog.teraren.com/posts/e-learning-reference-sites/</guid><description>e-learning系参考サイト</description><pubDate>Fri, 20 Aug 2010 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;Academic Earth. &lt;a href=&quot;http://academicearth.org/&quot;&gt;http://academicearth.org/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;アメリカの著名大学の講義を見られる。 $1000程度で学士を取れるサービスも提供されている。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Khan Academy &lt;a href=&quot;http://www.khanacademy.org/&quot;&gt;http://www.khanacademy.org/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Salman Khanさんが1600本以上の授業をblack boardと音声解説で提供している。 ライセンスはCreative Commons。 こんな良質なコンテンツが無料で提供される状態なので、基礎教育は超ローコストに提供できるようになりそう。&lt;/p&gt;
</content:encoded></item><item><title>関東の花火大会をTweetするBotを作りました</title><link>https://blog.teraren.com/posts/fireworks/</link><guid isPermaLink="true">https://blog.teraren.com/posts/fireworks/</guid><description>関東の花火大会をTweetするBotを作りました</description><pubDate>Tue, 03 Aug 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;関東の花火大会をTweetするbotを作ったのでフォローよろしく！&lt;/p&gt;
&lt;p&gt;http://x.com/hanabi_kanto&lt;/p&gt;
&lt;h2&gt;動機&lt;/h2&gt;
&lt;p&gt;花火大会に行きたいけど、いざ行く事を想定してみると混んでそうだし、渋滞しそうなので、いく前から腰が重くなってしまいます。&lt;br /&gt;
だから、衝動買いのように衝動で花火大会へ行くことを支援するためのbot。&lt;/p&gt;
&lt;h2&gt;制作&lt;/h2&gt;
&lt;p&gt;プログラム1.5時間、花火大会のデータ整形2時間。&lt;/p&gt;
</content:encoded></item><item><title>JavascriptのsetTimeout</title><link>https://blog.teraren.com/posts/javascript-settimeout/</link><guid isPermaLink="true">https://blog.teraren.com/posts/javascript-settimeout/</guid><description>JavascriptのsetTimeout</description><pubDate>Fri, 30 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/07/WS0769.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/07/WS0769.jpg&quot; alt=&quot;&quot; title=&quot;settimeout&quot; /&gt;&lt;/a&gt; setTimeoutって便利だね。 簡単にスレッドを実装できちゃうね。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/static/thread.html&quot;&gt;サンプル1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/static/thread2.html&quot;&gt;サンプル2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>MySQLの日付(Date)型を比較する際の注意</title><link>https://blog.teraren.com/posts/mysql-date-string/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-date-string/</guid><description>MySQLでBETWEENを使う際にDATETIME型と文字列を混在させると比較結果が狂う落とし穴をSQL実行例で解説</description><pubDate>Tue, 27 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;column BETWEEN A AND B&lt;/code&gt; イコール &lt;code&gt;A &amp;lt;= column and column &amp;lt;= B&lt;/code&gt;
なので、以下のSQLの結果は同一かと思ったが、一部の条件で挙動が異なった。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# andの後ろの項を含んでほしいのですが、含んでいない様子。
mysql&amp;gt; select &apos;2010-07-26 00:00:00&apos; BETWEEN &apos;2010-07-25&apos; AND &apos;2010-07-26&apos;;
+-------------------------------------------------------------+
| &apos;2010-07-26 00:00:00&apos; BETWEEN &apos;2010-07-25&apos; AND &apos;2010-07-26&apos; |
+-------------------------------------------------------------+
| 0 |
+-------------------------------------------------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# castをすれば含んでくれる
mysql&amp;gt; select cast(&apos;2010-07-26 00:00:00&apos; as datetime) BETWEEN &apos;2010-07-25&apos; AND &apos;2010-07-26 00:00:00&apos;;
+----------------------------------------------------------------------------------------+
| cast(&apos;2010-07-26 00:00:00&apos; as datetime) BETWEEN &apos;2010-07-25&apos; AND &apos;2010-07-26 00:00:00&apos; |
+----------------------------------------------------------------------------------------+
|                                                                                      1 |
+----------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;なぜかというと、ただのクウォートだと文字として比較してしまうから。&lt;br /&gt;
&lt;strong&gt;比較対象のカラムは型を意識しなければならない。&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT CAST(&apos;2010-07-26 00:00:00&apos; AS DATETIME) BETWEEN &apos;2010-07-25&apos; AND &apos;2010-07-26&apos;;
+-------------------------------------------------------------------------------+
| CAST(&apos;2010-07-26 00:00:00&apos; AS DATETIME) BETWEEN &apos;2010-07-25&apos; AND &apos;2010-07-26&apos; |
+-------------------------------------------------------------------------------+
|                                                                             1 |
+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;range指定は対象カラムの型に自動変換されるみたい。&lt;/p&gt;
&lt;h2&gt;DateとDatetimeの比較演算&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| UTC                | UTC                 |
+--------------------+---------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select CAST(&apos;2014-08-04 13:00:00&apos; AS DATETIME) &amp;lt;= &apos;2014-08-04&apos;;
+---------------------------------------------------------+
| CAST(&apos;2014-08-04 13:00:00&apos; AS DATETIME) &amp;lt;= &apos;2014-08-04&apos; |
+---------------------------------------------------------+
|                                                       0 |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select CAST(&apos;2014-08-05 00:00:00&apos; AS DATETIME) &amp;lt;= &apos;2014-08-04&apos;;
+---------------------------------------------------------+
| CAST(&apos;2014-08-04 10:00:00&apos; AS DATETIME) &amp;lt;= &apos;2014-08-04&apos; |
+---------------------------------------------------------+
|                                                       0 |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select CAST(&apos;2014-08-04 00:00:00&apos; AS DATETIME) &amp;lt;= &apos;2014-08-04&apos;;
+---------------------------------------------------------+
| CAST(&apos;2014-08-04 00:00:00&apos; AS DATETIME) &amp;lt;= &apos;2014-08-04&apos; |
+---------------------------------------------------------+
|                                                       1 |
+---------------------------------------------------------+
1 row in set (0.00 sec)

mysql&amp;gt; select CAST(&apos;2014-08-04 00:00:01&apos; AS DATETIME) &amp;lt;= &apos;2014-08-04&apos;;
+---------------------------------------------------------+
| CAST(&apos;2014-08-04 00:00:01&apos; AS DATETIME) &amp;lt;= &apos;2014-08-04&apos; |
+---------------------------------------------------------+
|                                                       0 |
+---------------------------------------------------------+
1 row in set (0.00 sec)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>lvm管理しているファイルシステムにディスクを追加</title><link>https://blog.teraren.com/posts/add-hdd-to-lvm-managed-fs/</link><guid isPermaLink="true">https://blog.teraren.com/posts/add-hdd-to-lvm-managed-fs/</guid><description>稼働中のLVM管理ファイルシステムにオンラインのままHDDを追加する手順。vgextend・resize2fsコマンドでディスク容量を拡張する方法と、Free PEを使い切るlvresizeの設定を解説。</description><pubDate>Thu, 22 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今回紹介する方法は、新品のディスク丸ごとを、稼働中のLogical Volumeへ追加する場合の手順。オンラインのままできます。&lt;/p&gt;
&lt;p&gt;手順は以下。&lt;br /&gt;
resize2fsコマンド実行中に、dfを見ると徐々にディスク容量が増えていくのが確認できる。&lt;br /&gt;
resize2fsは1.5TBで1時間かかる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# fdisk /dev/sdc
# 一応パーティション消しておく。
# vgextend sv1 /dev/sdc
# resize2fs /dev/mapper/sv1-home
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;いろんな解説ページがいろんな方法を提示してあって、正解にたどり着くまで大変だった。。。確かに、目的に応じて使うコマンドや手順が違ってくるね。前提をしっかり書いて欲しい。&lt;/p&gt;
&lt;p&gt;追記(7/25)：&lt;/p&gt;
&lt;p&gt;なぜか、pvにFree PEが残っていたので、使い切る設定をする。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sv1 /etc]# pvscan
  PV /dev/sda2   VG sv1   lvm2 [232.64 GB / 0    free]
  PV /dev/sdc    VG sv1   lvm2 [1.46 TB / 324.69 GB free]
  Total: 2 [1.69 TB] / in use: 2 [1.69 TB] / in no VG: 0 [0   ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LVにFree PEを追加する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sv1 /etc]# lvresize -l +2533332 /dev/sv1/home
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ファイルシステムをオンラインでresize&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@sv1 /etc]# resize2fs /dev/sv1/home
resize2fs 1.41.3 (12-Oct-2008)
Filesystem at /dev/sv1/home is mounted on /home; on-line resizing required
old desc_blocks = 88, new_desc_blocks = 102
Performing an on-line resize of /dev/sv1/home to 424471552 (4k) blocks.

[root@sv1 /etc]# pvscan
  PV /dev/sda2   VG sv1   lvm2 [232.64 GB / 0    free]
  PV /dev/sdc    VG sv1   lvm2 [1.36 TB / 0    free]
  Total: 2 [1.59 TB] / in use: 2 [1.59 TB] / in no VG: 0 [0   ]
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Webページの最下部へのスクロールを判定するjQuery</title><link>https://blog.teraren.com/posts/bottom-scroll-detection-jquery/</link><guid isPermaLink="true">https://blog.teraren.com/posts/bottom-scroll-detection-jquery/</guid><description>Webページの最下部へのスクロールを判定するjQuery</description><pubDate>Thu, 22 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;ユーザがページ最下部へスクロールしたことを検出するjQuery書きました。&lt;/p&gt;
&lt;h2&gt;サンプルコード&lt;/h2&gt;
&lt;p&gt;github&lt;br /&gt;
&lt;a href=&quot;http://github.com/matsubo/detect-reaching-to-the-bottom-of-the-page&quot;&gt;http://github.com/matsubo/detect-reaching-to-the-bottom-of-the-page&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;デモ&lt;/h2&gt;
&lt;h2&gt;TODO&lt;/h2&gt;
&lt;p&gt;jQuery pluginにする&lt;/p&gt;
</content:encoded></item><item><title>本質を理解して、一緒にスタート地点に立つ</title><link>https://blog.teraren.com/posts/proposal/</link><guid isPermaLink="true">https://blog.teraren.com/posts/proposal/</guid><description>本質を理解して、一緒にスタート地点に立つ</description><pubDate>Sat, 17 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;お世話になっている飲食店経営者からWebリニューアルを依頼をいただきました。&lt;/p&gt;
&lt;h2&gt;依頼内容&lt;/h2&gt;
&lt;p&gt;依頼された内容は&lt;br /&gt;
・Webリニューアル&lt;br /&gt;
・かっこよく&lt;br /&gt;
・予算はxxxxx円&lt;br /&gt;
だけ。&lt;/p&gt;
&lt;h2&gt;問題点を解読する&lt;/h2&gt;
&lt;p&gt;これをそのままリニューアルとしてとらえてカッコイイデザインを提供するだけでは、依頼者がなぜリニューアルをするのかがわかりません。&lt;br /&gt;
Webのリニューアルをただのデザイン変更と考えるのではなく、依頼者のコンセプトを共有し、問題意識を理解してから、Webリニューアルのスタートラインに立てます。&lt;/p&gt;
&lt;h2&gt;情報共有&lt;/h2&gt;
&lt;p&gt;お互い異なる業界、異なる立場で働いています。よって、見ていること、考えていることが異なります。まずは、お互いの視点や考えを共有します。&lt;br /&gt;
相互理解は円滑なコミュニケーションの土台になるのでしっかりと行います。&lt;/p&gt;
&lt;h2&gt;成果&lt;/h2&gt;
&lt;p&gt;従業員と私でコンセプトを共有し、マーケット、従業員、お客様のタイプなどを共有し、リニューアルの背景となる要素を共有できました。&lt;/p&gt;
&lt;p&gt;言葉では伝えづらいですが、和やかな雰囲気の中、建設的なディスカッションと情報共有が行えました！&lt;/p&gt;
</content:encoded></item><item><title>oEmbed</title><link>https://blog.teraren.com/posts/oembed/</link><guid isPermaLink="true">https://blog.teraren.com/posts/oembed/</guid><description>oEmbed</description><pubDate>Sat, 10 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;http://www.flickr.com/photos/marser/4510379035/in/faves-matsubokkuri/&lt;/p&gt;
&lt;p&gt;oEmbed便利！Flickrのpermalinkをテキスト部分に記載するだけで、自動でHTMLタグに変換してくれる。&lt;br /&gt;
ほんと、ただURLを書くだけ。こんな感じで↓　pre内も容赦なく置換されてしまう。&lt;/p&gt;
&lt;p&gt;https://www.flickr.com/photos/matsubo/32850057498/in/dateposted-public/&lt;/p&gt;
&lt;p&gt;アイキャッチ画像をoEmbedで設定できたら楽なのになぁ。&lt;br /&gt;
CCが設定されている他の人の画像には、CCのリンクもつけて欲しいなぁ。&lt;/p&gt;
</content:encoded></item><item><title>ThinkStation S20でMySQLベンチマーク</title><link>https://blog.teraren.com/posts/thinkstation-s20-mysql-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/thinkstation-s20-mysql-benchmark/</guid><description>ThinkStation S20を使いMySQL 5.1と5.5のトランザクション処理数を比較。InnoDBはコネクション込みで6倍・クエリのみで80%の性能向上を確認。mysqlbenchで128スレッド実測。</description><pubDate>Sat, 10 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/07/logomysql.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/thinkstation-s20-ff14-benchmark/%E3%81%AE%E7%B6%9A%E3%81%8D%E3%80%82&quot;&gt;/posts/thinkstation-s20-ff14-benchmark/の続き。&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.publickey1.jp/blog/10/mysql_55innodb200mysql_conferenceexpo.html&quot;&gt;MySQL 5.5のInnoDBプラグインの性能が大幅に改善された&lt;/a&gt;と言うことで、MySQL5.5のベンチマークを取ってみた。&lt;/p&gt;
&lt;h2&gt;実行環境&lt;/h2&gt;
&lt;p&gt;クライアント： Debian GNU/Linux 5.0 　Core 2 Duo E7200　256M RAM (on Windows XP)&lt;br /&gt;
ホスト： Ubuntu ja 10.04 desktop ThinkStation S20 Xeon W3540 4G RAM&lt;br /&gt;
ネットワーク： 1000Mbps Ethernet&lt;/p&gt;
&lt;p&gt;テストにはmysqlbenchを利用。テスト内容は行更新による負荷をかけたときのトランザクション処理数を計測。&lt;br /&gt;
実行コマンド。128スレッドそれぞれ1000トランザクション。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ./mysqlbench  -U root -h 192.168.0.108 -E myisam  -c 128 -t 1000  test
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;結果1&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/07/WS0747.jpg&quot; alt=&quot;MySQL 5.1 VS 5.5 (include connection)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;コネクション時間を含んだトランザクション処理数。5.1と5.5ではMyISAMで12倍、InnoDBで6倍の差がある。&lt;br /&gt;
libmysqlclient, mysqldのコネクション周りで大きな変更があったのかも。&lt;/p&gt;
&lt;h2&gt;結果2&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/07/WS0748.jpg&quot; alt=&quot;MySQL 5.1 VS 5.5 (exclude connection)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;コネクション時間を除いたトランザクション処理数。5.1と5.5ではMyISAMで10%、InnoDBで80%の性能向上がある。&lt;br /&gt;
やはりInnnoDBの改良は大きかったようだ。&lt;/p&gt;
&lt;h2&gt;結論&lt;/h2&gt;
&lt;p&gt;5.5早い！DBの更新が少ないサイトでは恩恵は少ないかも。&lt;br /&gt;
しかし、確実に早いのでリリースされたら使ってみるべき。&lt;/p&gt;
&lt;h2&gt;備考&lt;/h2&gt;
&lt;p&gt;結果を掲載したExcelファイル　&lt;a href=&quot;/uploads/2010/07/summary.xls&quot;&gt;summary.xls&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>gitにて公開したbranchでrebaseしちゃダメ</title><link>https://blog.teraren.com/posts/git-do-not-rebase/</link><guid isPermaLink="true">https://blog.teraren.com/posts/git-do-not-rebase/</guid><description>gitにて公開したbranchでrebaseしちゃダメ</description><pubDate>Fri, 09 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/07/WS0746.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/07/WS0746.jpg&quot; alt=&quot;&quot; title=&quot;git branch&quot; /&gt;&lt;/a&gt; 言いたいことは、「&lt;strong&gt;公開したbranchではrebase禁止！&lt;/strong&gt;」 例えば：Aさんがbranch作り、Bさんが派生したbranchを作ったら、Aさんはrebase禁止！ 以下、gitのモデルを理解している人に対しての説明です。 rebaseすると、過去のcommit IDが書き換わってしまうのでBさんが作ったbranchの親ブランチをトラッキングできなくなってしまい、BさんのbranchとAさんのbranchをmergeする時にconflictが発生しまくってしまう。 もし、Aさんがrebaseしてしまっていたら、Bさんはbranch切り直しと、cherry-pickで地道に修復しないといけなくなってしまう。&lt;/p&gt;
</content:encoded></item><item><title>Windows上でAPRSを試してみた</title><link>https://blog.teraren.com/posts/post-2920/</link><guid isPermaLink="true">https://blog.teraren.com/posts/post-2920/</guid><description>Windows上でAPRSを試してみた</description><pubDate>Mon, 05 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/07/WS0745.jpg&quot; alt=&quot;UI-View32&quot; /&gt;&lt;/p&gt;
&lt;p&gt;UI-View32&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://ja.wikipedia.org/wiki/APRS&quot;&gt;APRS&lt;/a&gt;で遊んでみた。&lt;/p&gt;
&lt;p&gt;APRSとは、メッセージ、気象情報などの情報を位置情報と一緒にアマチュア無線の電波帯域を使ってブロードキャストする仕組み。アマチュア無線とインターネットのゲートウェイも設置されているので、アマチュア無線機から電子メールを送ることもできる。&lt;/p&gt;
&lt;p&gt;APRSでどんなことができるかを一目で見るには、以下のサイトがわかりやすい。&lt;/p&gt;
&lt;p&gt;Google Maps APRS。&lt;br /&gt;
&lt;a href=&quot;http://ja.aprs.fi/&quot;&gt;http://ja.aprs.fi/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;APRS自体、スケーラブルなモデルではなく、利用するためには無線の免許が必要なのであまり流行らないとは思う。&lt;/p&gt;
&lt;p&gt;自分の位置情報を公開してトラッキングしてもらう場合には、使えそう。&lt;/p&gt;
</content:encoded></item><item><title>ThinkStation S20でFF14ベンチマーク</title><link>https://blog.teraren.com/posts/thinkstation-s20-ff14-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/thinkstation-s20-ff14-benchmark/</guid><description>Xeon W3540搭載のThinkStation S20でFF14ベンチマークと3DMark 06を計測し、拡張性や使い勝手をレビュー</description><pubDate>Sat, 03 Jul 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ThinkStation S20&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://fansfans.jp/campaigns/detail/16&quot;&gt;ThinkPad/IdeaPad 製品お試しキャンペーン&lt;/a&gt;に当選しました！まず、AMNの皆様、御礼を申し上げます。新しいものに触れる機会を与えてくださりとても嬉しいです！&lt;/p&gt;
&lt;p&gt;さて、まずは基礎情報の把握と、今巷で話題の&lt;a href=&quot;http://www.finalfantasyxiv.com/media/benchmark/jp/&quot;&gt;FF14のベンチマーク&lt;/a&gt;をしてみます。&lt;/p&gt;
&lt;h2&gt;オフィシャルの仕様&lt;/h2&gt;
&lt;p&gt;一般のPCに比較して大きな特徴は拡張性がとても高い。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/07/spec.png&quot; alt=&quot;ThinkStation S20 仕様&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ThinkStation S20 仕様&lt;/p&gt;
&lt;h2&gt;CPU詳細&lt;/h2&gt;
&lt;p&gt;モデルはCore i7と書いてあるが、実際に搭載されているのはXeonのW3540である。構造はCore i7と同じbloomfieldにECC機能などが追加されている。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/07/WS000000.jpg&quot; alt=&quot;CrystalCPUID&quot; /&gt;&lt;/p&gt;
&lt;p&gt;CrystalCPUID&lt;/p&gt;
&lt;h2&gt;GPU詳細&lt;/h2&gt;
&lt;p&gt;RAMは512MB、クロックは700MHz。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/07/WS000001.jpg&quot; alt=&quot;GPU-Z&quot; /&gt;&lt;/p&gt;
&lt;p&gt;GPU-Z&lt;/p&gt;
&lt;h2&gt;FF14のベンチマークスコア&lt;/h2&gt;
&lt;p&gt;1675はぎりぎり合格のレベル。ベンチマーク実行時に、重いレンダリングをしている時にラグがおきる時がある。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/07/WS000004.jpg&quot; alt=&quot;FF14 benchmark result&quot; /&gt;&lt;/p&gt;
&lt;p&gt;FF14 benchmark result&lt;/p&gt;
&lt;h2&gt;3D Mark 06の結果&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/07/WS000007.jpg&quot; alt=&quot;3D Mark 06&quot; /&gt;&lt;/p&gt;
&lt;p&gt;3D Mark 06&lt;/p&gt;
&lt;h2&gt;ファーストインプレッション&lt;/h2&gt;
&lt;p&gt;以下に、ファーストインプレッションの良い点、悪い点をまとめておきます。&lt;/p&gt;
&lt;h3&gt;良い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ハードディスクの交換が横パネルをガチャっと空けて簡単に抜き差しできる。&lt;/li&gt;
&lt;li&gt;マザーボードにRAIDコントローラが内蔵されている。&lt;/li&gt;
&lt;li&gt;個人でも買える値段。約12万円から！&lt;/li&gt;
&lt;li&gt;現在、仕事で使っているPCはCore 2 Duoの2GHzぐらいなので、8スレッドあるとアプリケーションの切り替えがかなりスムーズ。バックグラウンド処理がフロントの処理を邪魔しない。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;悪い点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;今の案件のWeb開発では以下のアプリケーションを立ち上げているので、HDD4台ぐらいでストライピングした構成でモニタしたかった。&lt;br /&gt;
　（Virtual Machine上のLinux1つ、Eclipse、Firefox、Chrome、Internet Explorer、Dreamweaver、Fireworks、Becky!）&lt;/li&gt;
&lt;li&gt;使っている、モニタと相性が悪いみたいで、正常に表示されなかった。　左右に黒帯が入って、横から圧縮された映像が表示されてしまう。&lt;/li&gt;
&lt;li&gt;SATAではなく、SASで試したかった。以前、DELLのSASx2 ストライピングを使っていたが、1.5倍ぐらいしか早くなかったのでLenovoマシーンでどのくらい速度が出るのか試してみたかった。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;参照&lt;/h2&gt;
&lt;p&gt;以下、ThinkStation S20について記載しているサイト。&lt;br /&gt;
&lt;a href=&quot;http://plusd.itmedia.co.jp/pcuser/articles/0907/14/news061.html&quot;&gt;http://plusd.itmedia.co.jp/pcuser/articles/0907/14/news061.html&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://journal.mycom.co.jp/articles/2009/05/25/s20/index.html&quot;&gt;http://journal.mycom.co.jp/articles/2009/05/25/s20/index.html&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://blogs.itmedia.co.jp/kichi/2010/06/thinkstation--3.html?ref=rssall&quot;&gt;http://blogs.itmedia.co.jp/kichi/2010/06/thinkstation--3.html?ref=rssall&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://fx-gp.seesaa.net/article/152279878.html&quot;&gt;http://fx-gp.seesaa.net/article/152279878.html&lt;/a&gt;　この方と同じ筐体です。&lt;/p&gt;
&lt;h2&gt;感想&lt;/h2&gt;
&lt;p&gt;家にモニタが無いのに、ワークステーションが届いて唖然としてしまった。。。自腹でタクシーを使い、会社まで輸送してベンチマーク取ってます！&lt;/p&gt;
</content:encoded></item><item><title>メールアドレスのドメイン部分をチェック</title><link>https://blog.teraren.com/posts/validate-domain-using-dns/</link><guid isPermaLink="true">https://blog.teraren.com/posts/validate-domain-using-dns/</guid><description>PHPでユーザ入力のメールアドレスのドメイン部分をDNSのMXレコード照会で検証するMailAddressValidatorクラスの実装例</description><pubDate>Fri, 28 May 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/15319336@N07/2060971239/&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/05/email.gif&quot; alt=&quot;email メールアドレスのドメイン部分をチェック&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ユーザが入力したメアドの検証をするために、アットマーク以降のドメイン部分を検証する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
/**
 * Validate the mail address
 *
 * @author Yuki Matsukura
 * @version $Id: a2b2c6ff3d160a4c91fb39a45c2a32af27867684 $
 */
class MailAddressValidator
{
  /**
   * Validate the mailaddress MX record.
   * - Call this method after validating e-mail regex check.
   * - throws exception if the error is occurred
   *
   * @param string $mail_address
   * @author Yuki Matsukura
   */
  public static function validateMX($mail_address)
  {
    if(preg_match(&apos;/@(.*)$/&apos;, $mail_address, $matches)){

      $domain = $matches[1];
      if(checkdnsrr($domain, &apos;MX&apos;) === true){
        return;
      }

      throw new Exception(sprintf(&apos;メールアドレスの@以降が間違っている可能性があります。(%s)&apos;, $mail_address));
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>qmail+vpopmailで存在しないアカウントをSMTPで拒否する方法</title><link>https://blog.teraren.com/posts/qmail-vpopmail-reject-unknown-accoun/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qmail-vpopmail-reject-unknown-accoun/</guid><description>qmail+vpopmailにchkuserパッチを適用し、存在しない宛先へのメールをSMTP段階で拒否する設定方法。スパムによるバウンスメール大量発生を防ぐパッチ適用手順と注意点を解説。</description><pubDate>Thu, 20 May 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/05/WS0708.jpg&quot; alt=&quot;WS0708 500x365 qmail+vpopmailで存在しないアカウントをSMTPで拒否する方法&quot; /&gt;&lt;/p&gt;
&lt;p&gt;qmailのqmail-smtpdは、ローカルにアカウントが存在しなくてもメールを受け取ってしまう。しかしながら、fromを偽装して送られるスパムのターゲットになってしまった場合は問題が起きるので、&lt;a href=&quot;http://www.interazioni.it/opensource/chkuser/&quot;&gt;chkuser&lt;/a&gt;パッチを適用してみた。日本での適応事例がなかったのでメモを残しておく。&lt;/p&gt;
&lt;p&gt;1通のメールから、これだけの処理が発生する。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;スパマーがFromをnon-existed@mydomain.jpに設定し、non-existed@targetdomain.jpへ配信した場合、エラーメールがnon-existed@mydomain.jpへ配信される。&lt;/li&gt;
&lt;li&gt;qmail-smtpdはnon-existed@mydomain.jpへ配送されたメールをlocal-queueに入れ、配信を試みるが存在しないからエラーメールを構築し、remote queueへ入れる。&lt;/li&gt;
&lt;li&gt;しかし、そのエラーメールの宛先は間違っているから配送できない。mailer-daemon@mydomain.jpへメールが送信されて終了&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;この処理を最小限にするためには（2）の段階で、qmail-smtpdがローカルに存在するメールアカウントをチェックしてrejectするのがベスト。これを実行するのが&lt;a href=&quot;http://www.interazioni.it/opensource/chkuser/&quot;&gt;chkuser&lt;/a&gt;パッチ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/uploads/2019/04/chkuser-2.0.9-release.patch&quot;&gt;/uploads/2019/04/chkuser-2.0.9-release.patch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;qmail周りのインストール方法をまとめると以下のようになる。パッチを適用の順番は重要です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tar zxvf qmail-1.03.tar.gz
$ cd qmail-1.03
$ patch &amp;lt; ../qmail-103.patch
$ patch &amp;lt; ../qmail-date-localtime.patch
$ patch &amp;lt; ../qmail-glibc.patch
$ patch &amp;lt; ../qmail-smtpd-relay-reject
$ patch &amp;lt; ../qmail-0.0.0.0.patch
$ cd ..
$ tar xzvf qmail-smtpd-auth-0.31.tar.gz
$ cd qmail-1.03
$ cp ../qmail-smtpd-auth-0.31/*.* ./
$ patch &amp;lt; auth.patch
$ patch -p1 &amp;lt; ../chkuser-2.0.9-release.patch
（qmail-smtpd-authのパッチとコンフリクトするので、適宜目で見て修正する。）
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# make setup
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;2010-05-20 15:46:27.267796500 CHKUSER rejected rcpt: from &amp;lt;derekdymond @learndirect.net::&amp;gt; remote &amp;lt;abts -North-Dynamic-085.59.163.122.airtelbroadband.in:unknown:122.163.59.85&amp;gt; rcpt &amp;lt;dolce @mydomain.jp&amp;gt; : not existing recipient
2010-05-20 15:46:28.956170500 CHKUSER rejected rcpt: from &amp;lt;holte @vazda.com::&amp;gt; remote &amp;lt;abts -North-Dynamic-085.59.163.122.airtelbroadband.in:unknown:122.163.59.85&amp;gt; rcpt &amp;lt;dolce @mydomain.jp&amp;gt; : not existing recipient
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>位置情報付きFacebook Likeボタン</title><link>https://blog.teraren.com/posts/facebook-like-button-with-location/</link><guid isPermaLink="true">https://blog.teraren.com/posts/facebook-like-button-with-location/</guid><description>位置情報付きFacebook Likeボタン</description><pubDate>Tue, 11 May 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/05/WS0698.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/05/WS0698.jpg&quot; alt=&quot;WS0698 位置情報付きFacebook Likeボタン&quot; title=&quot;WS0698&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://matsu.teraren.com/static/20100509-takaosan/&quot;&gt;高尾山登山の行動履歴ページ&lt;/a&gt;に位置情報のメタ情報付きLikeボタンを設置してみた。&lt;/p&gt;
&lt;p&gt;likeボタン押しても、自分のactivity feedの一番上には表示されず、feedの下の方に表示される↓&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2010/05/WS0699.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/05/WS0699.jpg&quot; alt=&quot;WS0699 500x381 位置情報付きFacebook Likeボタン&quot; title=&quot;WS0699&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;位置情報も露出していないみたいです。&lt;/p&gt;
&lt;p&gt;裏でどんな通信が行われているかを見てみた↓&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2010/05/WS0700.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/05/WS0700.jpg&quot; alt=&quot;WS0700 500x156 位置情報付きFacebook Likeボタン&quot; title=&quot;WS0700&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;主な情報は、ボタンを押したURLとlikeボタンが押されたのか、解除されたのかのフラグだけ。非同期でfacebookからページの情報をクロールしているのみたい。&lt;/p&gt;
</content:encoded></item><item><title>ロードバイクメンテナンス</title><link>https://blog.teraren.com/posts/road-bike-maintenance/</link><guid isPermaLink="true">https://blog.teraren.com/posts/road-bike-maintenance/</guid><description>タイヤ・ブレーキシュー交換から変速機調整まで、ロードバイクのメンテナンス作業とパーツ選びの実体験レポート</description><pubDate>Thu, 06 May 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/05/4580525059_f9f802933a_o.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/05/4580525059_f9f802933a_o.jpg&quot; alt=&quot;4580525059 f9f802933a o 500x375 ロードバイクメンテナンス&quot; title=&quot;canonndale R700&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最高気温が２０度以上にならないと自転車に乗らないライダーです。&lt;br /&gt;
最近暖かくなってきたので、みなさんもきっちりメンテナンスしてサイクリングシーズンに備えてみてはいかがでしょうか？&lt;/p&gt;
&lt;p&gt;今日は半日かかってメンテナンスしました。&lt;/p&gt;
&lt;p&gt;まず、直さないといけないと思っていたところ：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2.5年前に交換したリアタイアの側面にひび割れがでてきたのと、急制動のかけすぎで表面にスリットが入ってるし、設置面積が多くなってきて交換したかった。&lt;/li&gt;
&lt;li&gt;ギアが入りづらかった。フロントディレーラー、リアディレーラーともがつんと変速できなくなってきた。&lt;/li&gt;
&lt;li&gt;雨に何回か降られたので、油や泥でフレームが汚い・・・&lt;/li&gt;
&lt;li&gt;雨の日に乗ったので、ブレーキシューに金属カスが溜まってブレーキが効きづらくなってきた。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;こうもやりたいことが溜まってしまうとどんどん腰が重くなるばかりでなかなか手をつけていませんでした。&lt;/p&gt;
&lt;p&gt;まず、パーツ選びが結構大変。自転車パーツはいろんなメーカーからたくさん出ているし、値段と性能が比例していないものも多いので選定が結構大変でした。お店行ったり、Webで調べたりして結局以下のものを買いました。&lt;/p&gt;
&lt;h2&gt;タイヤx2&lt;/h2&gt;
&lt;p&gt;::amazon{asin=&quot;B003UCK13G&quot;}&lt;/p&gt;
&lt;h2&gt;ブレーキシュー(リアだけ減っていたので)&lt;/h2&gt;
&lt;p&gt;::amazon{asin=&quot;B000NORMUY&quot;}&lt;/p&gt;
&lt;p&gt;選定基準：&lt;br /&gt;
タイヤは、今までストラディアスエリート 700X23Cを使っていたのですが、雨の日には乗らないし、このシリーズ特有であるストロングコード仕様が厄介でシマノの完組ホイールに装着するにはかなり時間がかかるから、よりレース仕様のグレードを選んでみました。&lt;/p&gt;
&lt;p&gt;ブレーキシューは、いつものようにDURA-ACEのシュー。100円ショップで買った2mmのアーレンキーで回したら、ねじ山は切れるわ、アーレンキー自体もイかれるわぁでどうしようもないアーレンキーでした。これにより、工具の大事さを知りました。&lt;/p&gt;
&lt;p&gt;メンテナンス内容：&lt;br /&gt;
タイヤを前後取替え、ブレーキシュー取替え、ブレーキのセンター出し、クリーニング、ショップで変速機の調整。&lt;/p&gt;
&lt;p&gt;そして、お店で立ち読みして見つけたんだけどこの本がすごいよかった。ロードバイクのメンテナンス本って絵が少なかったり的確な説明がされていないのが多いのですが、この本は完璧。&lt;br /&gt;
メンテナンスに関してはこの本だけでいいのではないかと思う。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;488393344X&quot;}&lt;/p&gt;
&lt;p&gt;—&lt;br /&gt;
追記 2010/5/15&lt;br /&gt;
さすがに、1段階レース向けに近いタイヤを選んだだけあって、転がり抵抗が少ない！5～10%ぐらい多く進むようになった！&lt;/p&gt;
&lt;p&gt;あと、低速での安定感が減った。安定感と転がり抵抗の削減はトレードオフ。&lt;/p&gt;
</content:encoded></item><item><title>kmemsizeをnagiosで監視</title><link>https://blog.teraren.com/posts/kmemsize-nagios/</link><guid isPermaLink="true">https://blog.teraren.com/posts/kmemsize-nagios/</guid><description>VPSのOpenVZ環境でkmemsizeオーバーによるOSダウンを防ぐため、/proc/user_beancountersをPerlスクリプトでnagios監視する方法</description><pubDate>Fri, 23 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/04/kmemsize.png&quot; alt=&quot;kmemsize 500x49 kmemsizeをnagiosで監視&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/kmemsize/&quot;&gt;VPSで運用している環境にて、kmemsizeの制約にひっかかり、いきなりOSが止まってしまいました。&lt;/a&gt;&lt;br /&gt;
それを回避するためにnagiosでこのkmemsizeを監視するスクリプトを書きました。&lt;/p&gt;
&lt;p&gt;kmemsizeは/proc/user_beancountersに仮想ファイルとして出力されています。&lt;br /&gt;
このファイルはrootしか読めないため、/etc/sudoersへnagiosを実行しているユーザを追加する必要があります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/perl
use strict;

## add following lines to /etc/sudoers
# Defaults:nagios !requiretty
# nagios ALL=(ALL) NOPASSWD: /bin/cat

my $CRITICAL = 0.8;
my $WARNING = 0.7;

my $kmem_line = `sudo cat /proc/user_beancounters 2&amp;gt; /dev/null  | grep kmem`;
chomp $kmem_line;

$kmem_line =~ /([0-9]+) +([0-9]+) +([0-9]+) +([0-9]+)/;

my $current_kmemsize = $1;
my $max_kmemsize = $4;

my $status = &quot;OK&quot;;
if($max_kmemsize * $CRITICAL &amp;lt; $current_kmemsize){
  $status = &quot;CRITICAL&quot;;
}elsif($max_kmemsize * $WARNING &amp;lt; $current_kmemsize){
  $status = &apos;WARNING&apos;;
}

print $status;
print &quot; - &quot;;
print $current_kmemsize;
print &quot; | &quot;;
print $kmem_line;
print &quot;\n&quot;;
exit(0);
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>facebookのlikeボタン</title><link>https://blog.teraren.com/posts/wordpress-facebook-like/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-facebook-like/</guid><description>facebookのlikeボタン</description><pubDate>Fri, 23 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/04/facebook.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/04/facebook.png&quot; alt=&quot;facebook 500x219 facebookのlikeボタン&quot; title=&quot;facebook&quot; /&gt;&lt;/a&gt; Facebookに新機能が追加された。&lt;br /&gt;
その名は、「&lt;strong&gt;Like Button&lt;/strong&gt;」。&lt;br /&gt;
&lt;a href=&quot;http://developers.facebook.com/docs/reference/plugins/like&quot;&gt;http://developers.facebook.com/docs/reference/plugins/like&lt;/a&gt; このボタンはただのボタンではなく、ページ作成者がページのコンテクストをあらかじめ設定しておける。もし、facebookユーザがこのボタンを押すとこのコンテクストがfacebook側で利用され、ユーザのインタレストグラフを構築するための材料となる。 今まで机上の空論かと考えていた&lt;a href=&quot;http://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%9E%E3%83%B3%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A6%E3%82%A7%E3%83%96&quot;&gt;セマンティックウェブ&lt;/a&gt;を実現するための大きな一歩となるサービス。 早速試してみた。&lt;br /&gt;
&lt;a href=&quot;http://www.facebook.com/&quot;&gt;Facebook&lt;/a&gt;に一度ログインしてから、このページを見ると下の方にボタンが表示されるはず。 WordPress用のLike Buttonプラグインはこちらからダウンロードできる。&lt;br /&gt;
activateしたら、自動的に各postの下部に写真のようなボタンが付く。&lt;br /&gt;
&lt;a href=&quot;http://blog.bottomlessinc.com/wp-content/uploads/2010/04/like.zip&quot;&gt;Facebook Like WordPress Plugin v1.0&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>kmemsize</title><link>https://blog.teraren.com/posts/kmemsize/</link><guid isPermaLink="true">https://blog.teraren.com/posts/kmemsize/</guid><description>VPS上でkmemsizeの上限に達してOSが停止した事例を解説。CPIの制限値32MBと使用率確認コマンド、muninグラフを用いた監視方法を紹介</description><pubDate>Thu, 22 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/04/WS0694.jpg&quot; alt=&quot;WS0694 500x47 kmemsize&quot; /&gt;&lt;/p&gt;
&lt;p&gt;kmemsize&lt;/p&gt;
&lt;p&gt;VPS上のOSがいきなり止まったから原因を調べたら、VPSで割り当てられているkmemsizeがリミットに達したからだった。&lt;br /&gt;
物理メモリ使用量や、プロセス数はさほど多くないのにkmemsizeのリミットに引っかかるとは。。。意外な落とし穴だった。&lt;/p&gt;
&lt;p&gt;CPIでは、32MB割り当てられている。VPSのサービス内容を見てみるとkmemsizeは必ず示されて居るぐらい重要な指標みたい。&lt;/p&gt;
&lt;p&gt;nagiosの監視項目に追加しておかなきゃです。&lt;/p&gt;
&lt;p&gt;CPIでは、このトラブルが起きた時にはParallelsからコンテナ（VPS上の仮想OS）の再起動を手動で実行する必要があります。&lt;/p&gt;
&lt;p&gt;この事に関して、CPIの回答は消極的。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;kmemsizeの制限にかかった際にOSが停止したようであるとの事ですが、&lt;br /&gt;
そのような場合にコンテナを再起動するような設定はいたしかねます。&lt;/p&gt;
&lt;p&gt;尚、リソースを多く使用するプログラム等を設置されている場合は、&lt;br /&gt;
お客様にてプログラムの見直しを行っていただきますよう&lt;br /&gt;
お願い申し上げます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/04/Processes.png&quot; alt=&quot;Processes kmemsize&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下に、kmemsizeがリミットに達した時の物理メモリ容量とプロセス数のmuninグラフを添付しておきます。これじゃ、物理メモリを1GBも使い切れないじゃん！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/04/Memory-usage.png&quot; alt=&quot;Memory usage kmemsize&quot; /&gt;&lt;/p&gt;
&lt;p&gt;何パーセント消費されているか表示するコマンド&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# cat /proc/user_beancounters|grep kmemsize | gawk &apos;{ print $3/$5; }&apos;
0.989777
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>@softbank.ne.jpと@i.softbank.jp</title><link>https://blog.teraren.com/posts/softbank-ne-jp-i-softbank-jp/</link><guid isPermaLink="true">https://blog.teraren.com/posts/softbank-ne-jp-i-softbank-jp/</guid><description>@softbank.ne.jpと@i.softbank.jp</description><pubDate>Sun, 18 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Webサイトで、メアドの入力をさせると、iphoneユーザへのメール到達率が低い。なぜなら、ソフトバンクがわかりづらいメールアドレスを発行しているから。以下にまとめます。&lt;/p&gt;
&lt;h2&gt;@softbank.ne.jp&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;一部のiphoneユーザ。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ガラケー。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;@i.softbank.jp&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;iphoneユーザ全て。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;参考：&lt;a href=&quot;http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1132755386?fr=diff_chie_detail&quot;&gt;http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1132755386?fr=diff_chie_detail&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>STOP: 0x0000007f (0×00000000, 0×00000000, 0×00000000, 0×00000000)</title><link>https://blog.teraren.com/posts/stop-0x0000007f-0x00000000-0x00000000-0x00000000-0x00000000/</link><guid isPermaLink="true">https://blog.teraren.com/posts/stop-0x0000007f-0x00000000-0x00000000-0x00000000-0x00000000/</guid><description>STOP: 0x0000007f (0×00000000, 0×00000000, 0×00000000, 0×00000000)</description><pubDate>Fri, 02 Apr 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/04/20100402-123304.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/04/20100402-123304.jpg&quot; alt=&quot;20100402 123304 500x375 STOP: 0x0000007f (0x00000000, 0x00000000, 0x00000000, 0x00000000)&quot; title=&quot;STOP: 0x0000007f (0x00000000, 0x00000000, 0x00000000, 0x00000000)&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;STOP: 0x0000007f (0x00000000, 0x00000000, 0x00000000, 0x00000000)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;STOP: 0x0000007f (0×00000000, 0×00000000, 0×00000000, 0×00000000)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;今使っているThinkpad T60で以下の状況が発生した。&lt;br /&gt;
みなさんは何が問題だと思いますか？&lt;/p&gt;
&lt;p&gt;・Windows起動途中にブルースクリーンになって上記のエラーが発生した。&lt;br /&gt;
・Windowsを再インストールしようとしたが、インストール途中にブルースクリーン。&lt;br /&gt;
・Knoppixは正常に動く。&lt;br /&gt;
・memtest86+ではエラー無し。&lt;br /&gt;
・PC Doctorでエラー無し。&lt;/p&gt;
&lt;p&gt;答えは、PCカードに刺さっているメモリアダプタ。&lt;br /&gt;
5年以上前のTDK製。&lt;/p&gt;
</content:encoded></item><item><title>torne用外付けHDD増設</title><link>https://blog.teraren.com/posts/2010-03-25-tornekehdd/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2010-03-25-tornekehdd/</guid><description>PS3 torne用に2TB外付けHDDを約15,000円で増設した記録。HDDケースの選定基準、FAT32フォーマット手順、放熱対策まで実践的にまとめた。</description><pubDate>Thu, 25 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/03/4460100210_6ae0bb4951_b.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;torneでテレビを録画すると1時間6GBも消費するので2TBのHDDを増設！2TBだと13日以上連続して録画できる量！&lt;/p&gt;
&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;必要なものは、ハードディスクとハードディスクケースだけ。&lt;/p&gt;
&lt;p&gt;以下の製品を買って、正常動作を確認しました！&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0034KXVDQ&quot;}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;トータル約15,000円。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;ハードディスク選定基準&lt;/h2&gt;
&lt;p&gt;最近はハードディスクが安くて、2TBで1万3000円ぐらいで買えてしまう。。。&lt;/p&gt;
&lt;p&gt;相性確認は&lt;a href=&quot;http://torne.jpn.org/index.php?FAQ/HDD%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D&quot;&gt;こちら&lt;/a&gt;を見るのが良い。&lt;/p&gt;
&lt;p&gt;Western Digital WD20EARSは動作音が静かで、低温でよさそうだが、正常に動作しない報告が多いから避けた方がいい。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0042A9KZA&quot;}&lt;/p&gt;
&lt;h2&gt;ハードディスクケース&lt;/h2&gt;
&lt;p&gt;購入条件は、安くて電源がPS3本体と連動し、放熱性に優れていて、ケースとねじ留めできてしっかり固定できるか。&lt;/p&gt;
&lt;p&gt;そして、2ch wikiで動作確認が取れていること。&lt;/p&gt;
&lt;p&gt;↓&lt;strong&gt;玄人志向 GW3.5AI-SU3/SW は買ってはいけない。&lt;/strong&gt;&lt;br /&gt;
ハードディスクとケースの固定がねじ留めでないため、コネクタが自然に外れたりして、接触不良が起きやすい。&lt;/p&gt;
&lt;p&gt;2台の新品を試してみたが動作が安定しなかった。（1台買って、初期不良でもう1台使ってみたが、正常動作しない）&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B0034KXVDQ&quot;}&lt;/p&gt;
&lt;h2&gt;フォーマット&lt;/h2&gt;
&lt;p&gt;PS3は外付けHDDをフォーマットする機能がないので、買ってきたHDDをそのままPS3に刺しても使えない！&lt;/p&gt;
&lt;p&gt;PCでFAT32形式でフォーマットしてから、PS3に刺す。&lt;/p&gt;
&lt;p&gt;Windows XPでは32GB以上のHDDをFAT32でフォーマットできないので、専用ツールを使っておこなう。これでクイックフォーマットをすれば1分ぐらいで終わる。フルフォーマットする必要なんて無し。&lt;br /&gt;
&lt;a href=&quot;http://www.vector.co.jp/soft/winnt/util/se443311.html&quot;&gt;Fat32Formatter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ちなみに、クイックフォーマットじゃないと、2TBだと6時間ほどかかるらしい。クイックフォーマットだと30秒ぐらい。&lt;/p&gt;
&lt;h2&gt;PS3側でのtorne設定&lt;/h2&gt;
&lt;p&gt;ハードディスクケースにハードディスクを入れて、PS3に刺すだけではtorneでは利用できない。&lt;br /&gt;
PS3にHDDを刺した後、torneを立ち上げて設定からHDDを登録する必要がある。&lt;/p&gt;
&lt;h2&gt;設置したところ&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/03/R0011468.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;夏は、外付けHDDのケースがすんごく暑くなります！USBで動く扇風機や冷却ボード必須です！&lt;br /&gt;
稼働中はとても熱くて素手で10秒触れません。。。。&lt;/p&gt;
&lt;p&gt;私は、秋葉原でアルミのヒートシンクを買って、ケースにボンドでがっつりくっつけました。&lt;br /&gt;
また、USBから電源をとる冷却ファンを1400円で買って、風を送るようにしてあります。&lt;/p&gt;
&lt;h2&gt;その他の選択肢&lt;/h2&gt;
&lt;p&gt;以下の既製品を買ってつなげばできます。値段は約19000円なのでこの記事で紹介するやり方よりかは3割ほど高くつく。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B00FR86SGK&quot;}
torneを安く買う方法はこちら。&lt;a href=&quot;http://gigazine.net/index.php?/news/comments/20100807_ps3_torne/&quot;&gt;http://gigazine.net/index.php?/news/comments/20100807_ps3_torne/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>PHPでXML-RPC</title><link>https://blog.teraren.com/posts/php-xml-rpc/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-xml-rpc/</guid><description>ブログ更新をGoogleやBingなどの検索エンジンにXML-RPCで通知するPHPコードをPEAR XML_RPC2で実装する方法</description><pubDate>Fri, 12 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/03/doodle4.png&quot; alt=&quot;doodle4 PHPでXML RPC&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Blog記事の更新をサーチエンジンなどに通知するXML RPCをPHPで実装する方法を紹介します。&lt;/p&gt;
&lt;p&gt;まず、weblogUpdates.pingの仕様。&lt;br /&gt;
&lt;a href=&quot;http://www.xmlrpc.com/weblogsCom&quot;&gt;http://www.xmlrpc.com/weblogsCom&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;weblogUpdates.ping (weblogname, weblogurl, changesurl=weblogurl, categoryname=&quot;none&quot;) returns struct
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ちなみに、weblogUpdates.extendedPingというpingより多くの必須パラメータがあるインターフェイスも存在する。&lt;br /&gt;
pingで事足りるのでpingだけを実装。&lt;br /&gt;
&lt;a href=&quot;http://weblogs.com/api.html#5&quot;&gt;http://weblogs.com/api.html#5&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PHPでXML-RPCを扱うためには、PEARのXML_RPC2を使うのが便利。APIの設計は綺麗で使いやすい。&lt;/p&gt;
&lt;p&gt;以下にコード書いておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
require_once(&apos;XML/RPC2/Client.php&apos;);

$blog_title = &apos;おれのブログ&apos;;
$blog_url = &apos;https://matsu.teraren.com/&apos;;

$url_array = array(
 &apos;http://www.google.com/webmasters/tools/ping&apos;
,&apos;http://search.yahooapis.com/SiteExplorerService/V1/ping&apos;
,&apos;http://www.bing.com/webmaster/ping.aspx&apos;
,&apos;http://submissions.ask.com/ping&apos;
);

$options = array(
    &apos;prefix&apos; =&amp;gt; &apos;weblogUpdates.&apos;
);

$call_option = array(
    $blog_title
  , $blog_url
);

foreach($url_array as $url){

  try{
    $client = XML_RPC2_Client::create($url, $options);
    $result = $client-&amp;gt;remoteCall___(&apos;ping&apos;, $call_option);

    if($result[&apos;flerror&apos;]){
      // goo returns error but message says success.
      if(strpos($result[&apos;message&apos;], &apos;Thanks for the ping.&apos;) === false){
        throw new UnexpectedValueException($result[&apos;message&apos;]);
      }
    }

  }catch(UnexpectedValueException $e){
    trigger_error($url.&quot;\n\n&quot;.print_r($e, true), E_USER_NOTICE);
  }catch(XML_RPC2_Exception $e){
    trigger_error($url.&quot;\n\n&quot;.print_r($e, true), E_USER_NOTICE);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pingサーバは使えなくなる場合が多いので、例外はしっかりハンドリングしておく。半年前の&lt;a href=&quot;http://www.koekatamarin.com/ping/index.php?%B9%B9%BF%B7Ping%A5%EA%A5%B9%A5%C8%A1%CA20%A5%B3%B8%B7%C1%AA%A1%CB&quot;&gt;厳選20サーバ&lt;/a&gt;中、半分以上が存在していない状態でした。&lt;/li&gt;
&lt;li&gt;レスポンスのフォーマットが仕様通りじゃない&lt;/li&gt;
&lt;li&gt;ブログタイトルにマルチバイトを含むときはUTF-8に変換して送る処理を入れてね。または、UTF8で書く。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>AndroidのSlideScreen</title><link>https://blog.teraren.com/posts/android-slidescreen/</link><guid isPermaLink="true">https://blog.teraren.com/posts/android-slidescreen/</guid><description>AndroidのSlideScreen</description><pubDate>Mon, 08 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/03/4393915453_15bc0b5254_b.jpg&quot; alt=&quot;4393915453 15bc0b5254 b 332x500 AndroidのSlideScreen&quot; /&gt;&lt;/p&gt;
&lt;p&gt;SlideScreenというhigh qualityなホームスクリーンをインストールしてみた。ユーザビリティはいまいちだけど、かっこいい！とにかく、かっこいい！&lt;/p&gt;
&lt;p&gt;Androidアプリは審査がないのでクウォリティが低いアプリが乱発されることを懸念していたけど、このアプリが登場したのを見てAndroidの未来が明るいことを感じた。&lt;/p&gt;
&lt;p&gt;ダウンロードはこちら。&lt;br /&gt;
&lt;a href=&quot;http://slidescreenhome.com/&quot;&gt;http://slidescreenhome.com/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>HT-03aテザリング可能</title><link>https://blog.teraren.com/posts/ht-03a-tethering/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ht-03a-tethering/</guid><description>HT-03aテザリング可能</description><pubDate>Mon, 08 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/03/doodle3.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/03/doodle3.png&quot; alt=&quot;ht-03a bill&quot; title=&quot;bill&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;どうやら、HT-03aでテザリングした分のパケット料は、Bizホーダイに含まれていた模様。&lt;/p&gt;
&lt;p&gt;テストのために3月頭に、30分ぐらい。20MBほど通信しました。もし、Bizホーダイに含まれていない場合は、32,768円になってたはず。&lt;/p&gt;
&lt;p&gt;想定環境：&lt;br /&gt;
&lt;a href=&quot;http://www.nttdocomo.co.jp/service/world/roaming/outline/data_packet.html&quot;&gt;0.2円／パケット&lt;/a&gt; (1パケット=128バイト)&lt;br /&gt;
上記の請求予定書は3月7日までの情報。&lt;/p&gt;
&lt;p&gt;PDANetのインストール方法はこちらを参照。簡単なので10分ぐらいでできると思います。&lt;br /&gt;
PDANetはrootを必要としないので、公式ROMでテザリングできちゃいます。&lt;br /&gt;
&lt;a href=&quot;http://ht-03a.windows-keitai.com/?HT-03A/%E3%82%88%E3%81%8F%E3%81%82%E3%82%8B%E8%B3%AA%E5%95%8F/%E3%83%86%E3%82%B6%E3%83%AA%E3%83%B3%E3%82%B0&quot;&gt;http://ht-03a.windows-keitai.com/?HT-03A/%E3%82%88%E3%81%8F%E3%81%82%E3%82%8B%E8%B3%AA%E5%95%8F/%E3%83%86%E3%82%B6%E3%83%AA%E3%83%B3%E3%82%B0&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Chromeの広告ブロッカー</title><link>https://blog.teraren.com/posts/chrome-ad-block/</link><guid isPermaLink="true">https://blog.teraren.com/posts/chrome-ad-block/</guid><description>Chromeの広告ブロッカー</description><pubDate>Tue, 02 Mar 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/03/doodle2.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/03/doodle2.png&quot; alt=&quot;doodle2 500x156 Chromeの広告ブロッカー&quot; title=&quot;doodle&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;メインブラウザをChromeに変更してから、広告が目に付く。。。。なぜかというと、Firefoxでは広告ブロックするアドオンを入れていたが、Chromeでは入れていなかった。&lt;/p&gt;
&lt;p&gt;そこで、以下の拡張（Extension）をインストールした。&lt;br /&gt;
&lt;a href=&quot;https://chrome.google.com/extensions/detail/gighmmpiobklfepjocnamgkkbiglidom?hl=ja&quot;&gt;AdBlock&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;これは、かなり使える！インストール後は、オプションを開いて日本向けの広告プロファイルにチェックを入れる必要がある。&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2010/03/doodle1.png&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/03/doodle1.png&quot; alt=&quot;doodle1 Chromeの広告ブロッカー&quot; title=&quot;japanese filters&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;そして、Yahooやmixiを開いてみると、広告が一気になくなった！すごい！！&lt;/p&gt;
&lt;p&gt;自分で、楽天アフィリエイトなどをやっていると、アフィリエイトの管理画面が崩れてしまうので、ホワイトリストに追加してあげましょう。&lt;br /&gt;
今開いているURLをホワイトリストへ追加するためには、&lt;code&gt;Ctrl + Shift + L&lt;/code&gt; を押すとホワイトリストへ追加できる。&lt;/p&gt;
&lt;p&gt;より一段と快適になりました！&lt;/p&gt;
</content:encoded></item><item><title>Beckyのスプラッシュ画像を消す</title><link>https://blog.teraren.com/posts/becky-remove-splash-image/</link><guid isPermaLink="true">https://blog.teraren.com/posts/becky-remove-splash-image/</guid><description>Beckyのスプラッシュ画像を消す</description><pubDate>Sat, 20 Feb 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2010/02/becky.gif&quot;&gt;&lt;img src=&quot;../../assets/uploads/2010/02/becky.gif&quot; alt=&quot;becky 500x364 Beckyのスプラッシュ画像を消す&quot; title=&quot;becky&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Becky!が起動するときに表示されるスプラッシュウィンドウを消す方法。&lt;/p&gt;
&lt;p&gt;スプラッシュ画像は340KBのビットマップ形式の画像である。起動のたびにこの無駄な画像を表示している！その無駄な画像を表示するがためにBecky本体の起動が遅くなってしまう。&lt;/p&gt;
&lt;p&gt;このスプラッシュウィンドウを消すためには、インストールされたディレクトリにある画像を消すだけでOK！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;C:\Program Files\RimArts\B2\B2default.bmp&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上記のファイルを消すバッチファイルを用意したので、以下からダウンロードしてダブルクリックすれば完了！（セキュリティソフトにアラーと出されるかも。。。）&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://matsu.teraren.com/static/delete_b2_splash.bat&quot;&gt;&lt;strong&gt;delete_b2_splash.bat ダウンロード&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>WordPressの高クオリティテーマ、Mystiqueの日本語版作りました</title><link>https://blog.teraren.com/posts/mystique-wordpress-japanese/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mystique-wordpress-japanese/</guid><description>WordPressの高クオリティテーマ、Mystiqueの日本語版作りました</description><pubDate>Fri, 05 Feb 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/02/WS0666.jpg&quot; alt=&quot;Mystique - WordPress theme&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WordPressのテーマである&lt;a href=&quot;http://digitalnature.ro/projects/mystique/&quot;&gt;Mystique&lt;/a&gt;の日本語設定ファイルを作りました。&lt;br /&gt;
&lt;a href=&quot;http://github.com/downloads/matsubo/Mystique-Japanese-Edition/mystique.zip&quot;&gt;Mystique日本版ダウンロード&lt;/a&gt; （解凍後は、mystiqueにディレクトリ名を変更してください） (&lt;a href=&quot;http://github.com/matsubo/Mystique-Japanese-Edition&quot;&gt;github&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Mystiqueテーマは現時点で最高のテーマです！主な機能はTwitter連携や言語ファイルの分割、ウィジェット利用可能、オリジナルCSSの編集などをWordPressの管理画面から行えます。とてもフレキシブルです。このBlogで使っているテーマです。&lt;/p&gt;
&lt;p&gt;難点は、ウィジェットをたくさん付けるとページの表示が遅くなってしまう点です。WP-Super-Cacheなどのページ表示をキャッシュするプラグインを併用した方がいいと思います。&lt;/p&gt;
&lt;p&gt;日本語の言語ファイルが付属していないので、作成して再配布します。テーマの作成者には日本語の言語ファイルを含めていただけるように連絡してあります。&lt;br /&gt;
ライセンスはGPL3だったので、GPL3に準拠して公開します。配布元のバージョンはMystique 1.7.2です。それに日本語の言語ファイルを追加して再配布しています。&lt;/p&gt;
&lt;p&gt;言語ファイルの共同編集者はこちらにて参加して、修正を行えます。&lt;br /&gt;
&lt;a href=&quot;http://github.com/matsubo/Mystique-wordpress-translation&quot;&gt;http://github.com/matsubo/Mystique-wordpress-translation&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>tokyotyrantをdaemontoolsで管理</title><link>https://blog.teraren.com/posts/tokyotyrant-daemontools/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tokyotyrant-daemontools/</guid><description>tokyotyrantをdaemontoolsで管理</description><pubDate>Fri, 05 Feb 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;runファイルのサンプルを掲載します。
必ずオプションを確認して各自にあった設定に変更してください。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh

PATH=$PATH:/usr/local/bin
basedir=&quot;/path/to/datadir&quot;
configdir=&quot;/path/to/luadir&quot;

exec 2&amp;gt;&amp;amp;1
exec envuidgid daemon softlimit -d300000 \
ttserver -port 1978  \
-host 127.0.0.1 \
-ulog $basedir/ulog \
-sid 1 \
-ext $configdir/ttexpire.lua  -extpc expire 600 \
-thnum 2 \
$basedir/casket.tct#idx=e:desc#dfunit=8
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>MySQLクイックチューニング</title><link>https://blog.teraren.com/posts/mysql-quick-tuning/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-quick-tuning/</guid><description>MySQLクイックチューニング</description><pubDate>Tue, 19 Jan 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;mysqlのパラメータチューニングをある程度おおざっぱに行うスクリプトを発見。&lt;br /&gt;
一言で言えば、&lt;strong&gt;10分である程度チューニングできる！&lt;/strong&gt;&lt;br /&gt;
&lt;a href=&quot;http://blog.mysqltuner.com/&quot;&gt;http://blog.mysqltuner.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/01/WS0656.jpg&quot; alt=&quot;WS0656 500x481 MySQLクイックチューニング&quot; /&gt;&lt;/p&gt;
&lt;p&gt;mysqltuner実行画面&lt;/p&gt;
&lt;p&gt;使い方は至って簡単、ダウンロードして実行するだけ。&lt;br /&gt;
実行すると、MySQLへのログインIDとパスワードが聞かれる。入力すると、MySQLのステータスや変数、物理メモリ容量をチェックされ、その環境に合ったパラメータを提案してくれる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget http://mysqltuner.com/mysqltuner.pl
% perl mysqltuner.pl
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;適当に運用している環境ではすごい楽。デフォルトのmy.cnfでは物足りないけど、パラメータチューニングをExcelを使って統計情報を元にチューニングするのは面倒という人向け。&lt;br /&gt;
24時間以上運用していないと統計値が収束しないので、ある程度運用してから実行した方がいいです。&lt;/p&gt;
</content:encoded></item><item><title>CPAN初期設定</title><link>https://blog.teraren.com/posts/cpan-setting/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cpan-setting/</guid><description>CPAN初期設定</description><pubDate>Mon, 18 Jan 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair &lt;em&gt;/}
install Bundle::CPAN しろと言われたけど、接続できない 凸(｀、´メ）
{/&lt;/em&gt; textlint-enable ja-technical-writing/no-unmatched-pair */}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/01/WS0652.jpg&quot; alt=&quot;WS0652 468x500 CPAN初期設定&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下のようにして、&lt;a href=&quot;http://www.cpan.org/SITES.html&quot;&gt;ミラーサイト&lt;/a&gt;を追加してあげる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo cpan
&amp;gt; o conf urllist push ftp://ftp.kddilabs.jp/CPAN/
&amp;gt; o conf commit
&amp;gt; install Bundle::CPAN
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>SSHトンネルが切れる</title><link>https://blog.teraren.com/posts/ssh-tunnel/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ssh-tunnel/</guid><description>SSHトンネルが切れる</description><pubDate>Fri, 15 Jan 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;MySQLの接続をSSHトンネルしているといつの間にかリモートホストに切断されているときがある。&lt;br /&gt;
そんなときは、serveraliveintervalオプションを設定して接続する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% /usr/bin/ssh -o serveraliveinterval=60 -N -L 3306:localhost:3306 remotehost
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;もしくはリモートホストの/etc/ssh/sshd_configに以下を追加して、sshdを再起動すればKeepaliveを設定できる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;KeepAlive yes
ClientAliveInterval 60
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;参考文献&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://madphilosopher.ca/2005/07/an-ssh-keep-alive-tip/&quot;&gt;http://madphilosopher.ca/2005/07/an-ssh-keep-alive-tip/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://slashdot.jp/~gm300/journal/451300&quot;&gt;http://slashdot.jp/~gm300/journal/451300&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>YMC vs CPI</title><link>https://blog.teraren.com/posts/ymc-vs-cpi/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ymc-vs-cpi/</guid><description>VPSサービスYMCとCPIのHTTPレスポンス性能をApache Benchで比較した結果、CPIがYMCより4.7倍高速だった検証記録</description><pubDate>Thu, 07 Jan 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;YMC vs CPI&lt;/p&gt;
&lt;p&gt;VPSのbenchmark。&lt;br /&gt;
目的：ネットワーク帯域など、クライアントから見たHTTPのレスポンス性をチェックする。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;測定環境&lt;/strong&gt;&lt;br /&gt;
apache上げて単純なHTMLファイルの転送。&lt;/p&gt;
&lt;p&gt;ファイルの内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;It works!&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;apache benchのオプション：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% /usr/local/apache2/bin/ab -n 1000 -c 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://www.ymc.ne.jp/service/custom/&quot;&gt;YMC&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Requests per second:    34.84 [#/sec] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://www.scalable.jp/&quot;&gt;CPI&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Requests per second:    163.67 [#/sec] (mean)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;結果&lt;/strong&gt;&lt;br /&gt;
4.7倍 CPIが高速！&lt;/p&gt;
</content:encoded></item><item><title>git1.6 install</title><link>https://blog.teraren.com/posts/git1-6-install/</link><guid isPermaLink="true">https://blog.teraren.com/posts/git1-6-install/</guid><description>git 1.6をソースからビルドする際にGUI関連のTcl/Tkコンパイルエラーが発生する場合の--without-tcltk オプションを使った回避方法</description><pubDate>Wed, 06 Jan 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;環境によってはインストールオプションが必要みたい。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget http://kernel.org/pub/software/scm/git/git-1.6.6.tar.bz2
./configure
make
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;とすると、
こんなエラーが出て、makeが出て止まる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    BUILTIN git-repo-config
    BUILTIN git-show
    BUILTIN git-status
    BUILTIN git-whatchanged
    SUBDIR git-gui
GITGUI_VERSION = 0.10.2
    * new locations or Tcl/Tk interpreter
    GEN git-gui
    INDEX lib/
    * tclsh failed; using unoptimized loading
    MSGFMT    po/de.msg make[1]: *** [po/de.msg] Error 127
make: *** [all] Error 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;gettextもtclも入っている。
おそらくGUI関連のバイナリも作ろうとしているので、configureを以下のようにして回避。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./configure --without-tcltk
make
sudo make install
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>IX2015設定ファイルダンプ</title><link>https://blog.teraren.com/posts/ix2015-backup-file/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ix2015-backup-file/</guid><description>IX2015設定ファイルダンプ</description><pubDate>Tue, 05 Jan 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;IX2015 設定サンプル&lt;/p&gt;
&lt;p&gt;IX2015の設定ファイルコピペ。&lt;/p&gt;
&lt;p&gt;設定の方向性:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NAPT環境&lt;/li&gt;
&lt;li&gt;不要なパケットは外に出さない&lt;/li&gt;
&lt;li&gt;LANからのみtelnet接続可能&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>NEC IX2015設定要点と設定サンプル</title><link>https://blog.teraren.com/posts/ix2015-setting/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ix2015-setting/</guid><description>NEC IX2015ルーターの時刻設定・NTP・ホスト名・保存など主要コマンドのリファレンスと設定サンプル集</description><pubDate>Tue, 05 Jan 2010 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;::amazon{asin=&quot;B01HR07ATO&quot;}&lt;/p&gt;
&lt;p&gt;主要コマンドのメモ&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;時間の設定&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# timezone 9
Router(config)# ntp retry 3
Router(config)# ntp interval 3600
Router(config)# clock 16 01 0 3 1 2010
Router(config)# show clock
Sunday, 3 January 2010 16:01:28 +09 00
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;ホスト名の設定(任意）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# hostname cu
cu(config)#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;保存&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# write memory
Building configuration…
% Warning: do NOT enter CNTL/Z while saving to avoid config corruption.
Router(config)#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;インターフェイス状態の確認&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# show interfaces FastEthernet0/0.0
Interface FastEthernet0/0.0 is administratively down
  Fundamental MTU is 1500 octets
  Current bandwidth 100M b/s, QoS is disabled
  Datalink header cache type is none: 0/0 (standby/dynamic)
  SNMP MIB-2:
    ifIndex is 518
  Logical INTERFACE:
    Elapsed time after clear counters 0:11:00
    0 packets input, 0 bytes, 0 errors
      0 unicasts, 0 non-unicasts, 1 unknown protos
      0 drops, 0 misc errors
    0 output requests, 0 bytes, 0 errors
      0 unicasts, 0 non-unicasts
      0 overflows, 0 neighbor unreachable, 0 misc errors
    1 link-up detected, 0 link-down detected
  Encapsulation ETHERNET:
    State is initialized
  FastEthernet status:
    Physical address is 00:30:13:36:ce:03
    Port status is up
    Full-duplex, 100M b/s, 100BaseTX
    Promiscuous mode is disabled
    Statistics:
      Rx errors:
        0 alignment errors, 0 CRC errors
        0 long frames, 0 short frames, 0 overflows
      Tx errors:
        0 single collisions, 0 multiple collisions
        0 excessive collisions, 0 late collisions
        0 deferred transmissions, 0 carrier sense errors
        0 underflows
Router(config)#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;FE0/0に固定IP設定&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# interface FastEthernet0/0.0
Router(config-FastEthernet0/0.0)# ip address 192.168.0.1/24
Router(config-FastEthernet0/0.0)# ipv6 address autoconfig
Router(config-FastEthernet0/0.0)# no shutdown
Router(config-FastEthernet0/0.0)# show ip address
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;FE0/1にDHCP設定&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# interface FastEthernet0/1.0
Router(config-FastEthernet0/1.0)# ip address dhcp
Router(config-FastEthernet0/1.0)# ipv6 address autoconfig
Router(config-FastEthernet0/1.0)# no shutdown
Router(config-FastEthernet0/1.0)# show ip address
Router(config-FastEthernet0/1.0)# ip nat enable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NAT設定&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# interface FastEthernet0/1.0
Router(config-FastEthernet0/1.0)# ip nat translation timeout 3600
Router(config-FastEthernet0/1.0)# ip nat dynamic list lan pool abc
Router(config-FastEthernet0/1.0)# ip nat enable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;telnetサーバ&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# ip access-list lan permit ip src 192.168.0.0/24 dest any
Router(config)# telnet-server ip access-list lan
Router(config)# telnet-server ip enable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;default route設定&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# ip route default FastEthernet0/1.0 dhcp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;NTPサーバ設定&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# ntp server 133.27.4.121
Router(config)# ntp server 210.173.160.27
Router(config)# ntp ip enable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;DHCPサーバ設定&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# ip dhcp profile lan
Router(config-dhcp-lan)# assignable-range 192.168.0.100 192.168.0.254
Router(config-dhcp-lan)# subnet-mask 255.255.255.0
Router(config-dhcp-lan)# dns-server 192.168.0.1
Router(config-dhcp-lan)# exit
Router(config)# ip dhcp enable
Router(config)# interface FastEthernet0/0.0
Router(config-FastEthernet0/0.0)# ip dhcp binding lan
Router(config-FastEthernet0/0.0)# exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;DNS proxy設定&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# dns cache enable
Router(config)# proxy-dns ip enable
Router(config)# proxy-dns ipv6 enable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;UFSキャッシュ有効化&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;UFS キャッシュ（Unified Forwarding Service Cache）は、フィルタ、NAT/NAPT、IPSec など&lt;br /&gt;
のサービスを使用している場合に有効な高速フォワーディングキャッシュメカニズムであり、&lt;br /&gt;
IX1000/2000/3000 の独自機能です。UFS キャッシュにより、フィルタの多段設定、IPSec の複&lt;br /&gt;
数設定等におけるスケーラビリティを向上させます。Ver4.2 以降の IPv4、IPv6 それぞれで設定&lt;br /&gt;
できます。Ver.4.3 以降ではポリシールーティングが、Ver.7.3以降では、QoS、ダイナミックフィ&lt;br /&gt;
ルタでも UFS キャッシュが適用されます。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;Router(config)# ip ufs-cache enable
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Filtering設定&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip access-list strict-block deny tcp src any sport any dest any dport eq 137 
ip access-list strict-block deny udp src any sport any dest any dport eq 137 
ip access-list strict-block deny udp src any sport any dest any dport eq 138 
ip access-list strict-block deny tcp src any sport any dest any dport eq 139 
ip access-list strict-block deny tcp src any sport any dest any dport eq 445 
ip access-list strict-block deny udp src any sport any dest any dport eq 445
ip access-list weak-block deny tcp src any sport any dest any dport eq 1 
ip access-list weak-block deny udp src any sport any dest any dport eq 1 
ip access-list weak-block deny tcp src any sport any dest any dport eq 11 
ip access-list weak-block deny udp src any sport any dest any dport eq 11 
ip access-list weak-block deny tcp src any sport any dest any dport eq 15 
ip access-list weak-block deny udp src any sport any dest any dport eq 15 
ip access-list weak-block deny tcp src any sport any dest any dport eq 70 
ip access-list weak-block deny udp src any sport any dest any dport eq 70 
ip access-list weak-block deny tcp src any sport any dest any dport eq 79 
ip access-list weak-block deny udp src any sport any dest any dport eq 79 
ip access-list weak-block deny tcp src any sport any dest any dport eq 87 
ip access-list weak-block deny udp src any sport any dest any dport eq 87 
ip access-list weak-block deny tcp src any sport any dest any dport eq 95 
ip access-list weak-block deny udp src any sport any dest any dport eq 95 
ip access-list weak-block deny tcp src any sport any dest any dport eq 111 
ip access-list weak-block deny udp src any sport any dest any dport eq 111 
ip access-list weak-block deny tcp src any sport any dest any dport eq 135 
ip access-list weak-block deny udp src any sport any dest any dport eq 135 
ip access-list weak-block deny tcp src any sport any dest any dport eq 144 
ip access-list weak-block deny udp src any sport any dest any dport eq 144 
ip access-list weak-block deny tcp src any sport any dest any dport eq 161 
ip access-list weak-block deny udp src any sport any dest any dport eq 161 
ip access-list weak-block deny tcp src any sport any dest any dport eq 162 
ip access-list weak-block deny udp src any sport any dest any dport eq 162 
ip access-list weak-block deny tcp src any sport any dest any dport eq 177 
ip access-list weak-block deny udp src any sport any dest any dport eq 177 
ip access-list weak-block deny tcp src any sport any dest any dport eq 220 
ip access-list weak-block deny udp src any sport any dest any dport eq 220 
ip access-list weak-block deny tcp src any sport any dest any dport eq 445 
ip access-list weak-block deny udp src any sport any dest any dport eq 445 
ip access-list weak-block deny tcp src any sport any dest any dport eq 512 
ip access-list weak-block deny udp src any sport any dest any dport eq 512 
ip access-list weak-block deny tcp src any sport any dest any dport eq 513 
ip access-list weak-block deny udp src any sport any dest any dport eq 513 
ip access-list weak-block deny tcp src any sport any dest any dport eq 514 
ip access-list weak-block deny udp src any sport any dest any dport eq 514 
ip access-list weak-block deny tcp src any sport any dest any dport eq 515 
ip access-list weak-block deny udp src any sport any dest any dport eq 515 
ip access-list weak-block deny tcp src any sport any dest any dport eq 517 
ip access-list weak-block deny udp src any sport any dest any dport eq 517 
ip access-list weak-block deny tcp src any sport any dest any dport eq 518 
ip access-list weak-block deny udp src any sport any dest any dport eq 518 
ip access-list weak-block deny tcp src any sport any dest any dport eq 520 
ip access-list weak-block deny udp src any sport any dest any dport eq 520 
ip access-list weak-block deny tcp src any sport any dest any dport eq 540 
ip access-list weak-block deny udp src any sport any dest any dport eq 540 
ip access-list weak-block deny tcp src any sport any dest any dport eq 1025 
ip access-list weak-block deny udp src any sport any dest any dport eq 1025 
ip access-list weak-block deny tcp src any sport any dest any dport eq 2000 
ip access-list weak-block deny udp src any sport any dest any dport eq 2000 
ip access-list weak-block deny tcp src any sport any dest any dport eq 2049 
ip access-list weak-block deny udp src any sport any dest any dport eq 2049 
ip access-list weak-block deny tcp src any sport any dest any dport eq 2766 
ip access-list weak-block deny udp src any sport any dest any dport eq 2766 
ip access-list weak-block deny tcp src any sport any dest any dport range 6000 6063 
ip access-list weak-block deny udp src any sport any dest any dport range 6000 6063 
ip access-list weak-block deny tcp src any sport any dest any dport eq 12345 
ip access-list weak-block deny udp src any sport any dest any dport eq 12345
ip access-list specialuse deny ip src 0.0.0.0/8 dest any 
ip access-list specialuse deny ip src 10.0.0.0/8 dest any 
ip access-list specialuse deny ip src 172.16.0.0/12 dest any 
ip access-list specialuse deny ip src 192.168.0.0/16 dest any 
ip access-list specialuse deny ip src 127.0.0.0/8 dest any 
ip access-list specialuse deny ip src 169.254.0.0/16 dest any 
ip access-list specialuse deny ip src 192.0.2.0/24 dest any 
ip access-list specialuse deny ip src 224.0.0.0/3 dest any 
ip access-list specialuse deny ip src 198.18.0.0/15 dest any 
ip access-list mynetwork permit ip src 192.168.0.0/24 dest any 
ip access-list all-pass permit ip src any dest any 
ip filter forced-reassembly
interface  FastEthernet0/1.0 
ip filter all-pass 65000 in 
ip filter all-pass 65000 out 
ip filter mynetwork 50 out 
ip filter strict-block 1 in 
ip filter strict-block 1 out 
ip filter weak-block 100 in 
ip filter weak-block 100 out 
ip filter specialuse 101 in 
ip filter specialuse 101 out
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;再起動&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# スタートアップコンフィグのロード、DRAMメモリのクリア
restart

# プログラムのロード、スタートアップコンフィグのロード、DRAMメモリのクリア
reload
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;不思議な所&lt;/strong&gt;
ip filterでdenyしているにもかかわらずnatテーブルができてしまう。もしかして、filterを通過しているのかと思ったけどちゃんとパケットは落とされている。謎。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;いけてないところ&lt;/strong&gt;&lt;br /&gt;
WAN側のIFはISPからDHCPでIPが振られているのだが、そのリース期限は6時間。&lt;br /&gt;
6時間毎にIFがIPをリリースし、一度downしてしまう。よって、NAPTテーブルも全部クリアされてしまう。再度割り当てられるIPは同じIPなので、とても不便。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2010/01/WS0668.jpg&quot; alt=&quot;WS0668 150x150 IX2015設定メモ&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;すばらしい安定性&lt;/strong&gt;&lt;br /&gt;
1ヶ月運用しているが、一度も再起動しないで稼働している。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;変更履歴&lt;/strong&gt;&lt;br /&gt;
2010/2/23 DHCPのフィルタ削除。&lt;br /&gt;
以下、削除部分。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ip access-list weak-block deny tcp src any sport any dest any dport eq 67
ip access-list weak-block deny udp src any sport any dest any dport eq 67
ip access-list weak-block deny tcp src any sport any dest any dport eq 68
ip access-list weak-block deny udp src any sport any dest any dport eq 68
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2018/9/21 追記&lt;/h2&gt;
&lt;p&gt;この記事、結構アクセスがありますが、今となっては、IX2015はスペック的に見劣りするので&lt;a href=&quot;/posts/rtx1200-deployment/&quot;&gt;RTX1200&lt;/a&gt;を使うのが良いです。&lt;/p&gt;
&lt;h2&gt;2022/2/8 追記&lt;/h2&gt;
&lt;p&gt;一応、ほそぼそとNECも後継機を作っているのでNECが好きならばこちらを。YAMAHAのほうが個人的にはおすすめです。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B07W41QWW8&quot;}&lt;/p&gt;
</content:encoded></item><item><title>NEC IX2015 初期設定</title><link>https://blog.teraren.com/posts/nec-ix2015-initial-setup/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nec-ix2015-initial-setup/</guid><description>企業向けルータNEC IX2015をヤフオクで5000円以下で入手し、IPSec確認やインターフェース番号など初期設定時に必要な基礎知識をまとめたメモ</description><pubDate>Tue, 05 Jan 2010 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;背景&lt;/h2&gt;
&lt;p&gt;会社で使っているLinksysのルータが調子悪くて、1日に数回ハングアップするようになった。そこで、2chで評判がいいIX2015をヤフオクで買った。標準価格：120,750円（税込）の製品が5000円以下。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B089VMT65S&quot;}&lt;/p&gt;
&lt;p&gt;このエントリーでは初期設定や前提となるメモを書いておく。&lt;/p&gt;
&lt;p&gt;設定ファイルの内容などは&lt;a href=&quot;/archive/tag/NEC%20IX2015/&quot;&gt;IX2015&lt;/a&gt;&lt;a href=&quot;/archive/tag/NEC%20IX2015/&quot;&gt;関連記事&lt;/a&gt;を見てください。&lt;/p&gt;
&lt;h2&gt;想定環境&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;LAN 192.168.0.0/24&amp;gt;&lt;/code&gt; – [192.168.0.1]&lt;code&gt;&amp;lt;FE0/0:IX2015FE0/1&amp;gt;&lt;/code&gt;[DHCP] – &lt;code&gt;&amp;lt;internet&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;IFの番号&lt;/h2&gt;
&lt;p&gt;FE0/0 = FastEthernet0/0.0
FE0/1 = FastEthernet0/1.0&lt;/p&gt;
&lt;h2&gt;BRIの用途&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;デジタル専用回線(HSD64/128など)、またはISDN回線（INSネット64）に接続することができます&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;IPSecキー確認&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;Router# enable-confi
Enter configuration commands, one per line. End with CNTL/Z.
Router(config)# show lic
IPsec H/W encryption is activated
Software Key Code is xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ISDN-BRI/VRRP option is activated
Software Key Code is xxxxxxxxxxxxxxxxxxxxxxxxx
Router(config)#
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>[Thu Dec 17 22:56:22 2009] [notice] child pid 2121 exit signal Segmentation fault (11)</title><link>https://blog.teraren.com/posts/thu-dec-17-225622-2009-notice-child-pid-2121-exit-signal-segmentation-fault-11/</link><guid isPermaLink="true">https://blog.teraren.com/posts/thu-dec-17-225622-2009-notice-child-pid-2121-exit-signal-segmentation-fault-11/</guid><description>[Thu Dec 17 22:56:22 2009] [notice] child pid 2121 exit signal Segmentation fault (11)</description><pubDate>Thu, 17 Dec 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/12/WS06351.JPG&quot; alt=&quot;segmentation fault&quot; /&gt; PHP 5.2.8にて、apacheのエラーログにsegmentation faultが記録されるが、どこで起きているかわからない。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[Thu Dec 17 22:56:22 2009] [notice] child pid 2121 exit signal Segmentation fault (11)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;しかし、xdebugを使えばエラー箇所をわかりやすく教えてくれる。 1.5時間も使ってしまった！&lt;/p&gt;
</content:encoded></item><item><title>新生銀行自動ログイン用Greasemonkey</title><link>https://blog.teraren.com/posts/shinsei-bank-greasemonkey/</link><guid isPermaLink="true">https://blog.teraren.com/posts/shinsei-bank-greasemonkey/</guid><description>新生銀行自動ログイン用Greasemonkey</description><pubDate>Wed, 16 Dec 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/12/WS0635.JPG&quot; alt=&quot;WS0635&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ついに新生銀行のログインスクリーンのデザインが変わってしまいました。&lt;br /&gt;
そこで、&lt;a href=&quot;http://xxsionxx.blog17.fc2.com/blog-entry-1060.html&quot;&gt;今まで利用していた&lt;/a&gt;&lt;a href=&quot;https://addons.mozilla.org/ja/firefox/addon/748&quot;&gt;Greasemonkey&lt;/a&gt;スクリプトが動かなくなってしまいました。&lt;/p&gt;
&lt;p&gt;今まで使っていたスクリプトを改変して以下のところに置いたのでどうぞ！&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://userscripts.org/scripts/show/64306&quot;&gt;Shinsei Wand&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>tcmgr copyの環境変数</title><link>https://blog.teraren.com/posts/tcmgr-copy/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tcmgr-copy/</guid><description>tcmgr copyの環境変数</description><pubDate>Tue, 15 Dec 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;以下のコマンドを実行したときに、シェルスクリプトに渡される環境変数を調べる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% tcrmgr copy localhost &apos;@/var/lib/scm/tokyotyrant/persistent-session/ttbackup.sh&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;結果は以下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$0 = /var/lib/scm/tokyotyrant/persistent-session/ttbackup.sh
$1 = /var/www/cyta.jp/tokyotyrant/persistent-session/casket.tct
$2 = 1260873164312114
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>jQuery-UIのデフォルトパラメータを設定</title><link>https://blog.teraren.com/posts/jquery-ui-default-parameters/</link><guid isPermaLink="true">https://blog.teraren.com/posts/jquery-ui-default-parameters/</guid><description>jQuery-UIのdialogウィジェットでモーダル・幅・ボタンなどのデフォルト値をJQuery.ui.dialog.defaultsで一括設定する方法。毎回パラメータを書く冗長なコードをシンプルにするテクニック。</description><pubDate>Fri, 04 Dec 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/12/WS0634.JPG&quot; alt=&quot;jqueryui dialog&quot; /&gt;&lt;/p&gt;
&lt;p&gt;jQuery-UIのdialogを普通に使うときは、以下のように書く。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$(&apos;&amp;lt;div title=&quot;ERROR&quot;&amp;gt;&amp;lt;/div&amp;gt;&apos;)
  .text(&apos;Error message&apos;)
  .dialog({
    modal: true,
    buttons: {
      &quot;Close&quot;: function() {
        $(this).dialog(&quot;close&quot;);
      }
    }
  });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかしながら、dialogを使うときに毎回上記のようにパラメータを設定していると冗長するコードが増えてしまうので、デフォルトパラメータを上書きしたい。&lt;/p&gt;
&lt;p&gt;そんな場合は以下でデフォルト値を設定（上書き）できる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/**
 * Override jQuery-UI property
 */
jQuery.ui.dialog.defaults.modal = true;
jQuery.ui.dialog.defaults.bgiframe = true;
jQuery.ui.dialog.defaults.resizable = true;
jQuery.ui.dialog.defaults.width = 400;
jQuery.ui.dialog.defaults.buttons = {
  &quot;Close&quot;: function() {
  $(this).dialog(&quot;close&quot;);
}};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;dialogを表示するときは以下のような短いコードで済むし、別途パラメータも渡せる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$(&apos;&amp;lt;div title=&quot;ERROR&quot;&amp;gt;&amp;lt;/div&amp;gt;&apos;)
  .text(response.error)
  .dialog();
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>innodb_log_file_sizeを変更する方法</title><link>https://blog.teraren.com/posts/innodb-log-file-size/</link><guid isPermaLink="true">https://blog.teraren.com/posts/innodb-log-file-size/</guid><description>MySQLのinnodb_log_file_sizeを安全に変更する手順。ib_logfileの移動が必要な理由と、変更しないまま再起動した場合に起きる.frmエラーの原因と対策を解説。</description><pubDate>Tue, 01 Dec 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;innodb_log_file_sizeの変更手順。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; SET GLOBAL innodb_fast_shutdown=0;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# /etc/init.d/mysql.server stop
# mv ib_logfile* /tmp/
# /etc/init.d/mysql.server start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;コピペ用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/etc/init.d/mysql.server stop  &amp;amp;&amp;amp; sleep 1 &amp;amp;&amp;amp; mv ib_logfile* /tmp/ &amp;amp;&amp;amp; /etc/init.d/mysql.server start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;innodb_log_file_sizeとは、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ログ グループ内のそれぞれの長いファイルのバイトでのサイズ。ログ ファイルの結合したサイズは32ビット コンピュータ上で 4GB 以下でなければいけません。デフォルトは5MB です。実用的な値は、N がグループ内のログ ファイル数だとして、バッファ プールのサイズの1MB から 1/N-th です。 値が大きいほど、ディスク I/O を節約し、バッファ プール内で必要とされるチェックポイント フラッシュ活動は少なくなります。しかし、ログ ファイルが大きいという事はクラッシュした時の復旧のスピードが遅いという事も意味します。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;my.cnfのコメントに、推奨値はinnodb_buffer_pool_sizeの25%が書いてありました。&lt;br /&gt;
上記の説明とは食い違うなぁ。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Set the log file size to about&lt;br /&gt;
25 % of the buffer pool size&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;innodb_log_file_sizeの値の影響はどの辺にあるかというと、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;この値が大きいほど、バッファプールで必要となるチェックポイントフラッシュの回数が減るため、ディスク I/O が削減される。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;とあるので、書き込みが少ない用途の場合はこの値が少なくてもいいということか。&lt;/p&gt;
&lt;p&gt;そこで、innodb logファイルの更新日を見てみたら、3日ほどローテーションされていないから、この場合は4MBでも十分みたい。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ll -h ib_logfile*
-rw-rw----  1 mysql mysql 2.0M 2009/12/01 13:57:44 ib_logfile0
-rw-rw----  1 mysql mysql 2.0M 2009/11/28 11:27:27 ib_logfile1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ref:&lt;br /&gt;
&lt;a href=&quot;http://q.hatena.ne.jp/1236080287&quot;&gt;&lt;/a&gt;&lt;a href=&quot;http://q.hatena.ne.jp/1236080287&quot;&gt;http://q.hatena.ne.jp/1236080287&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;もし、ib_logfileを移動しないで再起動すると、mysqld自体は起動しますがストレージエンジンの参照ができなくなります！&lt;/strong&gt;&lt;br /&gt;
ほんとこれはトリッキー。mysqldのrestartは成功するけど、mysqlを利用できない。エラー内容は.frmが壊れているというようなメッセージが表示されるので、原因特定が難しい。&lt;/p&gt;
&lt;p&gt;その際は以下のようなエラーがmysqlのログファイルに書かれます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;InnoDB: Error: log file ./ib_logfile0 is of different size 0 5242880 bytes
InnoDB: than specified in the .cnf file 0 268435456 bytes!
090813 11:00:18 [Warning] &apos;user&apos; entry &apos;root@XXXXX.com&apos; ignored in --skip-name-resolve mode.
090813 11:00:18 [Note] /usr/sbin/mysqld: ready for connections.
Version: &apos;5.0.81-community-log&apos;  socket: &apos;/var/lib/mysql/mysql.sock&apos;  port: 3306  MySQL Community Edition (GPL)
090813 11:00:19 [ERROR] /usr/sbin/mysqld: Incorrect information in file: &apos;./XXXX/User.frm&apos;
090813 11:00:19 [ERROR] /usr/sbin/mysqld: Incorrect information in file: &apos;./XXXX/User.frm&apos;
090813 11:00:19 [ERROR] /usr/sbin/mysqld: Incorrect information in file: &apos;./XXXX/User.frm&apos;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>マルチバイトサブドメインを使うときの設定</title><link>https://blog.teraren.com/posts/punycode/</link><guid isPermaLink="true">https://blog.teraren.com/posts/punycode/</guid><description>日本語ドメインをApacheで運用する際のPunycode・UTF-8・URLエンコードの3形式対応設定方法。ブラウザや掲示板の互換性問題への対処法を解説。</description><pubDate>Thu, 26 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2019/04/tumblr_ktp2x2LMBT1qzx62xo1_500.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;マルチバイトサブドメイン&lt;/strong&gt;とは、http://テスト.example.com/のように、マルチバイトを含んだサブドメインのホストへアクセスすることを言う。&lt;/p&gt;
&lt;p&gt;普通は、&lt;a href=&quot;http://ja.wikipedia.org/wiki/Punycode&quot;&gt;Punycode&lt;/a&gt; (&lt;a href=&quot;http://tools.ietf.org/html/rfc3492&quot;&gt;RFC 3492&lt;/a&gt;)を利用して、エンコードする。テスト.example.comの場合はxn--zckzah.example.comとなる。&lt;/p&gt;
&lt;p&gt;しかし、ブラウザ（携帯端末）がRFC 3492対応していなかったり、マルチバイトサブドメインを含んだURLを貼り付けた掲示板がPunycodeを想定していない場合(Youtube)があるため、サービス提供者側でいくつかのエンコード形式でアクセスされたときのことを想定しておかなければならない。具体的には以下の3つ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Punycode&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;UTF-8のurlencode&lt;/li&gt;
&lt;li&gt;UTF-8&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Apacheの設定は以下のようになる。&lt;br /&gt;
&quot; http://テスト.example.com&quot; の場合&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
  ServerName xn--zckzah.example.com
  DocumentRoot /var/www/path/to/htdocs
&amp;lt;/VirtualHost&amp;gt;

&amp;lt;VirtualHost *:80&amp;gt;
  ServerName %83e%83X%83g.example.com
  Redirect permanent / http://xn--zckzah.example.com/
&amp;lt;/VirtualHost&amp;gt;

&amp;lt;VirtualHost *:80&amp;gt;
  ServerName テスト.example.com
  Redirect permanent / http://xn--zckzah.example.com/
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>MySQL InnoDB, Linux and SSD tuning</title><link>https://blog.teraren.com/posts/mysql-innodb-linux-and-ssd-tuning/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-innodb-linux-and-ssd-tuning/</guid><description>MySQL InnoDB, Linux and SSD tuning</description><pubDate>Fri, 20 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/11/WS0630.JPG&quot; alt=&quot;mtstat&quot; /&gt; &lt;a href=&quot;http://www.mysql.gr.jp/frame/modules/bwiki/index.php?matsunobu&quot;&gt;松信 嘉範さんによるhbstudy#5発表資料「Linux/MySQLサーバーのパフォーマンスチューニング」&lt;/a&gt; これを読んで、追加で行ったチューニングや新しいことメモ。さすが中の人だけあって詳しい。&lt;/p&gt;
&lt;h2&gt;1:1&lt;/h2&gt;
&lt;p&gt;InnoDBで。 TEXTなどのデータを別テーブルへ。 よく検索される列ごとにテーブルをまとめるとbuffer poolを効率よく使える。&lt;/p&gt;
&lt;h2&gt;物理メモリが足りなくなったときの挙動&lt;/h2&gt;
&lt;p&gt;ファイルシステムキャッシュを減らす。（100の場合、プロセスをスワップアウト）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# echo 0 &amp;gt; /proc/sys/vm/swappiness
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;永続化&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# echo &apos;vm.swappiness=0&apos; &amp;gt;&amp;gt; /etc/sysctl.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;mtstat&lt;/h2&gt;
&lt;p&gt;vmstatの高機能版かな。数値がhuman friendlyで、カラーリングされている。 （トップ画）&lt;/p&gt;
</content:encoded></item><item><title>Tokyo Promenadeインスコしてみた</title><link>https://blog.teraren.com/posts/tokyo-promenade/</link><guid isPermaLink="true">https://blog.teraren.com/posts/tokyo-promenade/</guid><description>Tokyo Promenadeインスコしてみた</description><pubDate>Thu, 19 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/11/WS0626.JPG&quot; alt=&quot;tokyo promenade&quot; /&gt;&lt;/p&gt;
&lt;p&gt;今開発しているサイトでKey Value Storeの利用可能性がいまいち思い浮かばないので、KVSを使っているTokyoPromenadeを使ってみた。 大規模サービスではKVSをRDBの補助的な役割として利用する事例はたくさんあるが、プライマリストレージとして利用する事例が無いので興味があって使ってみた。 →いまいちインスパイアされなかった。KVSそのままがUIに出てきてしまって使いづらいモノになってしまっている。KVS単体だと表現力が弱いなぁ。（あたりまえだけど） セットアップ方法はこちらの&lt;a href=&quot;https://matsu.teraren.com/tp/promenade.cgi&quot;&gt;デモサイト&lt;/a&gt;に掲載しました。&lt;/p&gt;
</content:encoded></item><item><title>munin plugin - MySQL query cache usage</title><link>https://blog.teraren.com/posts/munin-plugin-mysql-query-cache-usage/</link><guid isPermaLink="true">https://blog.teraren.com/posts/munin-plugin-mysql-query-cache-usage/</guid><description>munin plugin - MySQL query cache usage</description><pubDate>Tue, 17 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/11/WS0625.JPG&quot; alt=&quot;munin mysql plugin&quot; /&gt;&lt;/p&gt;
&lt;p&gt;MySQLのQuery Cacheの効き具合を継続的に調査するためにmuninのプラグイン書きました。&lt;br /&gt;
ニーズが多かったらGNUで公開しようと思います。&lt;/p&gt;
&lt;p&gt;グラフ描画に利用した変数は以下。&lt;br /&gt;
緑：query_cache_size - Qcache_free_memory&lt;br /&gt;
青：query_cache_size&lt;/p&gt;
&lt;p&gt;query cacheのhit rateなども欲しいなぁ。&lt;/p&gt;
</content:encoded></item><item><title>SQLで先月という表現</title><link>https://blog.teraren.com/posts/last-month/</link><guid isPermaLink="true">https://blog.teraren.com/posts/last-month/</guid><description>MySQLでBETWEENとdate_format、last_dayを使って「先月」の日付範囲を正確に指定するSQLの書き方を解説</description><pubDate>Mon, 16 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SQLで先月という制約を書く方法。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;col BETWEEN
date_format(adddate(now(), interval -1 month),&apos;%y-%m-01&apos;)
AND
last_day(adddate(now(), interval -1 month));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下、MySQLでの実験。現在は2009年11月16日。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select  &apos;2009-10-16&apos; between  DATE_FORMAT(adddate(now(), interval -1 month),&apos;%Y-%m-01&apos;) and last_day(adddate(now(), interval -1 month)) as result;
+--------+
| result |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)

mysql&amp;gt; select  &apos;2009-10-31&apos; between  DATE_FORMAT(adddate(now(), interval -1 month),&apos;%Y-%m-01&apos;) and last_day(adddate(now(), interval -1 month)) as result;
+--------+
| result |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)

mysql&amp;gt; select  &apos;2009-10-01&apos; between  DATE_FORMAT(adddate(now(), interval -1 month),&apos;%Y-%m-01&apos;) and last_day(adddate(now(), interval -1 month)) as result;
+--------+
| result |
+--------+
|      1 |
+--------+
1 row in set (0.00 sec)

mysql&amp;gt; select  &apos;2009-11-01&apos; between  DATE_FORMAT(adddate(now(), interval -1 month),&apos;%Y-%m-01&apos;) and last_day(adddate(now(), interval -1 month)) as result;
+--------+
| result |
+--------+
|      0 |
+--------+
1 row in set (0.00 sec)

mysql&amp;gt; select  &apos;2009-09-31&apos; between  DATE_FORMAT(adddate(now(), interval -1 month),&apos;%Y-%m-01&apos;) and last_day(adddate(now(), interval -1 month)) as result;
+--------+
| result |
+--------+
|      0 |
+--------+
1 row in set (0.00 sec)

mysql&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>CGI benchmarking</title><link>https://blog.teraren.com/posts/cgi-benchmarking/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cgi-benchmarking/</guid><description>HTML, PHP, Go, C, PerlでCGIの「Hello World」パフォーマンスをJMeterで測定したベンチマーク結果</description><pubDate>Fri, 13 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;環境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Server: Apache/2.2.11 (Unix) Debian GNU/Linux 5.0&lt;/li&gt;
&lt;li&gt;Client: JMeter 20,000 requests / 2 threads&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;測定内容&lt;/h2&gt;
&lt;p&gt;HTML, PHP, Go (golang), C, Perl で「Hello World!」を出力するCGIのパフォーマンスを測定。&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/11/WS0624.JPG&quot; alt=&quot;benchmark result&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>IPアドレスから位置情報への変換</title><link>https://blog.teraren.com/posts/ip-address-to-geolocation/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ip-address-to-geolocation/</guid><description>IPアドレスから位置情報への変換</description><pubDate>Mon, 09 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.maxmind.com/ja/geoip-demo&quot;&gt;GeopIP&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>NECルータ自動再起動</title><link>https://blog.teraren.com/posts/nec-router-auto-reboot/</link><guid isPermaLink="true">https://blog.teraren.com/posts/nec-router-auto-reboot/</guid><description>NATテーブルオーバーフローで頻繁にハングするNECルータをdaemontoolsで自動監視・再起動するシェルスクリプトの実装例</description><pubDate>Mon, 02 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;http://5.media.tumblr.com/tumblr_ksgtx2JYlP1qzx62xo1_500.jpg&quot; alt=&quot;NEC router&quot; /&gt;&lt;/p&gt;
&lt;p&gt;すぐハングアップするルータの対処方法を書きます。&lt;br /&gt;
こちらの続きです。&lt;a href=&quot;/posts/atermbr-745f68/&quot;&gt;/posts/atermbr-745f68/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;1，2日に1回NATテーブルがオーバーフローしてインターネットに繋がらなくなるルータの対処方法です。&lt;/p&gt;
&lt;p&gt;普通なら、NATテーブルがあふれたら管理画面開いて、ログ見て、ERRORという文字が出ていたらルータの再起動。という作業をやらなければならない・・・これがめんどくさいという人のために自動化するシェルスクリプト書きました。&lt;/p&gt;
&lt;h3&gt;仕様&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;5秒に1回、ルータの画面をチェックしてERROR文字が10行以上出力されていたらルータを再起動します&lt;/li&gt;
&lt;li&gt;ファイルはSJISで保存してください&lt;/li&gt;
&lt;li&gt;デーモンとして動きます&lt;/li&gt;
&lt;li&gt;VoIP利用中だったら、切れるまで待ちます&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ソースコード&lt;/p&gt;
&lt;p&gt;daemontoolsで起動する場合のrunファイルの中身&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh
exec 2&amp;gt;&amp;amp;1
exec  sh -c &apos;exec envuidgid daemon softlimit -o10 ./router_restart.sh&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しばらく運用するとdaemontoolsのログにはこんな感じで出力される&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[root@dev1 /var/log/routerreset]# cat  current|tai64nlocal
2009-10-30 10:36:29.241894500 Starting.
2009-10-30 11:10:50.983588500 Reset log
2009-10-30 11:10:51.063590500 Reboot
2009-10-30 16:53:41.973878500 Waiting for disconnecting the tel line.
2009-10-30 16:53:43.145824500 Waiting for disconnecting the tel line.
2009-10-30 16:53:44.322821500 Waiting for disconnecting the tel line.
2009-10-30 16:53:45.495036500 Waiting for disconnecting the tel line.
2009-10-30 16:53:46.674632500 Waiting for disconnecting the tel line.
2009-10-30 16:53:47.847190500 Waiting for disconnecting the tel line.
2009-10-30 16:53:49.020860500 Waiting for disconnecting the tel line.
2009-10-30 16:53:50.191697500 Waiting for disconnecting the tel line.
2009-10-30 16:53:51.367155500 Waiting for disconnecting the tel line.
2009-10-30 16:53:52.552524500 Waiting for disconnecting the tel line.
2009-10-30 16:53:53.727068500 Waiting for disconnecting the tel line.
2009-10-30 16:53:54.917356500 Waiting for disconnecting the tel line.
2009-10-30 16:53:56.128064500 Waiting for disconnecting the tel line.
2009-10-30 16:53:57.307613500 Waiting for disconnecting the tel line.
2009-10-30 16:53:58.506647500 Waiting for disconnecting the tel line.
2009-10-30 16:53:59.703276500 Waiting for disconnecting the tel line.
2009-10-30 16:54:00.883237500 Waiting for disconnecting the tel line.
2009-10-30 16:54:02.064220500 Waiting for disconnecting the tel line.
2009-10-30 16:54:03.245124500 Waiting for disconnecting the tel line.
2009-10-30 16:54:04.424067500 Waiting for disconnecting the tel line.
2009-10-30 16:54:05.610304500 Waiting for disconnecting the tel line.
2009-10-30 16:54:06.794509500 Waiting for disconnecting the tel line.
2009-10-30 16:54:07.989049500 Waiting for disconnecting the tel line.
2009-10-30 16:54:09.189855500 Waiting for disconnecting the tel line.
2009-10-30 16:54:10.381022500 Waiting for disconnecting the tel line.
2009-10-30 16:54:11.586075500 Waiting for disconnecting the tel line.
2009-10-30 16:54:12.774096500 Waiting for disconnecting the tel line.
2009-10-30 16:54:13.956662500 Reset log
2009-10-30 16:54:14.038838500 Reboot
2009-10-31 10:45:17.594545500 Reset log
2009-10-31 10:45:17.673467500 Reboot
2009-11-02 12:12:44.943487500 Reset log
2009-11-02 12:12:45.022605500 Reboot
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>URLリダイレクタ</title><link>https://blog.teraren.com/posts/url-redirector/</link><guid isPermaLink="true">https://blog.teraren.com/posts/url-redirector/</guid><description>2chのime.nuのようなURLリダイレクタをPHPで自作し、リンク元を隠してジャンプするサービスの実装方法を紹介</description><pubDate>Mon, 02 Nov 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;http://farm1.static.flickr.com/31/44965455_534be470f2.jpg&quot; alt=&quot;URL&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2chで、外部サイトへのURLリンクで使っているime.nuサービスみたいなのを書いてみた。&lt;/p&gt;
&lt;p&gt;使い方&lt;br /&gt;
&lt;a href=&quot;https://matsu.teraren.com/link/www.yahoo.co.jp&quot;&gt;https://matsu.teraren.com/link/www.yahoo.co.jp&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://matsu.teraren.com/link/http://www.yahoo.co.jp&quot;&gt;https://matsu.teraren.com/link/http://www.yahoo.co.jp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;リンク元をさらしたくないときにはどうぞ。&lt;/p&gt;
&lt;p&gt;ソースコード&lt;/p&gt;
&lt;p&gt;index.php&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
// path prefix
$prefix = &apos;/~matsu/link/&apos;;

$url = substr($_SERVER[&quot;REQUEST_URI&quot;], strlen($prefix));
// add protocol if protocol is not specified
if(strpos($url, &apos;http&apos;) === false){
  $url = &apos;http://&apos;.$url;
}

$url = htmlspecialchars($url);

?&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;jump&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;a href=&quot;&amp;lt;?php print $url; ?&amp;gt;&quot;&amp;gt;&amp;lt;?php print $url; ?&amp;gt;&amp;lt;/a&amp;gt;
別のサイトにジャンプしようとしています。宜しければ上記のリンクをクリックしてください
&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.htaccess&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;ifmodule mod_rewrite.c&amp;gt;
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /~matsu/link/index.php [L]
&amp;lt;/ifmodule&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>VPS契約時に確認すべき重要なこと</title><link>https://blog.teraren.com/posts/vps-contract/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vps-contract/</guid><description>VPS契約時に確認すべき重要なこと</description><pubDate>Thu, 29 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;短期的には問題にならないけど将来的にはかなり問題になること、それは&lt;strong&gt;機能がアップグレードされるかどうか&lt;/strong&gt;！？&lt;/p&gt;
&lt;p&gt;ハードウェアの調達コストは低くなるので、VPSプロバイダはVPSの新しいプランまたはアップグレードされたプランを発表する。しかしながら、すでに契約している顧客に対してはアップグレードをしない場合があったり、アップグレードする場合はIPアドレスが変わってしまうという事態が起こる。&lt;/p&gt;
&lt;p&gt;クラウド（PaaS）であればハードウェアも仮想化されているのでこのような問題は起こらないが、VPSでは起こってしまう。仮想化への過渡期なのでしょうがないが、VPSを契約する場合は注意すべき。&lt;/p&gt;
&lt;p&gt;サーバ仮想化技術の流れは以下で、専用サーバ→VPS→クラウド（PaaS）。VPSは発展途中でメリットデメリットが存在する。しかしながら、クラウドも実用段階に入ってきているので今VPSを契約するならしばらく待ってクラウドを契約した方が将来的には楽。&lt;/p&gt;
</content:encoded></item><item><title>fixcrioのプロセスが残る</title><link>https://blog.teraren.com/posts/fixcrio-process-remains/</link><guid isPermaLink="true">https://blog.teraren.com/posts/fixcrio-process-remains/</guid><description>fixcrioのプロセスが残る</description><pubDate>Mon, 19 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;先日の&lt;a href=&quot;/posts/unable-to-deliver-message-to-the-following-recipients/&quot;&gt;hotmail MTA対策&lt;/a&gt;を運用していて、少し問題があるので、解決方法を書きます。&lt;/p&gt;
&lt;p&gt;■問題&lt;br /&gt;
qmial-smtpdをdaemontoolで起動しているのですが、fixcrioプロセスが1日に5個ぐらいのペースで残っていきます。fixcrioを使う前まではこの現象がなかったのでfixcrioが原因の可能性が極めて高いです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root     23043  0.0  0.0  1332  144 ?        S    Oct16   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root     26764  0.0  0.0  1336  148 ?        S    Oct16   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root     30459  0.0  0.0  1332  144 ?        S    Oct16   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root     31536  0.0  0.0  1332  148 ?        S    Oct16   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root       640  0.0  0.0  1332  144 ?        S    Oct16   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root      7865  0.0  0.0  1336  184 ?        S    Oct17   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root     10241  0.0  0.0  1336  192 ?        S    Oct17   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root     15369  0.0  0.0  1336  148 ?        S    Oct17   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root     24527  0.0  0.0  1332  188 ?        S    Oct18   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root      7827  0.0  0.0  1332  180 ?        S    Oct18   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root     15577  0.0  0.0  1336  192 ?        S    Oct18   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root     23128  0.0  0.0  1332  188 ?        S    Oct18   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root     14132  0.0  0.0  1332  188 ?        S    06:25   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root     32109  0.0  0.0  1336  192 ?        S    09:46   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
root      6455  0.0  0.0  1332  188 ?        S    15:08   0:00 /usr/local/bin/fixcrio qmail-smtpd  vchkpw true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;■対処&lt;br /&gt;
面倒だけど、qmail-smtpdにパッチを当てて再度make setup.&lt;br /&gt;
自分の場合、patchが自動で当たらなかったので手作業でファイルを変更。&lt;br /&gt;
&lt;a href=&quot;http://www.qmail.org/qmail-smtpd-newline-1.03.patch&quot;&gt;http://www.qmail.org/qmail-smtpd-newline-1.03.patch&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;fixcrioを起動スクリプトから外して、qmail,qmail-smtpdを再起動して完了。&lt;/p&gt;
</content:encoded></item><item><title>VPSのHTTP速度</title><link>https://blog.teraren.com/posts/vps-speed-test/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vps-speed-test/</guid><description>VPSのHTTP速度</description><pubDate>Mon, 19 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;測定環境&lt;/h2&gt;
&lt;p&gt;jpgファイル: 145.19 KB&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% /usr/local/apache2/bin/ab -n 100 &amp;lt;url&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接続元：Fiberbit&lt;/p&gt;
&lt;h2&gt;測定結果&lt;/h2&gt;
&lt;p&gt;平均リクエスト完了時間&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;@YMC: 259ms&lt;/li&gt;
&lt;li&gt;CloudFront: 48ms&lt;/li&gt;
&lt;li&gt;CPI: 141ms&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>qmailがhotmailのメールを受信しなくなった</title><link>https://blog.teraren.com/posts/unable-to-deliver-message-to-the-following-recipients/</link><guid isPermaLink="true">https://blog.teraren.com/posts/unable-to-deliver-message-to-the-following-recipients/</guid><description>hotmailからのメールがqmailで受信できなくなった問題をfixcrioを追加してSMTPの不正なCRLFを修正することで解決した事例</description><pubDate>Thu, 08 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;この設定よりこちらの設定の方が適切です。(2009年10月22日追記)&lt;br /&gt;
&lt;a href=&quot;/posts/fixcrio-process-remains/&quot;&gt;fixcrioのプロセスが残る&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;hotmailから自社サーバにメールを送ったら、1日後に以下のエラーメール。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is an automatically generated Delivery Status Notification.&lt;/p&gt;
&lt;p&gt;THIS IS A WARNING MESSAGE ONLY.&lt;/p&gt;
&lt;p&gt;YOU DO NOT NEED TO RESEND YOUR MESSAGE.&lt;/p&gt;
&lt;p&gt;Delivery to the following recipients has been delayed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2日後に以下のエラーメール。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is an automatically generated Delivery Status Notification.&lt;/p&gt;
&lt;p&gt;Unable to deliver message to the following recipients, due to being unable to connect successfully to the destination mail server.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;が送り元のhotmailアカウントへ届くようになった。&lt;br /&gt;
現象は10月1日ぐらいから。&lt;/p&gt;
&lt;p&gt;ここの掲示板でも盛り上がってたように、問題はhotmailから送ってくるSMTPの中身が問題。&lt;br /&gt;
&lt;a href=&quot;http://forum.tsukaeru.net/viewtopic.php?t=4337&quot;&gt;http://forum.tsukaeru.net/viewtopic.php?t=4337&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;解決のために、/usr/local/bin/fixcrioを追加して、一件落着。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cd /service/smtpd
% cat run
#!/bin/sh
PATH=/usr/local/bin:/var/qmail/bin:/home/vpopmail/bin/:$PATH
exec /usr/local/bin/softlimit -m 15000000 \
tcpserver -R -H -l0 -v -x /home/vpopmail/etc/tcp.smtp.cdb -u qmaild -g nofiles 0 smtp \
/usr/local/bin/rblsmtpd -r blocked.rbl -r bl.spamcop.net \
/usr/local/bin/fixcrio \
qmail-smtpd www.example.com vchkpw true 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>VPS HTTP benchmark (YMC vs KDDI)</title><link>https://blog.teraren.com/posts/vps-http-benchmark-ymc-vs-kddi/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vps-http-benchmark-ymc-vs-kddi/</guid><description>VPS HTTP benchmark (YMC vs KDDI)</description><pubDate>Thu, 08 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;tareget file: 145.19 KB&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ab -c 2 -n 1000
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;ymc&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;              min  mean[+/-sd] median   max
Connect:       23   30 133.9     23    3025
Processing:   147  189  85.4    152     829
Waiting:       24   25   2.8     24      77
Total:        170  219 158.4    176    3207
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;kddi&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;              min  mean[+/-sd] median   max
Connect:        7   18  29.5     15     737
Processing:   126  228   9.0    230     248
Waiting:        7   28   8.4     29      50
Total:        192  247  24.9    246     868
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>科学における情報の上手な権利化と共有化メモ</title><link>https://blog.teraren.com/posts/data-sharing-in-science/</link><guid isPermaLink="true">https://blog.teraren.com/posts/data-sharing-in-science/</guid><description>Lawrence Lessigら登壇の東大シンポジウムを聴講したメモ。音楽と科学でのコピーライトの違い、Creative Commonsの意義、デジタル時代の著作権とイノベーションについて。</description><pubDate>Mon, 05 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今朝は生&lt;a href=&quot;https://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%83%AC%E3%83%B3%E3%82%B9%E3%83%BB%E3%83%AC%E3%83%83%E3%82%B7%E3%82%B0&quot;&gt;Lessig&lt;/a&gt;の公演を聞くために東京大学農学部へ。&lt;br /&gt;
午前中の2公演を聞いてきたのでサマっておきます。&lt;/p&gt;
&lt;p&gt;自分の言葉に置き換えている部分などがあるので、趣旨が違うところがあったら教えて欲しいです。&lt;/p&gt;
&lt;h3&gt;科学における情報の上手な権利化と共有化&lt;/h3&gt;
&lt;p&gt;Balancing IP Protection and Data Sharing in Science&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://symposium.lifesciencedb.jp/IPDS/&quot;&gt;http://symposium.lifesciencedb.jp/IPDS/&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Copyright in the Digital Age and Its Impact on Scientific Data Sharing&lt;/h4&gt;
&lt;p&gt;Lawrence Lessig　(Harvard Law School, Professor)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;今と昔ではcopyrightが適応される範囲が異なる。→広がっている&lt;/li&gt;
&lt;li&gt;musicとscienseでは著作権の利用目的が異なる
&lt;ul&gt;
&lt;li&gt;music: 利益のため。&lt;/li&gt;
&lt;li&gt;sciense: よりよい生活のため&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;アメリカの4大rich universitiesは著作権をあまり気にしない&lt;/li&gt;
&lt;li&gt;著作権を誇示するかしないかの判断指標
&lt;ul&gt;
&lt;li&gt;benefit VS protection cost&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;今まで（2002年）まではAll rights or None rights reserved.&lt;/li&gt;
&lt;li&gt;コンテンツの活発な流通のためにCC作った。
&lt;ul&gt;
&lt;li&gt;CCではSome rights reserved&lt;/li&gt;
&lt;li&gt;アメリカでは法的効力がある&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CC zeroも作った。
&lt;ul&gt;
&lt;li&gt;None rights reserved.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;著作者に対して、maximize benefit、minimize halmな法が必要。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;デジタル時代の著作権とイノベーション&lt;/h4&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-successive-word &lt;em&gt;/}
中山信弘　　(明治大学特任教授、東京大学名誉教授、弁護士)
{/&lt;/em&gt; textlint-enable */}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;流通形態が変わっているのに、不動産と同じモデルの著作権が適応されている。&lt;/li&gt;
&lt;li&gt;大きな流れ
&lt;ul&gt;
&lt;li&gt;利益追求する著作権&lt;/li&gt;
&lt;li&gt;commons&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;著作権法は毎年のように変わっている&lt;/li&gt;
&lt;li&gt;数年前までは検索エンジンを作ると著作権法に違反していた。&lt;/li&gt;
&lt;li&gt;デジタル媒体の著作権に関する法律はアメリカが2歩も3歩も進んでいる。
&lt;ul&gt;
&lt;li&gt;日本では若い研究者が着手したところ。&lt;/li&gt;
&lt;li&gt;著作権と技術はいたちごっこで、技術の発展とともにもっと複雑になっていくことが予想される。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;人格権はかなり複雑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://ja.wikipedia.org/wiki/%E8%91%97%E4%BD%9C%E8%80%85%E4%BA%BA%E6%A0%BC%E6%A8%A9&quot;&gt;http://ja.wikipedia.org/wiki/%E8%91%97%E4%BD%9C%E8%80%85%E4%BA%BA%E6%A0%BC%E6%A8%A9&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;質疑&lt;/h5&gt;
&lt;p&gt;利益重視型とフリー著作権を2つに分けてしまっては？&lt;br /&gt;
→経団連では3つに分けようと提案されている&lt;/p&gt;
&lt;h5&gt;用語&lt;/h5&gt;
&lt;p&gt;IP = Intellectual property&lt;/p&gt;
</content:encoded></item><item><title>WP Super Cacheでマルチバイトを使うとキャッシュが表示されない</title><link>https://blog.teraren.com/posts/wp-super-cache-with-multibyte-title/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wp-super-cache-with-multibyte-title/</guid><description>WP Super Cacheでマルチバイトを使うとキャッシュが表示されない</description><pubDate>Sat, 03 Oct 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;WordPressの設定にて、permalinkに%postlink%を含んだ状態にして、マルチバイトのslugを設定するとWP Super Cacheがうまく動かない。 理由は、mod_rewrite内のRewriteCondにて処理されるREQUEST_URIがdecodeされてしまっているから。decodeされないようにするためにはRewriteMapを使ってURL encodeをしてあげないとだめそう。 →面倒なので諦めた。 ということで、このblogはトップページと、アルファベットのslugがあるページだけ表示が速いです。&lt;/p&gt;
</content:encoded></item><item><title>freeコマンド</title><link>https://blog.teraren.com/posts/free-command/</link><guid isPermaLink="true">https://blog.teraren.com/posts/free-command/</guid><description>freeコマンド</description><pubDate>Fri, 18 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;空きメモリ容量はここを見る！&lt;/p&gt;
&lt;p&gt;buffer、cachedの意味。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/image-3.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;total = used + free&lt;/p&gt;
&lt;p&gt;最近(Ubuntu 20.04) のLinuxでは違った表示になります。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/10/image-4.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>git memo</title><link>https://blog.teraren.com/posts/git-memo/</link><guid isPermaLink="true">https://blog.teraren.com/posts/git-memo/</guid><description>Subversionから移行したgitの設定ファイルやよく使うサブコマンドを体系的にまとめたチートシート集</description><pubDate>Sat, 12 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;手元のgitメモが溜ってきたので放出！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat ~/.gitconfig
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;[user]
        name = Yuki Matsukura
        email = 秘密@秘密ドメイン
[color]
        ui = auto
        diff = auto
        status = auto
        branch = auto
        interactive = auto
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Subversion vs git&lt;/h3&gt;
&lt;p&gt;subversionへの不満が爆発。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2年前頃からtortoiseSVNでupdate,add,commitをしていると.svnディレクトリ内が壊れるようで、add,update,commitが一切できなくなる。回復するためには再チェックアウトするしかない。(過去2年で、かれこれ10回ぐらい起きた。)&lt;/li&gt;
&lt;li&gt;ファイルが多くなるとcommit,updateがすごい遅い。（1，2分かかる）&lt;/li&gt;
&lt;li&gt;チェックアウトすると小さいファイルを大量に作る→Disk IOが激しい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;gitが良さそう。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;軽い&lt;/li&gt;
&lt;li&gt;大規模プロジェクトで利用されている&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Web上の資料読んでもモデルが理解しづらいので&lt;a href=&quot;https://amzn.to/3qhPZA8&quot;&gt;Web+DB PRESS Vol.50&lt;/a&gt;を読むのが一番！&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;477413838X&quot;}&lt;/p&gt;
&lt;p&gt;Web+DBはあまり深く書いていないので、運用しているとかゆいところに手を出そうとしても手が出せない。もっとしっかり理解したい場合は、洋書だけど&lt;a href=&quot;https://amzn.to/3hfQN5l&quot;&gt;Version Control with Git&lt;/a&gt;がいい。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B008Y4OR3A&quot;}&lt;/p&gt;
&lt;h3&gt;TIPS&lt;/h3&gt;
&lt;h4&gt;あるコミット分だけ反映&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;% git fetch
% git-cherry-pick 0e736c1eff177f143ae55ab8971bae6e5753cdb6
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;ワークツリーの変更を取り消し&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;% git checkout -- path/to/file
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;直前のコミット取り消し&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;% git revert HEAD
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;mergeされていないbranchのリスト&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;% git branch --no-merged
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;あとからbranchを作る&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;% git branch new-branch
% git reset --hard 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;CVSやsvnのkeywordパラメータのように、$Id:$を自動的に置換する設定&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;% echo &quot;* ident&quot; &amp;gt;&amp;gt; .gitattributes
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;remote repositoryのbranchを消す&lt;/h4&gt;
&lt;p&gt;空のブランチをremoteにpushすればいい。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git push origin :20090918-sitemap
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;git fetchするだけでは、remoteの消えたbranchをローカルのtracking branchに反映してくれないので、&lt;br /&gt;
ローカルのtracking branchも消す&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git branch -d -r  origin/20090907-sitemap
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;あとからブランチを作る&lt;/h4&gt;
&lt;p&gt;小さな修正だと思って、masterをいじっていたら実は根が深く、branchを作っておけば良かったなぁと思ったときの対処法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git commit -a
% git branch new-branch
% git reset --hard HEAD~1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;worktreeをcommitしておく。現時点の作業がbranchになるため。&lt;br /&gt;
そして、index,worktreeを指定したrevisionに戻す。&lt;/p&gt;
&lt;h4&gt;UNIX設定ファイル共有&lt;/h4&gt;
&lt;p&gt;ホームディレクトリのファイルをgitで管理すると共有が楽。&lt;/p&gt;
</content:encoded></item><item><title>NEC AtermBR-745F68のNATテーブルオーバーフロー問題</title><link>https://blog.teraren.com/posts/atermbr-745f68/</link><guid isPermaLink="true">https://blog.teraren.com/posts/atermbr-745f68/</guid><description>FiberbitレンタルのNEC AtermBR-745F68でNATテーブルがオーバーフローして通信不能になる問題の調査記録</description><pubDate>Thu, 10 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;症状&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://www.fiberbit.net/&quot;&gt;Fiberbit&lt;/a&gt;でレンタルしている&lt;a href=&quot;http://www.cc9.jp/page.jsp?id=1535&quot;&gt;AtermBR&lt;/a&gt;とかいうルータがここ1ヶ月ぐらい調子が悪かった。&lt;/p&gt;
&lt;p&gt;ルータを取り替えても、サポートに3回ぐらい電話しても原因が判明せず。。。「PCが悪い！」とか言われたりもした。&lt;/p&gt;
&lt;h2&gt;原因&lt;/h2&gt;
&lt;p&gt;結局は、このルータのNATテーブルがオーバーフローするのが原因。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;http://butsuyokudaimajin.blogspot.com/2008/02/necnat-tx-error-list-create-error.html&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.google.co.jp/search?q=NEC%E8%A3%BD%E3%83%AB%E3%83%BC%E3%82%BF%E3%83%BC%E8%A2%AB%E5%AE%B3%E8%80%85%E3%81%AE%E4%BC%9A&quot;&gt;NEC製ルーター被害者の会&lt;/a&gt;というスレがいっぱいあった。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ルータのエラーログはこんな感じ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2009/09/10 20:59:54 NAT TX-ERROR List Create Error : TCP 192.168.0.100 : 2693 &amp;gt; 124.83.226.240 : 80 (IP-PORT=1)
2009/09/10 20:59:54 NAT TX-ERROR List Create Error : TCP 192.168.0.100 : 2694 &amp;gt; 124.83.226.240 : 80 (IP-PORT=1)
2009/09/10 20:59:54 NAT TX-ERROR List Create Error : TCP 192.168.0.100 : 2695 &amp;gt; 124.83.226.240 : 80 (IP-PORT=1)
2009/09/10 20:59:54 NAT TX-ERROR List Create Error : TCP 192.168.0.100 : 2696 &amp;gt; 124.83.226.240 : 80 (IP-PORT=1)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;調査（9/14）&lt;/h2&gt;
&lt;p&gt;Fiberbitへこの問題を解決するために電話で相談したが、積極的な対応は得られなかったので、Fiberbitの回線利用を諦めるしかない。ヘビーユーザはFiberbitを使っちゃだめ。&lt;/p&gt;
&lt;p&gt;以下、調査内容。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fiberbitへ別機種の付与を提案&lt;/strong&gt; → 無理。積極的な対応は期待できない。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ルータのNAT周りの設定を変更&lt;/strong&gt; → 設定を変更しても効果無し。NATタイマを短くしても接続できなくなるまでの時間が同じなので、NATタイマの設定が効いていない。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ルータのファームウェアの調査&lt;/strong&gt; → 最新。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;市販のVoIP機器の利用&lt;/strong&gt; → Fiberbitのサポートが得られなくなる。Fiberbitで動作しない可能性がある。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;追記（10/2）&lt;/h2&gt;
&lt;p&gt;このルータのDHCPサーバは重複したIPアドレスを配るという問題もある。ここ3ヶ月で5回ぐらい競合するIPアドレスを配った。&lt;/p&gt;
</content:encoded></item><item><title>YMC VPSベンチマーク</title><link>https://blog.teraren.com/posts/ymc-vps-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ymc-vps-benchmark/</guid><description>YMCのVPSサービス（カスタム10）のApache Benchによる静的HTML配信速度を測定し、表示が遅い原因を調査した記録</description><pubDate>Tue, 08 Sep 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;YMCのVPSを使っています。&lt;br /&gt;
しかしながら、ページ表示速度が遅いのでまず静的HTMLでベンチマーク取ってみました。&lt;br /&gt;
利用しているサービスはカスタム10。&lt;/p&gt;
&lt;h3&gt;測定環境&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;回線:100Mbps　光ファイバ（goo スピードテストで66.37Mbps）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ベンチマーク1&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ルータ経由数：21&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以下、測定結果。&lt;br /&gt;
重要なポイントだけ引用。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% date
Tue Sep  8 01:54:15 JST 2009
% /usr/local/apache2/bin/ab -n 100
Server Software:        Apache/2.2.11

Document Length:        18661 bytes

Concurrency Level:      1
Time taken for tests:   11.174 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      1896400 bytes
HTML transferred:       1866100 bytes
Requests per second:    8.95 [#/sec] (mean)
Time per request:       111.743 [ms] (mean)
Time per request:       111.743 [ms] (mean, across all concurrent requests)
Transfer rate:          165.73 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       23   24   0.5     24      26
Processing:    73   87  51.1     76     350
Waiting:       23   25   1.2     25      32
Total:         98  112  51.1    100     374
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;まとめると以下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;回線が遅い&lt;/li&gt;
&lt;li&gt;レスポンスが来るまでが遅い（Processingの時間が長い）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ベンチマーク2&lt;/h3&gt;
&lt;p&gt;YMCのトップページの表示速度はすごく速いのでベンチマーク取ってみた。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ルータ経由数：16&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% date
Tue Sep  8 01:54:15 JST 2009
% /usr/local/apache2/bin/ab -n 100 http://www.ymc.ne.jp/
This is ApacheBench, Version 2.3 &amp;lt; $Revision: 655654 $&amp;gt;
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.ymc.ne.jp (be patient).....done

Server Software:        Apache/2.0.52
Server Hostname:        www.ymc.ne.jp
Server Port:            80

Document Path:          /
Document Length:        27895 bytes

Concurrency Level:      1
Time taken for tests:   4.105 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      2804900 bytes
HTML transferred:       2789500 bytes
Requests per second:    24.36 [#/sec] (mean)
Time per request:       41.049 [ms] (mean)
Time per request:       41.049 [ms] (mean, across all concurrent requests)
Transfer rate:          667.29 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        4    6   0.5      6       8
Processing:    34   35   0.6     35      38
Waiting:        7    8   0.3      8       9
Total:         39   41   0.8     41      45
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;比較&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;http://chart.apis.google.com/chart?cht=bhs&amp;amp;chs=300x125&amp;amp;chd=t:24,6%7C87,35%7C25,8&amp;amp;chco=4d89f9,c6d9fd,0000FF&amp;amp;chbh=25&amp;amp;chxt=x,y&amp;amp;chxl=0:%7C0%7C160%7C1:%7CYMC%7CVPS&amp;amp;chds=0,160&quot; alt=&quot;benchmark: YMC top VS YMC VPS&quot; /&gt;&lt;/p&gt;
&lt;p&gt;VPSが19KB、YMCのHTMLが28KBなのに、この差。&lt;/p&gt;
</content:encoded></item><item><title>gitでハイフンから始まるブランチ名を削除</title><link>https://blog.teraren.com/posts/git-delete-branch-starting-with-hyphen/</link><guid isPermaLink="true">https://blog.teraren.com/posts/git-delete-branch-starting-with-hyphen/</guid><description>gitでハイフンから始まるブランチ名を削除</description><pubDate>Sat, 29 Aug 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;不覚にもコマンドの打ち間違いをしてしまい、ハイフンから始まるブランチができてしまった。削除するには以下のコマンド。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% git branch -D -- --track
Deleted branch --track (was 2353563).
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;lsと同じ要領で試してみたらできた。&lt;/p&gt;
</content:encoded></item><item><title>メールからRedmineのチケットを登録</title><link>https://blog.teraren.com/posts/2009-08-11-me-rukararedminenochiketowo/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2009-08-11-me-rukararedminenochiketowo/</guid><description>メール送信でRedmineチケットを自動登録する設定方法。qmailでのMTA設定とrdm-mailhandler.rbの使い方、Basic認証時の注意点も解説。</description><pubDate>Tue, 11 Aug 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;メールで議論して、要件が決定し、Redmineへチケットを登録するという流れが往々にしてある。&lt;/p&gt;
&lt;p&gt;しかしながら、メールクライアントを使っているときに、いちいちWebブラウザを立ち上げてチケットを登録するの面倒なので、メールからチケットを登録できるように設定した。&lt;/p&gt;
&lt;p&gt;設定方法はここに書いてあった。ドキュメントは英語にしかないみたい。
&lt;a href=&quot;http://www.redmine.org/wiki/redmine/RedmineReceivingEmails&quot;&gt;http://www.redmine.org/wiki/redmine/RedmineReceivingEmails&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;メールから投稿するには3種類ある。
メール送信後すぐにチケットが登録されて欲しいから、メール受信をアクチュエータとしたチケット登録する設定にする。
上記ページで、&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Forwarding emails from your email server.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;と書いてある項目。&lt;/p&gt;
&lt;p&gt;チケット登録はHTTP上のAPIで登録される。
そのAPIで利用するパスフレーズをRedmineの管理ページから取得する。
&lt;img src=&quot;../../assets/uploads/2009/08/WS0587.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;次にサーバの設定。
MTAがqmailで、メールの宛先を &lt;code&gt;redmine-test@example.com&lt;/code&gt; に送信する場合の設定。
1行書くだけ。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[root@sv2 ~alias]# cd ~alias
[root@sv2 ~alias]# cat .qmail-redmine-test
| /usr/local/bin/ruby /path/to/redmine/extra/mail_handler/rdm-mailhandler.rb --url http://example.com/redmine/ --key YoysTKcWiprqn9TFICZa --project test&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ポイント：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--project&lt;/code&gt;引数の値は、プロジェクトの識別子を指定する。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;これで一通り終わり。&lt;/p&gt;
&lt;p&gt;今回は、redmineにbasic認証をかけていたので、rdm-mailhandler.rbを実行すると&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Response received: 401&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;というエラーが出ていました。コマンドを実行するサーバからは認証無しでAPIにアクセスできるようにapacheを設定した。&lt;/p&gt;
</content:encoded></item><item><title>RedmineとSCMの連携</title><link>https://blog.teraren.com/posts/2009-08-10-redminetoscmno/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2009-08-10-redminetoscmno/</guid><description>Redmineとgit等のSCMを連携させる方法。コミットメッセージにrefs/fixesを書くだけでチケットとの紐付けや自動クローズができる設定を紹介。</description><pubDate>Mon, 10 Aug 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;redmineとSCM(gitなど)が連携して開発者の作業時間を減らす便利な機能を紹介します。&lt;/p&gt;
&lt;p&gt;SCMのコミットメッセージにredmineによって規定されたフォーマットでチケットIDを 記載するとチケットとソースコードの関連性を強化できます。&lt;/p&gt;
&lt;p&gt;■1　チケットとの参照 redmineのチケットとソースコードを関連づけられるので、 redmineに登録されたどの要望によって変更されたcommitかを把握できます。 逆に、あるコミットは何のためのコミットなのかも把握できます。&lt;/p&gt;
&lt;p&gt;要望やバグの細かいことはチケットに書いてある状態になるので、 コミット時に記載するメッセージを省略できます。&lt;/p&gt;
&lt;p&gt;フォーマット： refs # 　（使えるタグ：refs,references,IssueID）&lt;/p&gt;
&lt;p&gt;例： refs 3&lt;/p&gt;
&lt;p&gt;■2　自動的にタスクを終了にする このプロジェクトでは、redmineが共有レポジトリのmasterを監視しています。 共有レポジトリのマスタに反映された時点でタスクが終了に設定されます。&lt;/p&gt;
&lt;p&gt;フォーマット： fixes # 　（使えるタグ：fixes,closes）&lt;/p&gt;
&lt;p&gt;例： fixes 3&lt;/p&gt;
&lt;p&gt;細かいフォーマットはこちら &lt;a href=&quot;http://redmine.jp/tech_note/subversion/&quot;&gt;http://redmine.jp/tech_note/subversion/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;こんな感じに、チケットの詳細に表示される。 &lt;img src=&quot;../../assets/uploads/2009/08/WS0586.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>APCのapc.include_once_override=1は危険・・・</title><link>https://blog.teraren.com/posts/apc-include-once-override1-is-dangerous/</link><guid isPermaLink="true">https://blog.teraren.com/posts/apc-include-once-override1-is-dangerous/</guid><description>APCのapc.include_once_override=1は危険・・・</description><pubDate>Fri, 31 Jul 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;こんなエラーがいっぱい出てた。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Fri Jul 31 17:37:12 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:37:13 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:37:13 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:37:43 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:38:30 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:39:12 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:41:06 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:43:05 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:43:25 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:48:32 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:48:45 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:59:03 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:59:07 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:59:12 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 17:59:24 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 18:01:43 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 18:02:40 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 18:05:20 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 18:05:39 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 18:05:40 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 18:06:34 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
[Fri Jul 31 18:07:36 2009] [apc-error] Cannot redeclare class mail_smtp in /usr/local/lib/php/Mail.php on line 52.
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>andLinuxの起動が恐ろしく速い</title><link>https://blog.teraren.com/posts/andlinux-incredibly-fast-startup/</link><guid isPermaLink="true">https://blog.teraren.com/posts/andlinux-incredibly-fast-startup/</guid><description>andLinuxの起動が恐ろしく速い</description><pubDate>Thu, 23 Jul 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;30秒弱の動画なので見てみてください。&lt;br /&gt;
ブートからログインプロンプトが表示されるまで10秒かかってないです。Windows上でちょちょいと開発するには&lt;a href=&quot;http://www.andlinux.org/&quot;&gt;andLinux&lt;/a&gt;で事足りる。&lt;/p&gt;
&lt;p&gt;https://www.youtube.com/watch?v=ihhK2D-ZyVw&lt;/p&gt;
&lt;p&gt;いままでは、Linux上で動かすプログラム開発するときはVMwareをわざわざ起動していたけどこれでいいや。&lt;/p&gt;
&lt;p&gt;andLinux、意外とすごくて、cygwinと同じレベルでの仮想化と思っていたらもっと低いレイヤで仮想化して居るみたい。&lt;br /&gt;
i386のUbuntuバイナリがそのまま動く。&lt;/p&gt;
&lt;p&gt;なんでかと思ったら、&lt;a href=&quot;http://www.thinkit.co.jp/article/126/1/&quot;&gt;kernelが頑張ってくれたのね&lt;/a&gt;・・・&lt;/p&gt;
</content:encoded></item><item><title>mixi日記をRSS配信するサービスを作りました →廃止</title><link>https://blog.teraren.com/posts/mixi-diary-feed/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mixi-diary-feed/</guid><description>mixi日記をRSS2.0で配信するサービス「mixidiary2feed」の仕様を紹介。mixi IDをURLに指定するだけで12時間キャッシュ・最大30件のフィードが取得可能（現在廃止済み）。</description><pubDate>Thu, 23 Jul 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;メンテナンスが面倒なのでただいま停止しました&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;mixidiary2feed概要&lt;/h2&gt;
&lt;p&gt;mixi日記をRSS2.0で配信するためのサービスを作りました。名前は、&lt;strong&gt;mixidiary2feed&lt;/strong&gt;です。&lt;/p&gt;
&lt;p&gt;使い方は、mixi IDを引数に渡すだけです。&lt;/p&gt;
&lt;p&gt;URLフォーマット：&lt;/p&gt;
&lt;p&gt;https://matsu.teraren.com/contents/RSS.html?id=&lt;strong&gt;mixi ユーザのID&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;URLの例：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://matsu.teraren.com/contents/RSS.html?id=1005&quot;&gt;https://matsu.teraren.com/contents/RSS.html?id=1005&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;目的&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;mixiにログインしたくないけど特定の人のmixi日記をRSSリーダで読む。&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://friendfeed.com/matsubokkuri&quot;&gt;friendfeed&lt;/a&gt;や&lt;a href=&quot;http://twitterfeed.com/&quot;&gt;twitterfeed&lt;/a&gt;にmixi日記を登録する。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;仕様&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;RSS表示のリクエストが来たら、キューに追加し、順次プログラムによって処理されます。&lt;/li&gt;
&lt;li&gt;最低12時間キャッシュされます。&lt;/li&gt;
&lt;li&gt;表示件数は最大30件&lt;/li&gt;
&lt;li&gt;descriptionの文字はmixiの日記一覧で表示される部分に準拠。（約240文字）&lt;/li&gt;
&lt;li&gt;このユーザでクロールします。&lt;a href=&quot;http://mixi.jp/show_friend.pl?id=24146041&quot;&gt;http://mixi.jp/show_friend.pl?id=24146041&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要望などありましたらこの記事のコメントに残して欲しいです。&lt;/p&gt;
&lt;h2&gt;サポートツール&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://matsu.teraren.com/contents/RSSList.html&quot;&gt;RSS一覧&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://matsu.teraren.com/contents/RSSQueue.html&quot;&gt;RSSクロール待ち&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;自分のmixi IDの調べ方&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://mixi.jp/show_profile.pl&quot;&gt;ここを見る&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;更新情報&lt;/h2&gt;
&lt;p&gt;2009年7月23日：リリース&lt;br /&gt;
2009年9月16日：4690ヒット&lt;br /&gt;
2009年12月10日：5589ヒット&lt;br /&gt;
2010年12月18日：パフォーマンス改善&lt;br /&gt;
2012年12月30日：2012年8月ごろから稼働していなかったようなので、稼働するようにしました。&lt;a href=&quot;https://matsu.teraren.com/contents/RSSList.html&quot;&gt;RSS一覧&lt;/a&gt;と&lt;a href=&quot;https://matsu.teraren.com/contents/RSSQueue.html&quot;&gt;RSSクロール待ち&lt;/a&gt;ページを作りました。&lt;br /&gt;
2014年 需要が少なくなってきたので、サービス終了。&lt;/p&gt;
</content:encoded></item><item><title>PHPで先月の求め方</title><link>https://blog.teraren.com/posts/php-get-previous-month/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-get-previous-month/</guid><description>PHPで先月の求め方</description><pubDate>Mon, 29 Jun 2009 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;print date(&apos;n&apos;, strtotime(&apos;- 1 second &apos;, strtotime(date(&apos;Y-m-01&apos;))));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;アプローチは、今月の1日から1秒引いた時の月。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;strtotime(&apos;-1 month&apos;);&lt;/code&gt; はちゃんと返してくれない！&lt;/p&gt;
&lt;p&gt;例えば、7/31の時。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print date(&apos;n&apos;, strtotime(&apos;- 1 month&apos;, strtotime(date(&apos;2009-07-31&apos;)))); // 7が返るからダメ！
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>PHP 5.2.10 configure error</title><link>https://blog.teraren.com/posts/php-5-2-10-configure-error/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-5-2-10-configure-error/</guid><description>Debian 5.0環境でPHP 5.2.10をconfigureした際にlibcurlのヘッダーファイル不足で発生するエラーの解決方法と、5.2.10固有のFatal errorバグについて。</description><pubDate>Sat, 20 Jun 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.php.net/archive/2009.php#id2009-06-18-1&quot;&gt;PHP5.2.10&lt;/a&gt;が出たので開発環境へインストール。&lt;/p&gt;
&lt;p&gt;5.2.8と同じオプションでconfigureしたのにこんなエラーが出た。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ./configure  --enable-mbstring --enable-soap --enable-zend-multibyte --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql --with-curl --with-curlwrappers --with-gd --with-jpeg-dir=/usr/lib --with-png-dir=/usr/lib --with-zlib-dir=/usr/lib --with-mcrypt
.....
configure: error: Please reinstall the libcurl distribution -
    easy.h should be in &amp;lt;curl -dir&amp;gt;/include/curl/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/06/WS0536.JPG&quot; alt=&quot;configure　error&quot; /&gt;&lt;/p&gt;
&lt;p&gt;環境は、&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# cat /etc/issue
Debian GNU/Linux 5.0 \n \l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;headerファイルインストールして解決&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# aptitude install libcurl4-gnutls-dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2009/10/05追記&lt;br /&gt;
5.2.10は微妙。開発環境でしばらく動かしていたが、不定期に以下のエラーが表示される。&lt;br /&gt;
「Fatal error: Exception thrown without a stack frame in Unknown on line 0」&lt;/p&gt;
</content:encoded></item><item><title>ApacheのKeepAliveTimeout</title><link>https://blog.teraren.com/posts/apache-keepalive-timeout/</link><guid isPermaLink="true">https://blog.teraren.com/posts/apache-keepalive-timeout/</guid><description>ApacheのKeepAliveTimeout</description><pubDate>Sat, 13 Jun 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;mixiでは以下の値らしい。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;KeepAlive On
KeepAliveTimeout 1
MaxKeepAliveRequest 20
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;思ったこと：&lt;br /&gt;
KeepAliveTimeoutは1でいいんだ。&lt;/p&gt;
</content:encoded></item><item><title>都道府県マスタ・地域マスタ</title><link>https://blog.teraren.com/posts/prefecture-area-master-data/</link><guid isPermaLink="true">https://blog.teraren.com/posts/prefecture-area-master-data/</guid><description>都道府県マスタ・地域マスタ</description><pubDate>Thu, 04 Jun 2009 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;都道府県&lt;/li&gt;
&lt;li&gt;都道府県の知名度&lt;/li&gt;
&lt;li&gt;地域（関東・東海とか）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;の情報を定義するスキーマとデータ。&lt;/p&gt;
&lt;p&gt;知名度は、&lt;a href=&quot;http://ja.wikipedia.org/wiki/%E9%83%BD%E9%81%93%E5%BA%9C%E7%9C%8C%E3%81%AE%E4%BA%BA%E5%8F%A3%E4%B8%80%E8%A6%A7&quot;&gt;Wikipediaにある2005年時点&lt;/a&gt;の人口を元にプライオリティを付けました。&lt;br /&gt;
数値が高いほど知名度が高いです。&lt;/p&gt;
&lt;p&gt;SQLのデータ（MySQL用）: [&lt;a href=&quot;/uploads/2009/06/prefectures.txt&quot;&gt;ダウンロード&lt;/a&gt;]&lt;/p&gt;
&lt;h2&gt;データ&lt;/h2&gt;
&lt;p&gt;https://gist.github.com/matsubo/5476665&lt;/p&gt;
&lt;p&gt;ER図&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2009/06/ws0526.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2009/06/ws0526.jpg&quot; alt=&quot;ER:region-prefectures&quot; title=&quot;ER:region-prefectures&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;regionテーブル&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2009/06/ws0527.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2009/06/ws0527.jpg&quot; alt=&quot;ws0527&quot; title=&quot;ws0527&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;prefecturesテーブル&lt;br /&gt;
&lt;a href=&quot;../../assets/uploads/2009/06/ws0528.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2009/06/ws0528.jpg&quot; alt=&quot;ws0528&quot; title=&quot;ws0528&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>cronによるコマンド実行順番</title><link>https://blog.teraren.com/posts/cron-command-execution/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cron-command-execution/</guid><description>crontabに同時刻のコマンドを複数登録した場合、同期実行か非同期実行かを実験で検証し、セミコロンを使った同期実行の方法も紹介します。</description><pubDate>Fri, 15 May 2009 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;strong&gt;疑問&lt;/strong&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;crontabへ同時刻に実行するコマンドを書いたときに、各コマンドの終了を待って次に実行するのか？それとも、サブプロセスで実行するのか？&lt;/li&gt;
&lt;li&gt;ひと言で言えば、&lt;strong&gt;同期実行&lt;/strong&gt;か&lt;strong&gt;非同期実行&lt;/strong&gt;でコマンドを実行するのか？&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;strong&gt;答え&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;非同期実行&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;補足: 同期実行させたいときは、こんな感じ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;33 17 * * * /home/matsu/sleep.sh ; /home/matsu/sleep.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;検証&lt;/h2&gt;
&lt;p&gt;実行するファイルの中身。sleep.sh&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh
sleep 60
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;crontabに記述&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[matsu@dev ~]% crontab -l
# m h  dom mon dow   command
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
33 17 * * * /home/matsu/sleep.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;root      2015  0.0  0.0   2192   864 ?        Ss   03:39   0:00 /usr/sbin/cron
root      4339  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4340  0.0  0.1   4992  1412 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4344  0.0  0.0   3612   472 ?        S    17:33   0:00  |       _ sleep 60
root      4341  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4342  0.0  0.1   4992  1412 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4350  0.0  0.0   3608   468 ?        S    17:33   0:00  |       _ sleep 60
root      4343  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4345  0.0  0.1   4988  1408 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4357  0.0  0.0   3608   468 ?        S    17:33   0:00  |       _ sleep 60
root      4346  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4347  0.0  0.1   4988  1404 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4362  0.0  0.0   3608   468 ?        S    17:33   0:00  |       _ sleep 60
root      4348  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4364  0.0  0.1   4988  1408 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4371  0.0  0.0   3612   468 ?        S    17:33   0:00  |       _ sleep 60
root      4349  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4351  0.0  0.1   4988  1408 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4377  0.0  0.0   3608   468 ?        S    17:33   0:00  |       _ sleep 60
root      4352  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4353  0.0  0.1   4988  1408 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4381  0.0  0.0   3612   468 ?        S    17:33   0:00  |       _ sleep 60
root      4354  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4355  0.0  0.1   4988  1408 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4370  0.0  0.0   3608   468 ?        S    17:33   0:00  |       _ sleep 60
root      4356  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4358  0.0  0.1   4992  1408 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4372  0.0  0.0   3612   472 ?        S    17:33   0:00  |       _ sleep 60
root      4359  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4376  0.0  0.1   4988  1408 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4382  0.0  0.0   3608   464 ?        S    17:33   0:00  |       _ sleep 60
root      4360  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4367  0.0  0.1   4992  1412 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4374  0.0  0.0   3608   468 ?        S    17:33   0:00  |       _ sleep 60
root      4361  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4373  0.0  0.1   4988  1404 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4379  0.0  0.0   3608   464 ?        S    17:33   0:00  |       _ sleep 60
root      4363  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4368  0.0  0.1   4988  1404 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4375  0.0  0.0   3608   468 ?        S    17:33   0:00  |       _ sleep 60
root      4365  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4369  0.0  0.1   4992  1408 ?        Ss   17:33   0:00  |   _ /bin/sh /home/matsu/sleep.sh
matsu     4378  0.0  0.0   3612   468 ?        S    17:33   0:00  |       _ sleep 60
root      4366  0.0  0.0   2528   880 ?        S    17:33   0:00  _ /USR/SBIN/CRON
matsu     4380  0.0  0.1   4988  1408 ?        Ss   17:33   0:00      _ /bin/sh /home/matsu/sleep.sh
matsu     4383  0.0  0.0   3608   464 ?        S    17:33   0:00          _ sleep 60
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>PHPでFizzBuzz</title><link>https://blog.teraren.com/posts/php-fizzbuzz/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-fizzbuzz/</guid><description>PHPでFizzBuzz</description><pubDate>Wed, 13 May 2009 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;while(++$i&amp;lt;101)echo $i%15!=0?$i%5!=0?$i%3!=0?$i:Fizz:Buzz:FizzBuzz;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;ワンライナー&lt;/li&gt;
&lt;li&gt;69B&lt;/li&gt;
&lt;li&gt;error levelをNOTICEにしてたらerror出ると思う。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://ja.wikipedia.org/wiki/Fizz_Buzz&quot;&gt;FizzBuzz&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>GClientGeocoder</title><link>https://blog.teraren.com/posts/gclientgeocoder/</link><guid isPermaLink="true">https://blog.teraren.com/posts/gclientgeocoder/</guid><description>Google Maps APIのGClientGeocoderを使って地名や住所から緯度経度を取得するJavaScript実装例。jQueryを使ったサンプルコードとデモリンク付き。</description><pubDate>Tue, 12 May 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://code.google.com/apis/maps/documentation/reference.html#GClientGeocoder&quot;&gt;GClientGeocoder&lt;/a&gt;で地名から緯度経度を取得できる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/05/ws0517.jpg&quot; alt=&quot;ws0517&quot; /&gt;&lt;/p&gt;
&lt;p&gt;GClientGeocoderを使ってテストしてたら、よくテストで入力する用語である「asdf」という地名があった。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/uploads/2009/05/geocoding.html&quot;&gt;geocodingのサンプル実行&lt;/a&gt;&lt;br /&gt;
jquery使ってます。&lt;/p&gt;
&lt;p&gt;住所やsignificant pointから位置情報を得るためのコード抜粋。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getPoint(address)
{
  var geocoder = new GClientGeocoder();
  geocoder.getLatLng(address,
    function showMap(latlng){
      if (latlng){
        move(marker, latlng.lat(), latlng.lng());
        $(&apos;#message&apos;).empty();
      }else{
        $(&apos;#message&apos;).text(&quot;住所から緯度経度に変換できません&quot;);
      }
    }
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;最近右腕＆右肩が痛い！なんでじゃー！&lt;/h2&gt;
</content:encoded></item><item><title>jQueryによるチェックボックス一括チェック</title><link>https://blog.teraren.com/posts/jquery-check-all/</link><guid isPermaLink="true">https://blog.teraren.com/posts/jquery-check-all/</guid><description>jQueryによるチェックボックス一括チェック</description><pubDate>Tue, 12 May 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;今日はJavascripterです。&lt;br /&gt;
管理画面でありがちな行の先頭にあるチェックボックスを一括でチェックする。&lt;/p&gt;
&lt;p&gt;ポイントとなるコード。この1個を置いて適宜selectorを変更する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;input type=&quot;checkbox&quot; id=&quot;checkbox_all&quot; onclick=&quot;$(&apos;:checkbox[type=checkbox][name=something]&apos;).prop(&apos;checked&apos;, $(&apos;#checkbox_all&apos;).prop(&apos;checked&apos;));&quot;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;/uploads/2009/05/check.html&quot;&gt;サンプルコード&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2020/04/ws0518.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>PHPで標準入力読み込み</title><link>https://blog.teraren.com/posts/php-read-stdin/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-read-stdin/</guid><description>PHPで標準入力読み込み</description><pubDate>Thu, 07 May 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;マニュアルに明記されていなかったのでメモ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;file_get_contents(&apos;php://stdin&apos;);
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>見積もり手法</title><link>https://blog.teraren.com/posts/estimation-methods/</link><guid isPermaLink="true">https://blog.teraren.com/posts/estimation-methods/</guid><description>見積もり手法</description><pubDate>Tue, 24 Mar 2009 00:00:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;FP法&lt;/li&gt;
&lt;li&gt;データ・ファンクション&lt;/li&gt;
&lt;li&gt;トランザクション・ファンクション&lt;/li&gt;
&lt;li&gt;LOC&lt;/li&gt;
&lt;li&gt;COCOMO II&lt;/li&gt;
&lt;li&gt;類推法&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>PHPでQRCode</title><link>https://blog.teraren.com/posts/php-qrcode/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-qrcode/</guid><description>PHPのqr拡張モジュールをソースからインストールし、GIF形式のQRコード画像を生成して出力するコード例を紹介</description><pubDate>Sat, 07 Mar 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;PHPでQRコードを作る方法。&lt;br /&gt;
Extensionを使う。&lt;/p&gt;
&lt;p&gt;インストール&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget http://www.opendogs.org/pub/php_qr-0.3.1.tgz
tar zxvf php_qr-0.3.1.tgz
cd php_qr-0.3.1
phpize
./configure --enable-qr
make install
/usr/local/apache2/bin/apachectl graceful
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PHPコード&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$qr = new QRCode();
$qr-&amp;gt;setMagnify(3);
$qr-&amp;gt;setFormat(QRCode::FMT_GIF);
$qr-&amp;gt;addData($data);
$qr-&amp;gt;finalize();

header(&apos;Content-type: image/gif&apos;);
print $qr-&amp;gt;getSymbol();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記以外にもオプションがいっぱい用意されている。&lt;br /&gt;
APIリファレンスが見づらいなぁ。&lt;/p&gt;
&lt;p&gt;Thanks! &lt;a href=&quot;http://d.hatena.ne.jp/rsky/20070503/1178195963&quot;&gt;http://d.hatena.ne.jp/rsky/20070503/1178195963&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>zend frameworkでMobilePictogramConverter</title><link>https://blog.teraren.com/posts/zend-framework-mobilepictogramconverter/</link><guid isPermaLink="true">https://blog.teraren.com/posts/zend-framework-mobilepictogramconverter/</guid><description>Zend FrameworkのOutput Filterを使いMobilePictogramConverterで携帯絵文字をPCブラウザ向けに自動変換する実装方法</description><pubDate>Sun, 01 Mar 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;zend frameworkで絵文字を表示するために、MobilePictogramConverterを使いました。&lt;/p&gt;
&lt;p&gt;説明は少なめで、コードと状態表示をメインに書きます。&lt;br /&gt;
すでに、ページができあがっているという仮定で書きます。&lt;/p&gt;
&lt;h3&gt;背景&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;絵文字出したい。PCで見たら絵文字を画像で出したい。&lt;/li&gt;
&lt;li&gt;自分で実装したライブラリあるけど、昔に作ったから使い方忘れた。&lt;/li&gt;
&lt;li&gt;MobilePictogramConverter使うと楽にできる。&lt;/li&gt;
&lt;li&gt;zend frameworkの公式ドキュメントにはoutput filterの説明が無いので、ここにあるやる方行えばoutput filterを実装できる。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks! &amp;gt; &lt;a href=&quot;http://ishouldbecoding.com/2008/06/04/output-filters-in-zend_view&quot;&gt;http://ishouldbecoding.com/2008/06/04/output-filters-in-zend_view&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;環境&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;バージョン1.7.4で行いました。&lt;/li&gt;
&lt;li&gt;基本携帯向けのサイト。&lt;/li&gt;
&lt;li&gt;全部UTF-8&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;ディレクトリ構成&lt;/h3&gt;
&lt;p&gt;MobilePictogramConverterはlibrary以下に展開します。&lt;br /&gt;
Dandというのは、今作っているアプリケーション名なので、適宜ご自分の環境に合わせて変更してください。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;library/MobilePictogramConverter.php ←MobilePictogramConverter
library/Carrier/*  ←MobilePictogramConverter
library/Dand/Controller/Action.php　←これから作る
library/Dand/View/Filter/Emoji.php ←これから作る
application/controllers/IndexController.php　←表示用Controller
public/_common/images/mobile/* ←MobilePictogramConverterの画像ファイル
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;library/Dand/Controller/Action.php&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
class Dand_Controller_Action extends Zend_Controller_Action
{
    public function init()
    {
       parent::init();
       $this-&amp;gt;_helper-&amp;gt;layout-&amp;gt;getLayoutInstance()-&amp;gt;getView()
            -&amp;gt;addFilterPath(&apos;Dand/View/Filter&apos;, &apos;Dand_View_Filter_&apos;)-&amp;gt;addFilter(&apos;Emoji&apos;);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;library/Dand/View/Filter/Emoji.php&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
class Dand_View_Filter_Emoji
{
    public function filter($string)
    {
        $mpc = MobilePictogramConverter::factory($string, MPC_FROM_FOMA, MPC_FROM_CHARSET_UTF8, MPC_FROM_OPTION_WEB);
        $mpc-&amp;gt;setImagePath(&apos;/_common/images/mobile/&apos;);
        return $mpc-&amp;gt;autoConvert();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;application/controllers/IndexController.php
上で作ったclassを継承。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class IndexController extends Dand_Controller_Action
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;HTMLテンプレートに、Unicodeのコードで絵文字の参照を書いてく。&lt;/p&gt;
&lt;p&gt;す&lt;br /&gt;
ご&lt;br /&gt;
い&lt;/p&gt;
&lt;p&gt;DoCoMoの絵文字Unicode表記は参考。&lt;br /&gt;
&lt;a href=&quot;http://www.unicode.org/~scherer/emoji4unicode/20090206/full.html&quot;&gt;http://www.unicode.org/~scherer/emoji4unicode/20090206/full.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/03/ws0483.jpg&quot; alt=&quot;絵文字&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ブラウザで表示するとこうなる。&lt;/p&gt;
&lt;h3&gt;まとめ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;楽して携帯向けサイト作れる&lt;/li&gt;
&lt;li&gt;今後：Formに入力された絵文字のデコード&lt;/li&gt;
&lt;li&gt;今後：PCでformへ絵文字を復元したときに絵文字をエスケープする&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>PHPでアップロードしたファイルタイプ取得</title><link>https://blog.teraren.com/posts/php-get-uploaded-file-type/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-get-uploaded-file-type/</guid><description>ブラウザ依存の$_FILES[&apos;type&apos;]では不正確なため、finfofやmime_content_typeでサーバ側からファイルタイプを安全に判定する方法を解説</description><pubDate>Thu, 26 Feb 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ユーザがブラウザからファイルをアップロードした際に、サーバでファイルタイプをチェックする方法。&lt;/p&gt;
&lt;p&gt;おおまかに、ブラウザの環境変数から検証する方法と、サーバ側でチェックする方法がある。&lt;/p&gt;
&lt;h3&gt;簡単にチェック&lt;/h3&gt;
&lt;p&gt;まず、$_FILES変数にファイルタイプが設定されているのでこれを使う例。&lt;br /&gt;
typeというキーに入っています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;print_r($_FILES);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;Array
(
    [file] =&amp;gt; Array
        (
            [name] =&amp;gt; site-csv-200902261653.csv
            [type] =&amp;gt; text/comma-separated-values
            [tmp_name] =&amp;gt; /tmp/phpMaX6wO
            [error] =&amp;gt; 0
            [size] =&amp;gt; 3604
        )

)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;しかしながら、ブラウザによってこの値は異なります。（Windows VistaでCSVファイルをアップロードして検証）&lt;br /&gt;
Chromeに至っては、null。。。。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;FF3:text/comma-separated-values&lt;/li&gt;
&lt;li&gt;IE7:application/octet-stream&lt;/li&gt;
&lt;li&gt;Opera: text/comma-separated-values&lt;/li&gt;
&lt;li&gt;safari: application/octet-stream&lt;/li&gt;
&lt;li&gt;chrome: null&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;type変数を信じる場合は、メジャーなブラウザの場合は以下のコードで検証できます。これは、ブラウザ出力を信頼する場合。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$valid_type = array(&apos;text/comma-separated-values&apos;,&apos;application/octet-stream&apos;,null);

if(in_array($_FILES[&apos;file&apos;][&apos;type&apos;], $valid_type){
  print &apos;valid&apos;;
}else{
  print &apos;invalid&apos;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;しっかりチェック&lt;/h3&gt;
&lt;p&gt;サーバ側でちゃんとやるためには、Fileinfoライブラリを使う。&lt;br /&gt;
FileinfoはPECLで提供されている。libmagicライブラリに依存している。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# aptitude install libmagic-dev
# pecl install fileinfo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;php.iniに以下を追加して、サーバ再起動。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;extension=&apos;fileinfo.so&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のように書けば、ファイルタイプを返してくれる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$finfo = finfo_open(FILEINFO_MIME);
echo finfo_file($finfo, $csv_file) . &quot;\n&quot;;
finfo_close($finfo);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;text/plain charset=unknown
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;判定は以下のように。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$finfo = finfo_open(FILEINFO_MIME);
$type = finfo_file($finfo, $csv_file) ;
finfo_close($finfo);

if(strpos($type, &apos;text/plain&apos;) !== false){
  print &apos;valid&apos;;
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>qmail log</title><link>https://blog.teraren.com/posts/qmail-log/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qmail-log/</guid><description>qmail log</description><pubDate>Sat, 21 Feb 2009 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;2009-01-21 23:10:15.386280500 new msg 819216
2009-01-21 23:10:15.419363500 info msg 819216: bytes 5249 from  qp 27362 uid 2005
2009-01-21 23:10:15.466129500 starting delivery 127180: msg 819216 to local foo@example.com
2009-01-21 23:10:15.466132500 status: local 2/10 remote 0/20
2009-01-21 23:10:15.466133500 delivery 127179: success: did_0+1+0/qp_27362/
2009-01-21 23:10:15.466135500 status: local 1/10 remote 0/20
2009-01-21 23:10:15.482058500 end msg 819215
2009-01-21 23:10:15.522811500 delivery 127180: success: did_0+0+1/
2009-01-21 23:10:15.522814500 status: local 0/10 remote 0/20
2009-01-21 23:10:15.522815500 end msg 819216
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;qmailの挙動を追うために、qmailのログを見ていると、メッセージのID(new msg xxxxのxxxxの所)がいっぱい重複していた。&lt;br /&gt;
このメッセージIDはinode番号らしい。だから、重複する。（トラッキングしづらくて困るけど）&lt;/p&gt;
&lt;p&gt;delivery idはincrementされた数字なので、しばらくの期間は重複しない。&lt;/p&gt;
</content:encoded></item><item><title>vmwareの時間がものすごくずれる</title><link>https://blog.teraren.com/posts/vmware-time-drift/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vmware-time-drift/</guid><description>vmwareの時間がものすごくずれる</description><pubDate>Tue, 17 Feb 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;VMware 2.0 でうごいているクライアントホストの時計が、10分で2分ぐらいずれるという恐ろしい事になっていた。 VMware1.xの時はそこまでずれていなく、1時間に1回だけNTPサーバと同期していたが、それでは済まないレベル。 こちらに、解決法が載っていました。 &lt;a href=&quot;http://webos-goodies.jp/archives/50179807.html&quot;&gt;http://webos-goodies.jp/archives/50179807.html&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>vmware server 2.0 on Ubuntu Linux</title><link>https://blog.teraren.com/posts/vmware-server-20-on-ubuntu-linux/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vmware-server-20-on-ubuntu-linux/</guid><description>VMware Server 2.0をUbuntu 8.10にインストールしてWindowsゲストを動かすまでの手順を、実際のコマンドログとともに紹介します。</description><pubDate>Wed, 11 Feb 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;vmware server 2.0をUbuntu 8.10へ入れてみた。&lt;/p&gt;
&lt;h3&gt;インストール手順&lt;/h3&gt;
&lt;p&gt;シリアルキー以外をコピペ。&lt;br /&gt;
ほとんどデフォルト値でEnterを押していく。インストール先や、ブリッジするNICの設定などを適宜変更していく。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[matsu@matsu-ubuntu ~/archive]% tar zxvf VMware-server-2.0.0-122956.i386.tar.gz
[matsu@matsu-ubuntu ~/archive]% cd vmware-server-distrib
[matsu@matsu-ubuntu ~/archive/vmware-server-distrib]% sudo ./vmware-install.pl
[sudo] password for matsu:
Creating a new VMware Server installer database using the tar4 format.

Installing VMware Server.

In which directory do you want to install the binary files?
[/usr/bin] /usr/local/bin/

What is the directory that contains the init directories (rc0.d/ to rc6.d/)?
[/etc]

What is the directory that contains the init scripts?
[/etc/init.d]

In which directory do you want to install the daemon files?
[/usr/local/sbin]

In which directory do you want to install the library files?
[/usr/local/lib/vmware]

The path &quot;/usr/local/lib/vmware&quot; does not exist currently. This program is
going to create it, including needed parent directories. Is this what you want?
[yes]

In which directory do you want to install the manual files?
[/usr/local/share/man]

In which directory do you want to install the documentation files?
[/usr/local/doc/vmware]

The path &quot;/usr/local/doc/vmware&quot; does not exist currently. This program is
going to create it, including needed parent directories. Is this what you want?
[yes]

The installation of VMware Server 2.0.0 build-122956 for Linux completed
successfully. You can decide to remove this software from your system at any
time by invoking the following command: &quot;/usr/local/bin/vmware-uninstall.pl&quot;.

Before running VMware Server for the first time, you need to configure it by
invoking the following command: &quot;/usr/local/bin/vmware-config.pl&quot;. Do you want
this program to invoke the command for you now? [yes]

Making sure services for VMware Server are stopped.

Stopping VMware autostart virtual machines:
   Virtual machines                                                   failed
Stopping VMware management services:
   VMware Virtual Infrastructure Web Access
   VMware Server Host Agent                                           failed
Stopping VMware services:
   VMware Authentication Daemon                                        done
   Virtual machine monitor                                             done

You must read and accept the End User License Agreement to continue.
Press enter to display it.

NOTICE:  BY DOWNLOADING AND INSTALLING, COPYING OR OTHERWISE USING THE
SOFTWARE, YOU AGREE TO BE BOUND BY THE TERMS OF THIS VMWARE MASTER END
USER LICENSE AGREEMENT (&quot;EULA&quot;).  IF YOU DO NOT AGREE TO THE TERMS OF
THIS EULA, YOU MAY NOT DOWNLOAD, INSTALL, COPY OR USE THE SOFTWARE, AND
YOU MAY RETURN THE UNUSED SOFTWARE TO THE VENDOR FROM WHICH YOU ACQUIRED
IT WITHIN THIRTY (30) DAYS AND REQUEST A REFUND OF THE LICENSE FEE, IF
ANY, ALREADY PAID UPON SHOWING PROOF OF PAYMENT.  &quot;YOU&quot; MEANS THE
NATURAL PERSON OR THE ENTITY THAT IS AGREEING TO BE BOUND BY THIS EULA,
THEIR EMPLOYEES AND THIRD PARTY CONTRACTORS THAT PROVIDE SERVICES TO
YOU.  YOU SHALL BE LIABLE FOR ANY FAILURE BY SUCH EMPLOYEES AND THIRD
PARTY CONTRACTORS TO COMPLY WITH THE TERMS OF THIS AGREEMENT.

1.      DEFINITIONS

1.1     &quot;Designated Administrative Access&quot; means that access to the
standard user interfaces of a given instance of the Software
(designated in this section) that you may grant to a designated
third party (a) for which you have provided advance written notice
to VMware that you are providing outsourced services and (b) for
whose dedicated benefit you have licensed such instance of the
Software.  Designated Administrative Access is applicable only
where you are 1) an IT outsourcing company that is providing
outsourced IT services to a client company and 2) applicable only
to the following Software: ESX Server, VMware Server and
VirtualCenter.

1.2     &quot;GPL Software&quot; means GPL software licensed to you under the GNU
General Public License as published by the Free Software Foundation
(GPL).  A copy of the GPL is included on the media on which you
received the Software or included in the files you downloaded, if
you acquired the Software by electronic download.

1.3     &quot;Guest Operating Systems&quot; means instances of third-party operating
systems licensed by you and installed in a Virtual Machine and run
using the Software.

1.4     &quot;Licensed Additional Module&quot; means additional modules that may be
provided with and/or used in conjunction with the Software for
which you have paid the applicable license fee and accepted any
applicable additional license terms.

1.5     &quot;Open Source Software&quot; means various open source software
components licensed under the terms of applicable open source
license agreements included in the materials relating to such
software.  Open Source Software is composed of individual software
components, each of which has its own copyright and its own
applicable license conditions.  The Open Source Software licenses
can be found in the open_source_licenses.txt file, other materials
accompanying the software package, the documentation or
corresponding source files available at
http://www.vmware.com/download/open_source.html.

1.6     &quot;Processor&quot; means a single, physical chip that houses no more than
four (4) processor cores.

1.7     &quot;Sample Programs&quot; means sample client management programs or
scripts that may be distributed with the Software.

1.8     &quot;Server&quot; means a single physical computer of a type that meets the
specifications as set forth in the applicable product documentation
posted at  http://www.vmware.com/support/pubs/.  Multiple computers
that share processing power or operate in a networked configuration
as a single logical computer, such as a &quot;server farm&quot; or similar
arrangement, constitute multiple Servers for the purpose of this
EULA.

1.9     &quot;Software&quot; means software products that are licensed to you under
this EULA, including, but not limited to, any related components
purchased or provided with the Software, application programming
interfaces, associated media, printed materials, online or
electronic documentation, and any updates and maintenance releases
thereto.

1.10    &quot;Software License Key&quot; means, if applicable, a serial number issued
to you by VMware to activate and use the Software.   A separate,
additional Software License Key may be required to activate and use
each Licensed Additional Module.

1.11  &quot;VMware Tools&quot; means a suite of utilities and drivers that may
enhance the performance and functionality of your Guest Operating
System. VMware Tools may include some or all of the following,
depending on your Guest Operating System: an SVGA driver, a mouse

driver, the VMware Tools control panel and support for features
such as shared folders, drag and drop in Windows guests, shrinking
virtual disks, time synchronization with the host, VMware Tools
scripts, and connection and disconnection of devices while the
virtual machine is running.

1.12    &quot;Virtual Machine&quot; means an instance of a Guest Operating System and
any application programs installed thereon, running on a computing
device on which the Software is installed, or suspended to disk or
any other storage media accessible by the computing device.

2.      EVALUATION LICENSES

2.1     General.  If available, the Software and each Licensed Additional
Module may be activated with no-cost evaluation Software License
Key(s).  You acknowledge that Evaluation Software License Keys have
an expiration date (&quot;Expiration Date&quot;) and that VMware is not
obligated to permit further use of the Software.

2.2     Evaluation License.  If you activate the Software or any Licensed
Additional Module with an evaluation Software License Key
(&quot;Evaluation Product&quot;) you may use the Evaluation Product until the
Expiration Date only to evaluate the suitability of the Evaluation
Product for licensing on a for-fee basis.  You may acquire
evaluation Software License Key(s) for Licensed Additional Modules.
In such case, the Licensed Additional Modules are licensed to you
subject to the terms of this &quot;EVALUATION LICENSES&quot; section.

2.3     Evaluation Product Warranty Disclaimer.  During the use of the
Evaluation Product, the limited 90-day warranty referenced in
Section 7.1 below is not applicable to you.  THE EVALUATION PRODUCT
IS PROVIDED TO YOU &quot;AS IS&quot; WITHOUT WARRANTY OF ANY KIND, WHETHER
EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE.  VMWARE AND ITS
LICENSORS BEAR NO LIABILITY FOR ANY DAMAGES RESULTING FROM USE (OR
ATTEMPTED USE) OF THE EVALUATION PRODUCT THROUGH AND AFTER THE
EXPIRATION DATE.

2.4     No Support.  VMware has no duty to provide support to you during
your use of the Evaluation Product.

3.      GRANT AND USE RIGHTS FOR SOFTWARE.

3.1     License.  The Software is licensed, not sold.  Subject to the terms
of this EULA, VMware hereby grants you a non-exclusive, non-
transferable license, without rights to sublicense, to use the
object code of the Software for the purpose as set forth in the
applicable documentation for the Software and to the extent
permitted by your payment of applicable license fees under a VMware
approved licensing model and/or your Software License Key subject
to the software product specific terms specified in this EULA.
Depending upon the model utilized to compute the applicable license
fees paid by you to use the Software (whether per Processor, per
Virtual Machine, per user, or any other VMware approved licensing
model), an applicable Software License Key may limit your usage of
the Software accordingly.  You may use the documentation

accompanying the Software in connection with permitted uses of the
Software.  If the Software is a version that you have converted or
exchanged from a valid licensed prior version, you agree that by
using the Software you will no longer use the prior version.
VMware reserves the right to require the certification of the
destruction of such previous version of the Software.

3.2     License Limitations.  You may not copy the Software except for a
reasonable number of machine-readable copies of the Software for
backup or archival purposes and except as expressly permitted in
this EULA.  You may not remove any titles, trademarks or trade
names, copyright notices, legends, or other proprietary markings on
the Software.  You are not granted any rights to any trademarks or
service marks of VMware.  VMware retains all rights not expressly
granted to you in this EULA.

3.3     Restrictions.  You may not (i) sell, lease, license, sublicense,
distribute or otherwise transfer in whole or in part the Software
or the Software License Key to another party; (ii) provide,
disclose, divulge or make available to, or permit use of the
Software in whole or in part by, any third party (except Designated
Administrative Access) without VMware&apos;s prior written consent; or
(iii) modify or create derivative works based upon the Software.
Except to the extent expressly permitted by applicable law, and to
the extent that VMware is not permitted by that applicable law to
exclude or limit the following rights, you may not decompile,
disassemble, reverse engineer, or otherwise attempt to derive
source code from the Software, in whole or in part.   You may use
the Software to conduct internal performance testing and
benchmarking studies, the results of which you (and not
unauthorized third parties) may publish or publicly disseminate;
provided that VMware has reviewed and approved of the methodology,
assumptions and other parameters of the study.  Please contact
VMware at benchmark@vmware.com to request such review.

3.4     GPL Software. You can redistribute and/or modify the GPL Software
under the terms of the GPL.  You may obtain a copy of the source
code corresponding to the binaries for the GPL Software (the &quot;GPL
Source Files&quot;) by downloading the GPL Source Files from VMware&apos;s
Web site at http://www.vmware.com/download/open_source.html, or by
sending a request, with your name and address, to Vmware at the
address specified under the heading &quot;Contact Information&quot; below, in
which case Vmware will mail a copy of the GPL Source Files to you
on a CD or equivalent physical medium.  This offer to obtain a copy
of the GPL Source Files is valid for three years from the date you
acquired this Software product.

3.5     VMware Tools.  You may distribute the VMware Tools to any third
party provided that (i) you do not modify the VMware Tools; (ii)
you distribute the VMware Tools in object code format only and
solely in conjunction with, and as part of, the Virtual Machine you
create with the Software; (iii) you do not use VMware&apos;s name, logo
or trademarks to market the Virtual Machine you create with the
Software and (iv) you agree to indemnify, hold harmless, and defend
VMware from and against any claims or lawsuits, including
attorneys&apos; fees, that arise or result from the use or distribution

of the Virtual Machine you create.  Notwithstanding the foregoing,
you may refer to VMware names, logos or trademarks to indicate that
the Virtual Machine you create with the Software are compatible
with or designed for use with the Software.

3.6     Licenses required for third-party software.  The Software enables
you to run multiple instances of third-party guest operating
systems and application programs. You are responsible for obtaining
any licenses necessary to operate any such third-party software,
including Guest Operating Systems.

3.7     Sample Programs.  The Software may include Sample Programs.  You
may use and distribute Sample Programs under the terms set forth in
the applicable Sample Programs files.  VMware does not provide
support services for Sample Programs.

3.8     VMware License Programs.  VMware makes available VMware License
programs (for e.g., VMware Academic License).  If you have received
the Software pursuant to these VMware License programs, the then-
current terms and conditions posted on
http://www.vmware.com/download/eula/vmtn.html
for that program shall apply for use of the products under such
VMware License programs.

3.9     Audit Rights.   You will maintain accurate records as to your use of
the Software as authorized by this EULA, for at least two (2) years
from the last day on which support and subscription services
(&quot;Services&quot;) expired for the applicable Software.  VMware, or
persons designated by VMware, will, at any time during the period
when you are obliged to maintain such records, be entitled to
inspect such records and your computing devices, in order to verify
that the Software is used by you in accordance with the terms of
this EULA and that you have paid the applicable license fees and
Services fees for the Software; provided that VMware may conduct no
more than one (1) audit in any twelve (12) month period.  You shall
promptly pay to VMware any underpayments revealed by any such
audit.  Any such audit will be performed at VMware&apos;s expense during
normal business hours, provided that you shall promptly reimburse
VMware for the cost of such audit and any applicable fees if such
audit reveals an underpayment by you of more than five percent (5%)
of the amounts payable by you to VMware for the period audited.

4.      TITLE.  VMware retains all right, title, and interest in and to the
Software and the Software License Key and in all related
copyrights, trade secrets, patents, trademarks, and any other
intellectual and industrial property and proprietary rights,
including registrations, applications, renewals, and extensions of
such rights.

5.      SUPPORT AND SUBSCRIPTION SERVICES NOT INCLUDED

VMware will not provide any support services under this EULA.  This
EULA does not give you any rights to any updates or upgrades to the
Software or to any extensions or enhancements to the Software
developed by VMware at any time in the future.   VMware may offer
support and subscription services separately.  If you have
purchased VMware support and subscription services with the

Software, these services are provided to you under the Support
Contract Terms and Conditions posted on VMware&apos;s Web site at
http://www.vmware.com/support/  and by accepting the terms of this
EULA you are accepting these Support Contract Terms and Conditions.
Any supplemental software code or related materials that VMware
provides to you as part of any support and subscription services
are to be considered part of the Software and are subject to the
terms and conditions of this EULA.  VMware may use any technical
information you provide to VMware for any VMware business purposes
without restriction, including for product support and development.
VMware will not use information in a form that personally
identifies you.

6.      TERMINATION

6.1     Termination.  VMware may terminate this EULA immediately and
without notice if you fail to comply with any term of this EULA.

6.2     Effect of Termination.  In the event of termination, you must
destroy all copies of the Software and Software License Key.  In
addition you must remove all copies of the Software, including all
backup copies, from the Server and all computers and terminals on
which it is installed.  From time to time, VMware may change the
terms of this EULA.  VMware will notify you of such change.  Your
continued use of the Software will indicate your agreement to the
change.

7.      LIMITED WARRANTY AND LIMITATION OF LIABILITY

7.1     Limited Warranty. VMware warrants that the media, if any, on which
the Software is delivered will be free of defects and that the Software
will substantially conform to the description contained in the
applicable end user documentation with respect to the particular
Software licensed under this EULA in each case for a period of 90 days
after the date of shipment of the Software License Key to you (&quot;Warranty
Period&quot;).  If during the Warranty Period the media is defective and the
version of that Software is still commercially available, your sole
remedy will be that VMware shall, at its option, repair or replace the
defective media returned to VMware within the Warranty Period.  If you
are returning a defective media, please email VMware at sales@vmware.com
to request a Return Authorization number (RMA) and further instructions.
If during the Warranty Period the Software does not substantially
conform to the description contained in the applicable end user
documentation, your sole remedy will be that VMware shall, at it option,
correct the defects in the Software or refund the license fees you paid,
if any, related to the Software provided that (a) the Software has been
properly installed and used at all times and in accordance with the
instructions in the applicable end user documentation; (b) no
modification, alteration or addition has been made to the Software
product by persons other than VMware or VMware&apos;s authorized
representative; and (c) VMware receives written notice of the non-
conformity within ninety (90) days following shipment.  EXCEPT FOR THE
PRECEDING EXPRESS LIMITED WARRANTY, TO THE MAXIMUM EXTENT PERMITTED BY
APPLICABLE MANDATORY LAW, VMWARE AND ITS LICENSORS PROVIDE THE SOFTWARE
WITHOUT ANY WARRANTIES OF ANY KIND, EXPRESS, IMPLIED, STATUTORY, OR IN
ANY OTHER PROVISION OF THIS EULA OR COMMUNICATION WITH YOU, AND VMWARE

AND ITS LICENSORS SPECIFICALLY DISCLAIM ANY IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.

7.2     LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY
APPLICABLE MANDATORY LAW, IN NO EVENT WILL VMWARE AND ITS LICENSORS BE
LIABLE FOR ANY LOST PROFITS OR BUSINESS OPPORTUNITIES, LOSS OF USE,
BUSINESS INTERRUPTION, LOSS OF DATA, OR ANY OTHER INDIRECT, SPECIAL,
INCIDENTAL, OR CONSEQUENTIAL DAMAGES UNDER ANY THEORY OF LIABILITY,
WHETHER BASED IN CONTRACT, TORT, NEGLIGENCE, PRODUCT LIABILITY, OR
OTHERWISE.  BECAUSE SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR
LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE
PRECEDING LIMITATION MAY NOT APPLY TO YOU.  VMWARE AND ITS LICENSORS&apos;
LIABILITY UNDER THIS EULA WILL NOT, IN ANY EVENT, EXCEED THE LICENSE
FEES, IF ANY, PAID BY YOU FOR THE SOFTWARE LICENSED TO YOU UNDER THIS
EULA. THE FOREGOING LIMITATIONS SHALL APPLY TO THE MAXIMUM EXTENT
PERMITTED BY APPLICABLE LAW, REGARDLESS OF WHETHER VMWARE OR ITS
LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES AND
REGARDLESS OF WHETHER ANY REMEDY FAILS OF ITS ESSENTIAL PURPOSE.

8.      GENERAL

8.1    Entire Agreement. This Agreement sets forth VMware&apos;s entire
liability and your exclusive remedy with respect to the Software
and supersedes the terms of any purchase orders and any other
communications or advertising with respect to the Software. You
acknowledge that this Agreement is a complete statement of the
agreement between you and VMware with respect to the Software, and
that there are no other prior or contemporaneous understandings,
promises, representations, or descriptions with respect to the
Software.

8.2     Headings. Headings under this EULA are intended only for
convenience and shall not affect the interpretation of this EULA.

8.3     Waiver and Modification.  No failure of either party to exercise or
enforce any of its rights under this EULA will act as a waiver of
those rights.  This EULA may only be modified, or any rights under
it waived, by a written document executed by the party against
which it is asserted.

8.4     Severability.  If any provision of this EULA is found illegal or
unenforceable, it will be enforced to the maximum extent
permissible, and the legality and enforceability of the other
provisions of this EULA will not be affected.

8.5     Governing Law.  This EULA will be governed by California law and
the United States of America, without regard to its choice of law
principles. The United Nations Convention for the International
Sale of Goods shall not apply.

8.6     Government Restrictions.  You may not export or re-export the Soft-
ware except in compliance with the United States Export
Administration Act and the related rules and regulations and
similar non-U.S. government restrictions, if applicable.  The
Software and accompanying documentation are deemed to be
&quot;commercial computer software&quot; and &quot;commercial computer software
documentation,&quot; respectively, pursuant to DFAR Section 227.7202 and
FAR Section 12.212(b), as applicable.  Any use, modification,
reproduction, release, performing, displaying, or disclosing of the
Software by the U.S. Government shall be governed solely by the
terms of this EULA.

8.7     Contact Information.  If you have any questions about this EULA, or
if you want to contact VMware for any reason, please direct all
correspondence to: VMware, Inc., 3401 Hillview Avenue, Palo Alto,
CA 94304, United States of America or email info@vmware.com.

8.8     Other. VMware and VMTN are trademarks and/or registered trademarks
of VMware, Inc. in the United States and/or various jurisdictions.

9.      SOFTWARE PRODUCT SPECIFIC TERMS AND CONDITIONS

In addition to the above, the following Software products shall also be
subject to the following terms and conditions set forth below.  In the
event of any conflict between the following product-specific terms and
conditions and the preceding sections, the product-specific terms and
conditions shall control.

9.1     VMware Server:
(a) Additional Definitions:
&quot;Redistributable Components&quot; means the Programming API library that may
be provided in conjunction with the Software and licensed under the
Redistributable Components product specific terms and conditions.
 &quot;VirtualCenter Server Software&quot; is a proprietary component of the
Software which includes, without limitation, the management agent
software that is installed on each managed Server and a proprietary Web
Service Interface.
&quot;VMware Virtual Infrastructure Client Software&quot; is a proprietary client
component of the Software that provides the user interface and enables
management of the Software.
&quot;VMware WebAccess&quot; is a proprietary component that provides console
access to and management of Virtual Machines created with the Software.
&quot;Web Service Interface&quot; means a programmatic interface to perform
management operations on Servers that are activated for management by
the VirtualCenter Server Software through software programs written by
you or a third party.
(b) Additional License Terms:
VMware grants you a nonexclusive, nontransferable license, without
rights to sublicense, to (i) install or have installed a single instance
of the Software and each Licensed Additional Module on a single Server,
unless permitted by VMware to have multiple instances on a single Server
or to have multiple instances on multiple Servers; (ii) use the Software
and each Licensed Additional Module solely for information processing
and computing purposes, including the hosting of computer application-
based services from a Virtual Machine and provision of such services via
an internal or external network, provided such services may not consist
of services to a third party that provide primarily computing or
processing power (such as utility computing or grid computing) or any
computer application-based service that is traded, rented, leased or
sold on a Virtual Machine basis; and (iii) use and reproduce the VMware
Virtual Infrastructure Client Software or VMware WebAccess (in object
code form only) for the purposes of installation and operation on an
unlimited number of your own internal computers or terminals solely for
the purpose of accessing the Server on which the Software is installed;
(iv) internally use and reproduce the Redistributable Components to
create programs that interface with the Redistributable Components to
manage Virtual Machines (&quot;Your Management Programs&quot;); and (v) internally
use Your Management Programs solely for the purpose of managing Virtual
Machines operated on VMware software products installed on your own
internal Servers and computers. Subject to the above, each copy of the
Software may not be used by any other person, whether or not such person
is employed by or otherwise associated with your entity.
Distributing the Software.  VMware Server is intended for your personal
non-commercial use only. If you are interested in distributing the
Software for internal or external use, promotion, review or as part of a
solution, please apply now at http://www.vmware.com/go/distribution.

Do you accept? (yes/no) yes

Thank you.

None of the pre-built vmmon modules for VMware Server is suitable for your
running kernel.  Do you want this program to try to build the vmmon module for
your system (you need to have a C compiler installed on your system)? [yes]

Using compiler &quot;/usr/bin/gcc&quot;. Use environment variable CC to override.

What is the location of the directory of C header files that match your running
kernel? [/lib/modules/2.6.27-11-generic/build/include]

Extracting the sources of the vmmon module.

Building the vmmon module.

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config0/vmmon-only&apos;
make -C /lib/modules/2.6.27-11-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
  CC [M]  /tmp/vmware-config0/vmmon-only/linux/driver.o
  CC [M]  /tmp/vmware-config0/vmmon-only/linux/driverLog.o
  CC [M]  /tmp/vmware-config0/vmmon-only/linux/hostif.o
  CC [M]  /tmp/vmware-config0/vmmon-only/common/comport.o
  CC [M]  /tmp/vmware-config0/vmmon-only/common/cpuid.o
  CC [M]  /tmp/vmware-config0/vmmon-only/common/hashFunc.o
  CC [M]  /tmp/vmware-config0/vmmon-only/common/memtrack.o
  CC [M]  /tmp/vmware-config0/vmmon-only/common/phystrack.o
  CC [M]  /tmp/vmware-config0/vmmon-only/common/task.o
  CC [M]  /tmp/vmware-config0/vmmon-only/common/vmx86.o
  CC [M]  /tmp/vmware-config0/vmmon-only/vmcore/moduleloop.o
  LD [M]  /tmp/vmware-config0/vmmon-only/vmmon.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /tmp/vmware-config0/vmmon-only/vmmon.mod.o
  LD [M]  /tmp/vmware-config0/vmmon-only/vmmon.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
cp -f vmmon.ko ./../vmmon.o
make: Leaving directory `/tmp/vmware-config0/vmmon-only&apos;
The vmmon module loads perfectly into the running kernel.

None of the pre-built vmci modules for VMware Server is suitable for your
running kernel.  Do you want this program to try to build the vmci module for
your system (you need to have a C compiler installed on your system)? [yes]

Extracting the sources of the vmci module.

Building the vmci module.

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config0/vmci-only&apos;
make -C /lib/modules/2.6.27-11-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
  CC [M]  /tmp/vmware-config0/vmci-only/linux/driver.o
  CC [M]  /tmp/vmware-config0/vmci-only/linux/driverLog.o
  CC [M]  /tmp/vmware-config0/vmci-only/linux/vmciKernelIf.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciContext.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciDatagram.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciDriver.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciDs.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciEvent.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciGroup.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciHashtable.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciProcess.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciQueuePair.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciResource.o
  LD [M]  /tmp/vmware-config0/vmci-only/vmci.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /tmp/vmware-config0/vmci-only/vmci.mod.o
  LD [M]  /tmp/vmware-config0/vmci-only/vmci.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
cp -f vmci.ko ./../vmci.o
make: Leaving directory `/tmp/vmware-config0/vmci-only&apos;
The vmci module loads perfectly into the running kernel.

None of the pre-built vsock modules for VMware Server is suitable for your
running kernel.  Do you want this program to try to build the vsock module for
your system (you need to have a C compiler installed on your system)? [yes]

Extracting the sources of the vsock module.

Building the vsock module.

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config0/vsock-only&apos;
make -C /lib/modules/2.6.27-11-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
  CC [M]  /tmp/vmware-config0/vsock-only/linux/af_vsock.o
  CC [M]  /tmp/vmware-config0/vsock-only/linux/driverLog.o
  CC [M]  /tmp/vmware-config0/vsock-only/linux/util.o
/tmp/vmware-config0/vsock-only/linux/util.c: In function ‘VSockVmciLogPkt’:
/tmp/vmware-config0/vsock-only/linux/util.c:157: warning: format not a string literal and no format arguments
  CC [M]  /tmp/vmware-config0/vsock-only/linux/vsockAddr.o
  LD [M]  /tmp/vmware-config0/vsock-only/vsock.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /tmp/vmware-config0/vmmon-only/vmmon.mod.o
  LD [M]  /tmp/vmware-config0/vmmon-only/vmmon.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
cp -f vmmon.ko ./../vmmon.o
make: Leaving directory `/tmp/vmware-config0/vmmon-only&apos;
The vmmon module loads perfectly into the running kernel.

None of the pre-built vmci modules for VMware Server is suitable for your
running kernel.  Do you want this program to try to build the vmci module for
your system (you need to have a C compiler installed on your system)? [yes]

Extracting the sources of the vmci module.

Building the vmci module.

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config0/vmci-only&apos;
make -C /lib/modules/2.6.27-11-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
  CC [M]  /tmp/vmware-config0/vmci-only/linux/driver.o
  CC [M]  /tmp/vmware-config0/vmci-only/linux/driverLog.o
  CC [M]  /tmp/vmware-config0/vmci-only/linux/vmciKernelIf.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciContext.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciDatagram.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciDriver.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciDs.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciEvent.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciGroup.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciHashtable.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciProcess.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciQueuePair.o
  CC [M]  /tmp/vmware-config0/vmci-only/common/vmciResource.o
  LD [M]  /tmp/vmware-config0/vmci-only/vmci.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /tmp/vmware-config0/vmci-only/vmci.mod.o
  LD [M]  /tmp/vmware-config0/vmci-only/vmci.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
cp -f vmci.ko ./../vmci.o
make: Leaving directory `/tmp/vmware-config0/vmci-only&apos;
The vmci module loads perfectly into the running kernel.

None of the pre-built vsock modules for VMware Server is suitable for your
running kernel.  Do you want this program to try to build the vsock module for
your system (you need to have a C compiler installed on your system)? [yes]

Extracting the sources of the vsock module.

Building the vsock module.

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config0/vsock-only&apos;
make -C /lib/modules/2.6.27-11-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
  CC [M]  /tmp/vmware-config0/vsock-only/linux/af_vsock.o
  CC [M]  /tmp/vmware-config0/vsock-only/linux/driverLog.o
  CC [M]  /tmp/vmware-config0/vsock-only/linux/util.o
/tmp/vmware-config0/vsock-only/linux/util.c: In function ‘VSockVmciLogPkt’:
/tmp/vmware-config0/vsock-only/linux/util.c:157: warning: format not a string literal and no format arguments
  CC [M]  /tmp/vmware-config0/vsock-only/linux/vsockAddr.o
  LD [M]  /tmp/vmware-config0/vsock-only/vsock.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: &quot;VMCIDatagram_CreateHnd&quot; [/tmp/vmware-config0/vsock-only/vsock.ko] undefined!
WARNING: &quot;VMCIDatagram_DestroyHnd&quot; [/tmp/vmware-config0/vsock-only/vsock.ko] undefined!
WARNING: &quot;VMCI_GetContextID&quot; [/tmp/vmware-config0/vsock-only/vsock.ko] undefined!
WARNING: &quot;VMCIDatagram_Send&quot; [/tmp/vmware-config0/vsock-only/vsock.ko] undefined!
  CC      /tmp/vmware-config0/vsock-only/vsock.mod.o
  LD [M]  /tmp/vmware-config0/vsock-only/vsock.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
cp -f vsock.ko ./../vsock.o
make: Leaving directory `/tmp/vmware-config0/vsock-only&apos;
Unable to make a vsock module that can be loaded in the running kernel:
insmod: error inserting &apos;/tmp/vmware-config0/vsock.o&apos;: -1 Unknown symbol in module
There is probably a slight difference in the kernel configuration between the
set of C header files you specified and your running kernel.  You may want to
rebuild a kernel based on that directory, or specify another directory.

The VM communication interface socket family is used in conjunction with the VM
communication interface to provide a new communication path among guests and
host.  The rest of this software provided by VMware Server is designed to work
independently of this feature.  If you wish to have the VSOCK feature  you can
install the driver by running vmware-config.pl again after making sure that
gcc, binutils, make and the kernel sources for your running kernel are
installed on your machine. These packages are available on your distribution&apos;s
installation CD.
[ Press the Enter key to continue.]

Do you want networking for your virtual machines? (yes/no/help) [yes]

Configuring a bridged network for vmnet0.

Please specify a name for this network.
[Bridged]

The following bridged networks have been defined:

. vmnet0 is bridged to eth0

All your ethernet interfaces are already bridged.

Do you want to be able to use NAT networking in your virtual machines? (yes/no)
[yes] no

Do you want to be able to use host-only networking in your virtual machines?
[no]

None of the pre-built vmnet modules for VMware Server is suitable for your
running kernel.  Do you want this program to try to build the vmnet module for
your system (you need to have a C compiler installed on your system)? [yes]

Extracting the sources of the vmnet module.

Building the vmnet module.

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config1/vmnet-only&apos;
make -C /lib/modules/2.6.27-11-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
  CC [M]  /tmp/vmware-config1/vmnet-only/driver.o
  CC [M]  /tmp/vmware-config1/vmnet-only/hub.o
  CC [M]  /tmp/vmware-config1/vmnet-only/userif.o
  CC [M]  /tmp/vmware-config1/vmnet-only/netif.o
  CC [M]  /tmp/vmware-config1/vmnet-only/bridge.o
  CC [M]  /tmp/vmware-config1/vmnet-only/filter.o
  CC [M]  /tmp/vmware-config1/vmnet-only/procfs.o
  CC [M]  /tmp/vmware-config1/vmnet-only/smac_compat.o
  CC [M]  /tmp/vmware-config1/vmnet-only/smac.o
  CC [M]  /tmp/vmware-config1/vmnet-only/vnetEvent.o
  CC [M]  /tmp/vmware-config1/vmnet-only/vnetUserListener.o
  LD [M]  /tmp/vmware-config1/vmnet-only/vmnet.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /tmp/vmware-config1/vmnet-only/vmnet.mod.o
  LD [M]  /tmp/vmware-config1/vmnet-only/vmnet.ko
make[1]: Leaving directory `/usr/src/linux-headers-2.6.27-11-generic&apos;
cp -f vmnet.ko ./../vmnet.o
make: Leaving directory `/tmp/vmware-config1/vmnet-only&apos;
The vmnet module loads perfectly into the running kernel.

Please specify a port for remote connections to use [902]

Please specify a port for standard http connections to use [8222]

Please specify a port for secure http (https) connections to use [8333]

The current administrative user for VMware Server  is &apos;&apos;.  Would you like to
specify a different administrator? [no] yes

Please specify the user whom you wish to be the VMware Server administrator
 matsu

Using matsu as the VMware Server administrator.

insserv: warning: script &apos;S01linux-restricted-modules-common&apos; missing LSB tags and overrides
insserv: warning: script &apos;K04gdm&apos; missing LSB tags and overrides
insserv: warning: script &apos;K04vbesave&apos; missing LSB tags and overrides
insserv: warning: script &apos;K04powernowd.early&apos; missing LSB tags and overrides
insserv: warning: script &apos;K04xserver-xorg-input-wacom&apos; missing LSB tags and overrides
insserv: warning: script &apos;K04NetworkManager&apos; missing LSB tags and overrides
insserv: warning: script &apos;K04udev&apos; missing LSB tags and overrides
insserv: warning: script &apos;K03loopback&apos; missing LSB tags and overrides
insserv: warning: script &apos;K03udev-finish&apos; missing LSB tags and overrides
insserv: warning: script &apos;K04httpd&apos; missing LSB tags and overrides
insserv: warning: script &apos;K17acpi-support&apos; missing LSB tags and overrides
insserv: warning: script &apos;NetworkManager&apos; missing LSB tags and overrides
insserv: warning: script &apos;acpi-support&apos; missing LSB tags and overrides
insserv: warning: script &apos;gdm&apos; missing LSB tags and overrides
insserv: warning: script &apos;linux-restricted-modules-common&apos; missing LSB tags and overrides
insserv: warning: script &apos;loopback&apos; missing LSB tags and overrides
insserv: warning: script &apos;powernowd.early&apos; missing LSB tags and overrides
insserv: warning: script &apos;udev&apos; missing LSB tags and overrides
insserv: warning: script &apos;udev-finish&apos; missing LSB tags and overrides
insserv: warning: script &apos;vbesave&apos; missing LSB tags and overrides
insserv: warning: script &apos;xserver-xorg-input-wacom&apos; missing LSB tags and overrides
insserv: warning: script &apos;httpd&apos; missing LSB tags and overrides
insserv: script vmware: service VMware already provided!
insserv: exiting now!
illegal runlevel specified for vmware: r
In which directory do you want to keep your virtual machine files?
[/var/lib/vmware/Virtual Machines]

The path &quot;/var/lib/vmware/Virtual Machines&quot; does not exist currently. This
program is going to create it, including needed parent directories. Is this
what you want? [yes]

Please enter your 20-character serial number.

Type XXXXX-XXXXX-XXXXX-XXXXX or &apos;Enter&apos; to cancel:  秘密のシリアルキー

Creating a new VMware VIX API installer database using the tar4 format.

Installing VMware VIX API.

In which directory do you want to install the VMware VIX API binary files?
[/usr/local/bin]

In which directory do you want to install the VMware VIX API library files?
[/usr/local/lib/vmware-vix/lib]

The path &quot;/usr/local/lib/vmware-vix/lib&quot; does not exist currently. This program
is going to create it, including needed parent directories. Is this what you
want? [yes]

In which directory do you want to install the VMware VIX API document pages?
[/usr/local/doc/vmware-vix]

The path &quot;/usr/local/doc/vmware-vix&quot; does not exist currently. This program is
going to create it, including needed parent directories. Is this what you want?
[yes]

The installation of VMware VIX API 1.6.0 build-122956 for Linux completed
successfully. You can decide to remove this software from your system at any
time by invoking the following command:
&quot;/usr/local/bin/vmware-uninstall-vix.pl&quot;.

Enjoy,

--the VMware team

Starting VMware services:
   Virtual machine monitor                                             done
   Virtual machine communication interface                             done
   Virtual ethernet                                                    done
   Bridged networking on /dev/vmnet0                                   done
   VMware Server Authentication Daemon (background)                    done
   Shared Memory Available                                             done
[matsu@matsu-ubuntu ~/archive]%
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;注意点&lt;/h3&gt;
&lt;p&gt;VMware Server 2.0は、ローカルホストのみで使う場合はHTTPで管理画面へアクセスできます。しかし、リモートホストから管理画面へアクセスする場合は必ずSSLで接続しなければなりません。&lt;br /&gt;
SSLで接続する際に、個人証明書の提出が求められますがキャンセルすることで回避できます。&lt;/p&gt;
&lt;p&gt;わざわざViewerをPCへインストールしなくても利用できるのは楽ですね。&lt;/p&gt;
&lt;h3&gt;リモートのvmwareにアクセスするための設定&lt;/h3&gt;
&lt;p&gt;ポートの穴あけ。&lt;br /&gt;
TCPの8333と902.&lt;/p&gt;
&lt;p&gt;8333は、HTTPSによるvmwareの管理画面のため。&lt;br /&gt;
902は、各vmのコンソールへ接続するためのポート。コンソールにつなげる必要が無ければあけなくても良い。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/02/ws04801.jpg&quot; alt=&quot;vmware server 2.0&quot; /&gt;&lt;/p&gt;
&lt;p&gt;↓管理画面。Webでアクセスする。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/02/ws0481.jpg&quot; alt=&quot;console&quot; /&gt;&lt;/p&gt;
&lt;p&gt;↓コンソール。上記管理画面から、VMのコンソールを立ち上げたところ。Firefoxの場合はExtensionのインストールが必要になる。&lt;/p&gt;
&lt;h3&gt;トラブル&lt;/h3&gt;
&lt;p&gt;httpsで8333にアクセスしたときに、ブラウザのタイトルが「Loading...」となって何も表示されなかった。vmware serverを再起動したら表示されるようになった。。。。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/init.d/vmware restart
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>rsync error - failed: Permission denied (13) rsync error: errors selecting input/output files, dirs</title><link>https://blog.teraren.com/posts/rsync-error/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rsync-error/</guid><description>rsync error - failed: Permission denied (13) rsync error: errors selecting input/output files, dirs</description><pubDate>Sun, 01 Feb 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Cent OS 4.4(Final)である日（1月31日）から、以下のエラーが出るようになった。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% sudo -u daemon rsync -varu --delete  
building file list ... rsync: pop_dir &quot;/mnt/hoge/web/hoge&quot; failed: Permission denied (13) rsync error: errors selecting input/output files, dirs
 (code 3) at flist.c(1222)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2年前から同じ運用をしているのに、急にエラーが出るようになって、rsyncが失敗するようになった。&lt;br /&gt;
最新のrsync 3.0.5をソースからビルドしてそれを利用するようにしたら問題は解決した。&lt;/p&gt;
&lt;p&gt;RPMのupdateも出てない。&lt;br /&gt;
3台のうちの1台はエラーが出ていないのも不可解。&lt;/p&gt;
</content:encoded></item><item><title>Firewall解放ポート一覧</title><link>https://blog.teraren.com/posts/firewall-open-ports-list/</link><guid isPermaLink="true">https://blog.teraren.com/posts/firewall-open-ports-list/</guid><description>Firewall解放ポート一覧</description><pubDate>Thu, 29 Jan 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;DNS,Web,メールサーバを構築する場合、最近はいっぱいFirewallのポート開けないとだから、まとめておく。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TCP
&lt;ul&gt;
&lt;li&gt;22 (ssh)&lt;/li&gt;
&lt;li&gt;25 (smtp)&lt;/li&gt;
&lt;li&gt;53 (domain)&lt;/li&gt;
&lt;li&gt;80 (http)&lt;/li&gt;
&lt;li&gt;110 (pop3)&lt;/li&gt;
&lt;li&gt;143 (imap)&lt;/li&gt;
&lt;li&gt;443 (https)&lt;/li&gt;
&lt;li&gt;587 (submission)&lt;/li&gt;
&lt;li&gt;993 (imaps)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;UDP
&lt;ul&gt;
&lt;li&gt;53 (domain)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>UnixBench (linux, unix benchmark software)</title><link>https://blog.teraren.com/posts/unixbench-linux-unix-benchmark-software/</link><guid isPermaLink="true">https://blog.teraren.com/posts/unixbench-linux-unix-benchmark-software/</guid><description>LinuxベンチマークツールUnixBenchの使い方とXeon 3.8GHzでのCentOS・Ubuntuの実測スコアを比較</description><pubDate>Tue, 20 Jan 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2009/01/ws0466.jpg&quot; alt=&quot;unix bench&quot; /&gt;&lt;/p&gt;
&lt;p&gt;お手軽にLinuxのベンチマークを行うソフトウェアを紹介する。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;http://lbs.sourceforge.net/&quot;&gt;UnixBench&lt;/a&gt; - a fundamental high-level Linux benchmark suite, Unixbench integrates CPU and file I/O tests, as well as system behaviour under various user loads&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以下、実行方法。Cent OS 4.7で実行。&lt;br /&gt;
オプション無しでRunを実行すると、多数のテストを10回繰り返すため、かなり時間がかかる。&lt;br /&gt;
(rootで実行する必要ないけどね。。。)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# cd /tmp/
# wget http://www.tux.org/pub/tux/benchmarks/System/unixbench/unixbench-4.1.0.tgz
# tar zxvf unixbench-4.1.0.tgz
# cd unixbench-4.1.0
# make
# ./Run
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;お手軽にやるには、以下。&lt;br /&gt;
一部のテストを1回だけ行う。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ./Run -1 index
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;どうやら、topを見ていると1コアしか使っていないみたい。&lt;/p&gt;
&lt;p&gt;Intel(R) Xeon(TM) CPU 3.80GHz x2&lt;/p&gt;
&lt;h3&gt;Cent OS 4.7 (Linux 2.6.9-67.0.20.ELsmp)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;                     INDEX VALUES
TEST                                        BASELINE     RESULT      INDEX

Dhrystone 2 using register variables        116700.0  5477419.0      469.4
Double-Precision Whetstone                      55.0     1378.0      250.5
Execl Throughput                                43.0     2760.1      641.9
File Copy 1024 bufsize 2000 maxblocks         3960.0   242087.0      611.3
File Copy 256 bufsize 500 maxblocks           1655.0    72316.0      437.0
File Copy 4096 bufsize 8000 maxblocks         5800.0   568054.0      979.4
Pipe Throughput                              12440.0   675527.6      543.0
Process Creation                               126.0     8201.3      650.9
Shell Scripts (8 concurrent)                     6.0     1066.0     1776.7
System Call Overhead                         15000.0   617840.2      411.9
                                                                 =========
     FINAL SCORE                                                     590.0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Ubuntu 8.04.1 (Linux 2.6.24-19-server)&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;                     INDEX VALUES
TEST                                        BASELINE     RESULT      INDEX

Dhrystone 2 using register variables        116700.0  5062938.2      433.8
Double-Precision Whetstone                      55.0     1241.7      225.8
Execl Throughput                                43.0     2606.8      606.2
File Copy 1024 bufsize 2000 maxblocks         3960.0   289538.0      731.2
File Copy 256 bufsize 500 maxblocks           1655.0    84724.0      511.9
File Copy 4096 bufsize 8000 maxblocks         5800.0   744914.0     1284.3
Pipe Throughput                              12440.0   552157.9      443.9
Process Creation                               126.0     8863.2      703.4
Shell Scripts (8 concurrent)                     6.0      924.0     1540.0
System Call Overhead                         15000.0   766544.9      511.0
                                                                 =========
     FINAL SCORE                                                     609.0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.2％パフォーマンスが上がってる。&lt;/p&gt;
</content:encoded></item><item><title>LS-WH1.0TGL/R1</title><link>https://blog.teraren.com/posts/2009-01-18-ls-wh10tglr1/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2009-01-18-ls-wh10tglr1/</guid><description>Buffalo LS-WH1.0TGL/R1のRAID1対応NASレビュー。初期RAID0からの再構築手順と、従来LANDISKと比べたアクセス待ち時間の改善点。</description><pubDate>Mon, 19 Jan 2009 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;NASを新しくした。&lt;/p&gt;
&lt;p&gt;やはり、ミラーリングされていないと、ストレージとして使えない。バックアップ用ハードディスクとしての役割しか持たない。&lt;br /&gt;
ってことで、RAID1が使えるNASを買った。&lt;/p&gt;
&lt;p&gt;初期状態では、RAID0で組まれているので、RAID1を使う場合は再構築が必要になる。再構築とRAIDのチェックで一晩は覚悟しておこう。&lt;/p&gt;
&lt;p&gt;特筆すべきことは、今までのLANDISKはハードディスクがスピンアップするまで、Windowsからアクセスしたときにハングした状態になるのだが、このNASは待ち時間無しにアクセスできる。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;B001AOZ8VQ&quot; kw=&quot;LS-WH1.0TGBL/R1&quot;}&lt;/p&gt;
</content:encoded></item><item><title>mysql_config</title><link>https://blog.teraren.com/posts/mysql-config/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-config/</guid><description>mysql_config</description><pubDate>Wed, 24 Dec 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;tritonn-1.0.9-mysql-5.0.51a-linux-i686に付属しているmysql_configの設定値が間違ってる。。。&lt;br /&gt;
手で編集。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;before: pkglibdir=&apos;/usr/local/mysql/lib/mysql&apos;
after: pkglibdir=&apos;/usr/local/mysql/lib&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;zabbixのconfigure時に以下のように言われてしまったから。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;configure: error: Not found mysqlclient library
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>fastCGI用のPHPインストール</title><link>https://blog.teraren.com/posts/fastcgi-php-installation/</link><guid isPermaLink="true">https://blog.teraren.com/posts/fastcgi-php-installation/</guid><description>fastCGI用のPHPインストール</description><pubDate>Thu, 11 Dec 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;lighttpdでPHPを利用するためにはfastCGI APIを使ってlighttpdから呼ばれる。&lt;br /&gt;
それに対応したPHPのバイナリを作る。&lt;/p&gt;
&lt;p&gt;apxs対応のモジュールの作成とは同時にできない。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget http://jp2.php.net/get/php-5.2.8.tar.gz/from/this/mirror
% tar zxf php-5.2.8.tar.gz
% cd php-5.2.8
% ./configure   --enable-fastcgi --enable-force-cgi-redirect --enable-discard-path --enable-mbstring --enable-soap --enable-zend-multibyte --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql --with-curl --with-curlwrappers --with-gd --with-jpeg-dir=/usr/lib --with-png-dir=/usr/lib --with-zlib-dir=/usr/lib --with-mcrypt --with-bz2 --enable-zip --with-mysqli
% make
# sudo cp sapi/cgi/php-cgi /usr/local/bin/php-cgi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;lighttpd.confにPHPの設定が書いてあるから、コメントアウトを外す。&lt;br /&gt;
以下に該当部分を記載する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fastcgi.server             = ( &quot;.php&quot; =&amp;gt;
                               ( &quot;localhost&quot; =&amp;gt;
                                 (
                                   &quot;socket&quot; =&amp;gt; &quot;/var/run/lighttpd/php-fastcgi.socket&quot;,
                                   &quot;bin-path&quot; =&amp;gt; &quot;/usr/local/bin/php-cgi&quot;
                                 )
                               )
                            )
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>lighttpdベンチマーク</title><link>https://blog.teraren.com/posts/lighttpd-benchmark/</link><guid isPermaLink="true">https://blog.teraren.com/posts/lighttpd-benchmark/</guid><description>lighttpdベンチマーク</description><pubDate>Thu, 11 Dec 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;lighttpdをapache(prefork)と比較してみた。&lt;br /&gt;
グラフが長いほど高速。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2008/12/ws0473.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2008/12/ws0473.jpg&quot; alt=&quot;lighttpd benchmark&quot; title=&quot;lighttpd benchmark&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;単純なHTMLファイルの読み込みだと、apacheに比べて約3倍高速。&lt;br /&gt;
PHPの実行は約1.1倍apacheの方が早い。&lt;/p&gt;
&lt;p&gt;lighttpd+PHPが遅い理由は、fastCGIを経由するからかなぁ&lt;/p&gt;
&lt;p&gt;ベンチマークの測定環境や、数値は以下のExcelへ掲載してあります。&lt;br /&gt;
&lt;a href=&quot;/uploads/2008/12/lighttpd2.xls&quot;&gt;lighttpd&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Lighttpd installation</title><link>https://blog.teraren.com/posts/lighttpd-installation/</link><guid isPermaLink="true">https://blog.teraren.com/posts/lighttpd-installation/</guid><description>Lighttpd installation</description><pubDate>Thu, 11 Dec 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Lighttpdのベンチマークするためにソースコードからインストール。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ wget http://www.lighttpd.net/download/lighttpd-1.4.20.tar.gz
$ tar zxf lighttpd-1.4.20.tar.gz
$ cd lighttpd-1.4.20
$ ./configure --prefix=/usr/local/lighttpd
$ make
# make install
# cp  doc/rc.lighttpd /etc/init.d/lighttpd
# chkconfig --add lighttpd
# mkdir /usr/local/lighttpd/etc/
# cp doc/lighttpd.conf /usr/local/lighttpd/etc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ubuntu用のスタートアップスクリプト&lt;br /&gt;
&lt;a href=&quot;/uploads/2008/12/lighttpd.txt&quot;&gt;lighttpd&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;1.5系がすごいらしいが、まずは安定版の1.4を試す。&lt;br /&gt;
&lt;a href=&quot;http://www.drk7.jp/MT/archives/001155.html&quot;&gt;http://www.drk7.jp/MT/archives/001155.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;lighttpdのニックネームは、lightyと呼ぶらしい。&lt;/p&gt;
</content:encoded></item><item><title>CakePHP1.2でPaginate</title><link>https://blog.teraren.com/posts/cakephp12-paginate/</link><guid isPermaLink="true">https://blog.teraren.com/posts/cakephp12-paginate/</guid><description>CakePHP 1.2でページネーションを実装する方法。ControllerとViewのコードスニペットを使ったシンプルなPaginatorの導入手順を解説。</description><pubDate>Tue, 09 Dec 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://bakery.cakephp.org/articles/view/basic-pagination-overview-3cakephp%E3%81%A7Pager%E3%82%92%E8%B6%85%E7%B0%A1%E5%8D%98%E3%81%AB%E5%AE%9F%E8%A3%85%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F%E3%81%AD%E3%80%82%E8%8B%B1%E8%AA%9E%E8%AA%AD%E3%82%81%E3%81%AA%E3%81%8F%E3%81%A6%E3%82%82%E3%80%81%E7%90%86%E8%A7%A3%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%80%82&quot;&gt;http://bakery.cakephp.org/articles/view/basic-pagination-overview-3cakephpでPagerを超簡単に実装できるようになったね。英語読めなくても、理解できるよ。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;以下に、簡単にやり方をまとめておく。&lt;br /&gt;
Controllerへ、以下を追加。ModelからDBへアクセスしないで、Controllerのメソッドを経由して間接的にModelを呼ぶ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$this-&amp;gt;set(&apos;customers&apos;, $this-&amp;gt;paginate(&apos;Customer&apos;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Viewへ以下を追加。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Showing Page &amp;lt;?php echo $paginator-&amp;gt;counter(); ?&amp;gt;
&amp;lt;table&amp;gt;
    &amp;lt;tr&amp;gt;
        &amp;lt;th&amp;gt;&amp;lt;?php echo $paginator-&amp;gt;sort(&apos;Customer Name&apos;, &apos;name&apos;);?&amp;gt;&amp;lt;/th&amp;gt;
        &amp;lt;th&amp;gt;&amp;lt;?php echo $paginator-&amp;gt;sort(&apos;Store Location&apos;, &apos;store&apos;);?&amp;gt;&amp;lt;/th&amp;gt;
    &amp;lt;/tr&amp;gt;
&amp;lt;?php foreach($customers as $customer): ?&amp;gt;
    &amp;lt;tr&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;?php echo $customer[&apos;Customer&apos;][&apos;name&apos;]; ?&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;&amp;lt;?php echo $customer[&apos;Customer&apos;][&apos;store&apos;]; ?&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
&amp;lt;?php endforeach; ?&amp;gt;
&amp;lt;/table&amp;gt;
&amp;lt;?php echo $paginator-&amp;gt;prev(); ?&amp;gt;
&amp;lt;?php echo $paginator-&amp;gt;numbers(); ?&amp;gt;
&amp;lt;?php echo $paginator-&amp;gt;next(); ?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;1.xの時代からはかなり整理された。&lt;/p&gt;
</content:encoded></item><item><title>RPM &lt;-&gt; dpkg 変換表</title><link>https://blog.teraren.com/posts/rpm-dpkg-conversion-table/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rpm-dpkg-conversion-table/</guid><description>RHELのRPM/yumとDebianのdpkg/aptitudeコマンドを対応させた変換表。インストール・削除・検索・アップグレードなどの操作を両パッケージシステムで比較できます。</description><pubDate>Mon, 08 Dec 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;あなたは、rpm派？dpkg派？私は断然dpkg派。&lt;/p&gt;
&lt;h3&gt;rpmとdpkgの違い&lt;/h3&gt;
&lt;p&gt;削除&lt;/p&gt;
&lt;p&gt;rpmパッケージを削除すると、設定ファイルも同時に消える。または、.backとか.rpmとかいう拡張子が付いた設定ファイルが残る。 それに対し、dpkgは設定を残すか残さないかをアンインストール時のオプションで指定できる。&lt;/p&gt;
&lt;h3&gt;追加・削除&lt;/h3&gt;
&lt;p&gt;RPM&lt;/p&gt;
&lt;p&gt;yum&lt;/p&gt;
&lt;p&gt;dpkg&lt;/p&gt;
&lt;p&gt;aptitude&lt;/p&gt;
&lt;p&gt;説明&lt;/p&gt;
&lt;p&gt;rpm -ivh foo.rpm&lt;/p&gt;
&lt;p&gt;yum install foo.rpm&lt;/p&gt;
&lt;p&gt;dpkg -i foo.rpm&lt;/p&gt;
&lt;p&gt;aptitude install foo.rpm&lt;/p&gt;
&lt;p&gt;インストール&lt;/p&gt;
&lt;p&gt;rpm -Uvh foo.rpm&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;アップグレード&lt;/p&gt;
&lt;p&gt;rpm -e foo&lt;/p&gt;
&lt;p&gt;yum remove foo&lt;/p&gt;
&lt;p&gt;dpkg -r foo（設定ファイル残す）&lt;br /&gt;
dpkg -P foo（設定ファイル消す）&lt;/p&gt;
&lt;p&gt;aptitude remove foo&lt;/p&gt;
&lt;p&gt;アンインストール&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;yum upgrade&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;aptitude upgrade&lt;/p&gt;
&lt;p&gt;全パッケージアップグレード&lt;/p&gt;
&lt;h3&gt;情報表示&lt;/h3&gt;
&lt;p&gt;RPM&lt;/p&gt;
&lt;p&gt;dpkg&lt;/p&gt;
&lt;p&gt;説明&lt;/p&gt;
&lt;p&gt;rpm -qa&lt;/p&gt;
&lt;p&gt;dpkg -l&lt;/p&gt;
&lt;p&gt;インストール済みのパッケージ一覧出力&lt;/p&gt;
&lt;p&gt;rpm -ql foo&lt;/p&gt;
&lt;p&gt;dpkg -L foo&lt;/p&gt;
&lt;p&gt;インストール済みのパッケージ foo に含まれるファイル一覧&lt;/p&gt;
&lt;p&gt;rpm -qf /path/to/file&lt;/p&gt;
&lt;p&gt;dpkg -S /path/to/file&lt;/p&gt;
&lt;p&gt;ファイル /path/to/file をインストールしたパッケージ&lt;/p&gt;
&lt;p&gt;rpm -qip foo.rpm&lt;/p&gt;
&lt;p&gt;dpkg -I foo.deb&lt;/p&gt;
&lt;p&gt;パッケージ情報&lt;/p&gt;
&lt;p&gt;rpm -qlp foo.rpm&lt;/p&gt;
&lt;p&gt;dpkg -c foo.deb&lt;/p&gt;
&lt;p&gt;パッケージ内のファイル一覧&lt;/p&gt;
&lt;p&gt;rpm -qi packagename&lt;/p&gt;
&lt;p&gt;dpkg -s packagename&lt;/p&gt;
&lt;p&gt;インストールパッケージの情報表示&lt;/p&gt;
&lt;p&gt;他に便利なコマンドあったら教えてください。&lt;/p&gt;
</content:encoded></item><item><title>Webアプリケーションの認証ロジック</title><link>https://blog.teraren.com/posts/web-app-auth-logic/</link><guid isPermaLink="true">https://blog.teraren.com/posts/web-app-auth-logic/</guid><description>開発・本番DBが分離した環境で、セッションのみで認証するWebアプリの脆弱点と、メール誤送信リスクを防ぐ認証ロジックの実装方法</description><pubDate>Wed, 03 Dec 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;くぅ。またくだらないミスを犯してしまった。。。&lt;br /&gt;
↓対処法&lt;br /&gt;
細かいことだけど，手軽な実装で大きなリスクを減らせる実装を紹介する．&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;システムの背景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Webアプリケーション&lt;/li&gt;
&lt;li&gt;HTTPセッション管理をファイルに保存している&lt;/li&gt;
&lt;li&gt;データベースが開発環境と運用環境に分離されている&lt;/li&gt;
&lt;li&gt;運用環境のデータを開発環境に取り込み，動作テストやリハーサルを行う場合がある&lt;/li&gt;
&lt;li&gt;ユーザのHTTPリクエストによって実行されるプログラムからメールを送信する&lt;/li&gt;
&lt;li&gt;ログイン認証をユーザIDなどの1つの値を保持するのみで実装してある&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;背景となるアプリケーションアーキテクチャの例．&lt;/p&gt;
&lt;p&gt;開発環境データベース&lt;/p&gt;
&lt;p&gt;→&lt;/p&gt;
&lt;p&gt;プログラム&lt;/p&gt;
&lt;p&gt;→&lt;/p&gt;
&lt;p&gt;ユーザ&lt;/p&gt;
&lt;p&gt;運用環境データベース&lt;/p&gt;
&lt;p&gt;→&lt;/p&gt;
&lt;p&gt;上記の背景では，オペレーションミスにより，運用環境に登録されているユーザへメールが送信されてしまう場合がある．&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;開発環境のデータベースを利用する状態でログインする．&lt;/li&gt;
&lt;li&gt;データベースを運用環境のデータベースに変更する．&lt;/li&gt;
&lt;li&gt;ブラウザで再度アクセスすると運用環境のユーザIDでログインされた状態になる&lt;/li&gt;
&lt;li&gt;メール送信を行うプログラムへアクセスすると，運用環境に登録されたユーザへメール送信される．&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;上記の問題を回避するために，ログインの定義を変更する．&lt;br /&gt;
ログインの定義が，「ユーザIDの保持」だと問題が発生するので，「ユーザIDとアカウント名の一致」とすることでセッションジャックの危険性を減らせる．セッションハイジャックの危険性をより減らすためには，より多くの情報とログイン状態を関連づける．&lt;/p&gt;
&lt;p&gt;背景の認証ロジックの式は以下．左辺と右辺が一致した場合はログイン認証を認める．&lt;/p&gt;
&lt;p&gt;仮定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;getFromSession()はセッションからログイン情報として保存してある文字列を取得する関数&lt;br /&gt;
idはセッションから取得した顧客ID&lt;/li&gt;
&lt;li&gt;isValid(id)は顧客IDを引数とし，ログイン可能な状態ならばidを返却する．&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;式：&lt;br /&gt;
&lt;code&gt;getFromSession() == isValid(id)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;問題を回避するための認証ロジックの式は以下．&lt;/p&gt;
&lt;p&gt;仮定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;other1, other2はidに関連した情報．ユーザ登録時から一切変更されない情報．idを元にデータベースから取得した情報。&lt;/li&gt;
&lt;li&gt;hash()は引数の値をseedに取るハッシュ関数．&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;式：&lt;br /&gt;
&lt;code&gt;getFromSession() == hash(isValid(id) , other1, [other2...])&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>WordPressのコメント数を正常化</title><link>https://blog.teraren.com/posts/wordpress-normalize-comment-count/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-normalize-comment-count/</guid><description>WordPressのコメント数を正常化</description><pubDate>Sun, 30 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;記事を一覧にしたときに表示されるコメント数と、記事のみを表示したときに表示されるコメント数が合致していない。&lt;/p&gt;
&lt;p&gt;以下のSQLを実行することでその不一致を修正できる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;update wp_posts p set p.comment_count = (select count(c.comment_ID) from wp_comments c where comment_post_ID=p.ID and c.comment_approved = 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;WordPressは一覧表示の高速化のためにコメント数をエントリーが保存されているテーブルにキャッシュしている。何らかの原因でこのキャッシュの数値がおかしくなったらしい。&lt;/p&gt;
&lt;p&gt;約1000件の記事中、14件あった。&lt;/p&gt;
</content:encoded></item><item><title>Ubuntu 8.10</title><link>https://blog.teraren.com/posts/ubuntu-810/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ubuntu-810/</guid><description>Ubuntu 8.10</description><pubDate>Fri, 28 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;パフォーマンステスト用と、最近のDesktop　Linuxの動向を感じてみるためにUbuntu Desktop入れてみた。&lt;br /&gt;
3年前に比べて、すんげぇ進化してるねー。&lt;/p&gt;
&lt;p&gt;これから、こいつをパフォーマンステストでいじめて行こうと思う。&lt;/p&gt;
</content:encoded></item><item><title>Partition Magicに代わるパーティション分割アプリ</title><link>https://blog.teraren.com/posts/partition-magic-alternative/</link><guid isPermaLink="true">https://blog.teraren.com/posts/partition-magic-alternative/</guid><description>Partition Magicに代わるパーティション分割アプリ</description><pubDate>Thu, 27 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;EASEUS Partition Manager&lt;br /&gt;
&lt;a href=&quot;http://www.partition-tool.com/&quot;&gt;http://www.partition-tool.com/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;個人だと無料で使える。神だ。&lt;br /&gt;
試してみたところ、ちゃんと使えた。マニュアルなんて見なくても使えるぐらい優しいUI.&lt;/p&gt;
</content:encoded></item><item><title>PHPセッションのGCを非同期にする</title><link>https://blog.teraren.com/posts/php-session-gc/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-session-gc/</guid><description>PHPセッションのGCがHTTPリクエストと同期で走る問題を、gc_probabilityを0にしてcronで代替する非同期化の方法を解説</description><pubDate>Sun, 16 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PHPのセッションハンドラをデフォルトで使っている場合のガーベージコレクタ(GC)の話。
{/* textlint-disable ja-technical-writing/ja-no-successive-word */}&lt;/li&gt;
&lt;li&gt;PHPはサーバ上で保存してあるセッション情報を保存してあるファイルを定期的に削除している。
{/* textlint-enable */}&lt;/li&gt;
&lt;li&gt;削除するタイミングはPHPが起動する時、HTTPリクエストまたはコマンドラインからPHPが起動した際に一定の確率でGCが起動するようになっている。Javaのアプリケーションサーバならメモリ上にJVMが常駐しているからプログラムの起動とは非同期にできるが、PHPは同期で処理している。そのため、PHPではGCが起動したときにプログラムの実行時間が長ってしまう。&lt;/li&gt;
&lt;li&gt;よって、大規模サイトになったときには必然的にセッションファイルが扱うセッションが多くなるため、GCにかかる時間が長くってしまうから、&lt;strong&gt;同期によるPHPのGCに任せないで自前で非同期にGCを行うべき。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;設定項目&lt;/h2&gt;
&lt;p&gt;PHPのGCを制御する設定はphp.iniに記載されている以下の3つ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;session.gc_probability = 1
session.gc_divisor     = 1024
session.gc_maxlifetime = 1440
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GCの起動確立は、gc_divisor 分のgc_probability。上記の例では1/1024の確立でGCが起動する。&lt;br /&gt;
セッションファイルの最終変更時間がgc_maxlifetime秒以前だったらセッションを削除する。&lt;br /&gt;
（PHP4.2.3以降はファイルの最終更新日、それより前は最終アクセス時間）&lt;/p&gt;
&lt;p&gt;gc_probabilityを0にすればPHPのGCは無効になる。&lt;br /&gt;
以下のようにすれば、PHPからGCが起動されることは無くなる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;session.gc_probability = 0
session.gc_divisor     = 1024
session.gc_maxlifetime = 1440
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;非同期でGCする設定&lt;/h2&gt;
&lt;p&gt;以下は、GCをcronで一定時間に削除する例。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;*/10 * * * * daemon ionice -c3 nice -n19 -n 18 find /tmp -type f -name &quot;sess_*&quot; -mmin +120 -exec rm {} ;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記の例では、10分に1回GCを起動し、最終変更時間から2時間経ったら削除する例。&lt;br /&gt;
プロセスの優先度は低め、IOの優先度も最低にしてある。&lt;/p&gt;
</content:encoded></item><item><title>svnコマンドでロールバック</title><link>https://blog.teraren.com/posts/svn-command-rollback/</link><guid isPermaLink="true">https://blog.teraren.com/posts/svn-command-rollback/</guid><description>svn mergeコマンドで特定リビジョンの変更を取り消してコミットする、TortoiseSVNのRevert相当のロールバック手順を解説</description><pubDate>Sat, 15 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;コマンドラインでロールバックの方法を発見。&lt;/p&gt;
&lt;p&gt;ロールバックそのものはできないけど、merge -&amp;gt; commit　で似たことができる。&lt;br /&gt;
TortoiseSVNの「Revert changes from this revision」をと同義です。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ svn merge -c -303 http://svn.example.com/repos/calc/trunk
U integer.c
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ svn status
M integer.c
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ svn diff
…
# verify that the change is removed
…
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ svn commit -m &quot;Undoing change committed in r303.&quot;
Sending integer.c
Transmitting file data .
Committed revision 350.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mergeスイッチにはたくさんオプションがあって、様々なロールバックを行える。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Valid options:
  -r [--revision] ARG      : ARG (some commands also take ARG1:ARG2 range)
                             A revision argument can be one of:
                                NUMBER       revision number
                                &apos;{&apos; DATE &apos;}&apos; revision at start of the date
                                &apos;HEAD&apos;       latest in repository
                                &apos;BASE&apos;       base rev of item&apos;s working copy
                                &apos;COMMITTED&apos;  last commit at or before BASE
                                &apos;PREV&apos;       revision just before COMMITTED
  -c [--change] ARG        : the change made by revision ARG (like -r ARG-1:ARG)
                             If ARG is negative this is like -r ARG:ARG-1
  -N [--non-recursive]     : obsolete; try --depth=files or --depth=immediates
  --depth ARG              : limit operation by depth ARG (&apos;empty&apos;, &apos;files&apos;,
                            &apos;immediates&apos;, or &apos;infinity&apos;)
  -q [--quiet]             : print nothing, or only summary information
  --force                  : force operation to run
  --dry-run                : try operation but make no changes
  --diff3-cmd ARG          : use ARG as merge command
  --record-only            : mark revisions as merged (use with -r)
  -x [--extensions] ARG    : Default: &apos;-u&apos;. When Subversion is invoking an
                             external diff program, ARG is simply passed along
                             to the program. But when Subversion is using its
                             default internal diff implementation, or when
                             Subversion is displaying blame annotations, ARG
                             could be any of the following:
                                -u (--unified):
                                   Output 3 lines of unified context.
                                -b (--ignore-space-change):
                                   Ignore changes in the amount of white space.
                                -w (--ignore-all-space):
                                   Ignore all white space.
                                --ignore-eol-style:
                                   Ignore changes in EOL style
                                -p (--show-c-function):
                                   Show C function name in diff output.
  --ignore-ancestry        : ignore ancestry when calculating merges
  --accept ARG             : specify automatic conflict resolution action
                            (&apos;postpone&apos;, &apos;base&apos;, &apos;mine-full&apos;, &apos;theirs-full&apos;,
                             &apos;edit&apos;, &apos;launch&apos;)
  --reintegrate            : lump-merge all of source URL&apos;s unmerged changes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://www.rustyrazorblade.com/2007/04/06/how-to-roll-back-commits-to-an-earlier-version-of-a-repository-in-svn/&quot;&gt;http://www.rustyrazorblade.com/2007/04/06/how-to-roll-back-commits-to-an-earlier-version-of-a-repository-in-svn/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;あるコミットを無かったことにする方法が書いてある。&lt;br /&gt;
スマートではないけど、正攻法。ダウンタイムあるのが良くない&lt;br /&gt;
&lt;a href=&quot;http://timhatch.com/ark/2006/04/18/howto-svn-commit-rollback&quot;&gt;http://timhatch.com/ark/2006/04/18/howto-svn-commit-rollback&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>WordPress 2.7-Beta2にしてみた</title><link>https://blog.teraren.com/posts/wordpress-27-beta2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/wordpress-27-beta2/</guid><description>WordPress 2.7-Beta2にしてみた</description><pubDate>Mon, 10 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2008/11/ws0468.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2008/11/ws0468.jpg&quot; alt=&quot;wordpress2.7&quot; title=&quot;wordpress2.7&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://ja.wordpress.org/2008/11/08/wordpress-27-beta-2/&quot;&gt;WordPress 2.7&lt;/a&gt;が11月10日にリリースされる予定だったけど、2週間ほど延期らしい。&lt;br /&gt;
→11/19 追記：11月中になってる。そして、チケットは結構残っている。&lt;br /&gt;
&lt;a href=&quot;http://trac.wordpress.org/milestone/2.7&quot;&gt;http://trac.wordpress.org/milestone/2.7&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;海外サイトで2.7の評判を見ているとかっこいいデザインなので早速使ってみた。&lt;/p&gt;
&lt;p&gt;使ってみた感想。&lt;br /&gt;
良い点&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;フロントエンドの描画が早くなった。今までコメントが10個ぐらいつくと表示に10秒近くかかっていた&lt;/li&gt;
&lt;li&gt;バックエンドのデザインがかっこよくなった。&lt;/li&gt;
&lt;li&gt;Gravatarが搭載された&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;悪い点&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;テーマが微妙に崩れる。&lt;/li&gt;
&lt;li&gt;Simple Tagsプラグインが動かなくなる。代わりに別のプラグインを入れろと催促されるが、Simple Tagsでつけたタグが引き継がれない。→Simple Tagsのソースコード内にバージョンチェックしているところがあるので、改変すれば使える&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;正式リリースが楽しみです。&lt;/p&gt;
&lt;p&gt;2008/11/16 WordPress 2.7 Beta 3が出た！&lt;/p&gt;
</content:encoded></item><item><title>都道府県コードの仕様</title><link>https://blog.teraren.com/posts/prefecture-code-specification/</link><guid isPermaLink="true">https://blog.teraren.com/posts/prefecture-code-specification/</guid><description>JIS X 0401で規定された都道府県コードの一覧と、システム開発でこの標準コードを使うべき理由を紹介</description><pubDate>Sun, 09 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;都道府県のIDが&lt;a href=&quot;http://ja.wikipedia.org/wiki/JIS_X_0401&quot;&gt;JIS X 0401&lt;/a&gt;によって決められています。&lt;br /&gt;
システムで都道府県のIDを扱うときにはこれを利用した方がいいね。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; 1  北海道
 2  青森県
 3  岩手県
 4  宮城県
 5  秋田県
 6  山形県
 7  福島県
 8  茨城県
 9  栃木県
10  群馬県
11  埼玉県
12  千葉県
13  東京都
14  神奈川県
15  新潟県
16  富山県
17  石川県
18  福井県
19  山梨県
20  長野県
21  岐阜県
22  静岡県
23  愛知県
24  三重県
25  滋賀県
26  京都府
27  大阪府
28  兵庫県
29  奈良県
30  和歌山県
31  鳥取県
32  島根県
33  岡山県
34  広島県
35  山口県
36  徳島県
37  香川県
38  愛媛県
39  高知県
40  福岡県
41  佐賀県
42  長崎県
43  熊本県
44  大分県
45  宮崎県
46  鹿児島県
47  沖縄県
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上記に追加して、99はその他と定義されているっぽい。&lt;/p&gt;
</content:encoded></item><item><title>Macのサルベージソフト</title><link>https://blog.teraren.com/posts/mac-data-recovery-software/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mac-data-recovery-software/</guid><description>Macのサルベージソフト</description><pubDate>Wed, 05 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Mac OS XのHFSなどに対応したファイル復元ソフトのリンク集。 日本語対応。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Data Rescue 2&lt;/li&gt;
&lt;li&gt;File Salvage&lt;/li&gt;
&lt;li&gt;Final Data&lt;/li&gt;
&lt;li&gt;完全復元&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;英語版&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stellar Phoenix Macintosh（起動したとたんクラッシュ）&lt;/li&gt;
&lt;li&gt;R-Studio for Mac Data Recovery&lt;/li&gt;
&lt;li&gt;その他&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>PHPで2GB以上のファイルを扱う</title><link>https://blog.teraren.com/posts/php-handle-files-over-2gb/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-handle-files-over-2gb/</guid><description>PHPで2GB以上のファイルを扱う</description><pubDate>Wed, 05 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;x86のLinuxにてPHPを普通にコンパイルすると2GBまでのファイルしか扱えない！OSやファイルシステムが対応していても、だめ。普通にコンパイルするとファイルシステム周りは32bit空間（ファイルシステムだと約2GB分）しか扱えないらしい。&lt;/p&gt;
&lt;p&gt;アプリケーションからログを出力していて、気づかないうちに2GBになったら、アプリケーションが途中で止まっちゃう。&lt;/p&gt;
&lt;p&gt;ここに、対応策が書いてあった。&lt;br /&gt;
&lt;a href=&quot;http://bugs.php.net/bug.php?id=36478&quot;&gt;http://bugs.php.net/bug.php?id=36478&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;gccへ&quot;-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64&quot;というフラグをgccへ渡すと、ファイルシステム周りのライブラリは64bit空間を利用できるようになる。&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% CFLAGS=&quot;-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64&quot; ./configure...
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>リモートホストのIPアドレスを表示</title><link>https://blog.teraren.com/posts/remote-host-ip/</link><guid isPermaLink="true">https://blog.teraren.com/posts/remote-host-ip/</guid><description>リモートホストのIPアドレスを表示</description><pubDate>Wed, 05 Nov 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;サーバのアクセス制限をするときに自分のグローバルIPアドレスを調べたいときあるよね。&lt;/p&gt;
&lt;p&gt;いちいち「&lt;a href=&quot;http://kakunin.teraren.com/&quot;&gt;確認君&lt;/a&gt;」というフレーズをぐぐるのがめんどくさいから、スクリプト作ってブックマーク入れておく方が楽。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kakunin.teraren.com/&quot;&gt;確認君&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;curlにも対応しているのでシェルスクリプトから自分のIPアドレスを求められます。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;% curl kakunin.teraren.com
54.64.69.23
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>PHPのsleepとusleepのメモ</title><link>https://blog.teraren.com/posts/php-sleep-and-usleep-memo/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-sleep-and-usleep-memo/</guid><description>PHPのsleepとusleepのメモ</description><pubDate>Thu, 30 Oct 2008 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;sleep(1) = usleep(1000000) 0.1 sec = usleep(100000) 0.01 sec = usleep(10000)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;usleepの引数はマイクロ秒。&lt;/p&gt;
</content:encoded></item><item><title>Mozilla Thunderbirdを使うとIMAPサーバ暴走</title><link>https://blog.teraren.com/posts/mozilla-thunderbird-imap-server-runaway/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mozilla-thunderbird-imap-server-runaway/</guid><description>Thunderbirdでメール削除時にIMAPサーバのロードアベレージが70に達する問題の原因と解決法。Trashフォルダに数万件のMaildirファイルが溜まりIO待ちプロセスが大量発生。ディレクトリ再作成で解消。</description><pubDate>Tue, 07 Oct 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;IMAPサーバを動かしているサーバのロードアベレージが70ぐらいになって、大変なことになっていた。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IMAPサーバ：dovecot-0.99.11-9.EL4　（ファイルシステムext3）&lt;/li&gt;
&lt;li&gt;IMAPクライアント：2.0.0.17&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;状況は、ps axuするとIO待ちのimapプロセスが大量に存在する。&lt;/p&gt;
&lt;p&gt;原因がわかったので、書いておく。&lt;br /&gt;
今回の場合、Trashフォルダに数万件のメールがあり、何かのメールを削除するとThunderbirdがTrashフォルダに&lt;br /&gt;
新規スレッドでアクセスする。&lt;br /&gt;
ファイルが大量にあるMaildirを見ると以下のように、ディレクトリ自体の容量が大きい。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ls -al
drwx------   2 matsu matsu  95M Sep 20 10:19 cur
drwx------   2 matsu matsu 7.9M Sep 20 10:19 new
drwx------   2 matsu matsu 9.1M Sep 24 08:00 tmp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;そのスレッドの処理にimapサーバが長時間かかる。&lt;br /&gt;
また、メールを削除するたびにサーバ側でimapスレッドが生成されてしまう。&lt;/p&gt;
&lt;p&gt;そのため、ファイル削除に加えて、ディレクトリの再作成をすれば回復する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cd ~/Maildir/.Trash/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下のスクリプト実行する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for target in cur tmp new
do
  find $target -type f -exec rm {} \;
  rmdir $target
  mkdir $target
  chmod 700 $target
done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ファイルを削除するだけだと、だめ。inodeのフラグメントがあるらしく時間がかかるからディレクトリを再作成してあげる必要がある。&lt;/p&gt;
&lt;p&gt;暴走したプロセスをkillするためのコマンドメモ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ps axuwwf | grep imap | grep matsu | grep -v ps | grep -v grep | gawk &apos;{print $2;}&apos; | xargs sudo kill  -9
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ユーザ名部分の&quot;matsu&quot;を適宜置き換えてください。&lt;br /&gt;
killのsignalは(9)KILLじゃないと落ちてくれないです。&lt;/p&gt;
</content:encoded></item><item><title>PHPソースコードのスペルチェッカ</title><link>https://blog.teraren.com/posts/php-source-code-spell-checker/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-source-code-spell-checker/</guid><description>PHPソースコードのスペルチェッカ</description><pubDate>Mon, 22 Sep 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;有料だとあるんだけど、無料が無い。 PHPUnitから実行したいからコマンドラインで動いて欲しい。   チェックして欲しい項目&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;変数&lt;/li&gt;
&lt;li&gt;クラス&lt;/li&gt;
&lt;li&gt;ファイル名&lt;/li&gt;
&lt;li&gt;メソッド名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;コメント内はいいや。 追記：2008/11/20　&lt;a href=&quot;https://blog.teraren.com/2008/10/11/%e3%82%bd%e3%83%bc%e3%82%b9%e3%82%b3%e3%83%bc%e3%83%89%e3%81%ae%e3%82%b9%e3%83%9a%e3%83%ab%e3%83%81%e3%82%a7%e3%83%83%e3%82%af/&quot;&gt;スペルチェックの方法があったのでこちらに記載&lt;/a&gt;。&lt;/p&gt;
</content:encoded></item><item><title>RCSの罠</title><link>https://blog.teraren.com/posts/rcs-pitfalls/</link><guid isPermaLink="true">https://blog.teraren.com/posts/rcs-pitfalls/</guid><description>RCSでチェックインした後にviで強制保存したファイルをチェックアウトしてもアラートが出ない落とし穴を解説。wq!は使わずq!にすべき理由を紹介。</description><pubDate>Tue, 16 Sep 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;なんとまぁ、RCSに足下すくわれてしまったよ。&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair &lt;em&gt;/}
以下の一連の操作の最後で、co -l をしているのだが、その際にアラートを出してほしいのに、出してくれなかった（T T
{/&lt;/em&gt; textlint-enable */}&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# ci -u -m&apos;modified something&apos; /etc/sync.sh
# vi /etc/sync.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;編集して、強制保存。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# co -l  /etc/sync.sh
/etc/RCS/sync.sh,v  --&amp;gt;  /etc/sync.sh
revision 1.12 (locked)
done
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;言葉で説明すると、&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;チェックイン&lt;/li&gt;
&lt;li&gt;本当は編集してはいけないのに、ファイルを編集して強制上書き保存。この際にファイルのwrite権限は無い&lt;/li&gt;
&lt;li&gt;チェックアウト。チェックインしたときとファイルの内容が変わっているから、にアラートを出してほしい！&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;やられました。&lt;/p&gt;
&lt;p&gt;viでwq!(w!)は使わないようにしましょう。q!はOK。&lt;/p&gt;
</content:encoded></item><item><title>UNIXタイムスタンプからユーザフレンドリーな日時</title><link>https://blog.teraren.com/posts/unix-timestamp-to-human-readable-datetime/</link><guid isPermaLink="true">https://blog.teraren.com/posts/unix-timestamp-to-human-readable-datetime/</guid><description>UNIXタイムスタンプからユーザフレンドリーな日時</description><pubDate>Sat, 06 Sep 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;https://matsu.teraren.com/timestamp_to_date.php&lt;/p&gt;
&lt;p&gt;今までありそうでなかったサービス。&lt;br /&gt;
ただのUNIXタイムスタンプを見やすい形式に変換するだけ。&lt;/p&gt;
</content:encoded></item><item><title>OpenSSLコマンドメモ</title><link>https://blog.teraren.com/posts/openssl-command-memo/</link><guid isPermaLink="true">https://blog.teraren.com/posts/openssl-command-memo/</guid><description>ApacheでSSLサーバを構築する際に必要な秘密鍵・CSR生成からサーバ証明書の確認まで、OpenSSLコマンドをまとめたリファレンス</description><pubDate>Tue, 26 Aug 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;apacheでSSLサーバを構築するために必要なコマンドや設定ファイルの要点をまとめておきます。&lt;/p&gt;
&lt;h3&gt;ファイル説明&lt;/h3&gt;
&lt;p&gt;server.key: 秘密鍵&lt;br /&gt;
server.csr: CSR（証明機関へ送るファイル）&lt;br /&gt;
server.crt: サーバ証明書（証明機関からもらったファイル）&lt;br /&gt;
verisign-ca.crt: 中間CA証明書（verisign）&lt;/p&gt;
&lt;h3&gt;生成系&lt;/h3&gt;
&lt;p&gt;秘密鍵生成&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cat /dev/random &amp;gt; /tmp/random
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;1分後ぐらいにCtrl-cで止める。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% openssl genrsa -rand /tmp/random -des3 2048 -o server.key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;CSRの作成&lt;/p&gt;
&lt;p&gt;&lt;s&gt;&lt;code&gt;% openssl req -new -key server.key -out test.csr&lt;/code&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;もはや、SHA1が安全では無いので、以下のSHA256オプションを付ける必要あり。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% openssl req -new -sha256 -key server.key -out test.csr
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;表示系&lt;/h3&gt;
&lt;p&gt;CSRの内容表示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% openssl req -in server.csr -text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;秘密鍵の内容表示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% openssl rsa -in server.key -text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;サーバ証明書の内容表示&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% openssl x509 -in server.crt -text
% openssl x509 -in verisign-ca.crt -text
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Apache設定&lt;/h3&gt;
&lt;p&gt;SSLCertificateChainFileは中間CA証明書が指定された場合のみ指定する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SSLCertificateKeyFile &quot;server.key&quot;
SSLCertificateFile &quot;server.crt&quot;
SSLCertificateChainFile &quot;verisign-ca.crt&quot;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>MySQLのカラムにYEAR型は使うべきではない</title><link>https://blog.teraren.com/posts/avoid-mysql-year-type/</link><guid isPermaLink="true">https://blog.teraren.com/posts/avoid-mysql-year-type/</guid><description>MySQLのカラムにYEAR型は使うべきではない</description><pubDate>Sat, 16 Aug 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;範囲が狭いし、表現方法が5種類あるし、それぞれに細かいルールがある。&lt;br /&gt;
保持できる範囲は1バイト分。&apos;1901&apos; ～ &apos;2155&apos;。&lt;br /&gt;
&lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/year.html&quot;&gt;https://dev.mysql.com/doc/refman/8.0/en/year.html&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;プログラムや、ユーザ入力の内容によっては予期しない動作をする可能性があるので、年だけを扱うならば、UNSIGNED SMALLINTを使うべき。&lt;/p&gt;
</content:encoded></item><item><title>長いSQL</title><link>https://blog.teraren.com/posts/long-sql/</link><guid isPermaLink="true">https://blog.teraren.com/posts/long-sql/</guid><description>長いSQL</description><pubDate>Thu, 14 Aug 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2008/08/ws04371.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2008/08/ws04371.jpg&quot; alt=&quot;&quot; title=&quot;long sql&quot; /&gt;&lt;/a&gt; 人生で一番長いSQL。。。。 書くのに1日かかった。。。。。。。 プログラムによる自動生成した結果。。。。。。その結果がこれ。 結合数：17 サブクエリ：5段階　（=サブサブサブサブサブクエリ）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ERレベルで設計変更をしっかり行える時間があれば、こんな長いSQL書かなくても良いんだけどなぁー&lt;/li&gt;
&lt;li&gt;運用環境が MySQL4.1だからView使えないしなー&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Subversion1.5になってからエラーが頻発・・・</title><link>https://blog.teraren.com/posts/subversion15-frequent-errors/</link><guid isPermaLink="true">https://blog.teraren.com/posts/subversion15-frequent-errors/</guid><description>Subversion1.5になってからエラーが頻発・・・</description><pubDate>Tue, 12 Aug 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;↓こんなこと言われたら、たまったもんじゃない。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% svn ci -m &apos;&apos;
svn: Working copy &apos;/hoge&apos; locked
svn: run &apos;svn cleanup&apos; to remove locks (type &apos;svn help cleanup&apos; for details)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ svn cleanup
svn: Unable to lock &apos;hoge&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;原因は、.svnディレクトリ内がぶっ壊れているため。&lt;/p&gt;
&lt;p&gt;解決策は、別の場所にmoduleをcheckoutして、同じ階層の.svnディレクトリを丸ごとコピー&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cp -ra /new/.svn /broken/
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>MySQLで直前にinsertしたレコードの取得。</title><link>https://blog.teraren.com/posts/mysql-get-last-inserted-record/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-get-last-inserted-record/</guid><description>MySQLで直前にinsertしたレコードの取得。</description><pubDate>Sun, 10 Aug 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;MySQL 直前に挿入されたレコードの検索&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;SELECT * FROM tbl_name WHERE auto_col IS NULL
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://dev.mysql.com/doc/refman/4.1/ja/comparison-operators.html&quot;&gt;http://dev.mysql.com/doc/refman/4.1/ja/comparison-operators.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PHPから使う分には、PDOオブジェクトから取得できるからいらないけど。&lt;/p&gt;
</content:encoded></item><item><title>mysql nullと0</title><link>https://blog.teraren.com/posts/mysql-null-and-zero/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-null-and-zero/</guid><description>mysql nullと0</description><pubDate>Wed, 06 Aug 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2008/08/ws0437.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;MySQLにて、nullを数字として計算すると、数字側がダウンキャストされて結果がNULLとして返される。&lt;br /&gt;
NULLがアップキャストされて、0にならないことに注意。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysql&amp;gt; select 100 - null;
+------------+
| 100 - null |
+------------+
|       NULL |
+------------+
1 row in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;version: 4.1.22-log&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>gooshすごい。。。</title><link>https://blog.teraren.com/posts/goosh-is-amazing/</link><guid isPermaLink="true">https://blog.teraren.com/posts/goosh-is-amazing/</guid><description>gooshすごい。。。</description><pubDate>Fri, 06 Jun 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2008/06/ws0428.jpg&quot;&gt;&lt;img src=&quot;../../assets/uploads/2008/06/ws0428.jpg&quot; alt=&quot;&quot; title=&quot;goosh&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;さすがに、つかわんけど、Webブラウザでここまで実装しちゃうのは尊敬する。&lt;br /&gt;
&lt;a href=&quot;http://goosh.org/&quot;&gt;http://goosh.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;このサービスは、ターゲットがとても狭いが、完成度は高い。ニッチ。&lt;/p&gt;
</content:encoded></item><item><title>SFCのNTPサーバ</title><link>https://blog.teraren.com/posts/sfc-ntp-server/</link><guid isPermaLink="true">https://blog.teraren.com/posts/sfc-ntp-server/</guid><description>SFCのNTPサーバ</description><pubDate>Tue, 27 May 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;密かに運用されていたりする。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ntp.sfc.keio.ac.jp&lt;br /&gt;
133.27.4.121&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.ne.jp/asahi/pino/databox/ntp_server.txt&quot;&gt;http://www.ne.jp/asahi/pino/databox/ntp_server.txt&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>qmail-0.0.0.0.patch</title><link>https://blog.teraren.com/posts/qmail-0000patch/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qmail-0000patch/</guid><description>qmail-0.0.0.0.patch</description><pubDate>Sat, 26 Apr 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;qmail-0.0.0.0.patchが保存してあるのサーバが落ちているようなので、キャッシュ用に保存しておきます。 &lt;a href=&quot;/uploads/2008/04/qmail-0.0.0.0.patch&quot;&gt;qmail-0.0.0.0.patch&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>シェルスクリプトでIPアドレスを求める方法</title><link>https://blog.teraren.com/posts/shell-script-get-ip-address/</link><guid isPermaLink="true">https://blog.teraren.com/posts/shell-script-get-ip-address/</guid><description>シェルスクリプトでIPアドレスを求める方法</description><pubDate>Tue, 08 Apr 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;シェルスクリプト内で自ホストのIPアドレスを利用したいときがあったので、書いてみた。&lt;/p&gt;
&lt;p&gt;長くて汚いなぁ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% /sbin/ifconfig|grep &apos;inet addr&apos;|grep -v 127.0.0.1|gawk &apos;{print $2;}&apos; | gawk -F : &apos;{print $2;}&apos;
192.168.100.84
%
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Linuxのみで動作します。&lt;br /&gt;
もっといい書き方有ったら教えてほしいです。&lt;/p&gt;
&lt;p&gt;/etc/sysconfig/network-scripts/ifcfg-eth0 から取得してもいいけど、ファイル名が違ったり、ディストリビューションによってファイルの置き場所が違うからいまいち汎用的じゃない。&lt;/p&gt;
</content:encoded></item><item><title>ポート番号からサービス名</title><link>https://blog.teraren.com/posts/service-name-from-port-number/</link><guid isPermaLink="true">https://blog.teraren.com/posts/service-name-from-port-number/</guid><description>ポート番号からサービス名</description><pubDate>Wed, 26 Mar 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2008/03/ws0394.JPG&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Linuxホスト上で、あるポートを占有しているプロセスを調べる方法。&lt;/p&gt;
&lt;p&gt;たまにしか使わないけど、重要なのでメモっておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# lsof -i:53
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>コピペでできるiptables</title><link>https://blog.teraren.com/posts/2008-03-25-kopipededekiruiptables/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2008-03-25-kopipededekiruiptables/</guid><description>サーバセットアップ時にそのまま使えるiptablesのコマンド例。FTP・HTTP・DNSの許可とINPUT DROPポリシーの設定をCentOS 4.6で動作確認済み。</description><pubDate>Tue, 25 Mar 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;サーバをセットアップするときに、iptablesをコマンドでちゃちゃっと設定したいときのためのメモ。&lt;/p&gt;
&lt;p&gt;リモートで実行する際にはお気を付けください。&lt;br /&gt;
自己責任でご利用願います。Cent OS 4.6にて動作確認はしてあります。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export PATH=$PATH:/sbin/:/usr/sbin/

# allow access for this setting
iptables -P INPUT ACCEPT
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# reset policy
iptables -F

# allow
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p udp --dport 20        -j ACCEPT
iptables -A INPUT -p tcp --dport 21        -j ACCEPT
iptables -A INPUT -p tcp --dport 80        -j ACCEPT
iptables -A INPUT -p udp --dport 53        -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# back to set input as drop
iptables -P INPUT DROP

# save
/etc/init.d/iptables save
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>ext3ってinode増えすぎると壊れるくさい</title><link>https://blog.teraren.com/posts/ext3-inode-overflow-corruption/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ext3-inode-overflow-corruption/</guid><description>ext3ってinode増えすぎると壊れるくさい</description><pubDate>Sat, 15 Mar 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2回経験した。&lt;/p&gt;
&lt;h3&gt;その1&lt;/h3&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/ja-no-successive-word &lt;em&gt;/}
PVがほどほどにあるサイトで、PHPを使ってページをレンダリングしていた。
{/&lt;/em&gt; textlint-enable */}&lt;/p&gt;
&lt;p&gt;PV数が多くなり、PHPのGCの処理が追いつかなくなり、セッションを保存するファイルが消えずにどんどん溜っていった。&lt;/p&gt;
&lt;p&gt;→fsckかけたらエラーだらけ。&lt;/p&gt;
&lt;h3&gt;その2&lt;/h3&gt;
&lt;p&gt;logrotateの設定をミスって、rotateしたログをrotateするという指数的にファイル数が増える状態になっていた。&lt;/p&gt;
&lt;p&gt;設定を間違っているのに気づき、ファイルを消した。その後、logrotateが途中で止まる。logrotate -dしても途中で止まる。CPUはuserレベルで100%使ってた。&lt;/p&gt;
&lt;p&gt;→fsckかけたらエラーだらけ。&lt;/p&gt;
&lt;p&gt;ext3 ファイルシステム信頼できね。&lt;/p&gt;
</content:encoded></item><item><title>qmail-date-localtime.patch</title><link>https://blog.teraren.com/posts/qmail-date-localtimepatch/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qmail-date-localtimepatch/</guid><description>qmail-date-localtime.patch</description><pubDate>Sat, 15 Mar 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;あちらこちらでリンク切れになっているのでコピーしておきます。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/uploads/2008/03/qmail-date-localtime.patch&quot;&gt;qmail-date-localtime.patch&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;こんな風にすれば適応できます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% wget ftp://ftp.jp.qmail.org/qmail/qmail-1.03.tar.gz
% wget /uploads/2008/03/qmail-date-localtime.patch
% tar zxf qmail-1.03.tar.gz
% cd qmail-1.03
% patch &amp;lt; ../qmail-date-localtime.patch
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>puttyで作成したプライベートキーをopenssh形式へ変換する方法</title><link>https://blog.teraren.com/posts/2008-03-14-puttydeshitapuraibe-toki-woopensshhesu/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2008-03-14-puttydeshitapuraibe-toki-woopensshhesu/</guid><description>PuTTYで作成したPPK形式の公開鍵をssh-keygenでOpenSSH形式に変換し、authorized_keysへ登録するまでの具体的な手順。</description><pubDate>Fri, 14 Mar 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;puttyで公開鍵認証用のキーペア（秘密鍵、公開鍵）を作成できますが、puttyでエクスポートした公開鍵は直接OpenSSH対応サーバに登録できません。&lt;/p&gt;
&lt;p&gt;OpenSSHサーバへ公開鍵を登録するためにはLinux上で公開鍵をコンバートする必要があります。&lt;/p&gt;
&lt;p&gt;コンバート手順は以下の2ステップ。&lt;/p&gt;
&lt;h3&gt;1. 秘密鍵の変換&lt;/h3&gt;
&lt;p&gt;puttykeygen.exeにて秘密鍵（拡張子がPPK）を読み込む。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Save public key&lt;/strong&gt;を選び、id_rsa_putty.pubという名前で保存する。&lt;/p&gt;
&lt;p&gt;id_rsa_putty.pubをLinux上にアップロードする。&lt;/p&gt;
&lt;h3&gt;2. 公開鍵の変換&lt;/h3&gt;
&lt;p&gt;以下のコマンドで公開鍵をOpenSSH形式に変換する。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ssh-keygen -i -f id_rsa_putty.pub &amp;gt; id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;できあがったid_rsa.pubはauthorized_keyへ登録できる形式となっています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cd
% cat id_rsa.pub &amp;gt;&amp;gt; .ssh/authorized_keys
% chmod 600 .ssh/authorized_keys

&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>シェルスクリプトで排他処理</title><link>https://blog.teraren.com/posts/shell-script-exclusive-processing/</link><guid isPermaLink="true">https://blog.teraren.com/posts/shell-script-exclusive-processing/</guid><description>シェルスクリプトで排他処理</description><pubDate>Tue, 04 Mar 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;運用サーバで、2分おきにsubversionのupdateを行うシェルスクリプトを動かしています。&lt;br /&gt;
今までは、1回のupdateが50秒程度で終了するので、同時実行を防ぐための排他処理をしていませんでした。しかし、サーバの負荷が高かったときは2分以内で終わらない場合があるためスクリプト実行の排他処理をしなければなりません。&lt;/p&gt;
&lt;p&gt;Webを調べているとシェルスクリプトでロック用のディレクトリを作ってます。しかし、かっこわるい。。。そこで見つけたのがlockfileというコマンド。このコマンドを使った方がロック取得を失敗したときの挙動を変えられるから便利そうです。（今回の場合は意味無いけど）&lt;/p&gt;
&lt;p&gt;以下にコード書いておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/sh

LOCKFILE=/tmp/subversion.locked

# try to get lock. With no retry.
lockfile -r 0 $LOCKFILE

# evaluate return code
if [ $? -ne 0 ]; then
  echo &quot;Command aborted&quot;
  exit 1
fi

# do something exclusive command
echo &quot;important command&quot;

# unlock
rm $LOCKFILE
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>1つのWordPressで、複数のブログを運用する設定（10行追加するだけ）</title><link>https://blog.teraren.com/posts/multiple-wordpress-blog-one-install/</link><guid isPermaLink="true">https://blog.teraren.com/posts/multiple-wordpress-blog-one-install/</guid><description>1つのWordPressインストールで複数ブログを運用するためにwp-config.phpを数行変更してテーブルプレフィックスを動的に切り替えるApache向け設定方法を解説します。</description><pubDate>Tue, 05 Feb 2008 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1つのWordPressプログラムで複数のblogを運用したい人向けの記事です。&lt;/li&gt;
&lt;li&gt;この記事で紹介する方法では、.htaccessを設置できる or サーバ上でシンボリックリンクを張れることが前提です。&lt;/li&gt;
&lt;li&gt;この方法なら数行の変更と1つの小さな設定で新たなblogを構築できます。&lt;/li&gt;
&lt;li&gt;Apache向けの設定です。（nginx用の設定ファイルは上手くかけませんでした。）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;アプローチ&lt;/h2&gt;
&lt;p&gt;WordPressはblogの記事や設定値をデータベースに入れて保存しています。HTTPでアクセスしてきた時に、指定されたURLのpathによってWordPressが参照するテーブル（データベース）の場所を動的に変えることにより1つのWordPress設置で、複数のWordPressのblogを構築できます。&lt;/p&gt;
&lt;h2&gt;設定&lt;/h2&gt;
&lt;p&gt;アクセスされたURLのpathとテーブル名の関連付けを行います。&lt;br /&gt;
編集するファイルは、WordPress管理ディレクトリのトップにあるwp-config.phpです。&lt;/p&gt;
&lt;p&gt;下の例は、&lt;br /&gt;
https://blog.teraren.com/&lt;br /&gt;
をメインとして運用して、&lt;br /&gt;
https://milklog.teraren.com/&lt;br /&gt;
をサブとして運用する場合の例です。&lt;/p&gt;
&lt;p&gt;/blog/でアクセスされた場合は、テーブルのプレフィックス（先頭語）にデフォルトである&quot;wp_&quot;を利用します。&lt;br /&gt;
/~matsu/milkblog/でアクセスされた場合はプレフィックスに&quot;wp_milklog_&quot;を利用します。&lt;/p&gt;
&lt;p&gt;$prefix_arrayは連想配列です。キーにURIを定義し、値に利用するテーブルのprefix（$table_prefixに代入する値）を定義します。以下にdiffを載せておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% rcsdiff -r1.1 -r1.3 wp-config.php
===================================================================
RCS file: RCS/wp-config.php,v
retrieving revision 1.1
retrieving revision 1.3
diff -r1.1 -r1.3
17a18,31
&amp;gt; // determine table prefix according to the REQUEST_URI
&amp;gt; $prefix_array = array(
&amp;gt;   &apos;/~matsu/milklog&apos; =&amp;gt; &apos;wp_milklog_&apos;
&amp;gt; );
&amp;gt;
&amp;gt; if($prefix_array){
&amp;gt;   $uri = $_SERVER[&apos;REQUEST_URI&apos;];
&amp;gt;   foreach($prefix_array as $search_uri =&amp;gt; $search_table_prefix){
&amp;gt;     if(strpos($uri, $search_uri) === false){ continue; }
&amp;gt;     $table_prefix = $search_table_prefix;
&amp;gt;   }
&amp;gt; }
&amp;gt;
&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;次に、指定されたpathでアクセスできるように設定します。&lt;br /&gt;
2種類の設定方法があるのでどちらかを選択してください。SSHでログインできない場合は.htaccessによる設定を選んでください。&lt;/p&gt;
&lt;h3&gt;1 シンボリックリンク&lt;/h3&gt;
&lt;p&gt;指定したpathでアクセスしたときに、WordPressのファイルを参照するようにシンボリックリンクを張ります。&lt;br /&gt;
1つめの引数にWordPressの実態、2つめの引数に新たに追加するblogのpathを指定します。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# wordpressが設置されているディレクトリの上で。
% ln -s blog milk_log

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2 .htaccess&lt;/h3&gt;
&lt;p&gt;新たなpathでアクセスされたときにWordPressの実体へアクセスするようにする.htaccessです。&lt;br /&gt;
以下に例を載せておきます。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RewriteEngine on
RewriteBase /~matsu/

# rewrite milk blog
RewriteRule milklog/(.*) /blog/$1
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule milklog/(.*) /blog/index.php [L]
# /end of rewrite milk blog

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;アイディア元はこちら。&lt;br /&gt;
&lt;a href=&quot;http://ameblo.jp/curiouseverything/entry-10167447535.html&quot;&gt;http://ameblo.jp/curiouseverything/entry-10167447535.html&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;新しいblogの設定&lt;/h2&gt;
&lt;p&gt;新しいblogのwordpress管理画面へアクセスするとblogの初期設定する画面が表示されます。&lt;/p&gt;
&lt;p&gt;例：&lt;br /&gt;
https://milklog.teraren.com/wp-admin/&lt;/p&gt;
&lt;h2&gt;注意&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;WordPress2.5以降で動作確認しています。&lt;/li&gt;
&lt;li&gt;WordPressのアップグレードに影響されない普遍性の高い設定なので、おすすめです。&lt;/li&gt;
&lt;li&gt;(2015/12/3) Worpress 4.3.xでも動作しております。&lt;/li&gt;
&lt;li&gt;(2017/10/31) 共通のファイルを使用すると、テーマやプラグインの管理が煩雑になったり、共通ファイルをblogごとにカスタマイズしたい場合に要求を満たせなくなってきたので1ブログ、1つのWordPressにするようにしました。この方法自体は、今もなお有効です。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;メリット&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;WordPress本体、plugin , themeのアップグレードが1発で終わる。&lt;/li&gt;
&lt;li&gt;新規ブログを立ち上げるのに、PHPファイルに数行追加、webサーバの設定に数行追加するだけで完了する。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;デメリット&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;画像のアセットが保存されているディレクトリが1箇所なので、全部のブログの画像が1つのディレクトリに保存されてしまう。それによって、ブログを1つ消したときにそれに関連付いた画像を消すのが困難。&lt;/li&gt;
&lt;li&gt;上記と同様に同様に、テーマファイル、プラグインも混ざる。1つのブログで導入したプラグインが、全部のブログで表示されてしまっていまいち。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>グレシャム（Gresham）の法則</title><link>https://blog.teraren.com/posts/gresham-law/</link><guid isPermaLink="true">https://blog.teraren.com/posts/gresham-law/</guid><description>グレシャム（Gresham）の法則</description><pubDate>Thu, 31 Jan 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;「質の悪い仕事が質のよい仕事を駆逐する」 ソフトウェアコンストラクションに適合する法則である。 建築にたとえると、10階建てのビルのうち、1つの柱が手抜き工事だったら全体として安全ではない建物となる。 ソフトウェア設計理論に関する論文。 理想的なソフトウェア開発と各段階でのアウトプットの出し方を提案している。そこら辺の本を読むよりいい。シンプルにまとまって読みやすい。 A RATIONAL DESIGN PROCESS: HOW AND WHY TO FAKE IT&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Establish and document requirements.&lt;/li&gt;
&lt;li&gt;Design and document the module structure&lt;/li&gt;
&lt;li&gt;Design and document the module interfaces&lt;/li&gt;
&lt;li&gt;Design and document the uses hierarchy&lt;/li&gt;
&lt;li&gt;Design and document the module internal structures&lt;/li&gt;
&lt;li&gt;Write Programs&lt;/li&gt;
&lt;li&gt;Maintain&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>全国駅データの無料版！</title><link>https://blog.teraren.com/posts/free-japan-station-data/</link><guid isPermaLink="true">https://blog.teraren.com/posts/free-japan-station-data/</guid><description>全国駅データの無料版！</description><pubDate>Sat, 19 Jan 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;駅データは普通は販売されており、値段は数万～数十万円します。掲載されている情報は緯度経度、営業距離、カナなど様々です。 しかし、&lt;a href=&quot;http://www.ekidata.jp/&quot;&gt;株式会社ワクワクプラン&lt;/a&gt;様が無料で全国駅データを公開しています。情報量もそこそこ豊富なので、「xx駅周辺の最寄り駅10個」とか「ある路線の駅一覧」といった情報を取り出せます。 以下は掲載されている項目の一覧です。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;鉄道概要コード&lt;/li&gt;
&lt;li&gt;路線コード&lt;/li&gt;
&lt;li&gt;駅コード&lt;/li&gt;
&lt;li&gt;路線並び順&lt;/li&gt;
&lt;li&gt;駅並び順&lt;/li&gt;
&lt;li&gt;駅グループコード&lt;/li&gt;
&lt;li&gt;駅タイプ&lt;/li&gt;
&lt;li&gt;鉄道概要名&lt;/li&gt;
&lt;li&gt;路線名&lt;/li&gt;
&lt;li&gt;駅名&lt;/li&gt;
&lt;li&gt;都道府県コード&lt;/li&gt;
&lt;li&gt;経度&lt;/li&gt;
&lt;li&gt;緯度&lt;/li&gt;
&lt;li&gt;表示フラグ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SQLでぶち込むのは面倒なので、スキーマと駅情報のデータを記載したSQLを作成したので、適当にご利用ください。用途は小規模サイト用で作ったのでindexのカラムは要確認です。 &lt;a href=&quot;/uploads/2008/01/ekidata.sql&quot;&gt;駅データのスキーマとデータ（2008年1月19日）&lt;/a&gt; 駅データは頻繁に更新されているようです。&lt;/p&gt;
</content:encoded></item><item><title>Fatal error: Exception thrown without a stack frame in Unknown on line 0</title><link>https://blog.teraren.com/posts/fatal-error-exception-thrown-without-a-stack-frame-in-unknown-on-line-0/</link><guid isPermaLink="true">https://blog.teraren.com/posts/fatal-error-exception-thrown-without-a-stack-frame-in-unknown-on-line-0/</guid><description>Fatal error: Exception thrown without a stack frame in Unknown on line 0</description><pubDate>Mon, 07 Jan 2008 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;PHPのsession管理のためにファイルを利用しているとき、そのファイルを保存する場所が読み書きできない場合に発生。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Fatal error: Exception thrown without a stack frame in Unknown on line 0
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>IMAP web client</title><link>https://blog.teraren.com/posts/imap-web-client/</link><guid isPermaLink="true">https://blog.teraren.com/posts/imap-web-client/</guid><description>IMAP web client</description><pubDate>Thu, 20 Dec 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;海外に出かけるので、Webから会社のメールを見るためにIMAPのWebクライアントを捜していたら、超すごいのを発見。&lt;/p&gt;
&lt;p&gt;インストールは、ダウンロードして設定ファイル書き換えて、データベースを初期化して終わり。テキストファイルを編集して設定するのが面倒だったけど、スムーズにできる。日本語もサポートしていいかんじ。UIはajaxを使っているため、gmailのようにメールを読める。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.roundcube.net/&quot;&gt;roundcube mail&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2007/12/ws0365_r2_c2.gif&quot;&gt;&lt;img src=&quot;../../assets/uploads/2007/12/ws0365_r2_c2.thumbnail.gif&quot; alt=&quot;ws0365_r2_c2.gif&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>携帯ページで使うapacheのリダイレクト</title><link>https://blog.teraren.com/posts/apache-redirect-mobile/</link><guid isPermaLink="true">https://blog.teraren.com/posts/apache-redirect-mobile/</guid><description>携帯ページで使うapacheのリダイレクト</description><pubDate>Sat, 01 Dec 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;携帯では、temporary moved(302)を返すべき！&lt;/p&gt;
&lt;p&gt;moved permanent (301)を返すと、DoCoMoで警告がでちゃいます。auでは出ないことを確認しました。&lt;/p&gt;
&lt;p&gt;警告を出さないようにするためには、Found（302）を返します。RedirectディレクティブのデフォルトがFoundなので、以下のように書けば問題ないです。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Redirect /service http://foo2.bar.com/service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下でも同義&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Redirect temp /service http://foo2.bar.com/service
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;mod_rewriteだと以下のように&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RewriteRule ^/service/(.*) http://foo2.bar.com/service/$1 [R=302,L]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Apacheの設定ではないけど、携帯端末を対象にリダイレクト をしたい場合は、Foundを返して、Locationヘッダで飛ばしてもいい。&lt;/p&gt;
</content:encoded></item><item><title>unixコマンドでgrepの否定条件</title><link>https://blog.teraren.com/posts/grep-invert/</link><guid isPermaLink="true">https://blog.teraren.com/posts/grep-invert/</guid><description>unixコマンドでgrepの否定条件</description><pubDate>Sat, 01 Dec 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;-v&lt;/code&gt;で指定した正規表現の否定にマッチする。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% grep -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ヘルプにこう書いてある。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-v, --invert-match        select non-matching lines
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用例&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;% cat textfile
a
b
c

% grep -v b textfile
a
c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;::amazon{asin=&quot;4802610327&quot;}&lt;/p&gt;
</content:encoded></item><item><title>複数台で運用しているサーバのアクセスログを1つに統合する</title><link>https://blog.teraren.com/posts/apaceh-integrate-logs/</link><guid isPermaLink="true">https://blog.teraren.com/posts/apaceh-integrate-logs/</guid><description>複数台のApacheサーバに分散したアクセスログをawstatsのlogresolvemerge.plで時系列順に統合し、一括解析する方法</description><pubDate>Fri, 30 Nov 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;複数台のフロントエンドサーバでapacheが動いている場合を想定します。&lt;/p&gt;
&lt;p&gt;その場合、アクセスログが複数のサーバにまたがってしまいます。&lt;/p&gt;
&lt;p&gt;こんなかんじ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;web-01.access-log.20071130&lt;/li&gt;
&lt;li&gt;web-02.access-log.20071130&lt;/li&gt;
&lt;li&gt;web-03.access-log.20071130&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;webalizerやawstatsといったアクセスログ解析ソフトではこのファイルの状態では解析できない。&lt;/p&gt;
&lt;p&gt;なぜなら、webalizerやawstatsのデフォルトでは1つのファイルのみを入力として受け付け、時系列順に記録されていなければならない。&lt;/p&gt;
&lt;p&gt;この問題を解決するスクリプトを発見しました。awstatsの中に入っているlogresolvemerge.plというperlスクリプトです。&lt;/p&gt;
&lt;p&gt;使い方は超簡単。引数に統合したいファイルを指定して実行すると、標準出力に時系列順にそろったレコードが出力される。&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% perl logresolvemerge.pl /path/to/log/*access.log.20071130|more
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;引数にgz圧縮されたファイルを指定してもちゃんと動きます。至れり尽くせりなスクリプト。&lt;/p&gt;
&lt;p&gt;★おまけ情報★&lt;br /&gt;
ある日まで、commonフォーマットでアクセスログを取っていて、ある時点からcombinedフォーマットでログを取りだした場合、1つのアクセスログの中に2種類のフォーマットのログが混入してしまう。&lt;/p&gt;
&lt;p&gt;そこで見つけたのがこの方法。commonフォーマットをcombinedフォーマットにする方法。&lt;br /&gt;
&lt;a href=&quot;http://www.trisweb.com/archives/2007/02/15/convert-apache-common-logs-to-combined-logs/&quot;&gt;http://www.trisweb.com/archives/2007/02/15/convert-apache-common-logs-to-combined-logs/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;3回シェルのコマンドを実行すればできちゃう！CUIはすばらしい。&lt;/p&gt;
&lt;p&gt;参照：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://awstats.sourceforge.net/&quot;&gt;http://awstats.sourceforge.net/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>dot-qmailハマった。。。</title><link>https://blog.teraren.com/posts/dot-qmail-no-such-file-or-directory/</link><guid isPermaLink="true">https://blog.teraren.com/posts/dot-qmail-no-such-file-or-directory/</guid><description>dot-qmailハマった。。。</description><pubDate>Tue, 27 Nov 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;dot-qmailのパイプを使ってプログラムを実行しようとしていたけど、以下のエラーが出て実行できなかった！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@40000000474be69c2d94c514 delivery 476: deferral: bash:_receipt_mail.sh_:_No_such_file_or_directory/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ファイルは存在するのに、全然見てくれない。&lt;/p&gt;
&lt;p&gt;いろいろ妄想しました、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;chroot勝手にされているのか？&lt;/li&gt;
&lt;li&gt;.qmailは600にしないといけないのか？&lt;/li&gt;
&lt;li&gt;qmail自体がバグったのか？&lt;/li&gt;
&lt;li&gt;/binにpathが通っていないのか？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;とか。。。6時間ぐらい費やした。しかし上記はすべてハズレ！&lt;/p&gt;
&lt;p&gt;原因は改行コード。dot-qmailの最後の行に\rが入ってたためです。エラーログにも出てこないのでトラブルシュートが辛かった。。。&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair &lt;em&gt;/}
改行コード 凸(`、´メ）
{/&lt;/em&gt; textlint-enable ja-technical-writing/no-unmatched-pair */}&lt;/p&gt;
</content:encoded></item><item><title>PHPの日時に関連する関数の制限</title><link>https://blog.teraren.com/posts/php-date-function/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-date-function/</guid><description>PHPのdate関数とstrtotime関数が32ビット環境で1901〜2038年の範囲しか扱えない制限を実験で確認し、1800〜2500年を表現する代替方法を検討した調査メモ</description><pubDate>Fri, 23 Nov 2007 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;問題意識&lt;/h2&gt;
&lt;p&gt;PHPが表現できる日付に制限があり、1800年といった表記をdate関数から&lt;br /&gt;
出力できないため、1800年から2500年程度の時間を表現する方法を導く。&lt;/p&gt;
&lt;h2&gt;実験内容&lt;/h2&gt;
&lt;p&gt;まず、制限値の詳細を知るために&lt;br /&gt;
1．date関数の第2引数に与えられるタイムスタンプの範囲を調べる。&lt;br /&gt;
2．strtotime関数の引数に指定できる時間の範囲を調べる。&lt;/p&gt;
&lt;h2&gt;実験結果&lt;/h2&gt;
&lt;p&gt;1．date関数の第2引数にタイムスタンプとして指定した場合：&lt;br /&gt;
最小値:-2147483648(1901-12-14 05:45:52)&lt;br /&gt;
最大値: 2147483647 (2038-01-19 12:14:07)&lt;/p&gt;
&lt;p&gt;2．strtotime関数の引数に時間を指定した場合&lt;br /&gt;
最小値: 1901-12-14 05:45:52&lt;br /&gt;
最大値: 2038-01-19 12:14:07&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;32ビット環境において、&lt;br /&gt;
PHPで整数を扱う場合は-2^31から2^31-1しか扱えない。&lt;/p&gt;
&lt;h2&gt;次の問題意識&lt;/h2&gt;
&lt;p&gt;pearのDateクラスは有効か調査する。&lt;/p&gt;
&lt;h2&gt;実験内容&lt;/h2&gt;
&lt;p&gt;2.1 コンストラクタに2147483647を指定し、&lt;br /&gt;
秒を追加してゆき、getDateを表示してみて&lt;br /&gt;
想定する結果との差異を検証。&lt;/p&gt;
&lt;p&gt;2.2&lt;br /&gt;
コンストラクタに-2147483648を指定し、&lt;br /&gt;
秒を減らしてゆき、getDateを表示してみて&lt;br /&gt;
想定する結果との差異を検証。&lt;/p&gt;
&lt;h2&gt;実験結果&lt;/h2&gt;
&lt;p&gt;2.1&lt;br /&gt;
9999-12-31 23:59:59 まで表示可能その後に1秒を足すと現在時刻に初期化される。&lt;/p&gt;
&lt;p&gt;Date.phpのソースコードを追ってみると、年・月・日や時・分・秒はそれぞれ変数になっている。&lt;br /&gt;
なぜ、999年までしかいけないかというと、addSpanメソッドで無理矢理4桁に処理されているため。&lt;/p&gt;
&lt;p&gt;2.2&lt;br /&gt;
999-12-31 23:59:59 まで表示可能。その後に1秒を引くと9909-12-31 23:59:58となる&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;西暦が4桁ならば正常に動作。&lt;/p&gt;
&lt;h2&gt;次の問題意識&lt;/h2&gt;
&lt;p&gt;3.1 mktimeのサポートする範囲&lt;/p&gt;
&lt;h2&gt;実験結果&lt;/h2&gt;
&lt;p&gt;3.1&lt;br /&gt;
年の入力に制限がある。&lt;br /&gt;
年の入力範囲：0-38,70-110,1903-2038&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;mktimeは1903年から2038年まで。&lt;/p&gt;
&lt;h2&gt;次の問題意識&lt;/h2&gt;
&lt;p&gt;4.checkdateのサポートする範囲&lt;/p&gt;
&lt;h2&gt;実験結果&lt;/h2&gt;
&lt;p&gt;4.西暦1年1月1日から、西暦32767年12月31日&lt;/p&gt;
&lt;h2&gt;まとめ&lt;/h2&gt;
&lt;p&gt;西暦は16ビット分。チェックには利用可能。&lt;/p&gt;
&lt;h2&gt;次の問題意識&lt;/h2&gt;
&lt;p&gt;mktime,strtotimeが表現できる日時に制限があるため、目的の範囲を&lt;br /&gt;
サポートする日時のvalidation方法はあるのか。&lt;/p&gt;
&lt;h2&gt;調査&lt;/h2&gt;
&lt;p&gt;・symphonyはmktime,strtotimeを利用してチェック。&lt;br /&gt;
・zend frameworkはcheckdateにて日付をチェック。&lt;br /&gt;
・Mapleはcheckdateにて日付のみチェック。&lt;/p&gt;
&lt;h2&gt;結論&lt;/h2&gt;
&lt;p&gt;PHPのネイティブ関数でサポートする日時表記の積集合部分は&lt;br /&gt;
1901-12-14 05:45:52から2038-01-19 12:14:07である。&lt;/p&gt;
&lt;p&gt;日付のチェックはcheckdateを使えば実用に問題はない。&lt;/p&gt;
&lt;p&gt;時間のチェックは自分で書く。&lt;/p&gt;
&lt;p&gt;ネイティブでサポートされていない日時表記のためにはPearのDateクラスを利用すれば&lt;br /&gt;
1000年から9999年まで表現できる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
/**
 * 実験1
 * date関数の第2引数がサポートするタイムスタンプの最大値、最小値を求める。
 *
 */

require_once(&apos;Date.php&apos;);

print &apos;result:&apos;.getMax(2147558400 - 60*60*24, 1);

function getMax($from = 0 , $step = 1){

  $i = $from;
  $last_i = 0;

  while(true){

    $current =  date(&apos;Y-m-d H:i:s&apos;, $i);

    if($current == $last){
      return $last_i;
    }

    if(($i % $step) == 0){
      print sprintf(&quot;%s %d\n&quot;, $current, $i);
    }

    $last_i = $i;
    $last = $current;

    // increment
    $i += $step;

  }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
/**
 * 2.Dateクラスの範囲測定
 *
 */

require_once(&apos;Date.php&apos;);

//$date = new Date(2147483647);
$date = new Date(-2147483647);

for($i=0;$i &amp;lt; 902;$i++){
$date-&amp;gt;addSeconds(-60*60*24*365);
}
$date-&amp;gt;addSeconds(-60*60*24*200);

$last = &apos;&apos;;
while(true){
  $current = $date-&amp;gt;getDate();
  if($current == $last){

    var_dump($current);
    var_dump($date);
    break;
  }

  var_dump($current);

  $date-&amp;gt;addSeconds(-1);
  $last = $current;

}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
/**
 * 実験3
 * mktimeがサポートする範囲
 *
 */

for($i=0;$i&amp;lt;10000;$i++){

  var_dump(mktime(0,0,0,0,0,$i));
  print $i.&quot;\n&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
/**
 * 実験4
 * checkdateがサポートする範囲
 *
 */

var_dump(checkdate(1,1,-100));
var_dump(checkdate(1,1,1));
var_dump(checkdate(1,1,10));
var_dump(checkdate(1,1,1969));
var_dump(checkdate(1,1,2039));
var_dump(checkdate(1,1,9999));
var_dump(checkdate(1,1,10000));
var_dump(checkdate(12,31,32767));
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>F5 BIG-IP 1500 と Link Controllerの組み合わせで不具合</title><link>https://blog.teraren.com/posts/f5-big-ip-1500-link-controller/</link><guid isPermaLink="true">https://blog.teraren.com/posts/f5-big-ip-1500-link-controller/</guid><description>F5 BIG-IP 1500 と Link Controllerの組み合わせで不具合</description><pubDate>Thu, 22 Nov 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;F5 BIG-IP 1500 と Link Controllerを仕事で使っているのだが、細かいところで不具合がある。&lt;/p&gt;
&lt;p&gt;Link Controllerとは複数のグローバル回線を統括して回線のup-and-downを把握し、内蔵のDNSサーバがupしている方のWAN InterfaceのIPアドレスを返すBIG-IPのアドオンモジュールです。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Link Controllerにて管理するDNSで、ドメイン名に対してAレコードをアサインできない。&lt;/li&gt;
&lt;li&gt;AレコードのTTLを10秒程度に すると、約10秒に1回、クライアントPCでAレコードが引けなくなる。どうやら、クライアント側のルータのキャッシュ方法と相性が悪いらしいが、複数の事務所、家庭から不具合の報告の連絡がある。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;1年経っても上記の問題は解決されず、年間の保守料が80万円もする。。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2007/11/bigip15001.jpg&quot; alt=&quot;bigip15001.jpg&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>WordPress 最強アクセスロガー Slimstat EX</title><link>https://blog.teraren.com/posts/slimstat-ex/</link><guid isPermaLink="true">https://blog.teraren.com/posts/slimstat-ex/</guid><description>WordPress 最強アクセスロガー Slimstat EX</description><pubDate>Wed, 21 Nov 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;../../assets/uploads/2007/11/ws0381.JPG&quot;&gt;&lt;img src=&quot;../../assets/uploads/2007/11/ws0381.thumbnail.JPG&quot; alt=&quot;ws0381.JPG&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;今までSlimstatを使っていたけど、こっちの方が多機能で、綺麗。 &lt;a href=&quot;http://082net.com/2006/756/wp-slimstat-ex-plugin-en/&quot;&gt;http://082net.com/2006/756/wp-slimstat-ex-plugin-en/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>PHP 5.2.5 と nucleus</title><link>https://blog.teraren.com/posts/php525/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php525/</guid><description>PHP 5.2.5 と nucleus</description><pubDate>Sun, 18 Nov 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;PHP5.2.5にしたらnucleusの管理ページにて、segmentention faultしちゃう。&lt;/p&gt;
&lt;p&gt;5.2.4に戻したら解決&lt;/p&gt;
&lt;p&gt;こんなんでいいんすか。PHPよ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$a = 1;
$b = &quot;1a&quot;;

if($a == $b){
  print &apos;same&apos;;　　// ←表示されるし。凸(｀、´メ）
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>apc.optimization=1　止まる。</title><link>https://blog.teraren.com/posts/apc-optimization1-stops/</link><guid isPermaLink="true">https://blog.teraren.com/posts/apc-optimization1-stops/</guid><description>apc.optimization=1　止まる。</description><pubDate>Wed, 24 Oct 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;使えない。&lt;/p&gt;
</content:encoded></item><item><title>Compiling subversion from source distribution.</title><link>https://blog.teraren.com/posts/compiling-subversion-from-source-distribution/</link><guid isPermaLink="true">https://blog.teraren.com/posts/compiling-subversion-from-source-distribution/</guid><description>Compiling subversion from source distribution.</description><pubDate>Mon, 01 Oct 2007 00:00:00 GMT</pubDate><content:encoded>&lt;pre&gt;&lt;code&gt;% ./configure --with-apr=/usr/local/apache2   --with-apr-util=/usr/local/apache2 --with-ssl
% make
# make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;subversion-1.4.5 on linux CentOS 4.4.&lt;/p&gt;
&lt;p&gt;クライアントしか使わなければ、このオプションもつけた方がいい。&lt;code&gt;--disable-mod-activation&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>GMTとUTCは違う</title><link>https://blog.teraren.com/posts/get-utc/</link><guid isPermaLink="true">https://blog.teraren.com/posts/get-utc/</guid><description>GMTとUTCは違う</description><pubDate>Wed, 12 Sep 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;学校では、GMTに関してしか習っていなかったのですが、実際の世の中はUTC基準で時刻が決定されているようです。 GMTより、UTCの方が精度が高いです。NTPサーバで同期しているNTPサーバはUTCです。 詳しい説明： &lt;a href=&quot;http://www.asahi-net.or.jp/~hi5k-stu/compt/utc_gmt.htm&quot;&gt;http://www.asahi-net.or.jp/~hi5k-stu/compt/utc_gmt.htm&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>[ERROR] Got error 134 when reading table &apos;./データベース名/テーブル名&apos;</title><link>https://blog.teraren.com/posts/error-got-error-134-when-reading-table/</link><guid isPermaLink="true">https://blog.teraren.com/posts/error-got-error-134-when-reading-table/</guid><description>MySQLでError 134が発生してMyISAMテーブルがクラッシュした際、repairやrestartでは解決せずダンプ・drop・recreateで復旧した手順を紹介。</description><pubDate>Sat, 08 Sep 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;MySQLのテーブルがクラッシュしたくさい。&lt;/p&gt;
&lt;p&gt;MySQLのログにこんな感じでエラーがでてる。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[ERROR] Got error 134 when reading table &apos;./データベース名/テーブル名 &apos;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;環境：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CentOS release 4.5&lt;/li&gt;
&lt;li&gt;mysql-5.0.24 + senna-1.0.1&lt;/li&gt;
&lt;li&gt;MyISAM&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;対処：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;repairしてもOKといわれた。&lt;/li&gt;
&lt;li&gt;checkしてもOKといわれた。&lt;/li&gt;
&lt;li&gt;MySQLをrestartしても改善されない&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;解決方法：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;問題のあるテーブル をdump&lt;/li&gt;
&lt;li&gt;drop&lt;/li&gt;
&lt;li&gt;create&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;トランザクションが使えないから、こんなかんじで。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;mysqldump -u root database table &amp;gt; table.sql
mysql -u root database &amp;lt; table.sql
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>このblogのCMSをNuclleusからWordPressに変更しました</title><link>https://blog.teraren.com/posts/2007-09-02-changed-cms-to-wordpress/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2007-09-02-changed-cms-to-wordpress/</guid><description>ブログのCMSをNucleusからWordPressへ移行した際のURL変更とリダイレクト設定について。Nucleusの更新停止とバグの多さが移行の決め手。</description><pubDate>Mon, 03 Sep 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;必要に応じて、ブックマークとかRSSの変更お願いします。&lt;/p&gt;
&lt;p&gt;一部ページは、以降後のページへリダイレクトするように設定してあります。&lt;/p&gt;
&lt;p&gt;変更前：https://blog.teraren.com/nucleus/&lt;/p&gt;
&lt;p&gt;↓&lt;/p&gt;
&lt;p&gt;変更後：&lt;a href=&quot;https://diary.teraren.com/&quot;&gt;https://diary.teraren.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nucleusはしょぼすぎる。更新も行われていないし、バグも多い。&lt;/p&gt;
&lt;p&gt;Wordpressさいこー！&lt;/p&gt;
</content:encoded></item><item><title>PHPのPDO::mysql。prepared statementはquery cacheを使っている！</title><link>https://blog.teraren.com/posts/php-pdo-mysql/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-pdo-mysql/</guid><description>PHPのPDO::mysqlでprepared statementがクエリキャッシュを活用するか実験。キャッシュON/OFFの速度差が最大823倍になる検証結果を紹介。</description><pubDate>Thu, 02 Aug 2007 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;目的&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PHPのPDO::mysqlはquery cacheを使っているかを知る。&lt;/li&gt;
&lt;li&gt;使っていたらqueryメソッドとの速度差はどのくらいかを知る。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実験環境&lt;/h2&gt;
&lt;p&gt;VM上のLinuxで実験&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: Core2 Duo 2GHz(Host OS)&lt;/li&gt;
&lt;li&gt;OS: Windows XP(Host) CentOS release 4.4 (VM)&lt;/li&gt;
&lt;li&gt;PHP 5.2.3 (CLI)&lt;/li&gt;
&lt;li&gt;MySQL 5.0.41&lt;/li&gt;
&lt;li&gt;郵便番号テーブル 121973件&lt;/li&gt;
&lt;li&gt;検索するカラム: INT(10) unsigned&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実験1&lt;/h2&gt;
&lt;p&gt;prepared statementがquery cacheを使っているかを求める。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;条件
&lt;ul&gt;
&lt;li&gt;10000 times&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;marker time index ex time

prepared statement 1186039399.87295300 4.21059203148
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;条件&lt;/li&gt;
&lt;li&gt;100 times&lt;/li&gt;
&lt;li&gt;mysql&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;set global query_cache_size = 0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;marker time index ex time

prepared statement 1186039289.14549200 34.6095161438
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;結果
&lt;ul&gt;
&lt;li&gt;Query cacheをONにしてprepared statementを使った場合は、OFFにした場合に比べて約823倍速い。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;実験2&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;条件
&lt;ul&gt;
&lt;li&gt;10000 times&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;marker time index ex time perct

exec 1186039395.66236100 4.05659389496 49.07%

prepared statement 1186039399.87295300 4.21059203148 50.93%
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;結果&lt;/li&gt;
&lt;li&gt;execの方が4%早い！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;結論&lt;/h2&gt;
&lt;p&gt;PHPのPDO::mysqlはquery cacheを利用している。&lt;/p&gt;
</content:encoded></item><item><title>PHPのコンパイルオプションに --disable-allをつけて、不要なモジュールをインストールしないときのベンチマーク</title><link>https://blog.teraren.com/posts/2007-07-12-phpnokonpairuopushonni-disable-allwotsuketena/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2007-07-12-phpnokonpairuopushonni-disable-allwotsuketena/</guid><description>PHP 5.2.3のconfigureで--disable-allを指定した場合のファイルサイズ・メモリ使用量・実行速度への影響をベンチマークで比較検証した結果。</description><pubDate>Thu, 12 Jul 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;PHP5.2.3の configureオプションである--disable-allを指定した場合にどの程度パフォーマンスに影響するかを実験する。 --disable-allとは、PHPをインストールする際にデフォルトでインストールされる機能をインストールしないようにするオプション。デフォルトでは不要なも機能まで入ってしまうため、無駄が発生する場合がある。例えば、XML,JSON、filter、PDOなどである。&lt;/p&gt;
&lt;h4&gt;PHP実験環境&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;共通環境
&lt;ul&gt;
&lt;li&gt;ゲスト：CentOS release 4.4 (Final) （on Vmware server 1.0.2）&lt;/li&gt;
&lt;li&gt;ホスト：Windows XP Professional&lt;/li&gt;
&lt;li&gt;CPU: Intel　Core2 Duo 6600 2.4G&lt;/li&gt;
&lt;li&gt;Apache：2.2.4
&lt;ul&gt;
&lt;li&gt;./configure --prefix=/usr/local/apache2 --enable-ssl --enable-rewrite --enable-so&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;環境1&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;./configure --enable-mbstring --enable-soap --enable-zend-multibyte --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql --with-curl --with-curlwrappers --with-gd --with-jpeg-dir=/usr/lib --with-png-dir=/usr/lib --with-zlib-dir=/usr/lib --with-mcrypt
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;環境2&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;./configure --enable-mbstring --enable-soap --enable-zend-multibyte --with-apxs2=/usr/local/apache2/bin/apxs --with-mysql=/usr/local/mysql --with-pdo-mysql=/usr/local/mysql --with-curl --with-curlwrappers --with-gd --with-jpeg-dir=/usr/lib --with-png-dir=/usr/lib --with-zlib-dir=/usr/lib --with-mcrypt --enable-libxml --disable-all
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;環境1には入っていて、環境2には入っていないモジュール
&lt;ul&gt;
&lt;li&gt;ctype&lt;/li&gt;
&lt;li&gt;dom&lt;/li&gt;
&lt;li&gt;filter&lt;/li&gt;
&lt;li&gt;hash&lt;/li&gt;
&lt;li&gt;iconv&lt;/li&gt;
&lt;li&gt;json&lt;/li&gt;
&lt;li&gt;pcre&lt;/li&gt;
&lt;li&gt;PDO&lt;/li&gt;
&lt;li&gt;pdo_mysql&lt;/li&gt;
&lt;li&gt;pdo_sqlite&lt;/li&gt;
&lt;li&gt;posix&lt;/li&gt;
&lt;li&gt;session&lt;/li&gt;
&lt;li&gt;SimpleXML&lt;/li&gt;
&lt;li&gt;SPL&lt;/li&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;li&gt;tokenizer&lt;/li&gt;
&lt;li&gt;xml&lt;/li&gt;
&lt;li&gt;xmlreader&lt;/li&gt;
&lt;li&gt;xmlwriter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;結果&lt;/h4&gt;
&lt;h5&gt;ファイルサイズ&lt;/h5&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;環境1&lt;/th&gt;
&lt;th&gt;環境2&lt;/th&gt;
&lt;th&gt;環境2/環境1 (100%以下なら小さい)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;libphp5.soのファイルサイズ（B）&lt;/td&gt;
&lt;td&gt;17268191&lt;/td&gt;
&lt;td&gt;11998616&lt;/td&gt;
&lt;td&gt;69%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/usr/local/bin/phpのファイルサイズ（B）&lt;/td&gt;
&lt;td&gt;16307443&lt;/td&gt;
&lt;td&gt;11306924&lt;/td&gt;
&lt;td&gt;69%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;apache起動直後のメインプロセスVSZ （kB）&lt;/td&gt;
&lt;td&gt;19572&lt;/td&gt;
&lt;td&gt;17332&lt;/td&gt;
&lt;td&gt;89%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;apache起動直後のサブプロセスVSZ （kB）&lt;/td&gt;
&lt;td&gt;19704&lt;/td&gt;
&lt;td&gt;17468&lt;/td&gt;
&lt;td&gt;89%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h5&gt;コマンドラインベンチマーク&lt;/h5&gt;
&lt;p&gt;コマンドラインにてfunction callの速度を計測。PHPのソースコードに付属している ./Zend/bench.php を利用。 5回実行した結果の平均を記載。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% php ./Zend/bench.php|awk &apos;{print $2}&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;環境1&lt;/th&gt;
&lt;th&gt;環境2&lt;/th&gt;
&lt;th&gt;環境2/環境1 (100%以下なら環境1が高速)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;/table&gt;
&lt;h5&gt;Webベンチマーク&lt;/h5&gt;
&lt;p&gt;Webでアクセスした際のパフォーマンス測定。コマンドラインと同じスクリプトを利用&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;環境1&lt;/th&gt;
&lt;th&gt;環境2&lt;/th&gt;
&lt;th&gt;環境2/環境1 (100%以下なら環境1が高速)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;/table&gt;
&lt;h4&gt;結論&lt;/h4&gt;
&lt;p&gt;Webで利用した場合は、環境1と環境2において差異は無さそう。&lt;/p&gt;
&lt;p&gt;ファイル容量がモジュールを削減した分、20%程度減っているため、プロセス起動が頻繁に発生する場合に環境2はアドバンテージがある。&lt;/p&gt;
&lt;p&gt;環境1 &lt;a href=&quot;http://www.flickr.com/photos/matsubokkuri/786357206/&quot;&gt;&lt;img src=&quot;../../assets/uploads/2007/07/786357206_5476a4e4ca_b.jpg&quot; alt=&quot;php env1&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;環境2 &lt;a href=&quot;http://www.flickr.com/photos/matsubokkuri/786357232/&quot;&gt;&lt;img src=&quot;../../assets/uploads/2007/07/786357232_c67c354bd5_b.jpg&quot; alt=&quot;php env2&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>PHP プロファイリング時に知っておくべき原則</title><link>https://blog.teraren.com/posts/2007-06-28-php-purofuairinguniteokubeki/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2007-06-28-php-purofuairinguniteokubeki/</guid><description>xdebugを使ったPHPプロファイリング時のパフォーマンス低下の実測値。通常時・xdebug有効時・ファイル記録時間の比率は1:4:16。</description><pubDate>Thu, 28 Jun 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;PHPプログラムをプロファイリングするためにxdebugを利用するが、xdebugを利用すると パフォーマンスが悪くなる。 どのくらい悪くなるかは以下の通り。&lt;/p&gt;
&lt;p&gt;普通：60ms xdebugを有効にしたHTTPアクセス:240ms xdebugの吐くファイルに記載されている時間:640ms&lt;/p&gt;
&lt;p&gt;1:4:16&lt;/p&gt;
</content:encoded></item><item><title>SYN FLOOD のテスト</title><link>https://blog.teraren.com/posts/syn-flood-test/</link><guid isPermaLink="true">https://blog.teraren.com/posts/syn-flood-test/</guid><description>SYN FLOOD のテスト</description><pubDate>Mon, 18 Jun 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SYN FLOODを作るためのシェルスクリプト。 悪用しないでね。&lt;/p&gt;
</content:encoded></item><item><title>YMCのVPSサービスをフルに使う！</title><link>https://blog.teraren.com/posts/ymc-vps-full-usage/</link><guid isPermaLink="true">https://blog.teraren.com/posts/ymc-vps-full-usage/</guid><description>YMC VPS（CentOS・Xen）でroot権限を活かし、不要なデーモンを削除してSubversionやGCCを導入するなどリソースを最大限に活用するセットアップ手順</description><pubDate>Thu, 14 Jun 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://www.ymc.ne.jp/&quot;&gt;＠YMCのVPS&lt;/a&gt;を借りました。&lt;br /&gt;
カスタマイズドなので、root権限でやりたい放題できます。&lt;/p&gt;
&lt;p&gt;Xenで動いています。ゲストOSはCentOS　4.5 です。&lt;/p&gt;
&lt;p&gt;しかしながら、初期状態ではいくつかいらないアプリケーションが元から入っているので削除します。&lt;/p&gt;
&lt;p&gt;以下は、コマンドの意味がわかる方のみ実行してください！かなーり危険です。&lt;/p&gt;
&lt;p&gt;以下のコマンドを実行。&lt;br /&gt;
このコマンドを実行すると、デーモンはsshd,syslogd,cronぐらいしか動いていない状態となり、&lt;br /&gt;
スッキリする。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# yum remove sendmail dhclient squid httpd isdn4k-utils pcmcia-cs mysql bind xinetd at
# yum install subversion rcs bison gcc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;このコマンドを実行すると、DNSのキャッシュサーバが無くなります。&lt;br /&gt;
DNSサーバの指定を買えましょう。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/resolve.conf&lt;/code&gt; を編集して適当なDNSキャッシュサーバを指定する。&lt;/p&gt;
&lt;p&gt;VPSでは&lt;br /&gt;
・プロセス数の制限&lt;br /&gt;
・RAMの制限&lt;br /&gt;
・CPU計算時間の制限&lt;br /&gt;
・ディスク容量&lt;br /&gt;
がきっついのでいらないモノはどんどん削除。&lt;/p&gt;
&lt;p&gt;もっとプロセス数を減らしたければ、&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/inittab&lt;/code&gt; を変更してrebootすればコンソール用のプロセスを5つ消せる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ rcsdiff inittab
===================================================================
RCS file: RCS/inittab,v
retrieving revision 1.1
diff -r1.1 inittab
46,50c46,50
&amp;lt; 2:2345:respawn:/sbin/mingetty tty2
&amp;lt; 3:2345:respawn:/sbin/mingetty tty3
&amp;lt; 4:2345:respawn:/sbin/mingetty tty4
&amp;lt; 5:2345:respawn:/sbin/mingetty tty5
&amp;lt; 6:2345:respawn:/sbin/mingetty tty6
---
&amp;gt; #2:2345:respawn:/sbin/mingetty tty2
&amp;gt; #3:2345:respawn:/sbin/mingetty tty3
&amp;gt; #4:2345:respawn:/sbin/mingetty tty4
&amp;gt; #5:2345:respawn:/sbin/mingetty tty5
&amp;gt; #6:2345:respawn:/sbin/mingetty tty6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;比較はこんな感じ。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;before&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[admin@www ~]$ ps axu
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.3  1704  552 ?        S    Jun11   0:00 init [3]
root         2  0.0  0.0     0    0 ?        S    Jun11   0:00 [migration/0]
root         3  0.0  0.0     0    0 ?        SN   Jun11   0:00 [ksoftirqd/0]
root         4  0.0  0.0     0    0 ?        S    Jun11   0:00 [watchdog/0]
root         5  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [events/0]
root         6  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [khelper]
root         7  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [kthread]
root         8  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [xenwatch]
root         9  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [xenbus]
root        16  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [kblockd/0]
root        40  0.0  0.0     0    0 ?        S    Jun11   0:00 [pdflush]
root        41  0.0  0.0     0    0 ?        S    Jun11   0:00 [pdflush]
root        43  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [aio/0]
root        42  0.0  0.0     0    0 ?        S    Jun11   0:00 [kswapd0]
root       559  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [kseriod]
root       589  0.0  0.0     0    0 ?        S    Jun11   0:00 [kjournald]
root      1851  0.0  0.0     0    0 ?        S    Jun11   0:00 [kjournald]
root      1859  0.0  0.2  1600  472 ?        S&amp;gt;s  Jun11   0:00 udevd
root      2184  0.0  0.3  1616  540 ?        Ss   Jun11   0:00 syslogd -m 0
root      2188  0.0  0.2  1560  380 ?        Ss   Jun11   0:00 klogd -x
named     2203  0.0  1.6 30172 2680 ?        Ssl  Jun11   0:00 /usr/sbin/named -u named -t /var/named/chroot
rpc       2221  0.0  0.3  1696  524 ?        Ss   Jun11   0:00 portmap
root      2234  0.0  0.6  4096 1140 ?        Ss   Jun11   0:00 /usr/sbin/sshd
root      2249  0.0  0.4  2160  760 ?        Ss   Jun11   0:00 xinetd -stayalive -pidfile /var/run/xinetd.pid
root      2271  0.0  1.2  7388 2000 ?        Ss   Jun11   0:00 sendmail: accepting connections
smmsp     2282  0.0  0.9  6492 1624 ?        Ss   Jun11   0:00 sendmail: Queue runner@01:00:00 for /var/spool/clientmque
root      2292  0.0  0.5  4540  924 ?        Ss   Jun11   0:00 crond
root      2309  0.0  0.2  1788  428 ?        Ss   Jun11   0:00 /usr/sbin/atd
root      2316  0.0  0.2  1548  436 tty1     Ss+  Jun11   0:00 /sbin/mingetty tty1
root      2317  0.0  0.2  1548  440 tty2     Ss+  Jun11   0:00 /sbin/mingetty tty2
root      2318  0.0  0.2  1552  444 tty3     Ss+  Jun11   0:00 /sbin/mingetty tty3
root      2319  0.0  0.2  1552  440 tty4     Ss+  Jun11   0:00 /sbin/mingetty tty4
root      2320  0.0  0.2  1552  444 tty5     Ss+  Jun11   0:00 /sbin/mingetty tty5
root      2321  0.0  0.2  1552  444 tty6     Ss+  Jun11   0:00 /sbin/mingetty tty6
root      4087  0.0  1.5  6972 2596 ?        Ss   01:45   0:00 sshd: admin [priv]
admin     4097  0.0  1.0  6972 1788 ?        S    01:46   0:00 sshd: admin@pts/0
admin     4104  0.0  0.8  4308 1396 pts/0    Ss   01:46   0:00 -bash
admin     4130  0.0  0.4  2388  784 pts/0    R+   01:46   0:00 ps axu
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;after&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[admin@www ~]$ ps axu
USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.3  1704  552 ?        S    Jun11   0:00 init [3]
root         2  0.0  0.0     0    0 ?        S    Jun11   0:00 [migration/0]
root         3  0.0  0.0     0    0 ?        SN   Jun11   0:00 [ksoftirqd/0]
root         4  0.0  0.0     0    0 ?        S    Jun11   0:00 [watchdog/0]
root         5  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [events/0]
root         6  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [khelper]
root         7  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [kthread]
root         8  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [xenwatch]
root         9  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [xenbus]
root        16  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [kblockd/0]
root        40  0.0  0.0     0    0 ?        S    Jun11   0:00 [pdflush]
root        41  0.0  0.0     0    0 ?        S    Jun11   0:00 [pdflush]
root        43  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [aio/0]
root        42  0.0  0.0     0    0 ?        S    Jun11   0:00 [kswapd0]
root       559  0.0  0.0     0    0 ?        S&amp;gt;   Jun11   0:00 [kseriod]
root       589  0.0  0.0     0    0 ?        S    Jun11   0:00 [kjournald]
root      1851  0.0  0.0     0    0 ?        S    Jun11   0:00 [kjournald]
root      1859  0.0  0.2  1600  472 ?        S&amp;gt;s  Jun11   0:00 udevd
root      2184  0.0  0.3  1616  540 ?        Ss   Jun11   0:00 syslogd -m 0
root      2188  0.0  0.2  1560  380 ?        Ss   Jun11   0:00 klogd -x
root      2234  0.0  0.6  4096 1140 ?        Ss   Jun11   0:00 /usr/sbin/sshd
root      2292  0.0  0.5  4540  924 ?        Ss   Jun11   0:00 crond
root      2316  0.0  0.2  1548  436 tty1     Ss+  Jun11   0:00 /sbin/mingetty tty1
root      4087  0.0  1.5  6972 2596 ?        Ss   01:45   0:00 sshd: admin [priv]
admin     4097  0.0  1.1  7124 1804 ?        R    01:46   0:00 sshd: admin@pts/0
admin     4104  0.0  0.8  4308 1420 pts/0    Ss   01:46   0:00 -bash
admin     5076  0.0  0.4  2392  788 pts/0    R+   02:00   0:00 ps axu
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;スッキリしました！&lt;/p&gt;
&lt;p&gt;起動直後のRAM使用量は30MB。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;top - 02:13:53 up 0 min,  1 user,  load average: 0.17, 0.06, 0.02
Tasks:  28 total,   2 running,  26 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.0% us,  0.0% sy,  0.0% ni, 100.0% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:    163976k total,    32036k used,   131940k free,     3432k buffers
Swap:  1048568k total,        0k used,  1048568k free,    13908k cached
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>SYN_RECVが大量発生</title><link>https://blog.teraren.com/posts/syn-recv-mass-occurrence/</link><guid isPermaLink="true">https://blog.teraren.com/posts/syn-recv-mass-occurrence/</guid><description>SYN_RECVが大量発生</description><pubDate>Fri, 25 May 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;運用サーバでSYN_RECVが大量に発生してる。。。&lt;br /&gt;
&lt;a href=&quot;https://www.sonicwall.com/ja-jp/&quot;&gt;SONIC WALL&lt;/a&gt;という統合型ルータが変なパケットを出してるみたい。&lt;/p&gt;
&lt;p&gt;とりあえずの設定。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# echo 1 &amp;gt; /proc/sys/net/ipv4/tcp_syncookies
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;スタートアップ時に上記を適用する設定&lt;/p&gt;
&lt;p&gt;&lt;code&gt;/etc/sysctl.conf&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;net.ipv4.tcp_syncookies = 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;それでもなおらん。。。SYN_RECVのタイムアウトいじるのってどこだろ。&lt;br /&gt;
&lt;a href=&quot;http://jlvs.infoscience.co.jp/defense.html&quot;&gt;http://jlvs.infoscience.co.jp/defense.html&lt;/a&gt;にあるパラメータがないぞ。。。&lt;/p&gt;
&lt;p&gt;結果報告。&lt;/p&gt;
&lt;p&gt;ある特定のWindowsサーバで動作しているForward proxyサーバとこちらで運用しているネットワーク機器との相性が悪いらしい。&lt;br /&gt;
また、大量のSYN_RECVパケットが発生する時はProxyサーバの向こう側にいる端末がIE6を利用し、大量の1秒間に数十回のGETをSSLで10秒程度繰り返したときのみに発生する。&lt;/p&gt;
&lt;p&gt;最終的には問題は解決しなかったが、Firefoxを利用してもらうことで解決した。&lt;/p&gt;
</content:encoded></item><item><title>tinydnsでSPFレコード</title><link>https://blog.teraren.com/posts/2007-05-01-tinydns-spf/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2007-05-01-tinydns-spf/</guid><description>tinydnsでSPFレコードを設定する具体的な書き方。コロンや半角スペースのエスケープ方法と、hotmailへメールが届かない問題の解決例。</description><pubDate>Tue, 01 May 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;tinydnsのレコードで書くとこんな感じ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&apos;secure-shop.jp:v=spf1\040ip4\072124.34.28.50\040~all
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;メールサーバのIPアドレスは124.34.28.50&lt;/li&gt;
&lt;li&gt;コロンは、]072でエスケープ&lt;/li&gt;
&lt;li&gt;半角スペースは]040でエスケープしてる。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://e-words.jp/w/SPF.html&quot;&gt;SPF&lt;/a&gt; Sender Policy Frameworkだとさ。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;メールの送信元アドレスの偽装を防止する技術。Pobox.com社の創設者Meng Wong氏が提唱した方式で、無差別に大量に送られる広告メール(SPAMメール)の抑止につながるとして期待されている。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;仕事で運用しているECサイトのメールがhotmailに届かないので原因を調べてみたら、hotmailの受信サーバはスパム判定にDNSのSPFレコードを見ていると書いてあった。&lt;/p&gt;
&lt;p&gt;SPFレコードを作成したら、hotmailにも届くようになった。&lt;br /&gt;
無事解決。&lt;br /&gt;
YahooやGmailもSPFを見ているようだが、hotmailほど重きを置いていないっぽいので問題なかった。&lt;/p&gt;
</content:encoded></item><item><title>Microsoft Windows Storage Server 2003のNFSが挙動不審！</title><link>https://blog.teraren.com/posts/2007-04-18-microsoft-windows-storage-server-2003nonfsga/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2007-04-18-microsoft-windows-storage-server-2003nonfsga/</guid><description>Windows Storage Server 2003のNFSでクライアントごとに見えるファイルが異なるバグに遭遇。最終的にLinux NFSサーバへ移行して解決した記録。</description><pubDate>Wed, 18 Apr 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Microsoft Windows Storage Server 2003をNFSサーバとして動かして、4ホストからマウントしています。&lt;/p&gt;
&lt;p&gt;クライアントはCentOS4.4。&lt;/p&gt;
&lt;p&gt;しかーし！　NFSクライアントからStorage Serverをマウントして、ファイルを見るとクライアントによって見えるファイルが違う！&lt;/p&gt;
&lt;p&gt;たとえばこんな感じ。&lt;br /&gt;
@host1&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ls /mnt/file
a.jpg b.jpg

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;@host2&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ls /mnt/file/
a.jpg

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ファイルサーバなのに役目を果たしていない。。。。。。。。。バグレポートもでいないらしい。&lt;br /&gt;
現在利用しているのは32ビット版だが、&lt;a href=&quot;http://support.microsoft.com/kb/895398/ja&quot;&gt;64ビット版ではbug fixが出ている&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;LinuxとWindowsは仲良くなれないんだね。&lt;/p&gt;
&lt;p&gt;最終的には、利用を停止してLinuxのNFSサーバにしました。&lt;/p&gt;
&lt;p&gt;追記：2008/12/25&lt;br /&gt;
NFSクライアント側にもバグがあり、再発しました。kernelを最新にすることで解決します。&lt;/p&gt;
</content:encoded></item><item><title>Senna インストールメモ</title><link>https://blog.teraren.com/posts/senna-installation-memo/</link><guid isPermaLink="true">https://blog.teraren.com/posts/senna-installation-memo/</guid><description>MySQLで日本語全文検索を実現するSennaをMeCabと共にソースからビルドしてインストールするコピペ用手順メモ</description><pubDate>Mon, 05 Mar 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2007年3月4日時点で、最新の安定版のライブラリを使った場合のSennaのインストールメモ。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://qwik.jp/senna/&quot;&gt;Senna&lt;/a&gt;とは、MySQLのFULLTEXT INDEXを日本語でも行えるようにするMyISAMテーブルの拡張モジュール。&lt;/p&gt;
&lt;p&gt;以下のコマンドをコピペすればインストールが完了することを目的で書いています。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /usr/local/src

# mecab
wget http://superb-west.dl.sourceforge.net/sourceforge/mecab/mecab-0.94.tar.gz
tar zxf mecab-0.94.tar.gz
cd mecab-0.94
./configure --prefix=/usr --with-charset=utf8
make
make install

cd ..

# mecab dic
wget http://easynews.dl.sourceforge.net/sourceforge/mecab/mecab-ipadic-2.7.0-20060707.tar.gz
tar zxf  mecab-ipadic-2.7.0-20060707.tar.gz
cd mecab-ipadic-2.7.0-20060707
./configure --with-charset=utf8 --prefix=/usr
make
make install

cd ..

# senna
wget http://osdn.dl.sourceforge.jp/senna/24191/senna-1.0.1.tar.gz
tar senna-1.0.1.tar.gz
cd senna-1.0.1
./configure --prefix=/usr
make
make install
mkdir /var/senna
echo &apos;sjis&apos; &amp;gt; /var/senna/senna.conf

cd ..

# mysql
wget http://www.rootman.co.kr/NFS2/APM/mysql-5.0.24.tar.gz
tar zxf mysql-5.0.24.tar.gz
cd mysql-5.0.24
patch -p1 &amp;lt; ../senna-1.0.1/bindings/mysql/mysql-5.0.24a.senna.diff
patch -p1 &amp;lt; ../senna-1.0.1/bindings/mysql/mysql-5.0.24a.senna.2ind.diff

libtoolize -c -f
aclocal-1.9
autoheader
automake-1.9 -c -a -i
autoconf
touch sql/sql_yacc.yy

CFLAGS=&quot;-O3 -mtune=nocona -I/usr/local/include&quot; \
CXX=gcc CXXFLAGS=&quot;-O3 -mtune=nocona \
-felide-constructors -fno-exceptions -fno-rtti -I/usr/local/include&quot; \
LDFLAGS=&quot;-L/usr/local/lib&quot; \
./configure \
--prefix=/usr/local/mysql \
--with-charset=utf8 \
--with-extra-charsets=all \
--with-mysqld-user=mysql \
--with-senna \
--enable-thread-safe-client \
--enable-assembler \
--with-readline \
--with-mysqld-ldflags=-all-static \
--disable-shared

make
make install
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>PHP preg_matchで中括弧が引っかからない。</title><link>https://blog.teraren.com/posts/php-preg-match-curly-braces-not-matching/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-preg-match-curly-braces-not-matching/</guid><description>PHP preg_matchで中括弧が引っかからない。</description><pubDate>Tue, 13 Feb 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;PHPの正規表現関数の中で一番早いpreg_matchが思い通り動かない。&lt;/p&gt;
&lt;p&gt;以下のコードで中括弧が無かったら、trueを出したいのだが、無くてもtrueが出ちゃう。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;preg_match(&apos;/[^{}]+/&apos;,&apos;紙&apos;);
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>MySQLPHPGridを使ってみた</title><link>https://blog.teraren.com/posts/mysqlphpgrid-usage/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysqlphpgrid-usage/</guid><description>MySQLPHPGridを使ってみた</description><pubDate>Wed, 07 Feb 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;MySQLPHPGridを使ってみたんだけど、日本語使えない。 &lt;a href=&quot;http://&quot;&gt;http://www.drasticdata.nl/mysqlphpgrid.htm&lt;/a&gt; MySQLPHPGridとは、Webから利用できるMySQLの編集スクリプト。PHPでかかれています。 MySQLPHPGridでは、いろいろなオプションを設定できるので日本語のカラムは非表示にしたり、編集できないようにすれば実用的にOKです。&lt;/p&gt;
&lt;h3&gt;利点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;超簡単にテーブル内容を編集できる&lt;/li&gt;
&lt;li&gt;Basic認証で、アクセス制限をかけられる&lt;/li&gt;
&lt;li&gt;enumタイプにも対応してる。&lt;/li&gt;
&lt;li&gt;sortできる&lt;/li&gt;
&lt;li&gt;信頼性は高いとおもう&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;欠点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;日本語未対応&lt;/li&gt;
&lt;li&gt;テーブルごとにPHPスクリプトを作らなければならない。
&lt;ul&gt;
&lt;li&gt;（テーブルを選択するプログラムを書けば対応可能）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;スクリプト自体がshort tagで始まっているPHPファイルなので、iniで設定してあげる必要がある。short tag openがOffの場合は画面に何も表示されないっす。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;がんばれMySQLPHPGrid！&lt;/p&gt;
</content:encoded></item><item><title>計画停電の時に実行すべきLinuxコマンド</title><link>https://blog.teraren.com/posts/shutdown-at/</link><guid isPermaLink="true">https://blog.teraren.com/posts/shutdown-at/</guid><description>Linuxのatコマンドとshutdownコマンドを使って計画停電前に時刻指定でサーバをシャットダウンする方法。時間フォーマットの違いとリモート接続での注意点を解説。</description><pubDate>Wed, 07 Feb 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;atコマンド&lt;/p&gt;
&lt;p&gt;以下のコマンドでスケジュールできる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# at -t &apos;200702100700&apos;
at&amp;gt; shutdown -h now
Ctrl+D
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;予定を確認する場合は以下のコマンド。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# atq
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# shutdown -h time
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;を実験してみました。&lt;/p&gt;
&lt;p&gt;Linuxの場合は、timeのフォーマットが3種類ある。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;now: すぐに&lt;/li&gt;
&lt;li&gt;+x: x秒後にシャットダウン&lt;/li&gt;
&lt;li&gt;hh:mm : 次回のhh時mm分&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;日付指定はできないから、ある時間にシャットダウンしたい場合は3番目を利用する。&lt;/p&gt;
&lt;p&gt;3番目をシェルプロンプトへ利用すると、プロンプトが帰ってこないでシャットダウンが開始するまでずっとブロックされてしまいます。リモートから時間指定でシャットダウンをする場合はずっと接続しっぱなしにしなければならないのでscreenなどを使ってでシェルを立ち上げっぱなしにしておかなければなりません。&lt;/p&gt;
&lt;p&gt;また、定期的にシャットダウン予定までのアラートが標準出力に出るようです。（ちょっとびびる）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /sbin/shutdown -h 12:00
automatically shutdown process now begin.
Broadcast message from root (pts/1) (Wed Apr  2 16:00:40 2008):
The system is going DOWN for system halt in 1200 minutes!
Broadcast message from root (pts/1) (Wed Apr  2 17:00:40 2008):
The system is going DOWN for system halt in 1140 minutes!
Broadcast message from root (pts/1) (Wed Apr  2 18:00:40 2008):
The system is going DOWN for system halt in 1080 minutes!
Broadcast message from root (pts/1) (Wed Apr  2 19:00:41 2008):
The system is going DOWN for system halt in 1020 minutes!
Broadcast message from root (pts/1) (Wed Apr  2 20:00:41 2008):
The system is going DOWN for system halt in 960 minutes!
.
.
.
.
.
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>phpideのファイルオープン時の文字コード</title><link>https://blog.teraren.com/posts/phpide-file-open-encoding/</link><guid isPermaLink="true">https://blog.teraren.com/posts/phpide-file-open-encoding/</guid><description>phpideのファイルオープン時の文字コード</description><pubDate>Mon, 22 Jan 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;phpideを使い始めた。 まず、ファイルをすべてUTF-8で扱ってしまって、たいへん。。。。 扱う文字コードを買えるには以下の設定をする。 Window &amp;gt; Preference &amp;gt; General &amp;gt; Appearance &amp;gt; Content Types &amp;gt; Text &amp;gt; PHP 右下に表示される文字コードに「SJIS」と入力して「Update」ボタンを押す。&lt;/p&gt;
</content:encoded></item><item><title>APCとmemcachedの速度比較</title><link>https://blog.teraren.com/posts/apc-vs-memcached-speed-comparison/</link><guid isPermaLink="true">https://blog.teraren.com/posts/apc-vs-memcached-speed-comparison/</guid><description>APCとmemcachedの速度比較</description><pubDate>Thu, 18 Jan 2007 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;環境&lt;/h2&gt;
&lt;p&gt;Celeron 2.13GHz&lt;br /&gt;
Fedora Core 4&lt;/p&gt;
&lt;h2&gt;計測&lt;/h2&gt;
&lt;p&gt;1KBぐらいのPHP Objectを10000回取り出したときの所要時間&lt;/p&gt;
&lt;p&gt;APC 4.02729010582 sec&lt;br /&gt;
memcached 7.36776900291 sec&lt;/p&gt;
&lt;p&gt;1KBぐらいのPHP Objectを10000回書き込んだときの所要時間&lt;/p&gt;
&lt;p&gt;APC 4.73176598549 sec&lt;br /&gt;
memcached 6.97650694847 sec&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;読み込み&lt;br /&gt;
APCのほうが約1.8倍高速&lt;/p&gt;
&lt;p&gt;書き込み&lt;br /&gt;
APCの方が約1.5倍高速&lt;/p&gt;
</content:encoded></item><item><title>PEARのMailにて、persist有効時のパフォーマンス</title><link>https://blog.teraren.com/posts/pear-mail-persist-performance/</link><guid isPermaLink="true">https://blog.teraren.com/posts/pear-mail-persist-performance/</guid><description>PHPのPEAR::MailでSMTP接続のpersistオプションを有効にした場合の速度差を計測。100通送信でpersistあり・なしの比較結果とテストコードを公開。</description><pubDate>Mon, 15 Jan 2007 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;PEARのMailを使って、SMTP接続をしてメール送信をする際、&lt;br /&gt;
persistを使ったときと使わなかったときのパフォーマンスを測定しました。&lt;/p&gt;
&lt;h2&gt;条件&lt;/h2&gt;
&lt;p&gt;100通メール送信&lt;br /&gt;
MTAはqmail&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;persist利用時: 5.12351703644 sec&lt;br /&gt;
persist非利用時: 6.3600769043 sec&lt;/p&gt;
&lt;h2&gt;結果&lt;/h2&gt;
&lt;p&gt;persistを使うと1.24134981089459 倍速いです。&lt;/p&gt;
&lt;p&gt;以下、テストコード&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
/*
* Created on 2007/01/15
*
* To change the template for this generated file go to
* Window - Preferences - PHPeclipse - PHP - Code Templates
*/
include(&apos;Mail.php&apos;);
require_once(&apos;Benchmark/Timer.php&apos;);

$timer = new Benchmark_Timer();

$recipients = &apos;matsu-test@example.com&apos;;

$headers[&apos;From&apos;]    = &apos;matsu@ec1.localdomain&apos;;
$headers[&apos;To&apos;]      = $recipients;
$headers[&apos;Subject&apos;] = &apos;subject&apos;;

$body = &apos;Test message&apos;;

// SMTPサーバ
$mail_options = array(
  &apos;host&apos;      =&amp;gt; &apos;localhost&apos;,
  &apos;port&apos;      =&amp;gt; 25,
  &apos;auth&apos;      =&amp;gt; false,
  &apos;persist&apos;   =&amp;gt; false
);

// Create the mail object using the Mail::factory method
$mail_object = &amp;amp;Mail::factory(&apos;smtp&apos;,$mail_options);  // SMTP送信準備

$timer-&amp;gt;start();
for($i=0;$i &amp;lt; 100;$i++){
  $mail_object-&amp;gt;send($recipients, $headers, $body.&apos;:&apos;.$i);
}
$timer-&amp;gt;stop();
$timer-&amp;gt;display();
print_r($timer-&amp;gt;getProfiling());
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>subversionがNFS越しで止まる。。。</title><link>https://blog.teraren.com/posts/2006-12-14-subversionganfsshidemaru/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2006-12-14-subversionganfsshidemaru/</guid><description>NFS越しにsvn updateを実行するとロックのタイムアウトで停止する問題の原因と、cleanupでも復旧できない場合の対処法。</description><pubDate>Thu, 14 Dec 2006 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;こんな問題が起こった： ======== cronで2分おきに % svn update するように設定していたのだが、すぐ止まる。1、2時間で止まる。&lt;/p&gt;
&lt;p&gt;% svn cleanup しても、 /path/to/somewhere/.svn/tmp　が存在しないと言われて、cleanupが途中で止まる。&lt;/p&gt;
&lt;p&gt;復旧する方法は、checkoutし直すしかない。 ========&lt;/p&gt;
&lt;p&gt;いろいろ試した結果、 NFS越しにsvn updateするとおかしくなる。 ってことがわかった。&lt;/p&gt;
&lt;p&gt;おそらく、subversionがupdateの際にファイルのロックをしているのだけれど、レポジトリのからupdateする速度が遅くて、ロックが途中でタイムアウトしているのだと思う。 まったく、困ったものだ。&lt;/p&gt;
</content:encoded></item><item><title>sambaが遅い原因がわかった</title><link>https://blog.teraren.com/posts/samba-slow-cause-found/</link><guid isPermaLink="true">https://blog.teraren.com/posts/samba-slow-cause-found/</guid><description>sambaが遅い原因がわかった</description><pubDate>Sun, 19 Nov 2006 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;sambaのゴミ箱機能がonになっている状態で、subversionをsamba経由で使うと、めっっっっっっっちゃ遅くなることがわかった！ 今まで、どうしてdisk IOがいっぱいいっぱいになるのかわからなかったけど、やっとわかった。。すっきり！&lt;/p&gt;
</content:encoded></item><item><title>MySQLで郵便番号を保持するスキーマ</title><link>https://blog.teraren.com/posts/mysql-zip-code-table/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-zip-code-table/</guid><description>郵便局提供データを月次で一括置換してMySQLに保管するスキーマ設計とトランザクション戦略を解説。住所補完フォームの実装例として活用できる</description><pubDate>Mon, 30 Oct 2006 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;概要&lt;/h2&gt;
&lt;p&gt;郵便番号から住所を探して入力フォームに補完したいという要望があり、避けては通れなくはなってしまった。自社で郵便番号の最新情報を持つ。&lt;/p&gt;
&lt;p&gt;なんといっても、面倒なのは月に1回、100件ほどの更新がある郵便番号データ。データ自体は&lt;a href=&quot;http://www.post.japanpost.jp/zipcode/&quot;&gt;郵便局が提供しています&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;設計&lt;/h2&gt;
&lt;p&gt;運用は以下のようにする。&lt;br /&gt;
・月1回丸ごとデータを入れ替える&lt;br /&gt;
　・時間はかかるけど、差分を積み重ねたときの不整合が出てしまうリスクを回避&lt;br /&gt;
　・更新用のスクリプトを2つ書かなくてすむ。&lt;br /&gt;
・入れ替える際に、SQLクライアントから参照不可能になっては困るので、トランザクションをかけてデータを更新。&lt;br /&gt;
　・重いけど、月1回だし、ロジックが楽。&lt;br /&gt;
・マスタにあって利用しない情報も一応保管しておく。&lt;/p&gt;
&lt;p&gt;ビジネスロジックでは、郵便番号から住所を検索する用途にしか利用しないため、indexは郵便番号だけ。&lt;br /&gt;
スキーマは以下の通り。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CREATE TABLE `postcode` (
  `postcode_id` int(10) unsigned NOT NULL auto_increment,
  `postcode_jis` varchar(5) NOT NULL default &apos;&apos;,
  `postcode_old` varchar(5) NOT NULL default &apos;&apos;,
  `postcode_new` varchar(7) NOT NULL default &apos;&apos;,
  `postcode_prefecture_kana` varchar(255) NOT NULL default &apos;&apos;,
  `postcode_city_kana` varchar(255) NOT NULL default &apos;&apos;,
  `postcode_suburb_kana` varchar(255) default NULL,
  `postcode_prefecture` varchar(255) NOT NULL default &apos;&apos;,
  `postcode_city` varchar(255) NOT NULL default &apos;&apos;,
  `postcode_suburb` varchar(255) default NULL,
  `postcode_is_separated_suburb` tinyint(3) unsigned NOT NULL default &apos;0&apos;,
  `postcode_is_koaza` tinyint(3) unsigned NOT NULL default &apos;0&apos;,
  `postcode_is_chome` tinyint(3) unsigned NOT NULL default &apos;0&apos;,
  `postcode_is_include_area` tinyint(3) unsigned NOT NULL default &apos;0&apos;,
  `postcode_status` tinyint(3) unsigned NOT NULL default &apos;0&apos;,
  `postcode_reason` tinyint(3) unsigned NOT NULL default &apos;0&apos;,
  PRIMARY KEY  (`postcode_id`),
  KEY `postcode_new` (`postcode_new`(4))
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;データをつっこむスクリプト要点(日本語のところは適宜置き換えてね)
トランザクションかけているので途中でデータの挿入に失敗しても、中途半端にならないはず。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ini_set(&apos;max_execution_time&apos;,600);

$handle = fopen(ふぁいる, &apos;r&apos;);

とらんざくしょんはじめ。

れこーどをけす (truncate table postcode)

while (!feof($handle)) {

$line = fgets($handle, 8192);
$line = trim($line);

if(!$line) continue;

// 文字列の処理
$line = str_replace(&apos;以下に掲載がない場合&apos;, &apos;&apos;,$line);

$field_array = explode(&apos;,&apos;, $line);

// 文字列の処理
foreach($field_array as &amp;amp;$field){
$field = str_replace(&apos;&quot;&apos;,&apos;&apos;,$field);
}

// 補足として書いてある括弧を消す
$field_array[5] = mb_ereg_replace(&apos;(\([^\)]+\))&apos;,&apos;&apos;,$field_array[5]);
$field_array[8] = mb_ereg_replace(&apos;(（[^）]+）)&apos;,&apos;&apos;,$field_array[8]);

えんてぃてぃ作る

てーぶるに いんさーと

}
fclose($handle);

とらんざくしょんこみっと。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;あとは、&lt;a href=&quot;http://www.post.japanpost.jp/zipcode/dl/oogaki.html&quot;&gt;月1回全国のデータをダウンロード&lt;/a&gt;して、上記のスクリプトを実行すればダウンタイムなしに、&lt;br /&gt;
しかも楽に更新ができる。&lt;/p&gt;
&lt;p&gt;余裕があれば、&lt;br /&gt;
・上記のURLから自動でファイルをダウンロード&lt;br /&gt;
・解凍&lt;br /&gt;
・プログラム実行&lt;/p&gt;
</content:encoded></item><item><title>PCが1時間に1回ハングアップする</title><link>https://blog.teraren.com/posts/development-speed-part2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/development-speed-part2/</guid><description>PCが1時間に1回ハングアップする</description><pubDate>Wed, 25 Oct 2006 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ハングアップしないPC：1&lt;br /&gt;
1時間に1回ハングアップするPC：0.05&lt;/p&gt;
&lt;p&gt;1時間に1回ハングアップって聞いてもあんまりピンとこないかもしれないけど
{/* textlint-disable &lt;em&gt;/}
開発スピードにめっっっっっっっっっっっっっっっっっっちゃくちゃ影響する。
{/&lt;/em&gt; textlint-enable */}&lt;/p&gt;
&lt;p&gt;ハングアップすると以下のコストが発生する。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;立ち上がり待ち&lt;/li&gt;
&lt;li&gt;OSにログイン&lt;/li&gt;
&lt;li&gt;デスクトップ立ち上がりまち&lt;/li&gt;
&lt;li&gt;アプリケーション立ち上げ　＋　待ち　x5&lt;/li&gt;
&lt;li&gt;UNIXシェルでログイン&lt;/li&gt;
&lt;li&gt;やってたところを思い出す。。。。。。。。。。。。。。。。。&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Subversionで$Id:$をCVSのように置換する方法</title><link>https://blog.teraren.com/posts/subversion-id-keyword-substitution-like-cvs/</link><guid isPermaLink="true">https://blog.teraren.com/posts/subversion-id-keyword-substitution-like-cvs/</guid><description>Subversionで$Id:$をCVSのように置換する方法</description><pubDate>Tue, 24 Oct 2006 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;SubversionではCVSのようにテキストファイル内に特定の文字列がある場合、&lt;br /&gt;
それを自動的に置き換えない。&lt;/p&gt;
&lt;p&gt;Subversionの場合はファイルごとに文字列の置き換えを指定してあげないと&lt;br /&gt;
いけない。&lt;/p&gt;
&lt;p&gt;1つ1つ置き換えるのは面倒なので以下のコマンドでカレントディレクトリ以下&lt;br /&gt;
にIDタグの置き換えを行う設定をできる。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% svn propset svn:keywords Id `find . \( -name .svn -prune \) -o -type f -print | xargs grep -l &apos;$Id:&apos;`
% svn commit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;レポジトリ自体の設定にできないのだろうか。。。&lt;/p&gt;
</content:encoded></item><item><title>新版Perl言語プログラミングレッスン</title><link>https://blog.teraren.com/posts/new-edition-perl-programming-lesson/</link><guid isPermaLink="true">https://blog.teraren.com/posts/new-edition-perl-programming-lesson/</guid><description>新版Perl言語プログラミングレッスン</description><pubDate>Sun, 01 Oct 2006 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;技術界では著名な結城浩さんが新しい本を出版します！&lt;/p&gt;
&lt;p&gt;新版Perl言語プログラミングレッスン入門編&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;4797336803&quot;}&lt;/p&gt;
&lt;p&gt;私自身、Perlを一時期使ってたことがあり、Perlの構文や癖を知るために&lt;br /&gt;
いろいろ書籍とかWebをあさりまくった。&lt;/p&gt;
&lt;p&gt;しかしながら、書籍では汚いソースコードを貼り付けられ、理論が全く書いてない&lt;br /&gt;
本ばかりで切れそうになってました。唯一いけてた本は、カバーが真っ黒の本（名前忘れた）だけでした。&lt;/p&gt;
&lt;p&gt;Perlは手名付ければ簡潔に書けますが、ちゃんとPerlを理解していないと汚いコードになります。世の中のPerlでかかれたコードの95％は汚いと思う。難解不読で、MVCもへったくれもないコード。&lt;/p&gt;
&lt;p&gt;たぶん、結城浩さんが書いたPerlの本なんだから、初心者にわかりやすくかかれていると期待しています。&lt;/p&gt;
&lt;p&gt;目次を見る限り、これからプログラミングをはじめてみよー！手始めにCGIでも書いてみたいなーと思ってる人がまずはじめに読むべきほんだと思います。&lt;/p&gt;
&lt;p&gt;詳細はこちら。&lt;br /&gt;
&lt;a href=&quot;http://www.hyuki.com/pb/&quot;&gt;http://www.hyuki.com/pb/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>PHPでWindowsかどうかを判定</title><link>https://blog.teraren.com/posts/php-coding-tips/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-coding-tips/</guid><description>PHPでWindowsかどうかを判定</description><pubDate>Mon, 18 Sep 2006 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;条件分岐の早い書き方。&lt;/p&gt;
&lt;p&gt;Windowsかどうかを判定している式。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$isWindows = DIRECTORY_SEPARATOR == &apos;\\&apos;;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>microsformats</title><link>https://blog.teraren.com/posts/microsformats/</link><guid isPermaLink="true">https://blog.teraren.com/posts/microsformats/</guid><description>microsformats</description><pubDate>Sat, 22 Jul 2006 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://microformats.org/&quot;&gt;microformats&lt;/a&gt;を使ってみた。　今まではこのような細かいレベルでのマークアップ言語が無く、 XMLドキュメントのDTDで定義していた。microformatsのような緩い縛りで書ける仕様があると楽だ。 microformatsに対応したアプリケーションも増えてきており、今後に期待です。このエントリはgoogleにキャッシュされるかどうかのテスト。&lt;a href=&quot;http://maps.google.co.jp/&quot;&gt;google maps&lt;/a&gt;にキャッシュされたい。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;http://static.flickr.com/45/buddyicons/50007612@N00.jpg?1142645264&quot; alt=&quot;photo&quot; /&gt; &lt;a href=&quot;http://d-head.co.jp/&quot;&gt;Yuki Matsukura&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ダイアモンドヘッド株式会社&lt;/p&gt;
&lt;p&gt;RABANKA III 6F&lt;/p&gt;
&lt;p&gt;渋谷 3-3-3 , 東京 , 150-0013 日本&lt;/p&gt;
&lt;p&gt;03-6379-7600&lt;/p&gt;
&lt;p&gt;This &lt;a href=&quot;http://microformats.org/wiki/hcard&quot;&gt;hCard&lt;/a&gt; created with the &lt;a href=&quot;http://microformats.org/code/hcard/creator&quot;&gt;hCard creator&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>PHP5.0.5 bug</title><link>https://blog.teraren.com/posts/php505-bug/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php505-bug/</guid><description>PHP5.0.5 bug</description><pubDate>Tue, 24 Jan 2006 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This might be a bug. I want to try this stiation using 5.1.2 but PDFlib runs only 5.1.x environment.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
$num = 100;

// Doesn&apos;t work
header(&quot;Content-Length: $num&quot;);

// Works
header(&quot;Content-Length: &quot;.$num);

// Works
print(&quot;test $num&quot;);

// Works
print(&quot;test &quot;.$num);

?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I spent 1 hour to find this tricky spec.&lt;/p&gt;
</content:encoded></item><item><title>ゲームプログラミング</title><link>https://blog.teraren.com/posts/game-programming/</link><guid isPermaLink="true">https://blog.teraren.com/posts/game-programming/</guid><description>ゲームプログラミング</description><pubDate>Fri, 01 Jul 2005 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://web.sfc.keio.ac.jp/~wadari/game/&quot;&gt;ゲームプログラミングの最終課題&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;一夜漬け．というか，課題発表前からぶっ通しで10時間をかけて作った。
はぁー　携帯プログラミングはまじめんどいーーーーーよーーー．&lt;/p&gt;
&lt;p&gt;ゴルゴ13狙撃ゲーム作った！&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/matsubo/golgo13&quot;&gt;ソースコード github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/matsubokkuri/archives/WS21312000.JPG&quot; alt=&quot;WS21312000.JPG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;タイトル&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/matsubokkuri/archives/WS123003.JPG&quot; alt=&quot;WS123003.JPG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;使い方&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/matsubokkuri/archives/WS123001.JPG&quot; alt=&quot;WS123001.JPG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;ストーリー&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/matsubokkuri/archives/WS123002.JPG&quot; alt=&quot;WS123002.JPG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;狙撃！&lt;/p&gt;
</content:encoded></item><item><title>LPIC Level2</title><link>https://blog.teraren.com/posts/lpic-level2/</link><guid isPermaLink="true">https://blog.teraren.com/posts/lpic-level2/</guid><description>LPIC Level2</description><pubDate>Sat, 14 May 2005 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;22日（日）にLPICのレベル2を受けに行きます．&lt;br /&gt;
1.5時間の試験を2本立て．&lt;/p&gt;
&lt;p&gt;そして，いつの間にかLPIのCertificationに有効期限ができてた．&lt;br /&gt;
反感をおそれてか10年が有効期限らしい．どちらにしろ，この手のCertificateにしては長い．&lt;/p&gt;
&lt;p&gt;教材は、これを買いました。&lt;/p&gt;
&lt;p&gt;::amazon{asin=&quot;4798137510&quot;}&lt;/p&gt;
</content:encoded></item><item><title>Qmail patch for using IP alias or Multiple NIC.</title><link>https://blog.teraren.com/posts/qmail-patch-for-using-ip-alias-or-multiple-nic/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qmail-patch-for-using-ip-alias-or-multiple-nic/</guid><description>Qmail patch for using IP alias or Multiple NIC.</description><pubDate>Fri, 25 Mar 2005 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Enable to send mails using multiple Network Interface cards using qmail. &lt;a href=&quot;http://www.gadgetwiz.com/software/outgoingip.patch&quot;&gt;http://www.gadgetwiz.com/software/outgoingip.patch&lt;/a&gt; By default of qmail setting, qmail try to send main IP address of the host. By using this patch, qmail will send mails from IP addresses which are written in qmail/control/outgoingip. May be the delimiter of outgoingip file is .&lt;/p&gt;
</content:encoded></item><item><title>qmailのqueueがバグったときの対処法</title><link>https://blog.teraren.com/posts/qmail-rebuild-queue/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qmail-rebuild-queue/</guid><description>サーバ障害でqmailのキューの整合性が壊れた際に、queueディレクトリを削除・再構築して正常状態に戻すrootコマンド手順</description><pubDate>Sat, 19 Mar 2005 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;サーバが突然おちたりして，qmailのqueueの整合性がとれなくなった．&lt;br /&gt;
qmail-qstatでみると大量のメールがあるが，alermシグナルをqmail-sendへ送ってもqmail-remoteで配信される気配はない．qmHandleで削除を試みてもすべて消えない．&lt;/p&gt;
&lt;p&gt;そこで見つけたのがqueueディレクトリの再構築方法．&lt;/p&gt;
&lt;p&gt;以下をrootで実行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;svc -d /service/qmail

cd /var/qmail/queue
rm -rf info intd local mess remote todo

mkdir mess

for i in `seq 0 22`; do
  mkdir mess/$i
done

cp -r mess info
cp -r mess intd
cp -r mess local
cp -r mess remote
mkdir todo

chmod -R 750 mess todo
chown -R qmailq:qmail mess todo

chmod -R 700 info intd local remote
chown -R qmailq:qmail intd
chown -R qmails:qmail info local remote

svc -u /service/qmail
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>nagios</title><link>https://blog.teraren.com/posts/2005-02-24-nagios/</link><guid isPermaLink="true">https://blog.teraren.com/posts/2005-02-24-nagios/</guid><description>サーバ監視ツールnagiosの導入記録。nagios-statdによるリモートホスト監視の設定とBigBrotherとの比較についてまとめた。</description><pubDate>Thu, 24 Feb 2005 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;監視するサーバが最近多いので、nagiosインストールした。&lt;/p&gt;
&lt;p&gt;リモートホストのサービスを監視するために、&lt;a href=&quot;http://www.twoevils.org/files/netsaint_statd/&quot;&gt;nagios-statd&lt;/a&gt;を利用した。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2005/02/WS0asdf02-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;nagiosと並んで紹介されるBigBrotherというサービス監視アプリケーションもあるが、監視できる項目が少ないので却下。&lt;br /&gt;
逆に、nagiosは多すぎる気がするが。。。。まぁ、多いに越したことはない。設定ファイル1000行以上書いた。。。。&lt;/p&gt;
&lt;h1&gt;せっかく色々設定方法かいたのに、間違ってウィンドウを閉じてしまい、消えてしまった&lt;/h1&gt;
</content:encoded></item><item><title>グラフィックスプログラミング　最終課題</title><link>https://blog.teraren.com/posts/graphics-programming-final-assignment/</link><guid isPermaLink="true">https://blog.teraren.com/posts/graphics-programming-final-assignment/</guid><description>グラフィックスプログラミング　最終課題</description><pubDate>Sat, 05 Feb 2005 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;プリングルスたん&lt;/p&gt;
&lt;p&gt;苗場プリンスホテルで作ったグラフィックスプログラミング最終課題です…
Airエッジで作品のプレゼンを録画したWMVファイルをアップロードするのは大変だった…&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://sfc.teraren.com/&quot;&gt;ソースコード&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>MySQLのデータ復元，チェック，修復コマンド</title><link>https://blog.teraren.com/posts/mysql-data-recovery-check-repair/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-data-recovery-check-repair/</guid><description>MySQLのデータ復元，チェック，修復コマンド</description><pubDate>Sun, 30 Jan 2005 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://dev.mysql.com/doc/mysql/ja/check-table.html&quot;&gt;http://dev.mysql.com/doc/mysql/ja/check-table.html&lt;/a&gt; keywords:mysql table restore check repair&lt;/p&gt;
</content:encoded></item><item><title>vim 置換</title><link>https://blog.teraren.com/posts/vim-replacement/</link><guid isPermaLink="true">https://blog.teraren.com/posts/vim-replacement/</guid><description>vim 置換</description><pubDate>Mon, 20 Dec 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;vimで、ファイル内の文字列を置換するコマンド。&lt;/p&gt;
&lt;h2&gt;buffer内を確認しながら置換&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;:%s/group/`group`/gc
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;buffer内を全部置換&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;:%s/group/`group`/g
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>kernel &lt; 2.4.16</title><link>https://blog.teraren.com/posts/kernel-2416/</link><guid isPermaLink="true">https://blog.teraren.com/posts/kernel-2416/</guid><description>kernel &lt; 2.4.16</description><pubDate>Wed, 27 Oct 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;linux カーネルの2.4.10をext3サポートでインストールするための手順．&lt;br /&gt;
2.4.16まではext3がデフォルトでは含まれていないので自分で用意する必要がある．&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kernel.org/&quot;&gt;https://www.kernel.org/&lt;/a&gt;からソースをダウンロード&lt;/li&gt;
&lt;li&gt;カーネルのバージョンに合ったext3サポートのファイルをダウンロードして，パッチを当てる．&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&quot;http://www.zip.com.au/~akpm/linux/ext3/&quot;&gt;http://www.zip.com.au/~akpm/linux/ext3/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;終わり&lt;/p&gt;
</content:encoded></item><item><title>Java2D</title><link>https://blog.teraren.com/posts/java2d/</link><guid isPermaLink="true">https://blog.teraren.com/posts/java2d/</guid><description>Java2D</description><pubDate>Wed, 15 Sep 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2004/09/j2dWS000.jpg&quot; alt=&quot;j2dWS000.JPG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;これかなぁ．&lt;/p&gt;
</content:encoded></item><item><title>qmail</title><link>https://blog.teraren.com/posts/qmail/</link><guid isPermaLink="true">https://blog.teraren.com/posts/qmail/</guid><description>qmail</description><pubDate>Sat, 11 Sep 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;qmailの再配信について．&lt;br /&gt;
&lt;a href=&quot;http://www.ayamizu.com/mail_retry.htm&quot;&gt;http://www.ayamizu.com/mail_retry.htm&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;７分&lt;br /&gt;
20分&lt;br /&gt;
33分&lt;br /&gt;
47分&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>MySQLチューニング</title><link>https://blog.teraren.com/posts/mysql-tuning/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-tuning/</guid><description>MySQLチューニング</description><pubDate>Wed, 08 Sep 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;うん十万件，うん百万件のデータを扱うと，MySQLを使っていても遅く感じる． ここらへんをちゃんと読んで，チューニングをする必要がある． ここら辺のチューニングを行う前と行った後の性能比較もちゃんとしてみよっかな． &lt;a href=&quot;http://dev.mysql.com/doc/mysql/ja/MySQL_Optimisation.html&quot;&gt;http://dev.mysql.com/doc/mysql/ja/MySQL_Optimisation.html&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>mysqlのtimezone変更方法</title><link>https://blog.teraren.com/posts/mysql-timezone-change/</link><guid isPermaLink="true">https://blog.teraren.com/posts/mysql-timezone-change/</guid><description>mysqlのtimezone変更方法</description><pubDate>Sat, 04 Sep 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;RedHat9のパッケージでmysql-serverをつっこむと，timezoneがAmericaの状態でコンパイルされている．よって，my.cnfにtimezoneを変更する設定をする &lt;a href=&quot;http://www.modwest.com/help/kb6-256.html&quot;&gt;http://www.modwest.com/help/kb6-256.html&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Java SWF</title><link>https://blog.teraren.com/posts/java-swf/</link><guid isPermaLink="true">https://blog.teraren.com/posts/java-swf/</guid><description>Java SWF</description><pubDate>Sat, 21 Aug 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;JavaSWF2 Javaから，SWFを吐けるらしい． 利点がわからん．Flashを持っていない人がSWFを書きたいときに使うのか？ &lt;a href=&quot;http://www.anotherbigidea.com/javaswf/javaswfdoc.html&quot;&gt;OFFICIAL&lt;/a&gt; JavaSWF2 &lt;a href=&quot;http://www.anotherbigidea.com/javaswf/&quot;&gt;http://www.anotherbigidea.com/javaswf/&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>電子おもちゃ設計論の最終課題が完成！</title><link>https://blog.teraren.com/posts/atmel/</link><guid isPermaLink="true">https://blog.teraren.com/posts/atmel/</guid><description>電子おもちゃ設計論の最終課題が完成！</description><pubDate>Thu, 15 Jul 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;まぁ，なんだかんだで，最終発表の前々日に，やることを決めました． その名も，「ゴルゴ13養成マシーン」． エアガンでねらった的を打つゲームです． ATMELのICで開発しています。&lt;/p&gt;
&lt;p&gt;こちらは，回路とプログラムの開発中～&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2004/07/P1040372.jpg&quot; alt=&quot;P1040372.JPG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;こちらは，完成品～！ 顔にあたる，ボタンをエアガンで撃つと，左下の7seg LEDにその番号が表示されます． また，弾が当たったことを示す左上のLEDが点滅します．&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2004/07/P1040385.jpg&quot; alt=&quot;P1040385.JPG&quot; /&gt;&lt;/p&gt;
&lt;p&gt;{/* textlint-disable ja-technical-writing/no-unmatched-pair &lt;em&gt;/}
回路とかは，しょぼいんだけど，おもしろくて実用性抜群（w
{/&lt;/em&gt; textlint-enable ja-technical-writing/no-unmatched-pair */}&lt;/p&gt;
</content:encoded></item><item><title>APOPはプロトコルでは無い。POP3の1つの命令</title><link>https://blog.teraren.com/posts/about-apop/</link><guid isPermaLink="true">https://blog.teraren.com/posts/about-apop/</guid><description>APOPはプロトコルでは無い。POP3の1つの命令</description><pubDate>Wed, 11 Feb 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;CNSガイドを書いていて，ちょっとためになったこと．&lt;/p&gt;
&lt;p&gt;世の中で俗に言われている”APOP”．&lt;br /&gt;
「APOPはプロトコルか？」という疑問があがった．APOPを，POP3やIMAPなどと並列に扱ってよいのかどうかという問いかけがあった．&lt;/p&gt;
&lt;p&gt;僕の中では，APOP＝Authenticated Post Office Protocol と思っていて，POP3の拡張かと思っていた．しかし，それは間違いだった．&lt;/p&gt;
&lt;p&gt;{/* textlint-disable no-unmatched-pair &lt;em&gt;/}
どうやら，POP3で規定されている1つのコマンドに，”APOP”がある．POP3コマンドのLIST，DELE，RETRコマンドと並列に扱うものだった．
{/&lt;/em&gt; textlint-enable */}&lt;/p&gt;
&lt;p&gt;数年前頃からセキュリティの意識が高くなり，APOPという言葉が流行りだしたが，APOPの認証方式の仕様自体は昔から規定された．&lt;/p&gt;
&lt;p&gt;ここでかかれている内容は，いまいち正確ではない．正しいけど，抽象度が高く，勘違いを招く文章だ．&lt;br /&gt;
&lt;a href=&quot;http://e-words.jp/w/APOP.html&quot;&gt;http://e-words.jp/w/APOP.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;そして，こちらがPOP3のRFC．&lt;br /&gt;
&lt;a href=&quot;https://datatracker.ietf.org/doc/html/rfc1939&quot;&gt;https://datatracker.ietf.org/doc/html/rfc1939&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>debian sparc kernel compile</title><link>https://blog.teraren.com/posts/debian-sparc-kernel-compile/</link><guid isPermaLink="true">https://blog.teraren.com/posts/debian-sparc-kernel-compile/</guid><description>Debian SPARC環境でカーネルをビルドする際に発生するsparc64-linux-gccコマンド未発見エラーの解決方法。egcs64パッケージの導入とカーネルビルド手順。</description><pubDate>Mon, 09 Feb 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;kernelを構築しようとすると，以下のようなエラーが出る．&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% make dep
/bin/bash: sparc64-linux-gcc: command not found
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;なので，egcs64パッケージをインストールする．gcc　に単にaliasはるだけではだめみたい．&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt-get install egcs64
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;参考：&lt;br /&gt;
http://www.nets.ce.hiroshima-cu.ac.jp/~masato/Linux/Ultra/doc/UltraLinuxFAQ/faq-ja.html#q_4_9&lt;/p&gt;
&lt;p&gt;memo&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /path/to/kenrel_source
make menuconfig
make clean dep vmlinux modules (SPARCは，bzImageの代わりに，vmlinuxを)
make modules_install
cp arch/i386/boot/bzImage /boot/vmlinuz-2.4.xx
cp System.map /boot/System.map-2.4.xx
ln -s /boot/System.map-2.4.xx /boot/System.map

vi /boot/grub/menu.list
grub-install
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Eclipse java comm error</title><link>https://blog.teraren.com/posts/eclipse-java-comm-error/</link><guid isPermaLink="true">https://blog.teraren.com/posts/eclipse-java-comm-error/</guid><description>Eclipse java comm error</description><pubDate>Sat, 24 Jan 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Eclipseで，java commを使ってコードを書いていたんだけど，ある日から，以下のようなエラーが出て，起動しなくなった．&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Error loading win32com: java.lang.UnsatisfiedLinkError: no win32com in java.library.path&lt;/p&gt;
&lt;p&gt;コンソールからは実行できるけど，Eclipse空は実行できない状態だった．&lt;br /&gt;
googleしても，それらしき情報はのっておらず，java commのインストールが正常に行われていないという記述しか見あたらない．&lt;/p&gt;
&lt;p&gt;なので，試行錯誤してみた結果，java commについてきたwin32comを別の場所にコピーすることで解決した．&lt;/p&gt;
&lt;p&gt;ふつうは，&lt;br /&gt;
$SDK_HOME/bin/win32com.dll&lt;br /&gt;
に入れるけど，ここにもコピー&lt;br /&gt;
$SDK_HOME/jre/bin/win32com.dll&lt;/p&gt;
&lt;p&gt;そしたら，なおる．&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item><item><title>blackbox using cygwin</title><link>https://blog.teraren.com/posts/blackbox-using-cygwin/</link><guid isPermaLink="true">https://blog.teraren.com/posts/blackbox-using-cygwin/</guid><description>CygwinのデフォルトウィンドウマネージャをBlackboxに変更する手順。ソースからのコンパイルと.xinitrcの設定方法を解説。</description><pubDate>Wed, 21 Jan 2004 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;CygwinのWindowManagerを変える．&lt;/p&gt;
&lt;p&gt;blackboxの公式サイトから，Older Stable 0.62.1 をダウンロードして，インストール．&lt;br /&gt;
最新版だとコンパイルが通らない．&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% ./configure
% make
% make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;デフォルトのウィンドウマネージャを変更するために.xinitrcを作って，ウィンドウマネージャ名を変更する．&lt;br /&gt;
&quot;fvwm &amp;amp;&quot; と書いてあるところを &quot;blackbox &amp;amp;&quot;に変更する&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% cp /etc/X11/xinit/xinitrc ~/.xinitrc
% vi .xinitrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;test&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;% startx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/2004/01/WS015.jpg&quot; alt=&quot;WS015.JPG&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cygwin
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://cygwin.com/&quot;&gt;http://cygwin.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Blackbox window manager
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://blackboxwm.sourceforge.net/&quot;&gt;http://blackboxwm.sourceforge.net/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>linux 2.6.0</title><link>https://blog.teraren.com/posts/linux-260/</link><guid isPermaLink="true">https://blog.teraren.com/posts/linux-260/</guid><description>Linux Kernel 2.6.0の正式リリース直後にインストールし、BYTE Benchmarkで2.4系との性能を比較した実験記録</description><pubDate>Tue, 23 Dec 2003 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Kernel 2.6が正式リリースしたから，試しに入れて，ベンチマークしてみた．&lt;br /&gt;
結果としては，速度は2.4より遅くなってるみたい．（単純なベンチマークだから一概にはいえないけど）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;-- 2.4.21 --
  BYTE UNIX Benchmarks (Version 4.0.1)
  System -- Linux taro 2.4.21 #1 SMP Mon Jun 30 16:08:52 JST 2003 i686 unknown
  Start Benchmark Run: Sun Dec 21 02:52:56 JST 2003
   2 interactive users.
   02:52:56 up 12 days, 12:09,  2 users,  load average: 0.00, 0.00, 0.00
  lrwxrwxrwx    1 root     root            4 Jun 28 02:20 /bin/sh -&amp;gt; bash
  /bin/sh: symbolic link to bash
  /dev/hda3              5763648   2902140   2568724  54% /
Dhrystone 2 using register variables     2294584.9 lps   (10 secs, 10 samples)
Arithmetic Test (type = double)          389627.2 lps   (10 secs, 10 samples)
System Call Overhead                     530402.4 lps   (10 secs, 10 samples)
Pipe Throughput                          481352.2 lps   (10 secs, 10 samples)
Pipe-based Context Switching             164035.1 lps   (10 secs, 10 samples)
Process Creation                           6760.6 lps   (30 secs, 3 samples)
Execl Throughput                           1428.7 lps   (29 secs, 3 samples)
File Read 1024 bufsize 2000 maxblocks    294947.0 KBps  (30 secs, 3 samples)
File Write 1024 bufsize 2000 maxblocks   237044.0 KBps  (30 secs, 3 samples)
File Copy 1024 bufsize 2000 maxblocks    128832.0 KBps  (30 secs, 3 samples)
File Read 256 bufsize 500 maxblocks      157020.0 KBps  (30 secs, 3 samples)
File Write 256 bufsize 500 maxblocks     109942.0 KBps  (30 secs, 3 samples)
File Copy 256 bufsize 500 maxblocks       60326.0 KBps  (30 secs, 3 samples)
File Read 4096 bufsize 8000 maxblocks    387795.0 KBps  (30 secs, 3 samples)
File Write 4096 bufsize 8000 maxblocks   334843.0 KBps  (30 secs, 3 samples)
File Copy 4096 bufsize 8000 maxblocks    178603.0 KBps  (30 secs, 3 samples)
Shell Scripts (1 concurrent)               1625.6 lpm   (60 secs, 3 samples)
Shell Scripts (8 concurrent)                221.0 lpm   (60 secs, 3 samples)
Shell Scripts (16 concurrent)               111.0 lpm   (60 secs, 3 samples)
Arithmetic Test (type = short)           198475.3 lps   (10 secs, 3 samples)
Arithmetic Test (type = int)             202776.7 lps   (10 secs, 3 samples)
Arithmetic Test (type = long)            202784.9 lps   (10 secs, 3 samples)
Arithmetic Test (type = float)           389897.2 lps   (10 secs, 3 samples)
Arithoh                                  4602517.3 lps   (10 secs, 3 samples)
C Compiler Throughput                       704.8 lpm   (60 secs, 3 samples)
Dc: sqrt(2) to 99 decimal places          62865.4 lpm   (30 secs, 3 samples)
Recursion Test--Tower of Hanoi            31573.8 lps   (20 secs, 3 samples)

                     INDEX VALUES
TEST                                        BASELINE     RESULT      INDEX

Arithmetic Test (type = double)              29820.0   389627.2      130.7
Dhrystone 2 using register variables        116700.0  2294584.9      196.6
Execl Throughput                                43.0     1428.7      332.3
File Copy 1024 bufsize 2000 maxblocks         3960.0   128832.0      325.3
File Copy 256 bufsize 500 maxblocks           1655.0    60326.0      364.5
File Copy 4096 bufsize 8000 maxblocks         5800.0   178603.0      307.9
Pipe Throughput                              12440.0   481352.2      386.9
Process Creation                               126.0     6760.6      536.6
Shell Scripts (8 concurrent)                     6.0      221.0      368.3
System Call Overhead                         15000.0   530402.4      353.6
                                                                 =========
     FINAL SCORE                                                     310.9
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;-- 2.6.0 --
  BYTE UNIX Benchmarks (Version 4.0.1)
  System -- Linux taro 2.6.0 #1 SMP Tue Dec 23 02:38:17 JST 2003 i686 unknown
  Start Benchmark Run: Tue Dec 23 02:51:47 JST 2003
   1 interactive users.
   02:51:48 up 5 min,  1 user,  load average: 0.01, 0.07, 0.03
  lrwxrwxrwx    1 root     root            4 Jun 28 02:20 /bin/sh -&amp;gt; bash
  /bin/sh: symbolic link to bash
  /dev/hda3              5763648   2953552   2517312  54% /
Dhrystone 2 using register variables     2268556.1 lps   (10 secs, 10 samples)
Arithmetic Test (type = double)          339919.2 lps   (10 secs, 10 samples)
System Call Overhead                     538408.0 lps   (10 secs, 10 samples)
Pipe Throughput                          413614.5 lps   (10 secs, 10 samples)
Pipe-based Context Switching             143225.8 lps   (10 secs, 10 samples)
Process Creation                           5810.6 lps   (30 secs, 3 samples)
Execl Throughput                           1235.8 lps   (29 secs, 3 samples)
File Read 1024 bufsize 2000 maxblocks    281396.0 KBps  (30 secs, 3 samples)
File Write 1024 bufsize 2000 maxblocks   153456.0 KBps  (30 secs, 3 samples)
File Copy 1024 bufsize 2000 maxblocks     95361.0 KBps  (30 secs, 3 samples)
File Read 256 bufsize 500 maxblocks      134224.0 KBps  (30 secs, 3 samples)
File Write 256 bufsize 500 maxblocks      61439.0 KBps  (30 secs, 3 samples)
File Copy 256 bufsize 500 maxblocks       40408.0 KBps  (30 secs, 3 samples)
File Read 4096 bufsize 8000 maxblocks    384977.0 KBps  (30 secs, 3 samples)
File Write 4096 bufsize 8000 maxblocks   234124.0 KBps  (30 secs, 3 samples)
File Copy 4096 bufsize 8000 maxblocks    135067.0 KBps  (30 secs, 3 samples)
Shell Scripts (1 concurrent)               1457.2 lpm   (60 secs, 3 samples)
Shell Scripts (8 concurrent)                197.7 lpm   (60 secs, 3 samples)
Shell Scripts (16 concurrent)                99.0 lpm   (60 secs, 3 samples)
Arithmetic Test (type = short)           197377.3 lps   (10 secs, 3 samples)
Arithmetic Test (type = int)             201478.4 lps   (10 secs, 3 samples)
Arithmetic Test (type = long)            201471.4 lps   (10 secs, 3 samples)
Arithmetic Test (type = float)           388509.5 lps   (10 secs, 3 samples)
Arithoh                                  4567310.4 lps   (10 secs, 3 samples)
C Compiler Throughput                       671.0 lpm   (60 secs, 3 samples)
Dc: sqrt(2) to 99 decimal places          51417.1 lpm   (30 secs, 3 samples)
Recursion Test--Tower of Hanoi            31375.2 lps   (20 secs, 3 samples)

                     INDEX VALUES
TEST                                        BASELINE     RESULT      INDEX

Arithmetic Test (type = double)              29820.0   339919.2      114.0
Dhrystone 2 using register variables        116700.0  2268556.1      194.4
Execl Throughput                                43.0     1235.8      287.4
File Copy 1024 bufsize 2000 maxblocks         3960.0    95361.0      240.8
File Copy 256 bufsize 500 maxblocks           1655.0    40408.0      244.2
File Copy 4096 bufsize 8000 maxblocks         5800.0   135067.0      232.9
Pipe Throughput                              12440.0   413614.5      332.5
Process Creation                               126.0     5810.6      461.2
Shell Scripts (8 concurrent)                     6.0      197.7      329.5
System Call Overhead                         15000.0   538408.0      358.9
                                                                 =========
     FINAL SCORE                                                     263.0
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;-- G5 --
  BYTE UNIX Benchmarks (Version 4.1.0)
  System -- dhcp22.mkg.sfc.keio.ac.jp
  Start Benchmark Run: 〓〓〓  1  4 08:28:13 JST 2004
   2 interactive users.
   8:28  up 8 days, 17:31, 2 users, load averages: 0.32 0.16 0.07
  -r-xr-xr-x  1 root  wheel  603488 24  9 15:47 /bin/sh
  /bin/sh: Mach-O executable ppc
  /dev/disk0s9 245097216 6004796 238836420     2%    /
Dhrystone 2 using register variables     4879188.3 lps   (10.0 secs, 10 samples)
Double-Precision Whetstone                 1188.5 MWIPS (9.9 secs, 10 samples)
System Call Overhead                     156582.0 lps   (10.0 secs, 10 samples)
Pipe Throughput                          133642.3 lps   (10.0 secs, 10 samples)
Pipe-based Context Switching              26468.8 lps   (10.0 secs, 10 samples)
Process Creation                            918.6 lps   (30.0 secs, 3 samples)
Execl Throughput                            432.3 lps   (29.8 secs, 3 samples)
File Read 1024 bufsize 2000 maxblocks    133709.0 KBps  (30.0 secs, 3 samples)
File Write 1024 bufsize 2000 maxblocks   188153.0 KBps  (30.0 secs, 3 samples)
File Copy 1024 bufsize 2000 maxblocks     77938.0 KBps  (30.0 secs, 3 samples)
File Read 256 bufsize 500 maxblocks       42297.0 KBps  (30.0 secs, 3 samples)
File Write 256 bufsize 500 maxblocks      53613.0 KBps  (30.0 secs, 3 samples)
File Copy 256 bufsize 500 maxblocks       23243.0 KBps  (30.0 secs, 3 samples)
File Read 4096 bufsize 8000 maxblocks    264709.0 KBps  (30.0 secs, 3 samples)
File Write 4096 bufsize 8000 maxblocks    56800.0 KBps  (30.0 secs, 3 samples)
File Copy 4096 bufsize 8000 maxblocks     66699.0 KBps  (30.0 secs, 3 samples)
Shell Scripts (1 concurrent)               1245.2 lpm   (60.0 secs, 3 samples)
Shell Scripts (8 concurrent)                206.0 lpm   (60.0 secs, 3 samples)
Shell Scripts (16 concurrent)               104.3 lpm   (60.0 secs, 3 samples)
Arithmetic Test (type = short)           476879.5 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = int)             503175.9 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = long)            502918.8 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = float)           237639.7 lps   (10.0 secs, 3 samples)
Arithmetic Test (type = double)          254299.6 lps   (10.0 secs, 3 samples)
Arithoh                                  6034423.7 lps   (10.0 secs, 3 samples)
C Compiler Throughput                       947.3 lpm   (60.0 secs, 3 samples)
Dc: sqrt(2) to 99 decimal places           no measured results
Recursion Test--Tower of Hanoi            61443.1 lps   (20.0 secs, 3 samples)

                     INDEX VALUES            
TEST                                        BASELINE     RESULT      INDEX

Dhrystone 2 using register variables        116700.0  4879188.3      418.1
Double-Precision Whetstone                      55.0     1188.5      216.1
Execl Throughput                                43.0      432.3      100.5
File Copy 1024 bufsize 2000 maxblocks         3960.0    77938.0      196.8
File Copy 256 bufsize 500 maxblocks           1655.0    23243.0      140.4
File Copy 4096 bufsize 8000 maxblocks         5800.0    66699.0      115.0
Pipe Throughput                              12440.0   133642.3      107.4
Pipe-based Context Switching                  4000.0    26468.8       66.2
Process Creation                               126.0      918.6       72.9
Shell Scripts (8 concurrent)                     6.0      206.0      343.3
System Call Overhead                         15000.0   156582.0      104.4
                                                                 =========
     FINAL SCORE                                                     143.6
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>omega-rpg</title><link>https://blog.teraren.com/posts/omega-rpg/</link><guid isPermaLink="true">https://blog.teraren.com/posts/omega-rpg/</guid><description>omega-rpg</description><pubDate>Wed, 12 Nov 2003 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Command-line RPG game だそうだ．&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;../../assets/uploads/matsubokkuri/archives/omega-rpg.gif&quot; alt=&quot;omega-rpg.gif&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>Debian console</title><link>https://blog.teraren.com/posts/debian-console/</link><guid isPermaLink="true">https://blog.teraren.com/posts/debian-console/</guid><description>Debian console</description><pubDate>Fri, 07 Nov 2003 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Debian(Linux)のコンソールでCaps LockキーをCtrlにする方法&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# cd /etc/console/
# gzip -d boottime.kmap.gz
# vi boottime.kmap
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;keycode 58 =Control に変更
（/usr/share/keymap/とかから別のkeymapをこぴってきてもよし）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# gzip boottime.kmap
# /etc/init.d/keymap.sh reload
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>オススメしないLinuxディストリビューション→Turbolinux</title><link>https://blog.teraren.com/posts/turbolinux-frustration/</link><guid isPermaLink="true">https://blog.teraren.com/posts/turbolinux-frustration/</guid><description>オススメしないLinuxディストリビューション→Turbolinux</description><pubDate>Sat, 04 Oct 2003 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;おすすめできるLinux　Distributionってあるけど，逆におすすめできないDistributionもある．今回は2つのいけてないDistributionを紹介しよう．&lt;/p&gt;
&lt;h2&gt;Vine Linux2.6&lt;/h2&gt;
&lt;p&gt;こいつはまじでくそだ．&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# apt-get dist-upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;をしたら，途中でフリーズしてしまい，rpmで入れたファイル（ほぼすべて）が消えた状態になって，OSの再インストールをする羽目になった．&lt;/p&gt;
&lt;h2&gt;Turbolinux&lt;/h2&gt;
&lt;p&gt;こいつの自動パッケージアップグレードを使って，最新状態を保っているといつの間にかkernelもいじられていて，再起動しなくなる．&lt;br /&gt;
公式Webサイトもしょぼくて，今更Turbolinux2．0の資料もたくさんある．&lt;br /&gt;
メーリングリスト検索や，ユーザフォーラムの記事検索もできなくなっており，こんなDistributionのユーザにはなりたくない．&lt;/p&gt;
</content:encoded></item><item><title>PHP 複数ファイルアップロード</title><link>https://blog.teraren.com/posts/php-multiple-file-upload/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php-multiple-file-upload/</guid><description>PHP 複数ファイルアップロード</description><pubDate>Fri, 05 Sep 2003 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;現在、仕事でPHPのアプリケーション開発してるんだけど、&lt;code&gt;input type=file name=file[]&lt;/code&gt;とかで、複数の画像を一気にアップロードするとブラウザがオーバーフローする。&lt;/p&gt;
&lt;p&gt;なぜ、オーバーフローかといえると、サーバ自体にリクエストが飛んでいないから。&lt;br /&gt;
そして、ほかのブラウザではできるから。&lt;/p&gt;
&lt;p&gt;HTMLのコーディングの問題もあるかもしれないが、いまいち原因がわからない。&lt;br /&gt;
アップロードする画像の枚数が、少なければ正常にアップロードできる。&lt;/p&gt;
&lt;p&gt;特定の状況として、&lt;br /&gt;
10個同じファイルなら、正常にアップロードできて、10個違うファイルならアップロードできない。&lt;/p&gt;
</content:encoded></item><item><title>Linux kernel 2.4 コンパイル方法</title><link>https://blog.teraren.com/posts/memo/</link><guid isPermaLink="true">https://blog.teraren.com/posts/memo/</guid><description>Linux kernel 2.4 コンパイル方法</description><pubDate>Mon, 30 Jun 2003 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;以下の流れ。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd /usr/src/linux
(cp somewhere/.config ./)
(make oldconfig)
make menuconfig
make clean dep bzImage modules
make modules_install
cp arch/i386/boot/bzImage /boot/vmlinuz-2.4.xx
cp System.map /boot/System.map-2.4.xx
ln -s /boot/System.map-2.4.xx /boot/System.map

vi /boot/grub/menu.list
grub-install
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Perl shellでコマンド一発でモジュールをインストール</title><link>https://blog.teraren.com/posts/perl-shell/</link><guid isPermaLink="true">https://blog.teraren.com/posts/perl-shell/</guid><description>Perl shellでコマンド一発でモジュールをインストール</description><pubDate>Sun, 15 Jun 2003 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;perlモジュールをシェルから簡単にインストールするためのコマンド。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# perl -MCPAN -e shell
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# perl -MCPAN -e &apos;install(&quot;Bundle::Apache&quot;)&apos;
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Polymorphism（ポリモーフィズム）がよくわからない</title><link>https://blog.teraren.com/posts/polymorphism/</link><guid isPermaLink="true">https://blog.teraren.com/posts/polymorphism/</guid><description>Polymorphism（ポリモーフィズム）がよくわからない</description><pubDate>Sun, 08 Jun 2003 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;この説明が一番しっくりきた。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As the examples above illustrate, messages in Objective-C appear in the same syntactic positions as function calls in standard C. But, because methods ``belong to&apos;&apos; an object, messages behave differently than function calls.&lt;/p&gt;
&lt;p&gt;In particular, an object has access only to the methods that were defined for it. It can&apos;t confuse them with methods defined for other kinds of objects, even if another object has a method with the same name. This means that two objects can respond differently to the same message. For example, each kind of object sent a display message could display itself in a unique way. A Circle and a Rectangle would respond differently to identical instructions to track the cursor.&lt;/p&gt;
&lt;p&gt;This feature, referred to as polymorphism, plays a significant role in the design of object-oriented programs. Together with dynamic binding, it permits you to write code that might apply to any number of different kinds of objects, without your having to choose at the time you write the code what kinds of objects they might be. They might even be objects that will be developed later, by other programmers working on other projects. If you write code that sends a display message to an id variable, any object that has a display method is a potential receiver.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.toodarkpark.org/computers/objc/coreobjc.html#1329&quot;&gt;http://www.toodarkpark.org/computers/objc/coreobjc.html#1329&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本とか、あっちこっちの文献を見ていると、微妙にわかりづらい。&lt;/p&gt;
&lt;p&gt;この文章のように、理論と実装を明確に分けて書いてほしい。&lt;/p&gt;
</content:encoded></item><item><title>PHP5の新機能が発表されました</title><link>https://blog.teraren.com/posts/php/</link><guid isPermaLink="true">https://blog.teraren.com/posts/php/</guid><description>PHP5の新機能が発表されました</description><pubDate>Thu, 05 Jun 2003 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;PHP5についてまとめてある記事が発表された。 &lt;a href=&quot;http://www.atmarkit.co.jp/flinux/special/php5/php5a.html&quot;&gt;http://www.atmarkit.co.jp/flinux/special/php5/php5a.html&lt;/a&gt; いやぁ、Class関連の文法がかなりJavaちっくになってきた。4まではClass関連がまじでしょぼしょぼだったけど、一応これで安全にオブジェクト指向にかけるな。 それはいいとして、いい感じのFrameworkがほしい。&lt;/p&gt;
</content:encoded></item></channel></rss>