CircleCI Orbs are reusable packages of configuration, but they’re typically hosted on the public Orb Registry. When you need to share reusable CI/CD logic only within your organization, hosting a private Orb is the way to go. This keeps proprietary build steps and integrations secure and accessible only to your internal teams.

Let’s see how this looks in practice. Imagine you have a common build and deployment process for your Python microservices. Instead of repeating these steps in every project’s .circleci/config.yml, you can encapsulate them in a private Orb.

Here’s a simplified example of what a private Orb’s config.yml might look like:

version: 2.1

description: >
  Custom Python microservice build and deploy Orb

commands:
  build_and_test:
    description: >
      Builds and tests a Python microservice.
    parameters:
      python_version:
        type: string
        default: "3.9"
        description: The Python version to use.
    steps:
      - checkout
      - run:
          name: Set up Python
          command: |
            sudo apt-get update -yqq
            sudo apt-get install -y python<%= @params.python_version.gsub('.', '') %>
            python<%= @params.python_version.gsub('.', '') %> --version
      - run:
          name: Install Dependencies
          command: pip install -r requirements.txt
      - run:
          name: Run Tests
          command: pytest

jobs:
  build:
    description: >
      Builds and tests a Python microservice.
    parameters:
      python_version:
        type: string
        default: "3.9"
        description: The Python version to use.
    docker:
      - image: cimg/base:stable
    steps:
      - build_and_test:
          python_version: << parameters.python_version >>

workflows:
  version: 2
  build-workflow:
    jobs:
      - build:
          python_version: "3.10"

This Orb defines a build_and_test command and a build job. The build_and_test command handles checking out code, setting up a specific Python version, installing dependencies, and running tests. The build job then utilizes this command.

Now, to use this private Orb in one of your internal projects, your project’s .circleci/config.yml would reference it using its private registry path:

version: 2.1

orbs:
  my-python-orb: your-org-slug/my-python-orb@1.0.0 # Replace with your actual org slug and orb name

jobs:
  build-and-deploy:
    docker:
      - image: cimg/base:stable
    steps:
      - checkout
      - my-python-orb/build: # Using the job defined in the Orb
          python_version: "3.11"
      - run:
          name: Deploy to Staging
          command: echo "Deploying..."

workflows:
  version: 2
  main:
    jobs:
      - build-and-deploy

The key here is your-org-slug/my-python-orb@1.0.0. This tells CircleCI to look for the my-python-orb within your organization’s private registry, specifically at version 1.0.0.

To make this work, you first need to publish the Orb to your organization’s private registry. This is done via the CircleCI CLI. Assuming your Orb source code is in a directory named my-python-orb and your organization slug is my-company, you’d run:

circleci orb publish my-company/my-python-orb@1.0.0 ./my-python-orb/config.yml

This command uploads the Orb definition to your private registry. Once published, any project within your organization can reference it.

The most surprising true thing about private Orbs is that they don’t actually store your Orb’s code or dependencies. Instead, they act as versioned pointers to your Orb’s configuration. When a job uses a private Orb, CircleCI fetches the configuration from your private registry and then executes it within the specified Docker image. The actual code for your build steps (like pip install or pytest) still runs within the job’s execution environment, not within some isolated Orb container. This means your private Orb definition should include all necessary steps to set up the environment for your build logic.

The "private" aspect is purely about access control and discoverability. It ensures that only members of your organization can see and use the Orb, maintaining the confidentiality of your internal CI/CD processes.

When you’re building complex CI/CD pipelines that involve several internal tools or standardized deployment procedures, managing these as private Orbs dramatically reduces duplication and improves maintainability. You can update a single Orb, publish a new version, and then have all dependent projects automatically pick up the changes by simply updating their Orb version reference.

The next logical step after mastering private Orbs is exploring how to use private registries for your Docker images within these Orbs and project configurations.

Want structured learning?

Take the full Circleci course →