SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor

VPS पर अपना CalDAV कैलेंडर सर्वर कैसे सेटअप करें

Google के बिना अपने फोन और लैपटॉप पर कैलेंडर सिंक करने के लिए Radicale का उपयोग करें। इस गाइड में TLS, discovery और सर्वर कॉन्फ़िगरेशन के साथ सुरक्षित सेटअप की पूरी प्रक्रिया दी गई है।

आप क्या बना रहे हैं

एक self-hosted calendar आपके नियंत्रण वाले VPS पर स्थित एक CalDAV सर्वर है, जो TLS के पीछे सुरक्षित है और जिसमें प्रति व्यक्ति एक login होता है। आपकी जेब में मौजूद फोन और डेस्क पर रखा लैपटॉप एक ही events दिखाते हैं, और आपके साथी का लैपटॉप भी यही करता है। इसमें बीच में कोई Google account नहीं होता।

यह self-hosted booking page से अलग काम है। Booking page अजनबियों के लिए होता है: यह आपके खाली समय (free slots) को प्रकाशित करता है और किसी को उसे बुक करने की अनुमति देता है। Calendar सर्वर आपके अपने उपकरणों के लिए है: यह events को स्टोर करता है और हर client को सिंक में रखता है। लोग अक्सर दोनों का उपयोग करते हैं, और booking tool अपनी उपलब्धता की जानकारी उस CalDAV सर्वर से पढ़ता है जिसे आप यहाँ बनाएंगे।

इसका इंस्टॉलेशन छोटा है। Radicale एक Python package है और इसमें लगभग दस लाइन की config होती है। यह सेटअप पहले महीने के बाद भी चलेगा या नहीं, यह TLS, discovery, प्रति उपयोगकर्ता collections और backups पर निर्भर करता है। नीचे दिए गए विवरण में इन्हीं विषयों पर सबसे अधिक ध्यान दिया गया है।

CalDAV क्या है, और यह क्यों महत्वपूर्ण है?

CalDAV HTTP पर कैलेंडर सिंक करने की तकनीक है। इसे RFC 4791 में WebDAV (वेब डिस्ट्रीब्यूटेड ऑथरिंग एंड वर्ज़निंग, RFC 4918 में परिभाषित अतिरिक्त HTTP मेथड्स का एक समूह) के एक्सटेंशन के रूप में परिभाषित किया गया है। एक कैलेंडर एक कलेक्शन है, जो एक डायरेक्टरी की तरह काम करता है। एक इवेंट इसके अंदर एक फाइल होती है, जिसे iCalendar टेक्स्ट फॉर्मेट (RFC 5545) में लिखा जाता है, जो आपके मेल में मौजूद .ics अटैचमेंट जैसा ही फॉर्मेट है।

क्लाइंट्स कुछ अतिरिक्त मेथड्स के साथ सामान्य HTTP का उपयोग करते हैं। PROPFIND पूछता है कि यहाँ क्या है और इसकी क्या प्रॉपर्टीज हैं। REPORT एक फिल्टर्ड स्लाइस मांगता है, जैसे कि एक निश्चित तारीख सीमा के भीतर सभी इवेंट्स। PUT एक इवेंट को लिखता है और DELETE उसे हटा देता है। प्रत्येक इवेंट में एक UID लाइन होती है, और इसी आइडेंटिफायर के जरिए दो डिवाइस यह तय करते हैं कि वे एक ही इवेंट देख रहे हैं, न कि उसकी कोई कॉपी।

पोर्टेबिलिटी इसका सबसे बड़ा लाभ है, और यही इसे इस्तेमाल करने का मुख्य कारण है। iOS, macOS, Thunderbird, Evolution और DAVx⁵ के माध्यम से Android, सभी CalDAV का समर्थन करते हैं। आपका डेटा उस सर्वर से नहीं बंधा है जिसे आपने आज चुना है। फाइल्स को किसी दूसरे CalDAV सर्वर पर ले जाएं, क्लाइंट्स को नए होस्टनेम पर पॉइंट करें, और बाकी सब कुछ वैसा ही रहता है।

CardDAV भी इसी के साथ काम करता है। यह कॉन्टैक्ट्स के लिए भी वही विचार है, जिसे RFC 6352 में परिभाषित किया गया है और यह इवेंट्स के बजाय vCard फाइल्स को स्टोर करता है। नीचे दिए गए सभी सर्वर्स एक ही अकाउंट से दोनों प्रोटोकॉल सर्व करते हैं, इसलिए एक बार कैलेंडर काम करने लगे, तो एड्रेस बुक को सेटअप करना केवल एक चेकबॉक्स का काम है।

