Недействительный кэш CloudFront для веб-сайтов Hugo
Hugo - это отличный инструмент, который позволяет вам быстро и легко создавать веб-сайты. Он создаст полную статическую HTML-версию вашего сайта. Это делает его идеальным кандидатом для размещения в корзине S3. Затем вы можете использовать CloudFront для доставки контента по всему миру.
CloudFront кэш
Кэш может быть прекрасной вещью! Но это также может быть раздражающей вещью. Поэтому я решил немного углубиться в эту тему для своего личного веб-сайта. Таким образом, по умолчанию, когда вы используете S3 в качестве источника, по умолчанию TTL (время жизни) установлено на 24 часа. Это означает, что когда вы посещаете свой сайт, эта версия кэшируется на 24 часа в пограничном расположении.
Это означает, что если вы обновите свой веб-сайт, изменения не будут видны вам. Это связано с тем, что вы, скорее всего, окажетесь на одном и том же пограничном сервере. Вы можете аннулировать кэш, но такие объекты, как фотографии и видео, выигрывают от этого кэша.
Отменить только то, что изменилось
Итак, это подводит нас к следующему логическому шагу. Отменить только то, что было изменено. Я использую CodeCommit в качестве исходного репозитория, вы можете запросить у git, какие файлы были изменены:
git diff-tree --no-commit-id --name-only -r HEAD
Это даст вам список файлов, измененных в вашей последней фиксации, с этой информацией вы можете делать умные вещи:
- Выберите только те файлы, которые были изменены в папке
content
. - Замените части, содержащие любой
_index
наindex
. - Замените части, содержащие любой
.md
, на.html
. - Определите, где у нас есть агрегация сообщений.
Итак, для этого сообщения в блоге это приведет к:
$ git diff-tree --no-commit-id --name-only -r HEAD
content/blog/2023/07/invalidate-cloudfront-cache-for-hugo-websites/index.md
Поэтому Hugo использует файлы _index.md
для создания страниц со списком всех дочерних страниц. Эти обзорные страницы также кэшируются и также должны быть признаны недействительными.
С помощью следующего скрипта я включу эти страницы в свой список «для признания недействительными»:
#!/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))
Давайте посмотрим, что это нам принесет:
$ ./retrieve_files.py
/blog/2023/07/invalidate-cloudfront-cache-for-hugo-websites/index.html
/blog/index.html
/index.html
В списке указан сам пост в блоге, а также первая страница и раздел блога на моем веб-сайте. Поскольку на этих страницах указана моя страница, я включаю их в список страниц, чтобы сделать их недействительными.
Собираем это вместе
На этапе сборки я буду вызывать этот скрипт, так как там у меня будет доступ к истории коммитов. Простая команда сохранит эти файлы в файле changelog.txt
:
./retrieve_files.py > public/changelog.txt
Поскольку мой конвейер работает в отдельной учетной записи AWS, я не мог использовать функцию Lambda.
Вместо этого я загружаю файл журнала изменений в корзину S3. И я использую уведомления о событиях S3 для запуска вызова create_invalidation.
Заключение
Вы можете использовать существующие системы для отслеживания изменений. Вам нужно только правильно выставить их, чтобы их можно было использовать в последующих действиях.
Таким образом, вы используете шаблон, основанный на разделенных событиях.
Фото от Magda Ehlers