Using a dynamic registry reference
The documentation walks you through how to use a dynamic registry reference in the contract.
Explicit registry reference
Typically, the docker registry is referenced via the full docker URL in the compose file. For example,
services:
helloworld:
image: docker.io/library/hello-world@sha256:53f1bbee2f52c39e41682ee1d388285290c5c8a76cc92b42687eecf38e0af3f0
In the example, docker.io/library/ is the registry prefix, hello-world is the identifier of the OCI image in that registry, and sha256:53f1bbee2f52c39e41682ee1d388285290c5c8a76cc92b42687eecf38e0af3f0 is the unique identifier of the version of the image.
In such a case, the role that decides about the registry (and the associated pull credentials) is the workload provider, since both the registry reference as well as the pull credentials are part of the workload section of the contract.
Dynamic registry reference
There are cases where the registry is not known when the workload section is pre-encrypted, for example, when the workload provider wants to allow the deployer to use a registry mirror or a private container registry.
In such a case, it's possible to dynamically override the registry as well as the pull credentials. This is a coordinated effort between the workload provider and the deployer.
You can use a custom configuration to connect to a secure private registry. You must then define the IP address and the port of registry. The following snippet is an example:
auths:
"<registry IP or hostname>:<port>":
password: password
username: user
In the env section, you must define the cacerts parameter and add the certificates in the base64-encoded format. You can run the following command to get the base64-encoded version of the certificate:
base64 -i domain.crt | tr -d '\n'
The following snippet is an example of the env section:
env: |
type: env
logging:
logRouter:
hostname: f61c42c4-3e3a.ingress.us-south.logs.cloud.ibm.com
iamApiKey: *****************
port: 443
volumes:
test:
seed: "testing"
cacerts:
- certificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZyakNDQTVhZ0F3SUJBZ0lVT28xOVhGMUtrN0xhMkg2ZlNUaUFubUtqNllzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1hqRUxNQWtHQTFVRUJoTUNRVlV4RXpBUkJnTlZCQWdNQ2xOdmJXVXRVM1JoZEdVeElUQWZCZ05WQkFvTQpHRWx1ZEdWeWJtVjBJRmRwWkdkcGRITWdVSFI1SUV4MFpERVhNQlVHQTFVRUF3d09NVGt5TGpFMk9DNHhNakl1Ck5Ea3dIaGNOTWpVd05EQXhNVGcwTmpJNVdoY05Nall3TkRBeE1UZzBOakk1V2pCZU1Rc3dDUVlEVlFRR0V3SkIKVlRFVE1CRUdBMVVFQ0F3S1UyOXRaUzFUZEdGMFpURWhNQjhHQTFVRUNnd1lTVzUwWlhKdVpYUWdWMmxrWjJsMApjeUJRZEhrZ1RIUmtNUmN3RlFZRFZRUUREQTR4T1RJdU1UWTRMakV5TWk0ME9UQ0NBaUl3RFFZSktvWklodmNOCkFRRUJCUUFEZ2dJUEFEQ0NBZ29DZ2dJQkFKSXNkVHlFdU9QSEtBQ0hPcnEvQU9scittelc3Ny9QcTNhQU9LTisKcTMzY252aXNQUVJpVlZDRjVFak1iKzJVOFcvUlVnZi9ld3dYeTErZ0VmNnZ0Wm1vTXJwVmVwQlZjVUx3RDhIdwoyWHdWeC96QTZPRWdVNldQdWF3KzR5V0dvRlpFM0RMOG1BS1l0Q0kxYnFiUmRNaEpETmVHWTE5TXBOcHJFWTJaCndrTUJjd3F1WEI0TUpMZDRTZ2dnQnhpU2Y0SUwwMFRocG1qcXlDU1ovT0tMTE55djlOcVpMM1Nra2NxNm9WcmcKNm40akJnMmZRc3d2TlovckRJaVRlUmlBT0NsRVRQTjI5L2FPZkdrL1FveURaOFJDaVR5bDNLSVUwckxTbU9ncQo3SU1sNlNYOXU4UHlTNGo2RnVQeXRSV0lJdElKRDJOVWpGOTg4RVdmVGZvYjNKMlM0OTZZSEQxNWYxYytqNUVoCndEOGdwZDg2RTZXMFdLZDVWOFpBdXRsSkFIZEFSS2NlcXNUWXUrbXF1ckp4VVFuTHJaWFFjSVZTWnYyZEJiYUsKNWltMkdhcXd1RjRoZ214VExCb21MTlo4R0I2VG41VXdISEFQSG9Vd3AvQ3lINi94bGRjdGdvdmdab09KREQvTwpIU0FHTzhJMEQzMXRIREIrc1dXc1ZmNDd4OTZqM3FxY0UxR0gwT1BOMmR1UkZzVTUrMEhRUm4rSWxtUVo5WjBHCi9NOTJHL0tidXRaSWVEK2d3eGU4eXV5c3BKT01GVUV6WTFidUZmcm9KMDFIcVhYK3BUanhFdWo2eHVXQmJVVmkKTzJtbTMwRXp5eEdzeW9kRXd5MXpDekx2UzhKcElDbE92cHFtN1hDNUNQNVdoa0g0cHFDeWpkLzk3d201K0djcQp6VitWQWdNQkFBR2paREJpTUIwR0ExVWREZ1FXQkJRL3lKWGdoOEJ6OVpabkJ5YnpMY1NrQ0ZHYjdqQWZCZ05WCkhTTUVHREFXZ0JRL3lKWGdoOEJ6OVpabkJ5YnpMY1NrQ0ZHYjdqQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01BOEcKQTFVZEVRUUlNQWFIQk1Db2VqRXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnSUJBSEFpbWF1UnYyZ1d1NjhKYk5ZeApoU2RlRjdjMWdYY1BITXl6T0twelQvVzRyUlkyZkV2ODBwVElYT29CZ25wVUxYSXpnN3R0d3N0MjJUbzA4YkpxCmxtV0hUazNqWHZnWVNVQnV3RUhVOUN3eGtYQ3BLeFNPUlJKb3Zoem82bDJTaTVkK3ZNMnlVMHlBcVVKYWtRUkYKYVZhZDQrTm81ZENqNEV5TVBtdFZ6ODBOVnZTSmc1MEMwd2I1R2p0RUVOa3huVy93V3VQYTdGa1hscVdDZnlWcwpZWm5rSW9NZkNTQ0ZsZDllTUNUMm5rTGpHNjIrVjZNU0xGcUJtZUdwcFhBZkR5Nm50MmZZZ1lObGJ5bm1wNDhICkh5TzVhM01lSnBVaEtSZ0FnaUpUUGZGYWcycFVWd052WWVJeFdyNytyVit1UHVUbGlabXQ4UUZ4Vnh3VTJ6M20KQkJvdVZQYllpQ0U4S0VBbEwrSDJmd1IxODdGdWFWd3ZpUnBpNVh5Vzc1WE9lVUJ4Z21ad3UvVmhrL0puOEFpZQowODhIUXZFYlVOWXBHWkJPRk9SYU5jdDhYdGJkejJLSzRHbUpya0JTRm9yUW5jNVU0dFdEQkVnSWhjTXJnVmtMCmFSMENGbHQ4cnhtYitkUStxMHdVT1dtSW1GR0ZVUkhTdytERUp1aHhRTklVN052eUpERGtRQkNHZkc5Nk1SQ0sKbnFTb3hFaXBsTDg1NmJDNmwycUNIRXVNTWpIdkZmMDFZeERzNjd3U2k1WEZTdXZoV1BvZ25sQlRkeG4xREQwNwpoSmJLS3RHeE5tWUlDV1gyZk9Malh0TDlHVHU4d3RnYXhMOGFhNk9xUnZvNDhKRGdxVDI5S3ZPMVA0bG9aTGJyCnpONVVJRk9Pb1NRNSthNmhGV0tQU3luNwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
When you have multiple certificates, the following snippet shows how you can add them in the contract file:
env: |
type: env
logging:
logRouter:
hostname: f61c42c4-3e3a.ingress.us-south.logs.cloud.ibm.com
iamApiKey: *****************
port: 443
cacerts:
- certificate1: <base64 encoded of ca cert>
certificate2: <base64 encoded of ca cert>
certificate3: <base64 encoded of ca cert>
Workload provider
The workload provider marks the registry as dynamic by using a replacement variable in the docker compose file:
services:
helloworld:
image: ${REGISTRY}/hpse-docker-hello-world-s390x@sha256:43c500c5f85fc450060b804851992314778e35cadff03cb63042f593687b7347
Note that the digest of the image is identical across registries, so the workload provider can lock down the desired version of the image by setting the key, independent of what registry is actually being used. Using tokens in the compose file is a native feature of the compose specification.
Now the workload provider can prepare (encrypt) the workload section without specifying the pull secrets for that registry.
Deployer
The deployer fills in the missing information about the registry and the associated pull secrets.
The registry is set as an environment variable. Both the deployer and the workload provider can provide pieces to the overall environment and these are overlaid (with workload taking precedence).
The pull credentials are passed in via an auth section in the environment part of the contract. Just as environment variables, these sections are overlaid with the workload section taking precedence.
---
env:
type: env
auths:
"<registry IP or hostname>:<port>":
username: xxx
password: yyy
env:
REGISTRY: "<registry IP or hostname>:<port>/test"