Skip to content

Configure client tools for package formats

How to configure Maven, Gradle, pip, Docker, and npm for Craftifact, including context path, repository name, and token authentication.

Quick path

  1. Identify the public base URL of your instance, for example https://packages.example.com.
  2. Identify the repository name you want to use, for example libs-release.
  3. Generate a suitable user or robot token.
  4. Build the correct repository URL in the client from context path and repository name.
  5. Store the token in the client either as a bearer token or as the password for basic auth.

Customize snippets

Enter your instance and repository name here. The snippets below on this page update automatically.

https://

Example: packages.example.com

Example: libs-release

Base URL: https://packages.example.com Repo: libs-release

URL pattern for repository families

In Craftifact, the URL always combines base URL, context path, and repository name.

For the currently supported families, the base patterns are:

  • Maven: https://<instance>/repository/maven/<repo-name>/
  • Gradle: https://<instance>/repository/maven/<repo-name>/
  • Python: https://<instance>/repository/python/<repo-name>/simple/
  • npm: https://<instance>/repository/npm/<repo-name>/
  • OCI: https://<instance>/v2/<repo-name>/...
  • Go beta: support details are still being finalized.

For Docker commands, you usually do not write out the v2 context path yourself. The client uses it internally, while you work with host, repository name, and image path.

The configurator above sets these values automatically:

  • base URL such as https://packages.example.com
  • instance host such as packages.example.com
  • repository name such as libs-release

The remaining placeholders in the snippets are:

  • TOKEN as the generated API or robot token
  • ROBOT_ID such as acceptance-test

Maven and Gradle

For Maven and Gradle, you use the same repository context path:

URL
https://packages.example.com/repository/maven/libs-release/
Maven

A simple settings.xml example with a bearer token looks like this:

settings.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
  <servers>
    <server>
      <id>craftifact</id>
      <configuration>
        <httpHeaders>
          <property>
            <name>Authorization</name>
            <value>Bearer ${env.CRAFTIFACT_TOKEN}</value>
          </property>
        </httpHeaders>
      </configuration>
    </server>
  </servers>
</settings>

You can then deploy to the repository like this:

mvn deploy
mvn deploy \
  -s settings.xml \
  -DaltDeploymentRepository=craftifact::https://packages.example.com/repository/maven/libs-release/
Gradle

Example build.gradle configuration with a bearer token in the HTTP header:

build.gradle
repositories {
  maven {
    url = uri("https://packages.example.com/repository/maven/libs-release/")
    credentials(HttpHeaderCredentials) {
      name = "Authorization"
      value = "Bearer ${System.getenv('CRAFTIFACT_TOKEN')}"
    }
    authentication {
      header(HttpHeaderAuthentication)
    }
  }
}

For publishing, the same pattern works in publishing.repositories:

publishing
publishing {
  repositories {
    maven {
      url = uri("https://packages.example.com/repository/maven/libs-release/")
      credentials(HttpHeaderCredentials) {
        name = "Authorization"
        value = "Bearer ${System.getenv('CRAFTIFACT_TOKEN')}"
      }
      authentication {
        header(HttpHeaderAuthentication)
      }
    }
  }
}

pip and Poetry

For Python clients, the simple index URL is:

Simple index URL
https://packages.example.com/repository/python/libs-release/simple/
pip

An example pip.conf using basic auth:

pip.conf
[global]
index-url = https://ROBOT_ID:TOKEN@packages.example.com/repository/python/libs-release/simple/

If you prefer the placeholder __token__ instead of the robot ID, this also works:

Alternative
https://__token__:TOKEN@packages.example.com/repository/python/libs-release/simple/

The robot ID is still preferable because it keeps the token owner easier to identify later.

Poetry

For installs, add a source using the same simple index URL:

Add source
poetry source add --priority=primary craftifact \
  https://packages.example.com/repository/python/libs-release/simple/

Then configure credentials separately:

Credentials
poetry config http-basic.craftifact ROBOT_ID TOKEN

For publishing, also configure the upload repository URL without simple/:

Publishing
poetry config repositories.craftifact \
  https://packages.example.com/repository/python/libs-release/
poetry publish --build --repository craftifact

Here too, __token__ would work instead of ROBOT_ID. The robot ID remains the more readable option.

Docker

For OCI, the technical context path is always v2, but Docker handles that internally. For login, authenticate against the registry host, not an explicit /v2/ URL.

docker login
printf '%s' "$TOKEN" | docker login packages.example.com -u ROBOT_ID --password-stdin

You then address an image through host, repository name, and image path:

Image name
packages.example.com/libs-release/IMAGE_PATH:TAG

Example:

docker pull / push
docker pull packages.example.com/libs-release/demo/app:1.0.0
docker push packages.example.com/libs-release/demo/app:1.0.0

That means internally:

  • host: packages.example.com
  • repository name: libs-oci
  • image path: demo/app
  • API path used by the client: /v2/

npm

For npm, the registry URL is:

Registry URL
https://packages.example.com/repository/npm/libs-release/

A minimal .npmrc example:

.npmrc
registry=https://packages.example.com/repository/npm/libs-release/
always-auth=true
//packages.example.com/repository/npm/libs-release/:_authToken=TOKEN

If you use scoped packages, the base URL stays the same. Only the package name later includes the scope, for example @acme/demo.

Practical notes

  • Not every client expresses bearer and basic auth equally well, so prefer the form that fits the tool.
  • For Docker, host-level login is expected even though the registry API lives under v2.
  • For Python installs, simple/ is part of the URL and must not be omitted.
  • For Poetry publishing, use the repository URL without simple/.