INTEGRITY Документация

Начало работы

В этом руководстве вы развернёте Worker, который сможет выполнять запросы к одному или нескольким Container в ответ на запросы конечных пользователей. В этом примере каждый контейнер запускает небольшой веб-сервер, написанный на Go.

Этот пример Worker даёт представление о простом использовании Container и служит отправной точкой для более сложных сценариев.

Предварительные требования

Убедитесь, что Docker запущен локально

В этом руководстве мы соберём и отправим образ контейнера вместе с кодом Worker. По умолчанию этот процесс использует Docker ↗ чтобы сделать это.

Docker должен быть запущен локально при выполнении wrangler deploy. Большинству пользователей проще всего установить Docker, следуя документация по установке Docker Desktop ↗. Другие инструменты, такие как Colima ↗ тоже может подойти.

Проверить, что Docker работает корректно, можно с помощью команды docker info команду в терминале. Если Docker запущен, команда выполнится успешно. Если Docker не запущен, команда docker info зависнет или вернёт ошибку с сообщением "Cannot connect to the Docker daemon".

Разверните свой первый Container

Выполните следующую команду, чтобы создать и развернуть новый Worker с контейнером из стартового шаблона:

npm create cloudflare@latest -- --template=cloudflare/templates/containers-template

Чтобы развернуть изменение кода Worker или Container, выполните следующую команду с помощью Wrangler CLI:

npx wrangler deploy

При развёртывании Wrangler загружает ваш Worker, собирает и отправляет образ контейнера с помощью Docker, а затем обновляет экземпляры контейнеров в сети Cloudflare. Первая сборка и отправка обычно занимают больше всего времени. Последующие развёртывания повторно использовать кэшированные слои образа ↗.

Проверьте статус деплоя

После деплоя выведите список контейнеров вашего аккаунта и их статусы:

npx wrangler containers list

Просмотр списка образов в Cloudflare Registry:

npx wrangler containers images list

Выполнение запросов к Containers

Откройте URL вашего Worker. Он должен выглядеть примерно так: https://hello-containers.<YOUR_WORKERS_SUBDOMAIN>.workers.dev.

Прочитайте тело ответа, чтобы узнать, какой экземпляр обработал запрос. Если Worker отвечает, но маршруты контейнера всё ещё возвращают ошибку, подождите завершения подготовки, а затем проверьте Containers ↗ логи в дашборде.

Разбор кода

Теперь, когда вы развернули свой первый контейнер, разберёмся, что происходит в коде Worker, в конфигурационном файле, в коде контейнера и как маршрутизируются запросы.

Конфигурация

Ваш конфигурационный файл Wrangler определяет конфигурацию как для вашего Worker, так и для контейнера:

{
	"containers": [
		{
			"max_instances": 10,
			"class_name": "MyContainer",
			"image": "./Dockerfile",
		},
	],
	"durable_objects": {
		"bindings": [
			{
				"name": "MY_CONTAINER",
				"class_name": "MyContainer",
			},
		],
	},
	"migrations": [
		{
			"tag": "v1",
			"new_sqlite_classes": ["MyContainer"],
		},
	],
}
[[containers]]
max_instances = 10
class_name = "MyContainer"
image = "./Dockerfile"

[[durable_objects.bindings]]
name = "MY_CONTAINER"
class_name = "MyContainer"

[[migrations]]
tag = "v1"
new_sqlite_classes = [ "MyContainer" ]

Важные моменты об этой конфигурации:

Образ Container

Образ вашего контейнера должен быть способен выполняться на linux/amd64 архитектуру, но в остальном имеет мало ограничений.

В только что развёрнутом примере используется простой сервер на Golang, который отвечает на запросы на порту 8080 с помощью MESSAGE переменную окружения, которая будет задана в Worker, и автоматически создаваемая переменная окружения CLOUDFLARE_DEPLOYMENT_ID.

func handler(w http.ResponseWriter, r *http.Request) {
	message := os.Getenv("MESSAGE")
	instanceId := os.Getenv("CLOUDFLARE_DEPLOYMENT_ID")

	fmt.Fprintf(w, "Hi, I'm a container and this is my message: %s, and my instance ID is: %s", message, instanceId)
}

код Worker

Конфигурация Container

Первое замечание MyContainer который расширяет Container ↗ класс:

export class MyContainer extends Container {
  defaultPort = 8080;
  sleepAfter = '10s';
  envVars = {
    MESSAGE: 'I was passed in via the container class!',
  };

  override onStart() {
    console.log('Container successfully started');
  }

  override onStop() {
    console.log('Container successfully shut down');
  }

  override onError(error: unknown) {
    console.log('Container error:', error);
  }
}

Здесь задаётся базовая конфигурация контейнера:

Container класс сам расширяет DurableObject, поэтому ваш подкласс имеет доступ ко всему API Durable Object. Durable Object отвечает за маршрутизацию, жизненный цикл и постоянное хранение состояния, а процесс контейнера запускает ваш образ внутри Linux VM. Это значит, что вы можете использовать this.ctx.storage для постоянного хранения данных, которые сохраняются при перезапуске контейнера и находятся в непосредственной близости от самого контейнера.

См. Справочник по классу Container и низкоуровневый API Container для Durable Object для дополнительных сведений.

Маршрутизация к Containers

Когда запрос поступает в Cloudflare, вашего Worker fetch обработчик вызывается. Это код, который обрабатывает входящий запрос. Обработчик fetch в примере кода запускает контейнеры двумя способами на разных маршрутах:

Это позволяет использовать Containers несколькими способами:

Просмотр Containers в своём Dashboard

Дашборд Containers ↗ показывает полезную информацию о ваших контейнерах, включая:

После запуска Worker перейдите в дашборд Containers, выбрав Workers & Pages > Containers на боковой панели дашборда.

Дальнейшие шаги

Что ещё можно сделать: