Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Finsys/dockhand/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Push Docker images to configured container registries. Supports Docker Hub, private registries, and custom registry configurations with automatic tag management and authentication handling.
Endpoint
POST /api/images/push?env={environmentId}
Query Parameters
Environment ID containing the image to push. Optional for local environments.
Request Body
Image ID (SHA256 hash) to push
Current image name/tag (used for audit logging)
Registry ID where the image will be pushed. Must be a configured registry.
Custom tag for the pushed image. If not provided, uses the image’s existing tag.
Format: repository/name:tag or name:tag
Authentication
Requires images:push permission for the specified environment.
Registry Authentication
Registry credentials are retrieved from the database and sent to Docker API:
const authConfig = registry.username && registry.password
? {
username: registry.username,
password: registry.password,
serveraddress: authServerAddress
}
: {
serveraddress: authServerAddress
};
Async Response (default)
Returns job ID for progress tracking:
{
"jobId": "550e8400-e29b-41d4-a716-446655440000"
}
Sync Response (with Accept: application/json)
Returns final result immediately:
{
"status": "complete",
"message": "Image pushed to registry.example.com/app:v1.0",
"targetTag": "registry.example.com/app:v1.0"
}
Progress Events
Tagging
{
"status": "tagging",
"message": "Tagging image..."
}
Pushing
{
"status": "pushing",
"message": "Pushing to registry..."
}
Layer Progress
{
"id": "abc123",
"status": "Pushing",
"progressDetail": {
"current": 1048576,
"total": 10485760
},
"progress": "[====> ] 1MB/10MB"
}
Complete
{
"status": "complete",
"message": "Image pushed to registry.example.com/app:v1.0",
"targetTag": "registry.example.com/app:v1.0"
}
Error
{
"status": "error",
"error": "Authentication failed. Check registry credentials."
}
Error Responses
Invalid request - missing required fields{ "error": "Image ID and registry ID are required" }
Image has no tag{ "error": "Image has no tag. Please provide a tag name." }
Permission denied{ "error": "Permission denied" }
Registry not found{ "error": "Registry not found" }
Push failed - authentication or network error{
"status": "error",
"error": "TLS/HTTPS error. If your registry uses HTTP, add it to Docker's insecure-registries in /etc/docker/daemon.json"
}
Tag Management
The push endpoint automatically handles tag formatting for different registry types:
Docker Hub
Docker Hub images don’t require host prefix:
const isDockerHub = registryHost.includes('docker.io') ||
registryHost.includes('hub.docker.com') ||
registryHost.includes('registry.hub.docker.com') ||
registryHost.includes('index.docker.io');
// Docker Hub: username/image:tag
// Other registries: registry.example.com/org/image:tag
const targetTag = isDockerHub ? targetImageName : `${fullRegistry}/${targetImageName}`;
Private Registries
Private registry pushes include the full host path:
registry.company.com:5000/project/app:v1.0
Registry Prefix Removal
Existing registry prefixes are stripped before applying new target:
let baseImageName = sourceTag;
if (baseImageName.includes('/')) {
const parts = baseImageName.split('/');
// Check if first part looks like a registry (contains . or :)
if (parts[0].includes('.') || parts[0].includes(':')) {
baseImageName = parts.slice(1).join('/');
}
}
Edge Mode Support
For Hawser Edge environments:
if (edgeCheck.isEdge && edgeCheck.environmentId) {
if (!isEdgeConnected(edgeCheck.environmentId)) {
emit({ status: 'error', error: 'Edge agent not connected' });
return;
}
const authHeader = Buffer.from(JSON.stringify(authConfig)).toString('base64');
await sendEdgeStreamRequest(
edgeCheck.environmentId,
'POST',
`/images/${encodeURIComponent(targetTag)}/push`,
{ onData, onEnd, onError },
undefined,
{ 'X-Registry-Auth': authHeader }
);
}
Error Handling
The endpoint provides user-friendly error messages:
const formatError = (error: any): string => {
const errorMessage = error.message || error || '';
let userMessage = errorMessage || 'Failed to push image';
if (error.statusCode === 401 || errorMessage.includes('401')) {
userMessage = 'Authentication failed. Check registry credentials.';
} else if (error.statusCode === 404 || errorMessage.includes('404')) {
userMessage = 'Image not found';
} else if (errorMessage.includes('https') || errorMessage.includes('tls') ||
errorMessage.includes('certificate') || errorMessage.includes('x509')) {
userMessage = `TLS/HTTPS error. If your registry uses HTTP, add it to Docker's insecure-registries in /etc/docker/daemon.json`;
}
return userMessage;
};
Usage Examples
Push to Docker Hub
curl -X POST 'https://dockhand.example.com/api/images/push?env=1' \
-H 'Content-Type: application/json' \
-H 'Cookie: session=...' \
-d '{
"imageId": "sha256:abc123...",
"imageName": "myapp:latest",
"registryId": 1,
"newTag": "username/myapp:v1.0"
}'
Push to Private Registry
curl -X POST 'https://dockhand.example.com/api/images/push?env=1' \
-H 'Content-Type: application/json' \
-d '{
"imageId": "sha256:def456...",
"registryId": 2,
"newTag": "app:production"
}'
Push with Progress Tracking
const response = await fetch('/api/images/push?env=1', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
imageId: 'sha256:abc123...',
registryId: 1,
newTag: 'myapp:v2.0'
})
});
const { jobId } = await response.json();
const eventSource = new EventSource(`/api/jobs/${jobId}`);
eventSource.addEventListener('data', (e) => {
const progress = JSON.parse(e.data);
if (progress.data.status === 'complete') {
console.log('Push complete:', progress.data.targetTag);
eventSource.close();
} else if (progress.data.status === 'error') {
console.error('Push failed:', progress.data.error);
eventSource.close();
}
});
Audit Logging
Push operations are logged with full details:
await auditImage(
event,
'push',
imageId,
imageName || targetTag,
envIdNum,
{ targetTag, registry: registry.name }
);
Notes
- Images are automatically tagged before pushing
- Docker Hub uses
index.docker.io/v1/ for authentication
- Private registries must be configured with credentials
- Insecure registries require Docker daemon configuration
- Edge mode requires active Hawser agent connection
- Authentication failures provide helpful error messages
- TLS/certificate errors suggest insecure-registry configuration