Cargo repositories are Rust registries for cargo. Hosted repositories take cargo publish, cargo yank and cargo owner; proxy repositories cache crates.io or another sparse registry; groups combine them. Hosted crates can also have their docs (rustdoc) kept and served, and raw repositories can serve Rust toolchains to rustup.
1. Set up cargo
Add the registry to .cargo/config.toml (in the project, or ~/.cargo/config.toml), and give cargo an API token. Cargo sends its token only to registries that use the cargo:token credential provider, so turn it on as shown:
[registry]
global-credential-providers = ["cargo:token"]
[registries.depotex]
index = "sparse+https://depotex.example.com/repository/my-space/crates/"
export CARGO_REGISTRIES_DEPOTEX_TOKEN="$DEPOTEX_TOKEN" # or: cargo login --registry depotex
cargo add my-crate --registry depotex
cargo publish --registry depotex
- The token must be an API token (Profile → API tokens): cargo sends it without a user name, so a password won't do. cargo login opens your profile's tokens page.
- A dependency from the registry names it in Cargo.toml: my-crate = { version = "1.0", registry = "depotex" }.
- To fetch every crates.io crate through Depotex too, add [source.crates-io] with replace-with = "depotex", pointing depotex at a proxy or group.
- Cargo 1.68 or later is needed: Depotex serves the sparse index only, not the older git index.
With a Cargo group as the space's default, sparse+https://depotex.example.com/repository/my-space/cargo/ is one registry for your crates and crates.io's: use it for [registries] and for replacing crates.io, and cargo publish goes to the repository the group's write rules choose. The repository's Usage tab shows these snippets with your address and registry name filled in.
2. Publish, yank and owners
- Publish needs Publish permission. The crate is checked: a valid name (crates.io's rules; Rust's own names such as std and core are refused), a SemVer version, readable dependencies, and an archive whose Cargo.toml names the same crate and version. The largest crate is 10 MiB by default (CARGO_MAX_CRATE_SIZE), 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.
- A version can never be replaced: every Cargo.lock that uses it pins its checksum. New Cargo repositories publish once. Deleting a version (Delete permission) is the only way to free it.
- Names compare as cargo does: My_Crate and my-crate are one crate, kept under the spelling it was first published with.
- Yank (cargo yank --version 1.0.0, undo with --undo, or Yank this version and Undo the yank on the version's page in the browser): new lock files skip the version, projects that already use it keep building.
- Owners: whoever first publishes a crate owns it; cargo owner --add and --remove take Depotex user names or emails. A crate keeps at least one owner.
- Yanking and changing owners need Overwrite permission, or being an owner with Publish permission; repository admins can always. The browser's Yank shows to everyone who may yank, and asks before it acts.
- cargo search searches names, descriptions and keywords; a proxy forwards it to its upstream.
3. Repository settings
A Cargo repository's Settings tab has a Cargo section (repository admins):
| Setting | What it does |
|---|---|
| Only a crate's owners publish, yank and manage it | Off by default. On: only owners publish new versions of their crates, yank them and change their owners (and upload their docs). |
| Only repository admins publish new crate names | New names need an admin, or a reservation (below). New versions of existing crates are published as usual. |
| Reserved crate names | A name only its owners (and admins) can publish, before its first version exists. |
| Build docs for every published version | Queues a docs build for each new version (see Docs). |
| Docs size limit | The most a version's docs may take unpacked; empty uses the server's limit. |
| Hosted crates hide upstream crates of the same name (groups) | On by default: a crate any hosted member has gets no versions from proxy members, so a crate published on crates.io under one of your internal names can't reach your builds through the group. |
Changing these raises cargo.settings.update; yanking, owner changes, reservations and docs changes raise cargo.crate.update. Organization policies can refuse either.
4. Docs
Each version of a hosted crate can have its docs. Open them from the version's page in the browser (Open docs), or at https://depotex.example.com/repository/my-space/crates/docs/my-crate/latest/. Depotex checks that you can read the crate, then serves the docs in a sandbox, apart from the rest of Depotex, so their scripts can't reach your session.
While you read docs, the address in the browser holds a token that expires within 5 hours, and anyone with that address can read those docs until then. To share docs, share the …/docs/my-crate/latest/ address: it asks each reader to sign in.
- Upload cargo doc output (a .tar.gz or .zip of target/doc) with Publish permission: curl -f -H "Authorization: Bearer $DEPOTEX_TOKEN" --upload-file docs.tar.gz https://depotex.example.com/repository/my-space/crates/api/v1/docs/my-crate/1.0.0. Only the file types rustdoc writes are accepted, up to 100 MiB unpacked and 50,000 files by default.
- Or build them: with Build docs on, each new version is queued for a docs runner, which runs cargo doc --no-deps and uploads the result. Build docs (or Rebuild docs) on a version's page queues one by hand. The page shows the build's status and, when it fails, its log.
- Docs count toward the space's storage and are removed with their version.
5. Run a docs runner
Building docs runs a crate's build scripts and procedural macros, which can be any code, so Depotex never builds docs itself: a separate docs runner does, in a container you run apart from Depotex servers. Build its image from the Depotex source (apps/depotex/backend/cmd/cargo-doc-runner/Dockerfile) and run it with tight limits and network access to Depotex only:
docker run --rm --read-only --tmpfs /work:rw,exec,size=8g \
--memory 4g --cpus 2 --pids-limit 512 --cap-drop ALL --security-opt no-new-privileges \
--network depotex-only \
-e DEPOTEX_URL=https://depotex.example.com -e DEPOTEX_TOKEN=dpt_… \
-e DEPOTEX_REPOSITORIES=my-space/crates depotex-cargo-doc-runner
| Variable | Default | What it does |
|---|---|---|
| DEPOTEX_URL | — | The Depotex address |
| DEPOTEX_TOKEN | — | An API token with Publish permission on the repositories' docs |
| DEPOTEX_REPOSITORIES | — | Hosted Cargo repositories to build for: space/repository, comma-separated |
| DEPOTEX_DEPS_REGISTRY | The space's default Cargo group | Where dependencies come from (a sparse index address) |
| RUNNER_BUILD_TIMEOUT | 20m | The longest one build may run |
| RUNNER_POLL_INTERVAL | 15s | How often to look for queued builds |
| RUNNER_ONCE | false | Build at most one version and exit (one container per build) |
| RUNNER_NAME | Host name | Shown on builds |
Run as many runners as you like: each build goes to one of them. A runner that stops answering loses its build after the lease (10 minutes by default), and the build is tried again by another, up to 3 times.
6. Versions and policies
- Each crate version is a version in Depotex: it shows in the Versions tab, and cleanup policies, quotas, quarantine and the block list apply to it.
- Block-list ranges compare versions by SemVer; a group's write rules for releases and pre-releases go by the version (1.0.0-beta.1 is a pre-release).
- Blocked versions are left out of the index and their crates refused; quarantined versions too when the repository hides them.
7. Proxy repositories
Add an upstream with the crates.io preset (https://index.crates.io/) or another sparse registry's index address, allow it for the space, then create a proxy repository. Index files are re-checked after the metadata age; each crate is fetched when first asked for, checked against the checksum in the index, and kept. Crates are only fetched from the addresses the upstream's own config.json gives, and links to IP addresses or internal host names are refused. A proxy can also reach a Cargo repository of another Depotex (Depotex link).
8. In the artifact browser
Crates show by name, then their versions. The Overview shows the description, license, authors, owners, links, keywords, categories, minimum Rust version, edition, features, whether the version is yanked, and its docs; the README tab shows the crate's README; Dependencies lists normal, optional, build and dev dependencies. The quick facts show cargo add and the Cargo.toml line for the version.
9. Server settings
| Variable | Default | What it does |
|---|---|---|
| CARGO_MAX_CRATE_SIZE | 10485760 (10 MiB) | The largest crate a repository without its own size limit takes, in bytes, within the installation's limit. A repository's own size limit replaces it, larger or smaller |
| CARGO_DOCS_MAX_SIZE | 104857600 (100 MiB) | A version's docs, unpacked, for repositories without their own limit |
| CARGO_DOCS_MAX_FILES | 50000 | Files in a version's docs |
| CARGO_DOCS_BUILD_LEASE | 10m | How long a runner holds a build before another may take it (runners renew it while they work) |
| CARGO_DOCS_BUILD_ATTEMPTS | 3 | How often a build whose runner stopped answering is tried |
Set them the same on every server of a cluster.
10. Limits
- Sparse index only: cargo before 1.68 and tools that read only git indexes can't use Depotex registries.
- A crate's dependencies on other registries keep those registries' addresses: whoever builds it configures each of them. Groups don't rewrite them.
- No trusted publishing yet: publishing needs an API token.
- Docs are built without dependencies (--no-deps), so links to other crates' items don't resolve, and there's no search across crates. Only hosted crates have docs (no docs.rs proxy), and building needs a runner you deploy.
- Search matches words in names, descriptions and keywords, sorted by name; there are no download counts or categories pages.