# Binding Work Directories in Act Using `--bind`: A Complete Technical Guide

> Learn how to bind work directories in act using --bind for instant file sync. This technical guide explains how the --bind flag streamlines your workflow by mounting host directories into containers.

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

---

**The `--bind` (or `-b`) flag tells `act` to mount your host working directory directly into the job container instead of copying files, eliminating the copy step and enabling instant file synchronization between host and container.**

The `nektos/act` tool executes GitHub Actions workflows locally inside Docker containers. By default, the runner copies your entire repository into a Docker volume before starting each job, which creates overhead for large codebases or file-watching workflows. The `--bind` flag changes this behavior to create a live bind mount, drastically improving startup times and allowing real-time edits to reflect immediately inside running containers.

## How `--bind` Works Under the Hood

When you enable the bind mode, `act` bypasses its default copy mechanism and constructs a direct filesystem bridge between your host and the job container. This involves three key stages across the codebase:

### CLI Flag Definition and Configuration

The flag is declared in [`cmd/root.go`](https://github.com/nektos/act/blob/main/cmd/root.go) and stored in the runner configuration. When parsing arguments, `act` sets the `Config.BindWorkdir` boolean field defined in [`pkg/runner/runner.go`](https://github.com/nektos/act/blob/main/pkg/runner/runner.go). This single boolean determines whether the runner will copy files or mount them.

### Bind Mount String Construction

The core logic resides in `RunContext.GetBindsAndMounts()` inside [`pkg/runner/run_context.go`](https://github.com/nektos/act/blob/main/pkg/runner/run_context.go). When `BindWorkdir` is true, the function constructs a Docker bind string using the following pattern:

```go
fmt.Sprintf("%s:%s%s", rc.Config.Workdir, ext.ToContainerPath(rc.Config.Workdir), bindModifiers)

```

The `bindModifiers` string varies by host operating system to optimize performance and security:

- **macOS**: Appends `:delegated` to improve filesystem performance on Docker Desktop
- **SELinux-enabled hosts**: Appends `:z` to relabel the mount context for proper access control

### Container Launch and Docker Integration

After constructing the bind list, `RunContext.startJobContainer()` (also in [`pkg/runner/run_context.go`](https://github.com/nektos/act/blob/main/pkg/runner/run_context.go)) passes the configuration to `container.NewContainer`. The actual Docker API call occurs in [`pkg/container/docker_cli.go`](https://github.com/nektos/act/blob/main/pkg/container/docker_cli.go), where the bind string populates the `Binds` field of the container's host configuration. Docker then mounts the host directory directly into the container's workspace path, creating a live two-way sync.

## Using `--bind` in Practice

Enable bind mounting with the short or long flag form when invoking `act`:

**Run a specific job with bind mounting for faster startup:**

```bash
act -b -j build

```

**Explicitly disable the Docker socket bind while using workspace binding:**

```bash
act -b --container-daemon-socket -

```

**Combine bind mode with a custom runner image:**

```bash
act -b -P ubuntu-latest=catthehacker/ubuntu:act-latest

```

Without the `-b` flag, `act` creates a named Docker volume for the workspace and copies the repository contents into it before execution begins.

## Default Behavior Without `--bind`

When `--bind` is omitted, `GetBindsAndMounts()` creates a **named Docker volume** instead of a bind mount. The code assigns the container path to a volume map entry:

```go
mounts[name] = ext.ToContainerPath(rc.Config.Workdir)

```

`act` then performs a copy operation to populate this volume with your repository files. While this provides better isolation and avoids potential file permission issues, it introduces latency during job startup and requires explicit re-runs to see host filesystem changes.

## Summary

- **`--bind` mounts** the host working directory directly into the job container, while the **default mode copies** files into a named Docker volume.
- The flag sets `Config.BindWorkdir` in [`pkg/runner/runner.go`](https://github.com/nektos/act/blob/main/pkg/runner/runner.go), which triggers bind string construction in `RunContext.GetBindsAndMounts()`.
- Bind modifiers (`:delegated` for macOS, `:z` for SELinux) are automatically appended based on the host platform.
- Use `act -b` or `act --bind` to enable live file editing and faster job startup, especially for large repositories or workflows that watch files.

## Frequently Asked Questions

### Does `--bind` improve performance for all projects?

**Yes, particularly for large repositories and workflows with file watchers.** Eliminating the copy step reduces job startup time significantly when your repository contains many files or large assets. However, for very small projects, the performance difference may be negligible compared to the default volume-based approach.

### How does `act` handle file permissions with bind mounts on Linux?

**On SELinux-enabled systems, `act` automatically appends the `:z` flag to the bind mount string.** This relabels the mounted files so the container process can access them. If you encounter permission errors inside the container when using `--bind`, verify that your user has read access to the files on the host, as the container inherits the same UID/GID constraints.

### Can I use `--bind` with remote Docker hosts?

**The bind mount points to your local filesystem path.** If you are using a remote Docker daemon (via `DOCKER_HOST`), the remote daemon will attempt to mount a path from the remote machine's filesystem, not your local machine. In this scenario, the default copy behavior or volume mounts are more appropriate unless your remote Docker context has access to the same filesystem paths.

### What happens if I edit files while a job is running with `--bind`?

**Changes are visible immediately inside the container.** Since the host directory is bind-mounted, any file modifications, deletions, or additions on your host appear instantly in the container's workspace. This is ideal for debugging workflows that depend on file watchers or for iterative development where you need to fix code and retry steps without restarting the entire job.