SSG×Markdownで発信が劇的にラクになる理由

GUIで記事を書くことに疲れていないだろうか? 太字ボタンを押しても、見出しサイズを選んでも、結局「伝えたい情報の構造」が見えにくい。WordPressのようなCMSは便利だが、発信者の思考と記事構造のあいだに“操作のレイヤー”が介在しすぎている。その問題を根本から解消するのが、Markdown + SSGという組み合わせだ。 Markdownは構造思考に直結する Markdownは、見た目ではなく構造を先に書く記法だ。 ## 見出し - 箇条書き **強調** GUIでは「ここを太字にしようかな」「色は何色にしよう」など見た目の判断が先行する。それに対してMarkdownでは、情報の階層・強調・並列を考えてから文章に落とす。この違いは地味に大きい。記事を書きながら、情報のまとまりや粒度を自然と意識するようになる。 GUIの装飾操作は思考を中断させる WYSIWYGエディタ(見たまま編集)は、装飾操作と文章作成が交互に入る。 書く → 太字にしたい → ボタンを探す → マウスを使う → 書くに戻る この流れは、実は無駄が多い。Markdownでは **このように** と直接書くだけで完了。手が止まらない。思考と入力の距離が近いのだ。 静的サイトジェネレーター(SSG)との親和性 SSG(静的サイトジェネレーター)は、MarkdownファイルをHTMLにビルドして公開する仕組みだ。AstroやHugoのようなSSGは、フォルダ構造を自動でナビゲーションに変換し、見出しを目次にし、記事間のリンクも一元管理してくれる。これにより: Markdownを1ファイル書くだけで、綺麗なHTMLページになる 全体構造も自動で整理される Gitで管理できるため、リビジョン管理や差分確認も容易 GUIエディタでは「サイト全体をどう構成するか」を人力で考え、リンクを張り、カテゴリを選び…という負担がある。SSGならその多くが自動化されている。 執筆→更新→再利用の効率が飛躍する Markdown + SSGで一度書いた記事は: バージョン管理で差分を追える AIにそのまま渡して要約・再構成ができる 別の媒体(ZennやQiita、noteなど)にそのまま流用可能 とにかく再利用性と変換性が高い。 GUIでHTMLに埋まった状態のコンテンツだと、AIにも読みづらく、構造的な扱いがしにくい。Markdownなら文章が“素のまま”なので、処理・分析・変換が容易だ。 書くことに集中できる環境こそ強い SSG × Markdownは、「書くことに集中したい人」に最適な環境を提供する。 GUIで迷わない サイト構造を意識せず書ける 装飾ではなく内容に集中できる 結果として、記事数が自然と増え、ストックが溜まり、発信のエコシステムが自走し始める。これこそが最大の効率化だ。 見た目ではなく、構造と思考にフォーカスした発信。それがMarkdown + SSGの最大の強みである。 なお、SSGという仕組み自体をCMSと比較して俯瞰したい場合は、以下の別記事もあわせてどうぞ。CMS疲れを感じた背景から、構造的な代替手段としてのSSGまでを導入的に整理している。 SSGのすすめ ― CMS(WordPress)のセキュリティ対策にうんざりしてきたあなたに

2025年6月10日

CMSはなぜ脆弱なのか? よくある攻撃例と設計上の欠陥を解説

