Task lifecycle

When Batect runs a task, there are a number of steps that it follows. We'll use the following configuration as an example throughout this explanation:

image: my-image
image: fake-service
build_directory: .batect/dependency-2
- type: cache
container: /data
name: fake-service-cache
container: build-env
command: ./build.sh
- compile
- dependency-1
- dependency-2
container: build-env
command: ./test.sh

To begin with, Batect determines which tasks to run and what order to run them in, based on the prerequisites of the requested task and any prerequisites of those prerequisites and so on. For the example configuration, let's say we're running the test task. The test task declares compile as a prerequisite, so Batect determines that the compile task will need to run first, then the test task.

Each task will start, run to completion and clean up before the next task starts.

Next, for each task, it determines what containers need to be started for that task, based on the dependency relationships between containers. Each task will start its own instance of each container, even if multiple tasks share the same container.

For our sample configuration above, prerequisite relationship between tasks and dependency relationship between containers can be visualised like this:


Once the container dependency relationships have been determined, Batect then begins executing the task. It creates a Docker network for the task, and runs cache initialisation if required. In parallel to setting up the network and caches, for every container that makes up the task:

  1. It builds or pulls the image required for this container
  2. It waits for the task network to be ready
  3. It waits for cache initialisation to complete, if this container mounts any caches
  4. It waits for any containers that this container depends on to be ready - so each dependency must have reported as healthy and completed all setup commands
  5. It starts the container and the container's command
  6. It waits for the container to report as healthy
  7. It runs any setup commands, one at a time in the order provided

Once all setup commands have completed, any dependent containers can start.

Once the main container exits, Batect then cleans up the containers. This means that, for every container:

  1. It waits for all containers that depend on this one to stop
  2. It stops this container
  3. It removes this container
  4. It cleans up any temporary files or folders created for this container

Once all containers are removed, the task network is removed and then the task is complete.

You can picture this as a series of discrete steps with dependencies between them. For the example configuration, if we're running the test task, these are the steps involved and the dependencies between them:

Task networkCache initialisationbuild-envdependency-1dependency-2StartWait forhealthyRun setupcommandsCreatePullWait forcompletionBuildStartWait forhealthyRun setupcommandsCreateDestroyCreateRunPullStopDestroyStopDestroyStartWait forhealthyRun setupcommandsStopDestroyCreate