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
| Komponente | Version | Unterstützt bis |
|---|---|---|
| Apache | 2.4.68 | 2.4 ist die einzig gepflegte Linie |
| PHP | 8.5.9 Thread Safe x64 | 31.12.2029 |
| MariaDB | 11.4 LTS | 2029 |
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:
| Wert | Beispiel | Ihrer |
|---|---|---|
| Apache-Verzeichnis | C:\Apache | |
| PHP-Verzeichnis | C:\php | |
| Anwendungsverzeichnis | C:\beav_app | |
Webroot (das web-Verzeichnis darin) | C:\beav_app\web | |
| Servername | beav.firma.de | |
| Zertifikatsdatei | C:\Apache\conf\ssl\beav.crt.pem | |
| Schlüsseldatei | C:\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:
| Verzeichnis | Inhalt |
|---|---|
C:\beav_app | Programm — config\, web\, _beav_backups\ |
C:\beav | Daten — 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
| Was | Wo |
|---|---|
| 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
| Datei | SHA256 |
|---|---|
| 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.
| Punkt | Worauf 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%
| Wert | Bedeutung | Weiter mit |
|---|---|---|
0 | installiert | Schritt 4 |
3010 | installiert, Neustart nötig | Windows neu starten, dann Schritt 4 |
1638 | neuere Version vorhanden | Schritt 4 |
1602 | abgebrochen | erneut versuchen |
5 | Zugriff verweigert | als 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.
; =====================================================================
; 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:
| Was | Was es ist | Pflege |
|---|---|---|
cacert.pemin 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:
| Anzahl | Unterschied |
|---|---|
| 43 | Wurzelzertifikate, 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 |
| 28 | Wurzelzertifikate, 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
| Einstellung | Erlä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.
# =====================================================================
# 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
# =====================================================================
# 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:
- Anmeldung funktioniert
- Dashboard zeigt Daten — belegt die Datenbankverbindung
- Datensatz anlegen und speichern
- Dokument hochladen — prüft
fileinfo,gdund den Dateispeicher - Dokument wieder öffnen — prüft die Verarbeitung von Binärdaten
- PDF erzeugen
- Lizenzstatus aufrufen — prüft
curlundopenssl - Update-Prüfung aufrufen — prüft zusätzlich das CA-Bundle. Der Lizenzstatus allein genügt hier nicht: Er kann funktionieren, während die Update-Prüfung an fehlenden Wurzelzertifikaten scheitert
- Mobile PWA aufrufen und ein Foto hochladen — prüft HTTPS und Service Worker
- HTTPS ohne Zertifikatswarnung (bei echtem Zertifikat)
C:\php\logs\php_error_logist leer oder frei von Warnungen — nicht inC:\Apache\logssuchen, das ist der Webserver-Ordner; siehe Anhang Bdir C:\Apache\logs\*.logzeigt datierte Dateien- Nach einem Neustart kommt der Dienst selbstständig hoch
⚠️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:
| Bestandteil | Stand hier | Steckt in |
|---|---|---|
| libcurl | 8.21.0 | PHP |
| OpenSSL | 3.5.7 | PHP |
| zlib | 1.3.2 | PHP |
| Zeitzonendatenbank | 2026.3 | PHP |
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
| Was | Rhythmus | Warum und wie |
|---|---|---|
C:\php\cacert.pemCA-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.pemInvoke-WebRequest https://curl.se/ca/cacert.pem -OutFile C:\php\cacert.pemApache 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 |
ServerzertifikatC:\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:
- Pfad zum bisherigen
DocumentRoot - Servername und Zertifikatspfade
- Welche Module geladen sind:
httpd.exe -M - Welche Erweiterungen geladen sind:
php.exe -m - Werte aus der bisherigen
php.ini:memory_limit,upload_max_filesize,post_max_size,max_execution_time,date.timezone
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:
| Datei | Was 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-ZertifikateC:\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"
| Meldung | Ursache 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
| Symptom | Ursache |
|---|---|
| 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
| Meldung | Ursache 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
| Meldung | Abhilfe |
|---|---|
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:
| Verzeichnis | Wer schreibt | Was 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.
| Komponente | Prüfen auf |
|---|---|
| Apache | https://www.apachelounge.com/download/ |
| PHP | https://windows.php.net/download/ |
| CA-Bundle | https://curl.se/ca/cacert.pem — kommt in keinem der beiden Pakete mit, siehe Abschnitt 14 |
Ablauf eines Updates
- Neues Paket herunterladen und Prüfsumme kontrollieren
- Dienst stoppen:
net stop Apache - Verzeichnis sichern:
C:\ApachenachC:\Apache_altkopieren (bei PHP entsprechend) - Neue Dateien über das Verzeichnis entpacken
- Konfiguration zurückkopieren —
httpd.conf,httpd-ssl.conf,conf\ssl\undphp.iniwerden dabei überschrieben httpd.exe -tnet start Apache- 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.