VPS에 Radicale로 CalDAV 캘린더 서버 구축하기
Google 없이 스마트폰과 노트북 간 일정을 동기화하는 방법을 안내합니다. Radicale 설치부터 TLS 설정, 서비스 탐색 및 클라이언트 연결까지 VPS에서 직접 CalDAV 서버를 운영하는 전체 과정을 상세히 설명합니다.
구축할 시스템
직접 호스팅하는 캘린더는 사용자가 제어하는 VPS에서 TLS로 보호되며, 사용자별로 계정을 하나씩 사용하는 CalDAV 서버입니다. 주머니 속의 스마트폰과 책상 위의 노트북, 그리고 파트너의 노트북까지 모두 동일한 일정을 표시합니다. 중간에 Google 계정이 개입하지 않습니다.
이는 직접 호스팅하는 예약 페이지와는 다른 작업입니다. 예약 페이지는 낯선 사람들을 위한 것으로, 사용자의 빈 시간을 공개하고 누군가 그 시간을 예약할 수 있게 합니다. 반면 캘린더 서버는 사용자의 기기들을 위한 것으로, 일정을 저장하고 모든 클라이언트 간의 동기화를 유지합니다. 사람들은 종종 두 가지를 모두 운영하며, 이때 예약 도구는 여기서 구축할 CalDAV 서버로부터 가용 시간을 읽어옵니다.
설치는 간단합니다. Radicale은 하나의 Python 패키지와 약 10줄의 설정 파일로 구성됩니다. 이 설정이 첫 달을 무사히 넘길 수 있을지는 TLS, 서비스 탐색(discovery), 사용자별 컬렉션, 그리고 백업에 달려 있습니다. 아래 내용의 대부분은 이 부분들을 다룹니다.
CalDAV란 무엇이며, 왜 중요한가?
CalDAV는 HTTP를 통한 캘린더 동기화 규격입니다. RFC 4791에 정의되어 있으며, WebDAV(RFC 4918에 정의된 추가 HTTP 메서드 집합인 웹 분산 저작 및 버전 관리)의 확장입니다. 캘린더는 디렉터리처럼 동작하는 컬렉션입니다. 하나의 이벤트는 그 안에 포함된 하나의 파일이며, 메일의 .ics 첨부 파일과 동일한 형식인 iCalendar 텍스트 형식(RFC 5545)으로 작성됩니다.
클라이언트는 몇 가지 추가된 메서드와 함께 일반적인 HTTP를 사용합니다. PROPFIND은 해당 위치에 무엇이 있는지, 어떤 속성을 가지고 있는지 확인합니다. REPORT은 특정 날짜 범위 내의 모든 이벤트와 같이 필터링된 데이터 조각을 요청합니다. PUT은 이벤트를 하나 기록하고, DELETE는 이를 삭제합니다. 모든 이벤트에는 UID 줄이 포함되어 있으며, 이 식별자를 통해 두 장치는 서로 다른 복사본이 아닌 동일한 이벤트를 보고 있음을 확인합니다.
이 기술의 핵심 이점은 이식성입니다. iOS, macOS, Thunderbird, Evolution, 그리고 DAVx⁵를 사용하는 Android는 모두 CalDAV를 지원합니다. 데이터가 오늘 선택한 특정 서버에 종속되지 않습니다. 파일을 다른 CalDAV 서버로 옮기고 클라이언트의 호스트 이름만 새 서버로 변경하면, 다른 설정은 바꿀 필요가 없습니다.
CardDAV도 함께 사용됩니다. 이는 연락처를 위한 동일한 개념의 규격으로, RFC 6352에 정의되어 있으며 이벤트 대신 vCard 파일을 저장합니다. 아래에 소개된 모든 서버는 동일한 계정에서 두 프로토콜을 모두 제공하므로, 캘린더 설정이 완료되면 주소록은 체크박스 하나로 활성화할 수 있습니다.
어떤 CalDAV 서버를 운영해야 할까요?
Radicale은 가장 작고 효율적인 선택지입니다. Python 기반이며 별도의 데이터베이스가 필요 없고, 모든 데이터를 일반 파일 형태의 폴더에 저장합니다. 가정용 캘린더에는 이 정도면 충분하며, 새벽 3시에 문제가 발생할 확률이 매우 낮기 때문에 이 가이드에서는 Radicale을 사용합니다.
Baikal은 웹 관리 패널을 제공하는 옵션입니다. PHP와 sabre/dav 라이브러리로 동작하며, 사용자 및 캘린더 정보를 SQLite나 MySQL에 저장합니다. 명령줄 대신 브라우저에서 사용자를 추가할 수 있어, 계정 생성과 삭제가 잦은 경우에 적합합니다.
Nextcloud는 캘린더가 여러 기능 중 하나일 때 적합합니다. 캘린더, 연락처, 파일 관리, 모바일 앱을 모두 제공하지만, 그 대가로 PHP-FPM, 데이터베이스, 백그라운드 작업 실행기가 필요합니다. 이 구성이 실제 필요한 기능에 비해 너무 무겁게 느껴진다면 더 가벼운 Nextcloud 대안을 고려해 보십시오. 또한 사람들이 Nextcloud를 설치하는 또 다른 이유인 파일 동기화는 직접 호스팅하는 파일 동기화에서 다룹니다.
DAViCal은 오랫동안 사용되어 온 PostgreSQL 기반 옵션입니다. 이미 PostgreSQL을 운영 중이고 캘린더 데이터를 그 안에 저장하고 싶은 경우에만 고려할 가치가 있습니다.
Ubuntu 24.04에 Radicale 설치하기
2026년 8월 기준 최신 릴리스는 Radicale 3.5.10입니다. 이를 별도의 가상 환경에 설치하십시오.
sudo apt update
sudo apt install -y python3-venv apache2-utils nginx
sudo useradd --system --user-group --home-dir / --shell /usr/sbin/nologin radicale
sudo install -d -o radicale -g radicale -m 750 /var/lib/radicale/collections
sudo install -d -m 750 -o root -g radicale /etc/radicale
sudo python3 -m venv /opt/radicale/venv
sudo /opt/radicale/venv/bin/pip install --upgrade radicale가상 환경 사용은 선택 사항이 아닙니다. 시스템 Python에 sudo pip install radicale을 실행하면 error: externally-managed-environment 오류가 발생합니다. Ubuntu는 Python을 apt가 관리하는 패키지로 간주하므로 pip가 패키지 파일을 덮어쓰지 못하게 차단하기 때문입니다.
/etc/radicale/config을 작성하십시오:
[server]
hosts = 127.0.0.1:5232
[auth]
type = htpasswd
htpasswd_filename = /etc/radicale/users
htpasswd_encryption = autodetect
[storage]
filesystem_folder = /var/lib/radicale/collectionshosts는 의도적으로 루프백 인터페이스에 바인딩됩니다. nginx가 TLS를 종료하고 해당 포트로 전달하므로 Radicale은 인터넷에 직접 노출되지 않습니다. 0.0.0.0:5232의 업스트림 예시는 암호화되지 않은 서비스를 게시하여 비밀번호를 평문으로 수락하는데, 이는 여기서 가장 주의해야 할 실수입니다.
이제 계정을 설정합니다. -5은 SHA-512 crypt를 선택하며, Radicale은 별도의 모듈 없이 htpasswd_encryption = autodetect을 통해 이를 읽습니다:
sudo htpasswd -5 -c /etc/radicale/users you
sudo htpasswd -5 /etc/radicale/users partner
sudo chown root:radicale /etc/radicale/users
sudo chmod 640 /etc/radicale/users-c은 파일을 생성하고 기존 내용을 모두 삭제(truncate)합니다. 첫 번째 사용자를 추가할 때만 사용하십시오. 몇 달 뒤에 htpasswd -5 -c를 다시 실행하면 첫 번째 사용자 이후에 추가된 모든 계정이 삭제됩니다. 이 경우 한 명은 동기화가 잘 되지만 다른 사용자들은 비밀번호 입력 창이 무한히 반복되는 증상을 겪게 됩니다. Bcrypt도 사용할 수 있으며, 이를 위해서는 radicale[bcrypt]을 추가로 설치해야 합니다.
Radicale 문서의 유닛 파일을 참고하여 /etc/systemd/system/radicale.service을 생성하십시오:
[Unit]
Description=CalDAV and CardDAV server
After=network.target
Requires=network.target
[Service]
ExecStart=/opt/radicale/venv/bin/python -m radicale
Restart=on-failure
User=radicale
UMask=0027
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
NoNewPrivileges=true
ReadWritePaths=/var/lib/radicale/
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now radicale
curl -i http://127.0.0.1:5232/정상적인 결과는 WWW-Authenticate 헤더를 포함한 401 Unauthorized입니다. 서비스가 대기 중이며 인증이 활성화되었음을 의미합니다. Connection refused는 서비스가 시작되지 않았음을 뜻하며, journalctl -u radicale -n 50는 거부된 옵션의 이름을 나타냅니다. ProtectSystem=strict은 이 서비스를 위해 파일 시스템을 읽기 전용으로 마운트하므로, ReadWritePaths=/var/lib/radicale/은 서비스가 이벤트를 저장할 수 있게 해주는 필수 설정입니다. 해당 줄을 삭제하면 읽기 작업은 계속되지만 모든 쓰기 작업이 실패하게 됩니다.
TLS는 선택 사항이 아닙니다. 클라이언트가 평문 통신을 거부하기 때문입니다.
CalDAV는 HTTP Basic 인증을 사용하며, 이는 모든 요청마다 user:password을 base64로 인코딩하여 전송합니다. Base64는 인코딩 방식일 뿐 암호화가 아닙니다. 평문 HTTP를 사용하면 하루 종일 동기화가 이루어질 때마다 휴대폰과 서버 사이의 모든 네트워크 구간에 비밀번호가 노출됩니다.
클라이언트가 이를 강제합니다. Radicale 문서에 따르면 macOS Calendar.app은 보안이 적용되지 않은 HTTP를 통해 자격 증명을 전송하는 것을 조용히 거부할 수 있으며, iOS도 동일하게 동작합니다. 계정은 설정된 것처럼 보이지만 동기화는 전혀 이루어지지 않으며, 읽을 수 있는 오류 메시지도 표시되지 않습니다.
인증 기관이 확인 작업을 수행하므로 먼저 cal.example.com에 대한 A 레코드를 VPS로 지정하십시오. 그런 다음 /etc/nginx/sites-available/cal.example.com을 생성합니다.
server {
listen 80;
server_name cal.example.com;
location / {
proxy_pass http://localhost:5232/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_pass_header Authorization;
}
location = /.well-known/caldav { return 301 https://$host/; }
location = /.well-known/carddav { return 301 https://$host/; }
}네 줄의 프록시 헤더는 Radicale 문서에서 가져온 것입니다. 그대로 유지하십시오.
sudo ln -s /etc/nginx/sites-available/cal.example.com /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d cal.example.com
curl -i -u you https://cal.example.com/nginx -t은 syntax is ok와 test is successful을 출력합니다. 이 출력이 확인된 후에만 리로드하십시오. 파일에 오류가 있는 상태에서 리로드하면 이전 설정이 계속 실행되어 다음 재시작 전까지 실수를 발견할 수 없기 때문입니다. Certbot은 사이트 파일을 직접 수정합니다. 인증서를 설치하고 블록을 포트 443으로 전환하며 포트 80에서 리다이렉트를 추가합니다. 마지막 curl 명령은 비밀번호를 요구하며, Radicale의 웹 인터페이스인 200를 반환해야 합니다. 502 Bad Gateway가 출력된다면 nginx는 실행 중이지만 Radicale이 5232 포트에서 대기하고 있지 않다는 의미입니다.
휴대폰에서 계정 추가가 실패하는 이유는 무엇입니까?
검색(discovery) 과정 때문입니다. RFC 6764는 클라이언트가 호스트 이름을 어떻게 캘린더 URL로 변환하는지 설명합니다. 클라이언트는 _caldavs._tcp SRV 레코드를 찾은 다음 https://cal.example.com/.well-known/caldav을 요청하고 DAV 루트로의 리다이렉트를 기대합니다. 그곳에서 current-user-principal을 요청하고, 이어서 해당 주체의 calendar-home-set를 요청한 뒤에야 비로소 사용자의 캘린더를 확인합니다. 휴대폰은 서버 주소를 입력하는 필드를 하나만 제공하므로, 모든 단계가 자동으로 성공해야 합니다.
curl -sI https://cal.example.com/.well-known/caldav정상적인 응답은 location: https://cal.example.com/ 헤더를 포함한 HTTP/2 301입니다. iOS에서 계정 정보를 확인할 수 없다고 나오는 이유는 해당 단계에서 404가 발생하기 때문이며, 같은 네트워크의 Thunderbird가 정상 작동하는 이유는 Thunderbird가 사용자가 입력한 전체 URL을 그대로 사용하므로 리다이렉트가 필요 없기 때문입니다.
리다이렉트 대상은 서버에 따라 다릅니다. 사이트 루트에서 서비스되는 Radicale은 /으로 리다이렉트합니다. Baikal은 /dav.php로 308 상태 코드를 반환하는 샘플 규칙을 제공합니다. Nextcloud는 /remote.php/dav/로 리다이렉트합니다.
캘린더 생성 및 파트너와 공유
많은 클라이언트가 캘린더를 직접 생성하지 못하고 구독만 가능합니다. 브라우저에서 https://cal.example.com/을 열고 you 계정으로 로그인하여 캘린더를 생성하십시오. 디스크상에서는 /var/lib/radicale/collections/collection-root/you/ 경로 아래에 생성된 식별자가 폴더 이름으로 지정되어 저장됩니다.
Radicale의 기본 권한 백엔드는 owner_only입니다. 인증된 계정은 /USERNAME/ 아래에 있는 자신의 컬렉션만 읽고 쓸 수 있으며 다른 데이터에는 접근할 수 없습니다. 대부분의 가정 환경에서는 이 설정이 적절하며, 캘린더를 공유하는 가장 간단한 방법은 제3의 계정을 사용하는 것입니다. htpasswd를 사용하여 household 계정을 생성하고, 해당 계정으로 로그인하여 공유 캘린더를 만든 뒤 각 기기에 두 번째 CalDAV 계정으로 추가하십시오. 이 방식은 캘린더가 해당 계정의 홈 디렉터리 내에 위치하므로 iOS를 포함한 모든 클라이언트에서 정상적으로 작동합니다.
더 세밀한 제어가 필요하다면 규칙 기반 권한 설정으로 전환하십시오. /etc/radicale/config에 다음 내용을 추가하십시오.
[rights]
type = from_file
file = /etc/radicale/rights그런 다음 Radicale 문서의 예제를 참고하여 /etc/radicale/rights를 설정하십시오.
[root]
user: .+
collection:
permissions: R
[principal]
user: .+
collection: {user}
permissions: RW
[own-calendars]
user: .+
collection: {user}/[^/]+
permissions: rw
[shared-household]
user: you|partner
collection: you/2f0a9c1e-1f4c-4c2b-9a1b-0d2f7a5c9e11
permissions: rw대문자와 소문자는 서로 다른 의미를 갖습니다. R와 W은 캘린더나 주소록이 아닌 컬렉션(principal 폴더)에 대한 읽기 및 쓰기 권한을 의미합니다. r과 w은 캘린더 자체에 대한 읽기 및 쓰기 권한을 의미합니다. 해당 식별자를 위에서 확인한 저장 경로상의 실제 캘린더 폴더 이름으로 교체하십시오.
한 가지 분명한 한계가 있습니다. 캘린더 홈 세트만 읽는 클라이언트는 다른 사용자의 경로에 있는 캘린더를 표시하지 못하는데, 이는 탐색 과정에서 해당 경로를 거치지 않기 때문입니다. Thunderbird와 DAVx⁵는 전체 URL을 통해 추가할 수 있지만, iOS는 이를 지원하지 않습니다. 따라서 공유 계정 패턴이 언제나 확실하게 작동하는 방법입니다.
클라이언트 설정하기: 셀프 호스팅 캘린더 운영의 성패가 갈리는 지점
iPhone 및 iPad. 설정 앱을 열고 캘린더(최신 iOS 버전에서는 앱 항목 아래에 위치)로 이동합니다. 캘린더 계정, 계정 추가, 기타, CalDAV 계정 추가를 차례로 선택합니다. 서버 주소에는 cal.example.com를 입력하고 사용자 이름과 비밀번호를 입력합니다. 설명은 단순히 식별을 위한 이름입니다. 계정이 저장되지 않는다면 다시 해당 계정 설정으로 진입하십시오. 고급 보기에서 SSL 사용, 포트, 전체 계정 URL을 확인할 수 있으며, URL을 직접 붙여넣으면 자동 검색 과정을 생략할 수 있습니다.
Android. 기본 내장 CalDAV 클라이언트는 없습니다. F-Droid나 Google Play에서 DAVx⁵를 설치하십시오. 기본 URL https://cal.example.com/과 사용자 이름을 사용하여 계정을 추가한 뒤, 동기화할 캘린더를 선택합니다. DAVx⁵는 Android 캘린더 공급자에 데이터를 기록하므로, 기존에 사용하던 캘린더 앱에서 일정을 바로 확인할 수 있습니다.
Thunderbird. 새 캘린더, 네트워크에 저장, 사용자 이름과 위치 https://cal.example.com/을 입력합니다. 발견된 캘린더 목록이 나타나면 추가할 항목을 선택하십시오.
macOS. 시스템 설정, 인터넷 계정, 다른 계정 추가, CalDAV를 선택합니다. 계정 유형을 수동으로 설정한 뒤 사용자 이름, 비밀번호, 서버 주소를 입력합니다.
CalDAV는 폴링(polling) 방식의 프로토콜입니다. 사양상 푸시(push) 기능을 지원하지 않으므로, 노트북에서 추가한 일정이 휴대폰에 즉시 나타나지 않고 다음 동기화 시점에 반영됩니다. 각 클라이언트에서 허용 가능한 동기화 주기를 설정하십시오. 휴대폰의 경우 동기화 주기가 짧을수록 배터리 소모가 커진다는 점을 유의해야 합니다.
파일로만 구성된 저장소 백업하기
Radicale에서 캘린더는 .ics 파일들의 디렉터리이며, 이벤트당 파일 하나와 컬렉션당 작은 속성 파일 하나로 구성됩니다. 디렉터리를 복사하는 모든 도구로 백업이 가능하며, less으로 백업본을 열어 실제 이벤트가 포함되어 있는지 확인할 수 있습니다. 이는 읽을 수 없는 데이터베이스 덤프보다 확실한 장점입니다.
sudo systemctl stop radicale
sudo tar czf /root/radicale-$(date +%F).tar.gz -C /var/lib/radicale collections
sudo systemctl start radicale아카이브를 생성하는 몇 초 동안 서비스를 중단하여, 파일을 읽는 도중에 클라이언트가 쓰기 작업을 수행하지 않도록 합니다. 백업은 동일한 VPS에 두면 장애 발생 시 함께 소실되므로, 작업 후에는 반드시 서버 외부로 복사해야 합니다. 복구는 역순으로 진행합니다. 아카이브를 추출하고, sudo chown -R radicale:radicale /var/lib/radicale/collections를 수행한 뒤 서비스를 시작하십시오. 모든 클라이언트 또한 캘린더의 로컬 복사본을 가지고 있으므로, 장애 발생 이후 동기화되지 않은 노트북이 데이터의 두 번째 복사본 역할을 합니다.
Baikal과 Nextcloud 중 무엇이 더 적합한가
Baikal 0.12.1은 2026년 8월 5일에 릴리스되었으며 PHP 8.2 이상이 필요합니다. 웹 루트 외부의 압축을 풀고 html 디렉터리만 노출하십시오.
sudo apt install -y php-fpm php-sqlite3 php-xml php-mbstring php-curl unzip
cd /tmp
curl -LO https://github.com/sabre-io/Baikal/releases/download/0.12.1/baikal-0.12.1.zip
sudo unzip -q baikal-0.12.1.zip -d /srv
sudo chown -R www-data:www-data /srv/baikal/Specific /srv/baikal/config이 두 디렉터리는 웹 서버가 쓰기 작업을 수행하는 유일한 경로이므로, 다른 곳은 쓰기 권한이 필요하지 않습니다. nginx 서버 블록 내에서 Baikal 관련 설정은 다음과 같습니다.
root /srv/baikal/html;
index index.php;
location ~ /(\.ht|Core|Specific|config) { deny all; }
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location = /.well-known/caldav { return 308 /dav.php; }
location = /.well-known/carddav { return 308 /dav.php; }nginx를 리로드하고 브라우저에서 사이트를 열면 설정 마법사가 관리자 계정과 SQLite 데이터베이스를 생성합니다. 클라이언트 설정은 Radicale과 동일하며, well-known 규칙이 검색 요청을 /dav.php로 전달하므로 서버 주소로 https://cal.example.com/을 사용합니다.
Nextcloud는 파일 저장과 모바일 앱을 동일한 계정으로 사용하려는 경우에만 가치가 있습니다. Nextcloud의 DAV 루트는 /remote.php/dav/이며, 동일한 검색 규칙이 적용됩니다. 어떤 서비스를 선택하든 컨테이너에서 실행하면 호스트의 PHP 버전과 격리할 수 있습니다. VPS에서의 Docker Compose는 compose 파일과 앞단의 리버스 프록시 설정을 다루며, 2026년에 직접 호스팅할 가치가 있는 것은 어느 정도 수준까지 직접 운영할지 결정하는 데 도움이 되는 자료입니다.
Failure modes and the strings you will see
Every sync returns 401. Either the password file lost its accounts to a second htpasswd -c, or the radicale user cannot read it. Check with sudo -u radicale cat /etc/radicale/users; a permission denied there is your answer, and the fix is group radicale with mode 640. Radicale also waits one second after each failed login by default, so a client with a stale password looks slow rather than rejected.
nginx answers 405 on PROPFIND. The URL is being served as a static file, so the WebDAV method never reaches Radicale. Test the endpoint directly:
curl -u you -X PROPFIND -H "Depth: 0" -i https://cal.example.com/you/A working DAV collection answers 207 Multi-Status. Anything else means the request stopped in the web server.
The phone cannot verify the account, and the browser is happy. Two usual causes. The well-known redirect is missing, tested with the curl above. Or the certificate chain is incomplete, which browsers paper over by fetching the missing intermediate while iOS does not. Check it from the shell:
openssl s_client -connect cal.example.com:443 -servername cal.example.com </dev/nullLook for Verify return code: 0 (ok). If it fails, the nginx config is pointing at cert.pem where it should point at fullchain.pem.
Duplicate events after an import. Each event carries a UID, and clients treat that as identity. Import the same file twice through a tool that regenerates identifiers and you get two events that nothing will ever merge. Delete the extra copies on one device and let the deletion sync out.
It all stops working after a reboot. The service was started by hand. sudo systemctl is-enabled radicale prints disabled, and sudo systemctl enable --now radicale fixes it for good.
FAQ
자가 호스팅 CalDAV 서버에 TLS가 반드시 필요한가요?
네, 필요합니다. CalDAV는 HTTP Basic 인증을 사용하므로 비밀번호가 모든 요청마다 base64로 인코딩되어 전송되는데, base64는 쉽게 복호화할 수 있습니다. 클라이언트 측에서도 이를 강제합니다. macOS의 Calendar.app은 보안되지 않은 HTTP를 통한 자격 증명 전송을 조용히 거부할 수 있으며, iOS도 동일하게 동작하여 계정이 저장된 것처럼 보이지만 실제로는 동기화가 전혀 이루어지지 않습니다. sudo certbot --nginx -d cal.example.com이 이 모든 문제를 해결합니다.
Thunderbird에서는 잘 되는데 왜 휴대폰에서는 계정 추가에 실패하나요?
Thunderbird는 사용자가 입력한 전체 URL을 그대로 사용합니다. 반면 휴대폰은 서버 주소 필드 하나만 제공하므로 RFC 6764 검색 절차를 따릅니다. 즉, https://cal.example.com/.well-known/caldav를 요청하고 DAV 루트로의 리다이렉트를 기대합니다. 이 리다이렉트가 없으면 휴대폰은 404 오류를 반환하며 계정을 확인할 수 없다고 보고합니다. nginx에 location = /.well-known/caldav { return 301 https://$host/; }을 추가한 뒤, curl -sI https://cal.example.com/.well-known/caldav를 사용하여 301 리다이렉트와 location 헤더가 정상적으로 응답하는지 확인하십시오.
두 사람이 하나의 캘린더를 공유할 수 있나요?
네, 가능합니다. 가장 확실한 방법은 공유용 계정을 사용하는 것입니다. htpasswd으로 세 번째 계정을 생성하고 그 아래에 공유 캘린더를 배치한 뒤, 각 기기에 두 번째 CalDAV 계정으로 추가하십시오. Radicale의 권한 파일(rights file)을 통해 특정 사용자에게 다른 사용자의 경로 아래에 있는 컬렉션에 대한 읽기 및 쓰기 권한을 부여할 수도 있습니다. 하지만 자신의 캘린더 홈 세트만 읽는 클라이언트는 이를 표시하지 않으므로, 이 방식은 iOS보다는 Thunderbird나 DAVx⁵에 더 적합합니다.
VPS가 중단되면 내 일정 데이터는 어떻게 되나요?
Radicale의 저장소는 일반 텍스트 형식입니다. /var/lib/radicale/collections/collection-root/ 경로 아래에 이벤트당 하나의 .ics 파일이 생성되므로, tar로 백업하고 less으로 내용을 읽을 수 있습니다. 복구하려면 데이터를 추출하고 chown -R radicale:radicale을 수행한 뒤 서비스를 시작하면 됩니다. 동기화된 모든 클라이언트도 로컬 복사본을 유지하므로, 서버 장애 직전까지 동기화된 노트북에는 캘린더의 전체 복사본이 남아 있습니다.
CalDAV 서버가 연락처도 동기화해주나요?
연락처는 RFC 6352에 정의된 형제 프로토콜인 CardDAV를 사용하며, 이벤트 대신 vCard 파일을 저장합니다. Radicale, Baikal, Nextcloud 모두 동일한 계정과 호스트 이름으로 이 서비스를 제공합니다. Android에서는 DAVx⁵가 하나의 계정으로 캘린더와 연락처를 모두 동기화합니다. iOS에서는 동일한 자격 증명을 사용하여 CardDAV 유형의 계정을 하나 더 추가해야 합니다. 이것이 바로 /.well-known/carddav 리다이렉트 설정을 nginx 구성 파일의 CalDAV 설정 옆에 함께 배치해야 하는 이유입니다.