CircleCI
Run CircleCI jobs locally and execute workflows as sequential local pipelines directly from Workspace Tasks.
Table of Contents
New in v1.9.0: CircleCI support.
Experimental: CircleCI support is in early preview. Expect some rough edges and share your feedback!
There are some known limitations around local workflow emulation when running CircleCI jobs locally. Issues around running within devcontainers with Docker-outside-of-Docker (DooD) and Docker-in-Docker (DinD) are common but can be mitigated with the recommended DinD configuration. We are actively working on improving the experience and would love to hear about your use cases and any pain points you encounter.
Overview
Workspace Tasks discovers CircleCI config files (.circleci/config.yml / .circleci/config.yaml) and builds a tree with workflows and jobs.
- Jobs run via the CircleCI local CLI (
circleci local execute). - Workflows run as a local sequential orchestration of their jobs (Compound Task style).
Task Tree Structure
config.yml โ (non-runnable, group)
โโโ workflow: build-and-test โ (runnable, sequential)
โ โโโ lint โ (runnable)
โ โโโ test โ (runnable)
โโโ jobs โ (non-runnable, group)
โโโ lint โ (runnable)
โโโ test โ (runnable)
โโโ nightly-cleanup โ (runnable)
- The config file node is a non-runnable group โ it provides open-file access only.
- The workflow nodes are runnable and execute all their jobs sequentially.
- The jobs group always lists every job defined in the config, so individual jobs can be run directly at any time, regardless of whether they belong to a workflow.
Requirements
- CircleCI CLI must be installed and configured for use.
- Docker must be running for local job execution.
If circleci is not in your system path, configure workspaceTasks.applicationPath.circleci.
Execution Behavior
Running a Job
Jobs are executed with the CircleCI local CLI:
circleci local execute -c .circleci/config.yml <job-name>
Running a Workflow
CircleCI CLI does not natively run workflows locally. Workspace Tasks emulates this by executing workflow jobs one-by-one in workflow order.
- If a job fails, the workflow run stops.
- If you stop the workflow, the current job is terminated and no next job starts.
Limitations
- Local workflow runs are sequential emulation, not full CircleCI cloud orchestration.
- Parallel/fan-out branches in a workflow are linearized in v1 local execution.
- Online-only features (cache/artifacts/platform-managed contexts) may differ when running locally.
Configuration
{
"workspaceTasks.enabledTaskTypes": {
"circleci": true
},
"workspaceTasks.applicationPath.circleci": "circleci",
"workspaceTasks.circleci.additionalFilePatterns": []
}
| Setting | Type | Default | Description |
|---|---|---|---|
workspaceTasks.applicationPath.circleci | string | "circleci" | Path to the CircleCI CLI executable |
workspaceTasks.circleci.additionalFilePatterns | string[] | [] | Extra globs merged with built-in .circleci/config discovery patterns |
Troubleshooting
- No CircleCI tasks appear
- Ensure
.circleci/config.ymlexists. - Confirm
workspaceTasks.enabledTaskTypes.circleciis enabled.
- Ensure
- Job fails immediately
- Verify Docker is running.
- Run the same command manually in a terminal to validate local CLI setup.
- Workflow stops early
- A prior job failed or the workflow was manually stopped.
read /tmp/local_build_config.yml: is a directoryor similar mount errors- This is commonly a Docker-outside-of-Docker (DooD) problem in dev containers. When the CircleCI CLI instructs Docker to mount temp files, the host daemon looks for those paths on the host filesystem, not inside the dev container. If the file does not exist there, Docker can create a directory instead, causing the mount to fail.
- Recommended fix: Switch your dev container to Docker-in-Docker (DinD). DinD runs a nested Docker daemon inside the container, so CLI and daemon share the same filesystem.
// devcontainer.json "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": { "moby": false } }Remove any manual
/var/run/docker.sockbind mount โ it is not needed with DinD. - Alternative workaround: Keep DooD, but use a host/container mount with an identical absolute path that both sides can resolve for any temp file bind mounts.