Container API
This API allows to query the state of the watched containers.
This API allows to query the state of the watched containers.
Get all containers
This operation lets you get all the watched containers.
curl "http://drydock:3000/api/v1/containers?limit=25&offset=0"
{
"data": [
{
"id": "31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816",
"name": "homeassistant",
"watcher": "local",
"status": "running"
}
],
"total": 42,
"limit": 25,
"offset": 0,
"hasMore": true
}Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 0 | Maximum number of containers to return (0 means unbounded; max 200) |
offset | integer | 0 | Number of matching containers to skip |
includeVulnerabilities | boolean | false | Include full vulnerability arrays in data |
sort | string | Sort order: name, -name, status, -status, age, -age, created, -created (prefix - for descending) | |
order | string | Optional sort direction override: asc or desc | |
status | string | Filter by update/runtime status: update-available, up-to-date, running, stopped, exited, paused, restarting, dead, created | |
kind | string | Filter by update kind or watched state: major, minor, patch, digest, watched, unwatched, all | |
watcher | string | Filter by watcher name | |
maturity | string | Filter by update maturity: hot, mature, established |
Get container summary
Returns a lightweight summary of container and security counts, used by the dashboard sidebar.
curl http://drydock:3000/api/v1/containers/summary
{
"containers": {
"total": 12,
"running": 10,
"stopped": 2
},
"security": {
"issues": 3
}
}Response fields
| Field | Type | Description |
|---|---|---|
containers.total | integer | Total number of watched containers |
containers.running | integer | Number of running containers |
containers.stopped | integer | Number of stopped containers |
security.issues | integer | Number of containers with critical or high vulnerabilities |
hotUpdates | integer | Number of containers with updates less than 24 hours old |
matureUpdates | integer | Number of containers with updates between 24 hours and 7 days old |
Get recent container status
Returns a map of container names to their most recent update status, derived from the last 100 audit log entries. Used by the dashboard to show status badges on containers.
curl http://drydock:3000/api/v1/containers/recent-status
{
"statuses": {
"homeassistant": "updated",
"nginx": "pending",
"postgres": "failed"
}
}Response fields
| Field | Type | Description |
|---|---|---|
statuses | object | Map of container name to status |
statuses[name] | string | updated (update applied), pending (update available), or failed (update failed) |
Watch all Containers
This operation triggers a manual watch on all containers.
curl -X POST http://drydock:3000/api/v1/containers/watch
{
"data": [{
"id":"31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816",
"name":"homeassistant",
"watcher":"local",
"includeTags":"^\\d+\\.\\d+.\\d+$",
"image":{
"id":"sha256:d4a6fafb7d4da37495e5c9be3242590be24a87d7edcc4f79761098889c54fca6",
"registry":{
"url":"123456789.dkr.ecr.eu-west-1.amazonaws.com"
},
"name":"test",
"tag":{
"value":"2021.6.4",
"semver":true
},
"digest":{
"watch":false,
"repo":"sha256:ca0edc3fb0b4647963629bdfccbb3ccfa352184b45a9b4145832000c2878dd72"
},
"architecture":"amd64",
"os":"linux",
"created":"2021-06-12T05:33:38.440Z"
},
"result":{
"tag":"2021.6.5"
},
"updateAvailable": true
}],
"total": 42,
"limit": 0,
"offset": 0,
"hasMore": false
}Get a Container by id
This operation lets you get a container by id.
curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816
{
"id":"31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816",
"name":"homeassistant",
"watcher":"local",
"includeTags":"^\\d+\\.\\d+.\\d+$",
"image":{
"id":"sha256:d4a6fafb7d4da37495e5c9be3242590be24a87d7edcc4f79761098889c54fca6",
"registry":{
"url":"123456789.dkr.ecr.eu-west-1.amazonaws.com"
},
"name":"test",
"tag":{
"value":"2021.6.4",
"semver":true
},
"digest":{
"watch":false,
"repo":"sha256:ca0edc3fb0b4647963629bdfccbb3ccfa352184b45a9b4145832000c2878dd72"
},
"architecture":"amd64",
"os":"linux",
"created":"2021-06-12T05:33:38.440Z"
},
"result":{
"tag":"2021.6.5"
},
"updateAvailable": true
}Get all triggers associated to the container
This operation lets you get the list of triggers associated to the container.
curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/triggers
{
"data": [
{
"id": "ntfy.one",
"type": "ntfy",
"name": "one",
"configuration": {
"topic": "235ef38e-f1db-414a-964f-ce3f2cc8094d",
"url": "https://ntfy.sh",
"threshold": "major",
"mode": "simple",
"once": true,
"simpletitle": "New ${kind} found for container ${name}",
"simplebody": "Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? "\\n" + container.result.link : ""}",
"batchtitle": "${containers.length} updates available",
}
}
],
"total": 1
}Watch a Container
This operation triggers a manual watch on a container.
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/watch
{
"id":"31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816",
"name":"homeassistant",
"watcher":"local",
"includeTags":"^\\d+\\.\\d+.\\d+$",
"image":{
"id":"sha256:d4a6fafb7d4da37495e5c9be3242590be24a87d7edcc4f79761098889c54fca6",
"registry":{
"url":"123456789.dkr.ecr.eu-west-1.amazonaws.com"
},
"name":"test",
"tag":{
"value":"2021.6.4",
"semver":true
},
"digest":{
"watch":false,
"repo":"sha256:ca0edc3fb0b4647963629bdfccbb3ccfa352184b45a9b4145832000c2878dd72"
},
"architecture":"amd64",
"os":"linux",
"created":"2021-06-12T05:33:38.440Z"
},
"result":{
"tag":"2021.6.5"
},
"updateAvailable": true
}Run a trigger on the container
This operation lets you manually run a trigger on the container.
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/triggers/ntfy/oneFor containers managed by a remote agent, use the 4-segment variant to route the trigger through the agent:
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/triggers/ntfy/one/agent1Update a container
This operation triggers a direct container update — pulling the new image, stopping the old container, and recreating it with the updated image. This is equivalent to clicking "Update now" in the UI. Requires the Docker trigger to be configured for the container's watcher and DD_SERVER_FEATURE_CONTAINERACTIONS to be enabled.
Returns 200 with the updated container on success, 400 if no update is available, 403 if container actions are disabled, 404 if the container or Docker trigger is not found, or 500 on update failure.
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/updateUpdate container update policy (skip/snooze)
This operation lets you control per-container update suppression policy (stored in drydock DB):
skip-current: skip the currently detected remote tag or digestremove-skip: remove a single previously skipped tag or digest (requireskindandvalue)clear-skips: removeskipTagsandskipDigestssnooze: suppress update notifications until a date (supportsdaysor explicitsnoozeUntil)unsnooze: removesnoozeUntilclear: remove all update policyset-maturity-policy: require updates to be at least N days old before triggering (requiresmodeand optionallyminAgeDays)clear-maturity-policy: removematurityModeandmaturityMinAgeDays
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
-H 'Content-Type: application/json' \
-d '{"action":"skip-current"}'# Remove a single skipped tag
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
-H 'Content-Type: application/json' \
-d '{"action":"remove-skip","kind":"tag","value":"1.2.3"}'# Remove a single skipped digest
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
-H 'Content-Type: application/json' \
-d '{"action":"remove-skip","kind":"digest","value":"sha256:abc123..."}'curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
-H 'Content-Type: application/json' \
-d '{"action":"snooze","days":7}'# Require updates to be at least 14 days old before triggering
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
-H 'Content-Type: application/json' \
-d '{"action":"set-maturity-policy","mode":"mature","minAgeDays":14}'# Remove maturity policy (allow all updates regardless of age)
curl -X PATCH http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-policy \
-H 'Content-Type: application/json' \
-d '{"action":"clear-maturity-policy"}'Get security vulnerability overview
This operation returns pre-aggregated vulnerability data grouped by image across all scanned containers. Used by the Security view to display vulnerability summaries without loading every container individually.
curl http://drydock:3000/api/v1/containers/security/vulnerabilitiesThe response includes total and scanned container counts, the latest scan timestamp, and an images array where each entry groups vulnerabilities by image name with container IDs and an optional update severity summary.
Get latest vulnerability scan result
This operation returns the latest persisted vulnerability scan (safe-pull gate result) for a container.
When no scan was run yet, it returns status: "not-scanned" with an empty result set.
curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/vulnerabilitiesRun an on-demand security scan
This operation triggers a vulnerability scan, optional signature verification, and optional SBOM generation for a container. The scan targets the update candidate image when available, falling back to the current image tag. Results are persisted to container.security and the updated container is returned.
Requires DD_SECURITY_SCANNER=trivy to be configured.
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/scanRate-limited to 30 requests per minute.
Returns 200 with the updated container on success, 400 if security scanner is not configured, 404 if the container is not found, or 500 on scan failure.
Get SBOM for a container
This operation returns the latest SBOM document for a container in the requested format.
curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/sbom?format=spdx-jsonDownload container logs
Returns stdout/stderr output from a container as a downloadable text file. Supports gzip compression via Accept-Encoding: gzip header. For agent-managed containers, the request is proxied through the agent connection.
curl "http://drydock:3000/api/v1/containers/{id}/logs?tail=1000&stdout=true&stderr=true"Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
stdout | boolean | true | Include stdout output |
stderr | boolean | true | Include stderr output |
tail | integer | 1000 | Number of lines to return from the end of the log |
since | string | 0 | Unix timestamp (seconds) or ISO 8601 string — only return logs after this time |
timestamps | boolean | true | Include timestamps in output |
Returns 200 with the log text (Content-Disposition: attachment), 404 if the container is not found, or 500 on failure.
Stream container logs (WebSocket)
Opens a WebSocket connection for real-time container log streaming. The server demultiplexes Docker's binary stream format and sends individual JSON frames.
ws://drydock:3000/api/v1/containers/{id}/logs/stream?follow=true&tail=100Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
stdout | boolean | true | Include stdout output |
stderr | boolean | true | Include stderr output |
tail | integer | 100 | Number of initial lines to load |
since | string | 0 | Unix timestamp (seconds) or ISO 8601 string — only stream logs after this time |
follow | boolean | true | Continue streaming new output (set false for one-shot fetch) |
Message format
Each WebSocket message is a JSON object:
{
"type": "stdout",
"ts": "2026-03-18T19:18:38.485902360Z",
"line": "Server started on port 3000"
}| Field | Type | Description |
|---|---|---|
type | string | stdout or stderr |
ts | string | ISO 8601 timestamp from Docker |
line | string | Log line content (may contain ANSI escape codes) |
Close codes
| Code | Meaning |
|---|---|
1000 | Normal close (stream ended or client disconnect) |
4001 | Container is not running |
4004 | Container not found |
1011 | Watcher unavailable or stream error |
Authentication
WebSocket upgrade requests require a valid session cookie. Unauthenticated requests receive HTTP 401 during the upgrade handshake.
Rate limiting
WebSocket connections are rate-limited to 1,000 connections per 15-minute window per client IP (or per authenticated user when identity-aware rate limiting is enabled).
Reveal container environment variables
Returns the full (unredacted) runtime environment variables for a container. Environment values in the standard container response are redacted to *** for sensitive keys. This endpoint reveals the actual values and creates an audit trail entry.
Rate-limited to 10 requests per minute.
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/env/reveal
{
"env": [
{ "key": "TZ", "value": "America/New_York", "sensitive": false },
{ "key": "DATABASE_PASSWORD", "value": "s3cret", "sensitive": true }
]
}Response fields
| Field | Type | Description |
|---|---|---|
env[].key | string | Environment variable name |
env[].value | string | Unredacted value |
env[].sensitive | boolean | Whether the key matches known sensitive patterns (passwords, tokens, secrets) |
Returns 200 with the env array on success, 404 if the container is not found, or 429 if rate-limited.
Container action auth model: /start, /stop, /restart, and /update are authentication-gated only. In current single-operator deployments, any authenticated user can execute these actions for any container.
Start a container
This operation starts a stopped container. Requires DD_SERVER_FEATURE_CONTAINERACTIONS to be enabled.
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/startStop a container
This operation stops a running container. Requires DD_SERVER_FEATURE_CONTAINERACTIONS to be enabled.
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/stopRestart a container
This operation restarts a container. Requires DD_SERVER_FEATURE_CONTAINERACTIONS to be enabled.
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/restartPreview an update
This operation returns a dry-run preview of what an update would change, without executing it.
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/previewList all backups
Returns all image backups across all containers, optionally filtered by container name.
curl "http://drydock:3000/api/v1/containers/backups?containerName=homeassistant"
{
"data": [
{
"id": "abc123",
"containerId": "31a61a8305ef...",
"containerName": "homeassistant",
"imageName": "homeassistant/home-assistant",
"imageTag": "2024.11.3",
"imageDigest": "sha256:...",
"timestamp": "2024-12-01T10:00:00.000Z",
"triggerName": "docker.local"
}
],
"total": 1
}Query parameters
| Parameter | Type | Description |
|---|---|---|
containerName | string | Filter backups by container name |
Get container backups
This operation returns all image backups for a container, sorted by most recent first.
curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/backups
{
"data": [
{
"id": "abc123",
"containerId": "31a61a8305ef...",
"containerName": "homeassistant",
"imageName": "homeassistant/home-assistant",
"imageTag": "2021.6.4",
"imageDigest": "sha256:...",
"timestamp": "2021-06-15T10:30:00.000Z",
"triggerName": "docker.local"
}
],
"total": 1
}Rollback a container
This operation rolls back a container to a previously backed-up image. If no backupId is provided, the most recent backup is used.
Rollback is destructive and requires explicit confirmation via X-DD-Confirm-Action: container-rollback.
curl -X POST http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/rollback \
-H 'X-DD-Confirm-Action: container-rollback' \
-H 'Content-Type: application/json' \
-d '{"backupId": "abc123"}'Returns 200 on success, 404 if the container/backup/trigger is not found, or 428 if confirmation is missing.
Get update/rollback history
Returns the persisted update and rollback operation history for a container, sorted by most recent first. Each entry tracks the full lifecycle of an update (phases, status, versions, rollback reason if applicable).
curl http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816/update-operations
{
"data": [
{
"id": "a1b2c3d4-...",
"containerName": "homeassistant",
"status": "succeeded",
"phase": "succeeded",
"createdAt": "2024-12-01T10:00:00.000Z",
"updatedAt": "2024-12-01T10:01:30.000Z",
"containerId": "31a61a8305ef...",
"triggerName": "docker.local",
"fromVersion": "2024.11.3",
"toVersion": "2024.12.0",
"targetImage": "homeassistant/home-assistant:2024.12.0"
},
{
"id": "e5f6a7b8-...",
"containerName": "homeassistant",
"status": "rolled-back",
"phase": "rolled-back",
"createdAt": "2024-11-20T08:00:00.000Z",
"updatedAt": "2024-11-20T08:02:00.000Z",
"containerId": "31a61a8305ef...",
"fromVersion": "2024.11.2",
"toVersion": "2024.11.3",
"rollbackReason": "Health check failed"
}
],
"total": 2,
"limit": 0,
"offset": 0,
"hasMore": false
}Response fields
| Field | Type | Description |
|---|---|---|
id | string | Unique operation ID |
containerName | string | Container name |
status | string | in-progress, succeeded, rolled-back, or failed |
phase | string | Current phase: prepare, renamed, new-created, old-stopped, new-started, health-gate, health-gate-passed, succeeded, rollback-started, rolled-back, rollback-failed |
createdAt | string | ISO 8601 timestamp when the operation started |
updatedAt | string | ISO 8601 timestamp of the last phase transition |
containerId | string | Container ID |
triggerName | string | Trigger that initiated the update |
fromVersion | string | Previous image tag or digest |
toVersion | string | Target image tag or digest |
targetImage | string | Full target image reference |
rollbackReason | string | Reason for rollback (only present on rolled-back operations) |
lastError | string | Error message (only present on failed operations) |
Returns 200 with the operations array on success, or 404 if the container is not found.
Get container stats
GET /api/v1/containers/stats
Returns CPU and memory usage stats for all monitored containers.
Response
| Field | Type | Description |
|---|---|---|
data | array | Array of container stat objects |
data[].id | string | Container ID |
data[].name | string | Container name |
data[].stats | object | Latest stats snapshot |
data[].stats.cpuPercent | number | CPU usage percentage |
data[].stats.memoryUsageBytes | number | Memory usage in bytes |
data[].stats.memoryLimitBytes | number | Memory limit in bytes |
data[].stats.memoryPercent | number | Memory usage percentage |
data[].stats.networkRxBytes | number | Network bytes received |
data[].stats.networkTxBytes | number | Network bytes transmitted |
data[].stats.timestamp | string | ISO 8601 timestamp |
Get single container stats
GET /api/v1/containers/:id/stats
Returns the latest stats snapshot and history for a single container.
Response
| Field | Type | Description |
|---|---|---|
data | object | Latest stats snapshot |
history | array | Array of historical snapshots |
Stream container stats (SSE)
GET /api/v1/containers/:id/stats/stream
Server-Sent Events stream for real-time container stats. Sends dd:container-stats events with the latest snapshot and dd:heartbeat events every 15 seconds.
Get container release notes
GET /api/v1/containers/:id/release-notes
Returns GitHub release notes for the container's available update, if available.
Delete a Container
This operation lets you delete a container by id. Requires DD_SERVER_FEATURE_DELETE to be enabled.
Delete is destructive and requires explicit confirmation via X-DD-Confirm-Action: container-delete.
curl -X DELETE http://drydock:3000/api/v1/containers/31a61a8305ef1fc9a71fa4f20a68d7ec88b28e32303bbc4a5f192e851165b816 \
-H 'X-DD-Confirm-Action: container-delete'Returns 204 on success, 403 if delete is disabled, 404 if the container does not exist, or 428 if confirmation is missing.