
2026/05/07 16:16
ラズパイ上でサイトをホストする方法
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
著者は、静的サイトジェネレーターや Vercel などのプラットフォームを介さず、直接動的な Web サイトを実行することにより、Raspberry Pi で独自のセルフホスティングソリューションを実装しました。このアプローチは、特定の不管理国際化ライブラリが動的には動作するものの、静的生成とは互換性がないため必要でした。Astro.js は SvelteKit が選択されました。これは、サーバーサイドレンダリングのために Node.js を使用するためです。インフラストラクチャは GitHub Actions(プッシュ時にトリガーされる)によって簡素化されており、コードを取得し、
$HOME/Documents ディレクトリ内でビルドを実行し、PM2 を介してサーバーを再起動します。これには手動の介入が不要です。カスタム Caddy Web サーバー構成により、異なるポート(Astro は 4321、Svelte/Kit は 5173、React は 3000)で複数のフレームワークを管理し、OS サービスとの競合を回避します。ネットワークアクセスは、ホームルーターのポートフォワーディングと DNS A レコードを Pi のパブリック IP に設定することで保護されています。このアーキテクチャにより、開発者と中小企業が家庭用ハードウェアから複雑なアプリケーションをホスティングできるようになり、クラウドコストを削減しつつ、ビルドパイプラインとデータの制御を維持できます。本文
たまたまドメインを購入し、余っていた RASPbery Pi もある状態だったので、Web サイトの作成に取りかかりました。Astro と Svelte の両方以前に手をつけていた経験から、どちらを採用するかしばらく悩みましたが、結局 Astro を選ぶことにしました。これで決定的な選択をしてよかったです。Astro が単純な Web サイトにおいていかに素晴らしいものかを別のブログ記事で詳しく紹介することもできるかもしれませんが、それは(もしかしたら?)今後の話です。
さて、Mart さんへのあなたの質問かもしれません:「なぜ完全に静的 Web サイトの場合に Raspberry Pi を使うのでしょうか?本当に必要なのでしょうか?」実は、Verce l で動作しないが、かつ動的な挙動を示す特定のライブラリが存在したからです。そのライブラリは今回のサイト以前にも別のウェブサイト(このサブドメインと同じく RASPbery Pi でホストされていた)で使用しており、もはやメンテナンスされていませんが、国際化 (i18n) の処理には非常に優れていました。
こうして現在の状況に至りました。では、どうやって動くのでしょうか? このガイドは網羅的ではありませんが、Node.js フレームワークで構築された自ホスト Web サイトへの自己導入を始めるための参考ポイントとしてご活用ください。
ステップ 1: ポート転送の設定
- まず、ルーターの設定を確認し、その IP アドレスを RASPbery Pi の IP アドレスに転送するように設定してください。Google で検索すれば多くのチュートリアルが見つかりますが、ルーターによって手順は異なるため、ご自身のルーター向けの方法を確認することをお勧めします。
- 次に、リポジトリを機械上に
して取得してください。git pull - その後、Caddy をインストールし、その Caddyfile(あるいは類似のファイル)に以下の内容を追加します:
m4rt.nl { root * /home/mart/Documents/m4rt.nl # ここを実際の Web サイトのルートディレクトリに変更してください file_server reverse_proxy localhost:4321 # Astro なら 4321、SvelteKit なら 5173、React なら 3000 }
- Caddyfile を再読み込みすることを忘れないでください。詳細な設定方法については Google をご参照ください!
ステップ 2: DNS の設定
- ドメインを購入した後は、プロバイダへアクセスして新しいレコードを追加してください:
- A レコード: yoursite.com → ルーターの公開 IP アドレス
- これにより、ルーターは自動的に受信するトラフィックをその IP アドレス経由で Web サイトへと転送します!
ステップ 3: Web サイトのビルドと配信
- 次に、Web サイトを JavaScript ファイルにパッケージ化する必要があります。これはほぼ常に
(またはお好みのパッケイジマネージャーを実行)することで実現できます。これにより、npm run build
やdist
という名前のディレクトリが作成されます。out - そのディレクトリを開き、エントリーポイントファイルを探してください。通常は
またはentry.cjs
と呼ばれています。entry.mjs - その後、PM2 をインストールしてください。PM2 は Node.js アプリをあなたが停止命令を出すまで稼働させるためのサービスです。コマンド一つでインストールできます:
。npm i -g pm2 - 次に、dist ディレクトリへ移動し (
)cd
を実行してください!pm2 run entry.mjs - これで完了です。Web サイトがライブになりそうです :) やっとおめでとうございます!
ステップ 4: 高度な CI/CD(継続的インテグレーション) おそらくここは Verce l と比較して少し違和感を覚えたでしょう: コミットを何か行ったらどうなるでしょうか?Web サイトがビルドされません! luckily、これを解決するために GitHub Actions というものがあります。
- まず、
という新しいディレクトリを作成し、その中に.github
ディレクトリを置きます。この中にファイルを作成し、「update_server.yml」などの名前に付けます(名称は自由に設定可能です)。workflows - 以下の内容を追加します:
name: Update server code and restart the server on: [push] jobs: build: name: Build runs-on: ubuntu-latest steps: - name: Update server code and restart the server uses: appleboy/ssh-action@v1 with: host: ${{ secrets.HOST }} username: your-username # これは RASPbery Pi 上の sudo ユーザー名です! password: ${{ secrets.PASSWORD }} script: | ~/bin/pull-all.sh
- 次に、リポジトリの設定画面に入り、「Actions」>「Secrets」を選択してください:
- 「New secret」をクリックし、RASPbery Pi のホスト IP とパスワードをそれぞれ HOST と PASSWORD という名前で追加します。
- その後、
フォルダにスクリプトを作成(私はbin
という名称を使用)し、以下の内容を記述してください:pull-all.sh
#!/usr/bin/env bash set -euo pipefail BASE_DIR="$HOME/Documents" # これは頻繁に使用するディレクトリに変更してください # ここで使用しているポートです。状況に応じて変更してください。Linux はシステムソフトウェアを動作させるために一部のポートを使用するため、手動で設定するのが推奨されます。 PORTS=(4321 4322) PORT_COUNT=${#PORTS[@]} PORT_INDEX=0 echo "updating git repositories..." # ディレクトリがリポジトリかどうかをチェックし、最新の変更をプルします for dir in "$BASE_DIR"/*/ ; do if [[ -d "$dir/.git" ]]; then echo "→ Entering $dir" ( cd "$dir" && git pull ) fi done echo -e "building websites with assigned ports..." for dir in "$BASE_DIR"/*/ ; do # Node.js プロジェクトかどうかをチェックします。Deno を使用する場合はこの処理を変更する必要があるかもしれません if [[ -f "$dir/package.json" ]]; then CURRENT_PORT=${PORTS[$PORT_INDEX]} echo "building in $dir using PORT: $CURRENT_PORT" ( cd "$dir" npm run build -- --port "$CURRENT_PORT" ) PORT_INDEX=$(( (PORT_INDEX + 1) % PORT_COUNT )) fi done echo -e "restarting pm2..." pm2 restart all
これで完了です! ご覧いただきありがとうございます。良い一日をお過ごしください。 Mart サインアウト