Apache
Apache ist der Server, der fast überall eingesetzt wird. Lässt sich auch gut dockern, dabei aber nur über eigene Images anpassen. Hat eine Weile gedauert, das herauszufinden.
Wichtig: der Server ist eigentlich "httpd", Apache ist die Organisation dahinter. Bei Docker-Images wird das mal so, mal so verwendet
- Doku: https://httpd.apache.org
- Hub "httpd": https://hub.docker.com/_/httpd
- Hub "php", auch mit Apache möglich: https://hub.docker.com/_/php
docker-compose
Ich finde es einfacher, Apache mit docker-compose zu benutzen, da sind die Einstellungen einfach übersichtlicher. Meist reicht das für meinen Anwendungsfall und die Ergänzung von Datenbanken und anderen Sachen ist einfacher. Dabei hilft es, sich für den Start und das Beenden kleine Skripte zu schreiben, vor allem, wenn man dort noch Infos für den Aufruf hinterlegt.
Start
Skript: up.sh
- detach - Container im Hintergrund ausführen
#!/bin/bash echo "Run server at http://localhost:8000" echo "inspect with: docker exec --interactive --tty apache bash" echo docker-compose up --detach
Stop
Skript: down.sh
#!/bin/bash echo "Stop server" echo docker-compose down
Apache/httpd: docker-compose.yml
version: '3.8' services: apache: container_name: apache image: httpd volumes: - ../API-Client/:/usr/local/apache2/htdocs/ - ../../larc-api/api/generated/:/usr/local/apache2/htdocs/api/ ports: - 8000:80
Hier nehmen wir das httpd-Image, das Verzeichnis für die Webseiten ist:
/usr/local/apache2/htdocs/
Es können verschiedene Verzeichnisse auf verschiedene Zielverzeichnisse gemappt werden, das ist ganz hilfreich, wenn man Dateien an unterschiedlichen Orten hat. Das Beispiel ist von hier: https://gitlab.com/opentt/larc
Wichtig:
- es sind kaum Module aktiviert
.htaccess
ist ausgeschaltet, das muss explizit über die Konfiguration eingeschaltet werdenhttpd.conf
oderapache.conf
AllowOverride None
ändern zuAllowOverride All
<Directory "/var/www/htdocs"> AllowOverride All
- dafür muss wohl ein eigenes Image erzeugt werden, hab ich mir gespart, daher kein Beispiel
PHP+Apache/httpd: docker-compose.yml
version: '3.8' services: php-apache: container_name: apache image: php:apache volumes: - ../API-Client:/var/www/html - ../../larc-api/api/generated/:/var/www/html/api/ ports: - 8000:80
Hier nehmen wir das php-Image, das Verzeichnis für die Webseiten ist:
/var/www/html/
Im Netz finden man auch die Möglichkeit, PHP und Apache getrennt zu verwenden und einzubinden, ich weiß nicht, wo da die Vor- und Nachteile liegen und für meinen Zweck ist php:apache
genau richtig.
Es können verschiedene Verzeichnisse auf verschiedene Zielverzeichnisse gemappt werden, das ist ganz hilfreich, wenn man Dateien an unterschiedlichen Orten hat. Das Beispiel ist von hier: https://gitlab.com/opentt/larc
Wichtig:
- es sind einige Module aktiviert
- ausgerechnet
mod_rewrite
natürlich nicht - dafür muss ein eigenes Image erzeugt werden (siehe URL Rewriting)
- ausgerechnet
URL Rewriting
Konkretes Problem: ich liefere json-Dateien aus, die unter einem anderen Namen aufgerufen werden sollen. Das Muster ist:
- https://www.opentt.de/larc/api/larcs/ -> https://www.opentt.de/larc/api/larcs/all.json
- https://www.opentt.de/larc/api/larcs/2022-1 -> https://www.opentt.de/larc/api/larcs/2022-1.json
Dokumentation:
- rewrite: https://httpd.apache.org/docs/current/rewrite/
- mod_rewrite: https://httpd.apache.org/docs/current/mod/mod_rewrite.html
- Konfiguration: https://httpd.apache.org/docs/current/configuring.html
- .htaccess: https://httpd.apache.org/docs/current/howto/htaccess.html
- Ubuntuusers: https://wiki.ubuntuusers.de/Apache/mod_rewrite/
Zunächst muss rewrite aktiviert werden, falls es noch nicht läuft, siehe rewrite aktivieren.
Umleitungen erfolgen über RewriteRule
in der .htaccess
(geht auch in der Apache-Konfig, aber da kommt man selten ran).
Die Regeln werden von oben bis zum ersten Treffer abgearbeitet.
.htaccess
lege ich ins Verzeichnis https://www.opentt.de/larc/api/
Umleitungen:
.../larcs/ -> .../api/larcs/all.json
.../larcs/<id> -> .../api/larcs/<id>.json
Das [END]
sorgt dafür, dass das rewrite sofort abbricht, also keine Endlosschleifen in einer Regel entstehen können.
Die RewriteCond
sorgt dafür, dass .json-Dateien nicht ersetzt werden, verhindert also auch Endlosschleifen.
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^(.*)/$ $1/all.json [END] RewriteCond %{REQUEST_URI} !.(json)$ RewriteRule ^(.*)/(.*)$ $1/$2.json [END] </IfModule>
rewrite aktivieren
Hier: für php:apache
Dafür muss ein eigenes Image erzeugt werden, damit ich das nicht jedesmal machen muss, hab ich auch für andere Projekte meine eigenen Docker-Images, die auch auf dem Dockerhub liegen:
Kurz:
FROM php:apache RUN a2enmod rewrite
Test: wird .htaccess ausgewertet?
In einem Verzeichnis eine .htaccess
anlegen, die einen Fehler enthält, also z.B. in der ersten Zeile nur das Wort "Test":
Test <IfModule mod_rewrite.c> RewriteEngine On ...
Dann sollte erscheinen:
Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Wenn kein Fehler erscheint, dann wird .htaccess
nicht ausgewertet.
Test: ist URL-Rewriting aktiviert?
In einem Verzeichnis eine .htaccess
anlegen:
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^rewrite$ rewrite.html </IfModule>
Im selben Verzeichnis rewrite.html
anlegen:
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Rewrite Test</title> </head> <body> <h1>Rewrite Test</h1> <p>If you came here via <a href="rewrite">rewrite</a>, it works.</p> <p>If you only came here via <a href="rewrite.html">rewrite.html</a>, it does not work.</p> </body> </html>
Aufrufen mit http://localhost/rewrite oder ergänzt um das Verzeichnis. Wenn die Seite angezeigt wird funktioniert der rewrite.