From 5b802d136c4352ddd5f96aadd1c0ce8a6f494bc1 Mon Sep 17 00:00:00 2001 From: Github Actions <> Date: Thu, 11 Sep 2025 05:48:19 +0000 Subject: [PATCH] Generate documentation --- master.html | 1429 +++++++++++++++++++++++++++------------------------ 1 file changed, 769 insertions(+), 660 deletions(-) diff --git a/master.html b/master.html index cdc0a4d3..aa489529 100644 --- a/master.html +++ b/master.html @@ -176,23 +176,23 @@ connection between Radicale and the reverse proxy
Hint: instead of downloading from PyPI look for packages provided by -used distribution, they -contain also startup scripts to run daemonized.
You want to try Radicale but only have 5 minutes free in your calendar? Let's go right now and play a bit with Radicale!
-When everything works, you can get a client and start creating calendars and -address books. The server, configured with settings from this section, -only binds to localhost (is not reachable over the network) and you can -log in with any user name and password. When everything works, you may -get a local client and start creating calendars and address books. If -Radicale fits your needs, it may be time for some basic configuration to support remote -clients and desired authentication type.
+The server, configured with settings from this section, only binds to +localhost (i.e. it is not reachable over the network), and you can log +in with any username and password. When everything works, you may get a +local client and start creating +calendars and address books. If Radicale fits your needs, it may be time +for some basic configuration to +support remote clients and desired authentication type.
Follow one of the chapters below depending on your operating system.
Hint: instead of downloading from PyPI, look for packages provided by +your distribution. They +contain also startup scripts integrated into your distributions, that +allow Radicale to run daemonized.
First, make sure that python 3.9 or later and
pip are installed. On most distributions it should be
enough to install the package python3-pip
.
python3-pip
.
python3 -m pip install --user --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
If install is not working and instead
error: externally-managed-environment
is displayed, create
-and activate a virtual environment in advance
python3 -m venv ~/venv
source ~/venv/bin/activate
and try to install with
@@ -348,12 +352,13 @@ userAlternative one can install and run as system user or as root (not -recommended)
-# Run the following command as root (not required)
-# or non-root system user (can require --user in case of dependencies are not available system-wide and/or virtual environment)
+Alternatively, you can install and run as system user or as root (not
+recommended):
+# Run the following command as root (not recommended) or non-root system user
+# (the later may require --user in case dependencies are not available system-wide and/or virtual environment)
python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
-Start the service manually, data is stored in a system folder
+Start the service manually, with data stored in a system folder under
+/var/lib/radicale/collections
:
# Start, data is stored in a system folder (requires write permissions to /var/lib/radicale/collections)
python3 -m radicale --storage-filesystem-folder=/var/lib/radicale/collections --auth-type none
@@ -369,14 +374,13 @@ now". Wait a couple of minutes, it's done!
-m radicale --storage-filesystem-folder=~/radicale/collections --auth-type none python
Victory! Open http://localhost:5232 in your browser! +
Success!!! Open http://localhost:5232 in your browser!
You can log in with any username and password as no authentication is
-required by example option --auth-type none
. But this is
-INSECURE, see Configuration/Authentication for
-more.
--auth-type none
. This is
+INSECURE, see Configuration/Authentication for more details.
Just note that default configuration for security reason binds the
server to localhost
(IPv4: 127.0.0.1
, IPv6:
-::1
). See Addresses and Configuration/Server for more.
::1
). See Addresses and Configuration/Server for more details.
All configuration options are described in detail in the Configuration section.
In its default configuration since 3.5.0 Radicale rejects by default
-all authentication by type = denyall
(introduced with
-3.2.2) until explicitly configured.
Before 3.5.0 it didn't check usernames or passwords if not explicitly -configured, and if the server is reachable over a network, you should -change this as soon as possible.
+In its default configuration since version 3.5.0, Radicale rejects
+all authentication attempts by using config option
+type = denyall
(introduced with 3.2.2) as default until
+explicitly configured.
Versions before 3.5.0 did not check usernames or passwords at all, +unless explicitly configured. If such a server is reachable over a +network, you should change this as soon as possible.
First a users
file with all usernames and passwords must
be created. It can be stored in the same directory as the configuration
file.
The users
file can be created and managed with htpasswd:
Note: some OS contain unpatched htpasswd
(< 2.4.59)
-without supporting SHA-256 or SHA-512 (e.g. Ubuntu LTS 22), in this case
-use '-B' for "bcrypt" hash method or stay with insecure MD5 (default) or
-SHA-1 ('-s').
Note that support of SHA-256 or SHA-512 was introduced with 3.1.9
+Note: some OSes or distributions contain outdated versions of
+htpasswd
(< 2.4.59) without support for SHA-256 or
+SHA-512 (e.g. Ubuntu LTS 22). In these cases use htpasswd
's
+command line option -B
for the bcrypt
hash
+method (recommended), or stay with the insecure (not recommended) MD5
+(default) or SHA-1 (command line option -s
).
Note: support of SHA-256 and SHA-512 was introduced with 3.1.9
# Create a new htpasswd file with the user "user1" using SHA-512 as hash method
$ htpasswd -5 -c /path/to/users user1
New password:
@@ -444,7 +451,7 @@ user2:password2
The default configuration binds the server to localhost. It can't be +
The default configuration binds the server to localhost. It cannot be reached from other computers. This can be changed with the following configuration options (IPv4 and IPv6):
[server]
@@ -458,7 +465,7 @@ the following configuration:
[storage]
filesystem_folder = /path/to/storage
-Security: The storage folder should not be readable
+
Security: The storage folder shall not be readable
by unauthorized users. Otherwise, they can read the calendar data and
lock the storage. You can find OS dependent instructions in the Running as a service section.
@@ -492,89 +499,87 @@ operating system and requirements.
Recommendation: check support by Linux Distribution Packages
instead of manual setup / initial configuration.
Create the radicale user and group for the Radicale
-service. (Run
-useradd --system --user-group --home-dir / --shell /sbin/nologin radicale
-as root.) The storage folder must be writable by
-radicale. (Run
-mkdir -p /var/lib/radicale/collections && chown -R radicale:radicale /var/lib/radicale/collections
-as root.)
-If a dedicated cache folder is configured (see option 'storage' ->
-'filesystem_cache_folder'), it also must be also writable by
-radicale. (Run
-mkdir -p /var/cache/radicale && chown -R radicale:radicale /var/cache/radicale
-as root.)
+service by running (as root
:
+useradd --system --user-group --home-dir / --shell /sbin/nologin radicale
+The storage folder must be writable by the radicale
+user by running (as root
):
+mkdir -p /var/lib/radicale/collections && chown -R radicale:radicale /var/lib/radicale/collections
+If a dedicated cache folder is configured (see option filesystem_cache_folder), it also
+must be also writable by radicale. To achieva that, run
+(as root
):
+mkdir -p /var/cache/radicale && chown -R radicale:radicale /var/cache/radicale
-Security: The storage should not be readable by
-others. (Run chmod -R o= /var/lib/radicale/collections
as
-root.)
+Security: The storage shall not be readable by
+others. To make sure this is the case, run (as root
):
+chmod -R o= /var/lib/radicale/collections
Create the file
/etc/systemd/system/radicale.service
:
-[Unit]
-Description=A simple CalDAV (calendar) and CardDAV (contact) server
-After=network.target
-Requires=network.target
-
-[Service]
-ExecStart=/usr/bin/env python3 -m radicale
-Restart=on-failure
-User=radicale
-# Deny other users access to the calendar data
-UMask=0027
-# Optional security settings
-PrivateTmp=true
-ProtectSystem=strict
-ProtectHome=true
-PrivateDevices=true
-ProtectKernelTunables=true
-ProtectKernelModules=true
-ProtectControlGroups=true
-NoNewPrivileges=true
-ReadWritePaths=/var/lib/radicale/
-# Replace with following in case of dedicated cache folder should be used
-#ReadWritePaths=/var/lib/radicale/ /var/cache/radicale/
-
-[Install]
-WantedBy=multi-user.target
-Radicale will load the configuration file from
-/etc/radicale/config
.
+[Unit]
+Description=A simple CalDAV (calendar) and CardDAV (contact) server
+After=network.target
+Requires=network.target
+
+[Service]
+ExecStart=/usr/bin/env python3 -m radicale
+Restart=on-failure
+User=radicale
+# Deny other users access to the calendar data
+UMask=0027
+# Optional security settings
+PrivateTmp=true
+ProtectSystem=strict
+ProtectHome=true
+PrivateDevices=true
+ProtectKernelTunables=true
+ProtectKernelModules=true
+ProtectControlGroups=true
+NoNewPrivileges=true
+ReadWritePaths=/var/lib/radicale/
+# Replace with following in case dedicated cache folder should be used
+#ReadWritePaths=/var/lib/radicale/ /var/cache/radicale/
+
+[Install]
+WantedBy=multi-user.target
+In this system-wide implementation, Radicale will load the
+configuration from the file /etc/radicale/config
.
To enable and manage the service run:
-# Enable the service
-$ systemctl enable radicale
-# Start the service
-$ systemctl start radicale
-# Check the status of the service
-$ systemctl status radicale
-# View all log messages
-$ journalctl --unit radicale.service
+# Enable the service
+$ systemctl enable radicale
+# Start the service
+$ systemctl start radicale
+# Check the status of the service
+$ systemctl status radicale
+# View all log messages
+$ journalctl --unit radicale.service
Linux with systemd as a user ¶
Create the file
~/.config/systemd/user/radicale.service
:
-[Unit]
-Description=A simple CalDAV (calendar) and CardDAV (contact) server
-
-[Service]
-ExecStart=/usr/bin/env python3 -m radicale
-Restart=on-failure
-
-[Install]
-WantedBy=default.target
-Radicale will load the configuration file from
-~/.config/radicale/config
. You should set the configuration
-option filesystem_folder
in the storage
-section to something like
+
[Unit]
+Description=A simple CalDAV (calendar) and CardDAV (contact) server
+
+[Service]
+ExecStart=/usr/bin/env python3 -m radicale
+Restart=on-failure
+
+[Install]
+WantedBy=default.target
+In this user-specific configuration, Radicale will load the
+configuration from the file ~/.config/radicale/config
. You
+should set the configuration option filesystem_folder
in
+the storage
section to something like
~/.var/lib/radicale/collections
.
To enable and manage the service run:
-# Enable the service
-$ systemctl --user enable radicale
-# Start the service
-$ systemctl --user start radicale
-# Check the status of the service
-$ systemctl --user status radicale
-# View all log messages
-$ journalctl --user --unit radicale.service
+# Enable the service
+$ systemctl --user enable radicale
+# Start the service
+$ systemctl --user start radicale
+# Check the status of the service
+$ systemctl --user status radicale
+# View all log messages
+$ journalctl --user --unit radicale.service
Windows with "NSSM - the Non-Sucking Service Manager" ¶
@@ -639,31 +644,31 @@ below.
}
Example Apache configuration extension:
See also for latest examples: https://github.com/Kozea/Radicale/tree/master/contrib/apache/
-RewriteEngine On
- ^/radicale$ /radicale/ [R,L]
- RewriteRule
-<Location "/radicale/">
- http://localhost:5232/ retry=0
- ProxyPass http://localhost:5232/
- ProxyPassReverse set X-Script-Name /radicale
- RequestHeader set X-Forwarded-Port "%{SERVER_PORT}s"
- RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
- RequestHeader<IfVersion >= 2.4.40>
-
- Proxy100Continue Off</IfVersion>
- </Location>
RewriteEngine On
+ ^/radicale$ /radicale/ [R,L]
+ RewriteRule
+<Location "/radicale/">
+ http://localhost:5232/ retry=0
+ ProxyPass http://localhost:5232/
+ ProxyPassReverse set X-Script-Name /radicale
+ RequestHeader set X-Forwarded-Port "%{SERVER_PORT}s"
+ RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
+ RequestHeader<IfVersion >= 2.4.40>
+
+ Proxy100Continue Off</IfVersion>
+ </Location>
Example Apache .htaccess configuration:
- disabled
- DirectoryIndexRewriteEngine On
- ^(.*)$ http://localhost:5232/$1 [P,L]
- RewriteRule
-# Set to directory of .htaccess file:
- set X-Script-Name /radicale
- RequestHeader set X-Forwarded-Port "%{SERVER_PORT}s"
- RequestHeader unset X-Forwarded-Proto
- RequestHeader<If "%{HTTPS} =~ /on/">
- set X-Forwarded-Proto "https"
- RequestHeader</If>
disabled
+ DirectoryIndexRewriteEngine On
+ ^(.*)$ http://localhost:5232/$1 [P,L]
+ RewriteRule
+# Set to directory of .htaccess file:
+ set X-Script-Name /radicale
+ RequestHeader set X-Forwarded-Port "%{SERVER_PORT}s"
+ RequestHeader unset X-Forwarded-Proto
+ RequestHeader<If "%{HTTPS} =~ /on/">
+ set X-Forwarded-Proto "https"
+ RequestHeader</If>
Example lighttpd configuration:
server.modules += ( "mod_proxy" , "mod_setenv", "mod_rewrite" )
@@ -686,7 +691,7 @@ terminated after a timeout.
Set the configuration option type
in the
auth
section to http_x_remote_user
. Radicale
uses the username provided in the X-Remote-User
HTTP header
-and disables HTTP authentication.
+and disables its internal HTTP authentication.
Example nginx configuration:
location /radicale/ {
proxy_pass http://localhost:5232/;
@@ -709,42 +714,41 @@ and disables HTTP authentication.
}
}
Example Apache configuration:
-RewriteEngine On
- ^/radicale$ /radicale/ [R,L]
- RewriteRule
-<Location "/radicale/">
-AuthType Basic
- "Radicale - Password Required"
- AuthName "/etc/radicale/htpasswd"
- AuthUserFile valid-user
- Require
- http://localhost:5232/ retry=0
- ProxyPass http://localhost:5232/
- ProxyPassReverse<IfVersion >= 2.4.40>
-
- Proxy100Continue Off</IfVersion>
- set X-Script-Name /radicale
- RequestHeader set X-Remote-User expr=%{REMOTE_USER}
- RequestHeader</Location>
+RewriteEngine On
+ ^/radicale$ /radicale/ [R,L]
+ RewriteRule
+<Location "/radicale/">
+AuthType Basic
+ "Radicale - Password Required"
+ AuthName "/etc/radicale/htpasswd"
+ AuthUserFile valid-user
+ Require
+ http://localhost:5232/ retry=0
+ ProxyPass http://localhost:5232/
+ ProxyPassReverse<IfVersion >= 2.4.40>
+
+ Proxy100Continue Off</IfVersion>
+ set X-Script-Name /radicale
+ RequestHeader set X-Remote-User expr=%{REMOTE_USER}
+ RequestHeader</Location>
Example Apache .htaccess configuration:
- disabled
- DirectoryIndexRewriteEngine On
- ^(.*)$ http://localhost:5232/$1 [P,L]
- RewriteRule
-AuthType Basic
- "Radicale - Password Required"
- AuthName "/etc/radicale/htpasswd"
- AuthUserFile valid-user
- Require
-# Set to directory of .htaccess file:
- set X-Script-Name /radicale
- RequestHeader set X-Remote-User expr=%{REMOTE_USER} RequestHeader
+ disabled
+ DirectoryIndexRewriteEngine On
+ ^(.*)$ http://localhost:5232/$1 [P,L]
+ RewriteRule
+AuthType Basic
+ "Radicale - Password Required"
+ AuthName "/etc/radicale/htpasswd"
+ AuthUserFile valid-user
+ Require
+# Set to directory of .htaccess file:
+ set X-Script-Name /radicale
+ RequestHeader set X-Remote-User expr=%{REMOTE_USER} RequestHeader
Security: Untrusted clients should not be able to
access the Radicale server directly. Otherwise, they can authenticate as
any user by simply setting related HTTP header. This can be prevented by
-restrict listen to loopback interface only or at least a local firewall
-rule.
+listening to the loopback interface only or local firewall rules.
@@ -753,24 +757,24 @@ rule.
connection between Radicale and the reverse proxy. First you have to
generate a certificate for Radicale and a certificate for the reverse
proxy. The following commands generate self-signed certificates. You
-will be asked to enter additional information about the certificate, the
-values don't matter and you can keep the defaults.
-openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem \
--nodes -days 9999
- openssl req -x509 -newkey rsa:4096 -keyout client_key.pem -out client_cert.pem \
--nodes -days 9999
+will be asked to enter additional information about the certificate,
+these values do not really matter and you can keep the defaults.
+openssl req -x509 -newkey rsa:4096 -keyout server_key.pem -out server_cert.pem \
+-nodes -days 9999
+ openssl req -x509 -newkey rsa:4096 -keyout client_key.pem -out client_cert.pem \
+-nodes -days 9999
Use the following configuration for Radicale:
-[server]
-ssl = True
-certificate = /path/to/server_cert.pem
-key = /path/to/server_key.pem
-certificate_authority = /path/to/client_cert.pem
-If you're using the Let's Encrypt's Certbot, the configuration should
+
[server]
+ssl = True
+certificate = /path/to/server_cert.pem
+key = /path/to/server_key.pem
+certificate_authority = /path/to/client_cert.pem
+If you are using the Let's Encrypt Certbot, the configuration should
look similar to this:
-[server]
-ssl = True
-certificate = /etc/letsencrypt/live/{Your Domain}/fullchain.pem
-key = /etc/letsencrypt/live/{Your Domain}/privkey.pem
+[server]
+ssl = True
+certificate = /etc/letsencrypt/live/{Your Domain}/fullchain.pem
+key = /etc/letsencrypt/live/{Your Domain}/privkey.pem
Example nginx configuration:
location /radicale/ {
proxy_pass https://localhost:5232/;
@@ -788,60 +792,60 @@ look similar to this:
environment variable, otherwise no configuration file is loaded and the
default configuration is used.
Example uWSGI configuration:
-[uwsgi]
-http-socket = 127.0.0.1:5232
-processes = 8
-plugin = python3
-module = radicale
-env = RADICALE_CONFIG=/etc/radicale/config
+[uwsgi]
+http-socket = 127.0.0.1:5232
+processes = 8
+plugin = python3
+module = radicale
+env = RADICALE_CONFIG=/etc/radicale/config
Example Gunicorn configuration:
-gunicorn --bind '127.0.0.1:5232' --env 'RADICALE_CONFIG=/etc/radicale/config' \
---workers 8 radicale
+gunicorn --bind '127.0.0.1:5232' --env 'RADICALE_CONFIG=/etc/radicale/config' \
+--workers 8 radicale
Manage user accounts with the WSGI server ¶
Set the configuration option type
in the
-auth
section to remote_user
. Radicale uses the
-username provided by the WSGI server and disables authentication over
-HTTP.
+auth
section to remote_user
. This way Radicale
+uses the username provided by the WSGI server and disables its internal
+authentication over HTTP.
-
-Versioning with Git ¶
+
+Versioning collections with Git ¶
This tutorial describes how to keep track of all changes to calendars
and address books with git (or any other version
control system).
The repository must be initialized in the collection base directory
of the user running radicale
daemon.
-## assuming "radicale" user is starting "radicale" service
-# change to user "radicale"
-su -l -s /bin/bash radicale
-
-# change to collection base directory defined in [storage] -> filesystem_folder
-# assumed here /var/lib/radicale/collections
-cd /var/lib/radicale/collections
-
-# initialize git repository
-git init
-
-# set user and e-mail, here minimum example
-git config user.name "$USER"
-git config user.email "$USER@$HOSTNAME"
-
-# define ignore of cache/lock/tmp files
-cat <<'END' >.gitignore
-.Radicale.cache
-.Radicale.lock
-.Radicale.tmp-*
-END
+## assuming "radicale" user is starting "radicale" service
+# change to user "radicale"
+su -l -s /bin/bash radicale
+
+# change to collection base directory defined in [storage] -> filesystem_folder
+# assumed here /var/lib/radicale/collections
+cd /var/lib/radicale/collections
+
+# initialize git repository
+git init
+
+# set user and e-mail, here minimum example
+git config user.name "$USER"
+git config user.email "$USER@$HOSTNAME"
+
+# define ignore of cache/lock/tmp files
+cat <<'END' >.gitignore
+.Radicale.cache
+.Radicale.lock
+.Radicale.tmp-*
+END
The configuration option hook
in the
storage
section must be set to the following command:
-git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"")
+git add -A && (git diff --cached --quiet || git commit -m "Changes by \"%(user)s\"")
The command gets executed after every change to the storage and
commits the changes into the git repository.
Log of git
can be investigated using
-su -l -s /bin/bash radicale
-cd /var/lib/radicale/collections
-git log
+su -l -s /bin/bash radicale
+cd /var/lib/radicale/collections
+git log
In case of problems, make sure you run radicale with
--debug
switch and inspect the log output. For more
information, please visit section on
@@ -860,18 +864,20 @@ logging.
Configuration ¶
Radicale can be configured with a configuration file or with command
line arguments.
+Configuration files have INI-style syntax comprising key-value pairs
+grouped into sections with section headers enclosed in brackets.
An example configuration file looks like:
-[server]
-# Bind all addresses
-hosts = 0.0.0.0:5232, [::]:5232
-
-[auth]
-type = htpasswd
-htpasswd_filename = ~/.config/radicale/users
-htpasswd_encryption = autodetect
-
-[storage]
-filesystem_folder = ~/.var/lib/radicale/collections
+[server]
+# Bind all addresses
+hosts = 0.0.0.0:5232, [::]:5232
+
+[auth]
+type = htpasswd
+htpasswd_filename = ~/.config/radicale/users
+htpasswd_encryption = autodetect
+
+[storage]
+filesystem_folder = ~/.var/lib/radicale/collections
Radicale tries to load configuration files from
/etc/radicale/config
and
~/.config/radicale/config
. Custom paths can be specified
@@ -882,34 +888,32 @@ configuration files can be separated by :
(resp.
optional.
The same example configuration via command line arguments looks
like:
-python3 -m radicale --server-hosts 0.0.0.0:5232,[::]:5232 \
---auth-type htpasswd --auth-htpasswd-filename ~/.config/radicale/users \
- --auth-htpasswd-encryption autodetect
+python3 -m radicale --server-hosts 0.0.0.0:5232,[::]:5232 \
+--auth-type htpasswd --auth-htpasswd-filename ~/.config/radicale/users \
+ --auth-htpasswd-encryption autodetect
Add the argument --config ""
to stop Radicale from
loading the default configuration files. Run
python3 -m radicale --help
for more information.
-One can also use command line options in startup scripts using
-following examples:
-## simple variable containing multiple options
-RADICALE_OPTIONS="--logging-level=debug --config=/etc/radicale/config --logging-request-header-on-debug --logging-rights-rule-doesnt-match-on-debug"
-/usr/bin/radicale $RADICALE_OPTIONS
-
-## variable as array method #1
-RADICALE_OPTIONS=("--logging-level=debug" "--config=/etc/radicale/config" "--logging-request-header-on-debug" "--logging-rights-rule-doesnt-match-on-debug")
-/usr/bin/radicale ${RADICALE_OPTIONS[@]}
-
-## variable as array method #2
-RADICALE_OPTIONS=()
-RADICALE_OPTIONS+=("--logging-level=debug")
-RADICALE_OPTIONS+=("--config=/etc/radicale/config")
-/usr/bin/radicale ${RADICALE_OPTIONS[@]}
-In the following, all configuration categories and options are
-described.
+You can also use command-line options in startup scripts as shown in
+the following examples:
+## simple variable containing multiple options
+RADICALE_OPTIONS="--logging-level=debug --config=/etc/radicale/config --logging-request-header-on-debug --logging-rights-rule-doesnt-match-on-debug"
+/usr/bin/radicale $RADICALE_OPTIONS
+
+## variable as array method #1
+RADICALE_OPTIONS=("--logging-level=debug" "--config=/etc/radicale/config" "--logging-request-header-on-debug" "--logging-rights-rule-doesnt-match-on-debug")
+/usr/bin/radicale ${RADICALE_OPTIONS[@]}
+
+## variable as array method #2
+RADICALE_OPTIONS=()
+RADICALE_OPTIONS+=("--logging-level=debug")
+RADICALE_OPTIONS+=("--config=/etc/radicale/config")
+/usr/bin/radicale ${RADICALE_OPTIONS[@]}
+The following describes all configuration sections and options.
-server ¶
-The configuration options in this category are only relevant in
-standalone mode. All options are ignored, when Radicale runs via
-WSGI.
+[server] ¶
+The configuration options in this section are only relevant in
+standalone mode; they are ignored, when Radicale runs on WSGI.
hosts ¶
A comma separated list of addresses that the server will bind to.
@@ -982,7 +986,7 @@ Format: OpenSSL cipher list (see also "man openssl-ciphers")
-encoding ¶
+[encoding] ¶
request ¶
Encoding for responding requests.
@@ -995,53 +999,59 @@ Format: OpenSSL cipher list (see also "man openssl-ciphers")
-auth ¶
+[auth] ¶
type ¶
The method to verify usernames and passwords.
-Available backends:
-none
: Just allows all usernames and passwords.
-denyall
(>= 3.2.2) : Just denies all
-usernames and passwords.
-htpasswd
: Use an Apache
-htpasswd file to store usernames and passwords.
-remote_user
: Takes the username from the
-REMOTE_USER
environment variable and disables HTTP
-authentication. This can be used to provide the username from a WSGI
-server which authenticated the client upfront. Required to validate,
-otherwise client can supply the header itself which is unconditionally
-trusted then.
-http_x_remote_user
: Takes the username from the
-X-Remote-User
HTTP header and disables HTTP authentication.
-This can be used to provide the username from a reverse proxy which
-authenticated the client upfront. Required to validate, otherwise client
-can supply the header itself which is unconditionally trusted then.
-ldap
(>= 3.3.0) : Use a LDAP or AD server to
-authenticate users by relaying credentials from client and handle
-result.
-dovecot
(>= 3.3.1) : Use a Dovecot server to
-authenticate users by relaying credentials from client and handle
-result.
-imap
(>= 3.4.1) : Use an IMAP server to
-authenticate users by relaying credentials from client and handle
-result.
-oauth2
(>= 3.5.0) : Use an OAuth2 server to
-authenticate users by relaying credentials from client and handle
-result. Oauth2 authentication (SSO) directly on client is not supported.
-Use herefore http_x_remote_user
in combination with SSO
-support in reverse proxy (e.g. Apache+mod_auth_openidc).
-pam
(>= 3.5.0) : Use local PAM to
-authenticate users by relaying credentials from client and handle
-result..
-Default: none
(< 3.5.0) denyall
-(>= 3.5.0)
+Available types are:
+
+none
+Just allows all usernames and passwords.
+denyall
(>= 3.2.2)
+Just denies all usernames and passwords.
+htpasswd
+Use an Apache
+htpasswd file to store usernames and passwords.
+remote_user
+Takes the username from the REMOTE_USER
environment
+variable and disables Radicale's internal HTTP authentication. This can
+be used to provide the username from a WSGI server which authenticated
+the client upfront. Requires validation, otherwise clients can supply
+the header themselves, which then is unconditionally trusted.
+http_x_remote_user
+Takes the username from the X-Remote-User
HTTP header and
+disables Radicale's internal HTTP authentication. This can be used to
+provide the username from a reverse proxy which authenticated the client
+upfront. Requires validation, otherwise clients can supply the header
+themselves, which then is unconditionally trusted.
+ldap
(>= 3.3.0)
+Use a LDAP or AD server to authenticate users by relaying credentials
+from clients and handle results.
+dovecot
(>= 3.3.1)
+Use a Dovecot server to authenticate users by relaying credentials from
+clients and handle results.
+imap
(>= 3.4.1)
+Use an IMAP server to authenticate users by relaying credentials from
+clients and handle results.
+oauth2
(>= 3.5.0)
+Use an OAuth2 server to authenticate users by relaying credentials from
+clients and handle results. OAuth2 authentication (SSO) directly on
+client is not supported. Use herefore http_x_remote_user
in
+combination with SSO support in reverse proxy (e.g.
+Apache+mod_auth_openidc).
+pam
(>= 3.5.0)
+Use local PAM to authenticate users by relaying credentials from client
+and handle result..
+
+Default: none
(< 3.5.0) /
+denyall
(>= 3.5.0)
cache_logins ¶
(>= 3.4.0)
Cache successful/failed logins until expiration time. Enable this to
avoid overload of authentication backends.
-Default: false
+Default: False
cache_successful_logins_expiry ¶
@@ -1062,29 +1072,35 @@ avoid overload of authentication backends.
htpasswd_encryption ¶
-The encryption method that is used in the htpasswd file. Use the htpasswd
+
The encryption method that is used in the htpasswd file. Use htpasswd
or similar to generate this files.
Available methods:
-plain
: Passwords are stored in plaintext. This is
-obviously not secure! The htpasswd file for this can be created by hand
-and looks like:
+
+plain
+Passwords are stored in plaintext. This is not recommended. as it is
+obviously insecure! The htpasswd file for this can be
+created by hand and looks like:
user1:password1
-user2:password2
-bcrypt
: This uses a modified version of the Blowfish
-stream cipher. It's very secure. The installation of
-bcrypt is required for this.
-md5
: This uses an iterated MD5 digest of the password
-with a salt (nowadays insecure).
-sha256
(>= 3.1.9) : This uses an iterated
-SHA-256 digest of the password with a salt.
-sha512
(>= 3.1.9) : This uses an iterated
-SHA-512 digest of the password with a salt.
-argon2
(>= 3.5.3) : This uses an iterated
-ARGON2 digest of the password with a salt. The installation of
-argon2-cffi is required for this.
-autodetect
(>= 3.1.9) : This selects
-autodetection of method per entry.
-Default: md5
(< 3.3.0)
+user2:password2
+bcrypt
+This uses a modified version of the Blowfish stream cipher, which is
+considered very secure. The installation of Python's
+bcrypt module is required for this to work.
md5
+Use an iterated MD5 digest of the password with salt (nowadays
+insecure).
sha256
(>= 3.1.9)
+Use an iterated SHA-256 digest of the password with salt.
sha512
(>= 3.1.9)
+Use an iterated SHA-512 digest of the password with salt.
argon2
(>= 3.5.3)
+Use an iterated ARGON2 digest of the password with salt. The
+installation of Python's argon2-cffi module is required
+for this to work.
autodetect
(>= 3.1.9)
+Automatically detect the encryption method used per user entry.
Default: md5
(< 3.3.0) /
autodetect
(>= 3.3.0)
Average delay after failed login attempts in seconds.
+Average delay (in seconds) after failed login attempts.
Default: 1
LDAP attribute whose value shall be used as the username after successful authentication.
If set, you can use flexible logins in ldap_filter
and
-still have consolidated usernames, e.g. to allow login in using mail
-addresses as an alternative to cn, simply set
ldap_filter = (&(objectclass=inetOrgPerson)(|(cn={0})(mail={0})))
-ldap_user_attribute = cn
+still have consolidated usernames, e.g. to allow users to login using
+mail addresses as an alternative to cn, simply set
+ldap_filter = (&(objectclass=inetOrgPerson)(|(cn={0})(mail={0})))
+ldap_user_attribute = cn
Even for simple filter setups, it is recommended to set it in order to get usernames exactly as they are stored in LDAP and to avoid inconsistencies in the upper-/lower-case spelling of the login @@ -1166,21 +1182,31 @@ username)
(>= 3.3.0)
-Use ssl on the LDAP connection. Deprecated, use
-ldap_security
instead**!**
Use ssl on the LDAP connection. Deprecated! Use
+ldap_security
instead.
(>= 3.5.2)
-Use encryption on the LDAP connection. One of none
,
-tls
, starttls
.
Use encryption on the LDAP connection.
+One of
+none
tls
starttls
Default: none
(>= 3.3.0)
-Certificate verification mode for tls and starttls. One of
-NONE
, OPTIONAL
, REQUIRED
.
Certificate verification mode for tls and starttls.
+One of
+NONE
OPTIONAL
REQUIRED
.Default: REQUIRED
Quirks for Authentik LDAP server, which violates the LDAP RFCs: add modifyTimestamp and createTimestamp to the exclusion list of internal ldap3 client so that these schema attributes are not checked.
-Default: false
Default: False
(>= 3.4.1)
-Connection type for dovecot authentication -(AF_UNIX|AF_INET|AF_INET6)
+Connection type for dovecot authentication.
+One of:
+AF_UNIX
AF_INET
AF_INET6
Note: credentials are transmitted in cleartext
Default: AF_UNIX
(>= 3.3.1)
-The path to the Dovecot client authentication socket (eg. -/run/dovecot/auth-client on Fedora). Radicale must have read / write +
Path to the Dovecot client authentication socket (eg. +/run/dovecot/auth-client on Fedora). Radicale must have read & write access to the socket.
Default: /var/run/dovecot/auth-client
(>= 3.4.1)
-Host of via network exposed dovecot socket
+Host of dovecot socket exposed via network
Default: localhost
(>= 3.4.1)
-Port of via network exposed dovecot socket
+Port of dovecot socket exposed via network
Default: 12345
(>= 3.4.1)
-IMAP server hostname: address | address:port | [address]:port | -imap.server.tld
+IMAP server hostname.
+One of:
+Default: localhost
(>= 3.4.1)
-Secure the IMAP connection: tls | starttls | none
+Secure the IMAP connection:
+One of:
+tls
starttls
none
Default: tls
(>= 3.5.0)
-OAuth2 token endpoint URL
-Default:
+Endpoint URL for the OAuth2 token
+Default: (unset)
(>= 3.5.0)
-PAM service
-Default: radicale
+PAM service name
+Default: radicale
(>= 3.5.0)
PAM group user should be member of
-Default:
+Default: (unset)
Сonvert username to lowercase, must be true for case-insensitive auth -providers like ldap, kerberos
+Сonvert username to lowercase. Recommended to be True
+for case-insensitive auth providers like ldap, kerberos, ...
Default: False
Notes:
lc_username
and uc_username
are mutually
exclusiveldap
the use of
-ldap_user_attribute
is preferredldap_user_attribute
is preferred over
+lc_username
(>= 3.3.2)
-Сonvert username to uppercase, must be true for case-insensitive auth -providers like ldap, kerberos
+Сonvert username to uppercase. Recommended to be True
+for case-insensitive auth providers like ldap, kerberos, ...
Default: False
Notes:
uc_username
and lc_username
are mutually
exclusiveldap
the use of
-ldap_user_attribute
is preferredldap_user_attribute
is preferred over
+uc_username
(>= 3.5.3)
-URL Decode the username. When the username is an email, some clients -send the username URL-encoded (notably iOS devices) breaking the +
URL-decode the username. If the username is an email address, some +clients send the username URL-encoded (notably iOS devices) breaking the authentication process (user@example.com becomes -user%40example.com). This setting will force decoding the username.
+user%40example.com). This setting forces decoding the username.Default: False
The backend that is used to check the access rights of +
Authorization backend that is used to check the access rights to collections.
-The recommended backend is owner_only
. If access to
-calendars and address books outside the home directory of users (that's
-/USERNAME/
) is granted, clients won't detect these
-collections and will not show them to the user. Choosing any other
-method is only useful if you access calendars and address books directly
-via URL.
Available backends:
-authenticated
: Authenticated users can read and write
-everything.
owner_only
: Authenticated users can read and write
-their own collections under the path /USERNAME/.
owner_write
: Authenticated users can read everything
-and write their own collections under the path /USERNAME/.
from_file
: Load the rules from a file.
The default and recommended backend is owner_only
. If
+access to calendars and address books outside the user's collection
+directory (that's /username/
) is granted, clients will not
+detect these collections automatically and will not show them to the
+users. Choosing any other authorization backend is only useful if you
+access calendars and address books directly via URL.
Available backends are:
+authenticated
+Authenticated users can read and write everything.
owner_only
+Authenticated users can read and write their own collections under the
+path /USERNAME/.
owner_write
+Authenticated users can read everything and write their own collections
+under the path /USERNAME/.
from_file
+Load the rules from a file.
Default: owner_only
File for the rights backend from_file
. See the Rights section.
Name of the file containing the authorization rules for the
+from_file
backend. See the Rights section for details.
Default: /etc/radicale/rights
(>= 3.1.9)
-Global control of permission to delete complete collection (default: -True)
-If False it can be permitted by permissions per section with: D
-If True it can be forbidden by permissions per section with: d
+Global permission to delete complete collections.
+False
it can be explicitly granted per collection by
+permissions: D
True
it can be explicitly forbidden per collection
+by permissions: d
Default: True
(>= 3.3.0)
-Global control of permission to overwrite complete collection -(default: True)
-If False it can be permitted by permissions per section with: O
-If True it can be forbidden by permissions per section with: o
+Global permission to overwrite complete collections.
+False
it can be explicitly granted per collection by
+permissions: O
True
it can be explicitly forbidden per collection
+by permissions: o
Default: True
The backend that is used to store data.
-Available backends:
-multifilesystem
: Stores the data in the filesystem.
multifilesystem_nolock
: The
-multifilesystem
backend without file-based locking. Must
-only be used with a single process.
Backend used to store data.
+Available backends are:
+multifilesystem
+Stores the data in the filesystem.
multifilesystem_nolock
+The multifilesystem
backend without file-based locking.
+Must only be used with a single process.
Default: multifilesystem
Folder for storing local collections, created if not present.
+Folder for storing local collections; will be auto-created if not +present.
Default: /var/lib/radicale/collections
(>= 3.3.2)
-Folder for storing cache of local collections, created if not -present
+Folder for storing cache of local collections; will be auto-created +if not present
Default: (filesystem_folder)
-Note: only used in case of use_cache_subfolder_* options are -active
+Note: only used if use_cache_subfolder_* options are active
Note: can be used on multi-instance setup to cache files on local node (see below)
Default: False
Note: use only on single-instance setup, will break consistency with -client in multi-instance setup
+Note: only use on single-instance setup: it will break consistency +with clients in multi-instance setup
Default: False
Note: use only on single-instance setup, will break consistency with -client in multi-instance setup
+Note: only use on single-instance setup: it will break consistency +with clients in multi-instance setup
(>= 3.3.2)
-Use last modifiction time (nanoseconds) and size (bytes) for 'item' -cache instead of SHA256 (improves speed)
+Use last modification time (in nanoseconds) and size (in bytes) for +'item' cache instead of SHA256 (improves speed)
Default: False
Note: check used filesystem mtime precision before enabling
-Note: conversion is done on access, bulk conversion can be done
-offline using storage verification option
-radicale --verify-storage
Notes:
+radicale --verify-storage
(>= 3.3.2)
-Use configured umask for folder creation (not applicable for OS -Windows)
-Default: (system-default, usual 0022
)
Useful value: 0077
(user:rw group:- other:-) or
-0027
(user:rw group:r other:-) or 0007
-(user:rw group:rw other:-) or 0022
(user:rw group:r
-other:r)
umask to use for folder creation (not applicable for OS Windows)
+Default: (system-default, usually 0022
)
Useful values:
+0077
(user:rw group:- other:-)0027
(user:rw group:r other:-)0007
(user:rw group:rw other:-)0022
(user:rw group:r other:r)Delete sync-token that are older than the specified time. -(seconds)
+Delete sync-tokens that are older than the specified time (in +seconds).
Default: 2592000
Command that is run after changes to storage. Take a look at the Versioning with Git tutorial for an -example.
-Default:
+Command that is run after changes to storage. Take a look at the Versioning collections with +Git tutorial for an example.
+Default: (unset)
Supported placeholders:
%(user)s
: logged-in user%(request)s
: request method (>= 3.5.5)Command will be executed with base directory defined in +
The command will be executed with base directory defined in
filesystem_folder
(see above)
Create predefined user collections
+Create predefined user collections.
Example:
- {
- "def-addressbook": {
- "D:displayname": "Personal Address Book",
- "tag": "VADDRESSBOOK"
- },
- "def-calendar": {
- "C:supported-calendar-component-set": "VEVENT,VJOURNAL,VTODO",
- "D:displayname": "Personal Calendar",
- "tag": "VCALENDAR"
- }
- }
-Default:
+{
+"def-addressbook": {
+ "D:displayname": "Personal Address Book",
+ "tag": "VADDRESSBOOK"
+ },
+ "def-calendar": {
+ "C:supported-calendar-component-set": "VEVENT,VJOURNAL,VTODO",
+ "D:displayname": "Personal Calendar",
+ "tag": "VCALENDAR"
+ }
+ }
Default: (unset)
The backend that provides the web interface of Radicale.
-Available backends:
-none
: Just shows the message "Radicale works!".
internal
: Allows creation and management of address
-books and calendars.
Available backends are:
+none
+Simply shows the message "Radicale works!".
internal
+Allows creation and management of address books and calendars.
Default: internal
Set the logging level.
-Available levels: debug, info, -warning, error, -critical
-Default: warning
(< 3.2.0) info
-(>= 3.2.0)
Available levels are:
+debug
info
warning
error
critical
Default: warning
(< 3.2.0) /
+info
(>= 3.2.0)
(> 3.5.4)
Filter debug messages starting with 'TRACE/
Precondition: trace_on_debug = True
Prerequisite: trace_on_debug = True
Default: (empty)
Don't include passwords in logs.
+Do not include passwords in logs.
Default: True
(>= 3.2.2)
-Log backtrace on level=debug
+Log backtrace on level = debug
Default: False
(>= 3.2.2)
-Log request on level=debug
+Log request on level = debug
Default: False
(>= 3.2.2)
-Log request on level=debug
+Log request on level = debug
Default: False
(>= 3.2.2)
-Log response on level=debug
+Log response on level = debug
Default: False
(>= 3.2.3)
-Log rights rule which doesn't match on level=debug
+Log rights rule which doesn't match on level = debug
Default: False
(>= 3.3.2)
-Log storage cache actions on level=debug
+Log storage cache actions on level = debug
Default: False
In this section additional HTTP headers that are sent to clients can -be specified.
+This section can be used to specify additional HTTP headers that will +be sent to clients.
An example to relax the same-origin policy:
-Access-Control-Allow-Origin = *
Access-Control-Allow-Origin = *
Hook binding for event changes and deletion notifications.
-Available types:
-none
: Disabled. Nothing will be notified.
rabbitmq
(>= 3.2.0) : Push the message to
-the rabbitmq server.
email
(>= 3.5.5) : Send an email
-notification to event attendees.
Available types are:
+none
+Disabled. Nothing will be notified.
rabbitmq
(>= 3.2.0)
+Push the message to the rabbitmq server.
email
(>= 3.5.5)
+Send an email notification to event attendees.
Default: none
(> 3.5.4)
-Dry-Run (do not really trigger hook action)
+Dry-Run / simulate (i.e. do not really trigger) the hook action.
Default: False
(>= 3.2.0)
-End-point address for rabbitmq server. Ex: -amqp://user:password@localhost:5672/
-Default:
+End-point address for rabbitmq server. E.g.:
+amqp://user:password@localhost:5672/
Default: (unset)
(>= 3.2.0)
-RabbitMQ topic to publish message.
-Default:
+RabbitMQ topic to publish message in.
+Default: (unset)
(>= 3.2.0)
RabbitMQ queue type for the topic.
-Default: classic
+Default: classic
(>= 3.5.5)
-Address to connect to SMTP server.
-Default:
+Address of SMTP server to connect to.
+Default: (unset)
(>= 3.5.5)
-Port to connect to SMTP server.
+Port on SMTP server to connect to.
Default:
(>= 3.5.5)
-Use encryption on the SMTP connection. none, tls, starttls
-Default: none
+Use encryption on the SMTP connection.
+One of:
+none
tls
starttls
Default: none
(>= 3.5.5)
-The certificate verification mode. Works for tls and starttls. NONE, -OPTIONAL or REQUIRED
-Default: REQUIRED
+The certificate verification mode for tls and starttls.
+One of:
+NONE
OPTIONAL
REQUIRED
Default: REQUIRED
(>= 3.5.5)
Username to authenticate with SMTP server. Leave empty to disable authentication (e.g. using local mail server).
-Default:
+Default: (unset)
(>= 3.5.5)
Password to authenticate with SMTP server. Leave empty to disable authentication (e.g. using local mail server).
-Default:
+Default: (unset)
(>= 3.5.5)
Email address to use as sender in email notifications.
-Default:
+Default: (unset)
(>= 3.5.5)
-Template to use for added/updated event email body (sent to an +
Template to use for added/updated event email body sent to an attendee when the event is created or they are added to a pre-existing -event).
+event.The following placeholders will be replaced:
$organizer_name
: Name of the organizer, or "Unknown
@@ -1768,9 +1858,9 @@ This is an automated message. Please do not reply.
(>= 3.5.5)
-Template to use for deleted/removed event email body (sent to an +
Template to use for deleted/removed event email body sent to an attendee when the event is deleted or they are removed from the -event).
+event.The following placeholders will be replaced:
$organizer_name
: Name of the organizer, or "Unknown
@@ -1800,12 +1890,11 @@ The following event has been deleted.
This is an automated message. Please do not reply.
(>= 3.5.5)
-Template to use for updated event email body (sent to an attendee -when non-attendee-related details of the event are updated).
+Template to use for updated event email body sent to an attendee when +non-attendee-related details of the event are updated.
Existing attendees will NOT be notified of a modified event if the only changes are adding/removing other attendees.
The following placeholders will be replaced:
@@ -1837,8 +1926,9 @@ The following event has been updated. This is an automated message. Please do not reply.(>= 3.2.3)
@@ -1861,6 +1951,7 @@ instead of returning the results.Many clients do not support the creation of new calendars and address books. You can use Radicale's web interface (e.g. http://localhost:5232) to create and manage address books and calendars.
-In some clients you can just enter the URL of the Radicale server
-(e.g. http://localhost:5232
) and your username. In others,
-you have to enter the URL of the collection directly (e.g.
-http://localhost:5232/user/calendar
).
In some clients, it is sufficient to simply enter the URL of the
+Radicale server (e.g. http://localhost:5232
) and your
+username. In others, you have to enter the URL of the collection
+directly (e.g. http://localhost:5232/user/calendar
).
Some clients (notably macOS's Calendar.app) may silently refuse to include account credentials over unsecured HTTP, leading to unexpected authentication failures. In these cases, you want to make sure the @@ -1888,7 +1979,8 @@ Radicale server is accessible over HTTPS.
Enter the URL of the Radicale server (e.g.
http://localhost:5232
) and your username. DAVx⁵ will show
-all existing calendars and address books and you can create new.
Adding CalDAV and CardDAV accounts in Evolution will automatically make them available in GNOME Contacts and GNOME Calendar.
In Kontact add a DAV Groupware resource to +Akonadi under Settings > Configure Kontact > Calendar > +General > Calendars, select the protocol (CalDAV or CardDAV), +add the URL to the Radicale collections and enter the credentials. After +synchronization of the calendar resp. addressbook items, you can manage +them in Kontact.
+Add a new calendar on the network. Enter your username and the URL of @@ -1948,80 +2049,81 @@ InfCloud.
calendars and address books. Use Radicale's web interface or a client with support for it (e.g. DAVx⁵).To create a new calendar run something like:
-$ curl -u user -X MKCOL 'http://localhost:5232/user/calendar' --data \
-'<?xml version="1.0" encoding="UTF-8" ?>
-<create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/">
- <set>
- <prop>
- <resourcetype>
- <collection />
- <C:calendar />
- </resourcetype>
- <C:supported-calendar-component-set>
- <C:comp name="VEVENT" />
- <C:comp name="VJOURNAL" />
- <C:comp name="VTODO" />
- </C:supported-calendar-component-set>
- <displayname>Calendar</displayname>
- <C:calendar-description>Example calendar</C:calendar-description>
- <I:calendar-color>#ff0000ff</I:calendar-color>
- </prop>
- </set>
-</create>'
$ curl -u user -X MKCOL 'http://localhost:5232/user/calendar' --data \
+'<?xml version="1.0" encoding="UTF-8" ?>
+<create xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:I="http://apple.com/ns/ical/">
+ <set>
+ <prop>
+ <resourcetype>
+ <collection />
+ <C:calendar />
+ </resourcetype>
+ <C:supported-calendar-component-set>
+ <C:comp name="VEVENT" />
+ <C:comp name="VJOURNAL" />
+ <C:comp name="VTODO" />
+ </C:supported-calendar-component-set>
+ <displayname>Calendar</displayname>
+ <C:calendar-description>Example calendar</C:calendar-description>
+ <I:calendar-color>#ff0000ff</I:calendar-color>
+ </prop>
+ </set>
+</create>'
To create a new address book run something like:
-$ curl -u user -X MKCOL 'http://localhost:5232/user/addressbook' --data \
-'<?xml version="1.0" encoding="UTF-8" ?>
-<create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav">
- <set>
- <prop>
- <resourcetype>
- <collection />
- <CR:addressbook />
- </resourcetype>
- <displayname>Address book</displayname>
- <CR:addressbook-description>Example address book</CR:addressbook-description>
- </prop>
- </set>
-</create>'
$ curl -u user -X MKCOL 'http://localhost:5232/user/addressbook' --data \
+'<?xml version="1.0" encoding="UTF-8" ?>
+<create xmlns="DAV:" xmlns:CR="urn:ietf:params:xml:ns:carddav">
+ <set>
+ <prop>
+ <resourcetype>
+ <collection />
+ <CR:addressbook />
+ </resourcetype>
+ <displayname>Address book</displayname>
+ <CR:addressbook-description>Example address book</CR:addressbook-description>
+ </prop>
+ </set>
+</create>'
The collection /USERNAME
will be created automatically,
when the user authenticates to Radicale for the first time. Clients with
automatic discovery of collections will only show calendars and address
books that are direct children of the path /USERNAME/
.
Delete the collections by running something like:
-curl -u user -X DELETE 'http://localhost:5232/user/calendar'
curl -u user -X DELETE 'http://localhost:5232/user/calendar'
Note: requires config/option
permit_delete_collection = True
This section describes the format of the rights file for the
from_file
authentication backend. The configuration option
file
in the rights
section must point to the
rights file.
The recommended rights method is owner_only
. If access
-to calendars and address books outside the home directory of users
-(that's /USERNAME/
) is granted, clients won't detect these
-collections and will not show them to the user. This is only useful if
-you access calendars and address books directly via URL.
/USERNAME/
), clients will not detect these
+collections automatically, and will not show them to the users. This is
+only useful if you access calendars and address books directly via
+URL.
An example rights file:
-# Allow reading root collection for authenticated users
-[root]
-user: .+
-collection:
-permissions: R
-
-# Allow reading and writing principal collection (same as username)
-[principal]
-user: .+
-collection: {user}
-permissions: RW
-
-# Allow reading and writing calendars and address books that are direct
-# children of the principal collection
-[calendars]
-user: .+
-collection: {user}/[^/]+
-permissions: rw
# Allow reading root collection for authenticated users
+[root]
+user: .+
+collection:
+permissions: R
+
+# Allow reading and writing principal collection (same as username)
+[principal]
+user: .+
+collection: {user}
+permissions: RW
+
+# Allow reading and writing calendars and address books that are direct
+# children of the principal collection
+[calendars]
+user: .+
+collection: {user}/[^/]+
+permissions: rw
The titles of the sections are ignored (but must be unique). The keys
user
and collection
contain regular
expressions, that are matched against the username and the path of the
@@ -2051,51 +2153,53 @@ expensive search requests)
calendars)
permit_delete_collection=False
(>= 3.3.0)
permit_delete_collection=True
(>= 3.3.0)
permit_overwrite_collection=False
permit_overwrite_collection=True
This document describes the layout and format of the file system
-storage (multifilesystem
backend).
It's safe to access and manipulate the data by hand or with scripts.
-Scripts can be invoked manually, periodically (e.g. with cron)
+storage, the multifilesystem
backend.
It is safe to access and manipulate the data by hand or with scripts.
+Scripts can be invoked manually, periodically (e.g. using cron)
or after each change to the storage with the configuration option
-hook
in the storage
section (e.g. Versioning with Git).
hook
in the storage
section (e.g. Versioning collections with
+Git).
The file system contains the following files and folders:
+The file system comprises the following files and folders:
.Radicale.lock
: The lock file for locking the
storage.collection-root
: This folder contains all collections
and items.A collection is represented by a folder. This folder may contain the
-file .Radicale.props
with all WebDAV properties of the
+
Each collection is represented by a folder. This folder may contain
+the file .Radicale.props
with all WebDAV properties of the
collection encoded as JSON.
An item is represented by a file containing the iCalendar data.
-All files and folders, whose names start with a dot but not +
Each item in a calendar or address book collection is represented by +a file containing the item's iCalendar resp. vCard data.
+All files and folders, whose names start with a dot but not with
.Radicale.
(internal files) are ignored.
If you introduce syntax errors in any of the files, all requests that -access the faulty data will fail. The logging output should contain the -names of the culprits.
+Syntax errors in any of the files will cause all requests accessing +the faulty data to fail. The logging output should contain the names of +the culprits.
Caches and sync-tokens are stored in the .Radicale.cache
folder inside of collections. This folder may be created or modified,
while the storage is locked for shared access. In theory, it should be
safe to delete the folder. Caches will be recreated automatically and
-clients will be told that their sync-token isn't valid anymore.
You may encounter files or folders that start with
.Radicale.tmp-
. Radicale uses them for atomic creation and
deletion of files and folders. They should be deleted after requests are
-finished but it's possible that they are left behind when Radicale or
-the computer crashes. It's safe to delete them.
Use the flock -utility.
-# Exclusive
-$ flock --exclusive /path/to/storage/.Radicale.lock COMMAND
-# Shared
-$ flock --shared /path/to/storage/.Radicale.lock COMMAND
# Exclusive lock for COMMAND
+$ flock --exclusive /path/to/storage/.Radicale.lock COMMAND
+# Shared lock for COMMAND
+$ flock --shared /path/to/storage/.Radicale.lock COMMAND
To create a new collection, you have to create the corresponding +
To create a new collection, you need to create the corresponding
folder in the file system storage (e.g.
-collection-root/user/calendar
). To tell Radicale and
+collection-root/user/calendar
). To indicate to Radicale and
clients that the collection is a calendar, you have to create the file
.Radicale.props
with the following content in the
folder:
{"tag": "VCALENDAR"}
The calendar is now available at the URL path
-/user/calendar
. For address books the file must
-contain:
{"tag": "VADDRESSBOOK"}
{"tag": "VCALENDAR"}
The calendar is now available at the URL path (e.g.
+/user/calendar
). For address books
+.Radicale.props
must contain:
{"tag": "VADDRESSBOOK"}
Calendar and address book collections must not have any child collections. Clients with automatic discovery of collections will only show calendars and address books that are direct children of the path @@ -2202,13 +2307,13 @@ calendar or an address book through network:
Radicale is only the server part of this architecture.
-Please note that:
+Please note:
Radicale being a CalDAV/CardDAV server, it also can be seen as a -special WebDAV and HTTP server.
+Radicale being a CalDAV/CardDAV server, can also be seen as a special +WebDAV and HTTP server.
Radicale is not the client part of this architecture. It means that Radicale never draws calendars, address books, events and contacts on the screen. It only stores them and give @@ -2221,48 +2326,52 @@ application.
The radicale
package offers the following modules.
__init__
: Contains the entry point for WSGI.
__main__
: Provides the entry point for the
+
__init__
: Contains the entry point for
+WSGI.
__main__
: Provides the entry point for the
radicale
executable and includes the command line parser.
It loads configuration files from the default (or specified) paths and
-starts the internal server.
app
: This is the core part of Radicale, with the code
-for the CalDAV/CardDAV server. The code managing the different HTTP
+starts the internal server.
app
: This is the core part of Radicale, with the
+code for the CalDAV/CardDAV server. The code managing the different HTTP
requests according to the CalDAV/CardDAV specification can be found
-here.
auth
: Used for authenticating users based on username
-and password, mapping usernames to internal users and optionally
-retrieving credentials from the environment.
config
: Contains the code for managing configuration
-and loading settings from files.
ìtem
: Internal representation of address book and
-calendar entries. Based on VObject.
log
: The logger for Radicale based on the default
-Python logging module.
rights
: This module is used by Radicale to manage
-access rights to collections, address books and calendars.
server
: The integrated HTTP server for standalone
-use.
storage
: This module contains the classes representing
-collections in Radicale and the code for storing and loading them in the
-filesystem.
web
: This module contains the web interface.
utils
: Contains general helper functions.
httputils
: Contains helper functions for working with
-HTTP.
pathutils
: Helper functions for working with paths and
-the filesystem.
xmlutils
: Helper functions for working with the XML
+here.
auth
: Used for authenticating users based on
+username and password, mapping usernames to internal users and
+optionally retrieving credentials from the environment.
config
: Contains the code for managing
+configuration and loading settings from files.
ìtem
: Internal representation of address book and
+calendar entries. Based on VObject.
log
: The logger for Radicale based on the default
+Python logging module.
rights
: This module is used by Radicale to manage
+access rights to collections, address books and calendars.
server
: The integrated HTTP server for standalone
+use.
storage
: This module contains the classes
+representing collections in Radicale and the code for storing and
+loading them in the filesystem.
web
: This module contains the web
+interface.
utils
: Contains general helper functions.
httputils
: Contains helper functions for working
+with HTTP.
pathutils
: Helper functions for working with paths
+and the filesystem.
xmlutils
: Helper functions for working with the XML
part of CalDAV/CardDAV requests and responses. It's based on the
-ElementTree XML API.
Radicale can be extended by plugins for authentication, rights management and storage. Plugins are python modules.
-To get started we walk through the creation of a simple authentication plugin, that accepts login attempts with a static password.
@@ -2270,49 +2379,49 @@ password. modules is Distutils. For a minimal setup create the filesetup.py
with the
following content in an empty folder:
-#!/usr/bin/env python3
-
-from distutils.core import setup
-
-="radicale_static_password_auth",
- setup(name=["radicale_static_password_auth"]) packages
#!/usr/bin/env python3
+
+from distutils.core import setup
+
+="radicale_static_password_auth",
+ setup(name=["radicale_static_password_auth"]) packages
In the same folder create the sub-folder
radicale_static_password_auth
. The folder must have the
same name as specified in packages
above.
Create the file __init__.py
in the
radicale_static_password_auth
folder with the following
content:
from radicale.auth import BaseAuth
-from radicale.log import logger
-
-= {"auth": {
- PLUGIN_CONFIG_SCHEMA "password": {"value": "", "type": str}}}
-
-
-class Auth(BaseAuth):
-def __init__(self, configuration):
- super().__init__(configuration.copy(PLUGIN_CONFIG_SCHEMA))
-
-def _login(self, login, password):
- # Get password from configuration option
- = self.configuration.get("auth", "password")
- static_password # Check authentication
- "Login attempt by %r with password %r",
- logger.info(
- login, password)if password == static_password:
- return login
- return ""
from radicale.auth import BaseAuth
+from radicale.log import logger
+
+= {"auth": {
+ PLUGIN_CONFIG_SCHEMA "password": {"value": "", "type": str}}}
+
+
+class Auth(BaseAuth):
+def __init__(self, configuration):
+ super().__init__(configuration.copy(PLUGIN_CONFIG_SCHEMA))
+
+def _login(self, login, password):
+ # Get password from configuration option
+ = self.configuration.get("auth", "password")
+ static_password # Check authentication
+ "Login attempt by %r with password %r",
+ logger.info(
+ login, password)if password == static_password:
+ return login
+ return ""
Install the python module by running the following command in the
same folder as setup.py
:
python3 -m pip install .
python3 -m pip install .
To make use this great creation in Radicale, set the configuration
option type
in the auth
section to
radicale_static_password_auth
:
[auth]
-type = radicale_static_password_auth
-password = secret
[auth]
+type = radicale_static_password_auth
+password = secret
You can uninstall the module with:
-python3 -m pip uninstall radicale_static_password_auth
python3 -m pip uninstall radicale_static_password_auth
Radicale is available on PyPI. To install, just type as superuser:
-python3 -m pip install --upgrade radicale
python3 -m pip install --upgrade radicale
If you want the development version of Radicale, take a look at the git repository on GitHub, or install it directly with:
-python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
python3 -m pip install --upgrade https://github.com/Kozea/Radicale/archive/master.tar.gz
You can also download the content of the repository as an archive.
Radicale is available as a Docker
image for platforms linux/amd64
and
linux/arm64
. To install the latest version, run:
docker pull ghcr.io/kozea/radicale:latest
docker pull ghcr.io/kozea/radicale:latest
An example docker-compose.yml
and detailed instructions
will soon be updated.