beAV Pro - Apache 2.4 und PHP 8.5 einrichten

Version 1.0 | Stand: 2026-08-08

Apache 2.4 und PHP 8.5 unter Windows einrichten

ℹ️Für wen ist diese Anleitung?

Für Administratoren, die beAV Pro auf einem Windows-Rechner betreiben und dafür einen eigenständigen Webserver einrichten — statt eines Software-Pakets wie XAMPP.

Sie führt von einem leeren Windows-System bis zum laufenden Webserver. Ist bereits XAMPP installiert, gilt zusätzlich Anhang A.

Ergebnis: Apache 2.4.68 und PHP 8.5.9 als Windows-Dienst mit automatischem Start, HTTPS, Log-Rotation und Sicherheitsunterstützung bis Ende 2029.

Zeitbedarf rund 45 Minuten
Erforderlich Administratorrechte, Neustartmöglichkeit
Ausfallzeit wenige Minuten (nur Abschnitt 10)
Voraussetzung Datenbank läuft bereits — siehe MariaDB 11.4 einrichten

⚠️Reihenfolge einhalten

Erst Datenbank, dann Webserver, dann beAV Pro. Die Abschnitte 1 bis 9 sind vorbereitend und lassen den vorhandenen Webserver unberührt — umgeschaltet wird erst in Abschnitt 10. Bis dahin ist jeder Schritt gefahrlos.


Warum diese Versionen

KomponenteVersionUnterstützt bis
Apache2.4.682.4 ist die einzig gepflegte Linie
PHP8.5.9 Thread Safe x6431.12.2029
MariaDB11.4 LTS2029

PHP 8.5 endet zeitgleich mit MariaDB 11.4 — beide Ablösungen fallen damit künftig zusammen statt versetzt.

Thread Safe ist zwingend

PHP läuft unter Windows als Modul innerhalb des Apache-Prozesses, und Apache arbeitet dort mit Threads. Nur der Thread-Safe-Build (ZTS) enthält die dafür nötige Datei php8apache2_4.dll. Der Non-Thread-Safe-Build ist unbrauchbar.

ℹ️Apache VS18 und PHP VS17 — kein Widerspruch

Apache wird mit Visual Studio 2026 (VS18) gebaut, PHP 8.5 mit Visual Studio 2022 (VS17). Das ist unbedenklich: Microsoft erlaubt ausdrücklich das Kombinieren der Build-Tools v140 bis v145, und Apache verlangt das Redistributable „für Visual Studio 2017–2026" — ein Paket für beide Generationen.

Ältere VS17-Builds von Apache scheiden ohnehin aus: Der letzte (2.4.66) hat mit CVE-2026-23918 eine offene Lücke der Stufe Important.


1. Vorbereitung

1.1 Werte festlegen

Tragen Sie Ihre Werte ein, bevor Sie beginnen. Sie werden mehrfach gebraucht:

WertBeispielIhrer
Apache-VerzeichnisC:\Apache 
PHP-VerzeichnisC:\php 
AnwendungsverzeichnisC:\beav_app 
Webroot (das web-Verzeichnis darin)C:\beav_app\web 
Servernamebeav.firma.de 
ZertifikatsdateiC:\Apache\conf\ssl\beav.crt.pem 
SchlüsseldateiC:\Apache\conf\ssl\beav.key.pem 

⚠️Verzeichnisnamen ohne Versionsnummer

C:\Apache statt C:\Apache24, C:\php statt C:\php85. Andernfalls müssten bei jedem Update sämtliche Pfade in den Konfigurationsdateien geändert werden. Auch keine Leerzeichen im Pfad — sonst brauchen alle Direktiven Anführungszeichen.

🔴Der Webroot zeigt auf web, nicht darüber

Der DocumentRoot muss direkt auf das web-Verzeichnis zeigen. Nur dann liegt config/ mit den Datenbank-Zugangsdaten außerhalb des über den Browser erreichbaren Bereichs.

⚠️Anwendung und Dokumente nicht gleich benennen

Ist als Dateispeicher lokal eingestellt, liegen die hochgeladenen Dokumente in einem eigenen Verzeichnis — häufig C:\beav. Wählen Sie für die Anwendung deshalb einen davon klar unterscheidbaren Namen. Die Empfehlung:

VerzeichnisInhalt
C:\beav_appProgramm — config\, web\, _beav_backups\
C:\beavDaten — die hochgeladenen Dokumente (Wert von STORAGE_LOCAL_ROOT in config\config.php)

Wer beides gleich benennt, kopiert früher oder später Programmdateien über den Dokumentenbestand. Prüfen Sie vor dem Anlegen, was auf dem Zielsystem bereits existiert: dir C:\beav* /b

🔴Die Anwendung gehört nicht unter C:\xampp\htdocs

Liegt sie dort, nimmt eine XAMPP-Deinstallation sie mitsamt config\ und den Zugangsdaten mit — siehe Anhang A.5. Bei einer Neuinstallation legen Sie sie deshalb von vornherein außerhalb an; bei einer bestehenden Installation holen Sie sie heraus, sobald es die Zeit erlaubt.

1.2 Dateien laden

WasWo
Apache 2.4.68
Win64, VS18
https://www.apachelounge.com/download/
Datei: httpd-2.4.68-260617-Win64-VS18.zip
PHP 8.5.9
Thread Safe, x64
https://windows.php.net/download/
Datei: php-8.5.9-Win32-vs17-x64.zip
VC++ Redistributable x64 https://aka.ms/vc14/vc_redist.x64.exe
CA-Bundle
(Wurzelzertifikate für PHP)
https://curl.se/ca/cacert.pem

🔴Beim PHP-Download genau hinsehen

Es gibt vier Varianten. Sie brauchen „Thread Safe" und x64. Die Datei heißt php-8.5.9-Win32-vs17-x64.zip — ohne den Zusatz nts. Die NTS-Variante enthält kein Apache-Modul.

1.3 Prüfsummen kontrollieren

In PowerShell, im Download-Verzeichnis:

Get-FileHash php-8.5.9-Win32-vs17-x64.zip -Algorithm SHA256
Get-FileHash httpd-2.4.68-260617-Win64-VS18.zip -Algorithm SHA256
DateiSHA256
php-8.5.9-Win32-vs17-x64.zip 6a8af9f5d2a35b81cd9f1db04bd4037c3609828db62f81589e29e13faffd45f9
httpd-2.4.68-260617-Win64-VS18.zip eac38a9f8d21b6ba0817cd1576a3d291cc771afd3c6a210d120bdea6f4aa4aeb
vc_redist.x64.exe 843068991daaa1f73ad9f6239bce4d0f6a07a51f18c37ea2a867e9beca71295c

