Как установить и настроить Radicale на VPS
Если вам нужен свой сервер календарей и контактов без гигабайтных зависимостей и полноценной СУБД, Nextcloud для этого — избыточное решение. Radicale делает ровно то же самое на уровне протокола: отдаёт и принимает CalDAV/CardDAV, синхронизируется с телефоном, Thunderbird и macOS Calendar — и укладывается в один Python-процесс на пару десятков мегабайт памяти. Разберём, как установить и настроить Radicale на VPS: от systemd-сервиса до TLS через nginx и прав доступа для нескольких пользователей.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Radicale и когда он уместен
Radicale — это сервер, реализующий протоколы CalDAV (календари) и CardDAV (контакты) поверх HTTP. Он не хранит данные в базе — по умолчанию каждая коллекция (календарь или адресная книга) это папка на диске, а каждое событие или контакт — отдельный файл в формате iCalendar/vCard. Это осознанное архитектурное решение: данные легко бэкапить обычным rsync или tar, легко смотреть глазами при отладке и легко переносить на другой сервер без экспорта из БД.
Есть и минусы такого подхода. Radicale не умеет то, что умеет Nextcloud или Google Calendar из коробки: нет веб-интерфейса для просмотра расписания, нет шаринга приглашений по email, нет мобильного приложения — это чистый сервер протокола, а не приложение с интерфейсом. Вы подключаетесь к нему клиентом (Thunderbird с расширением, приложение "Календарь" на телефоне, DAVx5 на Android) и работаете как с любым облачным календарём. Если вам нужна именно синхронизация календарей и контактов между устройствами без завязки на Google или Apple — это ровно тот инструмент. Если нужен ещё и полноценный офисный веб-интерфейс с шарингом файлов — присмотритесь к Nextcloud, там CalDAV/CardDAV тоже есть, но ценой заметно большего потребления ресурсов.
Для одного-двух пользователей и десятка устройств Radicale хватает с запасом даже на самом младшем VPS: 1 CPU и 512 МБ-1 ГБ RAM — комфортный минимум с учётом ОС и nginx перед ним.
Установка Radicale
Radicale написан на Python и ставится через pip в виртуальное окружение — так проще следить за версией и не тащить системные пакеты Python в конфликт с ОС. На Ubuntu 24.04:
apt update
apt install -y python3-venv python3-pip nginx
useradd -r -m -d /var/lib/radicale -s /usr/sbin/nologin radicale
Отдельный системный пользователь radicale нужен, чтобы сервис не работал от root и его файлы календарей были изолированы правами доступа. Ставим сам Radicale в виртуальное окружение внутри его домашней директории:
sudo -u radicale python3 -m venv /var/lib/radicale/venv
sudo -u radicale /var/lib/radicale/venv/bin/pip install --upgrade pip
sudo -u radicale /var/lib/radicale/venv/bin/pip install radicale
Проверить, что пакет встал и видит свою версию:
sudo -u radicale /var/lib/radicale/venv/bin/radicale --version
Дальше нужны две вещи: конфиг с параметрами сервера и структура каталогов для данных.
mkdir -p /etc/radicale /var/lib/radicale/collections
chown -R radicale:radicale /var/lib/radicale
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверБазовый конфиг
Основной файл настроек — /etc/radicale/config, формат INI-подобный. Минимальный рабочий вариант для VPS за реверс-прокси:
[server]
hosts = 127.0.0.1:5232
[storage]
filesystem_folder = /var/lib/radicale/collections
[auth]
type = htpasswd
htpasswd_filename = /etc/radicale/users
htpasswd_encryption = bcrypt
[logging]
level = info
Пояснения по секциям. [server] hosts — слушать только локально на 127.0.0.1:5232, наружу сервис отдаст nginx с TLS, сам Radicale наружу смотреть не должен. [storage] filesystem_folder — куда складывать коллекции, тот самый каталог с файлами событий и контактов. [auth] включает обязательную аутентификацию: без пароля любой, кто найдёт адрес сервера, сможет читать и писать в чужие календари. htpasswd_encryption = bcrypt — важный момент, разберём его отдельно ниже, потому что здесь чаще всего ошибаются.
Пользователи и права доступа
Файл /etc/radicale/users — обычный htpasswd-файл, создаётся утилитой apache2-utils:
apt install -y apache2-utils
htpasswd -B -c /etc/radicale/users alice
htpasswd -B /etc/radicale/users bob
Флаг -c создаёт файл заново — используйте его только для первого пользователя, иначе сотрёте остальных. Флаг -B заставляет htpasswd хешировать пароль bcrypt'ом — это должно совпадать с htpasswd_encryption = bcrypt в конфиге. Частая ошибка новичков — сгенерировать хеш утилитой без флага -B (тогда получится MD5 или crypt) при выставленном в конфиге bcrypt: Radicale не сможет проверить пароль, и любой логин будет отклонён с ощущением, будто сервис вообще не работает.
По умолчанию у Radicale простая модель прав: каждый пользователь получает доступ к коллекциям в собственном пространстве имён /username/, и по умолчанию видит только свои календари. Для более тонкого контроля (общий календарь на несколько человек, доступ только на чтение) используется отдельный модуль [rights] с файлом-описанием прав вида:
[rights]
type = owner_only
Значение owner_only — самый строгий и самый частый режим: каждый работает только со своими коллекциями. Если нужен общий календарь для команды, переключитесь на type = from_file и опишите правила в отдельном файле с масками путей и списком пользователей, кому какая маска доступна на чтение или запись.
Запуск через systemd
Хранить сервис ручным запуском в screen — плохая идея, он должен подниматься сам после перезагрузки и рестартовать при сбое. Создайте юнит /etc/systemd/system/radicale.service:
[Unit]
Description=Radicale CalDAV/CardDAV server
After=network.target
[Service]
Type=simple
User=radicale
Group=radicale
ExecStart=/var/lib/radicale/venv/bin/radicale --config /etc/radicale/config
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
Включите и запустите:
systemctl daemon-reload
systemctl enable --now radicale
systemctl status radicale
Если статус active (running) — сервис поднялся и слушает 127.0.0.1:5232. Проверить локально можно так:
curl -u alice: http://127.0.0.1:5232/
Curl спросит пароль alice и в ответ должен прийти HTML или XML с содержимым корневой коллекции, а не ошибка соединения.
Nginx как реверс-прокси и TLS
Radicale сам умеет отдавать HTTPS, но на практике удобнее вынести TLS на nginx — так проще управлять сертификатами и добавить другие сервисы на тот же IP. Базовый конфиг /etc/nginx/sites-available/radicale:
server {
listen 80;
server_name caldav.example.com;
location / {
proxy_pass http://127.0.0.1:5232/;
proxy_set_header Host $host;
proxy_set_header X-Script-Name /;
proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
proxy_set_header X-Remote-User $remote_user;
proxy_pass_header Authorization;
client_max_body_size 50M;
}
}
Заголовок X-Script-Name нужен, если Radicale смонтирован не в корне — оставьте /, если сервис отдельный на своём поддомене, как в примере. proxy_pass_header Authorization важен: некоторые версии nginx по умолчанию не пробрасывают заголовок авторизации дальше, и клиенты будут получать бесконечный запрос пароля. client_max_body_size стоит увеличить, если в календарь будут попадать события с крупными вложениями.
Дальше получаем сертификат и включаем сайт — подробный процесс с выпуском и автопродлением разобран в статье про certbot и acme.sh, кратко для Let's Encrypt:
ln -s /etc/nginx/sites-available/radicale /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
certbot --nginx -d caldav.example.com
Certbot сам допишет в конфиг редирект на 443 и блок с сертификатами. После этого шага Radicale доступен снаружи только по HTTPS на порту 443, а порт 5232 остаётся закрытым на loopback-интерфейсе и недоступен извне даже без фаервола — но фаервол всё равно стоит настроить как отдельный слой обороны, как и защиту от перебора паролей: если Radicale смотрит в интернет с базовой авторизацией, fail2ban на nginx-логах существенно снижает шум от автоматического перебора. Общий разбор настройки nginx как реверс-прокси — в отдельной пошаговой статье.
Подключение клиентов
С сертификатом и рабочим nginx клиенты подключаются по стандартному URL discovery — большинству достаточно указать адрес сервера и логин, остальное клиент находит сам через .well-known. Добавьте в серверный блок nginx редиректы для автообнаружения:
location = /.well-known/caldav {
return 301 $scheme://$host/;
}
location = /.well-known/carddav {
return 301 $scheme://$host/;
}
Дальше в клиентах:
| Клиент | Что указать |
|---|---|
| DAVx5 (Android) | https://caldav.example.com/ + логин/пароль, дальше автообнаружение |
| Thunderbird (с TbSync или встроенным CalDAV) | тот же адрес и учётные данные |
| macOS/iOS Calendar и Contacts | тип аккаунта "CalDAV" вручную, адрес сервера без /username/ |
| Прямая ссылка на конкретный календарь | https://caldav.example.com/alice/имя-календаря/ |
Первый календарь и адресная книга у пользователя обычно не создаются автоматически — большинство клиентов при первом подключении сами предложат создать коллекцию по умолчанию. Если клиент этого не делает, можно создать пустую директорию вручную внутри /var/lib/radicale/collections/collection-root/alice/ с нужными правами владельца radicale, и Radicale подхватит её как коллекцию при следующем запросе.
Бэкап и обслуживание
Поскольку данные Radicale — это просто файлы на диске, бэкап не требует ничего специфичного для CalDAV: обычный архив каталога коллекций.
tar -czf radicale-backup-$(date +%F).tar.gz -C /var/lib/radicale collections
Такую команду удобно повесить в cron раз в сутки и хранить архивы за последнюю неделю, дополнительно синхронизируя их на другой сервер или в объектное хранилище. Восстановление — обратная операция: распаковать архив на место, выставить владельца radicale:radicale и перезапустить сервис. Обновление самого Radicale делается штатно через pip в виртуальном окружении:
sudo -u radicale /var/lib/radicale/venv/bin/pip install --upgrade radicale
systemctl restart radicale
Перед крупным обновлением версии стоит свериться с changelog проекта — формат хранения на диске стабилен уже давно, но мажорные релизы иногда меняют структуру конфига.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Radicale не отвечает на 443, хотя nginx запущен — в чём дело?
Чаще всего сам сервис Radicale не поднялся или слушает не тот адрес. Проверьте systemctl status radicale и ss -tlnp | grep 5232 — порт должен слушаться на 127.0.0.1, а не отсутствовать в списке.
Клиент постоянно спрашивает пароль по кругу.
Обычно это значит, что nginx не пробрасывает заголовок Authorization дальше в Radicale. Добавьте proxy_pass_header Authorization в location и перезагрузите nginx.
Можно ли сделать общий календарь для нескольких пользователей?
Да, через [rights] type = from_file и отдельный файл с масками путей и списком пользователей на чтение/запись — режим по умолчанию owner_only даёт доступ только к своим коллекциям.
Нужна ли отдельная база данных для Radicale?
Нет, по умолчанию используется файловое хранилище: каждая коллекция — папка, каждое событие или контакт — файл. Это упрощает бэкап, но не годится для сотен параллельных пользователей — там уместнее СУБД-ориентированное решение вроде Nextcloud.
Чем Radicale отличается от Nextcloud для календарей?
Radicale — только сервер протокола CalDAV/CardDAV, минимум ресурсов, без веб-интерфейса. Nextcloud даёт полноценный веб-клиент, шаринг и файловое хранилище, но требует БД, PHP-FPM и заметно больше памяти.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →