Composer repositories serve PHP packages to composer require, install, update, show, search, outdated and audit (Composer 2). Hosted repositories take uploads of zip archives; proxy repositories cache Packagist or another Composer repository; groups combine them.
1. Add the repository
composer config repositories.depotex composer https://depotex.example.com/repository/my-space/php
composer config --global http-basic.depotex.example.com me "$DEPOTEX_TOKEN"
composer require acme/tools:^1.2
The token goes in your auth.json, not in the project. To get every Packagist package through Depotex too, point the repository at a proxy or group and turn Packagist off: composer config repositories.packagist.org false. The repository's Usage tab shows these commands with your address filled in.
2. Upload a version
Composer has no publish command, so versions are uploaded with an HTTP PUT (Publish permission) of a zip whose composer.json is at its root or in its single top folder, as git archive makes:
git archive --format=zip --prefix=tools/ v1.2.0 > tools-1.2.0.zip
curl -f -u "me:$DEPOTEX_TOKEN" -T tools-1.2.0.zip \
https://depotex.example.com/repository/my-space/php/packages/upload/acme/tools/1.2.0
- The archive's composer.json must name the package in the address, and its version, when it has one, must be the same. Composer's version rules apply: v1.0 and 1.0.0 are the same version.
- A version can never be replaced; delete it (Delete permission) to free it. Archives are at most COMPOSER_MAX_ARCHIVE_SIZE (100 MiB by default), within the installation's limit, for a repository without its own size limit. A repository's own size limit (its Largest artifact setting) replaces it, larger or smaller: that's how to change it for one repository.
- Only what belongs in repository metadata is served from composer.json: never its scripts or config.
- Branches (dev-main, 1.x-dev) are versions someone uploads; Depotex doesn't follow git.
3. Abandoned packages
On a version's page in the browser, people with Delete permission on a hosted repository can mark the package abandoned, optionally naming a replacement. Composer then warns everyone who installs it. This raises the composer.package.abandon event.
4. Repository settings
A Composer repository's Settings tab has a Composer section (repository admins); changes raise the composer.settings.update event:
| Setting | Applies to | What it does |
|---|---|---|
| Hosted packages hide upstream packages of the same name | Groups | On (the default): a package a hosted member has gets no versions from proxy members, so nobody can publish a newer version of an internal package's name on Packagist and have it picked up |
| Keep git sources in the metadata | Proxies | Off (the default): versions install from their archives, through Depotex only. On: composer install --prefer-source can clone from the upstream's git repositories |
| GitHub token | Proxies | Used only for archives hosted on GitHub (Packagist's are), to avoid GitHub's rate limits and reach private repositories. Stored encrypted and never shown again; a fine-grained read-only token is enough |
5. Versions and policies
- Each package version is a version in Depotex, compared as Composer compares them: cleanup policies, quotas, quarantine and the block list apply.
- Blocked versions, and versions you can't read, are left out of the metadata. Quarantined versions are left out when the repository hides quarantined versions; otherwise they're listed and their downloads refused.
- composer audit reads security advisories from a proxy's upstream; hosted repositories have none, and a group uses its first proxy member's.
Composer 2.8 doesn't read filter lists, which is how Depotex marks quarantined versions it still lists. For older Composer versions, turn on hiding quarantined versions in the repository's settings.
6. Proxy repositories
Add an upstream with the Packagist preset (https://repo.packagist.org) or another Composer 2 repository, allow it for the space, then create a proxy repository with it. Depotex reads the upstream's metadata and points every version's download at itself; each archive is fetched when first asked for, checked against the upstream's checksum when it gives one, and kept. Packagist's archives are on GitHub, so add a GitHub token in the settings above if you hit GitHub's rate limits. Search and the package list are forwarded to the upstream. Composer 1 repositories can't be proxied.
7. Groups
A Composer group merges the metadata of its members (the first member that has a version wins), serves each archive from the first member that has it, and sends uploads to the member its write rules choose by package and version.
8. In the artifact browser
A version's page shows what its composer.json says (type, licence, authors, support links, the PHP version and extensions it needs), its dependencies (require and require-dev), its README and whether the package is abandoned. The Install bar shows composer require.
9. Server settings
| Variable | Default | Description |
|---|---|---|
| COMPOSER_MAX_ARCHIVE_SIZE | 104857600 | Largest archive a hosted repository without its own size limit takes, in bytes (1 KiB–1 TiB), within the installation's limit. A repository's own size limit replaces it, larger or smaller |
10. Limits
- Composer 2.0 or later: Composer 1 (end of life since 2020) finds no packages.
- No composer publish (Composer has none) and no builds from git repositories, as Satis does.
- Only GitHub tokens for proxies: GitLab, Bitbucket and Private Packagist credentials aren't supported.
- Metadata has no Last-Modified, so Composer fetches each metadata file in full when it checks for updates.
- Search matches names and descriptions only.