Serverlessのすゝめ――自分でサーバーを運用して分かった「管理からの自由」

Serverless の方が楽なのに、どうしてわざわざ自分でサーバーを管理するの?

この記事の結論

Serverless しか使っていなかった人間が自分で物理サーバーを運用してみた結果、Serverless がどれだけ面倒を肩代わりしていたか が分かりました。その落差の記録です。

  • Serverless が隠していたのは「OS 更新」「再起動」「デプロイ基盤」の面倒そのもの
  • オンプレで手に入るのは 今の状態が SSH で見えること、そして 1 台に集約できる強さ
  • 代わりに差し出すのは、責任を全部自分で持つこと

比べた 2 つの自由はこうです。

Serverless オンプレ
得られる自由 管理からの自由 構成の自由
代わりに失うもの 実行環境の自由度 管理されない安心
詰まりどころ 起動待ち・権限・課金グラフ OS 更新・再起動・責任の所在

そして、この記事で一番伝えたいことを先に書いておきます。

どちらが優れているかの話ではなく、「何から自由になりたいか」の話です。 Serverless を選ぶのは管理から自由になるため、オンプレを選ぶのは構成から自由になるため。自分で運用してみるまで、僕は前者の自由を自由だと認識できていませんでした。

この記事でいう「オンプレ」は、企業の大規模なデータセンターではなく、僕が自分で管理している物理サーバーを指します。自宅サーバーという言葉に少しでもロマンを感じる人には、たぶん分かってもらえると思います。


1. Serverlessとは何か

Serverlessとは、サーバーが存在しない仕組みではありません。

サーバーは当然どこかで動いています。

ただし、OSの更新、物理マシンの故障、プロセスの再起動、アクセス量に応じたスケールなどを、アプリケーション開発者が直接面倒を見る場面が減ります。

僕はServerlessを、こう理解しています。

サーバーを考える範囲を減らす仕組み

AWS LambdaやCloud Run functionsのようなFunction as a ServiceだけがServerlessではありません。

VercelやCloud Runのように、アプリやコンテナをデプロイすると実行環境やスケーリングを管理してくれるサービスも、広い意味でServerlessとして扱われます。

2. 今回比べる環境

実際に僕が使っている環境は、こうです。

自分のサーバー Serverless
実行環境 Xeon E3-1200 v2 / 32GB RAM Vercelの無料枠
データ SSD 1TB + HDDたくさん Neon / Supabaseの無料枠
管理 Ubuntu Server 20.04から自分で管理 各プラットフォームに任せる

なお、Ubuntu 20.04 LTSの標準セキュリティメンテナンスは、2025年5月に終了しています。

2026年現在も使い続けるなら、Ubuntu ProのESMを有効にするか、サポート中のLTSへ移行する必要があります。

参考: Ubuntu release cycle

これは性能ベンチマークではありません。

物理サーバー1台と複数のマネージドサービスでは、そもそも比較する単位が違います。

ここで比べたいのは、「どこまで自分が管理するのか」です。

また、無料枠の内容は変更されることがあります。

実際に構成を選ぶときは、各サービスの最新の料金・制限を確認してください。

3. 実例は「やすみ?」

ここからは、僕が実際に運用している「やすみ?」を例に考えます。

「やすみ?」はDockerコンテナとして自分のサーバー上で動いています。

構成を単純化すると、こうです。

flowchart LR
    User["ユーザー"] --> CF["Cloudflare"]
    CF --> Tunnel["Cloudflare Tunnel"]
    Tunnel --> App["やすみ?<br>Dockerコンテナ"]
    App --> DB["データベース"]

アプリのコードだけでなく、Docker、Ubuntu、ネットワーク、ストレージ、物理マシンまでが僕の管理範囲です。

ここからが、Serverlessと大きく違うところです。

4. CI/CDの前に路線を引く

コードをGitHubにpushしたら自動でデプロイされる。

結果だけ見ると、オンプレでもServerlessでも同じです。

ただし、オンプレでそこに辿り着くまでには、先に「路線」を引かなければなりません。

正直、オンプレでCI/CD環境を整えるのはかなり面倒です。

flowchart LR
    Push["GitHubへpush"] --> Actions["GitHub Actions"]
    Actions --> Runner["Self-hosted Runner"]
    Runner --> Build["Docker Build"]
    Build --> Deploy["docker compose up"]

僕はGitHub ActionsのSelf-hosted Runnerを使っています。

