Skip to content
This page was translated with AI and may contain inaccuracies. Help improve it on GitHub.

Docker Management API ​

Prefix /api/docker, JSON. Errors are always returned as {"error":"..."}. All write endpoints require Content-Type: application/json (except file uploads). Long-running operations (pulling/pushing/building images, compose up, and so on) return {"task":"<taskId>"}; poll /tasks/{id} for progress.

System and settings ​

MethodPathDescription
GET/info{version,apiVersion,os,arch,kernel,name,cpus,memTotal,storageDriver,rootDir,containers:{total,running,paused,stopped},images,composeCli:bool,composeCliVersion,daemonMirrors:string[]}
GET/disk-usage{images:{count,size,reclaimable},containers:{count,size,reclaimable},volumes:{count,size,reclaimable},buildCache:{count,size,reclaimable}}
POST/prune`{target:"containers"
GET/PUT/settings{host, mirrors:string[], registries:[{server,username,password}], autoCheckHours:number}. GET returns registries[].password as "******"; when PUT receives "******", the existing value is kept
GET/tasksTask list (without lines)
GET/tasks/{id}Task details `{id,kind,title,status:"running"
DELETE/tasksClear finished tasks
GET/logsModule operation log (existing)

Containers ​

ContainerView (list item; existing fields are kept) gains: imageId, networks:string[], mounts:number, and started (RFC3339, present only while running).

MethodPathDescription
GET/containersList (including stopped containers)
GET/containers/{id}Details; see ContainerDetail below
POST/containersCreate; see ContainerSpec for the body. With pull:true, the image is pulled first if missing; autoStart starts the container after creation; returns {id}
POST/containers/{id}/editRecreate the container from a ContainerSpec (same rollback flow as upgrade); returns {id}
POST/containers/{id}/{action}action ∈ start stop restart pause unpause kill
DELETE/containers/{id}?volumes=1Force delete; volumes=1 also deletes anonymous volumes
POST/containers/{id}/rename{name}
POST/containers/{id}/commit{repo,tag,comment,pause?:bool} → {id}
GET/containers/{id}/logs?tail=300&timestamps=1{logs} (existing; adds the timestamps parameter, default 1)
GET/containers/{id}/statsSingle sample {cpuPercent,memUsage,memLimit,memPercent,netRx,netTx,blockRead,blockWrite,pids}
GET/containers/{id}/processes{titles:string[],processes:string[][]}
GET/containers/{id}/execWebSocket. Query parameters: cmd (default /bin/sh; may contain space-separated arguments), cols, rows, user. The protocol matches the Web Terminal: the client sends text JSON {"t":"i","d":"input"} / {"t":"r","c":cols,"r":rows}, and the server sends binary output; error messages are sent as text {"d":"..."}. Rejected if the container is not running
POST/containers/check-allCheck every running container for image updates one by one (a task); returns {task}; results are written to each container's update field
POST/containers/{id}/check /upgradeExisting; unchanged
POST/containers/upgrade-batch{ids:string[]} upgrades them in sequence (a task); returns {task}

Container files ​

All paths are absolute paths inside the container, implemented through the Engine's archive API.

MethodPathDescription
GET/containers/{id}/files/list?path=/[{name,path,dir:bool,size,mode,modified,link?:string}]; directories first, then sorted by name
GET/containers/{id}/files/read?path={content,size,truncated}; text only, at most 1MiB; binary files return 400
GET/containers/{id}/files/download?path=Files download directly; directories are packed as tar.gz
POST/containers/{id}/files/write{path,content} overwrites the file (keeps the original permissions; new files get 0644)
POST/containers/{id}/files/mkdir{path}
POST/containers/{id}/files/rename{from,to}
POST/containers/{id}/files/uploadmultipart: field path (target directory) + file (may repeat)
DELETE/containers/{id}/files?path=Delete (the archive API cannot delete, so this runs rm -rf through exec; the container must be running)

ContainerSpec ​

json
{
  "name": "web",
  "image": "nginx:latest",
  "pull": false,
  "autoStart": true,
  "command": "nginx -g 'daemon off;'",      // shell-style string; empty uses the image default
  "entrypoint": "",                         // same as above
  "env": ["A=1", "B=2"],
  "ports": [{"hostIp":"","host":8080,"container":80,"proto":"tcp"}],
  "volumes": [{"type":"bind","source":"/data","target":"/data","readOnly":false},
              {"type":"volume","source":"myvol","target":"/var/lib/x","readOnly":false}],
  "network": "bridge",                      // network name; "host" / "none" go here too
  "networks": ["extra1"],                   // additional networks to join
  "ip": "",                                 // fixed IP on the primary network; may be empty
  "aliases": [],
  "restart": "unless-stopped",              // no / always / unless-stopped / on-failure
  "restartMaxRetries": 0,
  "privileged": false,
  "capAdd": [], "capDrop": [],
  "devices": [{"host":"/dev/ttyUSB0","container":"/dev/ttyUSB0","perm":"rwm"}],
  "user": "", "workdir": "", "hostname": "",
  "dns": [],
  "labels": {"k":"v"},
  "memoryMB": 0, "cpus": 0,                 // 0 means unlimited
  "tty": false, "stdinOpen": false
}

GET /containers/{id} returns ContainerDetail: all fields of ContainerSpec (used to prefill the edit form; settings that cannot be reconstructed keep their original values, and when editing, the container is recreated from the original configuration with only the fields present in the spec overridden), plus id, state, status, created, started, imageId, path, args, mounts:[{type,name,source,destination,rw}], networkDetails:[{name,ip,gateway,mac,aliases}], exitCode, restartCount, healthStatus, composeProject, and composeService.

Images ​

MethodPathDescription
GET/images[{id,tags:string[],digests:string[],size,created,containers:number,dangling:bool}]
GET/images/{id}Details {id,tags,size,created,os,arch,author,cmd,entrypoint,env,exposedPorts,workdir,user,labels,layers:[{createdBy,size,created}]}
POST/images/pull{ref} → {task}; authenticates with the registries from settings. If the pull fails and mirrors are configured, each mirror is tried in turn and the image is re-tagged back to its original name
POST/images/push{ref} → {task}
POST/images/search{term,limit?} → Docker Hub search results [{name,description,stars,official}]
POST/images/{id}/tag{repo,tag}
DELETE/images/{id}?force=1Delete; id may also be name:tag (URL-encoded)
POST/images/loadThe request body is a tar produced by docker save (Content-Type: application/x-tar); returns {output}
GET/images/{id}/exportDownload a docker save tar
POST/images/build{tag, dockerfile?, gitUrl?, buildArgs?:{}}; provide exactly one of dockerfile (inline Dockerfile text) or gitUrl (remote context); returns {task}
POST/images/upgrade-checkCheck all containers whose image reference has an update; equivalent to containers/check-all

Networks ​

MethodPathDescription
GET/networks[{id,name,driver,scope,subnet,gateway,internal,ipv6,builtin:bool,containers:[{id,name,ip}]}]
POST/networks{name,driver?:"bridge",subnet?,gateway?,internal?,attachable?,ipv6?} → {id}
DELETE/networks/{id}Delete
POST/networks/{id}/connect{container,aliases?:[],ip?}
POST/networks/{id}/disconnect{container,force?:bool}

Volumes ​

MethodPathDescription
GET/volumes[{name,driver,mountpoint,created,size,refCount,usedBy:[{id,name}],labels}]; size comes from disk-usage, and is -1 when unknown
POST/volumes{name,driver?:"local"}
DELETE/volumes/{name}?force=1Delete
GET/volumes/{name}/exportPacks the volume into a tar.gz download using a temporary helper container (alpine, pulled automatically if missing)
POST/volumes/{name}/importThe request body is a tar.gz (Content-Type: application/gzip), extracted into the volume (created if it does not exist); returns {ok:true}

Compose ​

Projects are aggregated from the container labels com.docker.compose.project / .service / .project.working_dir / .project.config_files. start / stop / restart / down are performed directly through the Engine API. up / pull / build and file reads and writes depend on the docker compose CLI and on access to the compose file path; when unavailable, they return 501 with a clear message.

MethodPathDescription
GET/compose/projects`[{name,workingDir,configFiles:string[],status:"running"
POST/compose/projects{name,content} creates a new project (writes compose/<name>/compose.yaml) and runs up; returns {task}
POST/compose/{project}/{action}action ∈ start stop restart down pause unpause (down supports ?volumes=1 to also delete named volumes)
POST/compose/{project}/updocker compose up -d (?build=1, ?pull=1); returns {task}
POST/compose/{project}/pullPull the project's images; returns {task}
GET/compose/{project}/config{path,content,writable}; reads the first compose file
PUT/compose/{project}/config{content} writes it back; with ?apply=1, runs up right after writing and returns {task} (otherwise {ok:true})
GET/compose/{project}/logs?tail=300Aggregates the logs of every service container, prefixing each line with `service
DELETE/compose/{project}Managed projects only: runs down, then deletes the project directory

Not included ​

Container grouping and ordering (a UI preference only), daemon-level registry mirrors (would require modifying the host's daemon.json; use Gately's own mirrors setting instead), and scheduled backups of volumes and Compose projects (to be handled later by the scheduled tasks module).

Released under the Apache-2.0 license.