Skip to content

Task

Source: src/AWS/ECS/Task.ts

A Fargate task definition with a container image from one of three sources, declared flat on the props:

  • main — bundle an inline Effect program into a generated image (compose with image or an inline dockerfile to pick the environment; defaults to oven/bun:1).
  • context — build your own Dockerfile (dockerfile is a path relative to the cwd, defaulting to ${context}/Dockerfile).
  • image — run a pre-built registry image, mirrored into ECR.

Task provisions task + execution IAM roles, a CloudWatch log group, and an ECR repository holding the built (or mirrored) image, then registers a Fargate task definition. Each reconcile registers a new immutable revision. A launched task runs until its process exits — it is the target of AWS.ECS.RunTask / StopTask bindings and AWS.ECS.Schedule; effectful impls return { run }, executed to completion when the container starts.

Beyond the primary container you can declare task-level configuration (volumes, runtime platform, ephemeral storage, IPC/PID mode, placement constraints) and append additional sidecars for multi-container tasks.

Remote Image

const migrate = yield* Task("DbMigrate", {
image: "public.ecr.aws/docker/library/busybox:stable",
command: ["sh", "-c", "echo done"],
cpu: 256,
memory: 512,
});

Build Your Own Dockerfile

const render = yield* Task("RenderJob", {
context: "./render", // dockerfile defaults to ./render/Dockerfile
dockerfile: "./render/Dockerfile.gpu", // always a PATH
cpu: 1024,
memory: 4096,
});

Inline Effect Program

const drainer = yield* Task(
"QueueDrainer",
{ main: import.meta.url, image: "oven/bun:1", cpu: 256, memory: 512 },
Effect.gen(function* () {
const receive = yield* AWS.SQS.ReceiveMessage(queue);
return {
run: Effect.gen(function* () {
// runs to completion, then the container exits
const batch = yield* receive({ MaxNumberOfMessages: 10 });
}),
};
}),
);
const task = yield* Task("ApiTask", {
main: import.meta.url,
port: 3000,
sidecars: [
{
name: "otel-collector",
image: "public.ecr.aws/aws-observability/aws-otel-collector:latest",
essential: false,
portMappings: [{ containerPort: 4317, protocol: "tcp" }],
},
],
});

main is bundled with rolldown at deploy time. Top-level calls in the effect, @effect/*, alchemy, @alchemy.run/*, and @distilled.cloud/* packages receive #__PURE__ annotations by default, so anything the task doesn’t use from those packages is tree-shaken out of the bundle. Any other package — including your own app — is left untouched unless you list it explicitly.

Treat additional packages as pure

Pass package names (or picomatch globs) via build.pure.packages to annotate them in addition to the defaults.

{
main: import.meta.url,
build: {
pure: { packages: ["my-lib", "@my-scope/*"] },
},
}

Listing a package annotates calls whose result is bound (variable initializers, exports) — safe anywhere. If a listed package also declares "sideEffects": false (or []) in its package.json, that combination opts it into full annotation: top-level calls whose result is discarded (e.g. router.on("/path", handler) registrations) are also marked pure and deleted under minification when unused. Only list a sideEffects: false package if its modules really are free of meaningful top-level side effects. The effect, alchemy, and @distilled.cloud defaults declare exactly that, on purpose — their modules are designed to be fully tree-shakeable.

Disable pure annotations

{
main: import.meta.url,
build: { pure: false },
}

ARM64 with EFS Volume and Ephemeral Storage

const task = yield* Task("WorkerTask", {
main: import.meta.url,
runtimePlatform: { cpuArchitecture: "ARM64", operatingSystemFamily: "LINUX" },
ephemeralStorage: { sizeInGiB: 40 },
volumes: [
{
name: "data",
efsVolumeConfiguration: { fileSystemId: fileSystem.fileSystemId },
},
],
container: {
mountPoints: [{ sourceVolume: "data", containerPath: "/data" }],
},
});

Environment Files from S3

const task = yield* Task("ApiTask", {
main: import.meta.url,
environmentFiles: [
{ value: "arn:aws:s3:::my-config-bucket/app.env", type: "s3" },
],
});