Skip to main content

Composer CLI Usage

Use the Composer CLI to install packages from Nexus Repository and clear the local Composer cache after creating and configuring a Composer repository. For more CLI commands, refer Composer CLI commands.

Install Composer Packages

After configuring Composer to use a Nexus Composer repository, run the following command:

composer install

Run the command from the Composer project that is configured to use the Nexus Repository URL in composer.json. Composer installs the packages using the configured Nexus Composer repository.

Clear the Local Cache to Pull From Nexus Repository

Composer caches dependencies to speed up builds and reduce network usage. Clear the local cache when Composer must pull package content from Nexus Repository again.

composer clear-cache

Run the command in the local Composer environment where you want to clear cached dependencies.

Upload Composer Packages

While uploading packager to a Composer hosted repository, make sure the archive contains a valid composer.json file with name value using the vendor/package format and the package archive is a .zip or .tar.gz file. To upload components through UI, refer to Uploading Components.

Package Organization

Composer hosted repositories use the following package and metadata path structure:

/repository/<REPOSITORY_NAME>/
├── packages.json
├── p2/
│   └── <VENDOR>/
│       └── <PACKAGE>.json
└── <VENDOR>/
    └── <PACKAGE>/
        └── <VERSION>/
            └── <VENDOR>-<PACKAGE>-<VERSION>

Where,

  • <REPOSITORY_NAME> - Your hosted Composer repository name.

  • <VENDOR> - Normalized package vendor.

  • <PACKAGE> - Normalized package name.

  • <VERSION> - Package version.

Nexus Repository derives the vendor, package, and storage path from composer.json. Binary archives are stored without a file extension.

Package Name Normalization

Nexus Repository normalizes Composer package names as follows:

  • Converts uppercase characters to lowercase.

  • Preserves underscores (_).

  • Does not allow leading or trailing separators.

  • Does not allow consecutive separators, except for -- in the package portion of the name.

The following examples show package-name normalization:

Package Name

Normalized Package Name

Symfony/Console

symfony/console

My_Vendor/My_Package

my_vendor/my_package

COMPANY/PRODUCT

company/product

Version Handling

For a Components REST API upload, provide the request version through the version form field. For a direct repository upload, provide the request version through the version query parameter.

The following rules apply:

Version in composer.json

Version in Upload Request

Result

Provided

Not provided

Nexus Repository uses the version from composer.json.

Not provided

Provided

Nexus Repository uses the version from the upload request.

Provided

Same value provided

The upload is accepted.

Provided

Different value provided

The upload is rejected with 400 Version mismatch.

Not provided

Not provided

The upload is rejected.

Neither version source overrides the other. When both sources provide a version, the values must match exactly.

Upload With The Components REST API

Use the following endpoint for automated uploads and CI/CD workflows.

POST /service/rest/v1/components?repository={repository-name}

The following fields are available:

Field

Type

Required

Description

asset

File

Yes

Composer package archive in .zip or .tar.gz format.

version

String

Conditional

Package version. Provide this field when composer.json does not contain a version. If both locations provide a version, the values must match exactly.

Use the following example when the version is defined in composer.json:

curl -u admin:admin123 \
  -F "[email protected];type=application/zip" \
  "http://example.nexus.com/service/rest/v1/components?repository=composer-hosted"

Upload With HTTP PUT

Use the following PUT endpoint to upload packages directly to a specific path in the repository:

PUT /repository/{repository-name}/

Use the following example when the version is defined in composer.json:

 curl -u admin:admin123 -X PUT \
  -H "Content-Type: application/zip" \
  --data-binary @acme-mypackage-1.0.0.zip \
  "http://example.nexus.com/repository/composer-hosted/"

When composer.json does not contain a version, supply it through the version query parameter as shown in the example:

 curl -u admin:admin123 -X PUT \
  -H "Content-Type: application/zip" \
  --data-binary @acme-mypackage-1.0.0.zip \
  "http://example.nexus.com/repository/composer-hosted/?version=1.0.0"

GitLab CI/CD Integration

Use the following syntax for the Components REST API upload step in a GitLab CI/CD pipeline:

curl -u "${NEXUS_USER}:${NEXUS_PASSWORD}" \
  -F "asset=@${PACKAGE_FILE};type=application/zip" \
  "${NEXUS_URL}/service/rest/v1/components?repository=${NEXUS_REPO}"

Where,

  • NEXUS_USER - Your Nexus Repository username or user token name code.

  • NEXUS_PASSWORD - Your Nexus Repository password or user token pass code.

  • PACKAGE_FILE - Package archive generated by the build job.

  • NEXUS_URL - Nexus Repository base URL.

  • NEXUS_REPO - Your Composer hosted repository name.

Example:

stages:
  - build
  - publish

variables:
  NEXUS_URL: "https://example.nexus.com"
  NEXUS_REPO: "composer-hosted"
  # NEXUS_USER and NEXUS_PASSWORD should be set as GitLab CI/CD variables

build:package:
  stage: build
  image: composer:2
  script:
    # Create a valid composer.json if not exists
    - |
      if [ ! -f composer.json ]; then
        cat > composer.json <<EOF
      {
          "name": "mycompany/${CI_PROJECT_NAME}",
          "version": "${CI_COMMIT_TAG:-${CI_COMMIT_SHORT_SHA}}",
          "description": "Package built from ${CI_PROJECT_NAME}",
          "type": "library"
      }
      EOF
      fi
    # Create the package archive
    - mkdir -p package
    - cp -r src composer.json package/
    - cd package && zip -r ../${CI_PROJECT_NAME}-${CI_COMMIT_TAG:-${CI_COMMIT_SHORT_SHA}}.zip .
    - cd ..
  artifacts:
    paths:
      - ${CI_PROJECT_NAME}-${CI_COMMIT_TAG:-${CI_COMMIT_SHORT_SHA}}.zip
    expire_in: 1 hour

publish:nexus:
  stage: publish
  image: curlimages/curl:latest
  dependencies:
    - build:package
  script:
    - |
      PACKAGE_FILE="${CI_PROJECT_NAME}-${CI_COMMIT_TAG:-${CI_COMMIT_SHORT_SHA}}.zip"

      # Upload to Nexus Repository
      curl -u "${NEXUS_USER}:${NEXUS_PASSWORD}" \
        -F "asset=@${PACKAGE_FILE};type=application/zip" \
        "${NEXUS_URL}/service/rest/v1/components?repository=${NEXUS_REPO}"

      echo "Package uploaded successfully to ${NEXUS_REPO}"
  rules:
    - if: $CI_COMMIT_TAG
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  environment:
    name: nexus
    url: ${NEXUS_URL}/repository/${NEXUS_REPO}

Configure the following GitLab CI/CD variables:

Variable

Description

Protected

NEXUS_URL

Nexus Repository base URL, such as https://example.nexus.com.

No

NEXUS_USER

Nexus Repository username with upload permissions.

Yes

NEXUS_PASSWORD

Nexus Repository password or user token.

Yes

NEXUS_REPO

Composer hosted repository name.

No