---
title: "Publish packages to Packagecloud"
description: "Configure CircleCI to publish packages to Packagecloud with the packagecloud CLI or API, including npm package deployment and dependency caching."
platform: "Cloud, Server"
doc_version: "Server"
last_updated: "2026-10-06"
---

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

# Publish packages to Packagecloud

In this how-to guide, you will learn how to configure CircleCI to publish packages to Packagecloud.

## Introduction

[Packagecloud](https://packagecloud.io) is a hosted package repository service. It allows users to host npm, Java/Maven, Python, apt, yum, and RubyGem repositories without any pre-configuration.

## 1\. Configure environment variables

Under project settings in CircleCI, create an environment variable with the name `PACKAGECLOUD_TOKEN`, containing the value of a packagecloud API token. This environment variable will be used to authenticate with the packagecloud API directly, or using the packagecloud CLI.

The packagecloud CLI will automatically read this environment variable from the system when interacting with repositories.

## 2\. Set the $PACKAGECLOUD\_URL for packagecloud:enterprise

Only set the `$PACKAGECLOUD_URL` if you are a packagecloud:enterprise customer.

This setting is only for packagecloud:enterprise customers. Under project settings in CircleCI, set the `$PACKAGECLOUD_URL` environment variable to the URL of the packagecloud:enterprise installation.

## 3\. Install the packagecloud CLI

To use the packagecloud CLI from CircleCI, install it using RubyGems by adding the following `run` step to your `.circleci/config.yml` under the job that is configured to deploy the package:

```yml
- run:
   name: Install packagecloud CLI
   command: gem install package_cloud
```

The CLI will automatically use the `$PACKAGECLOUD_TOKEN` environment variable to authenticate against the packagecloud service.

## 4\. Use dependency caching

If you want to cache this dependency between builds, you can add the `package_cloud` gem to a `Gemfile` and follow CircleCI’s guide for [Caching Dependencies](https://circleci.com/docs/guides/server/optimize/caching/).

## 5\. Push packages with the packagecloud CLI

The build processes for package types will vary, but pushing them into a packagecloud repository is quite simple. To add packages to a repository from your CircleCI builds, add a step in your `deploy` configuration that uses the packagecloud CLI.

The following is a full example `.circleci/config.yml` that will:

*   Checkout a git repository.
    
*   Run a `make` task (this command can be anything configured to build your package).
    
*   Deploy the package to a packagecloud repo.
    

**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
version: 2.1
defaults: &defaults
  working_directory: ~/repo
  docker:
    - image: cimg/ruby:3.1.2
jobs:
  build:
    <<: *defaults
    steps:
      - checkout
      - run:
          name: Build the package
          command: make
      - persist_to_workspace:
          root: ~/repo
          paths: .
  deploy:
    <<: *defaults
    steps:
      - attach_workspace:
          at: ~/repo
      - run:
          name: Install packagecloud CLI
          command: gem install package_cloud
      - run:
          name: Push deb package
          command: package_cloud push example-user/example-repo/debian/jessie debs/packagecloud-test_1.1-2_amd64.deb
workflows:
  package-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build
```

## 6\. Deploy npm packages

CircleCI users can deploy packages directly to npm registries hosted on Packagecloud.

### a. Configure the test job

This job will retrieve the project code, install its dependencies and run any tests in the NodeJS project:

```yaml
jobs:
  test:
    <<: *defaults

    steps:
      - checkout

      - restore_cache:
          keys:
          - v1-dependencies-.
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-

      - run: npm install
      - run:
          name: Run tests
          command: npm test

      - save_cache:
          paths:
            - node_modules
          key: v1-dependencies-

      - persist_to_workspace:
          root: ~/repo
          paths: .
```

### b. Configure the deploy job

The next job configured is the deploy job. This job will authenticate and publish to the packagecloud npm registry:

```yaml
jobs:
...
  deploy:
    <<: *defaults

    steps:
      - attach_workspace:
          at: ~/repo

      - run:
          name: Set registry URL
          command: npm set registry https://packagecloud.io/example-user/example-repo/npm/

      - run:
          name: Authenticate with the registry
          command: echo "//packagecloud.io/example-user/example-repo/npm/:_authToken=$PACKAGECLOUD_TOKEN" > ~/repo/.npmrc

      - run:
          name: Publish package
          command: npm publish
```

*   _Set registry URL_ : This command sets the registry to URL that will be used by the `npm` CLI.
    
*   _Authenticate with the registry_ : This command will set the `authToken` to be used by the `npm` CLI to the environment variable configured in the project settings.
    
*   _Publish package_ : Publish the package to the configured npm registry on packagecloud.
    

The packagecloud npm registry URL is in the following format:

```shell
https://packagecloud.io/:username/:repo_name/npm/
```

The full `.circleci/config.yml` looks something like this:

```yaml
version: 2.1

defaults: &defaults
  working_directory: ~/repo
  docker:
    - image: cimg/node:19.0.1

jobs:
  test:
    <<: *defaults
    steps:
      - checkout
      - restore_cache:
          keys:
          - v1-dependencies-.
          # fallback to using the latest cache if no exact match is found
          - v1-dependencies-
      - run: npm install
      - run:
          name: Run tests
          command: npm test
      - save_cache:
          paths:
            - node_modules
          key: v1-dependencies-
      - persist_to_workspace:
          root: ~/repo
          paths: .
  deploy:
    <<: *defaults
    steps:
      - attach_workspace:
          at: ~/repo
      - run:
          name: Set registry URL
          command: npm set registry https://packagecloud.io/example-user/example-repo/npm/
      - run:
          name: Authenticate with registry
          command: echo "//packagecloud.io/example-user/example-repo/npm/:_authToken=$PACKAGECLOUD_TOKEN" > ~/repo/.npmrc
      - run:
          name: Publish package
          command: npm publish

workflows:
  test-deploy:
    jobs:
      - test
      - deploy:
          requires:
            - test
```

The workflows section will tie together both the `test` and `deploy` jobs into sequential steps in the build process.

You can read more about publishing npm packages to packagecloud on the CircleCI blog post: [Publishing npm Packages Using CircleCI](https://circleci.com/blog/publishing-npm-packages-using-circleci-2-0/)

## Use the Packagecloud API

Packagecloud also provides a robust API to manage package repositories. You can read more about the [Packagecloud API](https://packagecloud.io/docs/api) and how to upload, delete, and promote packages across repositories.

## See also

*   [Storing and Accessing Artifacts](https://circleci.com/docs/guides/server/optimize/artifacts/)