sync iCloud calendar with CalDAV calendar
December 30, 2025•630 words
Ubuntu 24.04
We all sync our agendas. It means that your calendar is synchronized with a server and, probably, from the server synchronized with another client. So your laptop is in sync with your phone etc.
I was looking, however, for a tool to sync my Apple iCloud calendar with a calendar on my private SOGo-account (with CalDAV support). So in this respect 'syncing' means keeping two different agendas the same.
A simple way to do this is OneCal. But I don't want to share my credentials or calendar data with a third party. I want it to do on my own.
This is where the command line tool vdirsyncer comes to the rescue.
1- install vdirsyncer
This is rather straightforward.
apt install vdirsyncer
My version is 0.19.2:
vdirsyncer --version
vdirsyncer, version 0.19.2
2- create config file
Choose a path for your config and vdirsyncer working file(s), and create a DRAFT config file.
mkdir /opt/vdirsyncer
mkdir /opt/vdirsyncer/status
cd /opt/vdirsyncer
vi config
The content of the draft config contains the credentials of both your iCloud and SOGo/CalDAV-accounts:
[general]
status_path = "/opt/vdirsyncer/status/"
[pair my_cals]
a = "icloud"
b = "sogo"
collections = ["from a", "from b"]
metadata = ["displayname", "color"]
conflict_resolution ="a wins"
[storage icloud]
type = "caldav"
url = "https://caldav.icloud.com/"
username = "APPLEID"
password = "PASSWORD1"
[storage sogo]
type = "caldav"
url = "https://SERVER/SOGo/dav"
username = "SOGOLOGIN"
password = "PASSWORD2"
NOTES:
- PASSWORD1 is not your main AppleID-password, but a app-specific password. Create one here: https://support.apple.com/en-us/102654
- SOGOLOGIN is probably your full email address used on the SOGo system.
- The metadata tag takes care of synchronization of displayname and color. Remove it if not wanted.
- The conflict_resolution tag tells that in any conflict iCloud overrules (but it remains a two-way-sync!).
- This config is DRAFT and must be tuned to get it work, see step 3.
3- discover
This step is needed to match the calendar IDs of both agendas.
cd /opt/vdirsyncer
vdirsyncer -c /opt/vdirsyncer/config discover
Some information about both sides is shown:
Discovering collections for pair my_cals
icloud:
- "tasks" ("AgendaName")
- "8EBE0B9B-79EB-4050-A243-ABCDEF012345" ("CalendarA")
- "961E9995-5353-4D1D-BADC-ABCDEF012345" ("CalendarB")
sogo:
- "personal" ("CalenderC")
Saved for my_cals: collections = ["coll"]
It says there a two calandars on iCloud and one on SOGo. Now take the right IDs and add them to the config (line containing 'collections'):
[general]
status_path = "/opt/vdirsyncer/status/"
[pair my_cals]
a = "icloud"
b = "sogo"
collections = [["coll", "961E9995-5353-4D1D-BADC-ABCDEF012345", "personal"]]
metadata = ["displayname", "color"]
conflict_resolution ="a wins"
[storage icloud]
type = "caldav"
url = "https://caldav.icloud.com/"
username = "APPLEID"
password = "PASSWORD1"
[storage sogo]
type = "caldav"
url = "https://SERVER/SOGo/dav"
username = "SOGOLOGIN"
password = "PASSWORD2"
4- first run
Now you're good to go. Let's do a first, verbose test run:
cd /opt/vdirsyncer
vdirsyncer -c /opt/vdirsyncer/config -v INFO sync --dry-run
Check the output if it's working as expected. If so, remove the --dry-run tag and do a real one.
It is not a bad idea to create a backup of your calendars first (see e.g. https://support.apple.com/guide/calendar/import-or-export-calendars-icl1023/mac ).
If you run into problems and have to repeat previous steps make sure to have the database cleaned:
cd /opt/vdirsyncer/status
rm -r *
5- schedule
To sync the calendars every X minutes, add a cron job:
crontab -e
# Add the line below (runs every 10 minutes)
*/10 * * * * /bin/sh -c "/usr/bin/vdirsyncer -c /opt/vdirsyncer/config -v ERROR sync >> /var/log/vdirsyncer.log 2>&1"
6- etc
There's good documentation on vdirsyncer's website.
Use this directive to force a full sync:
# Force a full re‑download of everything
vdirsyncer sync --force-sync
The above configuration can be used to sync two SOGo-/CalDAV-accounts also.
-jer