You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In this guide, you will get started with Cloudflare Images and make your first API request.
8
+
In this guide, you will deploy a Worker that can make requests to one or more Containers in response to end-user requests.
9
+
In this example, each container runs a small webserver written in Go.
10
+
11
+
Requests are initially handled by the Worker, then passed to container-enabled [Durable Objects](/durable-objects).
12
+
Each Durable Object runs alongside a container, manages starting and stopping it, and
13
+
can interact with the container through its ports.
14
+
15
+
In a simple app, the Durable Object may just boot the container and proxy requests to it.
16
+
17
+
In a more complex app, having container-enabled Durable Objects allows you to route requests to individual stateful container
18
+
instances, manage the container lifecycle, pass in custom starting commands and environment variables to containers, run hooks
19
+
on container status changes, and more.
20
+
21
+
This example Worker should give you a sense for simple Container use, and provide a starting point for more complex use cases.
9
22
10
23
## Prerequisites
11
24
12
-
Before you make your first API request, ensure that you have a Cloudflare Account ID and an API token.
25
+
### Get an API Token with the correct permissions
26
+
27
+
Ensure you have a Cloudflare Account ID and an API token.
28
+
29
+
Refer to [Find zone and account IDs](/fundamentals/setup/find-account-and-zone-ids/) for help locating
30
+
your Account ID and [Create an API token](/fundamentals/api/get-started/create-token/) to learn how to create
31
+
an access your API token.
32
+
33
+
When making your API token, make sure you supply the "Cloudchamber: Edit" and "Workers: Edit" permissions.
34
+
35
+
{/* NOTE: Change to "Containers: Edit" once this permission exists */}
36
+
37
+
### Ensure Docker is running locally
38
+
39
+
In this guide, we will build and push a container image alongside your Worker code. By default, this process uses
40
+
Docker to do so. You must have Docker running locally when you run `wrangler deploy`.
41
+
42
+
If Docker is running properly, the `docker info` command will successfully run. If Docker is not running,
43
+
the `docker info` command will hang or return an error including the message "Cannot connect to the Docker daemon".
13
44
14
-
Refer to [Find zone and account IDs](/fundamentals/setup/find-account-and-zone-ids/) for help locating your Account ID and [Create an API token](/fundamentals/api/get-started/create-token/) to learn how to create an access your API token.
45
+
{/* FUTURE CHANGE: Add some image you can use if you don't have Docker running. */}
46
+
{/* FUTURE CHANGE: Link to docs on alternative build/push options */}
- Wrangler pushes you image to the Cloudchamber Image Registry, which is automatically
90
+
integrated with your Cloudflare account.
91
+
- Wrangler deploys your Worker, which includes setting up a "Container" for it to interact with.
92
+
93
+
:::note
94
+
The build and push usually take the longest on the first deploy. Future deploys
95
+
will go faster by [reusing cached image layers](https://docs.docker.com/build/cache/).
96
+
:::
97
+
98
+
After you deploy your Worker for the first time, you will need to wait several minutes until
99
+
it is ready to receive requests. Unlike Workers, Containers take a few minutes to be provisioned.
100
+
During this time, requests are sent to the Worker, but calls to the Container will error.
101
+
102
+
{/* FUTURE CHANGE: Add a command to check status from the CLI */}
103
+
104
+
### Make requests to Containers
105
+
106
+
Now, open the URL for your worker. It should look something like `https://container-starter.YOUR_ACCOUNT_NAME.workers.dev`.
107
+
108
+
If you make requests to the paths `/specific/1` or `/specific/2`, these requests are routed to specific containers.
109
+
Each different path after "/specific/" routes to a unique container.
110
+
111
+
If you make requests to `/lb`, you will load balanace requests to one of 3 containers chosen at random.
112
+
113
+
You can confirm this behavior by reading the output of each request.
114
+
115
+
## Understanding the Code
116
+
117
+
### Worker Config
118
+
119
+
First, wrangler config sets up a container and a Durable Object that will run alongside it.
27
120
28
-
You can dynamically optimize images that are stored outside of Cloudflare Images and deliver them using [transformation URLs](/images/transform-images/transform-via-url/).
121
+
```toml
122
+
[[containers]]
123
+
instances = 10
124
+
name = "hello-containers"
125
+
class_name = "MyContainer"
126
+
image = "./Dockerfile"
29
127
30
-
Cloudflare will automatically cache every transformed image on our global network so that you store only the original image at your origin.
128
+
[[durable_objects.bindings]]
129
+
name = "MY_CONTAINER"
130
+
class_name = "MyContainer"
31
131
32
-
To enable transformations on your zone:
132
+
[[migrations]]
133
+
tag = "v1"
134
+
new_sqlite_classes = ["MyContainer"]
135
+
```
136
+
137
+
Important points about this config:
33
138
34
-
1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com/login) and select your account.
35
-
2. Go to **Images** > **Transformations**.
36
-
3. Go to the specific zone where you want to enable transformations.
37
-
4. Select **Enable for zone**. This will allow you to optimize and deliver remote images.
139
+
-`image` points to a Dockerfile or to a directory containing a Dockerfile.
140
+
-`class_name` must be a Durable Object class name.
141
+
-`instances` declares the maximum number of simultaneously running container instances
142
+
that will run.
143
+
- The Durable Object must use `new_sqlite_classes` not `new_classes`.
38
144
145
+
{/* FUTURE CHANGE: Change instances to max_instances */}
39
146
:::note
147
+
`instances`**does not** mean the number of instances that will automatically run, it means the maximum number.
148
+
149
+
We plan to make `instances` optional some time during the Closed Beta period.
150
+
:::
151
+
152
+
### The Container Image
153
+
154
+
The container image itself has to run on the `linux/amd64` architecture, but aside from that has few limitations.
40
155
41
-
With **Resize images from any origin** unchecked, only the initial URL passed will be checked. Any redirect returned will be followed, including if it leaves the zone, and the resulting image will be transformed.
156
+
In this case, it is a simple Golang server that responds to requests on port 8080:
157
+
158
+
{/* TODO: Add reference about env variables that are auto-inserted */}
159
+
160
+
```go
161
+
funchandler(whttp.ResponseWriter, r *http.Request) {
162
+
country:= os.Getenv("CLOUDFLARE_COUNTRY_A2")
163
+
location:= os.Getenv("CLOUDFLARE_LOCATION")
164
+
region:= os.Getenv("CLOUDFLARE_REGION")
165
+
166
+
fmt.Fprintf(w, "Hi, I'm a container running in %s, %s, which is part of %s", location, country, region)
167
+
}
168
+
169
+
funcmain() {
170
+
http.HandleFunc("/", handler)
171
+
log.Fatal(http.ListenAndServe(":8080", nil))
172
+
}
173
+
```
42
174
175
+
For communication between the container and Workers, you will likely want to listen on
176
+
a specific port.
177
+
178
+
:::note
179
+
After deploying the example code, feel free to replace the provided image with one of your own.
When the Durable Object instance is created, it starts a new container
202
+
using the `startAndWaitForPort` method, which calls `this.ctx.container.start`.
203
+
204
+
The `fetch` method calls the `proxyFetch` helper, which passes a request
205
+
to the server running on the open port.
206
+
207
+
In this case, the Workers request will be proxied to the Golang server
208
+
listeining on port 8080.
209
+
210
+
{/* FUTURE CHANGE: Document the API for this.ctx.container in reference! */}
211
+
45
212
:::note
213
+
Currently, the container is stopped when the Durable Object is put to sleep.
214
+
215
+
We plan to add the ability to keep the container alive for a configurable amount of time
216
+
after the most recent request. This will be added soon.
217
+
:::
218
+
219
+
In the Worker's main `fetch` handler, Container-enabled Durable Objects are
220
+
launched in one of two ways:
221
+
222
+
- Making requests to `/specific/` passes requests to a new container for
223
+
each path. This is done by spinning up a new Durable Object and Container. You may note
224
+
that the first request to a new path takes longer than subsequent requests, this is
225
+
because a new container is booting.
226
+
227
+
```js
228
+
if (pathname.startsWith("/specific/")) {
229
+
// In this case, each unique pathname with spawn a new container
230
+
let id =env.MY_CONTAINER.idFromName(pathname);
231
+
let stub =env.MY_CONTAINER.get(id);
232
+
returnawaitstub.fetch(request);
233
+
}
234
+
```
235
+
236
+
- Making requests to `/lb` will load balance requests across several containers.
237
+
This uses a simple `loadBalance` helper method currently, which picks an ID at random
238
+
from a set number (defined with `LB_INSTANCES`), then routes to that Durable Object instance.
239
+
240
+
```js
241
+
if (pathname.startsWith("/lb")) {
242
+
let container =awaitloadBalance(env.MY_CONTAINER, LB_INSTANCES);
243
+
returnawaitcontainer.fetch(request);
244
+
}
245
+
```
246
+
247
+
This allows for multiple ways of using Containers:
248
+
249
+
- If you simply want to send requests to many stateless and interchangeable containers,
250
+
you should load balance.
251
+
- If you have stateful services or need individually addressable
252
+
containers, you should request specific Durable Objects.
253
+
- If you are running short-lived jobs, want fine-grained control over the container
254
+
lifecycle, want to parameterize container entrypoint or env vars, or
255
+
want to chain together multiple container calls, you should request specific
256
+
Durable Objects.
46
257
47
-
If you are using transformations in a Worker, you need to include the appropriate logic in your Worker code to prevent resizing images from any origin. Unchecking this option in the dash does not apply to transformation requests coming from Cloudflare Workers.
258
+
:::note
259
+
Currently, routing requests to one of many interchangeable Container instances is accomplished
260
+
with a function like `loadBalance`, written in the user's code.
48
261
262
+
We will add official first-party mechanisms for scaling and load-balanced routing soon.
49
263
:::
264
+
265
+
## View Containers in your Dashboard
266
+
267
+
The Containers Dashboard shows you helpful information about your Containers, including:
268
+
269
+
- Status and Health
270
+
- Metrics
271
+
- Logs
272
+
273
+
After launching your Worker, navigate to the Containers Dashboard
274
+
by clicking on "Containers" under "Workers & Pages" in your sidebar.
275
+
276
+
{/* TODO: Add note about navigation via the Worker once this is done */}
277
+
278
+
## Next Steps
279
+
280
+
To do more:
281
+
282
+
- Modify the image by changing the Dockerfile and calling `wrangler deploy`
283
+
- Review our [Examples](/containers/examples) for more inspiration
284
+
- Get [more information on the Containers Closed Beta](/containers/reference/closed-beta-info)
0 commit comments