Open3

Cloudflare Containersの調査

TSTS

ざっくり

名の通り、コンテナをワーカーと同じようにグローバルエッジネットワーク上にデプロイできる。

Deploy your container image to Region:Earth without worrying about managing infrastructure - just define your Worker and wrangler deploy.

構成にはDurable Objectを含める必要がある。
Container料金以外にDurable Objectの料金もかかると考えるとコストどうなのかって思うけど
Durable Objectも無料で10万件/日までさばけるから小さいうちは問題にならないか。

{
  "name": "container-starter",
  "main": "src/index.js",
  "containers": [
    {
      "class_name": "MyContainer",
      "image": "./Dockerfile",
      "instances": 5,
    }
  ],
  "durable_objects": {
    "bindings": [
      {
        "class_name": "MyContainer",
        "name": "MY_CONTAINER"
      }
    ]
  },
  "migrations": [
    {
      "new_sqlite_classes": [
        "MyContainer"
      ],
      "tag": "v1"
    }
  ],
}
import { Container, getContainer } from "@cloudflare/containers";

export class MyContainer extends Container {
  defaultPort = 4000; // Port the container is listening on
  sleepAfter = "10m"; // Stop the instance if requests not sent for 10 minutes
}

async fetch(request, env) {
  const { "session-id": sessionId } = await request.json();
  // Get the container instance for the given session ID
  const containerInstance = getContainer(env.MY_CONTAINER, sessionId)
  // Pass the request to the container instance on its default port
  return containerInstance.fetch(request);
}
TSTS

チュートリアル

チュートリアルのテンプレート
https://github.com/cloudflare/templates/tree/main/containers-template

コンテナ構成

wrangler.jsonc(またはtoml)でコンテナ関連の情報を定義

{
  "containers": [
    {
      "class_name": "MyContainer",
      "image": "./Dockerfile",
      "max_instances": 5,
    }
  ]
}

Durable Objectも必要

設定ファイル内のclassと付くものは一致させる必要がある

{
  "durable_objects": {
      "bindings": [
        {
          "class_name": "MyContainer",
          "name": "MY_CONTAINER"
        }
      ]
    }
    "migrations": [
      {
        "new_sqlite_classes": [
          "MyContainer"
        ],
        "tag": "v1"
      }
    ]
}

Dockerfile

コンテナのイメージはDockerfileに記述

# syntax=docker/dockerfile:1

FROM golang:1.24-alpine AS build

# Set destination for COPY
WORKDIR /app

# Download any Go modules
COPY container_src/go.mod ./
RUN go mod download

# Copy container source code
COPY container_src/*.go ./

# Build
RUN CGO_ENABLED=0 GOOS=linux go build -o /server

FROM scratch
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /server /server
EXPOSE 8080

# Run
CMD ["/server"]

テンプレに従って
workers:src
コンテナ:container_src
にするのがディレクトリとしてはシンプルなモノレポって感じの構成で良さそう