C++ teams reach for Conan 2 when CMake presets and compiler matrices already live in Git, yet cross-border latency still turns every recipe fetch into a flaky stage. This tutorial assumes shared remote Mac runners on Apple Silicon: you need auditable remotes, bounded parallel downloads, isolated package and compiler caches, and a conan.lock that survives code review. Browse the MacPull homepage, the blog index, and related C++ CI notes such as the vcpkg + CMake FetchContent matrix—all readable without logging in.

Scenario prerequisites

Pin the Conan 2 minor release in your runner image or bootstrap script; mixing clients across jobs corrupts local caches when metadata layouts shift. Commit profiles (os, arch, compiler version, compiler.cppstd, and macOS SDK expectations) next to conanfile.py or conanfile.txt. Export CONAN_HOME to fast APFS-backed storage that is unique per tenant or pipeline—never reuse a warm ~/.conan2 owned by another team on the same host unless you share a deliberate read-only cache contract.

Networking should list every HTTPS host Conan will hit: remote APIs, recipe sources, and any Git endpoints declared through tools.scm helpers. If security requires a man-in-the-middle TLS proxy, install its root into the system keychain before debugging download failures you misattribute to ConanCenter.

Decide who may regenerate conan.lock: only trusted bots, or any contributor with mandatory review. The workflow you pick belongs in the same runbook as CONAN_HOME, because stray lock refreshes from ad hoc laptops are how teams lose binary identity across regions.

Mirror endpoint comparison table

Most production pipelines replace public defaults with a mirror that preserves Conan’s REST layout. Artifactory and other hubs expose a Conan package index; your job is to ensure every reference resolves through the same logical remote name in dev and CI. When developers sit on dual-stack networks while runners use IPv4-only egress, fail fast with an explicit connectivity probe to your mirror hostname before Conan starts—split DNS surprises look like mysterious 403 cycles in the client log.

Endpoint pattern Typical use Operational note
https://center2.conan.io (ConanCenter remote) Quickstarts and OSS libraries without compliance friction Expect regional latency; pair with aggressive core.download tuning or a pull-through cache if builds cross oceans daily.
Virtual remote on Artifactory / Nexus (single URL) Teams that must aggregate public upstreams plus private packages Keep one enabled remote in CI to avoid ambiguous resolution when both the virtual and its backing remotes stay visible.
Dedicated on-prem mirror (read-through) Regions with unstable transit to public clouds Validate blob checksums after mirror refreshes; schedule brownout drills so Conan failures are not confused with recipe bugs.

Executable remote audit and switch:

conan remote list

# Example: add your mirror first in priority order (adjust URL to your hub)
conan remote add company-mirror https://artifacts.example.com/artifactory/api/conan/conan-virtual --index 0

# Point the legacy community remote at the mirror, or disable it when traffic must stay private
conan remote update conancenter --url https://artifacts.example.com/artifactory/api/conan/conancenter-proxy
# or: conan remote disable conancenter

conan remote login company-mirror "${CONAN_USER}" -p "${CONAN_PASSWORD}"

Concurrency and timeout thresholds

Conan 2 centralizes transport tuning in global.conf (or per-invocation --core-conf / -cc). Start from modest parallelism on shared hosts, then measure p95 download time rather than chasing peak threads.

  • core.download:parallel — concurrent artifact downloads (try 4–8 on busy pools, 8–16 only when NVMe and uplink stay healthy).
  • core.download:retry — retries for server-side pulls (often 2–4).
  • core.download:retry_wait — seconds between attempts (try 3–8; combine with job-level backoff for wide outages).

For HTTP stacks beneath Conan you may also tune core.net.* entries documented for your minor version; keep changes in Git via conan config install so every remote Mac inherits the same ladder.

# Write once to the job-local CONAN_HOME
mkdir -p "${CONAN_HOME}"
cat >> "${CONAN_HOME}/global.conf" <<'EOF'
core.download:parallel=8
core.download:retry=3
core.download:retry_wait=5
EOF

# One-off override without touching files
conan install . --lockfile=conan.lock \
  -cc core.download:parallel=6 \
  -cc core.download:retry=4

conan config show "core.download:*"

Remote Mac CI cache directory and disk watermark

Package blobs and metadata live under ${CONAN_HOME}/p and related structures; treat the whole CONAN_HOME prefix as disposable per job when correctness matters more than warm caches. For compiler repeatability, pair Conan with ccache (or your toolchain’s equivalent) so link-heavy stages do not thrash APFS when multiple pipelines overlap.

export CONAN_HOME="${CI_PROJECT_DIR:-$PWD}/.conan2"
export CCACHE_DIR="${CI_PROJECT_DIR:-$PWD}/.ccache"
mkdir -p "$CONAN_HOME" "$CCACHE_DIR"
export CC="ccache clang"
export CXX="ccache clang++"

du -sh "$CONAN_HOME" "$CCACHE_DIR" 2>/dev/null || true
ccache --show-stats

# Fail fast when the volume is nearly full (macOS df "Capacity" is percent used)
USED_PCT="$(df -h "$CONAN_HOME" | awk 'NR==2 { gsub(/%/,"",$5); print $5 }')"
if [ "${USED_PCT:-101}" -gt 88 ]; then
  echo "Low free disk headroom (Capacity ${USED_PCT}% used on ${CONAN_HOME})"
  exit 42
fi

Set team policy for watermarks: for example skip optional prefetch when free space is under twelve percent, run conan cache clean for stale revisions only, and schedule host-wide pruning when multiple tenants share one disk.

Failure retry and consistency checks

Wrap conan install in a shell retry loop for HTTP 5xx and TLS resets, but stop after a small cap so a broken mirror does not busy-loop the shared runner. When checksum errors repeat for the same reference, escalate to the mirror operator rather than only deleting caches.

Lockfile acceptance: generate conan.lock on a trusted workstation or protected pipeline, commit it, and require PRs that change dependencies to include a lockfile diff. CI should install with --lockfile and fail when someone attempts a floating resolve without updating the lock.

Policy Best when Trade-off
Strict --lockfile + --build=missing Release branches and artifact promotion Requires regeneration whenever profiles or options change; errors are explicit.
Lockfile diff gated on main only High-churn feature teams May let short-lived branches drift; mitigate with merge-queue bots that refresh locks.
Optional conan graph info smoke Catching accidental remote renames Adds seconds to each build; keep JSON output for narrow assertions.
set -euo pipefail
attempt=1
max_attempts=4
until conan install . --lockfile=conan.lock --build=missing; do
  attempt=$((attempt + 1))
  [ "$attempt" -le "$max_attempts" ] || exit 1
  sleep $((attempt * 3))
done

# Record expected integrity in Git; assert cleanliness in CI
shasum -a 256 conan.lock
git diff --exit-code -- conan.lock

conan graph info . --lockfile=conan.lock --format=json > graph.json

For a complementary take on Rust lockfiles on the same class of runners, see the Cargo mirror and lockfile matrix. Broader cache hygiene across Git, npm, and Homebrew appears in the remote Mac cache strategy guide.

FAQ

Can I point different jobs at different remotes? Yes, but document it: mixed remote lists between developer laptops and CI are the fastest way to get “missing binary” escalations that are really index drift.

Should download parallelism match Make or Ninja job counts? No. core.download:parallel governs network layers; compile parallelism belongs in CMake or -j settings. Raise them independently after measuring APFS pressure.

What if conan graph info disagrees with a solved IDE graph? Ensure the IDE uses the same profile path and CONAN_HOME. IDEs often skip lockfiles—load conan.lock into your workflow before trusting visual dependency views.

Summary

Treating remotes, download knobs, and lockfiles as one policy surface keeps Conan predictable on shared remote Mac pools. Prove settings on a dedicated Apple Silicon host, then roll the same global.conf bundle everywhere.

Continue to the homepage, compare plans and purchase a node, read the help center, or return to the technical blog—no account is required to browse these pages.