‘redir’ im Caddyserver

3 Minuten Lesezeit

Als ich meine Website weg von Github Pages auf einen eigenen Server umzog, hatte ich einige Probleme und offene Fragen bezüglich automatischer Weiterleitungen. Mein Blog ging nämlich von der root-Domain in eine Subdomain (blog.schallbert.de) über.

Anforderungen an die Weiterleitung

  • Bereits auf meine Blogartikel unter altem Namen referenzierte Links z.B. auf schallbert.de/about sollen korrekt auf die Subdomain weiterleiten (kein 404)
  • Die Stammseite unter schallbert.de soll vollständig nutzbar sein
  • Daten und Dateien für Domain und Subdomains sollen unabhängig voneinander sein
  • Die Webserver sollen für verschiedene Unterseiten unterschiedliche Technologien verwenden können

Umsetzung

Zuerst hatte ich gedacht, dass ich die Weiterleitungen im DNS-provider über A und CNAME Einträge erreichen könnte. Schnell wurde mir jedoch klar, dass ich a) keine Ahnung hatte, wie DNS überhaupt funktioniert und b) der richtige Weg über die Konfiguration meines Webservers führt.

Erster Versuch: redir bei ‘/’

Auf meinem Webserver (Caddy) werden Weiterleitungen in der Caddyfile per redir spezifiziert. Dabei kann das permanent (als sogenannte http 301) oder temporary per 302 (Standardeinstellung) geschehen.

Mein erster Gedanke war, dass ich schallbert.de unmodifiziert lasse und alles hinter einem eventuellen / weiterleite. Dies sieht dann in der Caddyfile wie folgt aus:

schallbert.de {
        # Define webserver
        root * /www/landing
        encode gzip
        file_server

        # Redir to subdomain if domain has a slash
        @redirect path_regexp /*
        redir @redirect https://blog.schallbert.de{uri}
}

In der Folge hat Caddy schlicht alles an die Subdomain weitergeleitet. Der Haken dabei war, dass die Subdomain selbst ja auch wieder Slashes bzw. eine URI hinter dem Slash enthält und dann wiederum weitergeleitet wird. Beispiel:

schallbert.de/post -> blog.schallbert.de/post -> blog.schallbert.de/post -> blog.schallbert.de/post -> [...]

Somit bekam ich eine rekursive Endlosweiterleitung. Ich habe meinen Server damit komplett lahmgelegt 😅

Zweiter Versuch: Filterung per Regexp

Ich brauche also eine bessere Filterung, sodass nur Slashes mit weiteren Zeichen dahinter auch wirklich weitergeleitet werden und die Weiterleitung nicht rekursiv ablaufen kann. Zum Glück hatte ich Hilfe von einem guten Freund, sodass kurze Zeit darauf folgendes Caddyfile entstand:

schallbert.de {
        # Define webserver
        root * /www/landing
        encode gzip
        file_server

        # Redir to subdomain to maintain links for blog
        @redirect path_regexp ^/[^/]+(/.*)?$
        redir @redirect https://blog.schallbert.de{uri}
}

Die Regexp prüft ab, ob ein Slash hinter der Domain URL vorliegt und dahinter zumindest ein weiteres Zeichen folgt. Hier funktioniert die Weiterleitung nun wie gewünscht und mein Blog ist auch unter den alten Links weiterhin vollständig erreichbar.

Trotzdem war ich noch nicht ganz zufrieden. Denn als ich mir eine schöne “Landing Page” auf meiner Root Domain erstellte, war von ihr plötzlich nur noch das reine HTML zu sehen. Kein favicon, keine Bilder, kein CSS.

Ein kurzer Blick in die Entwickleroptionen brachte schnell die Erkenntnis dass die Pfade aller Assets, die ich auf meiner Landing Page hinterlegt hatte, durch die Ordnerstruktur mit / gekennzeichnet, an die Subdomain weitergeleitet wurden. Wo sie natürlich nicht liegen.

Dritter Versuch: Regexp plus Dateisuche

Zum Glück bin ich wieder mal mit dem Problem nicht allein, sodass im Forum von Caddy die Lösung zu finden war:

Mit dem not file Marker kann ich in der Caddyfile Weiterleitungen definieren, falls Ressourcen auf der aktuellen Seite unauffindbar sind.

Somit sieht meine Lösung jetzt wie folgt aus:

schallbert.de {
        @filenotfound {
          path_regexp ^/[^/]+(/.*)?$
          not file
        }

        # show Caddy where to find page resources
        root * /www/landing
        encode gzip

        route {
          # Redirect to subdomain if article cannot found on root
          redir @filenotfound https://blog.schallbert.de{uri}

          # else, define webserver and show page
          file_server
        }
}

Hier ist wichtig, dass ich die Seite mit root * /www/<pagelocation> definiere, bevor ich die route anlege. Denn sonst werden die Assets erst verfügbar, nachdem ich bereits aus Ermangelung vorhandener Dateien weitergeleitet habe.

Erfolg!

Jetzt endlich wird meine Baustellenseite korrekt dargestellt.

Image: Correctly rendered 'website under construction' page on schallbert.de