====== Radicale ======
[[https://radicale.org/v3.html|Radicale]] is a CalDAV/CardDAV server. It can be used to store your contacts and calendars, and i will show you how to install also [[https://github.com/ckulka/infcloud-docker|InfCloud]] as a WEB GUI to it.
[[https://en.wikipedia.org/wiki/Web-based_Distributed_Authoring_and_Versioning|CalDAV]] is the WebDAV extension to manage Calendars
[[https://en.wikipedia.org/wiki/CardDAV|CardDAV]] is the WebDAV extension to manage address books and contacts in general.
To add support for both, which will allow your phone to sync contacts and calendars with your home server, i choose to use the great, simple and effective [[https://radicale.org/v3.html|Radicale]] server.
Please note that Radicale do not provide a user-interface to **edit** or **use** calendars or contacts, you need third party apps for that, and the one i am currently using is [[https://github.com/ckulka/infcloud-docker|InfCloud]], see installation instructions at the bottom of this page.
To install radicale, of course, you need it's dedicated user, so add user:
useradd -d /data/daemons/radicale -m radicale
Create data folder:
mkdir /data/cardcal
chown radicale:radicale /data/cardcal
Radicale uses //pip//, so as usual enable it on Gentoo for user Radicale by creating the file **/data/daemons/radicale/.config/pip/pip.conf** with this content:
[global]
break-system-packages = true
user = true
Install as user radicale:
su - radicale
pip install --upgrade radicale
Create the config file **~/.config/radicale/config**:
[server]
# Bind all addresses
hosts = 127.0.0.1:5232
[auth]
type = http_x_remote_user
#htpasswd_filename = ~/.config/radicale/users
#htpasswd_encryption = md5
[storage]
filesystem_folder = /data/cardcal
then start it:
su - radicale
radicale
==== Reverse Proxy ====
Radicale can be hosted both on subdomain or subpath, but i choose subdomain to make it easier to also host InfCloud on the same subdomain.
As usual you want it protected by the Reverse Proxy, so create the **radicale.conf** file:
server {
server_name radicale.mydomain.com;
listen 443 ssl;
listen 8443 ssl;
http2 on;
include "com.mydomain/authelia_location-basic.conf";
access_log /var/log/nginx/radicale.mydomain.com_access_log main;
error_log /var/log/nginx/radicale.mydomain.com_error_log info;
location / { # The trailing / is important!
proxy_pass http://127.0.0.1:5232/; # The / is important!
proxy_set_header X-Script-Name /;
proxy_set_header X-Remote-User $remote_user;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass_header Authorization;
include "com.mydomain/authelia_proxy.conf";
include "com.mydomain/authelia_authrequest-basic.conf";
}
location /gui/ { # The trailing / is important!
proxy_pass http://127.0.0.1:5233/; # The / is important!
proxy_set_header X-Script-Name /;
proxy_set_header X-Remote-User $remote_user;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass_header Authorization;
}
include com.mydomain/certbot.conf;
}
add this config file to NGINX (see [[selfhost:nginx|The Reverse Proxy concept]] for more details) and restart nginx.
This set-up links also Radicale to your SSO (see [[selfhost:sso|this page]], which is a good approach, but please note that this will make access to the radicale web ui (not the WEB GUI InfCloud) a bit more awkward as the Radicale login window cannot be disabled, and the user will need double authentication.
Now go with browser to **https://radicale.mydomain.com** to finish setup.
=== URLs summary ===
The following URL's are exposed between Radicale and InfCloud:
* https://radicale.mydomain.com: server web access, will redirect to ".web" and let you create calendars
* https://radicale.mydomain.com/gui/: InfCloud, client GUI to actually edit and access your calendars and contacts
And, last, when setting up your *DAV clients (like on Android or similar), use **https://radicale.mydomain.com** as server URL.
===== Startup =====
Since i use OpenRC, to start radicale simply create the following script under /etc/init.d:
#!/sbin/openrc-run
# Copyright 1999-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
description="Radicale WebDAV / WebCAL server"
pidfile="/run/radicale.pid"
command_background=true
command="/data/daemons/radicale/.local/bin/radicale"
command_args=""
command_user="radicale:users"
depend() {
need net
}
Make it executable and add the service to the default runlevel:
chmod +x /etc/init.d/radicale
rc-update add radicale default
==== Sharing calendars ====
Radicale doesn't directly support sharing calendars (see [[https://github.com/Kozea/Radicale/issues/696|here]]) but it's pretty easy to share calendars between users anyway by creating simple symlinks.
So, first of all login on Radicale web GUI with all the users you want to share the calendar with, then create in one of them the actual calendar.
At this point, you only need to link the calendar folder inside all he users:
ln -s /data/cardcal/collection-root/user1/72757af3-557c-e8e4-bdd7-c9bc5689b862 /data/cardcal/collection-root/user2/
and that's it.
====== WEB GUI for Radicale ======
[[https://inf-it.com/open-source/clients/infcloud/|InfCloud]] is a nice javascript WEB GUI for Radicale. It's a bit old-style, but solid and pretty usable. I strongly suggest to go the container way and use this [[https://github.com/ckulka/infcloud-docker|InfCloud docker]] solution here, which is pretty nice and easy to setup.
First of all, to avoid cross-domain issues (CORS) which are hard to solve due to using SSO on Radicale itself, i will host InfCloud on the same radicale domain, using the **/gui/** subpath.
First of all, setup the docker-compose file **/data/daemons/radicale/docker-compose.yml**:
version: "3"
services:
infcloud:
image: ckulka/infcloud
restart: always
depends_on:
- php
ports:
- "5233:80"
volumes:
- infcloud:/usr/share/nginx/infcloud
- ./config.js:/usr/share/nginx/infcloud/config.js:ro
php:
image: php:7.3-fpm-alpine
restart: always
volumes:
- infcloud:/usr/share/nginx/infcloud:ro
volumes:
infcloud:
Now, create the **/data/daemons/radicale/config.js**:
var globalNetworkCheckSettings={
href: "https://radicale.mydomain.com/",
timeOut: 90000,
lockTimeOut: 10000,
checkContentType: true,
settingsAccount: true,
delegation: true,
additionalResources: [],
hrefLabel: null,
forceReadOnly: null,
ignoreAlarms: false,
backgroundCalendars: []
};
var globalInterfaceLanguage='it_IT';
var globalSearchTransformAlphabet={
'[ÀàÁáÂâÄ䯿ÃãÅåĀā]': 'a', '[ÇçĆćČč]': 'c', '[Ďď]': 'd',
'[ÈèÉéÊêËëĒēĖėĘęĚě]': 'e', '[Ğğ]': 'g', '[ÌìÍíÎîİıÏïĪīĮį]': 'i',
'[ŁłĹ弾]': 'l', '[ŃńÑñŇň]': 'n', '[ÒòÓóÔôÖöŐőŒœØøÕõŌō]': 'o',
'[ŔŕŘř]': 'r', '[ŚśŠšȘșŞşẞß]': 's', '[ŤťȚțŢţ]': 't',
'[ÙùÚúÛûÜüŰűŮůŪū]': 'u', '[ÝýŸÿ]': 'y', '[ŹźŻżŽž]': 'z'
};
var globalSortAlphabet=' 0123456789'+
'AÀÁÂÄÆÃÅĀBCÇĆČDĎEÈÉÊËĒĖĘĚFGĞHIÌÍÎİÏĪĮJKLŁĹĽMNŃÑŇOÒÓÔÖŐŒØÕŌ'+
'PQRŔŘSŚŠȘșŞşẞTŤȚțŢţUÙÚÛÜŰŮŪVWXYÝŸZŹŻŽ'+
'aàáâäæãåābcçćčdďeèéêëēėęěfgğhiìíîïīįıjklłĺľmnńñňoòóôöőœøõō'+
'pqrŕřsśšßtťuùúûüűůūvwxyýÿzźżžАБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЮЯ'+
'Ьабвгґдеєжзиіїйклмнопрстуфхцчшщюяь';
var globalBackgroundSync=true;
var globalSyncResourcesInterval=120000;
var globalEnableRefresh=false;
var globalEnableKbNavigation=true;
var globalInterfaceCustomLanguages=[];
var globalResourceAlphabetSorting=true;
var globalNewVersionNotifyUsers=[];
var globalDatepickerFirstDayOfWeek=1;
var globalHideInfoMessageAfter=1800;
var globalEditorFadeAnimation=666;
var globalEventStartPastLimit=3;
var globalEventStartFutureLimit=3;
var globalTodoPastLimit=1;
var globalLoadedCalendarCollections=[];
var globalLoadedTodoCollections=[];
var globalActiveCalendarCollections=[];
var globalActiveTodoCollections=[];
var globalActiveView='multiWeek';
var globalOpenFormMode='double';
var globalTodoListFilterSelected=['filterAction', 'filterProgress'];
var globalCalendarStartOfBusiness=8;
var globalCalendarEndOfBusiness=17;
var globalDefaultEventDuration=120;
var globalDisplayHiddenEvents=false;
var globalTimeZoneSupport=true;
var globalTimeZone='Europe/Berlin';
var globalTimeZonesEnabled=[];
var globalRewriteTimezoneComponent=true;
var globalRemoveUnknownTimezone=false;
var globalShowHiddenAlarms=false;
var globalIgnoreCompletedOrCancelledAlarms=true;
var globalMozillaSupport=false;
var globalWeekendDays=[0, 6];
var globalAppleRemindersMode=true;
var globalLoadedAddressbookCollections=[];
var globalActiveAddressbookCollections=[];
var globalCompatibility={anniversaryOutputFormat: ['apple']};
var globalUriHandlerTel='tel:';
var globalUriHandlerEmail='mailto:';
var globalUriHandlerUrl='http://';
var globalUriHandlerProfile={
'twitter': 'http://twitter.com/%u',
'facebook': 'http://www.facebook.com/%u',
'flickr': 'http://www.flickr.com/photos/%u',
'linkedin': 'http://www.linkedin.com/in/%u',
'myspace': 'http://www.myspace.com/%u',
'sinaweibo': 'http://weibo.com/n/%u'
};
var globalDefaultAddressCountry='us';
var globalAddressCountryEquivalence=[
{country: 'de', regex: '^\\W*Deutschland\\W*$'},
{country: 'sk', regex: '^\\W*Slovensko\\W*$'}
];
var globalAddressCountryFavorites=[];
var globalContactStoreFN=['prefix',' last',' middle',' first',' suffix'];
var globalGroupContactsByCompanies=false;
var globalContactDataMinVisiblePercentage=0.95;
Edit to your likings, more detail can be found [[https://github.com/ckulka/infcloud-docker/blob/master/examples/config.js|here]].
Now create the startup config script **/etc/conf.d/user-containers.infCloud**:
USER=radicale
DESCRIPTION="WEB GUI for Radicale"
Create the link and start it:
cd /etc/init.d/
ln -s user-containers user-containers.infCloud
rc-update add user-containers.infCloud default
./user-containers.infCloud start
Now point your browser to **https://radicale.mydomain.com/gui/** to access infCloud.