Docker Registry Setup¶
This guide covers how to install and configure a private Docker registry for the Traceable Platform.
Overview¶
A private Docker registry is required for:
- Airgap deployments without internet access
- Faster image pulls from local storage
- Compliance requirements for image storage
- Custom image management
Prerequisites¶
- Docker, Podman, or Kubernetes cluster
- TLS certificates (self-signed or CA-signed)
- Storage for registry data
- (Optional) htpasswd for authentication
Pre-Setup¶
Create Registry Directories¶
Directory structure:
docker-registry/
├── cert/ # TLS certificates
├── registry/ # Image storage
└── auth/ # Authentication files
Create TLS Certificate¶
Generate a self-signed certificate:
openssl req -nodes -x509 -sha256 -newkey rsa:4096 \
-keyout $(pwd)/docker-registry/cert/tls.key \
-out $(pwd)/docker-registry/cert/tls.crt \
-days 356 \
-subj "/CN=localhost" \
-addext "subjectAltName = DNS:$(hostname), IP:$(hostname -i)"
Note: Update subjectAltName with your registry hostname and IP address.
Create Authentication File (Optional)¶
If you want to enable authentication:
Note: Remove htpasswd-related configuration if authentication is not required.
Installation Methods¶
Method 1: Docker/Podman¶
Run the registry container:
docker run -d \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/cert/tls.crt \
-e REGISTRY_HTTP_TLS_KEY=/cert/tls.key \
-e REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/var/lib/registry \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM=Registry-Realm \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-v $(pwd)/docker-registry/cert:/cert \
-v $(pwd)/docker-registry/registry:/var/lib/registry \
-v $(pwd)/docker-registry/auth/htpasswd:/auth/htpasswd \
-p 5000:5000 \
--name docker-registry \
registry:2.8.1
For Podman: Replace docker with podman.
Method 2: Docker Compose¶
Create docker-compose.yaml:
version: '3'
services:
registry:
image: registry:2.8.1
restart: always
ports:
- "5000:5000"
environment:
REGISTRY_HTTP_TLS_KEY: /cert/tls.key
REGISTRY_HTTP_TLS_CERTIFICATE: /cert/tls.crt
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /var/lib/registry
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry-Realm
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
volumes:
- ./docker-registry/registry:/var/lib/registry
- ./docker-registry/cert:/cert
- ./docker-registry/auth/htpasswd:/auth/htpasswd
Start the registry:
Method 3: Docker Swarm¶
Enable swarm mode:
Create the service:
docker service create \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/cert/tls.crt \
-e REGISTRY_HTTP_TLS_KEY=/cert/tls.key \
-e REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/data \
-e REGISTRY_AUTH=htpasswd \
-e REGISTRY_AUTH_HTPASSWD_REALM=Registry-Realm \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
--mount type=bind,source=$(pwd)/docker-registry/cert/,destination=/cert/ \
--mount type=bind,source=$(pwd)/docker-registry/registry/,destination=/data/ \
--mount type=bind,source=$(pwd)/docker-registry/auth/,destination=/auth/ \
-p 5000:5000 \
--name docker-registry \
--replicas 3 \
registry:2.8.1
Method 4: Kubernetes¶
Step 1: Create Secrets¶
# TLS certificate secret
kubectl create secret generic registry-cert \
--from-file $(pwd)/docker-registry/cert/tls.key \
--from-file $(pwd)/docker-registry/cert/tls.crt
# htpasswd secret
kubectl create secret generic registry-htpasswd \
--from-file $(pwd)/docker-registry/auth/htpasswd
Step 2: Create values.yaml
replicaCount: 2
tlsSecretName: registry-cert
service:
nodePort: 30000
type: NodePort
persistence:
enabled: true
storageClass: nfs-client
secrets:
htpasswd: registry-htpasswd
Note: Update storageClass for your environment. If the storage class doesn't support multi-node mounting, all pods will be scheduled on one node.
Step 3: Add Helm Repository¶
Step 4: Install Registry¶
Client Configuration¶
Add Certificate to Trust Store¶
For self-signed certificates, add the certificate to the client's trust store.
Find trust store location:
export dockerRegistry=<registry-hostname>
export dockerRegistryPort=<port>
curl -v https://${dockerRegistry}:${dockerRegistryPort}/ 2>&1 \
| grep CAfile \
| cut -d":" -f2
Add certificate to trust store:
echo | openssl s_client -connect ${dockerRegistry}:${dockerRegistryPort} -showcerts \
2>/dev/null </dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' \
>> /etc/ssl/certs/ca-certificates.crt
Login to Registry¶
If authentication is enabled:
Using curl:
Using Docker:
Push Images to Registry¶
Using Docker¶
Pull image:
Tag image:
Push image:
Using containerd¶
Pull image:
Tag image:
Push image:
Pull Images from Registry¶
Using Docker¶
Using containerd¶
Update Registry Credentials¶
To update Docker registry credentials in the Traceable Platform:
Step 1: Save Credentials¶
- Login to Traceable Installer
- Select the correct cluster name from the dropdown
- Navigate to Cluster Info
- Update:
- IMAGE REGISTRY USERNAME
- IMAGE REGISTRY PASSWORD
Step 2: Apply Credentials¶
- Navigate to Install Workflow → create_regcred
- Click Apply
- Verify no error messages appear at the bottom of the screen
Verification¶
Check Registry Health¶
Expected response: {}
List Repositories¶
List Image Tags¶
Troubleshooting¶
Certificate Errors¶
Symptoms: x509: certificate signed by unknown authority
Solutions:
- Add certificate to client trust store
- Use
--insecure-registryflag (not recommended for production) - Verify certificate SAN includes registry hostname
Authentication Failed¶
Symptoms: 401 Unauthorized
Solutions:
- Verify username and password
- Check htpasswd file is correctly mounted
- Regenerate htpasswd file if needed
Push/Pull Timeout¶
Symptoms: Operations timeout or hang
Solutions:
- Check network connectivity
- Verify firewall rules
- Check registry storage capacity
- Increase Docker timeout settings
Understanding Registry Host Options¶
When performing the installation, you are presented with several registry configuration options:
Available Options¶
| Option | Description |
|---|---|
--registry-host |
The hostname of the docker image registry (e.g., docker.io). The original image host will be used if explicitly set to an empty string. |
--registry-prefix |
The path prefix for the docker registry. Default value is empty string "". If provided, all images need to be in the same namespace. |
--registry-mono-repo |
Use this flag only when all images are uploaded to a single repo within the docker registry. If no prefix is provided, it will use the namespace as the image name. If a prefix is provided, it will use the prefix as the image name. |
Registry Configuration Examples¶
The following table shows the output with different combinations:
| registry-host | registry-prefix | mono-repo | Output |
|---|---|---|---|
example.com |
"" |
N/A | example.com/hypertrace/schema-registry:0.3.8 example.com/traceable/tiw-airgap:1.14.0 |
example.com |
"ces" |
N/A | example.com/ces/schema-registry:0.3.8 example.com/ces/tiw-airgap:1.14.0 |
example.com |
"ces" |
true | example.com/ces:schema-registry-tv-0.3.8 example.com/ces:tiw-airgap-tv-1.14.0 |
example.com |
"" |
true | example.com/hypertrace:schema-registry-tv-0.3.8 example.com/traceable:tiw-airgap-tv-1.14.0 |
example.com/namespace |
"" |
N/A | example.com/namespace/hypertrace/schema-registry:0.3.8 example.com/namespace/traceable/tiw-airgap:1.14.0 |
example.com/namespace |
ces |
N/A | example.com/namespace/ces/schema-registry:0.3.8 example.com/namespace/ces/tiw-airgap:1.14.0 |
example.com/namespace |
ces |
true | example.com/namespace/ces:schema-registry-tv-0.3.8 example.com/namespace/ces:tiw-airgap-tv-1.14.0 |
example.com/namespace |
"" |
true | example.com/namespace/hypertrace:schema-registry-tv-0.3.8 example.com/namespace/traceable:tiw-airgap-tv-1.14.0 |
example.com/namespace |
"ces/us" |
N/A | example.com/namespace/ces/us/schema-registry:0.3.8 example.com/namespace/ces/us/tiw-airgap:1.14.0 |
example.com/namespace |
"ces/us" |
true | example.com/namespace/ces/us:schema-registry-tv-0.3.8 example.com/namespace/ces/us:tiw-airgap-tv-1.14.0 |
Related Documentation¶
Support¶
For registry assistance, contact: support@harness.io
Provide the following information:
- Registry deployment method
- Error messages
- Client configuration
- Network topology