WordPressのようなCMS(コンテンツ管理システム)は、長年にわたりブログや企業サイトで広く使われてきた。しかし、近年その「セキュリティ設計の甘さ」が問題視されている。なぜCMSは脆弱になりやすいのか?本記事では、構造的な問題に焦点を当てて解説する。 よくあるCMS脆弱性の具体例 CMSの脆弱性は単に構造だけでなく、具体的な技術的ミスや攻撃ポイントに根ざしている。よくある脆弱性には次のようなものがある: 管理画面への総当たり(ブルートフォース)攻撃 プラグインのアップデート漏れによる既知脆弱性の放置 クロスサイトスクリプティング(XSS) データベースインジェクション(SQLi) これらはすべて、CMSが常に動的に動作し、かつ管理画面が公開されているという構造的特徴に起因している。 管理・表示・生成が同居する「一枚岩構成」 WordPressの典型的な構成は、以下のような「オールインワン型」だ: PHP + MySQL のLAMP環境 管理画面(/wp-admin)が公開サーバ上に存在 ページ生成はアクセス時にPHPでリアルタイム実行 つまり、「管理(入力)」「表示(出力)」「生成(ビルド)」の3機能がすべて1つの公開サーバで同時に動作している。この構成は利便性を優先する代わりに、セキュリティやスケーラビリティの面で明らかな犠牲を払っている。 公開サーバに管理画面がある不自然さ 管理画面が公開サーバに設置されているというのは、よく考えると不自然だ。攻撃者は、/wp-adminという予測しやすいURLを狙えば、管理インターフェースに直接アクセスできてしまう。仮にログイン試行を防げたとしても、「そこに管理画面がある」という事実自体がリスクを生む。 しかも、管理操作はPHP経由でDBを直接叩く構成であるため、脆弱なプラグインや設定ミスによって、システム全体への侵入経路になりうる。 リアルタイム生成のムダと脆弱性 WordPressは、アクセスのたびにPHPがHTMLを動的に生成し、DBにアクセスして内容を取得する。そのため、静的な内容であっても常に処理が走る。これは次のような問題を引き起こす: 負荷が高い:アクセスが増えるとサーバーがボトルネックになる 攻撃対象が広い:リクエストに応じて処理が走るため、DoS攻撃や脆弱性スキャンに弱い 静的なコンテンツであれば、ビルド時にHTMLを生成してCDNに載せるだけで済むはずなのに、それを「毎回動的にやる」というのは本質的に非効率かつ危険だ。 理想的な構成:管理・生成と表示の分離 ではどうすべきか?ひとつの解として、管理・生成サーバと表示サーバを完全に分離する構成がある: この構成の特徴: 管理画面やDBは公開されないネットワークに閉じ込める 静的HTMLをCI/CDでビルドして表示サーバにpush 表示サーバは静的ファイル配信のみを担当し、攻撃面積を最小化 セキュリティ上のベストプラクティスであるゼロトラスト原則やDMZ分離構成を取り入れることで、CMSに起因する大部分のリスクを構造的に排除できる。 CMS疲れからの脱却に向けて CMSの設計思想は「便利で何でもできる」ことにあったが、それゆえに「すべてが公開され、攻撃対象になる」というジレンマを抱えている。今こそ、構造的に堅牢なWeb構築を見直す時期に来ているのではないか。 SSG(静的サイトジェネレーター)やHeadless CMSといった手法は、このようなセキュリティ課題を根本から解決する構成を可能にする。CMS疲れに悩む人ほど、一歩引いてその構造を見直してみてほしい。 CMSとSSGの違いや、それぞれの特性を整理した以下記事もあわせてどうぞ。CMSに限界を感じたとき、どのような選択肢があるのかを俯瞰する第一歩として役立つはずだ。 SSGのすすめ ― CMS(WordPress)のセキュリティ対策にうんざりしてきたあなたに

2025年6月9日

SSGのすすめ ― CMS(WordPress)のセキュリティ対策にうんざりしてきたあなたに

