codeforge-dev 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devcontainer/.env +22 -0
- package/.devcontainer/CHANGELOG.md +197 -0
- package/.devcontainer/CLAUDE.md +117 -0
- package/.devcontainer/README.md +222 -0
- package/.devcontainer/config/main-system-prompt.md +502 -0
- package/.devcontainer/config/settings.json +47 -0
- package/.devcontainer/devcontainer.json +94 -0
- package/.devcontainer/features/README.md +113 -0
- package/.devcontainer/features/agent-browser/README.md +65 -0
- package/.devcontainer/features/agent-browser/devcontainer-feature.json +23 -0
- package/.devcontainer/features/agent-browser/install.sh +79 -0
- package/.devcontainer/features/ast-grep/README.md +24 -0
- package/.devcontainer/features/ast-grep/devcontainer-feature.json +24 -0
- package/.devcontainer/features/ast-grep/install.sh +51 -0
- package/.devcontainer/features/ccstatusline/README.md +296 -0
- package/.devcontainer/features/ccstatusline/devcontainer-feature.json +19 -0
- package/.devcontainer/features/ccstatusline/install.sh +290 -0
- package/.devcontainer/features/ccusage/README.md +205 -0
- package/.devcontainer/features/ccusage/devcontainer-feature.json +38 -0
- package/.devcontainer/features/ccusage/install.sh +132 -0
- package/.devcontainer/features/claude-code/README.md +498 -0
- package/.devcontainer/features/claude-code/config/settings.json +36 -0
- package/.devcontainer/features/claude-code/config/system-prompt.md +118 -0
- package/.devcontainer/features/claude-code/config/world-building-sp.md +1432 -0
- package/.devcontainer/features/claude-code/devcontainer-feature.json +42 -0
- package/.devcontainer/features/claude-code/install.sh +466 -0
- package/.devcontainer/features/claude-monitor/README.md +74 -0
- package/.devcontainer/features/claude-monitor/devcontainer-feature.json +38 -0
- package/.devcontainer/features/claude-monitor/install.sh +99 -0
- package/.devcontainer/features/lsp-servers/README.md +85 -0
- package/.devcontainer/features/lsp-servers/devcontainer-feature.json +40 -0
- package/.devcontainer/features/lsp-servers/install.sh +116 -0
- package/.devcontainer/features/mcp-qdrant/CHANGES.md +399 -0
- package/.devcontainer/features/mcp-qdrant/README.md +474 -0
- package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +57 -0
- package/.devcontainer/features/mcp-qdrant/install.sh +295 -0
- package/.devcontainer/features/mcp-qdrant/poststart-hook.sh +129 -0
- package/.devcontainer/features/mcp-reasoner/README.md +177 -0
- package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +20 -0
- package/.devcontainer/features/mcp-reasoner/install.sh +177 -0
- package/.devcontainer/features/mcp-reasoner/poststart-hook.sh +67 -0
- package/.devcontainer/features/notify-hook/README.md +86 -0
- package/.devcontainer/features/notify-hook/devcontainer-feature.json +23 -0
- package/.devcontainer/features/notify-hook/install.sh +38 -0
- package/.devcontainer/features/splitrail/README.md +140 -0
- package/.devcontainer/features/splitrail/devcontainer-feature.json +34 -0
- package/.devcontainer/features/splitrail/install.sh +129 -0
- package/.devcontainer/features/tree-sitter/README.md +138 -0
- package/.devcontainer/features/tree-sitter/devcontainer-feature.json +52 -0
- package/.devcontainer/features/tree-sitter/install.sh +173 -0
- package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +106 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-file.py +101 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py +137 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/.claude-plugin/plugin.json +8 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/SKILL.md +387 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/references/cli-flags-and-output.md +312 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/claude-code-headless/references/sdk-and-mcp.md +569 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/SKILL.md +309 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/references/compose-services.md +438 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker/references/dockerfile-patterns.md +340 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/SKILL.md +412 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/references/container-lifecycle.md +388 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/docker-py/references/resources-and-security.md +444 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/SKILL.md +344 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/middleware-and-lifespan.md +254 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/pydantic-models.md +245 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/routing-and-dependencies.md +255 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/fastapi/references/sse-and-streaming.md +318 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/SKILL.md +345 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/references/agents-and-tools.md +271 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/pydantic-ai/references/models-and-streaming.md +422 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/SKILL.md +220 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/cross-vendor-principles.md +139 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/patterns-and-antipatterns.md +376 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/skill-building/references/skill-authoring-patterns.md +356 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/SKILL.md +329 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/advanced-queries.md +314 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/javascript-patterns.md +323 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/python-patterns.md +354 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/sqlite/references/schema-and-pragmas.md +326 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/SKILL.md +356 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/ai-sdk-svelte.md +128 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/component-patterns.md +332 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/layercake.md +203 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/migration-guide.md +350 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/runes-and-reactivity.md +328 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/spa-and-routing.md +262 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/svelte5/references/svelte-dnd-action.md +181 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/SKILL.md +414 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/references/fastapi-testing.md +411 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codedirective-skills/skills/testing/references/svelte-testing.md +538 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/codeforge-lsp/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py +110 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/hooks/hooks.json +17 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py +108 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272create-pr.md +337 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272new.md +166 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272review-commit.md +290 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/commands/ticket/357/200/272work.md +257 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/plugin.json +8 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/.claude-plugin/system-prompt.md +184 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/.claude-plugin/plugin.json +6 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/config/planning-instructions.md +14 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/functional-conjuring-map.md +989 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/hooks/hooks.json +33 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/__pycache__/post-enhance-task.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhance-planning.py +71 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-plan.sh +68 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-task.sh +120 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-plan.py +133 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-task.py +253 -0
- package/.devcontainer/scripts/setup-aliases.sh +80 -0
- package/.devcontainer/scripts/setup-config.sh +28 -0
- package/.devcontainer/scripts/setup-irie-claude.sh +32 -0
- package/.devcontainer/scripts/setup-plugins.sh +80 -0
- package/.devcontainer/scripts/setup.sh +58 -0
- package/LICENSE.txt +674 -0
- package/README.md +267 -0
- package/package.json +44 -0
- package/setup.js +83 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: docker-py
|
|
3
|
+
description: >-
|
|
4
|
+
This skill should be used when the user asks to "manage Docker containers from Python",
|
|
5
|
+
"create containers programmatically", "stream Docker container logs",
|
|
6
|
+
"execute commands in a running container", "manage Docker volumes from code",
|
|
7
|
+
"build images with the Docker SDK", "use docker-py for container lifecycle",
|
|
8
|
+
"monitor container health from Python", or discusses docker-py,
|
|
9
|
+
aiodocker, programmatic container management, or Docker Engine API.
|
|
10
|
+
version: 0.1.0
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Docker SDK for Python
|
|
14
|
+
|
|
15
|
+
## Mental Model
|
|
16
|
+
|
|
17
|
+
The Docker SDK for Python (`docker-py`) provides **programmatic access to the Docker Engine API**. Where Dockerfiles and Compose files declare static configuration, the SDK enables dynamic container lifecycle management -- creating, starting, stopping, and inspecting containers at runtime from application code.
|
|
18
|
+
|
|
19
|
+
The SDK mirrors the Docker CLI's resource model: a `DockerClient` exposes collections (`.containers`, `.images`, `.volumes`, `.networks`), each with CRUD methods. Container objects are stateful handles -- they cache inspection data and expose methods like `.exec_run()`, `.logs()`, and `.stop()`. Call `.reload()` to refresh cached state from the daemon.
|
|
20
|
+
|
|
21
|
+
For async applications (FastAPI, event-driven systems), `aiodocker` provides an asyncio-native alternative with a similar API surface but different method signatures. The core Docker Engine API is the same underneath both libraries.
|
|
22
|
+
|
|
23
|
+
Assume `docker>=7.0` (the `docker` PyPI package) for all new code. Distinguish this skill from the docker skill (Dockerfiles and Compose), which covers static build and orchestration configuration.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Client Initialization
|
|
28
|
+
|
|
29
|
+
Two primary initialization patterns:
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
import docker
|
|
33
|
+
|
|
34
|
+
# From environment (reads DOCKER_HOST, DOCKER_TLS_VERIFY, DOCKER_CERT_PATH)
|
|
35
|
+
client = docker.from_env()
|
|
36
|
+
|
|
37
|
+
# Direct connection
|
|
38
|
+
client = docker.DockerClient(base_url="unix:///var/run/docker.sock")
|
|
39
|
+
|
|
40
|
+
# TCP with TLS
|
|
41
|
+
client = docker.DockerClient(base_url="tcp://192.168.1.10:2376", tls=True)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`from_env()` is the standard pattern for both local development and production. It auto-detects the Docker socket and API version. Key parameters: `timeout` (seconds), `max_pool_size` (connection pool), `use_ssh_client` (SSH transport).
|
|
45
|
+
|
|
46
|
+
### Connection Verification
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
client.ping() # Returns True if daemon is reachable
|
|
50
|
+
client.version() # Returns API version info dict
|
|
51
|
+
client.info() # Returns system-wide daemon information
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Container Lifecycle
|
|
57
|
+
|
|
58
|
+
All container operations live under `client.containers`.
|
|
59
|
+
|
|
60
|
+
### Create and Run
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
# Run detached (create + start, returns Container object)
|
|
64
|
+
container = client.containers.run(
|
|
65
|
+
"python:3.12-slim",
|
|
66
|
+
command="python -m http.server 8000",
|
|
67
|
+
name="my-server",
|
|
68
|
+
detach=True,
|
|
69
|
+
ports={"8000/tcp": 8080},
|
|
70
|
+
environment={"DEBUG": "1"},
|
|
71
|
+
labels={"app": "web", "env": "dev"},
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# Create without starting
|
|
75
|
+
container = client.containers.create(
|
|
76
|
+
"alpine:latest",
|
|
77
|
+
command="sleep 3600",
|
|
78
|
+
name="worker",
|
|
79
|
+
)
|
|
80
|
+
container.start()
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Key `run()` parameters:
|
|
84
|
+
|
|
85
|
+
- **`detach=True`**: Run in background, return `Container` object. Without this, `run()` blocks and returns logs.
|
|
86
|
+
- **`ports`**: Port mapping dict: `{"80/tcp": 8080}` or `{"80/tcp": ("127.0.0.1", 8080)}`.
|
|
87
|
+
- **`volumes`**: Dict syntax: `{"/host/path": {"bind": "/container/path", "mode": "rw"}}`.
|
|
88
|
+
- **`mounts`**: Preferred over `volumes`. Uses `docker.types.Mount` objects.
|
|
89
|
+
- **`environment`**: Dict `{"KEY": "val"}` or list `["KEY=val"]`.
|
|
90
|
+
- **`remove=True`**: Auto-remove container when it exits.
|
|
91
|
+
- **`network`**: Connect to a network at creation time.
|
|
92
|
+
- **`user`**: Run as specific UID or username.
|
|
93
|
+
- **`working_dir`**: Set the working directory inside the container.
|
|
94
|
+
- **`init=True`**: Run init process as PID 1 (proper signal forwarding).
|
|
95
|
+
|
|
96
|
+
### List and Inspect
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
# All running containers
|
|
100
|
+
containers = client.containers.list()
|
|
101
|
+
|
|
102
|
+
# Include stopped containers
|
|
103
|
+
containers = client.containers.list(all=True)
|
|
104
|
+
|
|
105
|
+
# Filter by label
|
|
106
|
+
containers = client.containers.list(filters={"label": "app=web"})
|
|
107
|
+
|
|
108
|
+
# Get a specific container
|
|
109
|
+
container = client.containers.get("my-server")
|
|
110
|
+
print(container.status) # "running", "exited", "created", etc.
|
|
111
|
+
print(container.name)
|
|
112
|
+
print(container.short_id)
|
|
113
|
+
print(container.labels)
|
|
114
|
+
print(container.attrs) # Full inspection dict
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Stop, Remove, Wait
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
container.stop(timeout=10) # SIGTERM, then SIGKILL after timeout
|
|
121
|
+
container.kill(signal="SIGTERM") # Send specific signal
|
|
122
|
+
container.restart(timeout=10)
|
|
123
|
+
container.pause()
|
|
124
|
+
container.unpause()
|
|
125
|
+
container.remove(force=True) # force=True kills if running
|
|
126
|
+
|
|
127
|
+
# Wait for exit (blocking)
|
|
128
|
+
result = container.wait(timeout=60)
|
|
129
|
+
print(result["StatusCode"]) # 0 for success
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
> **Deep dive:** See `references/container-lifecycle.md` for exec_run patterns, log streaming, health check configuration, health status polling, auto-remove patterns, and the wait/timeout API.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Executing Commands in Containers
|
|
137
|
+
|
|
138
|
+
`exec_run()` executes a command inside a running container:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
# Basic execution
|
|
142
|
+
result = container.exec_run("ls -la /app")
|
|
143
|
+
print(result.exit_code) # int
|
|
144
|
+
print(result.output) # bytes
|
|
145
|
+
|
|
146
|
+
# Streaming output
|
|
147
|
+
result = container.exec_run("tail -f /var/log/app.log", stream=True)
|
|
148
|
+
for chunk in result.output:
|
|
149
|
+
print(chunk.decode(), end="")
|
|
150
|
+
|
|
151
|
+
# Separated stdout/stderr
|
|
152
|
+
result = container.exec_run("some_command", demux=True)
|
|
153
|
+
stdout, stderr = result.output # tuple of (bytes | None, bytes | None)
|
|
154
|
+
|
|
155
|
+
# With environment and working directory
|
|
156
|
+
result = container.exec_run(
|
|
157
|
+
"python migrate.py",
|
|
158
|
+
environment={"DB_URL": "sqlite:///app.db"},
|
|
159
|
+
workdir="/app",
|
|
160
|
+
user="appuser",
|
|
161
|
+
)
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Key parameters: `stream` (return generator), `demux` (separate stdout/stderr), `detach` (fire-and-forget), `privileged` (extended privileges), `tty` (allocate pseudo-TTY).
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Log Streaming
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
# All logs as bytes
|
|
172
|
+
logs = container.logs()
|
|
173
|
+
|
|
174
|
+
# Stream in real-time (blocking generator)
|
|
175
|
+
for line in container.logs(stream=True, follow=True):
|
|
176
|
+
print(line.decode().strip())
|
|
177
|
+
|
|
178
|
+
# Tail last N lines
|
|
179
|
+
logs = container.logs(tail=100)
|
|
180
|
+
|
|
181
|
+
# Since a specific time
|
|
182
|
+
from datetime import datetime, timedelta
|
|
183
|
+
logs = container.logs(since=datetime.utcnow() - timedelta(hours=1))
|
|
184
|
+
|
|
185
|
+
# With timestamps
|
|
186
|
+
logs = container.logs(timestamps=True)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
`stream=True` returns a generator; `follow=True` keeps the connection open for new output. Combine both for real-time log tailing.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Image Management
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
# Pull an image
|
|
197
|
+
image = client.images.pull("python", tag="3.12-slim")
|
|
198
|
+
|
|
199
|
+
# Build from Dockerfile
|
|
200
|
+
image, build_logs = client.images.build(
|
|
201
|
+
path="/path/to/context",
|
|
202
|
+
tag="myapp:latest",
|
|
203
|
+
buildargs={"VERSION": "1.0"},
|
|
204
|
+
target="production",
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
# List and search
|
|
208
|
+
images = client.images.list()
|
|
209
|
+
dangling = client.images.list(filters={"dangling": True})
|
|
210
|
+
|
|
211
|
+
# Tag and push
|
|
212
|
+
image.tag("registry.example.com/myapp", tag="v1.0")
|
|
213
|
+
client.images.push("registry.example.com/myapp", tag="v1.0")
|
|
214
|
+
|
|
215
|
+
# Clean up
|
|
216
|
+
client.images.prune(filters={"dangling": True})
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
> **Deep dive:** See `references/resources-and-security.md` for volume management, bind mount patterns, network operations, resource limits (CPU, memory, I/O), security options, and the aiodocker async alternative.
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## Volumes and Bind Mounts
|
|
224
|
+
|
|
225
|
+
### Named Volumes
|
|
226
|
+
|
|
227
|
+
```python
|
|
228
|
+
volume = client.volumes.create(name="app-data", labels={"env": "prod"})
|
|
229
|
+
|
|
230
|
+
container = client.containers.run(
|
|
231
|
+
"myapp",
|
|
232
|
+
detach=True,
|
|
233
|
+
volumes={"app-data": {"bind": "/data", "mode": "rw"}},
|
|
234
|
+
)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Mount Objects (Preferred)
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
from docker.types import Mount
|
|
241
|
+
|
|
242
|
+
container = client.containers.run(
|
|
243
|
+
"myapp",
|
|
244
|
+
detach=True,
|
|
245
|
+
mounts=[
|
|
246
|
+
Mount(target="/data", source="app-data", type="volume"),
|
|
247
|
+
Mount(target="/config", source="/host/config", type="bind", read_only=True),
|
|
248
|
+
],
|
|
249
|
+
)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
`Mount` objects are explicit about mount type and read-only status. Prefer them over the dict-based `volumes` syntax. Mount types: `"volume"` (Docker-managed), `"bind"` (host filesystem path), `"tmpfs"` (memory-backed, ephemeral).
|
|
253
|
+
|
|
254
|
+
### Volume Lifecycle
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
# List all volumes
|
|
258
|
+
volumes = client.volumes.list(filters={"label": "env=prod"})
|
|
259
|
+
|
|
260
|
+
# Remove a specific volume
|
|
261
|
+
volume = client.volumes.get("app-data")
|
|
262
|
+
volume.remove()
|
|
263
|
+
|
|
264
|
+
# Prune unused volumes (not attached to any container)
|
|
265
|
+
result = client.volumes.prune()
|
|
266
|
+
print(f"Reclaimed: {result['SpaceReclaimed']} bytes")
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Volumes persist independently of containers. Removing a container does not remove its volumes unless `container.remove(v=True)` is called explicitly.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Network Operations
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
# Create a network
|
|
277
|
+
network = client.networks.create("app-net", driver="bridge")
|
|
278
|
+
|
|
279
|
+
# Connect a container with DNS aliases
|
|
280
|
+
network.connect(container, aliases=["web", "frontend"])
|
|
281
|
+
|
|
282
|
+
# Connect with static IP (requires IPAM configuration on the network)
|
|
283
|
+
network.connect(container, ipv4_address="192.168.52.10")
|
|
284
|
+
|
|
285
|
+
# Disconnect
|
|
286
|
+
network.disconnect(container)
|
|
287
|
+
|
|
288
|
+
# List connected containers
|
|
289
|
+
network.reload()
|
|
290
|
+
for c in network.containers:
|
|
291
|
+
print(f"{c.name}: {c.status}")
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Networks enable container-to-container communication via DNS names. Containers on the same network can reach each other by container name or by aliases specified during `connect()`. Use `internal=True` when creating a network to block external access entirely.
|
|
295
|
+
|
|
296
|
+
### Network IPAM Configuration
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
import docker.types
|
|
300
|
+
|
|
301
|
+
ipam_pool = docker.types.IPAMPool(subnet="192.168.52.0/24", gateway="192.168.52.254")
|
|
302
|
+
ipam_config = docker.types.IPAMConfig(pool_configs=[ipam_pool])
|
|
303
|
+
|
|
304
|
+
network = client.networks.create(
|
|
305
|
+
"isolated-net",
|
|
306
|
+
driver="bridge",
|
|
307
|
+
ipam=ipam_config,
|
|
308
|
+
internal=True,
|
|
309
|
+
attachable=True,
|
|
310
|
+
)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Health Check Monitoring
|
|
316
|
+
|
|
317
|
+
Configure health checks at container creation and poll the status programmatically:
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
SECOND = 1_000_000_000 # nanosecond conversion constant
|
|
321
|
+
|
|
322
|
+
container = client.containers.run(
|
|
323
|
+
"myapp:latest",
|
|
324
|
+
detach=True,
|
|
325
|
+
healthcheck={
|
|
326
|
+
"test": ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"],
|
|
327
|
+
"interval": 10 * SECOND,
|
|
328
|
+
"timeout": 5 * SECOND,
|
|
329
|
+
"retries": 3,
|
|
330
|
+
"start_period": 30 * SECOND,
|
|
331
|
+
},
|
|
332
|
+
)
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
All healthcheck time values are in **nanoseconds**. Define a `SECOND` constant for readability.
|
|
336
|
+
|
|
337
|
+
### Polling Health Status
|
|
338
|
+
|
|
339
|
+
```python
|
|
340
|
+
import time
|
|
341
|
+
|
|
342
|
+
def wait_for_healthy(container, timeout=60, interval=2):
|
|
343
|
+
"""Block until the container reports healthy or raise on failure."""
|
|
344
|
+
deadline = time.monotonic() + timeout
|
|
345
|
+
while time.monotonic() < deadline:
|
|
346
|
+
container.reload()
|
|
347
|
+
health = container.attrs.get("State", {}).get("Health", {})
|
|
348
|
+
status = health.get("Status", "none")
|
|
349
|
+
if status == "healthy":
|
|
350
|
+
return True
|
|
351
|
+
if status == "unhealthy":
|
|
352
|
+
logs = health.get("Log", [])
|
|
353
|
+
last = logs[-1] if logs else {}
|
|
354
|
+
raise RuntimeError(f"Unhealthy: {last.get('Output', '')[:200]}")
|
|
355
|
+
time.sleep(interval)
|
|
356
|
+
raise TimeoutError(f"Container not healthy within {timeout}s")
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
The health status is stored in `container.attrs["State"]["Health"]` and includes the current status (`"starting"`, `"healthy"`, `"unhealthy"`), the failing streak count, and a log of recent check results.
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Error Handling
|
|
364
|
+
|
|
365
|
+
The SDK exposes specific exception types for precise error handling:
|
|
366
|
+
|
|
367
|
+
```python
|
|
368
|
+
from docker.errors import ContainerError, ImageNotFound, NotFound, APIError
|
|
369
|
+
from requests.exceptions import ReadTimeout
|
|
370
|
+
|
|
371
|
+
try:
|
|
372
|
+
container = client.containers.run("myapp", detach=True)
|
|
373
|
+
result = container.wait(timeout=60)
|
|
374
|
+
except ImageNotFound:
|
|
375
|
+
# Image needs to be pulled first
|
|
376
|
+
client.images.pull("myapp", tag="latest")
|
|
377
|
+
except NotFound:
|
|
378
|
+
# Container was auto-removed before inspection
|
|
379
|
+
pass
|
|
380
|
+
except ContainerError as e:
|
|
381
|
+
print(f"Exit code: {e.exit_status}")
|
|
382
|
+
print(f"Stderr: {e.stderr.decode()}")
|
|
383
|
+
except ReadTimeout:
|
|
384
|
+
# wait() exceeded the timeout; stop the container manually
|
|
385
|
+
container.stop(timeout=5)
|
|
386
|
+
except APIError as e:
|
|
387
|
+
print(f"Docker daemon error: {e.status_code} {e.explanation}")
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
Catch specific exceptions rather than bare `except`. `ContainerError` fires when `detach=False` and the container exits with a non-zero code. `ReadTimeout` fires when `wait()` exceeds its timeout. `APIError` is the base class for most daemon-level errors.
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## Ambiguity Policy
|
|
395
|
+
|
|
396
|
+
These defaults apply when the user does not specify a preference. State the assumption when making a choice so the user can override:
|
|
397
|
+
|
|
398
|
+
- **Library choice:** Default to `docker` (docker-py) for synchronous code. Recommend `aiodocker` only when the application already uses asyncio throughout (e.g., FastAPI).
|
|
399
|
+
- **Container creation:** Default to `client.containers.run(detach=True)` for background containers. Use `create()` + `start()` only when pre-start configuration is needed.
|
|
400
|
+
- **Volume syntax:** Default to `Mount` objects over dict-based `volumes` parameter.
|
|
401
|
+
- **Connection:** Default to `docker.from_env()`. Use explicit `DockerClient()` only for remote daemons or custom socket paths.
|
|
402
|
+
- **Auto-remove:** Default to `remove=True` for ephemeral containers (one-off tasks). Omit for long-running services.
|
|
403
|
+
- **Error handling:** Import and catch specific exceptions (`ImageNotFound`, `NotFound`, `ContainerError`, `APIError`) rather than bare `except`.
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Reference Files
|
|
408
|
+
|
|
409
|
+
| File | Contents |
|
|
410
|
+
|------|----------|
|
|
411
|
+
| `references/container-lifecycle.md` | Container create/run options, exec_run patterns (stream, demux, detach), log streaming, health check configuration, health status polling, wait/timeout, auto-remove, prune |
|
|
412
|
+
| `references/resources-and-security.md` | Volume CRUD, bind mount patterns, Mount objects, network create/connect/disconnect, resource limits (CPU, memory, I/O), security options (capabilities, read-only, seccomp, namespaces), image management, aiodocker async alternative |
|