Skip to content

Commit 776f263

Browse files
update example and add regsync
Signed-off-by: Craig <[email protected]>
1 parent 69bc8ae commit 776f263

File tree

1 file changed

+135
-25
lines changed

1 file changed

+135
-25
lines changed

content/manuals/dhi/how-to/mirror.md

Lines changed: 135 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ repository to mirror.
124124

125125
## Mirror from Docker Hub to another registry
126126

127+
> [!IMPORTANT]
128+
>
129+
> To continue receiving image updates and preserve access to Docker Hardened
130+
> Images, ensure that any copies pushed to other registries remain private.
131+
127132
After you've mirrored a Docker Hardened Image repository to your organization's
128133
namespace on Docker Hub, you can optionally mirror it to another container
129134
registry, such as Amazon ECR, Google Artifact Registry, GitHub Container
@@ -134,40 +139,145 @@ You can use any standard workflow to mirror the image, such as the
134139
API](/reference/api/registry/latest/), third-party registry tools, or CI/CD
135140
automation.
136141

137-
However, to preserve the full security context, including signatures and
138-
attestations, you must also copy its associated OCI artifacts. Docker
139-
Hardened Images store the image layers on Docker Hub (`docker.io`) and the
140-
signed attestations in a separate registry (`registry.scout.docker.com`).
142+
However, to preserve the full security context, including attestations, you must
143+
also mirror its associated OCI artifacts. Docker Hardened Images store the image
144+
layers on Docker Hub (`docker.io`) and the signed attestations in a separate
145+
registry (`registry.scout.docker.com`).
141146

