Yohakuを個人スペースとしてデプロイした記録
この数日、静かな森 にアクセスした際に、そのテーマ Yohaku が自分の美的感覚に非常に合っていることに気づきました。以前使っていた、機能的にはより充実しているが洗練されていない Astral Reverie と比較すると、Yohaku は文章制作の深さにおいて生活記録、個人スペースにより適しており、その記録の表現形式も個人の雑事、学習、インスピレーションのニーズをカバーしています。今回初めてモダンなフロントエンドプロジェクトに触れたため、それまでは PHP やネイティブ CSS、JS が中心だった私が Yohaku をデプロイする際に大小さまざまな問題に直面しました。そのため、ここに記事として記録し、今後の参考に供します。
私はすでにパブリック IPv4 アドレスを持つクラウドサーバーを持っているため、この記事では主にLinux クラウドサーバー環境(宝塔パネル付き)でのデプロイ方法を紹介します。Vercel を使ったデプロイ方法についてはこの記事では扱いません。必要な場合はインターネット上の他の記事を参照してください。
参照
関連プロジェクトのリポジトリ:
この記事で参照している関連ドキュメント、技術説明、ガイド:
Important
Yohaku プロジェクトはクローズドソースプロジェクトであり、Innei の GitHub 上の Yohaku リポジトリはプライベートリポジトリです。このリポジトリにアクセスするには、GitHub Sponsor を通じて開発者をスポンサーする必要があります。
https://github.com/sponsors/Innei
環境デプロイと要件
Yohaku プロジェクトの本体は GitHub 上にあり、まずコンパイル・ビルドを行った後、サーバーにデプロイする必要があります。Node.js プロジェクトはコンパイル時にデバイスのパフォーマンス負荷が大きいため、GitHub Actions ワークフローを使用することにしました。
ドメイン名の登録と DNS の設定
現在、主流のドメイン登録チャネルとしては、国内の Tencent Cloud、Alibaba Cloud、Baidu Cloud、海外の Cloudflare、GoDaddy、DynaDot があります。ここでは個人的に Cloudflare を推奨しますが、お好みのドメインサービスプロバイダーを選んでも構いません。違いはありません。
ドメインを登録したら、ドメインサービスプロバイダーの「DNS 解析」管理画面(注意:Tencent Cloud のドメイン管理は DNSPod で行います)にアクセスし、以下の A レコードを追加してください。解決アドレスにはサーバーの パブリック IP を記入します:
- @
- api
Note
解決レコードとは、ドメインのサードレベル、フォースレベル、またはそれ以上のドメインを指します。例えば、
example.comに対して A 解決をアドレス1.1.1.1に設定し、レコードを api とした場合、DNS サーバーはapi.example.comを1.1.1.1に解決します。注意点として、@ はドメインのルートを指し、レコード @ はドメインそのものを表します。
サーバー環境とアカウント登録
まず、パブリックネットワークに接続可能なサーバーと、独自ドメインを用意する必要があります。Tencent Cloud を例にとると、一般的なクラウドサーバーの価格は月額 CNY 30 ~ CNY 70 程度、ドメインの最低価格は年間 CNY 10 です。これらのリソースはウェブサイトを構築するには高くなく、むしろ非常にお得です。これら 2 つのハードウェア要件に加えて、以下のソフトウェア要件も必須です:
- GitHub アカウント(こちらから登録)
- サーバーに以下の実行環境をデプロイ
- Docker
- Node.js 20.11 以降(特に注意:このソフトウェアは古いサーバーに搭載された CentOS 7 環境では実行できません)
- pnpm
- pm2
- sharp
さらに、Yohaku が持つさまざまな機能を実現するために、以下のソフトウェアを推奨します:
- Clerk アカウント
- TMDB アカウント
サーバーの Node.js 環境設定については、以下のコードを参考にしてください:
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
sudo dnf install -y nodejs
# 验证
node -v
npm install -g pnpm
# 验证
pnpm -v
npm install -g pm2
# 验证
pm2 -v
cd && mkdir -p mx-space/core && cd $_
pnpm add sharp
宝塔パネルの Node.js マネージャーを使用して Node.js をインストールした場合、ターミナルで Node.js が見つからないことがあります。その場合は、マネージャーに表示されるインストールパスを確認し、それを PATH に追加してください。
サーバーの Docker 環境設定について、Tencent Cloud の宝塔アプリケーションサーバーには通常 Docker がプリインストールされており、1Panel パネルにも Docker が付属しています。ターミナルで docker -v と入力して Docker がインストールされているか確認できます。バージョン番号が表示されれば、Docker がインストールされています。
必要に応じて、以下の Docker インストール用ターミナルコマンドを参照してください:
# 如果你的服务器在国内,建议使用阿里云的安装脚本
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
# 在国外,可以直接使用官方脚本安装
curl -fsSL https://get.docker.com | bash -s docker
# 查询版本以验证安装
docker -v
バックエンドサービスの設定
MixSpace のデプロイ
Tip
この部分については、公式ドキュメントでより詳細な説明を参照できます: https://mx-space.js.org/docs/core/docker
Yohaku プロジェクトはフロントエンドとバックエンドが分離されたプロジェクトであり、MixSpace バックエンドに依存しています。そのため、まず MixSpace をデプロイする必要があります。より簡単な Docker の例として、まずバックエンドデプロイ用の docker-compose.yml を取得します:
cd && mkdir -p mx-space/core && cd $_
# 拉取 docker-compose.yml 文件
wget https://fastly.jsdelivr.net/gh/mx-space/core@master/docker-compose.yml
docker-compose.yml の environment フィールドに以下の必須情報を記入します:
- JWT_SECRET=
- ALLOWED_ORIGINS=
これら 2 つの属性フィールドについては、以下の説明があります:
JWT シークレット:長さ 16 文字以上、32 文字以下の文字列を入力します。これはユーザーの JWT を暗号化するために使用されます。シークレットは必ず自分で保管し、他人に漏らさないでください。許可されるオリジン:許可されるドメインを入力します。先ほど DNS で設定した解決ドメインを、カンマ(,)区切りで入力してください。注意点として、入力するドメインは完全なプレフィックスなしのドメインです。例:api.example.com,example.com;次のような形式ではありません:https://api.example.comやapiや@のみ。
Core を起動:
docker compose up -d
リバースプロキシの設定
ここでは宝塔パネルを例にとります。宝塔パネルを開き、サイト に移動し、新しいサイトを作成します。ドメイン名に api.あなたのドメイン を入力し、その他は変更せずに作成をクリックします。このとき、あなたのドメインにアクセスし、「サイト作成成功!」と表示されれば、設定は問題ありません。
新しく作成したサイトプロジェクトの右側にある 設定 をクリックし、ポップアップの左側で SSL を見つけて証明書(例:Let's Encrypt 無料証明書)を設定し、HTTPS を有効にします。
次に、上記の手順を繰り返し、別のサイトを新規作成し、ドメイン名を あなたのドメイン とします。
バックエンドサイトの 設定 で、リバースプロキシ セクションの 追加 をクリックし、ターゲット に http://127.0.0.1:2333、送信元ドメイン に $host を入力し、確定をクリックします。
フロントエンドサイトの 設定 で、リバースプロキシ セクションの 追加 をクリックし、ターゲット に http://127.0.0.1:2323、送信元ドメイン に $host を入力し、確定をクリックします。
その後、https://api.あなたのドメイン/proxy/qaqdmin にアクセスし、バックエンドサーバーを設定します。
トラブルシューティング
さまざまな予期せぬ問題が発生した場合は、AI エージェントに尋ねることをお勧めします。
新時代の新しい風潮として、私たちは人工知能が急速に発展する時代にいます。問題に遭遇した場合は、まず各種 AI アシスタントプログラムに質問してください。それらはほとんどの疑問を解決してくれるでしょう。
ここでは私が遭遇した問題を 1 つだけ挙げます。私は以前サーバーに Cloudreve を設定していたため、Docker 内に既に redis という名前のコンテナが存在していました。その場合、docker-compose.yml 内の関連コンテナの名前を変更してデプロイすれば問題ありません。
MixSpace の更新
メジャーバージョン番号が同じ場合(例:11.0.6 -> 11.6.1 や 11.0.6 -> 11.0.8。最初の小数点前の数字が変わっていなければ、メジャーバージョンは同じと見なします)、MixSpace の更新は非常に簡単です:
- MixSpace Core のデプロイディレクトリに移動;
- 直接
pullで新バージョンを取得; - 新バージョンを起動。
cd ./mx-space/core
docker compose pull app
docker compose up -d app
Started の表示を確認したら、バックエンドページを開き、更新の確認を行います:
- 記事一覧が正常に表示される;
- 記事内の関連コメントとコンテンツが正常に表示される;
- バックエンドログインが正常;
- 記事を投稿し、削除して、記事が正常に公開・削除できるかテスト。
フロントエンド Yahaku のデプロイ
@Innei が提供する GitHub Actions を使用してプリビルド形式でデプロイしました。
Tip
この部分については、経験があれば開発者の公式ドキュメントを参照できます:
デプロイワークフローリポジトリの Fork
まず、作者のリポジトリから deploy リポジトリをあなたの GitHub アカウントに Fork する必要があります。
Note
「Fork(フォーク)」とは GitHub における「合法的なコピー」を意味します。 作者が「自動デプロイワークフロー」のテンプレートリポジトリを作成しています。あなたはサーバーとドメインのニーズに応じてこのワークフローにいくつかのパラメータ調整を行う必要がありますが、直接作者のコードを変更することはできません。そのため、Fork ボタンをクリックして、作者のリポジトリ全体をそのまま自分の GitHub アカウントにコピーします。これでそのリポジトリはあなたのものになり、好きなように変更できます。
- GitHub アカウントにログインします。
- 原作者のワークフローリポジトリアドレスを開きます: yohaku-deploy-action
- 画面の右上にある Fork というボタン(通常小さな数字が横にあります)を見つけてクリックします!
- "Create a new fork" の確認画面が表示されます。何も変更せずに、一番下までスクロールして緑色の Create fork ボタンをクリックします。
- 2~3秒待ってページがリフレッシュされると、左上のリポジトリ名が
あなたのユーザー名/yohaku-deploy-actionに変わっていることがわかります。
GH_PAT の取得
同じ GitHub の機能ですが、GitHub Actions 自体はアカウント名下のプライベートリポジトリのコードを表示する権限を持っていません。そのため、アカウントの API キー(Personal Access Token (PAT))を設定し、GitHub Actions がリポジトリにアクセスできるようにする必要があります。
- GitHub の任意のページ右上にある自分のアバターをクリックし、ドロップダウンメニューから一番下の Settings(設定) を選択します。
- 左側の長いメニューを一番下までスクロールし、Developer settings(開発者設定) をクリックします。
- 左側のメニューから Personal access tokens -> Tokens (classic) を選択します。
- ページ右上の Generate new token -> Generate new token (classic) をクリックします。(このとき、GitHub のパスワードを入力して本人確認を求められる場合があります)。
- 新しいトークン作成ページで:
- Note(備考): 任意の名前を入力します(例:
Deploy-Shiro)。 - Expiration(有効期限):
No expiration(無期限)を選択し、後で再設定する手間を省きます。 - Select scopes(権限範囲):
repoを見つけ、横の大きなチェックボックスにチェックを入れます(これにより、このトークンがプライベートリポジトリにアクセスできるようになります)。
- Note(備考): 任意の名前を入力します(例:
- 一番下までスクロールし、緑色の Generate token をクリックします。
Important
ページに非常に長い文字列(
ghp_で始まる)が表示されます。すぐにそれをコピーして、ローカルのメモ帳に保存してください! このトークンは一度しか表示されず、ページをリフレッシュすると二度と見られなくなります。
Secrets の設定
次に、アカウントの API キーとその他の必要な情報を Deploy リポジトリの設定情報に記入します:
- 最初に Fork したリポジトリのホームページ(
あなたのユーザー名/yohaku-deploy-action)に戻ります。 - リポジトリ右上の Settings(設定) タブをクリックします。
- 左側メニューから順に Secrets and variables -> Actions をクリックします。
- 緑色の New repository secret ボタンをクリックします。
- 入力ページで:
- Name(名前):
GH_PATと厳密に入力します(すべて大文字、この通りでなければなりません)。 - Secret(内容): 先ほどメモ帳に保存した
ghp_で始まるトークンを貼り付けます。
- Name(名前):
- Add secret をクリックします。
続けて New repository secret をクリックし、以下のすべてを追加します:
HOST:サーバーの IP を入力(例:1.1.1.1)USER:rootまたは他のユーザー名を入力PASSWORD:サーバーの root パスワードを入力(安全でない場合は、KEYに SSH キーを入力してもよく、どちらか一方で構いません。初心者にはパスワードの方が適しています)PORT:22を入力(SSH のポートを変更していなければ 22 です)BASE_URL:https://あなたのドメインを入力NEXT_PUBLIC_API_URL:https://api.あなたのドメイン/api/v3を入力NEXT_PUBLIC_GATEWAY_URL:https://api.あなたのドメインを入力
Note
注意:宝塔パネルとサーバープロバイダーのクラウドサーバーダッシュボードのファイアウォールで、
22ポートが開放されていることを確認してください。
.env 環境変数ファイルの設定
サーバーの /~ ディレクトリに shiro という名前のフォルダを作成し、その中に .env ファイルを作成します:
cd && mkdir -p shiro && cd $_ && touch .env
.env に以下の内容を記入し、空白部分に適切な値を入力します:
Tip
開発者の公式説明によると、
NEXT_PUBLIC_GATEWAY_URL=${BASE_URL}、NEXT_PUBLIC_API_URL={BASE_URL}/api/v3とすべきですが、 しかし Next.js は${BASE_URL}のような動的連結の記法を解析する際に時々バカを起こします。エラーを避けるために、完全なURLを直接書き込むことをお勧めします。
BASE_URL=
NEXT_PUBLIC_API_URL=
NEXT_PUBLIC_GATEWAY_URL=
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/
TMDB_API_KEY=
GH_TOKEN=
1. ベースURL部分(直接書き込む方が安全)
# 你的网站主域名
BASE_URL=https://你的域名
# 后端 API 地址(直接写完整网址)
NEXT_PUBLIC_API_URL=https://api.你的域名/api/v3
# 网关地址
NEXT_PUBLIC_GATEWAY_URL=https://api.你的域名
2. Clerk 認証(サイトのバックエンドログイン)
これはログインサービスを提供するサードパーティサービスです。
- Clerk 公式サイト にアクセスしてアカウントを登録し、新しいアプリケーションを作成します。
- 次に、そのコントロールパネルで以下の 2 つのキーを見つけて入力します:
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxxxxxxxx (填你在Clerk获取的公钥)
CLERK_SECRET_KEY=sk_test_xxxxxxxxxxx (填你在Clerk获取的私钥)
# 下面这四个是登录跳转的路由,保持原样不用动它!
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/
3. その他の API
TMDB_API_KEY=
GH_TOKEN=ghp_xxxxxxxxxxxxxxxxx
TMDB_API_KEY:TMDB は映画データベースです。Yohaku ブログでは映画カードの表示をサポートしています。一時的に設定したくない場合は空欄のままでも構いません(空欄だと映画ページにデータが表示されませんが、サイト全体の動作には影響しません)。設定する場合は、themoviedb.org で API を申請して入力してください。GH_TOKEN:GitHub の動的表示用トークンです。前の手順で取得したghp_で始まる「マスターキー」をそのままここに入力できます。
GitHub Actions
次に、リポジトリの Actions ページに移動し、GitHub Actions を使ってプロジェクトのプリビルドを行います。
- 上部の Actions タブをクリックします。
- 「I understand my workflows, go ahead and enable them」というメッセージが表示されたら、緑色のボタンをクリックして有効にします。
- 左側メニューからワークフロー名 Build and Deploy をクリックします。
- 右側にある Run workflow ボタンを見つけてクリックし、ポップアップした緑色の Run workflow を再度クリックします。
Run workflow ボタンがない場合は、.github/workflows/ フォルダに移動し、deploy.yml を開き、右上の編集(鉛筆)ボタンをクリックし、その後 Commit changes をクリックします。
Note
保存(Commit)をクリックすると、システムがコードの更新(push)と認識し、自動的に Build and Deploy が開始されます。
トラブルシューティング
GitHub Action を使用して Yohaku をビルドする際にエラーが発生し、ログが次のように表示された場合:
0s
Run sh ./ci-release-build.sh
sh ./ci-release-build.sh
shell: /usr/bin/bash -e {0}
env:
HASH_FILE: build_hash
PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
BASE_URL: ***
NEXT_PUBLIC_API_URL: ***
NEXT_PUBLIC_GATEWAY_URL: ***
No projects matched the filters in "/home/runner/work/shiroi-deploy-action/shiroi-deploy-action"
./ci-release-build.sh: 8: cd: can't cd to apps/web/.next
Error: Process completed with exit code 2.
その場合、deploy.yml を以下のように修正してみてください:
Caution
この方法は、筆者がエラー分析と AI エージェントのアドバイスに基づいて行った修正であり、まだ発見されていないバグが存在する可能性があります。同様の問題に遭遇した場合は、作者に連絡するか、GitHub の Issue で問題を報告してください。
name: Build and Deploy
on:
push:
branches:
- main
# schedule:
# - cron: '0 3 * * *'
repository_dispatch:
types: [trigger-workflow]
permissions: write-all
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
HASH_FILE: build_hash
SOURCE_REPO: innei-dev/Yohaku
BUILD_COMMAND: pnpm --filter @yohaku/web build:ci
STANDALONE_SUBPATH: standalone/apps/web
jobs:
prepare:
name: Prepare
runs-on: ubuntu-latest
if: ${{ github.event.head_commit.message != 'Update hash file' }}
outputs:
hash_content: ${{ steps.read_hash.outputs.hash_content }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Read HASH_FILE content
id: read_hash
run: |
content=$(cat ${{ env.HASH_FILE }}) || true
echo "hash_content=$content" >> "$GITHUB_OUTPUT"
check:
name: Check Should Rebuild
runs-on: ubuntu-latest
needs: prepare
outputs:
canceled: ${{ steps.use_content.outputs.canceled }}
steps:
- uses: actions/checkout@v4
with:
repository: innei-dev/Yohaku
token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT
fetch-depth: 0
lfs: true
submodules: recursive
- name: Use content from prev job and compare
id: use_content
env:
FILE_HASH: ${{ needs.prepare.outputs.hash_content }}
run: |
file_hash=$FILE_HASH
current_hash=$(git rev-parse --short HEAD)
echo "File Hash: $file_hash"
echo "Current Git Hash: $current_hash"
if [ "$file_hash" == "$current_hash" ]; then
echo "Hashes match. Stopping workflow."
echo "canceled=true" >> $GITHUB_OUTPUT
else
echo "Hashes do not match. Continuing workflow."
fi
build:
name: Build artifact
runs-on: ubuntu-latest
needs: check
if: ${{needs.check.outputs.canceled != 'true'}}
strategy:
matrix:
node-version: [lts/*]
outputs:
sha_short: ${{ steps.store.outputs.sha_short }}
branch: ${{ steps.store.outputs.branch }}
steps:
- uses: actions/checkout@v4
with:
repository: ${{ env.SOURCE_REPO }}
token: ${{ secrets.GH_PAT }} # `GH_PAT` is a secret that contains your PAT
fetch-depth: 0
lfs: true
submodules: recursive
- name: Checkout LFS objects
run: git lfs checkout
- uses: pnpm/action-setup@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'pnpm'
- uses: jongwooo/next-cache@v1
- name: Install dependencies
run: pnpm install
- name: Build project
env:
BASE_URL: ${{ secrets.BASE_URL }}
NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
NEXT_PUBLIC_GATEWAY_URL: ${{ secrets.NEXT_PUBLIC_GATEWAY_URL }}
run: |
${{ env.BUILD_COMMAND }}
cd apps/web/.next
rm -rf cache
cp -r ../public ./standalone/public
mv ./static ./standalone/apps/web/.next/static
cd ./standalone
echo ';process.title = "Yohaku (NextJS)"' >> server.js
cd "$GITHUB_WORKSPACE"
mkdir -p assets
rm -f assets/release.zip
(cd apps/web/.next && zip --symlinks -r "$GITHUB_WORKSPACE/assets/release.zip" ./* -x "dev/*" -x "cache/*")
# - uses: actions/upload-artifact@v4
# with:
# name: dist
# path: assets/release.zip
# retention-days: 7
- name: Cache Build Artifacts
id: cache-primes
uses: actions/cache/save@v4
with:
path: assets
key: ${{ github.run_number }}-release
- name: Store artifact commit version
shell: bash
id: store
run: |
sha_short=$(git rev-parse --short HEAD)
branch_name=$(git rev-parse --abbrev-ref HEAD)
echo "sha_short=$sha_short" >> "$GITHUB_OUTPUT"
echo "branch=$branch_name" >> "$GITHUB_OUTPUT"
deploy:
name: Deploy artifact
runs-on: ubuntu-latest
needs: build
steps:
# - name: Download artifact
# uses: actions/download-artifact@v4
# with:
# name: dist
- name: Restore cached Build Artifacts
id: cache-primes-restore
uses: actions/cache/restore@v4
with:
path: |
assets
key: ${{ github.run_number }}-release
- name: Move assets to root
run: mv assets/release.zip release.zip
- name: Create PM2 config file
run: |
cat > ecosystem.config.js << 'EOF'
module.exports = {
apps: [
{
name: 'Shiroi',
script: './server.js',
cwd: __dirname,
exec_mode: 'fork',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '180M',
env: {
NODE_ENV: 'production',
HOSTNAME: '0.0.0.0',
PORT: process.env.PORT || 2323,
},
log_date_format: 'YYYY-MM-DD HH:mm:ss',
merge_logs: true,
},
],
};
EOF
- name: copy file via ssh password
uses: appleboy/[email protected]
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
password: ${{ secrets.PASSWORD }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
source: 'release.zip'
target: '/tmp/yohaku'
- name: copy PM2 config via ssh password
uses: appleboy/[email protected]
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
password: ${{ secrets.PASSWORD }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
source: 'ecosystem.config.js'
target: '/tmp/yohaku'
- name: Exec deploy script with SSH
uses: appleboy/ssh-action@master
with:
command_timeout: 5m
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
password: ${{ secrets.PASSWORD }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
script: |
set -e
source $HOME/.bashrc
basedir=$HOME/yohaku
workdir=$basedir/${{ github.run_number }}
mkdir -p $workdir
mkdir -p $basedir/.cache
mv /tmp/yohaku/release.zip $workdir/release.zip
install -m 644 /tmp/yohaku/ecosystem.config.js $basedir/ecosystem.config.js
cd $workdir
unzip -qq -o $workdir/release.zip
rm -r /tmp/yohaku
rm -rf $workdir/${{ env.STANDALONE_SUBPATH }}/.env
ln -s $HOME/yohaku/.env $workdir/${{ env.STANDALONE_SUBPATH }}/.env
export NEXT_SHARP_PATH=$(npm root -g)/sharp
# https://github.com/Unitech/pm2/issues/3054
# symlink workdir node entry file to basedir
ln -sf $workdir/${{ env.STANDALONE_SUBPATH }}/server.js $basedir/server.js
mkdir -p $workdir/${{ env.STANDALONE_SUBPATH }}/.next
rm -rf $workdir/${{ env.STANDALONE_SUBPATH }}/.next/cache
ln -sf $basedir/.cache $workdir/${{ env.STANDALONE_SUBPATH }}/.next/cache
cd $basedir
if pm2 describe Shiroi >/dev/null 2>&1; then
pm2 reload ecosystem.config.js --update-env
else
pm2 start ecosystem.config.js --update-env
fi
rm $workdir/release.zip
pm2 save
echo "Deployed successfully"
- name: After deploy script
run: |
hash=${{ needs.build.outputs.sha_short }}
# curl -X "POST" "https://mx.innei.in/api/v2/fn/shiro/new-version-hook" -H 'Content-Type: application/json' -d "{\"hash\": \"$hash\", \"key\": \"\"}"
${{ secrets.AFTER_DEPLOY_SCRIPT }}
store:
name: Store artifact commit version
runs-on: ubuntu-latest
needs: [deploy, build]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token
fetch-depth: 0 # otherwise, you will failed to push refs to dest repo
# Get the commit version from the build job
- name: Use outputs from build
env:
SHA_SHORT: ${{ needs.build.outputs.sha_short }}
BRANCH: ${{ needs.build.outputs.branch }}
run: |
echo "SHA Short from build: $SHA_SHORT"
echo "Branch from build: $BRANCH"
- name: Write hash to file
env:
SHA_SHORT: ${{ needs.build.outputs.sha_short }}
run: echo $SHA_SHORT > ${{ env.HASH_FILE }}
- name: Commit files
run: |
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add ${{ env.HASH_FILE }}
git commit -a -m "Update hash file"
- name: Push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}
MixSpace での設定
Note
この部分に関する公式ドキュメント:
Mix Space の管理画面にアクセスし、「設定とクラウド関数」ページに移動し、右上の追加ボタンをクリックし、編集ページで以下の設定を入力します:
- 名称:
shiro - 参照:
theme - データ型:
JSON - データ(ここでは公式サンプルデータをテンプレートとします):
{
"footer": {
"otherInfo": {
"date": "2020-{{now}}",
"icp": {
"text": "萌 ICP 备 20236136 号",
"link": "https://icp.gov.moe/?keyword=20236136"
}
},
"linkSections": [
{
"name": "关于",
"links": [
{
"name": "关于本站",
"href": "/about-site"
},
{
"name": "关于我",
"href": "/about"
},
{
"name": "关于此项目",
"href": "https://github.com/innei/Shiro",
"external": true
}
]
},
{
"name": "更多",
"links": [
{
"name": "时间线",
"href": "/timeline"
},
{
"name": "友链",
"href": "/friends"
},
{
"name": "监控",
"href": "https://status.innei.in/status/main",
"external": true
}
]
},
{
"name": "联系",
"links": [
{
"name": "写留言",
"href": "/message"
},
{
"name": "发邮件",
"href": "mailto:[email protected]",
"external": true
},
{
"name": "GitHub",
"href": "https://github.com/innei",
"external": true
}
]
}
]
},
"config": {
"color": {
"light": [
"#33A6B8",
"#FF6666",
"#26A69A",
"#fb7287",
"#69a6cc",
"#F11A7B",
"#78C1F3",
"#FF6666",
"#7ACDF6"
],
"dark": [
"#F596AA",
"#A0A7D4",
"#ff7b7b",
"#99D8CF",
"#838BC6",
"#FFE5AD",
"#9BE8D8",
"#A1CCD1",
"#EAAEBA"
]
},
"bg": [
"/static/images/F0q8mwwaIAEtird.jpeg",
"/static/images/IMG_2111.jpeg.webp.jpg"
],
"custom": {
"css": [],
"styles": [],
"js": [],
"scripts": []
},
"site": {
"favicon": "/innei.svg",
"faviconDark": "/innei-dark.svg"
},
"hero": {
"title": {
"template": [
{
"type": "h1",
"text": "Hi, I'm ",
"class": "font-light text-4xl"
},
{
"type": "h1",
"text": "Innei",
"class": "font-medium mx-2 text-4xl"
},
{
"type": "h1",
"text": "👋。",
"class": "font-light text-4xl"
},
{
"type": "br"
},
{
"type": "h1",
"text": "A NodeJS Full Stack ",
"class": "font-light text-4xl"
},
{
"type": "code",
"text": "<Developer />",
"class": "font-medium mx-2 text-3xl rounded p-1 bg-gray-200 dark:bg-gray-800/0 hover:dark:bg-gray-800/100 bg-opacity-0 hover:bg-opacity-100 transition-background duration-200"
},
{
"type": "span",
"class": "inline-block w-[1px] h-8 -bottom-2 relative bg-gray-800/80 dark:bg-gray-200/80 opacity-0 group-hover:opacity-100 transition-opacity duration-200 group-hover:animation-blink"
}
]
},
"description": "An independent developer coding with love."
},
"module": {
"activity": {
"enable": true,
"endpoint": "/fn/ps/update"
},
"donate": {
"enable": true,
"link": "https://afdian.net/@Innei",
"qrcode": [
"/static/images/20191211132347.png",
"/static/images/0424213144.png"
]
},
"bilibili": {
"liveId": 1434499
}
}
}
}
ボタンをクリックして設定を保存します。
最後に
今回の Yohaku のデプロイプロセスは、本質的には現代の CI/CD ワークフローに対する実践的な演習でした。宝塔パネルの環境修正から GitHub Actions の深いデバッグに至るまで、Error を解決するたびに自身の知識体系の再構築が行われました。
デプロイの成功は第一歩に過ぎません。本当の楽しみはその後の創作やカスタマイズにあります。この記事を参考にしている途中で新たな「謎の問題」に遭遇した場合は、コメント欄で交流したり、直接作者の Innei に質問してください。この記事が皆さんの個人スペース構築の際に重要な助けとなることを願っています。