आपको कौन सा CalDAV सर्वर चलाना चाहिए?

Radicale सबसे छोटा और प्रभावी विकल्प है। यह Python पर आधारित है, इसमें किसी database की आवश्यकता नहीं होती, और डेटा साधारण फाइलों के एक फोल्डर में स्टोर होता है। यह गाइड इसका उपयोग करती है क्योंकि घरेलू कैलेंडर के लिए इससे अधिक की आवश्यकता नहीं होती, और रात के तीन बजे इसमें कुछ भी गलत होने की संभावना बहुत कम होती है।

Baikal वह विकल्प है जिसमें वेब एडमिन पैनल मिलता है। यह PHP और sabre/dav लाइब्रेरी पर चलता है, उपयोगकर्ताओं और कैलेंडर को SQLite या MySQL में रखता है, और आपको कमांड लाइन के बजाय ब्राउज़र में ही नया व्यक्ति जोड़ने की सुविधा देता है। इसे तब चुनें जब खाते अक्सर बनते और हटाए जाते हों।

Nextcloud तब सही विकल्प है जब कैलेंडर कई सुविधाओं में से केवल एक हो। आपको कैलेंडर, कॉन्टैक्ट्स, फाइलें और एक मोबाइल ऐप मिलता है, लेकिन इसके लिए PHP-FPM, एक database और एक बैकग्राउंड जॉब रनर की आवश्यकता होती है। यदि यह आपकी आवश्यकता के अनुसार बहुत भारी लगता है, तो हल्के Nextcloud विकल्प इस कमी को पूरा करते हैं, और self-hosted file sync उस दूसरे आधे हिस्से को कवर करता है जिसके लिए लोग Nextcloud इंस्टॉल करते हैं।

DAViCal लंबे समय से चला आ रहा PostgreSQL विकल्प है। इसे केवल तभी देखें यदि आप पहले से ही PostgreSQL चला रहे हैं और चाहते हैं कि कैलेंडर डेटा उसी में रहे।

Ubuntu 24.04 पर Radicale इंस्टॉल करें

अगस्त 2026 तक Radicale 3.5.10 वर्तमान release थी। इसे इसके अपने virtual environment में इंस्टॉल करें।

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

Virtual environment का उपयोग केवल एक शैली नहीं है। सिस्टम 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/collections

hosts जानबूझकर loopback पर bind होता है। nginx TLS termination करता है और उस port पर forward करता है, इसलिए Radicale कभी भी सीधे इंटरनेट के संपर्क में नहीं आता है। 0.0.0.0:5232 का upstream उदाहरण एक unencrypted सर्विस पब्लिश करता है जो पासवर्ड स्वीकार करती है, और यही वह एकमात्र गलती है जो यहाँ मायने रखती है।

अब accounts की बात करते हैं। -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 फाइल बनाता है और उसमें मौजूद किसी भी डेटा को हटा देता है। इसका उपयोग केवल पहले उपयोगकर्ता के लिए करें। महीनों बाद फिर से htpasswd -5 -c चलाने पर पहले के बाद जोड़े गए सभी account डिलीट हो जाएंगे, और इसका लक्षण यह होगा कि एक व्यक्ति sync कर पा रहा होगा जबकि बाकी सभी को पासवर्ड प्रॉम्प्ट मिलता रहेगा जो कभी खत्म नहीं होगा। 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.target
sudo systemctl daemon-reload
sudo systemctl enable --now radicale
curl -i http://127.0.0.1:5232/

एक सही परिणाम 401 Unauthorized है जिसमें WWW-Authenticate हेडर होता है: सर्विस listening मोड में है और authentication चालू है। Connection refused का मतलब है कि यह कभी शुरू ही नहीं हुई, और journalctl -u radicale -n 50 उस विकल्प का नाम बताता है जिसे अस्वीकार कर दिया गया। ProtectSystem=strict इस सर्विस के लिए फाइलसिस्टम को read-only मोड में माउंट करता है, इसलिए ReadWritePaths=/var/lib/radicale/ वह लाइन है जो इसे इवेंट सेव करने की अनुमति देती है। उस लाइन को हटाने पर reads काम करते रहेंगे लेकिन हर write विफल हो जाएगा।

TLS अनिवार्य है, क्योंकि क्लाइंट plaintext स्वीकार नहीं करते

