A lightweight Go HTTP API for managing Docker containers via the Docker Engine API. Provides a clean REST interface with API key authentication, structured JSON responses, and real-time log streaming.
- Full container lifecycle management (create, list, inspect, stop, remove)
- Host file writing with configurable permissions
- Real-time log streaming via Server-Sent Events (SSE)
- API key authentication on all protected routes
- Resource limits (CPU, memory) per container
- Port mappings, volume mounts, network configuration
- Restart policies
- Health check endpoint with Docker daemon status
- Structured JSON logging with request IDs
- Graceful shutdown
- Go 1.25+
- Docker daemon running and accessible
# Build
go build ./cmd/dockeragent
# Run
API_KEY=your-secret-key go run ./cmd/dockeragentOr use the Makefile:
make build # compile to ./dist/dockeragent
make run # go run
make vet # lint
make clean # remove build artifactsdocker build -t dockeragent .
docker run -d \
-e API_KEY=your-secret-key \
-p 3000:3000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /:/host \
dockeragent| Variable | Required | Default | Description |
|---|---|---|---|
API_KEY |
Yes | - | API key for authenticating requests |
LISTEN_ADDR |
No | :3000 |
Address the server listens on |
DOCKER_HOST |
No | - | Docker daemon socket/host |
DOCKER_API_VERSION |
No | - | Docker API version override |
All /api/v1/* routes require the X-API-Key header.
GET /health
Returns server and Docker daemon status. No authentication required.
{
"status": "ok",
"docker": "connected",
"timestamp": "2026-02-21T10:00:00Z"
}POST /api/v1/containers
{
"image": "nginx:latest",
"name": "web-server",
"cmd": ["nginx", "-g", "daemon off;"],
"env": ["NODE_ENV=production"],
"ports": [
{
"container_port": "80",
"host_port": "8080",
"protocol": "tcp",
"host_ip": "0.0.0.0"
}
],
"volumes": [
{
"source": "/host/data",
"target": "/container/data",
"read_only": false
}
],
"networks": ["my-network"],
"restart_policy": {
"name": "always"
},
"resources": {
"cpus": 1.5,
"memory_mb": 512
}
}Response (201 Created):
{
"id": "abc123def456...",
"warnings": []
}GET /api/v1/containers?all=true
| Query Param | Default | Description |
|---|---|---|
all |
false |
Include stopped containers |
GET /api/v1/containers/:id
Returns the full Docker inspect response for the container.
POST /api/v1/containers/:id/stop
{
"timeout": 10,
"signal": "SIGTERM"
}DELETE /api/v1/containers/:id?force=true&v=true
| Query Param | Default | Description |
|---|---|---|
force |
false |
Force remove a running container |
v |
false |
Remove associated anonymous volumes |
GET /api/v1/containers/:id/logs?tail=100&follow=false
| Query Param | Default | Description |
|---|---|---|
follow |
false |
Stream logs in real-time via SSE |
tail |
all |
Number of lines from the end |
since |
- | Show logs since timestamp |
until |
- | Show logs until timestamp |
timestamps |
false |
Include timestamps in log lines |
Non-follow response:
{
"lines": [
"2026-02-21 10:00:00 Server started",
"2026-02-21 10:00:01 Listening on port 80"
]
}Follow mode streams as text/event-stream (SSE).
POST /api/v1/files
Writes a file to the host filesystem. Parent directories are created automatically.
{
"path": "/etc/nginx/nginx.conf",
"content": "server { listen 80; }",
"permission": "0644"
}| Field | Required | Default | Description |
|---|---|---|---|
path |
Yes | - | Absolute file path on the host |
content |
No | "" |
File content as a string |
permission |
No | 0644 |
Unix file permission (octal string) |
Response (201 Created):
{
"path": "/etc/nginx/nginx.conf",
"size": 21,
"message": "file written successfully"
}All errors return a consistent JSON envelope:
{
"error": "Not Found",
"message": "no such container: abc123",
"status": 404
}Request -> recover -> requestid -> requestLogger -> [keyauth] -> handler -> service -> Docker daemon
| Layer | Responsibility |
|---|---|
handler |
HTTP concerns: parse input, validate, return JSON |
service |
Translate between API models and Docker API types |
model |
Pure data types for API request/response contracts |
router |
Middleware chain and route registration |
middleware |
API key authentication via X-API-Key header |
MIT