ワークフローを単純化すると、こうです。

name: deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: [self-hosted, linux, x64]
    steps:
      - uses: actions/checkout@v4
      - run: docker compose build
      - run: docker compose up -d --remove-orphans

ただし、このYAMLだけで完成ではありません。

実際には、次のものを管理する必要があります。

  • Runnerアプリの導入と更新
  • Runnerを動かすユーザーの権限
  • Dockerソケットへのアクセス
  • Secretsの保管
  • Runner自体の死活監視
  • 失敗したデプロイのロールバック

特にSelf-hosted Runnerは、GitHubから受け取ったコードを自分のマシン上で実行します。

そのため、実行を許可するリポジトリやワークフローを絞る必要があります。

GitHubも、Self-hosted Runnerは非公開リポジトリで使うことを推奨しています。

公開リポジトリのforkから、危険なコードが実行される可能性があるためです。

参考: Managing access to self-hosted runners using groups - GitHub Docs

さらに、RunnerからDockerを操作できるようにすると、Runnerは非常に強い権限を持ちます。

Docker公式ドキュメントでは、dockerグループへの所属はrootレベルの権限を与えると警告しています。

参考: Linux post-installation steps for Docker Engine - Docker Docs

少なくとも、実行可能なリポジトリの制限、mainブランチの保護、デプロイ用Secretsの最小権限化は考えたいところです。

もっと強く分けたいなら、デプロイ専用マシンや使い捨てRunnerという選択肢もあります。

ここまで作れば、pushだけでデプロイできるのでとても便利です。

一度作れば便利です。

でも、そこまでの路線を引くのが大変です。

そして、その面倒な路線を引いたのも、壊れたときに直すのも自分です。

VercelなどのGitHub連携が充実したプラットフォームでは、この路線の多くが最初から用意されています。

Serverlessの良さは、GitHub連携を簡単に設定できることだけではありません。

CI/CDを支えるマシンやプロセスも含めて、自分で管理するレイヤーが少ない。

これが大きいです。

5. 「再起動するだけ」が結構重い

オンプレでは、OS更新などでサーバーの再起動が必要になります。

再起動すると、そのサーバー上のサービスはまとめて止まります。

そして再起動後には、少なくとも次を確認します。

  • Dockerコンテナは正常に戻ったか
  • cloudflared は起動したか
  • DBは応答するか
  • サイトは外部から開けるか
  • ログに異常がないか
  • ダウンタイムはどれくらいだったか

Docker Composeのrestart: unless-stopped、ヘルスチェック、外形監視などを組み合わせれば、多くの確認は自動化できます。

たぶん、あれもこれももっと自動化できます。

でも、やっぱり面倒です。

その自動化を作って、動作を確認して、壊れたら直すのも自分だからです。

自分でサーバーを運用すると、「自動化すれば解決」の後ろにも運用があることがよくわかります。

Serverlessでもプラットフォーム側の障害は起きます。

ただし、少なくとも物理マシンやホストOSの再起動を、利用者が直接操作することはほぼありません。

6. コストは無料枠だけで決まらない

Serverlessは、小規模なら無料枠に収まるサービスも多く、個人開発の最初の一歩と相性が良いです。

一方で、アクセス、実行時間、データ転送量、ストレージなどが増えると、使用量に応じて費用が発生します。

オンプレは逆です。

最初に本体、ストレージ、必要ならUPSなどを購入します。

その後も、電気代、回線費用、故障時の交換費用がかかります。

電力の概算は次の式で出せます。

消費電力[W] × 24時間 × 30日 ÷ 1000 = 1か月の消費電力[kWh]

たとえば60Wで動き続けた場合は、約43.2kWh/月です。

これに契約している電力料金の単価を掛けると、電気代の目安になります。

なお、僕のサーバーは学校に置かせてもらっているため、僕自身は電気代を直接払っていません。

もちろん、オンプレの電気代が無料という意味ではありません。

そのため、電気代の実感については、正直なところ僕はあまり語れません。

また、自分の作業時間も忘れやすいコストです。

数十分の障害対応や更新作業も、積み上がれば大きくなります。

7. ServerlessでもDockerは使える

この記事のドラフトに、僕は「ServerlessでDockerを使えるサービスを見たことがない」と書いていました。

僕の中では、それくらい「Dockerを好きに使えること」がオンプレの強みとして大きかったからです。

