Apache

Ekkart Kleinod  • 

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

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 werden
    • httpd.conf oder apache.conf
    • AllowOverride None ändern zu AllowOverride 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)

URL Rewriting

Konkretes Problem: ich liefere json-Dateien aus, die unter einem anderen Namen aufgerufen werden sollen. Das Muster ist:

Dokumentation:

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.