@@ -128,54 +128,160 @@ repository to mirror.
128
128
129
129
## Mirror from Docker Hub to another registry
130
130
131
+ > [ !IMPORTANT]
132
+ >
133
+ > To continue receiving image updates and preserve access to Docker Hardened
134
+ > Images, ensure that any copies pushed to other registries remain private.
135
+
131
136
After you've mirrored a Docker Hardened Image repository to your organization's
132
137
namespace on Docker Hub, you can optionally mirror it to another container
133
138
registry, such as Amazon ECR, Google Artifact Registry, GitHub Container
134
139
Registry, or a private Harbor instance.
135
140
136
- You can use any standard workflow, including:
137
-
138
- - [ The Docker CLI] ( /reference/cli/docker/_index.md )
139
- - [ The Docker Hub Registry API] ( /reference/api/registry/latest/ )
140
- - Third-party registry tools or CI/CD automation
141
+ You can use any standard workflow to mirror the image, such as the
142
+ [ Docker CLI] ( /reference/cli/docker/_index.md ) , [ Docker Hub Registry
143
+ API] ( /reference/api/registry/latest/ ) , third-party registry tools, or CI/CD
144
+ automation.
145
+
146
+ However, to preserve the full security context, including attestations, you must
147
+ also mirror its associated OCI artifacts. Docker Hardened Images store the image
148
+ layers on Docker Hub (` docker.io ` ) and the signed attestations in a separate
149
+ registry (` registry.scout.docker.com ` ).
150
+
151
+ To copy both, you can use [ ` regctl ` ] ( https://regclient.org/cli/regctl/ ) , an
152
+ OCI-aware CLI that supports mirroring images along with attached artifacts such
153
+ as SBOMs, vulnerability reports, and SLSA provenance. For ongoing synchronization,
154
+ you can use [ ` regsync ` ] ( https://regclient.org/cli/regsync/ ) .
155
+
156
+ ### Example mirroring with ` regctl `
157
+
158
+ The following example shows how to mirror a specific tag of a Docker Hardened
159
+ Image from Docker Hub to another registry, along with its associated
160
+ attestations using ` regctl ` . You must [ install
161
+ ` regctl ` ] ( https://github.com/regclient/regclient ) first.
162
+
163
+ 1 . Set environment variables for your specific environment. Replace the
164
+ placeholders with your actual values.
165
+
166
+ ``` console
167
+ $ export DOCKER_USERNAME="YOUR_DOCKER_USERNAME"
168
+ $ export DOCKER_PAT="YOUR_DOCKER_PAT"
169
+ $ export DEST_REG="registry.example.com"
170
+ $ export DEST_REPO="mirror/dhi-python"
171
+ $ export SRC_REPO="docker.io/<your-org>/dhi-python"
172
+ $ export SRC_TAG="3.13-alpine3.21"
173
+ ```
174
+
175
+ 2 . Sign in via ` regctl ` to Docker Hub, the Scout registry that contains
176
+ the attestations, and your destination registry.
177
+
178
+ ``` console
179
+ $ regctl registry login -u "$DOCKER_USERNAME" --pass-stdin docker.io
180
+ $ regctl registry login -u "$DOCKER_USERNAME" --pass-stdin registry.scout.docker.com
181
+ $ regctl registry login "$DEST_REG
182
+ ```
183
+
184
+ 3 . Mirror the image by digest from Docker Hub to your destination registry.
185
+
186
+ First, get a digest for a specific tag and platform. For example, ` linux/amd64 ` .
187
+
188
+ ``` console
189
+ DIGEST="$(regctl manifest head "${SRC_REPO}:${SRC_TAG}" --platform linux/amd64)"
190
+ ```
191
+
192
+ Then, copy the image by digest to ensure you get the exact same image.
193
+
194
+ ``` console
195
+ regctl image copy \
196
+ "${SRC_REPO}@${DIGEST}" \
197
+ "${DEST_REG}/${DEST_REPO}@${DIGEST}"
198
+ ```
199
+
200
+ 4 . Mirror the attestations from the Scout registry to your target registry using
201
+ ` --referrers ` and referrer endpoints:
202
+
203
+ ``` console
204
+ $ regctl image copy \
205
+ --referrers \
206
+ --referrers-src "registry.scout.docker.com/<your-org>/dhi-python" \
207
+ --referrers-tgt "${DEST_REG}/${DEST_REPO}" \
208
+ "registry.scout.docker.com/<your-org>/dhi-python@${DIGEST}" \
209
+ "${DEST_REG}/${DEST_REPO}@${DIGEST}"
210
+ ```
211
+
212
+ 5 . Verify that artifacts were preserved.
213
+
214
+ List attached artifacts (SBOM, provenance, VEX, vulnerability reports).
215
+
216
+ ``` console
217
+ $ regctl artifact list "${DEST_REG}/${DEST_REPO}@${DIGEST}"
218
+ ```
219
+
220
+ If you use Docker Scout:
221
+
222
+ ``` console
223
+ $ docker scout attest list "registry://${DEST_REG}/${DEST_REPO}@${DIGEST}"
224
+ ```
225
+
226
+ ### Example ongoing mirroring with ` regsync `
227
+
228
+ ` regsync ` automates pulling from your organizations mirrored DHI repositories on
229
+ Docker Hub and pushing to your external registry including attestations. It
230
+ reads a YAML configuration file and can filter tags.
231
+
232
+ The following example uses a ` regsync.yaml ` file that syncs Node 24 and Python
233
+ 3.12 Debian 13 variants, excluding Alpine and Debian 12.
234
+
235
+ ``` yaml{title="regsync.yaml"}
236
+ version: 1
237
+ # Optional: inline creds if not relying on prior CLI logins
238
+ # creds:
239
+ # - registry: docker.io
240
+ # user: <your-docker-username>
241
+ # pass: "{{file \"/run/secrets/docker_token\"}}"
242
+ # - registry: registry.scout.docker.com
243
+ # user: <your-docker-username>
244
+ # pass: "{{file \"/run/secrets/docker_token\"}}"
245
+ # - registry: registry.example.com
246
+ # user: <service-user>
247
+ # pass: "{{file \"/run/secrets/dest_token\"}}"
248
+
249
+ sync:
250
+ - source: docker.io/<your-org>/dhi-node
251
+ target: registry.example.com/mirror/dhi-node
252
+ type: repository
253
+ fastCopy: true
254
+ referrers: true
255
+ referrerSource: registry.scout.docker.com/<your-org>/dhi-node
256
+ referrerTarget: registry.example.com/mirror/dhi-node
257
+ tags:
258
+ allow: [ "24.*" ]
259
+ deny: [ ".*alpine.*", ".*debian12.*" ]
260
+
261
+ - source: docker.io/<your-org>/dhi-python
262
+ target: registry.example.com/mirror/dhi-python
263
+ type: repository
264
+ fastCopy: true
265
+ referrers: true
266
+ referrerSource: registry.scout.docker.com/<your-org>/dhi-python
267
+ referrerTarget: registry.example.com/mirror/dhi-python
268
+ tags:
269
+ allow: [ "3.12.*" ]
270
+ deny: [ ".*alpine.*", ".*debian12.*" ]
271
+ ```
141
272
142
- The following example shows how to use the Docker CLI to pull a mirrored DHI and
143
- push it to another registry:
273
+ To do a dry run with the configuration file, you can run the following command.
274
+ You must [ install ` regsync ` ] ( https://github.com/regclient/regclient ) first.
144
275
145
276
``` console
146
- # Authenticate to Docker Hub (if not already signed in)
147
- $ docker login
148
-
149
- # Pull the image from your organization' s namespace on Docker Hub
150
- $ docker pull < your-namespace> /dhi-< image> :< tag>
151
-
152
- # Tag the image for your destination registry
153
- $ docker tag < your-namespace> /dhi-< image> :< tag> registry.example.com/my-project/< image> :< tag>
154
-
155
- # Push the image to the destination registry
156
- # You will need to authenticate to the third-party registry before pushing
157
- $ docker push registry.example.com/my-project/< image> :< tag>
277
+ $ regsync check -c regsync.yaml
158
278
```
159
279
160
- > [ !IMPORTANT]
161
- >
162
- > To continue receiving image updates and preserve access to Docker Hardened
163
- > Images, ensure that any copies pushed to other registries remain private.
164
-
165
- ### Include attestations when mirroring images
280
+ To run the sync with the configuration file:
166
281
167
- Docker Hardened Images are signed and include associated attestations that
168
- provide metadata such as build provenance and vulnerability scan results. These
169
- attestations are stored as OCI artifacts and are not included by default when
170
- using the Docker CLI to mirror images.
171
-
172
- To preserve the full security context when copying DHIs to another registry, you
173
- must explicitly include the attestations. One tool is ` regctl ` , which supports
174
- copying both images and their associated artifacts.
175
-
176
- For more details on how to use ` regctl ` to copy images and their associated
177
- artifacts, see the [ regclient
178
- documentation] ( https://regclient.org/cli/regctl/image/copy/ ) .
282
+ ``` console
283
+ $ regsync once -c regsync.yaml
284
+ ```
179
285
180
286
## What's next
181
287
0 commit comments