(更新:

Astro + Cloudflare Workersでブログを公開する:実践ガイド


前回の記事では、Markdownブログ向けのSSGを比較し、Astroが2026年時点でバランスの取れた選択肢であることを整理しました。

この記事では、実際にAstroでブログを構築し、Cloudflare Workersで公開するまでの手順を解説します。


TL;DR

  • Astroを使えば、Markdownで記事を書くだけのブログがすぐ作れる
  • 公開記事は posts/、下書きは drafts/ に分けると運用しやすい
  • WORKERS_CI_BRANCH を使うと、main では本番、その他ブランチではプレビューを分けられる
  • Cloudflare Workers Builds を使うと、push を起点にビルドとデプロイを自動化できる

「まず公開まで最短で到達する」ことを目的に、運用で詰まりやすいポイント(下書き除外・自動デプロイ)を優先して説明します。


この記事で扱う内容

  • Astroプロジェクトの作成
  • 記事の追加とフロントマター設定
  • 下書き機能の実装
  • Cloudflare Workersへのデプロイ

対象バージョン: Astro 5.x / Wrangler 3.x

ローカルでの動作確認から本番公開まで、一通りの流れを押さえます。


Astroプロジェクトの作成

初期化コマンド

npm create astro@latest

対話形式でいくつか質問されます。ブログ用途なら以下の選択が無難です。

  • テンプレート: Blog
  • TypeScript: お好みで(推奨は Yes)
  • 依存関係のインストール: Yes

ディレクトリ構成

作成されるプロジェクトの主要な構成は以下の通りです。

src/
├── content/
│   └── blog/         # Markdown記事を配置
├── components/       # 再利用可能なコンポーネント
├── layouts/          # ページレイアウト
├── pages/            # ルーティング
└── content.config.ts # コンテンツスキーマ定義

記事は src/content/blog/ にMarkdownファイルを追加するだけで認識されます。詳細はAstroブログチュートリアルを参照してください。


記事の追加

フロントマターの基本形

各記事の先頭には、タイトルや公開日などのメタ情報を記述します。公開日は publishedAt を正として扱います。

---
title: "記事タイトル"
description: "Astroで技術ブログを公開したい人向けに、プロジェクト作成、公開記事と下書きの分離、Content Collections設定、Cloudflare Workers Buildsによる本番・プレビュー運用、公開フローまでを実践的に解説します。"
canonicalId: "20260126_2"
urlSlug: "astro-blog-start-guide"
publishedAt: "2026-01-26"
tags: [Astro, Markdown, デプロイ]
---

本文をここに書きます。

スキーマ定義(Content Layer API)

このサイトでは src/content.config.ts で公開記事と下書きを分けて読み込み、frontmatter の型を定義しています。

import { defineCollection, z } from "astro:content";
import { glob } from "astro/loaders";

const blog = defineCollection({
  loader: glob({ base: "./src/content/blog", pattern: "**/*.{md,mdx}" }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      description: z.string(),
      canonicalId: z.string().min(1),
      urlSlug: z.string().min(1),
      publishedAt: z.coerce.date(),
      updatedDate: z.coerce.date().optional(),
      heroImage: image().optional(),
    }),
});

export const collections = { blog };

これで公開記事と下書きを同じコレクションで扱いつつ、公開記事側では publishedAt などの必須項目を揃えやすくなります。


下書き機能の実装

このサイトでは、公開記事と下書きを ディレクトリで分ける 方式を採用しています。

  • 公開記事: src/content/blog/posts/YYYY/<canonicalId>.md
  • 下書き: src/content/blog/drafts/<slug>.md

content.config.ts でブランチごとに読み分ける

Cloudflare Workers Builds が注入する WORKERS_CI_BRANCH を使うと、main では公開記事だけ、それ以外のブランチでは下書きも含める運用ができます。

const isDraftBranch =
  !!process.env.WORKERS_CI_BRANCH && process.env.WORKERS_CI_BRANCH !== "main";

