Registry Configuration
Embedded registry#
The mock server embeds an OCI registry that shares the mock container’s internal port, auto-configured with CI_REGISTRY_* variables. docker build/docker push against $CI_REGISTRY work out of the box.
The registry data lives on the glci-registry Docker volume, so it persists across daemon restarts.
Managing the registry#
# List images stored locally
glci registry list
# List images for a specific project
glci registry list --project group/myproject
# Show storage statistics
glci registry stats
# Pull an image from the local registry into Docker
glci registry pull registry.gitlab.com/group/project/app:latest
# Pull and retag with a prefix
glci registry pull registry.gitlab.com/group/project/app:latest local
# Clean up stored registry blobs
glci registry clean
# Clean only a specific project's images
glci registry clean --project group/myproject
Disabling or replacing the registry#
Disable the embedded registry with --no-registry, or point to an external registry:
glci run --no-registry
glci run --registry registry.gitlab.com --registry-user my-user --registry-password my-token
The external registry can also be configured in ~/.glci/config.toml (global config only):
[registry]
url = "registry.gitlab.com"
username = "my-user"
password = "$REGISTRY_PASSWORD" # env var reference supported
Pull-through cache#
The embedded registry acts as a read-through cache for a configurable list of upstream registries (defaults to registry.gitlab.com,registry-1.docker.io). Manifest/blob GETs that miss locally are fetched from the first upstream that has them, cached in the volume, and served – so repeat pulls stay on localhost after the first fetch.
This is especially useful for DinD pipelines: the DinD daemon inside each pipeline is automatically configured as a pull-through mirror of the embedded registry, so even docker pull inside DinD benefits from the local cache.
Push-through mirror#
Optionally mirror every image your pipeline pushes to CI_REGISTRY onward to the upstream registry (usually registry.gitlab.com).
Enable globally:
# ~/.glci/config.toml
[registry]
push_through = true
[registry.upstream]
username = "deploy-token"
password = "$REGISTRY_WRITE_TOKEN" # env var reference
Or per-run:
glci run --push-through
Semantics:
- Fires synchronously as part of each manifest
PUT— upstream failures surface as 5xx todocker push - Scoped to the current project — other projects are not mirrored
- Idempotent via upstream HEAD probes
- Credentials need
write_registryscope
TLS and insecure registries#
The embedded registry uses a self-signed TLS certificate. glci automatically:
- Generates a CA certificate and stores it in
~/.glci/registry-ca/ - Mounts the CA cert into job containers at
/glci-registry-certs/ca.crt - Updates system CA bundles inside containers (
/etc/ssl/certs/ca-certificates.crt,/etc/ssl/cert.pem) - Configures Docker’s
certs.dfor the registry hostname - Injects a
buildkitd.tomlmarking the mock registry as insecure (HTTP) for DinD builds
Configure additional TLS SANs (e.g., for custom hostnames or remote Docker hosts):
# ~/.glci/config.toml
[tls]
extra_sans = ["my-custom-host", "192.168.1.100"]
cert_validity = "48h" # default: 24h
Docker Hub authentication#
Host Docker credentials from ~/.docker/config.json are automatically merged into each job’s DOCKER_AUTH_CONFIG environment variable. This means authenticated Docker Hub rate limits apply (200 pulls/6h free, unlimited paid) instead of the anonymous 100/6h limit:
docker login
glci run