セルフホスト型Calendly代替4選を比較
Cal.com、Easy!Appointments、Rallly、DayOtterを比較します。二方向のカレンダー同期と外向きメール送信に加え、VPSのポート25制限も確認できます。
短い回答
VPS 上の内部ツールにはない役割を、セルフホスト型の Calendly 代替サービスは 1 つ担う必要があります。外部からの利用に対応することです。予約ページそのものが製品です。初日から実際のドメイン名と TLS(transport layer security)が必要です。また、サーバーの存在を知らない相手にもメールを届けられなければなりません。
現実的な選択肢は 4 つです。Cal.com は Calendly に最も近く、個人コンサルタントの第一候補です。Easy!Appointments は軽量な PHP と MySQL のアプリケーションで、1 GB VPS でも問題なく動作します。Rallly はグループ投票ツールで、予約ページはありません。DayOtter は最も新しい選択肢で、前段に確認優先のアシスタントを配置した AGPLv3 のスケジューリングプラットフォームです。
実際に運用できるかどうかは、2 つの質問で決まります。現在利用しているカレンダーと双方向に同期できますか。メールを送信できますか。ほとんどのセルフホスト型予約環境では、2 つ目の点がひそかに失敗するため、先に扱います。
送信メールで問題が発生します
予約確認メールが見知らぬ相手の受信トレイに届くことがあります。これは Gmail や Microsoft 365 に到達するトランザクションメールであり、受信側は送信元 IP アドレスと DNS レコードを基に送信元を評価します。
VPS から直接送信しても、ほとんどの場合は機能しません。多くのプロバイダーは、新規アカウントでの外向き TCP ポート 25 をブロックするため、接続がハングしてタイムアウトします。ポート 25 が開いている場合でも、新しい VPS のアドレスには送信履歴がありません。そのため、大手受信サービスは、未知のホスティング範囲にあるアドレスを不審なものとして扱います。予約はデータベースに記録され、ページには確認済みと表示されるのに、メールは誰にも届きません。サーバー側では問題がないように見えるため、予約者が来なかったことを顧客が数週間後に初めて発見するケースが多くなります。
リレーを使用してください。トランザクションメールのプロバイダーであれば利用でき、アプリケーションに必要なのはホスト名、ポート、ユーザー、パスワードだけです。アプリケーションの設定を変更する前に、ポートへ到達できることを確認してください。
nc -vz -w 5 "$SMTP_HOST" 587succeeded 行は経路が開いていることを示します。ハング、または Connection refused の場合は、ネットワークレベルでポートがブロックされています。この場合、.env をどれだけ編集しても解決しません。リレーが 587 または 465 で待ち受けるのは、ポート 25 が頻繁にブロックされるためです。
各プロジェクトは、それぞれ異なる方法でリレーを利用します。Cal.com は EMAIL_FROM、EMAIL_SERVER_HOST、EMAIL_SERVER_PORT、EMAIL_SERVER_USER、EMAIL_SERVER_PASSWORD を読み込み、代わりに RESEND_API_KEY も受け付けます。.env.example には注意してください。出荷時の .env.example は、ポート 1025 上の localhost を EMAIL_SERVER_HOST に指定します。これはローカル開発用のメールボックスです。デフォルトのままにすると、アプリケーションはエラーを出さずにメールを存在しない宛先へ送信します。Rallly は SMTP_HOST、SMTP_PORT、SMTP_USER、SMTP_PWD を使用します。DayOtter は SMTP 設定または Resend key を使用します。Easy!Appointments はアプリケーションから通知を送信するため、実際の予約を受け付ける前に、設定ページで同じリレーを指定してください。
続いて、リレーから提供された DNS レコードを公開します。SPF (sender policy framework) レコードは、ドメインに代わって送信できるサーバーを指定します。DKIM (domainkeys identified mail) key は各メッセージに署名し、受信側が内容の改ざんがないことを確認できるようにします。両方の認証に成功したら、DMARC (domain-based message authentication, reporting and conformance) ポリシーを追加します。大手プロバイダーの実在するアドレスへテスト予約を送信し、メッセージヘッダーを開いて、認証行が pass になっていることを確認してください。送信できない予約ページは、予約ページがない場合よりも深刻です。送信失敗が気付かれないままになるためです。
双方向で同期できるカレンダー連携
同期には2つの方向があり、それぞれ別々に失敗します。読み取り方向は空き状況の取得です。アプリが既存の予定を確認できなければ、すでに予定が入っている時間帯を予約可能として提示します。書き込み方向は予約の登録です。確定したイベントは、予約ツール内だけでなく、実際に確認するカレンダーにも表示される必要があります。
Google Calendar と Microsoft 365 は、self-hosted 環境では1つ条件がありますが、どちらの方向にも対応します。OAuth(オープン認可)クライアントは自分で作成します。ホスト型製品の client ID はソースコードに含まれていないためです。Cal.com では、Google Cloud console からダウンロードした JSON を .env 内の GOOGLE_API_CREDENTIALS に保存します。DayOtter でも、Google と Microsoft の OAuth 認証情報を同じ方法で設定します。
開始前に知っておくべき問題が2つあります。1つ目は、登録する redirect URI が、scheme と末尾のパスを含めて公開 URL と完全に一致している必要があることです。一致しない場合、Google は同意画面で redirect_uri_mismatch を表示して接続を停止します。2つ目は、Google project の公開ステータスが Testing のままだと、7日後に期限切れになる refresh token が発行されることです。同期は1週間は動作しますが、その後停止し、次回の更新時にアプリのログへ invalid_grant が記録されます。同意画面を In production に移行するか、毎週月曜日に手動で再接続します。
CalDAV(WebDAV のカレンダー拡張)はオープンな選択肢ですが、対応は限定的です。Cal.com には CalDAV アプリが含まれていますが、現在も beta と表示されています。Baikal、Radicale、Nextcloud、Kerio Connect などのサーバーで検証されています。Apple iCloud も同じアプリで利用できますが、Apple ID のパスワードではなく app-specific password が必要です。DayOtter では、Google と Microsoft 365 に加えて Apple を CalDAV 経由で利用できます。
ICS feed は同期ではありません。購読用の .ics URL は仕様上読み取り専用です。そのため予約ページで時間をブロックすることはできますが、予約を受け取ることはできません。カレンダー連携が ICS にしか対応していないツールでは、連携機能の半分しかなく、イベントを手動でコピーし続けることになります。
Easy!Appointments は Google Calendar との同期にのみ対応します。Rallly は空き状況をまったく読み取らず、候補日の一覧に対する投票を集めます。「6人でいつ会えるか」を決めるには適していますが、「私と30分の予定を予約する」用途には適していません。
予約ページは公開されるため、TLSを最初に設定します
自分でホストするサービスの多くは非公開です。Wiki、掲示板、ダッシュボードなどは、VPNやSSOログインの背後に置けば、インターネットに直接公開せずに運用できます。しかし、予約リンクはそうはいきません。送信した相手は誰でもそのリンクを開く必要があるため、構成には3つの具体的な違いが生じます。
何もインストールする前に、VPSを指すAレコードを設定したドメイン名が必要です。ブラウザーは通常のHTTPフォームを安全でないと表示し、利用者はそこに名前とメールアドレスを入力するため、初日から証明書も必要です。また、アプリの公開URLを設定ファイルで正しく設定する必要があります。この値は、送信メール内のリンクやOAuthのリダイレクトURIに埋め込まれるためです。Cal.comではNEXT_PUBLIC_WEBAPP_URL、RalllyではDOMAIN、Easy!AppointmentsではBASE_URL、またはインストール時にDAYOTTER_DOMAINを設定し、実際に使用するhttps://アドレスを指定します。
RalllyとDayOtterはTLSを自動的に処理します。RalllyにはTraefikを含む構成が組み込まれており、ACME_EMAILのアドレスを使用してLet's Encrypt証明書を発行します。DayOtterのインストーラーはCaddyを起動し、自動HTTPSを有効にします。Cal.comとEasy!Appointmentsにはこの機能がないため、nginxを前段に置き、Certbotを使ってnginxでLet's Encrypt証明書を取得する方法と同じ手順で自分で証明書を発行します。アプリコンテナは127.0.0.1にバインドし、管理しているプロキシ経由でのみアクセスできるようにします。同じホストで内部ボード用にセルフホストするTrello代替サービスも稼働している場合は、既存の認証の背後に置き、公開用のserver blockは予約用ホストだけに設定します。
VPS 上の Cal.com
Docker 構成は専用のリポジトリで管理され、イメージは Docker Hub にあらかじめ用意されています。そのため、ビルドせずに pull します。
git clone --recursive https://github.com/calcom/cal.diy.git
cd cal.diy
cp .env.example .env
openssl rand -base64 32
openssl rand -base64 24
docker compose pull
docker compose up -d最初のランダム値を NEXTAUTH_SECRET に、2 番目のランダム値を CALENDSO_ENCRYPTION_KEY に設定します。どちらも必須です。DATABASE_URL を設定し、NEXT_PUBLIC_WEBAPP_URL を公開アドレスに向けます。付属のスタックには Web アプリケーション、PostgreSQL、Prisma Studio が含まれます。ドキュメントには、外部でホストするデータベースに接続してアプリケーションだけを実行するための docker compose up -d calcom も記載されています。インストールが完了したら、この構成を使用します。
VPS 上ではイメージを pull し、ビルドしないでください。ソースからビルドする場合、プロジェクトの手順では NODE_OPTIONS="--max-old-space-size=16384" の export が必要です。これは Node だけで 16 GB のヒープを使用します。ARM ハードウェアでは、イメージタグに -arm のサフィックスを追加します。プロジェクトは、事前ビルド済みイメージの実行に必要な最小リソースを公開していません。そのため、アプリケーションと PostgreSQL に 2 GB という値は、ドキュメントに基づく値ではなく、私が運用上の目安としている値です。最初の 1 週間はメモリ使用量を監視してください。
起動したことを確認します。
docker compose ps
docker compose logs -f calcom
curl -sI https://cal.example.com | head -n 1curl の出力は HTTP/2 200 になるはずです。コンテナが running と表示されているのに nginx から 502 Bad Gateway が返る場合、初回起動時のデータベースマイグレーションがまだ実行中であることが多いです。数分待ち、壊れていると判断する前にログを確認してください。Cal.com の Webhook は予約が確定するたびに実行されます。そのため、予約を既存の自動化処理に連携できます。たとえば、VPS 上で HTTPS 経由で到達できる n8n インスタンスが該当します。
コア部分は AGPLv3 で提供されています。一部の機能は enterprise ディレクトリに分離され、別の商用ライセンスが適用されます。team 機能を使って有料の業務プロセスを構築する前に、そのライセンスを確認してください。
1 GB のサーバーで Easy!Appointments を運用する
要件は Apache または Nginx、PHP 8.2 以降、MySQL です。公式イメージは alextselegidis/easyappointments にあります。
最初に、1 点注意してください。リポジトリの docker-compose.yml は開発環境です。コンテナ内で shell を開き、npm install && composer install && npm start を実行することを前提としています。これはデプロイ用ではありません。公開済みのイメージを使用してください。
services:
easyappointments:
image: alextselegidis/easyappointments # pin the current tag from Docker Hub
environment:
- BASE_URL=https://book.example.com
- DB_HOST=mysql
- DB_NAME=easyappointments
- DB_USERNAME=easyapp
- DB_PASSWORD=change-me
ports:
- '127.0.0.1:8080:80'
depends_on:
- mysql
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=change-me-too
- MYSQL_DATABASE=easyappointments
- MYSQL_USER=easyapp
- MYSQL_PASSWORD=change-me
volumes:
- ./mysql:/var/lib/mysqlBASE_URL には、外部公開する HTTPS アドレスを指定する必要があります。設定を誤ると、確認メール内の予約リンクが、利用者から到達できないホストを指します。このイメージは、独自の証明書を使わずに port 80 で平文の HTTP を提供します。そのため、port は 127.0.0.1 にバインドし、前段の nginx で TLS を終端します。Compose の構文に慣れていない場合は、まず VPS での Docker Compose の基本 を確認してから戻ってきてください。
ここで紹介する中では、これが圧倒的に軽量な選択肢です。PHP アプリケーションと MySQL の 2 つのコンテナは、1 GB の VPS でも余裕を持って動作します。ただし、機能には制約があります。カレンダーのバックエンドは Google Calendar だけで、インターフェースも最新の予約フローではなく、従来型の管理パネルです。カレンダーに Microsoft 365、Fastmail、または Nextcloud を使用している場合は、最初から候補外です。
グループ投票用のRallly
Ralllyは別の用途に対応します。空き時間を公開するものではありません。候補日時をグループに提示して投票を集めます。取締役会の会議には適していますが、顧客向けの予約リンクには使えません。
curl -fsSL https://get.rallly.co | bashシェルにパイプする前に、スクリプトの内容を必ず確認してください。bashをlessに置き換え、動作を確認してから実行します。手動で進める方法でも同じ処理を、確認可能な手順に分けて実行できます。
git clone https://github.com/lukevella/rallly-selfhosted.git
cd rallly-selfhosted
./rallly.sh setup
./rallly.sh startドキュメントに記載された要件は、少なくとも2 GBのRAM、Compose v2に対応するDocker 19.03以降、80番ポートと443番ポートが空いていること、そしてサーバーを指すドメインです。同梱の構成には、HTTPS用のTraefik、Webアプリケーション、PostgreSQL、S3互換オブジェクトストレージ用のGarageが含まれます。DOMAIN、32文字以上のSECRET_PASSWORD、SUPPORT_EMAIL、INITIAL_ADMIN_EMAILを設定してください。すでにリバースプロキシを運用している場合はPROXY_MODE=externalとWEB_PORTを設定すると、Traefikは処理に介入しません。すでにMinIOを使用した自己ホスト型のS3互換オブジェクトストレージを運用している場合は、S3_*変数にその接続先を指定し、Garageコンテナを削除してください。
ここではSMTPは必須です。サインインにマジックリンクを使用するためです。動作するリレーがなければ、直前に作成した管理者アカウントを含め、誰もログインできません。これはメール障害としてはまだ良い状態です。3週間後に顧客の予約を失うのではなく、入口で処理を止められるからです。
DayOtter、最新の選択肢
DayOtter は、アシスタント機能を備えた AGPLv3 のスケジューリングプラットフォームです。本番環境へのインストールは、次の1コマンドで実行できます。
curl -fsSL https://raw.githubusercontent.com/Dayotter/dayotter/main/deploy/install.sh \
| sudo DAYOTTER_DOMAIN=cal.example.com bash前述のとおり、実行する前に内容を確認してください。インストーラーは Docker をセットアップし、Secret を生成して、Next.js Web アプリ、リマインダー・カレンダー同期・Webhook を処理するバックグラウンドワーカー、PostgreSQL、Redis、HTTPS を自動設定する Caddy で構成される完全なスタックを起動します。
4つの中で、カレンダー対応が最も広範です。Google、Microsoft 365、CalDAV 経由の Apple、ICS フィードに対応します。ただし、ICS については前述の注意点があります。その他の連携はすべて環境変数で明示的に有効化します。メールには SMTP または Resend、アシスタントには ANTHROPIC_API_KEY、SMS には Twilio、決済には Stripe を使用できます。アシスタントは確認を先に行う方式です。アシスタントが提案し、利用者が承認してから処理します。明示的に承認しない限り、予定がカレンダーに登録されることはありません。API key を空のままにすると、この機能は動作しません。
自己ホスト環境でのライセンスも明確です。コア部分は AGPLv3 で、ee/ ディレクトリには商用のクラウド専用ライセンスが含まれています。このライセンスは DAYOTTER_CLOUD=1 を設定しない限り有効になりません。つまり、2026年8月時点でホスト型プランが1シートあたり月額 $9 を請求するチーム機能を、自分のサーバーで利用できます。
ここで紹介した中では、最も構成が重く、プロジェクトとしても最も新しい製品です。既存の予約リンクと並行して2週間運用し、両方で実際の予約を受け付けてください。利用者を移行する前に、ワーカーログを確認してください。
各スタックに実際にかかるコスト
小規模な VPS にスタックがどれだけのリソースを要求するかを正直に判断するには、コンテナ数が適しています。各サービスには固有のメモリ下限があるためです。以下の数値は、各プロジェクトが公開している Docker スタックから確認したもので、2026 年 8 月時点のものです。
The data behind this chart
[
{
"tool": "Easy!Appointments",
"containers": 2,
"database": "MySQL"
},
{
"tool": "Cal.com",
"containers": 3,
"database": "PostgreSQL"
},
{
"tool": "Rallly",
"containers": 4,
"database": "PostgreSQL"
},
{
"tool": "DayOtter",
"containers": 5,
"database": "PostgreSQL and Redis"
}
]Easy!Appointments は 2 個のコンテナを必要とし、1 GB に収まります。Rallly の同梱スタックは 4 個で、ドキュメントでは 2 GB を求めています。DayOtter のインストーラーは 5 個を起動するため、ここにある中では最大のサーバーを必要とします。Cal.com と DayOtter は必要メモリの最小値を公開していません。そのため、両方ともサポート対象の数値ではなく、2 GB を開始点にしています。
すでにインフラを運用している場合、これらのうち 2 つはコンテナ数を減らせます。独自のプロキシとオブジェクトストレージを指定すれば、Rallly の Traefik と Garage のコンテナはどちらも不要になります。Cal.com の Prisma Studio は開発用ツールなので、公開サーバー上で実行したままにしないでください。
選ぶべきセルフホスト型Calendly代替サービス
個人コンサルタントには Cal.com が適しています。 ここで紹介する中で、利用者に認識されやすい予約ページ、VPS 上で Node のビルドを不要にする事前構築済みイメージ、Google や Microsoft のカレンダーを使っていない場合にも利用できる CalDAV 経路をすべて備えているのは Cal.com だけです。PostgreSQL データベース 1 つとアプリケーションコンテナ 1 つで済むため、数年間にわたって維持できる運用負荷に収まります。OAuth クライアントとメールリレーの設定には半日程度を見込んでください。また、CalDAV アプリはまだ beta のため、リンクを公開する前に、実際の予約を最初から最後まで 1 件テストしてください。
小規模チームでは DayOtter を検討してください。 重み付きラウンドロビンと一括予約が AGPLv3 のコアに含まれているため、セルフホストすれば、ホスティングサービスでは料金が発生する機能を利用できます。worker process は、チームが実際に利用するリマインダーと webhook に対応するよう設計されています。一方で、成熟度には注意が必要です。この一覧では最も新しいプロジェクトなので、まずは並行稼働させ、1 か月分の予約を確認するまで以前のリンクを有効にしておいてください。
用途が限定されるケースも 2 つあります。グループで集まれる時間を探すための投票だけが必要なら、Rallly をインストールして、それで終わりにしてください。1 GB の VPS を使い、Google Calendar を常用していて、そのサーバーで予約を受け付ける最小構成を求めるなら、Easy!Appointments は、その VPS に導入できるより高機能な選択肢よりも長く使えます。同じサーバーに何を追加する価値があるかという幅広い検討については、2026 年にセルフホストする価値があるもの を参照してください。
FAQ
ドメイン名なしでセルフホストの予約ページを運用できますか?
いいえ。これらのアプリはすべて、確認メール内のリンクに公開 URL を書き込みます。また、Google と Microsoft は OAuth のリダイレクト URI を同じ値と照合するため、IP アドレスだけを使うと同意画面で redirect_uri_mismatch になります。Let's Encrypt は IP アドレスに対して証明書を発行しないため、ページは平文の HTTP で読み込まれ、ブラウザーはフォームを安全でないと表示します。先にドメインを購入し、VPS を指す A レコードを設定してからインストールしてください。
予約確認メールがまったく届かないのはなぜですか?
ほとんどの場合、サーバーが自分でメールを配信しようとしていることが原因です。多くの VPS プロバイダーは新規アカウントの送信ポート 25 をブロックしているため、接続がハングします。ポートが開いている場合でも、新しい IP アドレスには送信実績がないため、大手の受信側はメールを拒否します。アプリをポート 587 のトランザクションメールリレーに接続し、nc -vz -w 5 "$SMTP_HOST" 587 でポートに到達できることを確認してください。その後、リレーから提供された SPF レコードと DKIM レコードを公開します。Cal.com を運用している場合は、同梱された EMAIL_SERVER_HOST=localhost と EMAIL_SERVER_PORT=1025 のデフォルト値を置き換えたことを確認してください。これらはローカルの開発用メールボックスを指しています。
セルフホストの Cal.com は CalDAV と同期しますか、それとも Google だけですか?
どちらにも対応していますが、成熟度は異なります。CalDAV アプリは beta とされており、Baikal、Radicale、Nextcloud、Kerio Connect などのサーバーで検証されています。Apple iCloud も、アプリ固有のパスワードを使って利用できます。Google Calendar と Microsoft 365 はどちらも双方向に同期します。ただし、セルフホスト環境では独自の OAuth クライアントを作成し、GOOGLE_API_CREDENTIALS で指定する必要があります。ホスト型サービスの認証情報はソースに含まれていないためです。
Google Calendar の同期が 1 週間後に停止するのはなぜですか?
Google Cloud プロジェクトの公開ステータスがまだ Testing だからです。この状態のアプリに対して Google が発行するリフレッシュトークンは 7 日後に期限切れになります。そのため、最初は接続できますが、次回のトークン更新時に停止し、アプリケーションログには invalid_grant が表示されます。OAuth 同意画面を In production に変更し、カレンダーを 1 回再接続してください。ステータスを変更せずに再接続しても、さらに 7 日間使えるだけです。
1 GB の VPS で動作するのはどれですか?
Easy!Appointments なら動作します。PHP アプリケーションと MySQL で構成されているためです。Rallly は 2 GB を最小要件としており、同梱されたスタックは 4 つのサービスを実行します。Cal.com と DayOtter は最小要件を公開していません。しかし、PostgreSQL を使用する Next.js アプリケーションであり、DayOtter では Redis とワーカープロセスも必要になるため、2 GB 以上を計画してください。小容量のサーバーで Cal.com をソースからビルドしないでください。プロジェクト独自のビルド手順では 16 GB の Node ヒープを要求しているため、代わりに事前ビルド済みのイメージを取得してください。