CalDAV, HTTP Basic के साथ authenticate करता है, जो हर request पर user:password को base64 encoded रूप में भेजता है। Base64 एक encoding है, encryption नहीं। सादे HTTP पर आप फोन और सर्वर के बीच के हर नेटवर्क को अपना पासवर्ड सौंप देते हैं, और यह हर sync के दौरान होता है।

क्लाइंट आपके लिए इसे लागू करते हैं। Radicale documentation बताता है कि macOS Calendar.app असुरक्षित HTTP पर credentials भेजने से चुपचाप मना कर सकता है, और iOS का व्यवहार भी ऐसा ही है। अकाउंट कॉन्फ़िगर तो दिखता है लेकिन कभी sync नहीं होता, और कोई error भी नहीं दिखाई देता।

सबसे पहले cal.example.com के लिए एक A record को VPS पर point करें, क्योंकि certificate authority इसकी जाँच करती है। फिर /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/; }
}

चारों proxy header लाइनें Radicale documentation से ली गई हैं। उन्हें वैसा ही रहने दें।

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 को प्रिंट करता है। इसके बाद ही reload करें, क्योंकि खराब फाइल के साथ reload करने पर पुरानी config चलती रहती है और अगली restart तक गलती का पता नहीं चलता। Certbot साइट फाइल को सीधे edit करता है: यह certificate install करता है, ब्लॉक को port 443 पर स्विच करता है और port 80 से एक redirect जोड़ता है। अंतिम curl कमांड पासवर्ड मांगता है और उसे 200 लौटाना चाहिए, जो Radicale का अपना वेब इंटरफेस है। 502 Bad Gateway का मतलब है कि nginx चल रहा है लेकिन Radicale 5232 पर listen नहीं कर रहा है।

फोन पर अकाउंट जोड़ने की प्रक्रिया विफल क्यों होती है?

इसका कारण discovery है। RFC 6764 यह बताता है कि एक client किस प्रकार hostname को calendar URL में बदलता है। यह सबसे पहले _caldavs._tcp SRV record की तलाश करता है, फिर https://cal.example.com/.well-known/caldav के लिए अनुरोध भेजता है और DAV root पर redirect की अपेक्षा करता है। वहां से यह current-user-principal के लिए पूछता है, फिर उस principal के calendar-home-set के लिए, और केवल तभी इसे आपके calendars दिखाई देते हैं। फोन में आपको सर्वर के लिए केवल एक field दी जाती है, इसलिए हर चरण का बिना किसी मानवीय हस्तक्षेप के काम करना आवश्यक है।

curl -sI https://cal.example.com/.well-known/caldav

एक सही प्रतिक्रिया HTTP/2 301 होती है जिसमें location: https://cal.example.com/ header शामिल हो। वहां मिलने वाला 404 ही वह कारण है जिसकी वजह से iOS कहता है कि वह account information को verify नहीं कर सकता, जबकि उसी नेटवर्क पर Thunderbird काम करता है: Thunderbird आपके द्वारा टाइप किए गए पूर्ण URL का उपयोग करता है, इसलिए उसे कभी भी redirect की आवश्यकता नहीं पड़ती।

Redirect का लक्ष्य सर्वर पर निर्भर करता है। साइट के root पर serve होने वाला Radicale, / पर redirect करता है। Baikal के साथ आने वाले sample rules /dav.php पर 308 status के साथ redirect करते हैं। Nextcloud /remote.php/dav/ पर redirect करता है।

कैलेंडर बनाएँ और एक को अपने पार्टनर के साथ साझा करें

कई clients कैलेंडर नहीं बना सकते, वे केवल subscribe कर सकते हैं। ब्राउज़र में https://cal.example.com/ खोलें, you के रूप में लॉग इन करें और वहाँ कैलेंडर बनाएँ। डिस्क पर यह /var/lib/radicale/collections/collection-root/you/ के अंतर्गत आता है, जिसमें फ़ोल्डर नाम के लिए एक जनरेट किया गया identifier होता है।

Radicale का डिफ़ॉल्ट rights backend owner_only है: एक authenticated account /USERNAME/ के अंतर्गत केवल अपने स्वयं के collections को पढ़ और लिख सकता है, और कुछ नहीं। अधिकांश घरों के लिए यह सही सेटिंग है, और कैलेंडर साझा करने का सबसे सरल तरीका एक तीसरा account है। household को htpasswd के साथ बनाएँ, उस login के अंतर्गत साझा कैलेंडर बनाएँ, और इसे प्रत्येक device पर दूसरे CalDAV account के रूप में जोड़ें। यह हर client पर काम करता है, जिसमें iOS भी शामिल है, क्योंकि कैलेंडर उस account के अपने home में स्थित होता है।

