# How to Force Docker Image Pulls Using `act --pull`

> Force Docker image pulls with act --pull to ensure your nektosact workflows use the latest image layers. Avoid outdated dependencies for reliable CI automation.

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

---

**Use the `act --pull` flag to force nektos/act to always fetch Docker images from the registry, even when cached versions already exist locally, ensuring your workflows run with the most recent image layers.**

The `nektos/act` CLI tool emulates GitHub Actions workflows locally using Docker containers. When executing workflow steps that reference container images, `act` must decide whether to reuse local copies or pull fresh updates from the registry. The **`act --pull`** flag controls this behavior explicitly, allowing you to override local caches and guarantee your local CI runs match the latest upstream environments.

## Understanding the `--pull` Flag Behavior

By default, `act` sets `--pull` to `true`, meaning it attempts to pull images even if they exist locally. This ensures you do not inadvertently run stale action environments. When you explicitly use **`act --pull`** (or the shorthand **`-p`**), you affirm this behavior. Conversely, setting **`act --pull=false`** instructs `act` to skip network requests and use whatever images are currently available on your Docker host.

This flag becomes critical when:
- You suspect a locally cached image tag (like `ubuntu-latest`) has drifted from the registry version
- You need to verify that workflows function with the absolute latest container builds
- You want to avoid the subtle bugs that outdated base images can introduce

## Internal Implementation: How the Flag Propagates

The `--pull` flag travels through multiple layers of the `act` architecture, from CLI parsing to Docker daemon execution. Understanding this path helps diagnose pull-related issues.

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

The flag registers in **[`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go)** using Cobra, binding directly to the `input.forcePull` boolean:

```go
rootCmd.Flags().BoolVarP(&input.forcePull, "pull", "p", true,
    "pull docker image(s) even if already present")

```

This establishes the default value of `true` and allows users to override it via `--pull=false`.

### Configuration Construction

Before execution, [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go) combines the flag value with the `--action-offline-mode` setting to produce the final `ForcePull` parameter:

```go
ForcePull: !input.actionOfflineMode && input.forcePull,

```

This logic ensures that enabling offline mode automatically disables forced pulling, regardless of the `--pull` flag value.

### Runner Configuration Structure

The `Config` struct defined in **[`pkg/runner/runner.go`](https://github.com/nektos/act/blob/main/pkg/runner/runner.go)** carries the boolean through the application:

```go
type Config struct {
    // ... other fields ...
    ForcePull bool // force pulling of the image, even if already present
}

```

### Runtime Execution in `RunContext`

When a job initializes, the `RunContext` in **[`pkg/runner/run_context.go`](https://github.com/nektos/act/blob/main/pkg/runner/run_context.go)** invokes the pull logic for both service containers and the primary job container:

```go
rc.pullServicesImages(rc.Config.ForcePull)
rc.JobContainer.Pull(rc.Config.ForcePull)

```

Additionally, each Docker-based step respects the flag through calls in **[`pkg/runner/step_docker.go`](https://github.com/nektos/act/blob/main/pkg/runner/step_docker.go)**:

```go
stepContainer.Pull(rc.Config.ForcePull)

```

### Docker Pull Implementation

The actual conditional logic resides in **[`pkg/container/docker_pull.go`](https://github.com/nektos/act/blob/main/pkg/container/docker_pull.go)**. The code checks the `ForcePull` attribute to determine whether to execute a registry fetch or inspect local image caches:

```go
pull := input.ForcePull
if !pull {
    // try to use existing image; if not found, set pull = true
}
if !pull {
    // skip pull entirely
}
// otherwise, execute docker pull

```

Finally, **[`pkg/container/docker_run.go`](https://github.com/nektos/act/blob/main/pkg/container/docker_run.go)** propagates the flag to the low-level executor:

```go
NewInfoExecutor("%sdocker pull image=%s platform=%s username=%s forcePull=%t",
    logPrefix, cr.input.Image, cr.input.Platform, cr.input.Username, forcePull)

```

## Interaction with `--action-offline-mode`

The **`--action-offline-mode`** flag takes precedence over `--pull`. When you enable offline mode, `act` sets `ForcePull` to `false` internally, preventing any network requests for Docker images or action metadata.

- **`act --pull`** (default) → Always attempts to pull images before running
- **`act --pull=false`** → Never pulls; uses local images exclusively
- **`act --action-offline-mode`** → Forces `ForcePull=false` and disables all external network calls

Use offline mode when running in air-gapped environments or when you need guaranteed reproducibility using only your local image cache.

## Practical Usage Examples

### Force Fresh Image Pulls

Run your workflow while explicitly ensuring all container images are current:

```bash
act --pull

```

### Disable Pulling for Cached Runs

Speed up local iterations when you know your images are current:

```bash
act --pull=false

```

### Complete Offline Execution

Prevent any network activity while running workflows:

```bash
act --action-offline-mode

```

### Complex Workflow with Custom Images

Combine the pull flag with platform specifications and artifact paths:

```bash
act --pull \
    --artifact-server-path ./artifacts \
    -j build \
    -P ubuntu-latest=ghcr.io/catthehacker/ubuntu:act-22.04

```

## Summary

- **`act --pull`** defaults to `true`, ensuring fresh images by default
- The flag propagates through [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go) into the `Config.ForcePull` field defined in [`pkg/runner/runner.go`](https://github.com/nektos/act/blob/main/pkg/runner/runner.go)
- `RunContext` applies the setting to **job containers**, **service containers**, and **step containers** via calls in [`pkg/runner/run_context.go`](https://github.com/nektos/act/blob/main/pkg/runner/run_context.go) and [`pkg/runner/step_docker.go`](https://github.com/nektos/act/blob/main/pkg/runner/step_docker.go)
- The actual Docker client logic in [`pkg/container/docker_pull.go`](https://github.com/nektos/act/blob/main/pkg/container/docker_pull.go) evaluates `ForcePull` to decide whether to skip local caches
- **`--action-offline-mode`** overrides `--pull`, forcing `ForcePull` to `false` and disabling network requests entirely

## Frequently Asked Questions

### What is the default value of `--pull` in act?

According to the source code in [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go), the default value is **`true`**. This means `act` attempts to pull images even when they exist locally, helping prevent stale environment issues during local testing.

### Does `--pull` affect service containers or just the main job container?

The `--pull` flag affects **all container types**. In [`pkg/runner/run_context.go`](https://github.com/nektos/act/blob/main/pkg/runner/run_context.go), the `ForcePull` configuration is passed to both `rc.pullServicesImages()` for service containers and `rc.JobContainer.Pull()` for the primary job container. Additionally, [`pkg/runner/step_docker.go`](https://github.com/nektos/act/blob/main/pkg/runner/step_docker.go) ensures that individual Docker steps also respect the flag.

### How does `--action-offline-mode` interact with `--pull`?

The `--action-offline-mode` flag takes precedence. As implemented in [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go), the final configuration uses the logic `ForcePull: !input.actionOfflineMode && input.forcePull`. This means enabling offline mode automatically sets `ForcePull` to `false`, preventing any image pulls regardless of the `--pull` flag value.

### Why does act pull images even when I have them locally?

When `--pull` is `true` (the default), `act` executes `docker pull` to ensure your local image matches the registry's current version for that tag. This prevents "cache drift" where your local `ubuntu-latest` might be weeks older than the registry's `ubuntu-latest`. Set `--pull=false` to skip this behavior and use local images exclusively.