---
title: "Sample config.yml Files"
description: "Sample .circleci/config.yml files to start from, with examples of concurrent, sequential, approval and fan-in/fan-out workflows and multiple executors."
platform: "Cloud, Server"
doc_version: "Server"
last_updated: "2026-10-15"
---

> 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).

# Sample config.yml Files

This document provides sample `.circleci/config.yml` files that you can use as a starting point when setting up projects, or to better understand different ways to orchestrate jobs using workflows and filters. For information on all configuration elements available to you, see the [Configuration Reference](https://circleci.com/docs/reference/configuration-reference/) page.

If you would like to get set up right away, see our language-specific quickstart guides:

*   [Node](https://circleci.com/docs/guides/server/getting-started/language-javascript/)
    
*   [Python](https://circleci.com/docs/guides/server/getting-started/language-python/)
    
*   [Go](https://circleci.com/docs/guides/server/getting-started/language-go/)
    

## Tools for editing configuration files

CircleCI has created an extension for [Visual Studio Code](https://circleci.com/docs/guides/server/toolkit/vs-code-extension-overview/) that reduces context switching between the web app and VS Code through a set of helpful features.

The VS Code extension reduces the time to create, modify, and troubleshoot configuration files through real-time syntax validation, highlighting, and autocomplete suggestions. Authenticating the extension with your CircleCI account will also allow you to visualize and manage your CircleCI pipelines directly from your code editor, and be notified of workflow status changes.

The CircleCI VS Code extension is available to download on the [VS Code marketplace](https://marketplace.visualstudio.com/items?itemName=circleci.circleci).

## Simple configuration examples

**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/).

### Concurrent workflow

The configuration example below shows a concurrent workflow in which the `build` and `test` jobs run at the same time. Both jobs are run in Docker containers using the base image provided by CircleCI.

*   Refer to the [Workflows](https://circleci.com/docs/guides/server/orchestrate/workflows/) document for complete details about orchestrating job runs with concurrent, sequential, and manual approval workflows.
    
*   Refer to the [developer hub convenience images](https://circleci.com/developer/images?imageType=docker) page to find out about available Docker images for running your jobs.
    

This image shows the workflow view for the following configuration example:

> **Image:** Concurrent Workflow Graph

Figure 1. Concurrent Workflow Graph

```yaml
version: 2.1

# Define the jobs we want to run for this project
jobs:
  build:
    docker:
      - image: cimg/base:2023.03
    steps:
      - checkout
      - run: echo "this is the build job"
  test:
    docker:
      - image: cimg/base:2023.03
    steps:
      - checkout
      - run: echo "this is the test job"

# Orchestrate our job run sequence
workflows:
  build_and_test:
    jobs:
      - build
      - test
```

### Sequential workflow

The configuration example below shows a sequential workflow where the `build` job runs, and then the `test` job runs once `build` has completed. Configure sequential workflows using the [`requires` key](https://circleci.com/docs/reference/configuration-reference/#requires), and specifying the `test` job "requires" the `build` job in order to run. Both jobs are run in Docker containers using the base image provided by CircleCI.

*   Refer to the [Workflows](https://circleci.com/docs/guides/server/orchestrate/workflows/) document for complete details about orchestrating job runs with concurrent, sequential, and manual approval workflows.
    
*   Refer to the [developer hub convenience images](https://circleci.com/developer/images?imageType=docker) page to find out about available Docker images for running your jobs.
    

This image shows the workflow view for the following configuration example, in which jobs run sequentially (one after the other):

> **Image:** Sequential Workflow Graph

Figure 2. Sequential Workflow Graph

```yaml
version: 2.1

# Define the jobs we want to run for this project
jobs:
  build:
    docker:
      - image: cimg/base:2023.03
    steps:
      - checkout
      - run: echo "this is the build job"
  test:
    docker:
      - image: cimg/base:2023.03
    steps:
      - checkout
      - run: echo "this is the test job"

# Orchestrate our job run sequence
workflows:
  build_and_test:
    jobs:
      - build
      - test:
          requires:
            - build
```

### Approval job

The example below shows a sequential workflow with an [Approval Job](https://circleci.com/docs/reference/configuration-reference/#type). Use an approval job to require manual approval before downstream jobs may proceed.

```yaml
version: 2.1

executors: # Define an executor
  my-executor:
    docker:
      - image: cimg/base:2024.01
# Define the jobs we want to run for this project
jobs:
  build:
    executor: my-executor
    steps:
      - checkout
      - run: echo "build"
  test:
    executor: my-executor
    steps:
      - checkout
      - run: echo "test"
  deploy:
    executor: my-executor
    steps:
      - checkout
      - run: echo "deploy"

# Orchestrate our job run sequence
workflows:
  build_and_test:
    jobs:
      - build
      - test:
          requires:
            - build
      - hold:
          type: approval
          requires:
            - build
      - deploy:
          requires:
            - hold
```

The workflow runs as follows:

1.  `build` job runs.
    
2.  `test` job runs.
    
3.  `hold` job, with `type: approval` ensures the workflow waits for manual approval in the CircleCI web app.
    
4.  Once `hold` job is approved the `deploy` job runs.
    

An approval job can have any name. In the example above the approval job is named `hold`. The name you choose for an approval job can not be used to define a job in the main configuration. An approval job only exists as a workflow orchestration device.

The image below shows the workflow view for the following configuration example. This image has three parts to show:

*   The workflow graph with the `hold` job paused.
    
*   The "Needs Approval" popup that appears when you click on a hold job.
    
*   The workflow view again once the `hold` job has been approved and the `deploy` job has run.
    

> **Image:** Approval Workflow Graph

Figure 3. Approval Workflow Graph

*   Refer to the [Workflows](https://circleci.com/docs/guides/server/orchestrate/workflows/) document for complete details about orchestrating job runs with concurrent, sequential, and manual approval workflows.
    
*   Refer to the [developer hub convenience images](https://circleci.com/developer/images?imageType=docker) page to find out about available Docker images for running your jobs.
    

### Hello world

```yml
# Use the latest 2.1 version of CircleCI pipeline process engine.
# See: https://circleci.com/docs/configuration-reference
version: 2.1

# Define a job to be invoked later in a workflow.
# See: https://circleci.com/docs/jobs-steps/#jobs-overview & https://circleci.com/docs/configuration-reference/#jobs
jobs:
  say-hello:
    # Specify the execution environment. You can specify an image from Docker Hub or use one of our convenience images from CircleCI's Developer Hub.
    # See: https://circleci.com/docs/executor-intro/ & https://circleci.com/docs/configuration-reference/#executor-job
    docker:
      # Specify the version you desire here
      # See: https://circleci.com/developer/images/image/cimg/base
      - image: cimg/base:current

    # Add steps to the job
    # See: https://circleci.com/docs/jobs-steps/#steps-overview & https://circleci.com/docs/configuration-reference/#steps
    steps:
      # Checkout the code as the first step.
      - checkout
      - run:
          name: "Say hello"
          command: "echo Hello, World!"

# Orchestrate jobs using workflows
# See: https://circleci.com/docs/workflows/ & https://circleci.com/docs/configuration-reference/#workflows
workflows:
  say-hello-workflow: # This is the name of the workflow, feel free to change it to better match your workflow.
    # Inside the workflow, you define the jobs you want to run.
    jobs:
      - say-hello
```

## Sample configuration with sequential workflow and secondary Docker container

Following is a sample `.circleci/config.yml` file using the following configuration features:

*   A sequential workflow
    
*   An orb
    
*   A secondary services container
    
*   Workspaces
    
*   Storing artifacts
    

```yaml
version: 2.1

orbs:
  node: circleci/node@3.0.0

jobs:
  build:
    working_directory: ~/mern-starter
    # Reuse Docker container specification given by the node Orb
    executor: node/default
    steps:
      - checkout
      # Install the latest npm - the node Orb takes care of it
      - node/install-npm
      # Install dependencies - the node Orb take care of installation and dependency caching
      - node/install-packages:
          app-dir: ~/mern-starter
          cache-path: node_modules
          override-ci-command: npm i
      # Save workspace for subsequent jobs (i.e. test)
      - persist_to_workspace:
          root: .
          paths:
            - .

  test:
    docker:
      # The primary container is an instance of the first image listed. The job's commands run in this container.
      - image: cimg/node:current
      # The service container is an instance of the second listed image which is run in a common network where ports exposed on the primary container are available on localhost.
      - image: mongo:4.2
    steps:
      # Reuse the workspace from the build job
      - attach_workspace:
          at: .
      - run:
          name: Demonstrate that Mongo DB is available as localhost
          command: |
            curl -sSJL https://www.mongodb.org/static/pgp/server-4.2.asc | sudo apt-key add -
            echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.2.list
            sudo apt update
            sudo apt install mongodb-org
            mongo localhost --eval "db.serverStatus()"
      - run:
          name: Test
          command: npm test
      - run:
          name: Generate code coverage
          command: './node_modules/.bin/nyc report --reporter=text-lcov'
      # You can specify either a single file or a directory to store as artifacts
      - store_artifacts:
          path: test-results.xml
          destination: deliverable.xml
      - store_artifacts:
          path: coverage
          destination: coverage

workflows:
  build_and_test:
    jobs:
      - build
      - test:
          requires:
            - build
```

This example shows a sequential workflow with the `test` job configured to run only on the main branch. Refer to the [Workflows](https://circleci.com/docs/guides/server/orchestrate/workflows/) document for complete details about orchestrating job runs with concurrent, sequential, and manual approval workflows.

## Sample configuration with fan-in/fan-out workflow

Below are two sample configurations for a Fan-in/Fan-out workflow.

On CircleCI Server, set the `machine` executor image to `default` in these examples.

> **Image:** Fan-in-out

Figure 4. Fan-in-out

```yaml
version: 2.1

orbs:
    docker: circleci/docker@1.0.1

jobs:
    prepare-dependencies:
        docker:
            - image: node:current-alpine
        steps:
            - checkout
            - run:
                  name: Compute version number
                  command: echo "0.0.${CIRCLE_BUILD_NUM}-${CIRCLE_SHA1:0:7}" | tee version.txt
            - restore_cache:
                  keys:
                      - yarn-deps-{{ checksum "yarn.lock" }}
                      - yarn-deps
            - run:
                  name: yarn install
                  command: yarn install
            - save_cache:
                  paths:
                      - node_modules
                  key: yarn-deps-{{ checksum "yarn.lock" }}-{{ epoch }}
            - store_artifacts:
                  path: yarn.lock
            - persist_to_workspace:
                  root: .
                  paths:
                      - .

    build-production:
        docker:
            - image: node:current-alpine
        steps:
            - attach_workspace:
                  at: .
            - run:
                  name: Production build
                  command: |
                      export __BUILD_VERSION="$(cat version.txt)"
                      yarn build
            - store_artifacts:
                  path: dist/server.js
            - persist_to_workspace:
                  root: .
                  paths:
                      - .

    build-docker-image:
        machine:
            image: ubuntu-2404:current
        steps:
            - attach_workspace:
                  at: .
            - run:
                  name: Setup __BUILD_VERSION envvar
                  command: |
                      echo 'export __BUILD_VERSION="$(cat version.txt)"' >> "$BASH_ENV"
            - docker/check:
                  registry: $DOCKER_REGISTRY
            - docker/build:
                  image: $DOCKER_IMAGE_NAME
                  tag: $__BUILD_VERSION
                  registry: $DOCKER_REGISTRY
            - docker/push:
                  image: $DOCKER_IMAGE_NAME
                  tag: $__BUILD_VERSION
                  registry: $DOCKER_REGISTRY

    test:
        docker:
            - image: node:current-alpine
        parallelism: 2
        steps:
            - attach_workspace:
                  at: .
            - run:
                  name: Run tests
                  command: |
                      circleci tests glob '**/*.test.ts' | circleci tests split --split-by timings | xargs yarn test:ci
            - store_artifacts:
                  path: test-results
            - store_test_results:
                  path: test-results

    deploy-docker-image:
        machine:
            image: ubuntu-2404:current
        steps:
            - attach_workspace:
                  at: .
            - run:
                  name: Setup __BUILD_VERSION envvar
                  command: |
                      echo 'export __BUILD_VERSION="$(cat version.txt)"' >> "$BASH_ENV"
            - docker/check:
                  registry: $DOCKER_REGISTRY
            - docker/pull:
                  images: $DOCKER_REGISTRY/$DOCKER_IMAGE_NAME:$__BUILD_VERSION
            - run:
                  name: Tag the image as latest
                  command: docker tag $DOCKER_REGISTRY/$DOCKER_IMAGE_NAME:$__BUILD_VERSION $DOCKER_REGISTRY/$DOCKER_IMAGE_NAME:latest
            - docker/push:
                  image: $DOCKER_IMAGE_NAME
                  tag: latest
                  registry: $DOCKER_REGISTRY

workflows:
    build-test-deploy:
        jobs:
            - prepare-dependencies
            - build-production:
                  requires:
                      - prepare-dependencies
            - build-docker-image:
                  context: docker-hub
                  requires:
                      - build-production
            - test:
                  requires:
                      - prepare-dependencies
            - deploy-docker-image:
                  context: docker-hub
                  requires:
                      - build-docker-image
                      - test
```

A job can only run when its dependencies are satisfied therefore it requires the dependencies of all upstream jobs. This means only the immediate upstream dependencies need to be specified in the `requires:` blocks.

## See also

*   See the [Concepts](https://circleci.com/docs/reference/concepts/#configuration) page and [Workflows](https://circleci.com/docs/guides/server/orchestrate/workflows/) for more details of the concepts covered in this example.
    
*   See the [Configuration Reference](https://circleci.com/docs/reference/configuration-reference/) document for full details of each individual configuration key.
    
*   See the [Example Public Repos](https://circleci.com/docs/guides/server/toolkit/examples-and-guides-overview/) document for a list of public projects that use CircleCI.