{"id":319,"date":"2026-03-26T00:00:00","date_gmt":"2026-03-26T00:00:00","guid":{"rendered":"https:\/\/wordpress.securinsight.ca\/index.php\/2026\/03\/26\/containers-easily-connect-containers-and-sandboxes-to-workers-3\/"},"modified":"2026-03-26T00:00:00","modified_gmt":"2026-03-26T00:00:00","slug":"containers-easily-connect-containers-and-sandboxes-to-workers-3","status":"publish","type":"post","link":"https:\/\/wordpress.securinsight.ca\/index.php\/2026\/03\/26\/containers-easily-connect-containers-and-sandboxes-to-workers-3\/","title":{"rendered":"Containers &#8211; Easily connect Containers and Sandboxes to Workers"},"content":{"rendered":"<p><a href=\"https:\/\/developers.cloudflare.com\/containers\/\">Containers<\/a> and <a href=\"https:\/\/developers.cloudflare.com\/sandbox\/\">Sandboxes<\/a> now support connecting directly to Workers over HTTP. This allows you to call Workers<br \/>\nfunctions and <a href=\"https:\/\/developers.cloudflare.com\/workers\/runtime-apis\/bindings\/\">bindings<\/a>, like <a href=\"https:\/\/developers.cloudflare.com\/kv\">KV<\/a> or <a href=\"https:\/\/developers.cloudflare.com\/r2\/\">R2<\/a>, from within the container at specific hostnames.<\/p>\n<h4>Run Worker code<\/h4>\n<p>Define an <code>outbound<\/code> handler to capture any HTTP request or use <code>outboundByHost<\/code> to capture requests to individual hostnames and IPs.<\/p>\n<div>\n<figure>\n<pre data-language=\"js\"><code class=\"language-js\"><div><div><span>export<\/span><span> <\/span><span>class<\/span><span> <\/span><span>MyApp<\/span><span> <\/span><span>extends<\/span><span> <\/span><span>Sandbox<\/span><span> <\/span><span>{}<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>MyApp<\/span><span>.<\/span><span>outbound<\/span><span> <\/span><span>=<\/span><span> <\/span><span>async<\/span><span> <\/span><span>(<\/span><span>request<\/span><span>,<\/span><span> <\/span><span>env<\/span><span>,<\/span><span> <\/span><span>ctx<\/span><span>)<\/span><span> <\/span><span>=&gt;<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span>  <\/span><span>\/\/ you can run arbitrary functions defined in your Worker on any HTTP request<\/span><\/div><\/div><div><div><span>  <\/span><span>return<\/span><span> <\/span><span>await<\/span><span> <\/span><span>someWorkersFunction<\/span><span>(<\/span><span>request<\/span><span>.<\/span><span>body<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>};<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>MyApp<\/span><span>.<\/span><span>outboundByHost<\/span><span> <\/span><span>=<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span>  <\/span><span>\"my.worker\"<\/span><span>:<\/span><span> <\/span><span>async<\/span><span> <\/span><span>(<\/span><span>request<\/span><span>,<\/span><span> <\/span><span>env<\/span><span>,<\/span><span> <\/span><span>ctx<\/span><span>)<\/span><span> <\/span><span>=&gt;<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span>    <\/span><span>return<\/span><span> <\/span><span>await<\/span><span> <\/span><span>anotherFunction<\/span><span>(<\/span><span>request<\/span><span>.<\/span><span>body<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>  <\/span><span>},<\/span><\/div><\/div><div><div><span>};<\/span><\/div><\/div><\/code><\/pre>\n<div>\n<div><\/div>\n<\/div>\n<\/figure>\n<\/div>\n<p>In this example, requests from the container to <code>http:\/\/my.worker<\/code> will run the function defined within <code>outboundByHost<\/code>,<br \/>\nand any other HTTP requests will run the <code>outbound<\/code> handler. These handlers run entirely inside the Workers runtime,<br \/>\noutside of the container sandbox.<\/p>\n<aside>\n<p>TLS support coming soon<\/p>\n<div>\n<p>Containers and Sandboxes currently only intercept HTTP traffic. HTTPS interception is coming soon. This will enable using Workers as a transparent proxy for credential injection.<\/p>\n<p>Even though this is just using HTTP, traffic to Workers is secure and runs on the same machine as the container.<br \/>\nIf needed, you can also upgrade requests to TLS from the Worker itself.<\/p>\n<\/div>\n<\/aside>\n<h4>Access Workers bindings<\/h4>\n<p>Each handler has access to <code>env<\/code>, so it can call any binding set in <a href=\"https:\/\/developers.cloudflare.com\/workers\/wrangler\/configuration\/#bindings\">Wrangler config<\/a>.<br \/>\nCode inside the container makes a standard HTTP request to that hostname and the outbound Worker translates it into a binding call.<\/p>\n<div>\n<figure>\n<pre data-language=\"js\"><code class=\"language-js\"><div><div><span>export<\/span><span> <\/span><span>class<\/span><span> <\/span><span>MyApp<\/span><span> <\/span><span>extends<\/span><span> <\/span><span>Sandbox<\/span><span> <\/span><span>{}<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>MyApp<\/span><span>.<\/span><span>outboundByHost<\/span><span> <\/span><span>=<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span>  <\/span><span>\"my.kv\"<\/span><span>:<\/span><span> <\/span><span>async<\/span><span> <\/span><span>(<\/span><span>request<\/span><span>,<\/span><span> <\/span><span>env<\/span><span>,<\/span><span> <\/span><span>ctx<\/span><span>)<\/span><span> <\/span><span>=&gt;<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span>    <\/span><span>const<\/span><span> <\/span><span>key<\/span><span> <\/span><span>=<\/span><span> <\/span><span>new<\/span><span> <\/span><span>URL<\/span><span>(<\/span><span>request<\/span><span>.<\/span><span>url<\/span><span>)<\/span><span>.<\/span><span>pathname<\/span><span>.<\/span><span>slice<\/span><span>(<\/span><span>1<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>    <\/span><span>const<\/span><span> <\/span><span>value<\/span><span> <\/span><span>=<\/span><span> <\/span><span>await<\/span><span> <\/span><span>env<\/span><span>.<\/span><span>KV<\/span><span>.<\/span><span>get<\/span><span>(<\/span><span>key<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>    <\/span><span>return<\/span><span> <\/span><span>new<\/span><span> <\/span><span>Response<\/span><span>(<\/span><span>value<\/span><span> <\/span><span>??<\/span><span> <\/span><span>\"\"<\/span><span>,<\/span><span> <\/span><span>{<\/span><span> status<\/span><span>:<\/span><span> <\/span><span>value<\/span><span> <\/span><span>?<\/span><span> <\/span><span>200<\/span><span> <\/span><span>:<\/span><span> <\/span><span>404<\/span><span> <\/span><span>}<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>  <\/span><span>},<\/span><\/div><\/div><div><div><span>  <\/span><span>\"my.r2\"<\/span><span>:<\/span><span> <\/span><span>async<\/span><span> <\/span><span>(<\/span><span>request<\/span><span>,<\/span><span> <\/span><span>env<\/span><span>,<\/span><span> <\/span><span>ctx<\/span><span>)<\/span><span> <\/span><span>=&gt;<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span>    <\/span><span>const<\/span><span> <\/span><span>key<\/span><span> <\/span><span>=<\/span><span> <\/span><span>new<\/span><span> <\/span><span>URL<\/span><span>(<\/span><span>request<\/span><span>.<\/span><span>url<\/span><span>)<\/span><span>.<\/span><span>pathname<\/span><span>.<\/span><span>slice<\/span><span>(<\/span><span>1<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>    <\/span><span>const<\/span><span> <\/span><span>object<\/span><span> <\/span><span>=<\/span><span> <\/span><span>await<\/span><span> <\/span><span>env<\/span><span>.<\/span><span>BUCKET<\/span><span>.<\/span><span>get<\/span><span>(<\/span><span>key<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>    <\/span><span>return<\/span><span> <\/span><span>new<\/span><span> <\/span><span>Response<\/span><span>(<\/span><span>object<\/span><span>?.<\/span><span>body<\/span><span> <\/span><span>??<\/span><span> <\/span><span>\"\"<\/span><span>,<\/span><span> <\/span><span>{<\/span><span> status<\/span><span>:<\/span><span> <\/span><span>object<\/span><span> <\/span><span>?<\/span><span> <\/span><span>200<\/span><span> <\/span><span>:<\/span><span> <\/span><span>404<\/span><span> <\/span><span>}<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>  <\/span><span>},<\/span><\/div><\/div><div><div><span>};<\/span><\/div><\/div><\/code><\/pre>\n<div>\n<div><\/div>\n<\/div>\n<\/figure>\n<\/div>\n<p>Now, from inside the container sandbox, <code>curl http:\/\/my.kv\/some-key<\/code> will access <a href=\"https:\/\/developers.cloudflare.com\/kv\">Workers KV<\/a> and <code>curl http:\/\/my.r2\/some-object<\/code> will access <a href=\"https:\/\/developers.cloudflare.com\/r2\/\">R2<\/a>.<\/p>\n<h4>Access Durable Object state<\/h4>\n<p>Use <code>ctx.containerId<\/code> to reference the container&#8217;s automatically provisioned <a href=\"https:\/\/developers.cloudflare.com\/durable-objects\">Durable Object<\/a>.<\/p>\n<div>\n<figure>\n<pre data-language=\"js\"><code class=\"language-js\"><div><div><span>export<\/span><span> <\/span><span>class<\/span><span> <\/span><span>MyContainer<\/span><span> <\/span><span>extends<\/span><span> <\/span><span>Container<\/span><span> <\/span><span>{}<\/span><\/div><\/div><div><div>\n<\/div><\/div><div><div><span>MyContainer<\/span><span>.<\/span><span>outboundByHost<\/span><span> <\/span><span>=<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span>  <\/span><span>\"get-state.do\"<\/span><span>:<\/span><span> <\/span><span>async<\/span><span> <\/span><span>(<\/span><span>request<\/span><span>,<\/span><span> <\/span><span>env<\/span><span>,<\/span><span> <\/span><span>ctx<\/span><span>)<\/span><span> <\/span><span>=&gt;<\/span><span> <\/span><span>{<\/span><\/div><\/div><div><div><span>    <\/span><span>const<\/span><span> <\/span><span>id<\/span><span> <\/span><span>=<\/span><span> <\/span><span>env<\/span><span>.<\/span><span>MY_CONTAINER<\/span><span>.<\/span><span>idFromString<\/span><span>(<\/span><span>ctx<\/span><span>.<\/span><span>containerId<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>    <\/span><span>const<\/span><span> <\/span><span>stub<\/span><span> <\/span><span>=<\/span><span> <\/span><span>env<\/span><span>.<\/span><span>MY_CONTAINER<\/span><span>.<\/span><span>get<\/span><span>(<\/span><span>id<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>    <\/span><span>return<\/span><span> <\/span><span>stub<\/span><span>.<\/span><span>getStateForKey<\/span><span>(<\/span><span>request<\/span><span>.<\/span><span>body<\/span><span>)<\/span><span>;<\/span><\/div><\/div><div><div><span>  <\/span><span>},<\/span><\/div><\/div><div><div><span>};<\/span><\/div><\/div><\/code><\/pre>\n<div>\n<div><\/div>\n<\/div>\n<\/figure>\n<\/div>\n<p>This provides an easy way to associate state with any container instance, and includes a <a href=\"https:\/\/developers.cloudflare.com\/durable-objects\/get-started\/#2-write-a-durable-object-class-using-sql-api\">built-in SQLite database<\/a>.<\/p>\n<h4>Get Started Today<\/h4>\n<p>Upgrade to <code>@cloudflare\/containers<\/code> version 0.2.0 or later, or <code>@cloudflare\/sandbox<\/code> version 0.8.0 or later to use outbound Workers.<\/p>\n<p>Refer to <a href=\"https:\/\/developers.cloudflare.com\/containers\/platform-details\/outbound-traffic\/\">Containers outbound traffic<\/a> and <a href=\"https:\/\/developers.cloudflare.com\/sandbox\/guides\/outbound-traffic\/\">Sandboxes outbound traffic<\/a> for more details and examples.<\/p>","protected":false},"excerpt":{"rendered":"<p>Containers and Sandboxes now support connecting directly to Workers over HTTP. This allows you to call Workers functions and bindings, like KV or R2, from within the container at specific hostnames. Run Worker code Define an outbound handler to capture any HTTP request or use outboundByHost to capture requests to individual hostnames and IPs. export [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-319","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/posts\/319","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/comments?post=319"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/posts\/319\/revisions"}],"wp:attachment":[{"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/media?parent=319"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/categories?post=319"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.securinsight.ca\/index.php\/wp-json\/wp\/v2\/tags?post=319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}