Die PHP-Prüfsumme steht so auch auf php.net. Der Apache-Wert stammt aus der hier geprüften Datei — er dient dem Abgleich, dass überall dieselbe Fassung verwendet wird.

ℹ️Abweichende Prüfsumme bei vc_redist.x64.exe

Microsoft veröffentlicht die Datei laufend neu — aka.ms/vc14/… liefert immer die jeweils aktuelle. Ein anderer Wert ist daher kein Fehler, sondern nur ein Zeichen für eine neuere Fassung. Für cacert.pem gilt dasselbe: Die Datei wird mehrmals jährlich erneuert und hat deshalb keine feste Prüfsumme.

1.4 Administratorrechte

Nahezu jeder Schritt braucht sie: Entpacken nach C:\, Dienste anlegen, den Systempfad ändern. Ein Fenster ohne Administratorrechte scheitert dabei nicht immer sichtbar — manche Befehle melden Erfolg und ändern nichts.

Öffnen Sie die Eingabeaufforderung deshalb über Rechtsklick → Als Administrator ausführen und prüfen Sie es. In PowerShell:

([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administratoren")

Erwartet: True. Auf englischsprachigen Systemen lautet die Gruppe Administrators.

⚠️Eingabeaufforderung und PowerShell sind nicht dasselbe

Die Befehle in dieser Anleitung sind jeweils für eine der beiden geschrieben. net, sc, reg, copy und ren gehören in die Eingabeaufforderung, Get-FileHash und alles mit $ oder […] in PowerShell. Vertauscht führt das zu Ausgaben, die nach einem Defekt aussehen, aber keiner sind: echo %PATH% etwa gibt in PowerShell wörtlich %PATH% aus — der Systempfad ist damit nicht verschwunden.

1.5 Konfigurationsdateien richtig speichern

Sie legen mehrere Textdateien an: php.ini, httpd.conf, httpd-ssl.conf. Beim Speichern gibt es drei Fallen.

PunktWorauf es ankommt
Kein BOM Speichern Sie als UTF-8, nicht als UTF-8 mit BOM. Die drei unsichtbaren Bytes am Dateianfang stehen vor der ersten Zeile — Apache liest sie als Teil der ersten Direktive und bricht mit einer Meldung ab, die auf eine völlig unverdächtige Zeile zeigt. Im Windows-Editor: Speichern unter → Feld Codierung → UTF-8.
Keine Dateiendung anhängen Der Windows-Editor macht aus php.ini stillschweigend php.ini.txt, wenn der Dateityp auf Textdateien steht. Wählen Sie Alle Dateien und blenden Sie in den Ordneroptionen die Dateinamenerweiterungen ein.
Nur Umlaute in Kommentaren In Pfaden und Werten keine Umlaute verwenden. Das erspart jede Frage nach der Zeichensatzbehandlung.

2. Visual C++ Runtime

🔴Reihenfolge beachten — Dienste vorher stoppen

Die Runtime-Bibliotheken werden von Apache, MariaDB und PHP benutzt. Laufen diese Dienste, kann der Installer die Dateien nicht ersetzen und verlangt einen Neustart. Werden sie vorher gestoppt, lässt sich der Neustart meist vermeiden.

1Vorhandene Version prüfen

powershell -Command "(Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64').Version"

Steht dort 14.51.36247 oder höher, überspringen Sie diesen Abschnitt. Apache 2.4.68 verlangt mindestens diese Version.

2Dienste stoppen

Eingabeaufforderung als Administrator. Welche Dienste vorhanden sind:

sc query state= all | findstr /i "apache maria mysql"

Dann stoppen — Webserver zuerst, Datenbank danach:

net stop Apache2.4
net stop MariaDB

3Installieren

vc_redist.x64.exe /install /passive /norestart
echo %ERRORLEVEL%
WertBedeutungWeiter mit
0installiertSchritt 4
3010installiert, Neustart nötigWindows neu starten, dann Schritt 4
1638neuere Version vorhandenSchritt 4
1602abgebrochenerneut versuchen
5Zugriff verweigertals Administrator ausführen

4Dienste starten und prüfen

net start MariaDB
net start Apache2.4

Datenbank zuerst — der Webserver soll sie bereits vorfinden.

powershell -Command "(Get-Item C:\Windows\System32\vcruntime140.dll).VersionInfo.FileVersion"

Erwartet: 14.51.36247.0 oder höher.

ℹ️Erfahrungswert

Bei einem Testlauf ohne vorheriges Stoppen der Dienste kam Rückgabewert 3010. Die Kernbibliotheken waren dennoch sofort aktuell, 14 weitere Dateien blieben für den Neustart vorgemerkt. Der Betrieb lief ununterbrochen weiter — der Neustart lässt sich also in ein späteres Wartungsfenster legen.


3. Apache und PHP entpacken

1Apache

Das Archiv enthält einen Ordner Apache24. Entpacken Sie ihn und benennen Sie ihn in Apache um, sodass entsteht:

C:\Apache\bin\httpd.exe
C:\Apache\conf\httpd.conf
C:\Apache\modules\
C:\Apache\logs\

Per PowerShell (als Administrator):

Expand-Archive httpd-2.4.68-260617-Win64-VS18.zip -DestinationPath C:\temp\ap
Move-Item C:\temp\ap\Apache24 C:\Apache

2PHP

Das PHP-Archiv hat keinen Wurzelordner — direkt in das Zielverzeichnis entpacken:

New-Item -ItemType Directory C:\php -Force
Expand-Archive php-8.5.9-Win32-vs17-x64.zip -DestinationPath C:\php

3Arbeitsverzeichnisse anlegen

New-Item -ItemType Directory C:\php\logs -Force
New-Item -ItemType Directory C:\php\tmp -Force
New-Item -ItemType Directory C:\Apache\conf\ssl -Force

4Kontrolle

C:\Apache\bin\httpd.exe -v
C:\php\php.exe -v

Erwartet: Apache/2.4.68 und PHP 8.5.9 ... (ZTS ...).

Das Kürzel ZTS muss erscheinen. Steht dort NTS, wurde die falsche Variante geladen — dann noch einmal von vorn mit dem Thread-Safe-Paket.

dir C:\php\php8apache2_4.dll

Diese Datei muss vorhanden sein (rund 37 KB). Fehlt sie, ist es ebenfalls der falsche Build.


4. PHP in den Systempfad aufnehmen

🔴Dieser Schritt wird gern übersehen — und kostet dann Stunden

Ohne ihn lassen sich mehrere Erweiterungen nicht laden, darunter curl. Für beAV Pro wäre das gravierend: kein Lizenz-Heartbeat, keine Updates, keine WebDAV- oder S3-Anbindung.

Der Grund: Erweiterungen wie php_curl.dll benötigen Hilfsbibliotheken (libssh2.dll, nghttp2.dll, libcrypto-3-x64.dll …), die in C:\php liegen. Der Apache-Prozess läuft aber in C:\Apache\bin und durchsucht C:\php nicht.

Besonders tückisch: In der Kommandozeile funktioniert alles, weil php.exe im selben Verzeichnis wie die Bibliotheken liegt. Der Fehler tritt nur über den Webserver auf.

PowerShell als Administrator:

$alt = [Environment]::GetEnvironmentVariable("Path","Machine")
[Environment]::SetEnvironmentVariable("Path", "C:\php;" + $alt, "Machine")

Kontrolle nach dem Öffnen einer neuen Eingabeaufforderung:

echo %PATH%

C:\php muss enthalten sein.

⚠️Typische Fehlermeldung, wenn dieser Schritt fehlt

PHP Warning: PHP Startup: Unable to load dynamic library 'curl' (tried: C:\php\ext\php_curl.dll (Das angegebene Modul wurde nicht gefunden))

Die Meldung führt in die Irre: Die genannte Datei existiert. Nicht gefunden werden ihre Abhängigkeiten.


5. php.ini anlegen

Legen Sie C:\php\php.ini mit folgendem Inhalt an. Die Datei ist bewusst kurz gehalten — alles Nichtaufgeführte behält die Vorgabe von PHP.

C:\php\php.ini
; =====================================================================
; PHP 8.5 fuer beAV Pro
; =====================================================================

[PHP]

; ---- Grundverhalten ----
engine = On
short_open_tag = Off
precision = 14
serialize_precision = -1
output_buffering = 4096
implicit_flush = Off
zlib.output_compression = Off
expose_php = Off

; ---- Laufzeit und Speicher ----
max_execution_time = 0
max_input_time = -1
memory_limit = 512M
max_input_vars = 1000
default_socket_timeout = 60

; ---- Fehlerbehandlung ----
error_reporting = E_ALL
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = "C:\php\logs\php_error_log"

; ---- Datei-Uploads ----
file_uploads = On
upload_max_filesize = 40M
post_max_size = 40M
max_file_uploads = 20
upload_tmp_dir = "C:\php\tmp"

; ---- Zeichensatz ----
default_charset = "UTF-8"

; ---- Netzwerk ----
allow_url_fopen = On
allow_url_include = Off

; ---- Erweiterungen ----
extension_dir = "C:\php\ext"

extension=bz2
extension=curl
extension=exif
extension=fileinfo
extension=ftp
extension=gd
extension=gettext
extension=mbstring
extension=mysqli
extension=openssl
extension=pdo_mysql
extension=pdo_sqlite
extension=zip

[Date]
date.timezone = Europe/Berlin

[Session]
session.save_handler = files
session.save_path = "C:\php\tmp"
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_httponly = 1
session.cookie_samesite = "Lax"
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.cache_limiter = nocache
session.sid_length = 32

[opcache]
opcache.enable = 1
opcache.enable_cli = 0
opcache.memory_consumption = 192
opcache.max_accelerated_files = 10000
opcache.validate_timestamps = 1
opcache.revalidate_freq = 60
opcache.interned_strings_buffer = 16

[curl]
; ZWINGEND - siehe Hinweis unter dieser Datei.
curl.cainfo = "C:\php\cacert.pem"

[openssl]
openssl.cafile = "C:\php\cacert.pem"

🔴Ohne CA-Bundle keine gesicherten Verbindungen

PHP nutzt unter Windows OpenSSL, nicht die Zertifikatsverwaltung von Windows. OpenSSL braucht eine eigene Liste vertrauenswürdiger Wurzelzertifikate. Fehlt sie, scheitert jede geprüfte HTTPS-Verbindung mit:

SSL certificate problem: unable to get local issuer certificate

Betroffen sind bei beAV Pro die Update-Prüfung und der Update-Download — beide fordern eine geprüfte Verbindung. Der Lizenzstatus funktioniert unter Umständen trotzdem, weshalb der Fehler leicht unentdeckt bleibt, bis das erste Update ansteht.

CA-Bundle bereitstellen

Die Datei muss vorhanden sein, bevor die beiden Zeilen wirken. Sie enthält die Wurzelzertifikate der Stellen, denen PHP vertrauen soll — sonst nichts.

Immer frisch herunterladen, in PowerShell:

Invoke-WebRequest https://curl.se/ca/cacert.pem -OutFile C:\php\cacert.pem

Stand kontrollieren — die Datei nennt ihn in der vierten Zeile:

Get-Content C:\php\cacert.pem -TotalCount 4 | Select-Object -Last 1

Erwartet wird ein Datum aus den letzten Monaten, etwa Certificate data from Mozilla as of: Thu Jul 16 03:12:01 2026 GMT.

ℹ️Warum „Mozilla" — und warum das kein Browser ist

Irgendjemand muss prüfen, welche Zertifizierungsstellen weltweit vertrauenswürdig sind. Mozilla betreibt dafür ein öffentliches Programm und veröffentlicht das Ergebnis frei; Microsoft, Apple und Google führen eigene Listen, aber nur für ihre eigenen Produkte. Das cURL-Projekt bereitet Mozillas Liste als Textdatei auf — reine Daten, keine Software. Deshalb verwenden sie Server, Programmiersprachen und Kommandozeilenwerkzeuge in aller Welt.

Windows führt eine eigene, gleichwertige Liste. PHP kommt nur nicht daran, weil es OpenSSL statt der Windows-Schnittstelle verwendet — daher die separate Datei.

⚠️Dreimal „curl" — und nur eines davon ist gemeint

Der Name führt in die Irre, weil er an drei Stellen auftaucht. Gemeint ist hier ausschließlich die Datendatei:

WasWas es istPflege
cacert.pem
in XAMPP: curl-ca-bundle.crt
Datendatei — eine Liste von Wurzelzertifikaten Hier geht es um diese Datei. Jährlich austauschen, siehe Abschnitt 14
libcurl Programmbibliothek — sie liest die Datei und baut die Verbindungen auf. Das ist, was beAV Pro benutzt Steckt in PHP. Kommt mit jedem PHP-Update mit. Keine eigene Pflege
curl.exe Kommandozeilenprogramm unter C:\Windows\System32 Kommt über Windows-Update. Von beAV Pro nicht benutzt

Bildlich: Die Datei ist ein Adressbuch, libcurl ist das Telefon. Veraltet ist das Adressbuch — am Telefon ist nichts zu tun.

🔴Nicht aus XAMPP übernehmen

XAMPP enthält unter C:\xampp\apache\bin\curl-ca-bundle.crt eine solche Datei. Verwenden Sie sie nicht. Sie stammt aus der jeweiligen XAMPP-Fassung und ist entsprechend alt — in der zuletzt verbreiteten Ausgabe vom 26. April 2022. Der Vergleich mit dem aktuellen Bundle zeigt, was das bedeutet:

AnzahlUnterschied
43Wurzelzertifikate, die die alte Datei noch als vertrauenswürdig führt, obwohl sie zurückgezogen wurden — teils wegen abgelaufener Gültigkeit, teils weil der Zertifizierungsstelle das Vertrauen entzogen wurde
28Wurzelzertifikate, die seither hinzugekommen sind und in der alten Datei fehlen — Verbindungen zu Gegenstellen, die darauf aufbauen, scheitern

Die zweite Gruppe fällt irgendwann als Fehler auf. Die erste nicht — sie schwächt die Prüfung still.

⚠️Diese Datei altert und wird von niemandem für Sie erneuert

Sie ist der einzige Bestandteil dieses Aufbaus, der nicht in einem Paket steckt: Apache bringt sie nicht mit, PHP bringt sie nicht mit, Windows-Update rührt sie nicht an. Ein PHP-Update erneuert sie also nicht. Planen Sie den Austausch einmal jährlich ein — derselbe Befehl, gleicher Ort, gleicher Name, keine Konfigurationsänderung, kein Neustart. Siehe Abschnitt 14.

🔴session.sid_bits_per_character nicht eintragen

Diese Einstellung ist in PHP 8.5 abgekündigt. Wird sie gesetzt, erscheint bei jedem Seitenaufruf eine Warnung im Fehlerlog — die Datei wächst dadurch rasant und echte Fehler gehen darin unter.

Hinweise zu einzelnen Werten

EinstellungErläuterung
display_errors = Off Fehler gehören ins Log, nicht in den Browser. Wichtig auch deshalb, weil eingeblendete Warnungen die JSON-Antworten der AJAX-Schnittstellen zerstören würden.
expose_php = Off Verhindert, dass die PHP-Version im HTTP-Header steht.
opcache.enable = 1 Beschleunigt die Anwendung erheblich, weil PHP große Dateien nicht bei jedem Aufruf neu übersetzt. In PHP 8.5 ist OPcache fest eingebaut.
opcache.revalidate_freq = 60 Nach einem Update greifen Änderungen spätestens nach einer Minute — ohne Neustart. Auf einem Entwicklungsrechner stattdessen opcache.enable = 0 setzen, sonst wirken Codeänderungen verzögert.
Erweiterungsliste Nur Erweiterungen, die in PHP 8.5 nicht fest eingebaut sind. bcmath, ctype, json, PDO, session und weitere sind bereits enthalten.

6. httpd.conf anlegen

Ersetzen Sie C:\Apache\conf\httpd.conf vollständig durch folgenden Inhalt. Die mit ANPASSEN markierten Zeilen müssen Sie ändern.

C:\Apache\conf\httpd.conf
# =====================================================================
# Apache 2.4 fuer beAV Pro
# Pfade mit Schraegstrich schreiben, auch unter Windows.
# =====================================================================

ServerRoot "C:/Apache"

Listen 80

# ---- Module ----
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule actions_module modules/mod_actions.so
LoadModule alias_module modules/mod_alias.so
LoadModule allowmethods_module modules/mod_allowmethods.so
LoadModule asis_module modules/mod_asis.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule autoindex_module modules/mod_autoindex.so
LoadModule cache_disk_module modules/mod_cache_disk.so
LoadModule cgi_module modules/mod_cgi.so
LoadModule dav_lock_module modules/mod_dav_lock.so
LoadModule dir_module modules/mod_dir.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule include_module modules/mod_include.so
LoadModule info_module modules/mod_info.so
LoadModule isapi_module modules/mod_isapi.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_module modules/mod_mime.so
LoadModule negotiation_module modules/mod_negotiation.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule status_module modules/mod_status.so
LoadModule version_module modules/mod_version.so

# ---- PHP 8.5 ----
LoadModule php_module "C:/php/php8apache2_4.dll"
PHPIniDir "C:/php"

<FilesMatch "\.php$">
    SetHandler application/x-httpd-php
</FilesMatch>

<FilesMatch "\.phps$">
    Require all denied
</FilesMatch>

# ---- Server-Identitaet ----
ServerAdmin postmaster@localhost

# ANPASSEN: eigener Servername
ServerName beav.firma.de:80

# ---- Verzeichnisse ----
<Directory />
    AllowOverride none
    Require all denied
</Directory>

# ANPASSEN: Pfad zum web-Verzeichnis von beAV Pro
DocumentRoot "C:/beav/web"

<Directory "C:/beav/web">
    Options FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

# Fuer die Zertifikatserneuerung (Let's Encrypt u.ae.)
<Directory "C:/beav/web/.well-known">
    Require all granted
    AllowOverride None
</Directory>

<IfModule dir_module>
    DirectoryIndex index.php index.html
</IfModule>

<Files ".ht*">
    Require all denied
</Files>

# ---- Protokollierung mit taeglicher Rotation ----
ErrorLog "|C:/Apache/bin/rotatelogs.exe C:/Apache/logs/error_%Y-%m-%d.log 86400"
LogLevel warn

<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common

    CustomLog "|C:/Apache/bin/rotatelogs.exe C:/Apache/logs/access_%Y-%m-%d.log 86400" combined
</IfModule>

# ---- Leistung und Zeitlimits ----
<IfModule mpm_winnt_module>
    ThreadsPerChild        150
    MaxConnectionsPerChild   0
</IfModule>

Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
UseCanonicalName Off
AccessFileName .htaccess
ServerTokens Prod
ServerSignature Off
HostnameLookups Off

<IfModule reqtimeout_module>
    RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>

# ---- MIME ----
<IfModule mime_module>
    TypesConfig conf/mime.types
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
</IfModule>

<IfModule headers_module>
    RequestHeader unset Proxy early
</IfModule>

# ---- HTTPS ----
Include conf/extra/httpd-ssl.conf

ℹ️Zu Options FollowSymLinks

Ohne Indexes — dadurch liefert Apache für Verzeichnisse ohne Indexdatei keine Dateiliste aus. Betreiben Sie eine Bestandsinstallation, die .htaccess-Dateien verwendet, setzen Sie AllowOverride All. Bei einer Neuinstallation von beAV Pro werden keine benötigt.


7. httpd-ssl.conf anlegen

C:\Apache\conf\extra\httpd-ssl.conf
# =====================================================================
# HTTPS fuer beAV Pro
# =====================================================================

Listen 443

SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4:!3DES
SSLHonorCipherOrder on

SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLProxyProtocol -all +TLSv1.2 +TLSv1.3

SSLPassPhraseDialog  builtin
SSLSessionCache      "shmcb:C:/Apache/logs/ssl_scache(512000)"
SSLSessionCacheTimeout 300

<VirtualHost _default_:443>

# ANPASSEN: wie in httpd.conf
DocumentRoot "C:/beav/web"

# ANPASSEN: eigener Servername
ServerName beav.firma.de:443

ServerAdmin postmaster@localhost

ErrorLog "|C:/Apache/bin/rotatelogs.exe C:/Apache/logs/error_%Y-%m-%d.log 86400"
TransferLog "|C:/Apache/bin/rotatelogs.exe C:/Apache/logs/access_%Y-%m-%d.log 86400"

SSLEngine on

# ANPASSEN: eigene Zertifikatsdateien
SSLCertificateFile    "C:/Apache/conf/ssl/beav.crt.pem"
SSLCertificateKeyFile "C:/Apache/conf/ssl/beav.key.pem"

<FilesMatch "\.php$">
    SSLOptions +StdEnvVars
</FilesMatch>

BrowserMatch "MSIE [2-5]" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

CustomLog "|C:/Apache/bin/rotatelogs.exe C:/Apache/logs/ssl_request_%Y-%m-%d.log 86400" \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

</VirtualHost>

⚠️Zu SSLProtocol

-all +TLSv1.2 +TLSv1.3 schließt die veralteten Verfahren TLS 1.0 und 1.1 aus. Müssen Sie sehr alte Geräte bedienen, die nur TLS 1.0 beherrschen, verwenden Sie stattdessen all -SSLv3 — dann aber im Bewusstsein, dass Sie damit veraltete Verschlüsselung zulassen.


8. Zertifikat einrichten

Vorhandenes Zertifikat übernehmen

Kopieren Sie Zertifikat und Schlüssel nach C:\Apache\conf\ssl\ und tragen Sie die Dateinamen in Abschnitt 7 ein. Beide Dateien müssen im PEM-Format vorliegen (Textdateien, beginnend mit -----BEGIN).

Prüfen, ob Zertifikat und Schlüssel zusammengehören — die beiden Ausgaben müssen übereinstimmen:

C:\Apache\bin\openssl.exe x509 -noout -modulus -in C:\Apache\conf\ssl\beav.crt.pem | C:\Apache\bin\openssl.exe md5
C:\Apache\bin\openssl.exe rsa  -noout -modulus -in C:\Apache\conf\ssl\beav.key.pem | C:\Apache\bin\openssl.exe md5

Laufzeit prüfen:

C:\Apache\bin\openssl.exe x509 -in C:\Apache\conf\ssl\beav.crt.pem -noout -subject -dates

Selbstsigniertes Zertifikat für Test- und Entwicklungsrechner

C:\Apache\bin\openssl.exe req -x509 -nodes -days 825 -newkey rsa:2048 ^
  -keyout C:\Apache\conf\ssl\server.key ^
  -out C:\Apache\conf\ssl\server.crt ^
  -subj "/C=DE/O=beAV/CN=localhost" ^
  -addext "subjectAltName=DNS:localhost,IP:127.0.0.1"

ℹ️subjectAltName nicht vergessen

Aktuelle Browser ignorieren den Feldwert CN und werten ausschließlich subjectAltName aus. Fehlt er, erscheint die Sicherheitswarnung selbst dann, wenn das Zertifikat im Windows-Zertifikatsspeicher als vertrauenswürdig hinterlegt ist.


9. Prüfen — vor dem Umschalten

✅Bis hierher ist nichts passiert

Der bisherige Webserver läuft unverändert weiter. Die folgende Prüfung greift ihn nicht an und lässt sich gefahrlos wiederholen.

C:\Apache\bin\httpd.exe -t

Erwartet: Syntax OK

Diese Prüfung lädt sämtliche Module einschließlich PHP. Erscheint Syntax OK, ist damit auch belegt, dass das PHP-Modul geladen werden kann.

Modulliste kontrollieren:

C:\Apache\bin\httpd.exe -M

php_module (shared) muss in der Liste erscheinen.

PHP für sich prüfen:

C:\php\php.exe -m
C:\php\php.exe -r "echo 'PHP ' . PHP_VERSION;"

Die Ausgabe von -m muss unter anderem enthalten: curl, gd, mbstring, openssl, pdo_mysql, zip, fileinfo. Fehlt etwas, prüfen Sie Abschnitt 4.

CA-Bundle prüfen

Diese Prüfung wird gern übersprungen. Sie ist der einzige Weg, den Fehler vor dem ersten Update zu bemerken.

Ist der Pfad überhaupt gesetzt?

C:\php\php.exe -r "echo ini_get('curl.cainfo');"

Erwartet: C:\php\cacert.pem. Kommt eine leere Zeile, greift der [curl]-Abschnitt aus Abschnitt 5 nicht.

Funktioniert eine geprüfte Verbindung wirklich?

C:\php\php.exe -r "$c=curl_init('https://www.php.net/');curl_setopt($c,CURLOPT_RETURNTRANSFER,1);curl_exec($c);echo curl_error($c)?:'OK';"

Erwartet: OK. Erscheint unable to get local issuer certificate, fehlt die Datei C:\php\cacert.pem oder der Pfad ist falsch geschrieben.


10. Umschalten

🔴Ab hier entsteht eine Unterbrechung

Der bisherige Webserver wird gestoppt. Beide können Port 80 und 443 nicht gleichzeitig belegen. Auf einem Produktivsystem gehört dieser Abschnitt in ein Wartungsfenster.

1Alten Webserver stoppen und deaktivieren

net stop Apache2.4
sc config Apache2.4 start= disabled

Beides ist nötig. Wird nur gestoppt, startet der alte Dienst nach dem nächsten Neustart wieder mit — dann streiten beide um Port 443, und welcher gewinnt, ist Zufall.

Das Leerzeichen nach start= ist Pflicht.

2Neuen Apache im Vordergrund starten

C:\Apache\bin\httpd.exe

Das Fenster bleibt offen, Fehlermeldungen erscheinen unmittelbar darin. Solange es offen ist, läuft Apache. Strg+C beendet ihn.

ℹ️Mehrere leere Konsolenfenster sind hier normal

Wenn Sie die Protokollierung über rotatelogs.exe eingerichtet haben, öffnet sich beim Start für jede dieser Zeilen ein zusätzliches, leeres Fenster — bei vier Logdateien also vier Fenster. Das ist kein Fehler: rotatelogs ist ein eigenes Programm, das Apache im Vordergrundbetrieb sichtbar mitstartet.

Nicht schließen. Wer eines davon wegklickt, beendet die Protokollierung dieser Datei. Alle verschwinden von selbst, sobald Apache in Abschnitt 11 als Dienst läuft — dann startet er sie unsichtbar im Hintergrund.

Rufen Sie die Anwendung jetzt im Browser auf und arbeiten Sie die Testliste ab.

3Bei Problemen sofort zurück

Strg+C im Apache-Fenster, dann:

sc config Apache2.4 start= auto
net start Apache2.4

Dauer: wenige Sekunden. Näheres unter Rückweg.


11. Als Dienst einrichten

Erst wenn die Testliste durchgelaufen ist. Strg+C im Apache-Fenster, dann als Administrator:

C:\Apache\bin\httpd.exe -k install -n "Apache"
net start Apache

⚠️Dienstnamen unterscheidbar wählen

Apache statt Apache2.4 — die Namen dürfen nicht verwechselbar sein, solange beide Installationen vorhanden sind.

Kontrolle:

sc qc Apache
sc query Apache
sc query Apache2.4

Erwartet: Apache mit AUTO_START und RUNNING, Apache2.4 mit DISABLED und STOPPED.

Neustartprobe

Starten Sie den Rechner neu und prüfen Sie die beiden Befehle erneut. Erst danach gilt die Installation als abgeschlossen — ein Dienst, der von Hand läuft, aber nach einem Stromausfall nicht hochkommt, fällt sonst zum ungünstigsten Zeitpunkt auf.


12. Log-Rotation vervollständigen

Die Konfiguration aus den Abschnitten 6 und 7 erzeugt täglich neue Logdateien mit Datum im Namen. Sie löscht jedoch nichts — dafür ist ein zusätzliches Skript nötig, sonst sammeln sich die Dateien unbegrenzt an.

Prüfen Sie zunächst, ob die Rotation greift:

dir C:\Apache\logs\*.log

Es müssen Dateien mit Datum im Namen erscheinen, etwa access_2026-08-08.log.

Für das Löschen alter Dateien liegt dem Paket ein Skript samt Anleitung bei:

logrotate\log_rotate.ps1
logrotate\INSTALLATION_ANLEITUNG.md

Darin ist einzig der Pfad anzupassen:

$apacheLogDir = "C:\Apache\logs"

13. Testliste

Ohne diese Prüfungen ist die Installation nicht abgeschlossen:

⚠️Wenn sich der DocumentRoot geändert hat

Zeigte der Webroot bisher auf ein übergeordnetes Verzeichnis, ändert sich die Adresse der Anwendung — aus https://server/beav/web/ wird https://server/. Alte Lesezeichen laufen dann ins Leere, und eine bereits installierte PWA muss neu eingerichtet werden.


14. Was gepflegt werden muss

Ein einmal aufgesetzter Webserver bleibt nicht von selbst in Ordnung. Entscheidend ist die Unterscheidung: Das meiste steckt in Paketen und wird beim Paketwechsel automatisch mit erneuert — zwei Dinge tun das nicht.

Erneuert sich mit dem Paket — keine gesonderte Pflege

Diese Bestandteile liegen innerhalb von Apache oder PHP. Ein Versionswechsel nach Anhang C bringt sie mit:

BestandteilStand hierSteckt in
libcurl8.21.0PHP
OpenSSL3.5.7PHP
zlib1.3.2PHP
Zeitzonendatenbank2026.3PHP
mime.types Apache

Die eigenen Stände lassen sich jederzeit ablesen — eine Zeile:

C:\php\php.exe -r "$c=curl_version(); echo 'libcurl '.$c['version'].' | '.$c['ssl_version'].' | zlib '.$c['libz_version'].' | tzdata '.timezone_version_get().PHP_EOL;"

Erneuert sich nicht von selbst — hier ist Pflege nötig

WasRhythmusWarum und wie
C:\php\cacert.pem
CA-Bundle
jährlich Liegt in keinem Paket — weder Apache, PHP noch Windows-Update erneuern es. Veraltet still: Zurückgezogene Zertifizierungsstellen bleiben vertrauenswürdig, neue fehlen.
Vorher sichern, dann ersetzen:
Copy-Item C:\php\cacert.pem C:\php\cacert_alt.pem
Invoke-WebRequest https://curl.se/ca/cacert.pem -OutFile C:\php\cacert.pem
Apache muss dafür weder gestoppt noch neu gestartet werden — PHP liest die Datei bei jeder Verbindung neu. Anschließend die Prüfung aus Abschnitt 9. Falls etwas nicht stimmt, genügt zur Rücknahme:
Copy-Item C:\php\cacert_alt.pem C:\php\cacert.pem -Force
Serverzertifikat
C:\Apache\conf\ssl\
vor Ablauf Bei einem ACME-Client (Let's Encrypt) geschieht das automatisch — dann aber die Bereitstellung prüfen, damit die erneuerte Datei auch an C:\Apache\conf\ssl\ ankommt und Apache neu geladen wird. Bei einem selbstsignierten oder gekauften Zertifikat ist der Austausch Handarbeit.
Restlaufzeit ablesen:
C:\Apache\bin\openssl.exe x509 -in C:\Apache\conf\ssl\server.crt -noout -dates
Apache und PHP siehe Anhang C Sicherheitsaktualisierungen erscheinen unabhängig voneinander und müssen aktiv geholt werden. Es gibt keinen automatischen Bezug.
Logdateien läuft automatisch Sofern Abschnitt 12 eingerichtet ist. Gelegentlich nachsehen, ob das Löschskript wirklich greift.

⚠️Übernommene Dateien tragen das Alter ihrer Quelle

Wird bei der Einrichtung etwas aus einer bestehenden Installation kopiert — CA-Bundle, Zertifikat, Konfiguration —, hat die Kopie den Stand der alten Umgebung, nicht den von heute. Bei XAMPP sind das schnell mehrere Jahre. Prüfen Sie bei jeder übernommenen Datei das Datum, statt sie ungesehen weiterzureichen.


Rückweg

✅Der alte Webserver bleibt vollständig erhalten

Er wird ausschließlich gestoppt und deaktiviert — nichts wird gelöscht oder überschrieben. Die Rückkehr dauert Sekunden.

Solange der neue nur im Vordergrund läuft

sc config Apache2.4 start= auto
net start Apache2.4

Wenn der neue bereits als Dienst eingerichtet ist

net stop Apache
sc config Apache start= disabled
sc config Apache2.4 start= auto
net start Apache2.4

Der neue Dienst muss deaktiviert werden, nicht nur gestoppt — sonst kollidieren nach dem nächsten Neustart beide auf Port 443.

Prüfen, wer gerade lauscht

netstat -ano | findstr ":80 :443"
sc query Apache
sc query Apache2.4

⚠️Was sich nicht zurücknehmen lässt

Das Visual C++ Redistributable. Ein Downgrade ist nicht vorgesehen. Es ist zugleich der unkritischste Teil: Die Bibliothek ist abwärtskompatibel, alle bisherigen Programme laufen mit der neueren Fassung weiter — auch der alte Apache und das alte PHP.


Anhang A — Wenn XAMPP oder ein anderer Webserver vorhanden ist

Diese Anleitung installiert neben der bestehenden Installation, nicht darüber. Das ist Absicht: Die alte bleibt als Rückfallebene erhalten.

A.1 Bestandsaufnahme

sc query state= all | findstr /i "apache maria mysql"
netstat -ano | findstr ":80 :443"

Notieren Sie sich vor dem Umbau:

A.2 Zertifikate übernehmen

Die vorhandenen Dateien nach C:\Apache\conf\ssl\ kopieren. Die alte Installation behält ihre Kopien — beide funktionieren nebeneinander, solange nur ein Webserver läuft.

Prüfen Sie dabei die Restlaufzeit, statt die Dateien ungesehen zu übernehmen:

C:\Apache\bin\openssl.exe x509 -in C:\Apache\conf\ssl\server.crt -noout -subject -dates

⚠️Was übernommen wird, ist so alt wie die Quelle

Das gilt für jede Datei, die aus der alten Installation stammt. Zwei Fälle sind bei XAMPP typisch:

DateiWas zu beachten ist
apache\bin\curl-ca-bundle.crt Nicht übernehmen. Stand 26.04.2022 — siehe Abschnitt 5. Immer frisch von curl.se laden.
apache\conf\ssl\server.crt Bei XAMPP ein selbstsigniertes Zertifikat auf CN=localhost mit einem Jahr Laufzeit. Für einen Testrechner brauchbar, für einen erreichbaren Server nicht — dort gehört ein echtes Zertifikat hin.

Die Übersicht, was danach dauerhaft gepflegt werden muss, steht in Abschnitt 14.

A.3 Datenbank nicht anfassen

Bringt das alte Paket eine eigene Datenbank mit (XAMPP etwa MariaDB 10.4), lassen Sie diese zunächst unberührt. Der Wechsel des Webservers und der Wechsel der Datenbank sind zwei getrennte Vorhaben und sollten nicht gleichzeitig erfolgen.

A.4 Das XAMPP Control Panel nach dem Umstieg

Das Control Panel kennt den neuen Apache nicht. Es zeigt seinen eigenen weiterhin als gestoppt an — das ist richtig so und muss nicht korrigiert werden.

🔴Das Kästchen links neben dem Dienst nicht anklicken

Es sieht aus wie ein Schalter für „Dienst starten", ist aber ein Schalter für Dienst installieren / deinstallieren. Ein Klick auf das gesetzte Häkchen entfernt den Windows-Dienst — beim Zurückklicken wird er neu angelegt, allerdings mit den Vorgaben von XAMPP. Nach dem Umstieg ist der alte Dienst absichtlich deaktiviert; ein versehentliches Neuanlegen setzt ihn wieder auf automatischen Start, und nach dem nächsten Neustart streiten beide Webserver um Port 443.

Nutzen Sie zum Starten und Stoppen ausschließlich net start / net stop in der Eingabeaufforderung.

A.5 XAMPP gegen versehentliche Deinstallation sperren

🔴Der gefährlichste Moment kommt Wochen später

Nach dem Umstieg wirkt XAMPP überflüssig — es läuft nichts mehr darin. Wer es daraufhin über Programme und Features entfernt, löscht mit einem Klick unter anderem:

  • C:\xampp\htdocs\… — die Anwendung selbst, sofern sie noch dort liegt
  • deren config/ mit den Datenbank-Zugangsdaten
  • C:\xampp\apache\conf\ssl\ — die Original-Zertifikate
  • C:\xampp\mysql\data\ — die alte Datenbank

Eine Warndatei im Ordner hilft nicht: Der Uninstaller löscht sie mit, und niemand öffnet das Verzeichnis, bevor er über das Startmenü deinstalliert.

Die eigentliche Lösung ist, die Anwendung aus C:\xampp\htdocs herauszuholen — etwa nach C:\beav. Anzupassen sind dann DocumentRoot samt Directory-Block in httpd.conf, DocumentRoot in httpd-ssl.conf und der Site Root im ACME-Client. Das ist eine eigene Änderung mit eigenem Test — nicht im selben Wartungsfenster.

Solange sie dort liegt, braucht es eine technische Sperre. Beide Wege — Programme und Features wie Doppelklick — laufen über dieselbe Datei. Eingabeaufforderung als Administrator:

ren C:\xampp\uninstall.exe uninstall.exe.GESPERRT

Danach scheitert die Deinstallation über beide Wege. Wer sie wirklich braucht, benennt die Datei zurück — dann aber bewusst.

Zusätzlich die Warnung dorthin setzen, wo deinstalliert wird — eine Zeile:

reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\xampp" /v DisplayName /t REG_SZ /d "XAMPP - NICHT DEINSTALLIEREN (enthaelt Anwendung und Zertifikate)" /f

In Programme und Features steht dann statt „XAMPP" der Warntext.

Kontrolle:

dir C:\xampp\uninstall*
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\xampp" /v DisplayName

Erwartet: uninstall.exe.GESPERRT und uninstall.dat, keine uninstall.exe.

⚠️Der Registrierungsschlüssel kann anders heißen

Meldet reg query „Der angegebene Schlüssel wurde nicht gefunden", suchen Sie ihn — eine Zeile in PowerShell:

Get-ChildItem "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall","HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" -EA 0 | ForEach-Object { $d=(Get-ItemProperty $_.PSPath -EA 0).DisplayName; if ($d -like "*XAMPP*") { $_.PSPath } }

Ergibt der Befehl nichts, ist XAMPP nicht registriert und lässt sich ohnehin nicht über Programme und Features entfernen. Die Umbenennung von uninstall.exe genügt dann.


Anhang B — Fehlersuche

Apache startet nicht

C:\Apache\bin\httpd.exe -t
powershell -Command "Get-Content C:\Apache\logs\error_*.log -Tail 30"
MeldungUrsache und Abhilfe
Cannot load php8apache2_4.dll Falscher PHP-Build (NTS statt Thread Safe) oder VC++ Redistributable zu alt — siehe Abschnitte 3 und 2
Address already in use / make_sock Der alte Webserver läuft noch. netstat -ano | findstr ":443"
SSLCertificateFile: file does not exist Pfad in httpd-ssl.conf falsch, oder Schrägstriche mit Backslashes vertauscht
server certificate is a CA certificate Nur ein Hinweis, kein Fehler. Tritt bei manchen selbstsignierten Zertifikaten auf
Syntax error on line ... Zeilennummer prüfen. Häufigste Ursache: Backslash statt Schrägstrich im Pfad

Apache läuft, aber PHP-Seiten bleiben leer oder werden heruntergeladen

SymptomUrsache
Browser bietet die PHP-Datei zum Download an FilesMatch-Block mit SetHandler fehlt in httpd.conf
Seite bleibt leer, Log zeigt Unable to load dynamic library 'curl' C:\php fehlt im Systempfad — siehe Abschnitt 4
Seite bleibt leer, Antwort enthält Location: Kein Fehler: Die Anwendung leitet auf HTTPS um. Über https:// aufrufen
Fatal error: Uncaught PDOException Datenbank nicht erreichbar oder Zugangsdaten in config/config.php falsch

Update-Prüfung oder Update-Download schlägt fehl

MeldungUrsache und Abhilfe
SSL certificate problem: unable to get local issuer certificate Das CA-Bundle fehlt. PHP nutzt unter Windows OpenSSL, nicht den Windows-Zertifikatsspeicher — C:\php\cacert.pem bereitstellen und curl.cainfo setzen, siehe Abschnitt 5
certificate has expired bei einer Gegenstelle, die im Browser einwandfrei ist Das CA-Bundle ist veraltet. Aktuelle Fassung von https://curl.se/ca/cacert.pem holen und ersetzen
Lizenzstatus funktioniert, aber die Update-Prüfung nicht Typisches Bild bei fehlendem CA-Bundle: Nur die Aufrufe mit Zertifikatsprüfung scheitern. Prüfung wie in Abschnitt 9
Eine Gegenstelle geht, eine andere nicht Deutet auf ein veraltetes statt fehlendes Bundle: Es enthält nur einen Teil der heute üblichen Wurzelzertifikate. Stand ablesen und erneuern, siehe Abschnitt 14

Alle Gegenstellen auf einmal prüfen — als Datei speichern und mit C:\php\php.exe datei.php aufrufen:

<?php
foreach ([
    'https://kunden.beav-web.de/',
    'https://feiertage-api.de/',
    'https://s3.eu-central-1.amazonaws.com/',
] as $url) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_NOBODY         => true,
        CURLOPT_TIMEOUT        => 20,
    ]);
    curl_exec($ch);
    $err = curl_error($ch);
    printf("%-42s %s\n", $url, $err === '' ? 'OK' : $err);
    unset($ch);
}