10年前、「Webサイトを作るならWordPressだよ」と誰もが口を揃えて言っていた時代があった。管理画面が整っていて、テーマもプラグインも豊富、何よりレンタルサーバーに「3クリック」で導入できる。その利便性に惹かれて、当時は多くの個人・企業がWordPressを採用していた。 だが、2020年代も半ばに差し掛かり、改めて情報発信を始めようとしたとき、様子が違うことに気づく。「WordPress セキュリティ」で検索すると、出てくるのは不安を煽る記事ばかり。脆弱なプラグイン、放置されたテーマ、改ざん被害、管理画面への攻撃……。10年前の「常識」が、今やリスクの温床と化していたのだ。 CMS構成の「構造的な欠陥」 WordPressを始めとする従来型CMSの最大の問題点は、「表示」「管理」「生成」という3つの役割を1つのサーバーでまかなっている点にある。管理画面は公開URLの直下にあり、ページは毎回PHPとDBを叩いて生成され、攻撃者にとっては「やりがいのある」構成だ。セキュリティパッチの更新も頻繁で、更新のたびに表示が崩れるリスクと戦うことになる。 しかも、サーバーは常時PHPとMySQLを動かし、静的ページすらも“動的に”生成される。この構造のまま「表示速度」「安定性」「セキュリティ」をすべて満たすのは、もはや不可能に近い。 なお、CMS構成のこうした構造的リスクについては、以下の別記事にて、設計レベルから詳しく解説している。「なぜ管理画面が公開URLにあるのか?」「リアルタイム生成は本当に必要なのか?」といった素朴な疑問から、理想的な分離構成まで踏み込んで考察している。 CMSはなぜ脆弱なのか? よくある攻撃例と設計上の欠陥を解説 Markdown + SSG + CDNという現代的解 そこで注目されるのが、**SSG(Static Site Generator)**という選択肢だ。SSGはあらかじめ記事をHTMLとして生成し、CDNで配信する。PHPもMySQLも要らない。表示は爆速、攻撃対象はほぼゼロ、コストは無料同然。さらにMarkdownで記事を書くため、装飾ではなく中身に集中できる。Gitとの親和性も高く、生成AIによる支援(構成案→記事化→整形)との相性も抜群だ。 なお、MarkdownとSSGの組み合わせがもたらす執筆効率の高さについては、以下の別記事で詳しく紹介している。装飾に煩わされず、思考と構造に集中できる執筆体験を、ぜひ知ってほしい。 SSG×Markdownで発信が劇的にラクになる理由 「思考の邪魔」をしない執筆体験 WordPressのGUI操作は、Markdownに慣れた者にとっては“地獄”に近い。太字にするだけでもボタンをクリックし、装飾の見た目がテーマ依存で変わってしまう。構造化されていない文書は、生成AIによる解析にも向かない。コンテンツの中身ではなく、見た目に気を取られた時点で、知的生産としては遠回りなのだ。 一方、Markdownは構造が明快で再利用しやすく、AIにも優しい。文章の意味と構造が分離されているため、自動処理・変換・連携もやりやすい。まさに「考えることに集中できる」執筆環境であり、今後の情報発信の主軸となるにふさわしい。 SSGを使うという“設計思想” SSGは単なるツールではなく、「セキュリティ設計」「コスト設計」「執筆思想」すべてに関わる選択である。構造的に堅牢で、表示高速、拡張も容易。そして何より「攻撃されにくい」という安心感がある。WordPressのように「防衛し続ける構成」ではなく、そもそも「狙われない構成」を作るべき時代になった。 CMSに疲れたすべての人にこそ、SSGという選択肢を知ってほしい。いま、Web発信の構造は、大きく変わろうとしている。

2025年6月8日

各SSGでのfrontmatterのまとめ