142147
To copy both, you can use [regctl](https://regclient.org/cli/regctl/), an
143148
OCI-aware CLI that supports mirroring images along with attached artifacts such
144-
as SBOMs, vulnerability reports, and SLSA provenance.
149+
as SBOMs, vulnerability reports, and SLSA provenance. For ongoing synchronization,
150+
you can use [regsync](https://regclient.org/cli/regsync/).
151+
152+
### Example mirroring with regctl
153+
154+
The following example shows how to mirror a specific tag of a Docker Hardened
155+
Image from Docker Hub to another registry, along with its associated
156+
attestations using `regctl`. You must [install
157+
`regctl`](https://github.com/regclient/regclient) first.
158+
159+
1. Set environment variables for your specific environment. Replace the
160+
placeholders with your actual values.
161+
162+
```console
163+
$ export DOCKER_USERNAME="YOUR_DOCKER_USERNAME"
164+
$ export DOCKER_PAT="YOUR_DOCKER_PAT"
165+
$ export DEST_REG="registry.example.com"
166+
$ export DEST_REPO="mirror/dhi-python"
167+
$ export SRC_REPO="docker.io/<your-org>/dhi-python"
168+
$ export SRC_TAG="3.13-alpine3.21"
169+
```
170+
171+
2. Sign in via regctl to Docker Hub, the Scout registry that contains
172+
the attestations, and your destination registry.
173+
174+
```console
175+
$ regctl registry login -u "$DOCKER_USERNAME" --pass-stdin docker.io
176+
$ regctl registry login -u "$DOCKER_USERNAME" --pass-stdin registry.scout.docker.com
177+
$ regctl registry login "$DEST_REG
178+
```
179+
180+
3. Mirror the image by digest from Docker Hub to your destination registry.
181+
182+
First, get a digest for a specific tag and platform. For example, `linux/amd64`.
183+
184+
```console
185+
DIGEST="$(regctl manifest head "${SRC_REPO}:${SRC_TAG}" --platform linux/amd64)"
186+
```
187+
188+
Then, copy the image by digest to ensure you get the exact same image.
189+
190+
```console
191+
regctl image copy \
192+
"${SRC_REPO}@${DIGEST}" \
193+
"${DEST_REG}/${DEST_REPO}@${DIGEST}"
194+
```
195+
196+
4. Mirror the attestations from the Scout registry to your target registry using
197+
`--referrers` and referrer endpoints:
198+
199+
```console
200+
$ regctl image copy \
201+
--referrers \
202+
--referrers-src "registry.scout.docker.com/<your-org>/dhi-python" \
203+
--referrers-tgt "${DEST_REG}/${DEST_REPO}" \
204+
"registry.scout.docker.com/<your-org>/dhi-python@${DIGEST}" \
205+
"${DEST_REG}/${DEST_REPO}@${DIGEST}"
206+
```
207+
208+
5. Verify that artifacts were preserved.
209+
210+
List attached artifacts (SBOM, provenance, VEX, vuln reports).
211+
212+
```console
213+
$ regctl artifact list "${DEST_REG}/${DEST_REPO}@${DIGEST}"
214+
```
215+
216+
If you use Docker Scout:
217+
218+
```console
219+
$ docker scout attest list "registry://${DEST_REG}/${DEST_REPO}@${DIGEST}"
220+
```
221+
222+
### Example ongoing mirroring with regsync
223+
224+
regsync automates pulling from your organizations mirrored DHI repositories on
225+
Docker Hub and pushing to your external registry including attestations. It
226+
reads a YAML configuration file and can filter tags.
227+
228+
The following example uses a `regsync.yaml` file that syncs Node 24.* and Python
229+
3.12.* Debian 13 variants, excluding Alpine and Debian 12.
230+
231+
```yaml{title="regsync.yaml"}
232+
version: 1
233+
# Optional: inline creds if not relying on prior CLI logins
234+
# creds:
235+
# - registry: docker.io
236+
# user: <your-docker-username>
237+
# pass: "{{file \"/run/secrets/docker_token\"}}"
238+
# - registry: registry.scout.docker.com
239+
# user: <your-docker-username>
240+
# pass: "{{file \"/run/secrets/docker_token\"}}"
241+
# - registry: registry.example.com
242+
# user: <service-user>
243+
# pass: "{{file \"/run/secrets/dest_token\"}}"
244+
245+
sync:
246+
- source: docker.io/<your-org>/dhi-node
247+
target: registry.example.com/mirror/dhi-node
248+
type: repository
249+
fastCopy: true
250+
referrers: true
251+
referrerSource: registry.scout.docker.com/<your-org>/dhi-node
252+
referrerTarget: registry.example.com/mirror/dhi-node
253+
tags:
254+
allow: [ "24.*" ]
255+
deny: [ ".*alpine.*", ".*debian12.*" ]
256+
257+
- source: docker.io/<your-org>/dhi-python
258+
target: registry.example.com/mirror/dhi-python
259+
type: repository
260+
fastCopy: true
261+
referrers: true
262+
referrerSource: registry.scout.docker.com/<your-org>/dhi-python
263+
referrerTarget: registry.example.com/mirror/dhi-python
264+
tags:
265+
allow: [ "3.12.*" ]
266+
deny: [ ".*alpine.*", ".*debian12.*" ]
267+
```
145268

146-
The following example uses `regctl` to mirror a DHI and then its attestations to a
147-
private registry:
269+
To do a dry run with the configuration file, you can run the following command.
270+
You must [install `regsync`](https://github.com/regclient/regclient) first.
148271

149272
```console
150-
$ regctl \
151-
--host "reg=docker.io,user=$DOCKER_USERNAME,pass=$DOCKER_PASSWORD_OR_PAT" \
152-
--host "reg=registry.example.com" \
153-
image copy \
154-
docker.io/docs/dhi-python@sha256:25c9... \
155-
my-registry.example.com/mirror/dhi-python@sha256:25c9...
156-
157-
$ regctl \
158-
--host "reg=registry.scout.docker.com,user=$DOCKER_USERNAME,pass=$DOCKER_PASSWORD_OR_PAT" \
159-
--host "reg=registry.example.com" \
160-
image copy --referrers \
161-
registry.scout.docker.com/docs/dhi-python@sha256:25c9... \
162-
my-registry.example.com/mirror/dhi-python@sha256:25c9...
273+
$ regsync check -c regsync.yaml
163274
```
164275

165-
This mirrors both the image and its associated attestations to a private OCI-compatible registry.
276+
To run the sync with the configuration file:
166277

167-
> [!IMPORTANT]
168-
>
169-
> To continue receiving image updates and preserve access to Docker Hardened
170-
> Images, ensure that any copies pushed to other registries remain private.
278+
```console
279+
$ regsync once -c regsync.yaml
280+
```
171281

172282
## What's next
173283

0 commit comments

Comments
 (0)