Die dritte Adresse betrifft nur Installationen mit S3-Dateispeicher.

Fehlerlog wächst schnell

MeldungAbhilfe
session.sid_bits_per_character INI setting is deprecated Diese Zeile aus der php.ini entfernen
Deprecated: curl_close() und ähnliche Veraltete beAV-Version. Ab Version 1.19 nicht mehr enthalten

Wo welches Log liegt

Es gibt zwei getrennte Log-Verzeichnisse. Wer im falschen sucht, findet nichts:

VerzeichnisWer schreibtWas darin steht
C:\Apache\logs Apache access — jeder Zugriff · error — Startprobleme, fehlende Dateien, Konfigurationsfehler · ssl_request — HTTPS-Verbindungen · httpd.pid ist kein Log
C:\php\logs PHP php_error_log — Fehler und Warnungen aus der Anwendung, darunter Zertifikats- und Verbindungsprobleme

ℹ️Die Datei heißt php_error_log — ohne Punkt, ohne Endung

Das ist der in php.ini eingetragene Name, kein Versehen. Der eingestellte Pfad lässt sich jederzeit ablesen:

C:\php\php.exe -r "echo ini_get('error_log');"

Ist die Datei 0 Bytes groß, sagt das für sich genommen noch nichts — sie könnte auch unbeschreibbar sein. Einmalig prüfen:

C:\php\php.exe -r "error_log('Schreibtest');"

Danach muss die Zeile in der Datei stehen. Anschließend wieder leeren: Clear-Content C:\php\logs\php_error_log

Vor einem Test das PHP-Log leeren — dann gehört jede neue Zeile eindeutig zum Test:

Clear-Content C:\php\logs\php_error_log
Get-Content C:\php\logs\php_error_log -Tail 30

Nützliche Befehle

C:\Apache\bin\httpd.exe -t         Konfiguration prüfen
C:\Apache\bin\httpd.exe -M         geladene Module
C:\Apache\bin\httpd.exe -V         Kompilierungseinstellungen
C:\php\php.exe -m                  geladene Erweiterungen
C:\php\php.exe --ini               welche php.ini gilt
C:\php\php.exe -i                  vollständige Konfiguration

Anhang C — Updates

Weder Apache noch PHP aktualisieren sich selbst; beide erscheinen nicht in Windows Update.

Empfohlener Rhythmus: vierteljährlich nachsehen, als Kalendereintrag.

KomponentePrüfen auf
Apachehttps://www.apachelounge.com/download/
PHPhttps://windows.php.net/download/
CA-Bundlehttps://curl.se/ca/cacert.pem — kommt in keinem der beiden Pakete mit, siehe Abschnitt 14

Ablauf eines Updates

  1. Neues Paket herunterladen und Prüfsumme kontrollieren
  2. Dienst stoppen: net stop Apache
  3. Verzeichnis sichern: C:\Apache nach C:\Apache_alt kopieren (bei PHP entsprechend)
  4. Neue Dateien über das Verzeichnis entpacken
  5. Konfiguration zurückkopieren — httpd.conf, httpd-ssl.conf, conf\ssl\ und php.ini werden dabei überschrieben
  6. httpd.exe -t
  7. net start Apache
  8. Testliste abarbeiten

⚠️Das CA-Bundle kommt bei einem PHP-Update nicht mit

Es liegt zwar unter C:\php, gehört aber nicht zum PHP-Paket — das neue Archiv enthält keine solche Datei. Ein Update erneuert es also nicht und überschreibt es auch nicht; die vorhandene Datei bleibt einfach stehen, mit ihrem alten Stand. Nehmen Sie den Austausch daher als eigenen Punkt in den Ablauf auf:

Invoke-WebRequest https://curl.se/ca/cacert.pem -OutFile C:\php\cacert.pem

ℹ️Deshalb Verzeichnisse ohne Versionsnummer

Weil die Pfade C:\Apache und C:\php keine Version enthalten, bleiben sämtliche Konfigurationszeilen bei einem Update gültig. Bei C:\php85 müsste jede Pfadangabe angefasst werden.

Wechsel auf eine neue PHP-Hauptversion

Innerhalb von 8.5 sind Updates unkritisch. Der Wechsel auf 8.6 oder höher ist ein eigenes Vorhaben: Erst prüfen, welche Funktionen abgekündigt oder entfernt wurden, dann auf einem Testsystem erproben — nie direkt auf dem Produktivsystem.

PHP 8.5 wird bis zum 31.12.2029 mit Sicherheitskorrekturen versorgt. Bis dahin besteht kein Handlungsbedarf.


✅Fertig — wie geht es weiter?

Der Webserver läuft. Ist beAV Pro noch nicht installiert, fahren Sie mit der Installationsanleitung fort. Fehlt noch die Datenbank, richten Sie zuerst MariaDB 11.4 ein.