जब आप अधिक नियंत्रण चाहते हैं, तो rule-based rights पर स्विच करें। इसे /etc/radicale/config में जोड़ें:

[rights]
type = from_file
file = /etc/radicale/rights

फिर Radicale documentation में दिए गए उदाहरण के आधार पर /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 उन collections को पढ़ते और लिखते हैं जो कैलेंडर या address book नहीं हैं, जो कि एक principal फ़ोल्डर होता है। r और w स्वयं कैलेंडरों को पढ़ते और लिखते हैं। उस identifier को ऊपर दिए गए storage path से अपने कैलेंडर के वास्तविक फ़ोल्डर नाम से बदलें।

एक स्पष्ट सीमा: जो client केवल कैलेंडर home set को पढ़ता है, वह किसी अन्य user के path के अंतर्गत स्थित कैलेंडर को प्रदर्शित नहीं करेगा, क्योंकि discovery कभी वहाँ नहीं जाती है। Thunderbird और DAVx⁵ इसे full URL द्वारा जोड़ सकते हैं। iOS ऐसा नहीं कर सकता, इसीलिए साझा account वाला तरीका ही एकमात्र ऐसा तरीका है जो हमेशा काम करता है।

Clients को सेट अप करें, क्योंकि यहीं पर self-hosted calendars काम करना बंद कर देते हैं

iPhone और iPad. Settings खोलें, फिर Calendar (हाल के iOS वर्ज़न में Apps के अंतर्गत), फिर Calendar Accounts, Add Account, Other, Add CalDAV Account पर जाएँ। Server cal.example.com है, उसके बाद user name और password डालें। Description केवल एक लेबल है। यदि यह save करने से मना करे, तो account को फिर से खोलें: advanced view में Use SSL, port और पूरा account URL दिखाई देगा, और URL को paste करने से discovery की प्रक्रिया पूरी तरह skip हो जाती है।

Android. इसमें कोई built-in CalDAV client नहीं है। F-Droid या Google Play से DAVx⁵ इंस्टॉल करें, base URL https://cal.example.com/ और अपने user name का उपयोग करके एक account जोड़ें, फिर उन calendars को tick करें जिन्हें आप चाहते हैं। DAVx⁵ सीधे Android calendar provider में लिखता है, इसलिए events आपके द्वारा पहले से उपयोग किए जा रहे किसी भी calendar app में दिखाई देंगे।

Thunderbird. New Calendar, On the Network, फिर अपना user name और location https://cal.example.com/ डालें। यह उन calendars की सूची दिखाएगा जो इसे मिले हैं और पूछेगा कि कौन से calendars जोड़ने हैं।

macOS. System Settings, Internet Accounts, Add Other Account, CalDAV पर जाएँ, Account Type को Manual पर सेट करें, फिर वही user name, password और server address डालें।

CalDAV एक polling protocol है। specification में कोई push सुविधा नहीं है, इसलिए laptop पर आपके द्वारा जोड़ा गया event फोन पर उसी सेकंड के बजाय अगले sync के समय दिखाई देगा। प्रत्येक client में एक ऐसा interval सेट करें जिसके साथ आप काम कर सकें, और ध्यान रखें कि फोन पर छोटा interval बैटरी की खपत बढ़ाता है।

स्टोर का बैकअप लें, जो केवल फाइलें हैं

Radicale के अंतर्गत आपका कैलेंडर .ics फाइलों की एक निर्देशिका (directory) है, जिसमें प्रत्येक इवेंट के लिए एक फाइल और प्रति कलेक्शन एक छोटी प्रॉपर्टीज फाइल होती है। कोई भी टूल जो निर्देशिका को कॉपी करता है, वह इसका बैकअप ले सकता है, और आप यह पुष्टि करने के लिए कि इसमें वास्तविक इवेंट्स मौजूद हैं, less के साथ बैकअप को खोल सकते हैं। यह डेटाबेस डंप की तुलना में एक वास्तविक लाभ है जिसे आप पढ़ नहीं सकते।

sudo systemctl stop radicale
sudo tar czf /root/radicale-$(date +%F).tar.gz -C /var/lib/radicale collections
sudo systemctl start radicale