ただ、調べてみると、その書き方は正確ではありませんでした。

「Dockerを使いたいからオンプレ」という言い方は、半分正しくて、半分間違っています。

たとえばGoogle Cloud Runは、コンテナイメージをデプロイできるServerlessプラットフォームです。

公式ドキュメントでも、インフラ管理を抽象化するServerlessなサービスとして説明されています。

参考: What is Cloud Run - Google Cloud Documentation

違いは、Dockerイメージを使えるかどうかだけではありません。

コンテナ実行型のServerless 自分のサーバー
コンテナイメージ デプロイできる 実行できる
ホストOS 触れない 触れる
Dockerデーモン プラットフォームが管理 自分で管理
任意のCompose構成 制約がある 自由に組める
特権操作 原則できない 自分次第
常駐プロセス サービス仕様に依存 自由に動かせる

つまり、オンプレの強みは「Dockerが使える」ことより、Dockerの下にあるOSやネットワークまで自分で触れることです。

自分のサーバーであれば、デプロイ基盤やジョブキューを組み合わせて、Vercelのような「コードを送れば動くプラットフォーム」自体を作ることもできます。

一方、一般的なPaaSでは、そのPaaSを支える下の層には触れません。

ここは、アプリを作るときには嬉しい制約です。

プラットフォームそのものを作りたいときには、越えられない壁になります。

8. SSHで今が見える

自分のサーバーには、SSHで入れます。

docker ps
htop
journalctl -u docker
psql yasumi

コンテナは生きているか。

CPUやメモリは足りているか。

サービスのログに異常はないか。

データベースは応答するか。

気になったことをその場で確認できるのは、とても楽しいです。

Serverlessでは普段触れないような低いレイヤーまで降りて、自分で状態を見て、自分で考えられます。

これが面白いです。

オンプレならVercelのようなサービスそのものを作れますが、Vercelの上でVercelを作ろうとすると、できたとしてもかなり面倒です。

もちろん、本番環境の設定ファイルをその場で直す運用は、変更履歴が残らず再現性も失われます。

触れることと、触ってよいことは別です。

トラブルシュートはSSHで行い、永続的な修正はコードや構成管理に戻すのが理想です。

9. Docker + Cloudflare Tunnel

僕の構成では、cloudflaredもDockerコンテナとして動かしています。

Cloudflare Tunnelは、サーバー側のcloudflaredからCloudflareに向けてアウトバウンド接続を作ります。

flowchart LR
    Internet["Internet"] --> CF["Cloudflare"]
    CF --> Tunnel["Cloudflare Tunnel"]
    Tunnel --> App1["app1:3000"]
    Tunnel --> App2["app2:8080"]
    Tunnel --> API["api:4000"]

これにより、各アプリのポートをルーターから直接インターネットへ開放せずに公開できます。

Cloudflareの公式ドキュメントでも、TunnelはオリジンからCloudflareへ作るアウトバウンドの経路として説明されています。

ファイアウォールでインバウンド通信を閉じ、cloudflaredのアウトバウンド通信だけを許可する構成も取れます。

現在の公式ドキュメントでは、Tunnelの運用にTCP/UDPの送信ポート7844を許可するよう案内されています。

参考:

ただし、Tunnelを使えばセキュリティ対策が終わるわけではありません。

  • 公開するホスト名とサービスの範囲
  • Tunnelトークンの保管
  • アプリ側の認証・認可
  • Cloudflare Accessなどのアクセス制御
  • オリジンとcloudflaredの更新

こうした運用は、依然として自分の責任です。

10. 1台に集約する強さと弱さ

CPU、RAM、ストレージ、回線に余裕があれば、1台のサーバーに複数のサービスを載せられます。

個人開発では、「とりあえずこのサーバーに載せる」ができるのはとても便利です。

まるでサイトをいくらでも生やせるような感覚があります。

しかし、物理的には1台です。

flowchart TD
    Server["1台のサーバー"] --> A["サービス A"]
    Server --> B["サービス B"]
    Server --> C["サービス C"]
    Failure["電源・OS・ストレージの障害"] -.-> Server

サーバーが落ちれば、その上のサービスがまとめて落ちます。

再起動やメンテナンスの影響も、全サービスに広がります。

CPUやRAMも共有するため、1つのサービスの負荷が他に影響することもあります。

「たくさん載せられる」と「障害の影響範囲が大きい」は、同じ構成の表裏です。

