DAViCal на сервере: частые ошибки и решения
DAViCal — один из самых старых CalDAV/CardDAV-серверов из тех, что ещё живы и работают: первый релиз датируется концом 2000-х, а последняя активная разработка — примерно 2021-2022 годами. При этом он до сих пор стоит на тысячах серверов, потому что делает одну вещь стабильно — хранит календари и контакты в PostgreSQL и отдаёт их по открытому протоколу без сюрпризов. Проблема в том, что связка «старый PHP-код + современный PHP 8.x + PostgreSQL» рождает вполне предсказуемый набор ошибок, и в этой статье — как их узнавать и чинить.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Почему DAViCal до сих пор в строю, и что в нём ломается
DAViCal — это классическое веб-приложение на PHP поверх библиотеки awl (Andrew's Web Libraries), которое работает через Apache (исторически — с mod_php) и использует PostgreSQL как единственную поддерживаемую СУБД. Никакого демона, никакого отдельного процесса — обычный CGI-стиль обработки запросов, как это делалось в 2008 году. Отсюда и плюсы, и минусы:
- Плюс: минимум движущихся частей, легко бэкапить (это просто база + конфиг), предсказуемое поведение под нагрузкой.
- Минус: код писался под PHP 5.x, и на PHP 8.1+ он генерирует массу deprecation-предупреждений (неявные nullable-параметры, обращения к строкам как к массивам и т.п.). Обычно это не ломает функциональность, но забивает логи и иногда всплывает белой страницой, если
display_errorsвключён на проде. - Минус: разработка почти остановилась, поэтому багфиксы под новые версии PHP/PostgreSQL приходится накатывать руками или брать из форков на GitLab/GitHub.
Если вам нужен активно поддерживаемый и более лёгкий вариант, посмотрите в сторону Baikal — он проще в установке и не тянет PostgreSQL. Но если вы уже держите DAViCal (например, унаследовали инфраструктуру) или вам нужна его модель прав на уровне principal/collection — ниже разбор конкретных проблем.
Установка на Debian/Ubuntu: пакет, зависимости и PHP-грабли
Проще всего ставить DAViCal из пакета — он есть в репозиториях Debian и в Ubuntu universe:
apt update
apt install davical postgresql apache2 libapache2-mod-php php-pgsql php-curl php-xml php-mbstring
Пакет использует dbconfig-common и на установке пытается сам создать базу и пользователя в PostgreSQL. Частая ошибка на этом шаге — установка запускается раньше, чем поднялся сервис PostgreSQL, и вы получаете что-то вроде:
dbconfig-common: could not connect to database server: could not connect to server: Connection refused
Решение простое: убедитесь, что PostgreSQL уже запущен и принимает подключения (systemctl status postgresql), а затем перезапустите настройку пакета:
dpkg-reconfigure davical
Второй по частоте вопрос на новых версиях Ubuntu (24.04 с PHP 8.3) — заваленный лог ошибок вида:
PHP Deprecated: Implicit conversion from float to int loses precision in /usr/share/davical/inc/...
PHP Deprecated: Passing null to parameter #1 ($string) of type string is deprecated
Это не критично для работы, но если у вас включён display_errors = On (проверьте php.ini), часть страниц может отдавать белый экран вместо календаря. Практическое решение — на проде держать:
display_errors = Off
log_errors = On
error_reporting = E_ALL & ~E_DEPRECATED & ~E_NOTICE
Это глушит именно шум от устаревшего синтаксиса, не пряча реальные фатальные ошибки. Если DAViCal ставится не из пакета, а из исходников (актуально, если вам нужна свежая версия с GitLab), процедура сложнее: нужно вручную развернуть схему из dba/, прописать конфиг и Apache-алиасы — в этом случае закладывайте больше времени на первую настройку и тестируйте на некритичном сервере.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверPostgreSQL: база данных и ошибки подключения
DAViCal хранит все данные в PostgreSQL, и большая часть «непонятных» ошибок на самом деле — это ошибки доступа к базе. Конфиг лежит в /etc/davical/<ваш-домен>/config.php (путь зависит от того, как вы называли сайт при установке пакета) и выглядит примерно так:
$c->dbhost = 'localhost';
$c->dbname = 'davical';
$c->dbuser = 'davical_app';
$c->dbpass = 'ваш-пароль';
$c->admin_email = 'admin@example.com';
$c->system_name = 'DAViCal';
$c->domain_name = 'caldav.example.com';
$c->local_tzid = 'Europe/Moscow';
Типичная ошибка FATAL: Peer authentication failed for user "davical_app" означает, что в pg_hba.conf для локальных подключений стоит метод peer, который сверяет системного пользователя ОС с ролью в PostgreSQL — а веб-сервер стучится не от имени davical_app. Правьте pg_hba.conf (обычно /etc/postgresql/16/main/pg_hba.conf):
local davical davical_app md5
host davical davical_app 127.0.0.1/32 md5
После правки — systemctl reload postgresql. Полный разбор похожих проблем с аутентификацией и коннектами есть в статье про частые ошибки PostgreSQL на сервере — база пригодится, даже если у вас никогда не было дела с PostgreSQL напрямую.
Второй момент — таймзона. Если $c->local_tzid не совпадает с таймзоной самой базы (SHOW timezone; в psql) и таймзоной ОС, события в календаре начинают «плавать» на час-два, особенно вокруг перехода на летнее/зимнее время в клиентских приложениях. Приведите все три значения к одной таймзоне, а лучше — держите сервер целиком в UTC и явно указывайте local_tzid в конфиге DAViCal.
Apache, SSL и реверс-прокси: 500-е и белые страницы
DAViCal исторически ожидает Apache с mod_php, и Debian-пакет сам добавляет конфиг в /etc/apache2/conf-available/davical.conf с алиасами вида /caldav.php, /webdav.php. Если вы ставите SSL через reverse proxy (например, nginx или Caddy перед Apache — обычная схема, если на сервере уже крутятся другие сайты), самая частая ошибка — 500 Internal Server Error из-за того, что Apache не понимает свой ServerName за проксёй, или заголовки X-Forwarded-* не пробрасываются, и DAViCal генерирует ссылки на http://localhost/... вместо реального домена.
Проверочный минимум для nginx-проксёра:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Если вместо этого вы вешаете SSL прямо на Apache (что проще и надёжнее для CalDAV — некоторые клиенты капризничают на редиректах через прокси), сертификат получаете стандартно через certbot:
certbot --apache -d caldav.example.com
Подробности про типичные грабли с сертификатами — в статье про Let's Encrypt SSL на сервере. Отдельная частая ошибка — AH01630: client denied by server configuration в логах Apache: значит, в блоке <Directory /usr/share/davical/htdocs> стоит старорежимный Order allow,deny без современного Require all granted (Apache 2.4+ требует новый синтаксис). Если вы переносили конфиг со старого сервера на Ubuntu 24.04 — проверьте это первым делом. Общий разбор ошибок связки Apache и PHP — в материале про Apache с mod_php на сервере.
Пользователи, календари и права доступа
В DAViCal есть три уровня сущностей: principal (пользователь или ресурс), collection (конкретный календарь/адресная книга) и права на неё. Создание пользователя — либо через веб-интерфейс администратора (/admin.php под учёткой admin), либо через SQL напрямую, если веб-интерфейс недоступен:
INSERT INTO usr (username, password, email, fullname, updated)
VALUES ('ivan', md5('пароль'), 'ivan@example.com', 'Иван Иванов', now());
Реальный пароль лучше всё же ставить через админку — DAViCal поддерживает разные схемы хеширования, и прямой INSERT легко сделать несовместимым с текущей версией.
Ошибка 403 Forbidden при попытке достучаться до чужого календаря — это не баг, а модель прав DAViCal: у каждой collection свои ACL, и по умолчанию календарь виден только своему principal и админам. Если нужен общий календарь на отдел — создавайте отдельный principal-ресурс (тип resource, не user) и явно выдавайте на него права read/write нужным пользователям через admin.php → Collections → Permissions.
Синхронизация с Thunderbird, DAVx5 и Apple Calendar
С точки зрения протокола DAViCal — вполне стандартный CalDAV/CardDAV-сервер, но у него старая реализация sync-collection (RFC 6578), и с современными Android-клиентами вроде DAVx5 иногда возникает ситуация, когда клиент запрашивает sync-token, а сервер отвечает 410 Gone, что заставляет клиент делать полную ресинхронизацию каждый раз. Это не ошибка конфигурации — это ограничение конкретной версии кода. Если вы часто видите в логах DAVx5 сообщения о повторных full sync без видимой причины — обновите DAViCal до последней версии из репозитория проекта на GitLab (там есть фиксы sync-token, не попавшие в дистрибутивный пакет), либо просто примите это как особенность: на практике полная ресинхронизация небольшого личного календаря занимает секунды и не мешает работе.
URL для подключения клиентов обычно такой:
https://caldav.example.com/caldav.php/ivan/calendar/
https://caldav.example.com/caldav.php/ivan/addresses/
Для Thunderbird с Lightning всё подключается через «New Calendar → On the Network → CalDAV» с этим URL. Для Apple Calendar/Contacts — через «Другая учётная запись CalDAV» с ручным вводом сервера. Если после ввода правильных данных клиент пишет «Не удаётся подключиться» — проверьте в браузере, что https://caldav.example.com/ вообще открывается и просит Basic Auth: если браузер получает 500 или редирект в цикл, проблема не в клиенте, а в связке Apache/nginx с шага выше.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
DAViCal ещё стоит ставить в 2026 году, или лучше сразу Baikal/Radicale?
Если вы начинаете с нуля и не связаны legacy-инфраструктурой — присмотритесь к Baikal: он проще ставить и обновлять, не требует PostgreSQL. DAViCal имеет смысл, если вам нужна его модель ресурсов и прав на уровне principal/collection или вы уже эксплуатируете его и данных много.
Можно ли перенести DAViCal на PHP-FPM вместо mod_php?
Технически да, но пакет из репозитория «из коробки» настроен под mod_php, и часть путей/алиасов в Apache-конфиге на это рассчитана. Если переносите на PHP-FPM (например, чтобы унифицировать со стеком nginx + php-fpm), закладывайте время на ручную правку конфигов и тестирование — готового рецепта от разработчиков нет.
Как сделать бэкап DAViCal?
Бэкапить нужно две вещи: базу PostgreSQL (pg_dump davical > davical.sql) и конфиг /etc/davical/. Данные календарей и контактов целиком живут в базе, файловой части там почти нет — это упрощает и бэкап, и восстановление на новом сервере.
Логи забиты PHP Deprecated — это опасно?
Само по себе нет, это следствие старого кода на новом PHP. Опасно, если из-за display_errors = On эти сообщения попадают прямо в HTML-ответ и ломают верстку страницы клиенту — проверьте, что на проде display_errors выключен, а ошибки уходят только в лог.
Нужен ли firewall специально под CalDAV-порты?
Отдельных портов нет — всё идёт через обычные 80/443. Если сервер смотрит в интернет напрямую, настройте базовые правила через ufw и ограничьте доступ к /admin.php по IP или отдельным Basic Auth поверх, если админка не должна быть публичной.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →