strt's blog

🗒🔨🙍

自宅サーバに自作Webアプリをデプロイできるようにした

2025/01/27

「知ってるけど触る機会なかったな」とか「0から触ってないな」という技術が結構溜まっていた、 気軽にWebアプリを料金気にせずデプロイできる環境をの雛形を作っておきたかったというモチベーションから、色々触ったことないものを試しながら、自宅サーバにWebアプリをデプロイできるようにしたなったので備忘の記録です。

何をやったのか

  • Cloudflare Tunnelを使って自宅サーバを外部公開
  • Todoアプリの作成
  • Githubのmainブランチにmergeしたら、自宅サーバ側で更新が走るよう修正

Cloudflare Tunnelを使って自宅サーバを外部公開

これはかなり簡単で、このドキュメントに従い公開するだけで済みます。

ただ、本当に全部のところからアクセスを受け付けたいわけではないため、Zero Trustの方で以下の設定を実施しました。

  • ルールグループ
    • 許可・拒否の条件を決める
      • 楽そうな「指定メールアドレスのみ、OTP認証を実施する」という条件にしました。
    • ポリシー
      • ルールグループを組み合わせたりして、許可/拒否する設定をする
        • 上記の条件で、OTP認証が通った場合のみアクセスが許可される、という条件にしました。
        • また、セッションの有効期限も決められます。
  • アプリケーション
    • 特定のアプリケーションとポリシーを紐づける

といった形で設定できます。

Todoアプリの作成

ここは別に何でもいいと言えばいいのですが、気になっていたT3 Stackに沿って作成しました。 Next.js TailwindCSS Prisma tRPC NextAuthって感じです。あとは相性良さそうなshadcn/uiを使いました。

基本的に構築自体はCreate T3 Appで終わりですが、おうちサーバで簡単に動かせるよう、一旦全部dockerで動かすことにしました。

DBとアプリケーションサーバを動かすためのdockerまわりをCreate T3 Appのドキュメントを読みながら作っていましたが、nodeが20系のイメージを使って書かれていたり、Prisma+マルチステージングビルドはOSがalpine/debianなど差分が出ているとエラー吐いたりなどがあったので、使うイメージを統一する等の作業がありました。

あと、しっかりマルチステージングビルドすると開発には支障がでるので、ソースファイルをmountしてnext devで起動する開発環境用のファイルを準備も実施しました。 その際はTurbopackでのビルドでエラーを吐くなどの事象もあり、根本原因は不明なのですがWebpackで渋々ビルドすることで問題解消したり、という側面もありました。

一通り環境構築後は、今回はVercelのv0に任せてUIを組んでみましたが、そこそこ良いですね。 正直tRPCとの繋ぎ込み部分に関しては自分で書いた方が体感良かった感じですが、CSSで時間が持って行かれないのが本当に楽です。 UI面はv0使って、機能面は自分で組み込む、というのが楽だったと思います。 Boltだとまた感覚変わるのかはみてみたいです。

また、T3 Stack自体は慣れちゃうとサクサクかける印象です。 ただ、tRPC/RPC自体はまだポテンシャルを引き出せていない(ToDoリストのCRUDなら別にRESTでも良い)という感触なので、もうちょっと触りたい感じです。

Githubのmainブランチにmergeしたら、自宅サーバ側で更新が走るよう修正

まぁGithub Actionsでございます。が、「Self-hosetd-runner」を追加すると、自宅サーバ内部でポート解放などもなくCICDが流せるそうなので、試してみました。

ここの手順に沿って自宅サーバ側にRunnerを入れるだけで使えるようになりました。 が、コンソールで起動しっぱなしも辛いので、サービスとして動かせるようにすると良い感じです。

あとは、workflowのymlで以下の感じで書くだけです。

name: Deploy
on:
  push:
  branches:
  - main

jobs:
  deploy:
  runs-on: self-hosted
  environment: production

steps:
  - name: Check out code
    uses: actions/checkout@v3

  - name: Generate .env file
  # 略。環境変数をGithub Secretから吐かせてファイルを作っています

  - name: Start services with Docker Compose
    run: |
      docker compose -f docker-compose.yml up --build -d
      # 開発環境のcomposefileをoverrideしてるので、本番環境用のもののみ流す

感想

色々「触ってないなぁ」という技術をあっちこっち触って使える状態になったのは大きかったです。これでお金のことを考えずに自分しか使わないアプリも出しやすくなります。

RPCはRESTとどういった使い分けをすべきかなどは追って行った方が良さそうという感触です。 特性的にはチャットアプリなどが向いてそうなので、試してみたい所存です。

あと、NextAuthは使いやすかったですね。今回はCloudflare Tunnelsと役割被ってる間はちょっとありますが、アプリケーション側の認証認可コントロールしやすいなと思いました。

余談

自作アプリとは別に、「Portainer」と「Taiga」を自宅サーバでコンテナとして動かしています。

また、現状ではデプロイがdocker compose up --buildとかいう状態なので、コンテナレジストリとかコンテナオーケストレーションツールを使いたい気持ちになっています。