11. 責任まで全部持つのはしんどい

最近は、オンプレからクラウドへ移行する企業が多くあります。

クラウドを使えば、物理ハードウェアやデータセンター、マネージドサービスのOSなどは、クラウド事業者の管理範囲に移ります。

ドラフトを書いたとき、僕は「クラウド側に責任を押し付けられるのもメリットなのでは」と考えました。

サービスが落ちたときに、ハードウェアもOSもすべて自分の責任になる状態は、正直しんどいです。

「ここから下はクラウド側が見てくれる」と言えるのは、利用者からすればとても気が楽です。

この感覚自体は、今も間違っていないと思います。

ただし、「障害や情報漏洩が起きてもクラウド側の責任にできる」とまで考えるのは危険です。

クラウドでは、一般に共同責任モデルで責任範囲を分けます。

AWSの説明では、クラウド基盤のハードウェア、ネットワーク、施設などはAWSが保護します。

一方、顧客は利用するサービスに応じて、データ、IAM、暗号化、アプリケーション、設定などに責任を持ちます。

参考: Shared responsibility - AWS Well-Architected Framework

管理対象 Serverless / マネージドサービス 自分のサーバー
物理ハードウェア 事業者が管理 自分が管理
ホストOS 事業者が管理 自分が管理
アプリと依存関係 利用者が管理 利用者が管理
IAM / Secrets / 設定 利用者が管理 利用者が管理
データの分類・保護 利用者が管理 利用者が管理

感情としては、「クラウド側に押し付けたい」です。

ただ、仕組みとして正確に言うなら、クラウド移行の利点は責任の押し付けではありません。

事業者が引き受ける管理範囲を契約と仕様で明確にし、自分たちが担う範囲を減らすことです。

オンプレにはロマンがあります。

セキュリティも法律も運用責任も完全に無視してよい架空の世界なら、僕は顧客情報すら自分のサーバーで持ちたいくらいです。

それくらい、自分のマシンで全部を動かすことに魅力を感じます。

もちろん、現実で顧客情報や機密情報を扱うなら、「ロマンがある」だけで構成を選んではいけません。

自分で運用するにしてもクラウドを使うにしても、脅威モデル、アクセス制御、暗号化、バックアップ、復旧手順、運用体制まで考える必要があります。

12. 結局どちらを選ぶのか

Serverlessは万能ではありません。

逆に、オンプレやVPSにすればすべてが幸せになるわけでもありません。

Serverlessを選びやすい オンプレ / VPSを選びやすい
Webアプリ・Web API 長時間実行する処理
Bot・イベント駆動処理 常駐プロセス
Cron処理 大容量ストレージ
アクセス量が読めないサービス 特殊なミドルウェアが必要な構成
インフラ運用よりアプリ開発に集中したい OSやネットワークを自由に触りたい

なお、これらは傾向です。

たとえばCloud Runにはジョブやワーカープールがあり、Serverlessでも長時間処理やバックグラウンド処理に対応できる場合があります。

「Serverlessだから」「オンプレだから」だけで決めず、実行時間、ストレージ、スケール、ネットワーク、データ保護の要件から選ぶべきです。

13. 2つの自由

実際に両方を使ってみて、Serverlessとオンプレは、異なる自由をくれるものだと思うようになりました。

Serverlessは「管理からの自由」

Serverlessでは、OS、物理ハードウェア、実行プロセス、スケーリングなどの多くを任せられます。

つまり、管理から自由になれます。

サービスを作りたいだけなら、この自由はとても大きいです。

オンプレは「制約からの自由」

オンプレでは、OSからネットワークまで好きなように構成できます。

つまり、プラットフォームの制約から自由になれます。

ただし、自由にしたものは、すべて自分で面倒を見る必要があります。

その面倒は、本当に面倒です。

でも、サーバーを触ること自体が目的なら、その面倒さえも楽しさになります。

14. まとめ

Serverlessを使えば、サーバーの面倒を見る範囲を減らして、サービス作りに集中できます。

オンプレを使えば、サーバーの面倒を見ることそのものを楽しめます。

やっぱりオンプレは面倒です。

それでも面白いので、やめられません。

最後に、最初の疑問に戻ります。

Q. こんなに面倒なのに、なぜオンプレを使うの?

A. 面白いから。

そして、僕はこれからも両方を使います。

Serverlessでサービスを作り、オンプレでサーバーを楽しみます。