आर्काइव बनाने में लगने वाले कुछ सेकंड के लिए सर्विस को रोक दें, ताकि फाइलें पढ़ते समय कोई क्लाइंट राइट (write) प्रक्रिया के बीच में न हो। इसके बाद आर्काइव को बॉक्स से बाहर कॉपी करें, क्योंकि उसी VPS पर रखा गया बैकअप उस विफलता (failure) से नहीं बच पाएगा जिसके लिए आप तैयारी कर रहे हैं। रिस्टोर करना इसकी विपरीत प्रक्रिया है: एक्सट्रैक्ट करें, sudo chown -R radicale:radicale /var/lib/radicale/collections करें, और सर्विस शुरू करें। प्रत्येक क्लाइंट के पास भी अपने कैलेंडर की एक स्थानीय कॉपी होती है, इसलिए विफलता के बाद से जिस लैपटॉप ने सिंक नहीं किया है, वह आपके डेटा की दूसरी कॉपी के रूप में कार्य करता है।

Baikal या Nextcloud में से बेहतर विकल्प का चुनाव

Baikal 0.12.1 को 5 August 2026 को release किया गया था और इसके लिए PHP 8.2 या उससे नया version आवश्यक है। इसे web root के बाहर unpack करें और केवल इसकी html directory को expose करें:

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

ये दो directories ही ऐसी हैं जिनमें web server को write करने की अनुमति चाहिए, इसलिए अन्य किसी भी चीज़ को writable होने की आवश्यकता नहीं है। आपके nginx server block के भीतर, 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 को reload करें, browser में site खोलें, और setup wizard admin account तथा SQLite database बना देगा। Client setup Radicale के समान ही है, जिसमें server address के रूप में https://cal.example.com/ का उपयोग होता है, क्योंकि well-known rule discovery को /dav.php पर भेज देता है।

Nextcloud केवल तभी उपयोगी है यदि आप एक ही login के साथ files और phone app का उपयोग करना चाहते हैं। इसका DAV root /remote.php/dav/ है, और वही discovery rules यहाँ भी लागू होते हैं। इनमें से किसी भी service को container में चलाने से आपके host पर PHP versions का प्रभाव नहीं पड़ता है: Docker Compose on a VPS में compose file और उसके सामने reverse proxy के बारे में जानकारी दी गई है, और what is worth self-hosting in 2026 यह तय करने के लिए एक उचित स्थान है कि आप इस दिशा में कितना आगे बढ़ना चाहते हैं।

विफलता के प्रकार और आपको दिखाई देने वाले स्ट्रिंग्स

प्रत्येक सिंक 401 लौटाता है। या तो पासवर्ड फ़ाइल से खाते किसी दूसरे htpasswd -c के कारण हट गए हैं, या radicale उपयोगकर्ता इसे पढ़ नहीं पा रहा है। sudo -u radicale cat /etc/radicale/users के साथ जाँचें; यदि वहाँ permission denied आता है, तो यही समस्या है, और इसका समाधान समूह radicale को 640 मोड के साथ सेट करना है। Radicale डिफ़ॉल्ट रूप से प्रत्येक विफल लॉगिन के बाद एक सेकंड प्रतीक्षा करता है, इसलिए पुराने पासवर्ड वाला क्लाइंट अस्वीकृत होने के बजाय धीमा दिखाई देता है।

nginx PROPFIND पर 405 उत्तर देता है। URL को एक static फ़ाइल के रूप में serve किया जा रहा है, इसलिए WebDAV विधि Radicale तक कभी नहीं पहुँचती है। endpoint का सीधे परीक्षण करें:

curl -u you -X PROPFIND -H "Depth: 0" -i https://cal.example.com/you/

एक कार्यशील DAV collection 207 Multi-Status उत्तर देता है। इसके अलावा कुछ भी आने का मतलब है कि अनुरोध वेब सर्वर पर ही रुक गया है।

फ़ोन खाते को सत्यापित नहीं कर पा रहा है, लेकिन ब्राउज़र ठीक काम कर रहा है। इसके दो सामान्य कारण हैं। well-known redirect गायब है, जिसे ऊपर दिए गए curl के साथ जाँचा जा सकता है। या certificate chain अधूरी है, जिसे ब्राउज़र गायब intermediate को फ़ेच करके छिपा लेते हैं, जबकि iOS ऐसा नहीं करता है। इसे शेल से जाँचें:

openssl s_client -connect cal.example.com:443 -servername cal.example.com </dev/null

Verify return code: 0 (ok) के लिए देखें। यदि यह विफल रहता है, तो nginx कॉन्फ़िगरेशन cert.pem की ओर इशारा कर रहा है जहाँ इसे fullchain.pem की ओर इशारा करना चाहिए था।

इंपोर्ट के बाद डुप्लिकेट इवेंट्स। प्रत्येक इवेंट में एक UID होता है, और क्लाइंट इसे पहचान के रूप में मानते हैं। यदि आप किसी ऐसे टूल के माध्यम से एक ही फ़ाइल को दो बार इंपोर्ट करते हैं जो पहचानकर्ताओं को पुनर्जीवित करता है, तो आपको दो ऐसे इवेंट मिलेंगे जिन्हें कोई भी मर्ज नहीं कर पाएगा। एक डिवाइस पर अतिरिक्त प्रतियों को हटा दें और विलोपन को सिंक होने दें।

रीबूट के बाद सब कुछ काम करना बंद कर देता है। सर्विस को मैन्युअल रूप से शुरू किया गया था। sudo systemctl is-enabled radicale, disabled प्रिंट करता है, और sudo systemctl enable --now radicale इसे स्थायी रूप से ठीक कर देता है।

FAQ

क्या मुझे वास्तव में self-hosted CalDAV सर्वर के लिए TLS की आवश्यकता है?

हाँ। CalDAV, HTTP Basic authentication का उपयोग करता है, इसलिए पासवर्ड हर request पर base64 encoded होकर जाता है, और base64 को आसानी से डिकोड किया जा सकता है। क्लाइंट्स भी इसे अनिवार्य बनाते हैं: macOS Calendar.app असुरक्षित HTTP पर credentials भेजने से चुपचाप मना कर सकता है, और iOS भी ऐसा ही व्यवहार करता है, जिससे खाता सेव तो हो जाता है लेकिन कभी सिंक नहीं होता। sudo certbot --nginx -d cal.example.com पूरी प्रक्रिया का मुख्य हिस्सा है।

जब Thunderbird काम करता है, तो मेरा फोन खाता जोड़ने में विफल क्यों रहता है?

Thunderbird आपके द्वारा टाइप किए गए पूरे URL का उपयोग करता है। फोन आपको केवल एक सर्वर फ़ील्ड देता है, इसलिए यह RFC 6764 डिस्कवरी का पालन करता है: यह https://cal.example.com/.well-known/caldav के लिए request भेजता है और 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 फ़ाइल किसी नामित उपयोगकर्ता को दूसरे उपयोगकर्ता के पाथ के अंतर्गत एक कलेक्शन पर read और write की अनुमति दे सकती है, लेकिन जो क्लाइंट केवल अपने स्वयं के कैलेंडर होम सेट को पढ़ता है, वह इसे कभी प्रदर्शित नहीं करेगा, इसलिए यह तरीका iOS के बजाय Thunderbird और DAVx⁵ के लिए उपयुक्त है।

यदि VPS बंद हो जाए तो मेरे इवेंट्स का क्या होगा?

Radicale के साथ डेटा plain text में होता है: /var/lib/radicale/collections/collection-root/ के अंतर्गत प्रति इवेंट एक .ics फ़ाइल, जिसका आप tar के साथ बैकअप ले सकते हैं और less के साथ पढ़ सकते हैं। रिस्टोर करने के लिए डेटा निकालें, chown -R radicale:radicale करें, और सर्विस शुरू करें। हर सिंक किया हुआ क्लाइंट एक स्थानीय कॉपी भी रखता है, इसलिए विफलता से पहले जो लैपटॉप अपडेट था, उसमें आपके कैलेंडर की पूरी दूसरी कॉपी मौजूद रहती है।

क्या CalDAV सर्वर मेरे कॉन्टैक्ट्स को भी सिंक करता है?

कॉन्टैक्ट्स CardDAV का उपयोग करते हैं, जो RFC 6352 में परिभाषित एक सह-प्रोटोकॉल है और इवेंट्स के बजाय vCard फ़ाइलों को स्टोर करता है। Radicale, Baikal और Nextcloud सभी इसे एक ही खाते और एक ही होस्टनेम से सर्व करते हैं। Android पर, DAVx⁵ एक ही खाते से कैलेंडर और कॉन्टैक्ट्स को सिंक करता है। iOS पर आप समान credentials के साथ CardDAV प्रकार का दूसरा खाता जोड़ते हैं, यही कारण है कि /.well-known/carddav रीडायरेक्ट आपके nginx कॉन्फ़िगरेशन में CalDAV वाले के बगल में होना चाहिए।

#caldav#calendar#radicale#सेल्फ़-होस्टिंग#sync