Генераторы статических сайтов становятся де-факто способом создания и развертывания веб-приложений, не требующих рендеринга на стороне сервера. Это приложения со страницами, которым не требуется фактический веб-сервер для динамической обработки контента. Типы страниц, которым действительно нужен сервер, часто защищены стеной аутентификации. Могут быть и другие сайты, где динамический контент создается на сервере для SEO.
Hugo, Gatsby и NextJS - одни из самых популярных решений в этой сфере. Все они создают выходные данные, состоящие из набора файлов (HTML, CSS, JavaScript, изображения) в папке, и затем мы можем предоставлять их пользователям с помощью обычного сервера (NGINX, Apache и т. Д.) Или, предпочтительно, через CDN (Content Delivery Network), поскольку для этого нам не понадобится бизнес-логика сервера. Только файловое хранилище, которое CDN будет использовать в качестве источника.
Наряду с этими артефактами для некоторых статических SPA, особенно приложений, разработанных с помощью react-router
, может потребоваться дополнительная настройка. Этого можно добиться, перенаправив все пути в один файл. Этого можно добиться с помощью балансировщика нагрузки или даже с помощью самих Cloudflare Workers.
Во всех этих случаях нам все еще нужно где-то хранить наши файлы. AWS с использованием корзины S3 и распространения Cloudfront исторически был отличным вариантом. Цель этого поста - продемонстрировать другое решение. Развертывайте напрямую в Cloudflare Workers, используя их последнее хранилище данных Workers KV.
Я должен отметить, что первоначальная цель Cloudflare Worker - довести вычислительные возможности до периферии. Бессерверная платформа. Развертывание статических сайтов - еще один вариант использования, поддерживаемый благодаря наличию магазина Workers KV.
Что такое рабочий
Cloudflare Worker - это фрагмент кода JavaScript, который запускается каждый раз, когда вы получаете доступ к определенному маршруту на веб-сайте, проксируемом Cloudflare. Код выполняется по каждому запросу до попадания в кеш Cloudflare. Это означает, что ответы Worker не кэшируются (хотя запросы, сделанные Worker к другим веб-службам, могут кэшироваться с соответствующими заголовками кеширования).
Рабочие выполняются в безопасном контексте, поэтому мы можем безопасно включать в него секреты. Работники не имеют доступа к контексту другого Работника.
Ниже приводится базовый рабочий:
Настроить домен / маршрут / воркер
Давайте развернем этого первого рабочего. Во-первых, вам нужен настроенный домен на Cloudflare. У меня уже есть outsrc.dev
на моей панели.
В разделе DNS добавьте тип реестра A для поддомена www
, указывающего на 192.2.0.1
. Этот IP-адрес был предложен, поскольку никто не сможет разрешить его. Наш работник в любом случае перехватит все запросы.
Затем мы можем создать воркера на вкладке worker.
На панели Рабочие создайте нового рабочего, измените имя (я использовал hello-worker
) и нажмите Сохранить и развернуть. Все рабочие могут быть автоматически развернуты в демонстрационном рабочем пространстве, в моем случае это https://hello-worker.outsrc.workers.dev/
После развертывания мы можем настроить маршрутизацию для запуска этого воркера в нашем основном домене outsrc.dev
, возможно, даже на одном пути маршрута. Для этого нам нужно перейти на главную панель управления учетной записью и выбрать вкладку Рабочие.
Добавьте Route с помощью www.outsrc.dev/hello
и выберите недавно развернутый hello-worker
Worker.
Теперь мы можем получить прямой доступ к этому URL: https://www.outsrc.dev/hello
$ http https://www.outsrc.dev/hello HTTP/1.1 200 OK CF-RAY: 55d4285c0f45d4ed-MIA Connection: keep-alive Content-Length: 11 Content-Type: text/plain;charset=UTF-8 Date: Thu, 30 Jan 2020 14:32:51 GMT Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" Server: cloudflare Set-Cookie: __cfduid=dbd7b5387c4e90a370fdc89ed5e908f701580394771; expires=Sat, 29-Feb-20 14:32:51 GMT; path=/; domain=.outsrc.dev; HttpOnly; SameSite=Lax Vary: Accept-Encoding hello world
Инструменты
Создание / изменение кода Worker вручную может оказаться сложным, особенно если учесть, что нам может потребоваться автоматизировать все шаги по развертыванию веб-приложения.
Откройте Wrangler, инструмент командной строки Cloudflare Worker. Https://developers.cloudflare.com/workers/tooling/wrangler/
$ npm i @cloudflare/wrangler -g
После установки нам нужно настроить аутентификацию перед загрузкой / развертыванием того же базового Hello Worker с парой команд. Перейдите по адресу https://dash.cloudflare.com/profile/api-tokens, чтобы создать токен API для инструмента Wrangler. (Используйте шаблон Cloudflare Worker для разрешений)
$ wrangler config wrangler config 💁 To find your API token, go to https://dash.cloudflare.com/profile/api-tokens and create it using the "Edit Cloudflare Workers" template 💁 If you are trying to use your Global API Key instead of an API Token (Not Recommended), run "wrangler config --api-key". Enter API token:
После настройки мы можем создать нового рабочего с помощью инструмента командной строки wrangler.
$ wrangler generate hello-worker https://github.com/cloudflare/worker-template
Этот шаблон воркера представляет собой простой JavaScript Hello Worker. Наряду с содержимым шаблона у нас также будет файл wrangler.toml
с настройками, которые нам нужно обновить, например:
- account_id: идентификатор вашей учетной записи, вы можете найти его на главной панели управления.
- zone_id: каждая зона DNS в Cloudflare имеет собственный идентификатор, который также отображается на панели управления.
- route: откуда можно будет получить доступ к Worker (например, www.outsrc.dev/hello)
- worker_dev: верно | false. Он развернет ваш Worker в промежуточной среде. Обычно в форме:
https://<worker_name>.<account_name>.worker.dev
Как только настройки будут на месте:
$ wrangler publish 💁 JavaScript project found. Skipping unnecessary build! ✨ Successfully published your script to www.outsrc.dev/hello
Рабочие КВ Магазин
Workers KV - это глобальное хранилище данных типа "ключ-значение" с малой задержкой. Он поддерживает исключительно большие объемы чтения с малой задержкой, что позволяет создавать высокодинамичные API-интерфейсы и веб-сайты, которые реагируют так же быстро, как и кэшированный статический файл.
С помощью этой функции мы можем:
- Храните наши статические ресурсы HTML, CSS, изображения и файлы JavaScript на краю
- Измените код нашего Worker'а, чтобы он возвращал правильный файл в соответствии с путем. (Это уже поддерживается в API JavaScript для Workers KV)
- Используйте
wrangler
, чтобы автоматизировать весь процесс.
Давай сделаем это.
Создание статического веб-сайта
Подойдет любой генератор статических сайтов. Нам нужно только иметь возможность иметь статическую папку вывода сборки, и мы развернем ее в Worker KV и в Worker script, который будет извлекать из хранилища и обслуживать его.
В качестве отправной точки будет использоваться репо https://github.com/outsrc/template-frontend. Это репо основано на NextJS и уже включает команду для статического экспорта веб-приложения (создается папка out
)
$ git clone [email protected]:outsrc/template-frontend.git static-app $ cd static-app $ yarn install $ yarn export
Давайте добавим wrangler
в качестве зависимости для разработки и настроим развертывание через wrangler.toml
$ yarn add --dev @cloudflare/wrangler $ wrangler init --site hello-worker ⬇️ Installing cargo-generate... 🔧 Creating project called `workers-site`... ✨ Done! New project created /Users/ernestofreyre/Documents/nodeprojects/static-app/workers-site ✨ Succesfully scaffolded workers site ✨ Succesfully created a `wrangler.toml`
Это добавит:
worker-site
папка: содержит все необходимые зависимости иindex.js
файл, который содержит наше статическое приложение Worker для внешнего интерфейса.wrangler.toml
файл: Настройки для развертывания Worker
Нам не нужно изменять папку worker-site
(на данный момент), но wrangler.toml
нуждается в некоторых обновлениях (выделено жирным шрифтом).
name = "hello-worker" type = "webpack" account_id = "<YOUR ACCOUNT ID>" workers_dev = true [site] bucket = "./out" entry-point = "workers-site"
После обновления мы можем развернуть в промежуточной среде:
$ wrangler publish 🌀 Created namespace for Workers Site "__hello-worker-workers_sites_assets" 💁 Uploading... ✨ Success added 2 packages from 2 contributors and audited 2 packages in 0.395s found 0 vulnerabilities ⬇️ Installing wranglerjs... ⬇️ Installing wasm-pack... ✨ Built successfully, built project size is 11 KiB. ✨ Successfully published your script to https://hello-worker.outsrc.workers.dev
Вот и все. Получите доступ к URL-адресу, отображаемому внизу, и вы увидите, что наше статическое приложение работает отлично (и очень быстро, я должен сказать)
Развернуть в производство
Это в нашем собственном домене. Нам нужно изменить wrangler.toml
файл, чтобы включить в него раздел среды.
name = "hello-worker" type = "webpack" account_id = "<YOUR ACCOUNT ID>" workers_dev = true [site] bucket = "./out" entry-point = "workers-site" [env.production] zone_id = "<YOUR ZONE ID>" route = "www.outsrc.dev/*"
Теперь мы можем:
$ wrangler publish --env production 🌀 Created namespace for Workers Site "__hello-worker-production-workers_sites_assets" 💁 Uploading... ✨ Success ⬇️ Installing wranglerjs... ⬇️ Installing wasm-pack... ✨ Built successfully, built project size is 11 KiB. ✨ Successfully published your script to www.outsrc.dev/*
Дальнейшее развертывание
Представьте, что мы создаем и развертываем все наши коммиты в хранилище Worker KV, используя хэш коммита в качестве префикса пути. (Пример: /8982c33e/index.html) Затем мы можем перенаправить весь запрос в режиме реального времени в любую папку фиксации, которую захотим. Это означает, что развертывание в производственной среде и откат можно выполнить мгновенно, изменив одно значение в хранилище KV. Также Canary Deplows (группа пользователей получит версию приложения)
Сначала создайте новое пространство имен Worker KV с именем CONTROL:
$ wrangler kv:namespace create "CONTROL" 🌀 Creating namespace with title "hello-worker-CONTROL" ✨ Success: WorkersKvNamespace { id: "22e976....", title: "hello-worker-CONTROL", } ✨ Add the following to your wrangler.toml: kv-namespaces = [ { binding = "CONTROL", id = "22e976...." } ]
Нам нужно поместить полужирный раздел поверх wrangler.toml
файла:
name = "hello-worker" type = "webpack" account_id = "<YOUR ACCOUNT ID>" workers_dev = true kv-namespaces = [ { binding = "CONTROL", id = "22e976...." } ] [site] bucket = "./out" entry-point = "workers-site" [env.production] zone_id = "<YOUR ZONE ID>" route = "www.outsrc.dev/*" kv-namespaces = [ { binding = "CONTROL", id = "22e976...." } ]
Поскольку наше приложение NextJS регенерирует папку статического вывода каждый раз, когда мы делаем yarn export
, нам нужно соответственно перемещать файлы. Кроме того, инструмент командной строки wrangler не сохраняет старые файлы от предыдущих развертываний. Нам нужно собрать их все в одну папку. (Было бы неплохо, если бы wrangler разрешил нам хранить старые файлы в хранилище). Создайте папку сборок, куда мы будем копировать все наши статические сборки.
$ mkdir builds
И измените сценарии развертывания, чтобы сначала переименовать папку out
в имя текущего хэша фиксации и переместить ее в папку builds
:
{ "name": "template-frontend", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "clean": "rimraf .next && rimraf out", "dev": "next", "build": "next build", "start": "next start", "export": "yarn clean && yarn build && next export", "test": "echo \"Error: no test specified\" && exit 1", "lint": "standard", "format": "prettier-standard --format", "pre-deploy": "mv out `git rev-parse HEAD | cut -c 1-8` && mv `git rev-parse HEAD | cut -c 1-8` builds", "deploy:production": "yarn export && yarn pre-deploy && wrangler publish --env production" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "next": "~9.2.0", "react": "^16.12.0", "react-dom": "^16.12.0" }, "devDependencies": { "@cloudflare/wrangler": "^1.6.0", "@types/node": "^12.12.7", "@types/react": "^16.9.11", "prettier-standard": "^15.0.1", "rimraf": "^3.0.0", "standard": "^14.3.1", "typescript": "^3.7.2" } }
Последние изменения, которые нам нужны, находятся в файле worker-site/index.js
. Для каждого запроса сначала получайте хэш фиксации, который мы хотим обслуживать, и переназначайте запрос в эту папку, содержащую наши активы. Используя значение из пространства имен CONTROL, которое мы только что установили.
Если мы развернем и попытаемся получить доступ к нашему приложению, мы получим:
$ yarn deploy:production yarn run v1.21.1 $ yarn export && yarn pre-deploy && wrangler publish --env production $ yarn clean && yarn build && next export $ rimraf .next && rimraf out $ next build Creating an optimized production build Compiled successfully. Automatically optimizing pages Page Size First Load ┌ ○ / 595 B 75.5 kB └ ○ /about 583 B 75.5 kB + shared by all 68.8 kB ├ static/_buildManifest.js 188 B ├ static/pages/_app.js 944 B ├ chunks/commons.9ed1b2.js 21.7 kB ├ chunks/framework.94bc9f.js 40.5 kB ├ runtime/main.99b7a8.js 4.69 kB └ runtime/webpack.b65cab.js 746 B λ (Server) server-side renders at runtime (uses getInitialProps or getServerProps) ○ (Static) automatically rendered as static HTML (uses no initial props) ● (SSG) automatically generated as static HTML + JSON (uses getStaticProps) > using build directory: /Users/ernestofreyre/Documents/nodeprojects/static-app/.next copying "static build" directory launching 15 workers Exporting (3/3) Export successful $ mv out `git rev-parse HEAD | cut -c 1-8` && mv `git rev-parse HEAD | cut -c 1-8` builds 🌀 Using namespace for Workers Site "__hello-worker-production-workers_sites_assets" 💁 Uploading... ✨ Success ⬇️ Installing wranglerjs... ⬇️ Installing wasm-pack... ✨ Built successfully, built project size is 11 KiB. ✨ Successfully published your script to www.outsrc.dev/* ✨ Done in 16.53s.
Мы просто пропустили установку значения show_commit
в пространстве имен CONTROL.
$ wrangler kv:key put --binding=CONTROL "show_commit" "0b0b0ef4" ✨ Success
Теперь, каждый раз, когда мы фиксируем и развертываем в производственной среде, приложение будет построено и развернуто в магазине KV. Команда для обновления используемого коммита:
$ wrangler kv:key put --binding=CONTROL "show_commit" "<COMMITHASH>"
Для отката просто требуется та же команда с хешем фиксации, который мы хотим откатить. Мгновенно.
Выводы
- Вашему веб-приложению требуется CDN, Cloudflare CDN - проверенное решение.
- Cloudflare Workers + Cloudflare Workers KV позволяет развертывать веб-приложения, созданные на основе статических сайтов, непосредственно на периферии.
- Также могут поддерживаться более сложные варианты использования: различные базовые пути, улучшенные схемы безопасности.
- Вы можете настроить конвейер CI / CD для непрерывного развертывания в хранилище Worker KV и решить позже, когда переводить пользователей на последние версии или выполнять откат при обнаружении ошибок.
Удачного взлома…