자체 호스팅 Calendly 대안 비교 및 추천
Cal.com, Easy!Appointments, Rallly, DayOtter의 핵심 기능을 비교합니다. VPS 운영 시 반드시 고려해야 할 양방향 캘린더 동기화와 아웃바운드 이메일 발송 실패 문제의 원인을 분석하고, 안정적인 예약 시스템 구축을 위한 실질적인 해결책을 제시합니다.
간단한 답변
자체 호스팅하는 Calendly 대안은 VPS의 내부 도구들이 결코 하지 않는 한 가지 작업, 즉 대중에게 응답하는 기능을 수행해야 합니다. 예약 페이지 자체가 곧 제품입니다. 따라서 첫날부터 실제 도메인 이름과 TLS(전송 계층 보안)가 필요하며, 서버에 대해 전혀 알지 못하는 사람들에게 메일을 발송할 수 있어야 합니다.
현실적으로 고려할 만한 프로젝트는 4가지입니다. Cal.com은 Calendly와 가장 유사하며 1인 컨설턴트에게 기본으로 권장되는 선택지입니다. Easy!Appointments는 PHP와 MySQL을 사용하는 가벼운 도구로, 1 GB VPS에서도 원활하게 작동합니다. Rallly는 그룹 투표 도구이며 예약 페이지 기능은 없습니다. DayOtter는 가장 최근에 등장한 AGPLv3 기반 일정 관리 플랫폼으로, 예약 확인을 우선하는 어시스턴트 기능을 전면에 내세우고 있습니다.
어떤 도구를 실제로 운영할지는 두 가지 질문으로 결정됩니다. 첫째, 현재 사용 중인 캘린더와 양방향 동기화가 가능한가? 둘째, 메일 발송이 가능한가? 두 번째 질문은 대부분의 자체 호스팅 예약 설정이 조용히 실패하는 지점이므로, 가장 먼저 확인해야 합니다.
아웃바운드 이메일 전송 실패
예약 확인 메일이 엉뚱한 사람의 수신함으로 전달되거나 아예 도착하지 않는 경우가 있습니다. Gmail이나 Microsoft 365와 같은 대형 메일 서비스는 발신 IP 주소와 DNS 레코드를 기준으로 메일의 신뢰성을 판단합니다.
VPS에서 직접 메일을 발송하는 방식은 거의 성공하지 못합니다. 대부분의 호스팅 업체는 신규 계정의 아웃바운드 TCP 25번 포트를 차단하므로, 연결 시도 시 응답이 없다가 타임아웃이 발생합니다. 설령 25번 포트가 열려 있더라도, 신규 VPS IP는 발신 이력(reputation)이 없어 대형 메일 서비스는 이를 스팸으로 간주합니다. 데이터베이스에는 예약이 기록되고 화면에는 확인 메시지가 뜨지만, 실제 메일은 발송되지 않습니다. 서버 측 로그에는 오류가 남지 않기 때문에, 예약자가 나타나지 않은 뒤에야 문제가 발견되는 경우가 많습니다.
릴레이 서비스를 사용하십시오. 트랜잭션 메일 제공업체를 이용하면 호스트명, 포트, 사용자 이름, 비밀번호만으로 간단히 설정할 수 있습니다. 애플리케이션 설정을 변경하기 전에 먼저 해당 포트에 연결 가능한지 확인하십시오.
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은 EMAIL_SERVER_HOST을 1025 포트의 localhost로 설정하는데, 이는 로컬 개발용 메일함입니다. 기본값을 그대로 두면 애플리케이션은 오류 없이 메일을 허공으로 보냅니다. Rallly는 SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PWD를 사용합니다. DayOtter는 SMTP 설정이나 Resend 키를 사용합니다. Easy!Appointments는 애플리케이션 설정 페이지에서 동일한 릴레이 정보를 입력해야 실제 예약을 받기 전에 알림을 정상적으로 보낼 수 있습니다.
그다음, 릴레이 서비스가 제공하는 DNS 레코드를 게시하십시오. SPF(Sender Policy Framework) 레코드는 귀하의 도메인을 대신해 메일을 보낼 수 있는 서버를 지정하며, DKIM(DomainKeys Identified Mail) 키는 메시지에 서명하여 위변조되지 않았음을 증명합니다. 두 설정이 모두 통과되면 DMARC(Domain-based Message Authentication, Reporting and Conformance) 정책을 추가하십시오. 대형 메일 서비스의 실제 주소로 테스트 예약을 보낸 뒤, 메시지 헤더를 열어 인증 항목이 pass로 표시되는지 확인하십시오. 메일을 보낼 수 없는 예약 페이지는 아예 없는 것보다 못합니다. 아무런 경고 없이 실패하기 때문입니다.
양방향 동기화를 지원하는 캘린더 백엔드
동기화는 두 가지 방향으로 이루어지며, 각각 독립적으로 실패할 수 있습니다. 읽기 방향은 가용성 확인입니다. 애플리케이션이 사용자의 기존 일정을 확인하지 못하면 이미 예약된 시간에 새로운 예약을 받을 수 있습니다. 쓰기 방향은 예약 자체를 의미합니다. 확정된 이벤트는 예약 도구 내부뿐만 아니라 실제로 사용하는 캘린더에도 나타나야 합니다.
Google Calendar와 Microsoft 365는 두 방향 모두 지원하지만, 자체 호스팅 설치 시 한 가지 조건이 있습니다. 호스팅 제품의 클라이언트 ID가 소스 코드에 포함되어 있지 않으므로 사용자가 직접 OAuth(Open Authorization) 클라이언트를 생성해야 합니다. Cal.com의 경우 이는 GOOGLE_API_CREDENTIALS의 .env에 해당하며, Google Cloud 콘솔에서 다운로드한 JSON 파일을 보관합니다. DayOtter도 동일한 방식으로 Google 및 Microsoft OAuth 자격 증명을 처리합니다.
이 과정에서 두 가지 문제가 발생할 수 있으며, 시작하기 전에 이를 숙지하는 것이 좋습니다. 첫째, 등록하는 리다이렉트 URI는 스킴과 후행 경로를 포함하여 공용 URL과 정확히 일치해야 합니다. 그렇지 않으면 Google은 동의 화면에서 redirect_uri_mismatch 오류를 발생시키며 연결을 차단합니다. 둘째, 테스트(Testing) 게시 상태로 둔 Google 프로젝트는 7일 후에 만료되는 갱신 토큰을 발행합니다. 동기화는 일주일 동안 정상 작동하다가 멈추며, 다음 갱신 시 앱 로그에 invalid_grant가 표시됩니다. 동의 화면을 프로덕션(In production)으로 변경하거나, 매주 월요일마다 수동으로 재연결해야 합니다.
CalDAV(Calendaring Extensions to WebDAV)는 개방형 옵션이지만 지원 범위가 더 좁습니다. Cal.com은 아직 베타 상태인 CalDAV 앱을 제공하며, Baikal, Radicale, Nextcloud, Kerio Connect 등의 서버에서 검증되었습니다. Apple iCloud도 동일한 앱을 통해 작동하지만, Apple ID 비밀번호가 아닌 앱 전용 비밀번호가 필요합니다. DayOtter는 Google 및 Microsoft 365와 함께 CalDAV를 통한 Apple 연동을 지원합니다.
ICS 피드는 동기화가 아닙니다. 구독형 .ics URL은 설계상 읽기 전용이므로 예약 페이지에서 시간을 차단할 수는 있지만, 예약을 수신할 수는 없습니다. 도구가 캘린더에 대해 ICS만 제공한다면 절반의 기능만 갖춘 것이며, 결국 이벤트를 수동으로 복사해야 합니다.
Easy!Appointments는 Google Calendar만 동기화하며 다른 서비스는 지원하지 않습니다. Rallly는 가용성을 전혀 읽지 않으며, 후보 날짜들에 대한 투표를 수집합니다. 따라서 "우리 6명이 언제 만날 수 있을까"라는 질문에는 적합한 도구이지만, "나와 30분 예약하기"에는 적합하지 않은 도구입니다.
예약 페이지는 공개되므로 TLS가 우선입니다
대부분의 자가 호스팅 서비스는 비공개입니다. 위키, 게시판, 대시보드 등은 모두 VPN이나 SSO 로그인 뒤에 숨겨 인터넷에 직접 노출하지 않을 수 있습니다. 하지만 예약 링크는 그럴 수 없습니다. 링크를 전달받은 누구나 페이지를 불러와야 하므로, 설정 방식이 다음 세 가지 측면에서 달라집니다.
무엇을 설치하기 전에 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 대안을 이미 운영 중이라면, 해당 서비스는 기존 인증 체계 뒤에 유지하고 예약 호스트에만 공개 서버 블록을 할당하십시오.
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에, 두 번째 값은 CALENDSO_ENCRYPTION_KEY에 입력합니다. 두 값 모두 필수입니다. DATABASE_URL을 설정하고 NEXT_PUBLIC_WEBAPP_URL이 공인 IP 주소를 가리키도록 지정하십시오. 번들로 제공되는 스택은 웹 애플리케이션, 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를 작업용 기준으로 잡고 첫 일주일 동안 메모리 사용량을 모니터링하십시오.
서비스가 정상적으로 시작되었는지 확인합니다.
docker compose ps
docker compose logs -f calcom
curl -sI https://cal.example.com | head -n 1curl 명령을 실행하면 HTTP/2 200가 출력되어야 합니다. 컨테이너는 실행 중인데 nginx에서 502 Bad Gateway 오류가 발생한다면, 이는 첫 부팅 시 데이터베이스 마이그레이션이 진행 중일 가능성이 높습니다. 몇 분 정도 기다린 후 로그를 확인하여 실제로 문제가 있는지 판단하십시오. Cal.com의 웹훅은 예약이 확정될 때마다 발생하므로, 이를 활용해 VPS에서 HTTPS로 접근 가능한 n8n 인스턴스와 같은 자동화 워크플로우를 연동할 수 있습니다.
핵심 코드는 AGPLv3 라이선스를 따르며, 일부 기능은 별도의 상용 라이선스가 필요한 엔터프라이즈 디렉터리에 포함되어 있습니다. 팀 기능을 기반으로 유료 비즈니스 프로세스를 구축하기 전에 해당 라이선스 내용을 반드시 확인하십시오.
1 GB 서버에서 Easy!Appointments 운영하기
요구 사항은 Apache 또는 Nginx, PHP 8.2 이상, 그리고 MySQL입니다. alextselegidis/easyappointments에 공식 이미지가 제공됩니다.
먼저 주의할 점이 있습니다. 저장소에 있는 docker-compose.yml은 개발 환경입니다. 이 환경은 컨테이너 내에서 셸을 열고 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 주소여야 합니다. 이 설정이 잘못되면 확인 이메일에 포함된 예약 링크가 클라이언트가 접근할 수 없는 호스트를 가리키게 됩니다. 이 이미지는 자체 인증서 없이 80번 포트에서 일반 HTTP를 서비스하므로, 포트를 127.0.0.1에 바인딩하고 앞단에서 Nginx가 TLS를 종료하도록 구성해야 합니다. Compose 문법이 생소하다면 VPS에서의 Docker Compose 기초를 먼저 읽고 돌아오십시오.
이 방식은 여기 소개된 옵션 중 가장 가볍습니다. PHP 애플리케이션과 MySQL, 두 개의 컨테이너가 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, Docker 19.03 이상(Compose v2 포함), 80번 및 443번 포트 개방, 그리고 서버를 가리키는 도메인입니다. 번들로 제공되는 스택은 HTTPS를 위한 Traefik, 웹 애플리케이션, 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 기반의 일정 관리 플랫폼입니다. 프로덕션 환경 설치는 다음 명령어 한 줄로 완료됩니다.
curl -fsSL https://raw.githubusercontent.com/Dayotter/dayotter/main/deploy/install.sh \
| sudo DAYOTTER_DOMAIN=cal.example.com bash위에서 언급했듯이 실행하기 전에 내용을 먼저 읽어보시기 바랍니다. 설치 프로그램은 Docker를 설정하고, 보안 키를 생성하며, 전체 스택을 구동합니다. 여기에는 Next.js 웹 앱, 알림·캘린더 동기화·웹훅을 처리하는 백그라운드 워커, PostgreSQL, Redis, 그리고 자동 HTTPS를 지원하는 Caddy가 포함됩니다.
캘린더 지원 범위는 소개된 4개 서비스 중 가장 넓습니다. Google, Microsoft 365, CalDAV를 통한 Apple, 그리고 ICS 피드를 지원합니다(ICS는 앞서 언급한 주의사항이 적용됩니다). 그 외의 모든 연동 기능은 환경 변수를 통해 선택적으로 활성화할 수 있습니다. 메일 발송을 위한 SMTP 또는 Resend, 어시스턴트를 위한 ANTHROPIC_API_KEY, SMS를 위한 Twilio, 결제를 위한 Stripe 등이 여기에 해당합니다. 어시스턴트는 '확인 우선' 방식을 따릅니다. 어시스턴트가 제안을 하면 사용자가 승인해야 하며, 명시적인 동의 없이는 어떤 내용도 캘린더에 반영되지 않습니다. API 키를 비워두면 해당 기능은 아예 실행되지 않습니다.
라이선스는 자가 호스팅 사용자에게 명확하게 적용됩니다. 핵심 코드는 AGPLv3를 따르며, ee/ 디렉터리에는 상용 클라우드 전용 라이선스가 포함되어 있습니다. 이 라이선스는 DAYOTTER_CLOUD=1 설정이 활성화되지 않는 한 작동하지 않습니다. 즉, 2026년 8월 기준 월 사용자당 9달러가 청구되는 호스팅 플랜의 팀 기능을 본인의 서버에서 그대로 사용할 수 있다는 의미입니다.
DayOtter는 이 목록에서 가장 무거운 스택을 사용하며 가장 최근에 시작된 프로젝트입니다. 기존 예약 링크와 함께 2주 동안 병행 운영하며 실제 예약을 양쪽 모두에서 받아보고, 워커 로그를 충분히 검토한 뒤에 클라이언트를 완전히 이전하십시오.
각 스택의 실제 비용
컨테이너 개수는 소규모 VPS에서 스택이 요구하는 자원을 가늠하는 정직한 지표입니다. 각 서비스는 고유한 최소 메모리 점유율을 가지기 때문입니다. 아래 수치는 2026년 8월 기준으로 각 프로젝트가 공개한 Docker 스택을 바탕으로 집계되었습니다.
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개를 실행하므로, 여기에 나열된 4개의 항목 중 가장 큰 서버 사양을 요구합니다. Cal.com과 DayOtter는 최소 메모리 수치를 공식적으로 명시하지 않았으므로, 지원되는 수치가 아닌 2 GB를 시작점으로 설정했습니다.
이미 인프라를 운영 중이라면 이 중 두 가지 항목의 컨테이너 개수는 줄어들 수 있습니다. Rallly의 Traefik과 Garage 컨테이너는 사용자가 기존에 운영 중인 프록시와 객체 스토리지로 연결할 경우 제거할 수 있습니다. Cal.com의 Prisma Studio는 개발 도구이므로 공개 서버에서 계속 실행해서는 안 됩니다.
어떤 셀프 호스팅 Calendly 대안을 선택해야 하는가
1인 컨설턴트라면 Cal.com을 운영하십시오. 이 프로젝트는 사람들이 익숙하게 느끼는 예약 페이지, VPS에서 Node 빌드를 수행할 필요가 없는 사전 빌드된 이미지, 그리고 Google이나 Microsoft 캘린더를 사용하지 않는 사용자를 위한 CalDAV 경로를 모두 갖춘 유일한 선택지입니다. PostgreSQL 데이터베이스 하나와 애플리케이션 컨테이너 하나로 구성되므로 수년간 유지 관리하기에 부담이 적습니다. OAuth 클라이언트와 메일 릴레이 설정에 오후 시간을 할애하십시오. CalDAV 앱은 아직 베타 단계이므로 링크를 공개하기 전에 실제 예약을 처음부터 끝까지 테스트해 보아야 합니다.
소규모 팀이라면 DayOtter를 고려하십시오. 가중치 기반 라운드 로빈(weighted round robin)과 공동 예약 기능이 AGPLv3 코어에 포함되어 있어, 셀프 호스팅을 통해 유료 서비스에서 비용을 지불해야 하는 기능을 사용할 수 있습니다. 워커 프로세스는 팀이 실제로 의존하는 알림 및 웹훅 처리에 최적화되어 있습니다. 단점은 성숙도입니다. 이 목록에서 가장 최신 프로젝트이므로, 한 달 동안 예약 과정을 충분히 지켜볼 때까지 기존 링크를 유지하며 병행 운영하십시오.
더 좁은 범위의 두 가지 사례가 있습니다. 그룹 회의 시간을 정하기 위한 투표 기능만 필요하다면 Rallly를 설치하는 것으로 충분합니다. 1 GB VPS를 사용 중이고 Google Calendar를 주로 쓰며, 예약 기능만 수행하는 가장 가벼운 도구를 원한다면 Easy!Appointments가 이 서버에 올릴 수 있는 다른 어떤 화려한 옵션보다 오래 지속될 것입니다. 같은 서버에 무엇을 더 올릴 가치가 있는지에 대한 더 넓은 질문은 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 앱은 베타 상태이며 Baikal, Radicale, Nextcloud, Kerio Connect 등의 서버에서 검증되었습니다. Apple iCloud는 앱 전용 암호를 사용하여 CalDAV를 통해 연동됩니다. Google Calendar와 Microsoft 365는 양방향 동기화가 가능하지만, 자체 호스팅 설치 시에는 직접 OAuth 클라이언트를 생성하여 GOOGLE_API_CREDENTIALS을 통해 제공해야 합니다. 호스팅 서비스의 자격 증명은 소스 코드에 포함되어 있지 않기 때문입니다.
Google Calendar 동기화가 일주일 뒤에 멈추는 이유는 무엇입니까?
Google Cloud 프로젝트의 게시 상태가 테스트(Testing)로 설정되어 있기 때문입니다. Google은 해당 상태의 앱에 7일 후 만료되는 갱신 토큰을 발급합니다. 따라서 연결은 정상적으로 작동하다가 다음 토큰 갱신 시점에 끊기며, 애플리케이션 로그에는 invalid_grant가 표시됩니다. OAuth 동의 화면을 프로덕션(In production)으로 변경하고 캘린더를 한 번 다시 연결하십시오. 상태를 변경하지 않고 재연결만 하면 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 힙 메모리를 요구하므로, 미리 빌드된 이미지를 가져와 사용하십시오.