Vetrix Docs

Admin: Mirror Configuration

This document covers instance-level mirror settings and operational guidance for Vetrix administrators.

Runtime settings

Key Default Description
mirror.enabled true Enable or disable mirroring instance-wide
mirror.max_per_repo 5 Maximum number of mirrors per repository
mirror.sync_interval_min 15 Minimum allowed sync interval in minutes (per-repo setting cannot go lower)
mirror.sync_interval_default 60 Default sync interval when creating a mirror without specifying one

Updating a setting

curl -X PUT https://<vetrix-host>/api/v1/admin/settings/mirror.enabled \
  -H "Authorization: Bearer <admin-token>" \
  -H "Content-Type: application/json" \
  -d '"false"'

Mirror scheduler

The mirror sync scheduler runs as a goroutine within the Vetrix server process. It polls the pull_mirrors table every minute to find mirrors whose next sync time has passed, then enqueues sync jobs.

Each sync job:

  1. Fetches from the remote using git fetch --prune
  2. Updates all local refs (force-update)
  3. Records last_sync_at and clears or sets last_error

Sync jobs are serialized per-repository to prevent concurrent fetches from the same remote.

Credential encryption

Mirror credentials (passwords and SSH private keys) are encrypted at rest using AES-256-GCM with a key derived from MIRROR_ENC_KEY (environment variable, 32-byte hex string).

Generate a key:

openssl rand -hex 32

Set the key before starting the server:

export MIRROR_ENC_KEY=<64-hex-character-string>

If MIRROR_ENC_KEY is not set, the server will refuse to start when any mirrors with stored credentials exist. When the variable is unset and no credentialed mirrors are present, the server still boots — but creating a new mirror with a credential fails until the key is configured.

Key rotation: There is no automated key rotation. To rotate:

  1. Export all mirror credentials from the database (decrypt with old key).
  2. Re-encrypt with the new key.
  3. Replace the key and restart.

Legacy zero-key mirrors

Older Vetrix deployments stored every mirror credential under an all-zero 32-byte AES key (the Services.MirrorEncKey field was never populated from the environment). Any DB dump from that window should be treated as plaintext-equivalent. To migrate a running instance forward:

  1. Rotate every credential upstream first (GitHub tokens, Bitbucket app passwords, deploy keys, etc.). Assume the old values are compromised.
  2. With the server stopped, delete the affected rows:
    UPDATE pull_mirrors SET credential_ref = '' WHERE credential_ref <> '';
    UPDATE push_mirrors SET credential_ref = '' WHERE credential_ref <> '';
    
  3. Set MIRROR_ENC_KEY to a freshly generated 64-char hex key.
  4. Start the server and re-enter the (newly rotated) credentials through the repository's mirror settings page — they will be sealed under the real key.

Disk impact

Pull mirrors store all fetched refs locally. A mirrored repository occupies the same disk space as the upstream repository, plus any local commits not present upstream.

Monitor disk usage:

curl https://<vetrix-host>/api/v1/admin/health \
  -H "Authorization: Bearer <admin-token>"
# Check disk.used_pct

For large mirrors (>10 GB), configure git.gc_cron to run repository garbage collection periodically:

[git]
gc_cron = "0 3 * * *"  # 3 AM daily

Failed mirrors

Mirrors that fail 3 consecutive syncs are marked error and paused. The last error message is stored in last_error.

To view failed mirrors across all repositories:

-- Run directly on the database
SELECT r.full_name, pm.remote_url, pm.last_error, pm.last_sync_at
FROM pull_mirrors pm
JOIN repositories r ON r.id = pm.repo_id
WHERE pm.status = 'error'
ORDER BY pm.last_sync_at DESC;

To resume a failed mirror, an admin or repo maintainer must force-sync it:

curl -X POST https://<vetrix-host>/api/v1/repos/<owner>/<repo>/mirrors/<id>/sync \
  -H "Authorization: Bearer <token>"

A successful sync clears the error and resets the retry counter.

Disabling mirroring instance-wide

During maintenance or storage pressure, disable all mirror syncing without deleting mirror configurations:

curl -X PUT https://<vetrix-host>/api/v1/admin/settings/mirror.enabled \
  -H "Authorization: Bearer <admin-token>" \
  -d '"false"'

Existing mirror configs are preserved. Syncing resumes when the setting is re-enabled.