[horde] Horde 6 upgrade Windows

admin at wap.dynu.net admin at wap.dynu.net
Tue Oct 27 12:31:50 UTC 2026


Hi, everyone. I don't have any problems - everything is working as 
expected so far. I finally upgraded to Horde 6 and since I'm on Windows, 
I thought I'd share the quirks I ran into. Claude AI helped me upgrade 
and after finishing I asked for this summary below. Problems A & D are 
kind of serious because every update will break Horde. Maybe one of the 
maintainers can look at those. I'm not sure if D is windows specific.

And 1 milliion thanks to the Horde devs. I've been using it for years, 
on Windows no less, and its always been rock solid. Great software.

-----------------
Subject: Horde 6 on Windows (XAMPP Apache 2.4 + mod_fcgid, PHP 8.5): 
working setup, and the Windows-specific problems I hit

ENVIRONMENT

Windows 11, Apache 2.4.54 with mod_fcgid, PHP 8.5.12 (CLI and FastCGI), 
MariaDB, Composer 2, Git. I migrated an existing Horde 5 install (PHP 7) 
to a fresh Horde 6 deployment, reusing the Horde 5 database. The wiki 
lists PHP 8.1/8.2. I used 8.5, and everything below works with the 
workarounds listed.

Installed versions: horde/horde 6.2.1, core 3.3.0, imp 7.2.0, kronolith 
5.0.3, turba 5.0.2, nag 5.0.0, mnemo 5.0.0, ingo 4.0.1, content 3.0.0, 
routes 3.0.1, horde-installer-plugin 2.7.3, plus gollem 5.0.0beta3, 
passwd 6.0.0RC3 and timeobjects 3.0.0beta4.

Tested and working: web login, IMP mailbox, Kronolith/Nag/task data from 
the migrated database, scheduled horde-alarms, CalDAV discovery from eM 
Client, ActiveSync from two Android clients (Nine and Samsung Mail). I 
have not tested every app.

INSTALL
git clone https://github.com/maintaina-com/horde-deployment.git horde6
cd horde6
composer install
composer require horde/imp horde/ingo horde/turba horde/kronolith 
horde/nag horde/mnemo horde/content horde/timeobjects horde/gollem 
horde/passwd

In php.ini the gettext extension must be enabled (Composer fails without 
it). Also enable intl, mbstring, openssl, pdo_mysql, mysqli, curl, 
fileinfo, sodium, zip, gd and exif. iconv is built in on the Windows 
builds.

DATABASE (MIGRATING FROM HORDE 5)
Work on a copy. Dump the old database, import it into a new database and 
user, and set the sql database name, username and password in 
var\config\horde\conf.php. Then run:

vendor\bin\horde-db-migrate up

This upgraded my Horde 5 schema without errors (horde 0 to 2, kronolith 
23 to 29, turba 11 to 13, nag 14 to 18, token 1 to 2).

CONFIG
Copy the old generated conf.php (and backends.local.php and similar 
files) into var\config<app>. Fix any hard-coded paths (log, cache, temp) 
and create those directories. I kept these Horde 5 lines and they work:

$conf['server']['name'] = $_SERVER['SERVER_NAME'] ?? 'mail.example.com';
$conf['cookie']['domain'] = $_SERVER['SERVER_NAME'] ?? 
'mail.example.com';

The configuration lives in var\config. The command "composer 
horde-reconfigure" copies it into web<app>\config ("copy" mode). Until 
that is run you get "Please create a .../var/config/horde/conf.php file 
and then run 'composer horde-reconfigure'", even though the file exists.

APACHE
DocumentRoot is ...\horde6\web, with AllowOverride All and Require all 
granted. The apps are then at /horde/, /imp/, /kronolith/ and so on.

For DAV and ActiveSync on a separate hostname I aliased rpc.php, one 
Alias line per path:

FcgidPassHeader Authorization
Alias /horde/rpc.php "<horde6>/web/horde/rpc.php"
Alias /rpc.php "<horde6>/web/horde/rpc.php"
Alias /Microsoft-Server-ActiveSync "<horde6>/web/horde/rpc.php"
Alias /autodiscover/autodiscover.xml "<horde6>/web/horde/rpc.php"
<Directory "<horde6>/web/horde">
Require all granted
</Directory>

FcgidPassHeader is only allowed at server or vhost level, not inside 
Directory. The aliased script must run under the same PHP handler as the 
rest of Horde. CalDAV/CardDAV URL: https://host/horde/rpc.php/

SCHEDULED ALARMS
C:\php85\php.exe <horde6>\vendor\horde\horde\bin\horde-alarms

Run every 5 minutes from Task Scheduler (it reports exit code 0). The 
CLI scripts print "The system cannot find the path specified." a few 
times, which is harmless.

PROBLEMS I HIT (WINDOWS-SPECIFIC OR VERSION MISMATCHES)

A. The installer writes a PHP syntax error on Windows. The generated 
registry.d/-location-.php files contain paths like 'X:...\horde' and the 
trailing backslash escapes the closing quote. This breaks every request 
and horde-db-migrate. Workaround, to be repeated after every composer 
install, update or horde-reconfigure (PowerShell):

Get-ChildItem <root> -Recurse -File -Filter "0*-location-*.php" | 
ForEach-Object {
$t = Get-Content $.FullName -Raw
$n = $t -replace "\';", "/';"
if ($n -ne $t) { Set-Content $.FullName -Value $n -NoNewline }
}

B. The JavaScript tree is not deployed when Composer runs as a normal 
user. web\js was created but stayed empty ("Linking javascript tree" 
fails silently, probably because symlinks need privileges). Symptoms: 
mail stuck on "loading", and 404s such as /js/horde/sidebar.js. Running 
"composer horde-reconfigure" from an Administrator prompt created a 
junction for web\js\horde. prototype.js and scriptaculous live in 
vendor\horde\core\js, so they also had to be copied into web\js\horde. 
The apps' JavaScript had to be copied manually into web\js<app>.

C. Trean 2.0.2 breaks everything routed through rampage.php. Its 
config\routes.php calls connect(), which the GroupMapper in horde/routes 
3.0.1 rejects ("connect() is not supported by GroupMapper. Use 
buildRoute() instead"). The fatal error hits any request that loads all 
apps' routes. I removed Trean with "composer remove horde/trean".

D. DAV fails with "Call to undefined method 
Horde\Content\Api::methods()". The Content 3.0.0 Api class implements 
only getApiInterfaceList(), but Registry.php in core 3.3.0 (lines 1107, 
1193 and 1247) calls $api_ob->methods() on every app's API object, so 
rpc.php returns a 500. My workaround was to add this method to 
vendor/horde/content/src/Api.php; it is lost whenever Content is 
updated:

public function methods(): array { return []; }

E. Cosmetic: script URLs for the base app come out as 
/js/horde//prototype.js (the registry's jsuri has a trailing slash and 
another is appended). It works once the files exist.

F. Unresolved: warnings 'Undefined array key "horde"' from lines 12 and 
14 of each generated 02-location-<app>.php (the horde webroot is not set 
yet), logged on rampage.php and rpc.php requests. They look harmless, 
but I don't know the cause.

QUESTIONS FOR THE LIST

Is there a supported way to deploy the web\js, web\themes and config 
trees on Windows without symlinks or Administrator rights?
Is Trean expected to work with horde/routes 3.0.1, and is Content meant 
to provide methods() for the current Registry?
Should the trailing-backslash path problem be fixed in 
horde-installer-plugin? (A newer 3.6.0 is available; I have not tried 
it.)


More information about the horde mailing list