デプロイ
このページの内容
デプロイ
site/ はプレーンな静的サイトです - 静的ファイルを配信できる場所であればどこにでも
ホストできます。bxSites deploy を使えば、一つの
コマンドで直接そこへ配信できます: S3(および DigitalOcean Spaces、Cloudflare R2、
Backblaze B2、MinIO などの S3 互換サービス)、Azure Blob Storage、Google Cloud
Storage、Firebase Hosting、FTP、SFTP、rsync-over-SSH、Netlify、Vercel、
Cloudflare Pages、ローカルディレクトリ、または GitHub Pages です。
deploy コマンド
最も単純な2つのターゲット(local / github-pages - フラグだけで動作します。
詳しくは CLI リファレンス を参照)を除き、すべての
ターゲットはプロジェクトルートの deployments/<name>.json ファイルで設定します -
実際に使用するデプロイターゲットごとに1ファイルで、それぞれがどの target かと、
そのターゲット固有のフィールドを指定します:
bxSites deploy --entry=production
{ "target": "s3", "bucket": "my-docs-site", "accessKeyIdEnvVar": "AWS_ACCESS_KEY_ID", "secretAccessKeyEnvVar": "AWS_SECRET_ACCESS_KEY" }
シークレットは必ず環境変数から取得され、deployments/*.json 内のリテラル値から
取得されることはありません。 EnvVar で終わるすべてのフィールドは、実際の
シークレット(アクセスキー、パスワード、API トークン)を保持している環境変数の
名前を指定します - デプロイ時にその都度解決されるため、deployments/*.json 自体は
常にコミットしても安全です。自分ですでに管理している認証情報ファイル(SSH 秘密鍵、
ダウンロードした GCP サービスアカウントの JSON キーなど)へのパスを指定する
フィールドだけは例外です - こちらは普通のフィールドのままにします。バージョン
管理から外すべきなのはパスではなくファイル自体だからです。ローカルでは、
これらの環境変数をシェルへ手作業でエクスポートする代わりに .env ファイルから
読み込むこともできます(BoxLang が自動的に1つを読み込み、各ターゲットが
それらの解決に使う getSystemSetting() が透過的にそれを参照します) - CI では、
ランナー上の実際のシークレットとして設定してください。
すべてのターゲットへ一括デプロイ
--entry も --target も指定せずに bxSites deploy を実行すると、単一の
共有ビルドを使って deployments/*.json の各エントリーが順番にデプロイ
されます:
bxSites deploy
エントリーの数に関わらず、サイトのビルドは一度だけ行われます。1つの
ターゲットが失敗しても他は止まりません - すべてのエントリーが試行され、
コマンドは少なくとも1つが失敗した場合にのみ非ゼロで終了します。サマリーには
成功した数が報告されます(例: Deployed to 2/3 target(s) (1 failed))。
--verbose(--entry/--target と組み合わせても使えます)を付けると、
最終的なサマリーだけでなく、ビルドおよび各ターゲットの開始/終了時にも進捗行が
出力されます。
local
ビルドしたサイトを任意のディレクトリ(共有ドライブ、ステージング用フォルダ、その他
どこでも)にコピーします。deployments/ のエントリを一切必要としない唯一の
ターゲットです。
bxSites deploy --target=local --destination=/path/to/somewhere
github-pages
gh-deploy が行うのと同じプッシュに、この統合
コマンドからも到達できます - こちらも deployments/ のエントリは不要です:
bxSites deploy --target=github-pages [--branch=gh-pages] [--remote=origin] [--message="..."]
s3
本物の AWS S3、または任意の S3 互換サービス - AWS 自体以外では endpoint を
設定し、AWS 以外のほとんどのプロバイダでは forcePathStyle: true も設定します。
{
"target": "s3",
"bucket": "my-docs-site",
"region": "us-east-1",
"prefix": "",
"accessKeyIdEnvVar": "AWS_ACCESS_KEY_ID",
"secretAccessKeyEnvVar": "AWS_SECRET_ACCESS_KEY"
}
{
"target": "s3",
"bucket": "my-docs-site",
"endpoint": "https://nyc3.digitaloceanspaces.com",
"forcePathStyle": true,
"accessKeyIdEnvVar": "SPACES_KEY",
"secretAccessKeyEnvVar": "SPACES_SECRET"
}
同じ形(カスタム endpoint + forcePathStyle: true)は、Cloudflare R2
(https://<accountid>.r2.cloudflarestorage.com)、Backblaze B2、MinIO/Wasabi も
カバーします。
azure
Azure Blob Storage。SAS トークン、アカウントキー、完全な接続文字列のいずれか一つで 認証します。
{
"target": "azure",
"account": "mystorageaccount",
"container": "site",
"accountKeyEnvVar": "AZURE_STORAGE_KEY"
}
gcs
Google Cloud Storage。ダウンロードしたサービスアカウントの JSON キー(Google Cloud Console -> IAM と管理 -> サービスアカウント -> 鍵)で認証します。
{
"target": "gcs",
"bucket": "my-docs-site",
"serviceAccountKeyPath": "/path/to/service-account.json"
}
firebase
Firebase Hosting。gcs と同種のサービスアカウントキーを使用します。
{
"target": "firebase",
"siteId": "my-firebase-site",
"serviceAccountKeyPath": "/path/to/service-account.json"
}
ftp / sftp
サイト全体を FTP または SFTP でリモートサーバーにアップロードし、フォルダ構造を 維持します。SFTP はパスワードまたは SSH 鍵に対応しています。
{
"target": "sftp",
"host": "example.com",
"username": "deploy",
"remotePath": "/var/www/html",
"key": "/home/me/.ssh/id_rsa"
}
rsync
実際の rsync バイナリを使い、SSH 経由でサイトをリモートサーバーに同期します -
変更分だけを転送するため、フルリビルドでは FTP/SFTP より高速です。bxSites を
実行するマシンに rsync と ssh が必要です。
{
"target": "rsync",
"host": "example.com",
"username": "deploy",
"remotePath": "/var/www/html",
"identityFile": "/home/me/.ssh/id_rsa"
}
netlify
{
"target": "netlify",
"siteId": "my-site-id-or-name.netlify.app",
"authTokenEnvVar": "NETLIFY_AUTH_TOKEN"
}
vercel
{
"target": "vercel",
"projectId": "my-project",
"authTokenEnvVar": "VERCEL_TOKEN"
}
cloudflare-pages
Cloudflare には direct-upload デプロイ向けの公式ドキュメント化された REST API が
ありません - あるのは wrangler CLI だけです。このターゲットは Wrangler 自身の
アップロードフローをリバースエンジニアリングしたもので、デフォルトの Java
インストールの多くには含まれていない BLAKE3 ハッシュ実装を JVM のクラスパス上に
必要とします - この点の粗さについての詳細で正直な説明は
CLI リファレンス とターゲット自身のソースを
参照してください。
{
"target": "cloudflare-pages",
"accountId": "your-account-id",
"projectName": "my-project",
"apiTokenEnvVar": "CLOUDFLARE_API_TOKEN"
}
package コマンド
上記のどのターゲットよりも単純なアーカイブの方が良い場合 - ビルドを GitHub
リリースに添付する、zip アップロードしか受け付けないホストに渡す、あるいは
どのプラガブルターゲットも届かない場所へ配送する、といったケースです。
bxSites package はサイトをビルドしてから、
ルートがビルドされたサイト自身の内容になっている(site/ フォルダで包まれて
いない)単一のファイルへ圧縮します:
bxSites package
bxSites package --output=dist/my-site.zip
--output のデフォルトは <projectRoot>/site.zip です。相対パスを指定した
場合はプロジェクトルートを基準に解決され、まだ存在しない親ディレクトリは
自動的に作成されます。
GitHub Actions(複数バージョン公開)
手動で実行する bxSites deploy/gh-deploy の代わりに、プッシュのたびに自動で
公開したい場合のために、このモジュールには main と development を GitHub
Pages 上で同じサイトの独立して稼働する 2 つのバージョンとして公開する、すぐに
使える GitHub Actions ワークフロー(.github/workflows/pages.yml)が付属して
います。このガイドの残りは、このリポジトリ自体のドキュメントが使用している
そのワークフローについて説明します。
動作内容
docs/、bxsites.yaml、またはモジュール自体のソース(テーマ/パイプラインの変更)に
触れる main または development へのすべての Push で、ワークフローが:
- BoxLang + bx-markdown をインストール
- このリポジトリをモジュールとして登録して
boxlang bxSites buildを解決 main以外のブランチでは、このビルドのみbaseURLを.../<branch-name>/に設定 (以下を参照)boxlang bxSites buildを実行site/をgh-pagesブランチに Push(mainはサイトルート、developmentは/development/)、 もう一方のバージョンには触れません
Actions タブから手動トリガー(workflow_dispatch)でも利用可能で、
新しいコミットなしに一回限りの再公開ができます。
初回セットアップ
ワークフローが公開できるようにする前に、GitHub Pages を gh-pages ブランチに向ける必要があります。
これはリポジトリの設定で行うもので、ワークフローファイルだけでは有効にできません。
最初の成功したランが gh-pages を作成するため、ワークフローが少なくとも一度実行されてから行います:
- Settings → Pages
- Build and deployment → Source で Deploy from a branch を選択
- Branch で gh-pages と / (root) を選択
それ以降、一致するすべての Push が自動的にビルドおよびデプロイされます。 最初のデプロイ完了後に Settings → Pages に公開 URL が表示されます。
2 つのバージョンを同時に公開
main はサイトルート(https://<user>.github.io/<repo>/)に公開されます(安定版/リリース済みドキュメントとして扱います)。
development は /development/(https://<user>.github.io/<repo>/development/)に公開されます(最新の未リリースドキュメント)。
両方が同時に稼働し続けます: 各ブランチのジョブは keep_files: true と独自の destination_dir を使用して
gh-pages にのみ Push するため、development のデプロイが main のコンテンツを上書きすることはなく、
その逆も同様です。
3 番目のブランチを追加するには(例: release/2.0 プレビュー)、on.push.branches リストに追加し、
destination_dir: release-2.0(または類似)を使用した if: github.ref_name == '...' デプロイステップを追加します。
独自プロジェクトへの応用
.github/workflows/pages.yml を独自のプロジェクトにコピーし(プロジェクトが bx-markdown 以外を
必要とする場合は modules: 行を調整し)、上記のように Pages を有効化すると、
main/development への Push が同様に公開されます。単一の公開バージョンのみが必要な場合は、
必要のないブランチを on.push.branches とその対応するデプロイステップから削除します。
プロジェクト Pages のサブパスからの配信
GitHub の プロジェクト Pages サイト(ユーザー サイトとは異なり)は
https://<user>.github.io/<repo>/ から配信されます(ドメインルートではありません)。
bxsites.yaml の baseURL をその完全な URL に設定して、すべての内部リンク、アセット、
ナビゲーションエントリに必要な /<repo>/ プレフィックスが付くようにしてください。
また、実際の sitemap.xml も生成されます:
baseURL: "https://<user>.github.io/<repo>/"
{ "baseURL": "https://<user>.github.io/<repo>/" }
baseURL が何をするかの完全な詳細については 設定 を参照してください。
<user>.github.io ユーザーサイト、またはサイトルートにマッピングされたカスタムドメインの
場合は、baseURL をデフォルト(/)のままにしておけます。
サイトへのアクセスを制限する
ここには組み込みのアクセス制御はありません - bx-sites が生成するのはあくまで
プレーンな静的 site/ であり、静的ファイルには「誰がリクエストしているか」という
概念がありません。bxsites.json の robots: false は、
行儀の良いクローラーにビルドをインデックスしないよう伝えます(検索結果に出したくない
ステージング/プレビューデプロイに便利です)が、これはあくまで丁重なお願いであって
鍵ではありません - URL を持っている人には引き続き機能します。実際にアクセスを
制限する必要がある場合、それは静的ファイルの手前、つまりそれを配信しているホスト側で
行う必要があります - よくある、静的サイトに適した選択肢をいくつか挙げます:
- Cloudflare Pages/Access - デプロイしたサイトを Cloudflare Access ポリシー(メールアドレスの許可リスト、SSO、またはワンタイム PIN)の背後に置きます - アプリケーションコードは一切不要です。
- Netlify - サイト設定だけで使える組み込みの パスワード保護 で、サイト単位/デプロイ単位のどちらでも設定できます。
- 小さなリバースプロキシ(任意のホスト)- 静的ファイルの手前に HTTP Basic 認証
(
.htpasswd形式のルール、または一つのファイルで済む Cloudflare Worker/Netlify Edge Function)を置けば、「検索エンジンや無関係な人を締め出す」目的には十分です - ただし、サインイン済みアプリが持つような本物のユーザーごとの識別ではありません。
これらはいずれも bx-sites 自体の機能ではありません - site/ の配信先ホストの側で
有効にする、ホストレベルの設定です。