---
title: "Run Docker commands"
description: "Build Docker images and run Docker commands within the Docker execution environment using remote Docker and the setup_remote_docker key."
platform: "Cloud, Server"
doc_version: "unversioned"
last_updated: "2026-10-15"
cloud_plans: "Free, Performance, Scale"
version_control: "All supported providers"
---

> For current CircleCI product defaults, deprecated patterns, and Cloud/Server differences, see [AGENTS.md](https://circleci.com/docs/AGENTS.md).
>
> For the complete documentation index and site structure, see [llms.txt](https://circleci.com/docs/llms.txt).

# Run Docker commands

**Cloud plans:** Free, Performance, Scale

**Version control:** [All supported providers](https://circleci.com/docs/guides/integration/version-control-system-integration-overview/)

Use the remote Docker environment to build Docker images within the Docker execution environment.

When you use remote Docker for a job, all Docker commands execute locally on the virtual machine used to spin up your primary Docker container.

The _remote_ in "remote Docker" is a legacy term from when remote Docker usage would spin up a separate, remote environment for running Docker commands.

## Introduction

To build Docker images (for example, using `docker` or `docker compose` commands) when using the Docker execution environment, you must use the `setup_remote_docker` key in your job:

**Using Docker?** Authenticating Docker pulls from image registries is recommended when using the Docker execution environment. Authenticated pulls allow access to private Docker images, and may also grant higher rate limits, depending on your registry provider. For further information, see [Using Docker Authenticated Pulls](https://circleci.com/docs/guides/execute/private-images/).

```yaml
jobs:
  build:
    docker:
      - image: cimg/base:2022.06
    steps:
      # ... steps for building/testing app ...
      - setup_remote_docker
```

Using `setup_remote_docker` for a job means that all Docker commands execute locally on the same virtual machine that spins up the primary container.

In the CircleCI web app, jobs that run in the remote Docker environment have the **Remote Docker** label, as follows:

> **Image:** Remote Docker label

Figure 1. Remote Docker label

Only use `setup_remote_docker` key for jobs where your primary executor _is_ a Docker container. If your job uses a VM rather than a container (for example, your executor is `machine`) you do **not** need to use the `setup_remote_docker` key. For an example, see [Run Docker commands using the `machine` executor](#run-docker-commands-using-the-machine-executor).

## Specifications

CircleCI runs remote Docker environments using **Linux or Arm machine resource classes**, depending on the resource class you assign to the Docker executor.

### x86 architecture

A remote Docker environment uses a **Linux VM machine** resource class that corresponds to the Docker executor class with the following exceptions:

*   `small` maps to `medium` (Linux VM).
    
*   `medium+` maps to `large` (Linux VM).
    

Gen2 resource classes are also available for remote Docker (for example, `medium.gen2`). The `small.gen2` resource class is not supported for remote Docker; the smallest available size is `medium.gen2`.

### Arm architecture

Arm-based Docker jobs use an equivalent **Arm machine** resource class for remote Docker.

Gen2 resource classes are also available for remote Docker (for example, `arm.medium.gen2`).

**Arm gen2 is currently in beta.** Performance and pricing are tentative and may change when this feature becomes generally available. Arm-based remote Docker also does not currently support the [IP Ranges](https://circleci.com/docs/guides/security/ip-ranges/).

### Docker executor to Remote Docker (Linux/Arm Machine) mapping

#### x86 architecture

| Docker resource class | Remote Docker (Linux Machine) resource class |
| --- | --- |
| `small` | `medium` (Linux VM) |
| `medium` | `medium` (Linux VM) |
| `medium+` | `large` (Linux VM) |
| `large` | `large` (Linux VM) |
| `xlarge` | `xlarge` (Linux VM) |
| `2xlarge` | `2xlarge` (Linux VM) |

#### x86 gen2 architecture

| Docker resource class | Remote Docker (Linux Machine) resource class |
| --- | --- |
| `medium.gen2` | `medium.gen2` (Linux VM) |
| `large.gen2` | `large.gen2` (Linux VM) |
| `xlarge.gen2` | `xlarge.gen2` (Linux VM) |
| `2xlarge.gen2` | `2xlarge.gen2` (Linux VM) |
| `2xlarge+.gen2` | `2xlarge+.gen2` (Linux VM) |

#### Arm architecture

| Docker resource class | Remote Docker (Arm Linux Machine) resource class |
| --- | --- |
| `arm.medium` | `arm.medium` (Arm VM) |
| `arm.large` | `arm.large` (Arm VM) |
| `arm.xlarge` | `arm.xlarge` (Arm VM) |
| `arm.2xlarge` | `arm.2xlarge` (Arm VM) |

#### Arm gen2 architecture Beta

| Docker resource class | Remote Docker (Arm Linux Machine) resource class |
| --- | --- |
| `arm.medium.gen2` | `arm.medium.gen2` (Arm VM) |
| `arm.large.gen2` | `arm.large.gen2` (Arm VM) |
| `arm.xlarge.gen2` | `arm.xlarge.gen2` (Arm VM) |
| `arm.2xlarge.gen2` | `arm.2xlarge.gen2` (Arm VM) |

*   Full list of resource classes: [Configuration Reference](https://circleci.com/docs/reference/configuration-reference/#resourceclass).
    
*   Full specifications and pricing: [CircleCI Pricing](https://circleci.com/pricing/price-list/)
    

### CircleCI Server

For CircleCI Server installations, contact the systems administrator for specifications.

## Run Docker commands using the Docker executor

The example below shows how you can build and deploy a Docker image for our [demo Docker project](https://github.com/CircleCI-Public/circleci-demo-docker) using the Docker executor, with remote Docker:

```yml
version: 2.1

jobs:
  build:
    docker:
      - image: cimg/go:1.17
    resource_class: xlarge
    steps:
      - checkout
      # ... steps for building/testing app ...

      - setup_remote_docker:
          docker_layer_caching: true

      # build and push Docker image
      - run: |
          TAG=0.1.$CIRCLE_BUILD_NUM
          docker build -t CircleCI-Public/circleci-demo-docker:$TAG .
          echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
          docker push CircleCI-Public/circleci-demo-docker:$TAG
```

Below is a breakdown of what is happening during this build’s execution:

*   All commands execute in the [Primary Container](https://circleci.com/docs/reference/glossary/#primary-container). (line 5).
    
*   Once you call `setup_remote_docker`, all Docker-related commands execute locally. (line 12).
    
*   Enable [Docker Layer Caching](https://circleci.com/docs/reference/glossary/#docker-layer-caching) (DLC) to speed up image building. (line 13).
    
*   We use [Set an Environment Variable in a Project](https://circleci.com/docs/guides/security/set-environment-variable/#set-an-environment-variable-in-a-project) to store credentials for Docker Hub. (line 19).
    

## Install the Docker CLI

[CircleCI Convenience Images](https://circleci.com/docs/guides/execute/circleci-images/) have the Docker CLI pre-installed. If you are using a third-party image that does not have the Docker CLI installed, [you need to install it](https://docs.docker.com/install/#supported-platforms) as part of your job.

```yml
      # Install via apk on alpine based images
      - run:
          name: Install Docker client
          command: apk add docker-cli
```

## Specify a Docker version for remote Docker

To optionally specify a Docker version, you can set it as a `version` attribute with supported tags:

```yml
      - setup_remote_docker:
          version: edge
```

CircleCI supports the tags listed below for remote Docker, as per our [Remote Docker Tagging Policy](https://circleci.com/docs/guides/execute/remote-docker-images-support-policy/#tagging).

For **x86** and **Arm** architecture, the following tags are available:

*   `default`
    
*   `edge`
    
*   `previous`
    

The above tags resolve to Docker 28.

To use Docker 29, use the following tag:

*   `docker29`
    

To use Docker 27, use the following tag:

*   `docker27`
    

To use Docker 26, use the following tag:

*   `docker26`
    

To use the current deprecated version, Docker 20, use `20.10.24`.

The `version` key is not supported on CircleCI Server. Contact your system administrator for information about the Docker version installed in your remote Docker environment.

## Run Docker commands using the machine executor

The example below shows how you can build a Docker image using the `machine` executor with the default image. Note that this does not require the use of remote Docker:

```yaml
version: 2.1

jobs:
  build:
    machine:
      image: ubuntu-2604:current
    steps:
      - checkout
      # start proprietary DB using private Docker image
      # with credentials stored in the UI
      - run: |
          echo "$DOCKER_PASS" | docker login --username $DOCKER_USER --password-stdin
          docker run -d --name db company/proprietary-db:1.2.3

      # build the application image
      - run: docker build -t company/app:$CIRCLE_BRANCH .

      # deploy the image
      - run: docker push company/app:$CIRCLE_BRANCH
```

## Prefer same-region image pulls

When you set `prefer_same_region` to `true`, CircleCI attempts to pull the image from the same region as the VM on a best-effort basis. If the same-region pull fails, it falls back to pulling from the image’s original region.

```yaml
      - setup_remote_docker:
          prefer_same_region: true
```

## See also

*   [Docker Layer Caching](https://circleci.com/docs/guides/optimize/docker-layer-caching/)
    
*   [Primary Container](https://circleci.com/docs/reference/glossary/#primary-container)