Blog
Deaktivieren Sie den CloudFront-Cache für Hugo-Websites

Hugo ist ein großartiges Tool, mit dem Sie schnell und einfach Websites erstellen können. Es rendert eine vollständige statische HTML-Version Ihrer Website. Das macht es zu einem idealen Kandidaten für das Hosten auf einem S3 Bucket. Sie können dann CloudFront verwenden, um die Inhalte weltweit bereitzustellen.
CloudFront Cache
Ein Cache kann eine wunderbare Sache sein! Aber er kann auch eine lästige Sache sein. Deshalb habe ich mich entschlossen, dieses Thema für meine eigene Website ein wenig zu vertiefen. Wenn Sie also S3 als Ursprung verwenden, ist die TTL (Time To Live) standardmäßig auf 24 Stunden eingestellt. Das heißt, wenn Sie Ihre Website besuchen, wird diese Version für 24 Stunden am Edge-Standort zwischengespeichert.
Das heißt, wenn Sie Ihre Website aktualisieren, werden die Änderungen für Sie nicht sichtbar sein. Der Grund dafür ist, dass Sie höchstwahrscheinlich auf demselben Edge-Server landen werden. Sie können den Cache zwar ungültig machen, aber Objekte wie Fotos und Videos profitieren von diesem Cache.
Nur ungültig machen, was sich geändert hat
Das bringt uns also zum nächsten logischen Schritt. Invalidieren Sie nur die Dinge, die geändert wurden. Ich verwende CodeCommit als Quell-Repository. Sie können git fragen, welche Dateien geändert wurden:
git diff-tree --no-commit-id --name-only -r HEAD
Damit erhalten Sie eine Liste der Dateien, die bei Ihrem letzten Commit geändert wurden. Mit diesen Informationen können Sie intelligente Dinge tun:
- Wählen Sie nur die geänderten Dateien im Ordner
contentaus. - Ersetzen Sie die Teile, die
_indexenthalten, durchindex. - Ersetzen Sie die Teile, die
.mdenthalten, durch.html. - Erkennen Sie, wo wir eine Post-Aggregation haben.
Für diesen Blogbeitrag würde das also bedeuten:
$ git diff-tree --no-commit-id --name-only -r HEAD
content/blog/2023/07/invalidate-cloudfront-cache-for-hugo-websites/index.md
Hugo verwendet also _index.md Dateien, um Seiten zu erzeugen, die alle untergeordneten Seiten auflisten. Diese Übersichtsseiten werden ebenfalls zwischengespeichert und müssen ebenfalls ungültig gemacht werden.
Mit dem folgenden Skript nehme ich diese Seiten in meine "zu entwertende" Liste auf:
#!/usr/bin/env python3
from typing import List
import os
import subprocess
command = ['git', 'diff-tree', '--no-commit-id', '--name-only', '-r', 'HEAD']
output = subprocess.check_output(command, cwd=os.getcwd()).decode('utf-8')
changed_files = output.strip().split('n')
def content_changed(path: str) -> bool:
return path.startswith("content/")
def convert_html_endpoints(path: str) -> str:
path = path.replace("content/", "")
path = path.replace("_index", "index")
path = path.replace(".md", ".html")
if not path.startswith("/"):
path = f"/{path}"
return path
def find_list_pages(path: str) -> List[str]:
existing_path = ""
list_pages = []
for part in path.split("/"):
list_page_path = os.path.join(existing_path, part, "_index.md")
if os.path.exists(list_page_path):
list_pages.append(os.path.join(existing_path, part, "_index.md"))
existing_path = os.path.join(existing_path, part)
return list_pages
def flatten_list(list_of_lists: List[List[str]]) -> List[str]:
return [item for sublist in list_of_lists for item in sublist]
changed_files += list(flatten_list(map(find_list_pages, changed_files)))
changed_files = list(dict.fromkeys(changed_files))
changed_files = filter(content_changed, changed_files)
changed_files = list(sorted(map(convert_html_endpoints, changed_files)))
list(map(print, changed_files))
Lassen Sie uns untersuchen, was uns das bringen würde:
$ ./retrieve_files.py
/blog/2023/07/invalidate-cloudfront-cache-for-hugo-websites/index.html
/blog/index.html
/index.html
Der Blogbeitrag selbst wird aufgelistet, aber auch die Startseite und der Blog-Bereich meiner Website. Da diese Seiten meine Seite auflisten, nehme ich sie in die zu entwertenden Seiten auf.
Zusammenstellen
In meiner Build-Phase werde ich dieses Skript aufrufen, da ich dort Zugriff auf die Commit-Historie haben werde. Mit einem einfachen Befehl können Sie diese Dateien in einer changelog.txt Datei erfassen:
./retrieve_files.py > public/changelog.txt
Da meine Pipeline in einem separaten AWS-Konto läuft, konnte ich keine Lambda-Funktion verwenden. Stattdessen lade ich die Changelog-Datei in den S3-Bucket hoch. Und ich verwende eine S3 Event Notifications, um den create_invalidation-Aufruf auszulösen.
Fazit
Sie können Ihre bestehenden Systeme verwenden, um zu verfolgen, was sich geändert hat. Sie müssen es nur auf die richtige Weise offenlegen, damit es in nachgelagerten Aktionen verwendet werden kann.
Auf diese Weise nutzen Sie ein entkoppeltes, ereignisgesteuertes Muster.
Foto von Magda Ehlers
Verfasst von

Joris Conijn
Joris is the AWS Practise CTO of the Xebia Cloud service line and has been working with the AWS cloud since 2009 and focussing on building event-driven architectures. While working with the cloud from (almost) the start, he has seen most of the services being launched. Joris strongly believes in automation and infrastructure as code and is open to learning new things and experimenting with them because that is the way to learn and grow.
Unsere Ideen
Weitere Blogs
Contact