const blog = defineCollection({
  loader: glob({
    base: "./src/content/blog",
    pattern: isDraftBranch
      ? ["posts/*/*.{md,mdx}", "drafts/*.{md,mdx}"]
      : "posts/*/*.{md,mdx}",
  }),
  schema: ({ image }) =>
    z.object({
      title: z.string().optional(),
      description: z.string().optional(),
      canonicalId: z.string().min(1).optional(),
      urlSlug: z.string().min(1).optional(),
      publishedAt: z.coerce.date().optional(),
      updatedDate: z.coerce.date().optional(),
      heroImage: image().optional(),
      tags: z.array(z.string()).optional(),
    }),
});

この方式なら、drafts/ の未完成原稿は main 本番ビルドに混ざらず、PR ブランチやローカル preview では確認できます。

公開時の操作

下書きが完成したら、drafts/ から posts/YYYY/ へ移動し、canonicalIdpublishedAt を確定させます。

# 下書き → 公開
mv src/content/blog/drafts/my-article.md \
  src/content/blog/posts/2026/20260126_2.md

ローカルでの確認

公開記事だけを見たいときは通常の dev/build を使い、下書きも含めて確認したいときは WORKERS_CI_BRANCH を指定します。

# 公開記事のみ
npm run dev

# 下書きも含めて確認
WORKERS_CI_BRANCH=draft npm run dev

Cloudflare Workersへのデプロイ

なぜCloudflare Workersか

  • 無料枠が実用的: 静的アセットは無制限、リクエストも10万/日
  • Workers Builds: GitHubリポジトリと連携するだけで自動デプロイ
  • 高速配信: 世界中のサーバーから最寄りの場所で配信
  • 将来の拡張性: Cloudflareの機能で問い合わせフォームやデータベース連携も追加できる

個人ブログなら十分すぎる環境です。詳細はCloudflare Workers公式ドキュメントを参照してください。

Workers Assets とは

Cloudflare Workersには静的ファイルをホスティングする「Assets」機能があります。Astroでビルドした dist/ フォルダをそのまま配信できます。

設定ファイルの追加

プロジェクトルートに wrangler.jsonc を作成します。

{
  "name": "your-site-name",
  "compatibility_date": "2026-01-12",
  "assets": {
    "directory": "./dist",
  },
}
項目説明
nameWorkers名(URLの一部になる)
compatibility_dateWorkers APIの互換性日付
assets.directory静的ファイルの出力先(Astroは dist

Workers Builds による自動デプロイ

Cloudflareには「Workers Builds」という自動ビルド・デプロイ機能があり、GitHub/GitLabと連携できます。

設定手順

  1. Cloudflareダッシュボードで「Workers & Pages」を開く
  2. 「Create」からGitHubリポジトリを連携
  3. ビルド設定:
    • Build command: npm run build
    • Deploy command: npx wrangler deploy

ビルドの流れ

GitHub push

Workers Builds(Cloudflare環境)
    ├─ npm clean-install(lockファイルを厳密に再現)
    ├─ npm run build(Astroビルド → dist/)
    └─ npx wrangler deploy(Workers Assetsにアップロード)

Cloudflare Workers(エッジ配信)

npm clean-installnpm ci)が使われるため、package-lock.json に記録されたバージョンが厳密に再現されます。

プレビュー環境

main 以外のブランチに push すると、ブランチごとにプレビューURLが自動生成されます。main は本番デプロイ、それ以外はプレビューという分け方です。

URL 形式はサービス名や設定に依存しますが、このサイトでは次の形式です。

https://<ブランチ名>-air-innovate-site.hasegawa496.workers.dev/

Cloudflare Access を設定すれば、プレビュー環境に認証をかけることもできます。


まとめ

  • Astroはブログテンプレートで即座に始められる
  • 公開記事と下書きを posts/ / drafts/ で分けると運用しやすい
  • WORKERS_CI_BRANCH を使うと、main 本番とプレビューの挙動を切り替えやすい
  • Cloudflare Workers + Workers Builds でビルドとデプロイを自動化できる
  • 将来的なAPI追加も同じ構成で対応可能

「Markdownで書いてGitで管理し、PR ブランチで確認してから main で公開する」という流れを、最小限の設定で回せます。


次にやること(実務向けチェックリスト)

  • 独自ドメインを workers.dev に割り当てる
  • npm run validate:tags を CI に組み込み、タグ揺れを防ぐ
  • OGP画像テンプレートを用意し、公開前に差し替える
  • README に「公開手順(下書き→公開)」を追記して運用を標準化する