各SSGでのfrontmatterのまとめ はじめに 最近、HugoからAstroへブログを移行しようとしたところ、frontmatterの互換性のなさに苦しんだ。特に、Hugoでは一般的なdateフィールドが、Astroのブログテンプレートでは認識されず、代わりにpubDateを使う必要があるという仕様は、公式にも明示されておらず罠のようだった。 将来的にSSGを乗り換える人が増えてくる中で、こうした違いは深刻な移行障壁となるだろうと思い、この記事を記すことにした。 共通部分 Markdownのfrontmatterは公式仕様ではなく、SSGやCMSが独自に解釈して使っている。 通常、YAML形式(--- で囲む)で記述されるが、HugoではTOMLやJSONにも対応。 よく使われる共通フィールド:title, description, tags, draft, slug Hugo 使用できるフォーマット:TOML, YAML, JSON, org 主なフィールド: title: ページのタイトル date: 作成日(公開日) tags: タグ description: ページの説明文 draft: 下書きフラグ(trueにするとビルド対象外) aliases: 追加のURL。ここに記載したURLからもアクセス可能になる。 lastmod: 最終更新日 slug: URLパスの最後のセグメントを上書きする。 参考: hugoで使えるFront Matterについてまとめ Astro 使用できる形式:YAML(.md / .mdx の先頭に記述) 主なフィールド: title: ページのタイトル description: ページの説明文 pubDate: 公開日(※dateではなくpubDateにしないとテンプレートで無視されることがある) tags: タグ(例:["astro", "blog"]) draft: 下書きフラグ(trueで非公開、ただし自動除外にはフィルターが必要) slug: 任意のスラッグ(ファイル名とは別にURLパスを指定可能) layout: 使用するレイアウトファイルのパス(例:../layouts/BlogLayout.astro) heroImage: 記事のトップに表示される画像(任意) author: 著者名(任意) pubDateの罠について Astroではブログテンプレート(例:astro-blog, AstroPaperなど)で記事を日付順に並べる処理や日付の表示が行われているが、そこで参照されているのはdateではなくpubDateだ。 そのため、Hugoから移行してきたMarkdown資産でdateしか指定していない場合、Astroでは日付が表示されなかったり、並び順に影響が出たりする。 この仕様はAstro公式ドキュメントには明記されておらず、テンプレートの実装依存しだいだ。 移行時には必ずdateをpubDateに変換するスクリプトまたは手動対応が必要になる。 ちなみにAstroでは、公式サイトを見ても、どのようなfrontmatterが使えるかは明記されていない。せいぜい、まともに解説があったのはstarlightというテーマでの解説のみ。今後、各SSG間の移行性や互換性が問題になりそうだ。 ...

2025年5月17日

静的サイトはSDGsに貢献する|環境と知識と技術の三方良し

はじめに:Web技術と持続可能性の交差点 近年、Webサイトの構築方法として「静的サイト生成(SSG)」が注目を集めている。これは、ページを事前に生成し、サーバーへの負荷を軽減する手法だ。一方で、持続可能な開発目標(SDGs)への関心も高まっており、環境への配慮が求められている。本記事では、静的サイトがどのようにSDGsに貢献し、環境、知識、技術の三方良しを実現するかを探る。 静的サイトの環境への利点 サーバー負荷の軽減 静的サイトは、ページをビルド済みで配信するため、アクセスのたびに処理を走らせる必要がない。これは、動的生成型のPHPサイトなどと対照的であり、サーバーの消費電力や負荷を大幅に軽減できる。サーバー台数の削減にもつながるため、結果的にCO₂排出の削減に貢献する。 CDNとの相性の良さ SSGはCDNとの親和性が高く、ユーザーの地理的位置に応じた効率的な配信が可能になる。データ転送の効率化により、ネットワーク全体の負荷とエネルギー消費を抑えられる。 知識の持続可能な共有 長期的なアクセス性の確保 動的CMSやデータベースベースのWikiは、サービス終了やデータベース障害に弱い。一方、静的サイトはMarkdownなどのプレーンファイルとして手元に保管でき、WebページもHTMLとしてそのまま保管できる。これにより、知識資産の長期保存が可能となる。 検索性とリンク性の向上 静的サイトでは、意味のあるURL(例:/dictionary/torque)を付けることができ、検索エンジンや人間にとっても扱いやすい。これは知識を引用・展開するうえで非常に重要であり、学術・教育サイトにとっては死活問題である。 技術的な利点と持続可能性 セキュリティの向上 動的サイトはサーバーサイドで処理が発生するため、XSSやSQLインジェクションなどの攻撃リスクがある。SSGは基本的にHTML配信のみなので、攻撃面が極端に少ない。これは保守性にも直結する。 メンテナンスと運用コスト 構成がシンプルなため、開発者・編集者にとっても扱いやすい。更新もローカルで行い、Gitで管理するようにすれば、チームでの共同編集も安全かつ再現性の高いものになる。 世の中的な動きとエビデンス Google:Core Web Vitalsの導入 Googleは検索ランキングにおいて「Core Web Vitals(LCP, FID, CLS)」といったWeb表示性能指標を導入しており、軽量かつ高速なサイトは明確に優遇されている。 参考:Google Search Central Blog – Core Web Vitals 将来への展望:Webサービスとエネルギー効率の評価へ 現時点では、Webサイトのエネルギー効率やCO₂排出量を評価する制度が浸透していないように思える。しかし、現在の社会ではすでに、サプライチェーン全体でのCO₂排出量算出や削減の取り組みが物質分野・エネルギー分野で加速している。 その中で、Webサービスにおける無駄なサーバー稼働による電力消費が評価の対象外であることは、いずれ問題視されるだろう。静的サイトへの移行は、この点でも社会的に評価される流れが生まれる可能性がある。 いまはまだ広く認知されていないが、将来的には「エネルギー効率の良いWeb設計」が、調達基準や社会的評価の対象になるかもしれない。 静的サイト運用の必要性を、実際の公共系サイトの構成から問題提起した例として、以下の記事も参照してほしい。というか、この記事のアイディアは、以下記事を書いている際に思い付くに至った。 日本機械学会の機械工学事典と「PHPの残念さ」について 結論:静的にしていくことは“正しさ”である 静的サイトは、単に「高速で安全」なだけでなく、環境負荷を減らし、知識の流通と保存を支える技術である。将来的に社会がこの方向に進まざるを得ないのは、「大衆が馬鹿じゃなければ」必然の流れだ。 技術者として、情報発信者として、静的にすることは正義である。

