# Auto-Removing Containers After Workflow Execution with `act --rm`

> Automatically remove Docker containers after workflow execution with act --rm. Free up disk space and prevent clutter from accumulated containers. Learn how today!

- Repository: [nektos/act](https://github.com/nektos/act)
- Tags: how-to-guide
- Published: 2026-03-03

---

**The `act --rm` command-line flag automatically deletes Docker containers and their attached volumes immediately after a GitHub Actions workflow finishes, preventing disk space exhaustion from accumulated stopped containers.**

The open-source CLI tool `act` (nektos/act) executes GitHub Actions workflows locally by spawning Docker containers for each job. Without explicit cleanup, these containers persist on your host as stopped instances, cluttering the Docker daemon and consuming storage. The `--rm` flag triggers a robust cleanup mechanism that removes containers regardless of whether the workflow succeeds or fails.

## How `act --rm` Works Internally

The flag operates through a multi-layered pipeline that spans command-line parsing, configuration propagation, and Docker runtime integration.

### Flag Registration in [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go)

At line 95 of [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go), the Cobra CLI framework registers the `--rm` boolean flag. When parsed, its value is stored in the `input.autoRemove` field:

```go
// Simplified representation of the registration
cmd.PersistentFlags().BoolVarP(&input.autoRemove, "rm", "", false, "automatically remove the container after execution")

```

### Propagation to Runner Configuration

At line 637 in the same file ([`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go)), the `autoRemove` value is copied into the runtime configuration struct as `rc.Config.AutoRemove`. This makes the setting available to the job executor and container runtime throughout the lifecycle of the workflow.

### Docker CLI Integration

In [`pkg/container/docker_cli.go`](https://github.com/nektos/act/blob/main/pkg/container/docker_cli.go) at line 205, the boolean translates directly into Docker’s native `--rm` option. When constructing the `docker run` command, the code injects `copts.autoRemove`, instructing the Docker daemon to delete the container automatically upon exit:

```go
// From pkg/container/docker_cli.go
if c.autoRemove {
    args = append(args, "--rm")
}

```

### Fallback Cleanup in [`job_executor.go`](https://github.com/nektos/act/blob/main/job_executor.go)

Even if Docker’s native `--rm` fails to trigger (for example, when a job errors before the container fully starts), the [`pkg/runner/job_executor.go`](https://github.com/nektos/act/blob/main/pkg/runner/job_executor.go) file implements a manual safety net at lines 107-108. The cleanup logic evaluates the condition `rc.Config.AutoRemove || jobError == nil`, meaning:

- If `--rm` is set, the container is removed regardless of job status.
- If `--rm` is omitted, the container is removed only if the job succeeded (`jobError == nil`).

This ensures containers never leak when the explicit removal flag is active.

## Usage Examples

### Basic Auto-Removal

Run a specific job and automatically clean up the container afterward, even if steps fail:

```bash
act --rm -j build

```

### Combining with Other Flags

Pull fresh images, bind-mount the working directory, and enable auto-removal in a single command:

```bash
act --pull --bind --rm -j test

```

### Debugging Container Lifecycle

Verify that `--rm` actually deletes containers by comparing `docker ps` output:

```bash

# First run without --rm to observe the leftover container

act -j lint
docker ps -a  # Shows a stopped container named "act-<uuid>"

# Now run with --rm

act --rm -j lint
docker ps -a  # The previous container is gone; no new stopped instances appear

```

## Key Source Files

Understanding the implementation requires examining these specific locations in the nektos/act repository:

- **[`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go)** (lines 95, 637): Defines the global `--rm` flag and propagates `input.autoRemove` into `rc.Config.AutoRemove`.
- **[`pkg/container/docker_cli.go`](https://github.com/nektos/act/blob/main/pkg/container/docker_cli.go)** (line 205): Appends the `--rm` option to the Docker run command when `c.autoRemove` is true.
- **[`pkg/runner/runner.go`](https://github.com/nektos/act/blob/main/pkg/runner/runner.go)** (lines 22-23): Contains the `Config` struct definition, including the `AutoRemove` boolean field that controls cleanup behavior.
- **[`pkg/runner/job_executor.go`](https://github.com/nektos/act/blob/main/pkg/runner/job_executor.go)** (lines 107-108): Houses the fallback cleanup logic that removes containers when `AutoRemove` is enabled or when jobs exit without error.

## Summary

- **`act --rm`** registers a boolean flag in [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go) that flows into `rc.Config.AutoRemove`.
- The flag injects Docker’s native `--rm` option via [`pkg/container/docker_cli.go`](https://github.com/nektos/act/blob/main/pkg/container/docker_cli.go), ensuring automatic deletion on container exit.
- A fallback mechanism in [`pkg/runner/job_executor.go`](https://github.com/nektos/act/blob/main/pkg/runner/job_executor.go) guarantees container removal even when Docker’s auto-remove cannot execute, such as during early job failures.
- When `--rm` is omitted, containers persist after runs unless the job succeeds, while the `--reuse` flag intentionally retains containers for caching purposes.

## Frequently Asked Questions

### Does `act --rm` remove containers even when workflow jobs fail?

Yes. According to the source code in [`pkg/runner/job_executor.go`](https://github.com/nektos/act/blob/main/pkg/runner/job_executor.go), the cleanup condition `rc.Config.AutoRemove || jobError == nil` evaluates to true whenever the `--rm` flag is set, ensuring removal regardless of whether `jobError` is nil or contains an error from a failed step.

### How does `--rm` differ from the `--reuse` flag?

The `--reuse` flag is designed to keep containers alive between runs to cache the GitHub Actions environment and dependencies, speeding up subsequent executions. In contrast, `--rm` explicitly destroys the container immediately after the job finishes, reclaiming disk space but requiring fresh container creation on the next run.

### Will `--rm` delete Docker volumes created during the workflow?

Yes. When Docker’s native `--rm` flag is passed (via [`pkg/container/docker_cli.go`](https://github.com/nektos/act/blob/main/pkg/container/docker_cli.go)), the Docker daemon automatically removes any anonymous volumes attached to the container. However, named volumes declared in your workflow may persist depending on your Docker daemon configuration.

### Where can I find the configuration struct that stores the `--rm` setting?

The `AutoRemove` field is defined in [`pkg/runner/runner.go`](https://github.com/nektos/act/blob/main/pkg/runner/runner.go) at lines 22-23 within the `Config` struct. This field is populated from the command-line input in [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go) and is referenced by both the Docker container logic and the job executor to determine cleanup behavior.