---
url: /en/artifact/composer.md
description: >
  Guide for configuring push and pull credentials and using the CNB Composer
  artifact registry to manage PHP packages, covering local development and CI
  pipeline scenarios.
---
## Configure Push Credentials

Upload artifact files to the Composer Artifact Registry via the CNB REST API.
For how to obtain `CNB_TOKEN`, refer to \[Creating an Access Token]
(./intro.md#creating-an-access-token).

### Option 1: Configure .netrc to Auto-load Credentials

```shell
printf "\nmachine composer.cnbprod.alpha.qq.com\nlogin cnb\npassword %s\n" "<CNB_TOKEN>" >> ~/.netrc
```

### Option 2: Directly Specify Credentials in the curl Command

```shell
curl -ucnb:<CNB_TOKEN> https://composer.cnbprod.alpha.qq.com/xxx... -T <PATH_TO_FILE>
```

## Configure Pull Credentials

1. Add the Artifact Registry address to the global config.json
   (usually located at ~/.composer/config.json). For how to obtain `CNB_COMPOSER_URL`,
   refer to [Obtaining the Artifact Registry Address](./intro.md#obtaining-the-artifact-registry-address).

```shell
composer config repos.packgist false -g
composer config repos.cnb composer <CNB_COMPOSER_URL> -g
```

2. Add credentials to the global auth.json (usually located at ~/.composer/auth.json).

```shell
composer config http-basic.composer.cnbprod.alpha.qq.com cnb <CNB_TOKEN> -g
```

## Push Artifacts

### Local Command Line Push

Paste the following content into composer.json to avoid packaging authentication information and dependencies.

```json
{
    "archive": {
        "exclude": ["auth.json", "composer.lock", "vendor"]
    }
}
```

2. Navigate to the package directory and package the Composer artifact.

```shell
composer archive -f zip --file package
```

3. Publish to CNB.

**Note:**

1. For how to obtain `CNB_COMPOSER_URL`, refer to [Obtaining the Artifact
   Registry Address](./intro.md#obtaining-the-artifact-registry-address).
2. `<vendor>/<package>/<version>` should be replaced with the actual values
   for the current package, e.g., `monolog/monolog/3.8.1`.

```shell
curl --netrc "<CNB_COMPOSER_URL>upload/<vendor>/<package>/<version>" -T package.zip
```

### Push in Cloud Native Build

Paste the following content into `.cnb.yml`, commit, then push a Tag to trigger
the build (the Tag value will be used as the artifact version).
Replace `CNB_COMPOSER_URL` with the actual value and `<vendor>/<package>`
with the actual values (e.g., `monolog/monolog`).

```yaml title=".cnb.yml"
$:
  tag_push:
    - docker:
        image: docker.cnb.cool/examples/language/php-8.4
      stages:
        - name: setup netrc
          # Configure push credentials (CNB injects the CNB_TOKEN env var)
          script: printf "machine composer.cnbprod.alpha.qq.com\nlogin cnb\npassword %s\n" "${CNB_TOKEN}" > ~/.netrc
        - name: archive
          # Package the Composer artifact as package.zip
          script: composer archive -f zip --file package
        - name: upload
          # ${CNB_BRANCH} is the Tag name under the tag_push event, used as the artifact version
          script: curl --netrc -T package.zip "<CNB_COMPOSER_URL>upload/<vendor>/<package>/${CNB_BRANCH}"
```

> Ensure `composer.json` has `archive.exclude` configured to avoid packaging
> authentication info (see the composer.json example in "Local Command Line Push" above).
> Please use [Semantic Versioning](https://semver.org/).

### Push in Workspaces

Paste the following content into `.cnb.yml`. After committing, click the
**「Workspace」** button in the upper right corner of the repository page
to enter the development environment, then configure credentials and push in the terminal:

```yaml title=".cnb.yml"
$:
  vscode:
    - docker:
        image: docker.cnb.cool/examples/language/php-8.4
      services:
        - vscode
        - docker
```

```shell
# Configure credentials
printf "machine composer.cnbprod.alpha.qq.com\nlogin cnb\npassword %s\n" "${CNB_TOKEN}" > ~/.netrc
# Package and upload (replace <vendor>/<package>/<version> with actual values, e.g., monolog/monolog/3.8.1)
composer archive -f zip --file package
curl --netrc -T package.zip "<CNB_COMPOSER_URL>upload/<vendor>/<package>/<version>"
```

> Ensure `composer.json` has `archive.exclude` configured (see the example in "Local Command Line Push" above).

## Use Artifacts

### Pull Artifacts

After configuring credentials as described in \[Configure Pull Credentials]
(#configure-pull-credentials), use the following command to pull artifacts.

```shell
composer require monolog/monolog
```

### Delete Artifacts

Composer does not provide a delete command. Refer to [Deleting Artifacts](./intro.md#deleting-artifacts).

## FAQ

### Q1: Upload Artifact Error - No Permission

**Example:**

```shell
curl --netrc <CNB_COMPOSER_URL>upload/monolog/monolog/3.8.0 -T monolog.zip
{"errcode":16,"errmsg":"not authorized"}
```

**Solution:**

Refer to [Creating an Access Token](./intro.md#creating-an-access-token)
and [Configure Push Credentials](#configure-push-credentials)
to correctly configure credentials.

### Q2: Upload Artifact Error - Invalid Version Format

**Example:**

```shell
curl --netrc <CNB_COMPOSER_URL>upload/monolog/monolog/xxx3.8.0 -T monolog.zip
{"errcode":3,"errmsg":"validate [Version:xxx3.8.0] failed"}
```

**Solution:**

Use [Semantic Versioning](https://semver.org/).

### About Composer 1.x

The official source stopped supporting Composer 1.x on August 1, 2025.
The CNB Composer Artifact Registry recommends using Composer 2.x or later.

If you are still using Composer 1.x, you can update to the latest stable 2.x
version via the `composer self-update` command.
