Docker Registry HTTP Routes
Nitro Repo implements the complete Docker Registry V2 API specification for hosted Docker repositories. This reference details every HTTP route, its purpose, and example usage. Replace placeholders with your own hostname, repository name, image name, tag, and authentication token.
<host>– Nitro Repo base URL (e.g.nitro.example.com)<repository>– Repository name (e.g.my-docker-repo)<image>– Docker image name (e.g.myapp,myproject/myapp)<reference>– Tag name or digest (e.g.latest,v1.0.0,sha256:abc123...)<digest>– Content digest (e.g.sha256:abc123...)<uuid>– Upload UUID for blob upload operations<token>– Bearer token for authentication
Core Registry API
API Version Check
Verify the registry supports Docker Registry V2 API:
curl "https://<host>/v2/"Response Headers:
Docker-Distribution-API-Version: registry/2.0Repository Catalog
List all repositories (may require admin permissions):
curl -H "Authorization: Bearer <token>" \
"https://<host>/v2/_catalog"Response:
{
"repositories": [
"myapp",
"myproject/webapp",
"tools/build-agent"
]
}Image Operations
List Tags
List all available tags for an image:
curl -H "Authorization: Bearer <token>" \
"https://<host>/v2/<image>/tags/list"Response:
{
"name": "myapp",
"tags": [
"latest",
"v1.0.0",
"v1.1.0",
"develop"
]
}Get Manifest
Retrieve manifest information for a tag or digest:
# Get manifest by tag
curl -H "Authorization: Bearer <token>" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
"https://<host>/v2/<image>/manifests/<reference>"
# Get manifest list (multi-arch)
curl -H "Authorization: Bearer <token>" \
-H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" \
"https://<host>/v2/<image>/manifests/<reference>"Response (Manifest V2):
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 7023,
"digest": "sha256:b5b2b2c507a0944348a0305746806797b0ec1c6a5c7c8ab5c5c7c8d5d6e7f8a"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 32654,
"digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f"
}
]
}Check Manifest Exists
Check if a manifest exists without downloading it:
curl -I -H "Authorization: Bearer <token>" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
"https://<host>/v2/<image>/manifests/<reference>"Upload Manifest
Upload a new manifest for an image:
curl -X PUT \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/vnd.docker.distribution.manifest.v2+json" \
--data-binary @manifest.json \
"https://<host>/v2/<image>/manifests/<reference>"Delete Manifest
Remove a manifest by tag or digest:
curl -X DELETE \
-H "Authorization: Bearer <token>" \
"https://<host>/v2/<image>/manifests/<reference>"Blob Operations
Download Blob
Download a layer or config blob by digest:
curl -L -H "Authorization: Bearer <token>" \
"https://<host>/v2/<image>/blobs/<digest>"Check Blob Exists
Check if a blob exists without downloading it:
curl -I -H "Authorization: Bearer <token>" \
"https://<host>/v2/<image>/blobs/<digest>"Initiate Blob Upload
Start a new blob upload session:
curl -X POST \
-H "Authorization: Bearer <token>" \
-H "Content-Length: 0" \
"https://<host>/v2/<image>/blobs/uploads/"Response Headers:
Location: /v2/myapp/blobs/uploads/<uuid>
Range: 0-0Upload Blob Chunk
Upload data to an existing upload session:
# Upload chunk
curl -X PATCH \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/octet-stream" \
-H "Content-Range: 0-1023" \
--data-binary @chunk.bin \
"https://<host>/v2/<image>/blobs/uploads/<uuid>"
# Upload complete blob (monolithic)
curl -X PUT \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/octet-stream" \
-H "Content-Length: 32768" \
--data-binary @layer.tar.gz \
"https://<host>/v2/<image>/blobs/uploads/?digest=sha256:<digest>"Complete Blob Upload
Finalize an upload session with digest:
curl -X PUT \
-H "Authorization: Bearer <token>" \
-H "Content-Length: 0" \
"https://<host>/v2/<image>/blobs/uploads/<uuid>?digest=sha256:<digest>"Delete Blob
Remove a blob by digest:
curl -X DELETE \
-H "Authorization: Bearer <token>" \
"https://<host>/v2/<image>/blobs/<digest>"Authentication
Get Bearer Token
Obtain authentication token for repository access:
curl -X POST "https://<host>/api/auth/token" \
-u "username:password" \
-d "service=nitro-repo" \
-d "scope=repository:<image>:pull,push"Response:
{
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 3600,
"issued_at": "2023-12-15T10:00:00Z"
}WWW-Authenticate Challenge
Registry challenges unauthorized requests:
WWW-Authenticate: Bearer realm="https://<host>/api/auth/token",service="nitro-repo",scope="repository:myapp:pull"Repository Management API
List Cached Packages
List cached Docker images and layers:
curl -H "Authorization: Bearer <token>" \
"https://<host>/api/repository/<repository-id>/packages?page=1&per_page=50"Delete Cached Artifacts
Remove cached images and layers (requires repository edit permission):
curl -X DELETE \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"paths": ["v2/myapp/blobs/sha256/abc123...", "v2/myapp/manifests/latest"]}' \
"https://<host>/api/repository/<repository-id>/packages"Repository Configuration
Get Docker repository configuration:
curl -H "Authorization: Bearer <token>" \
"https://<host>/api/repository/<repository-id>/config/docker"Update repository configuration:
curl -X PUT \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d @config.json \
"https://<host>/api/repository/<repository-id>/config/docker"Repository Statistics
Get repository usage statistics:
curl -H "Authorization: Bearer <token>" \
"https://<host>/api/repository/<repository-id>/stats"Response:
{
"total_images": 45,
"total_tags": 128,
"storage_used": "2.5GB",
"last_activity": "2023-12-15T15:30:00Z",
"top_images": [
{"name": "myapp", "tag_count": 12},
{"name": "webapp", "tag_count": 8}
]
}Error Responses
Common Error Codes
401 Unauthorized- Authentication required or invalid credentials403 Forbidden- Insufficient permissions404 Not Found- Repository, tag, or blob does not exist409 Conflict- Tag overwrite not allowed or digest mismatch422 Unprocessable Entity- Invalid manifest format500 Internal Server Error- Server-side error
Error Response Format
{
"errors": [
{
"code": "MANIFEST_UNKNOWN",
"message": "manifest unknown",
"detail": "manifest sha256:invalid... not found"
}
]
}Usage Examples
Complete Push Workflow
#!/bin/bash
HOST="https://nitro.example.com"
IMAGE="myproject/myapp"
TAG="v1.0.0"
USER="username"
PASS="password"
# Get auth token
TOKEN=$(curl -X POST "${HOST}/api/auth/token" \
-u "${USER}:${PASS}" \
-d "service=nitro-repo" \
-d "scope=repository:${IMAGE}:pull,push" \
| jq -r '.token')
# Upload layer (example)
LAYER_DIGEST="sha256:abc123..."
curl -X POST \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Length: 0" \
"${HOST}/v2/${IMAGE}/blobs/uploads/"
# Upload complete image
docker push ${HOST}/${IMAGE}:${TAG}Pull with Token Authentication
#!/bin/bash
HOST="https://nitro.example.com"
IMAGE="myapp"
TAG="latest"
TOKEN="your-bearer-token"
# Get manifest
curl -H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
"${HOST}/v2/${IMAGE}/manifests/${TAG}" | jq .
# Pull image with Docker
docker login ${HOST} # Use username/password or token auth
docker pull ${HOST}/${IMAGE}:${TAG}Use these endpoints as a foundation for Docker client integration, CI/CD pipelines, or custom tooling when working with Nitro Repo Docker repositories.
Complete reference for Docker registry HTTP routes. See Docker Quick Reference for usage examples and configuration.