2025年5月16日

Hugoで記事が表示されない?

Hugoで記事が表示されない? Hugoを使って記事を書いていたところ、記事が表示されないという現象に遭遇した。フロントマターに draft: false を設定しており、ファイル名やフォルダ構成にも問題はない。ビルドエラーも出ていない。それでも記事が出ない。 その原因は、日付フィールドが“未来”として扱われていたためだった。日本時間では「今日」でも、Hugoの内部処理では「まだ未来」だったのである。 Hugoの内部時間処理はUTC基準 Hugoでは、Markdown記事のフロントマターで指定する date: フィールドが、内部的に UTC(協定世界時)基準で解釈されている。そのため、たとえば日本時間で 2025-05-09 を指定した場合でも、 日本時間(JST)では5月9日 → 午前中 UTCではまだ5月8日 という時差がある。この状態でHugoを通常起動すると、「未来記事」として非表示扱いされる。 これは特に index.md を使った Leaf Bundle構成の記事や、content/ 以下に日付ベースで管理している場合に混乱を招きやすい。 初心者が気づきにくい理由 この挙動が厄介なのは、以下のような要因があるためだ: ビルドしてもエラーが出ない hugo server を使っても、記事が非表示である理由の明示はない draft: false にしていても関係なく非表示になる フォルダ構成やテーマ設定の問題と勘違いしやすい 結果として、「なぜか記事が出ない」という状態に陥り、構文ミス・設定ミスなどを疑って時間を浪費することになる。 対策①:date: を「過去日」にする もっとも単純で確実な解決法は、フロントマターの日付を現在の日本時間より確実に過去の日付にしておくことである。 例: date: "2025-05-08" 記事の執筆日と公開日を分ける設計にしておけば、JSTとUTCのズレによる非表示問題を防げる。 対策②:--buildFuture を付けて起動する 開発中で、あえて未来日付で記事を作成したい場合は、Hugoの起動オプションに --buildFuture を付けると、未来日付の記事もビルド対象になる。 hugo server --buildFuture ただし本番環境では、hugo 単体でビルドする限りこのオプションは無効なので注意。 対策③:ISO 8601形式でタイムゾーンを明示する(限定的) タイムゾーンを明示した形式: date: "2025-05-09T00:00:00+09:00" Papermodなど一部のテーマではこの表記に対応しているが、Hugo本体の表示制御には影響しない。表示可否に関しては、依然としてUTC基準で判断されるため、根本的な解決にはならない。 まとめ:日付の罠を避けるには Hugoでは、date: フィールドがUTC基準で処理されるという前提を押さえておくことが重要である。記事が表示されない場合、構文や構成ミスの前に「日付が未来になっていないか」を確認するのが鉄則だ。 実務上は、 date: は1日前など、明示的に過去日に設定する --buildFuture は開発時限定で使う といった運用を取り入れることで、この静かに発動する“非表示バグ”を回避できる。 この挙動を知っているだけで、Hugo運用はぐっと安定するだろう。

2024年7月1日