Skip to content

Commit 8348845

Browse files
authored
docs: fix building images guide to use real DockerImage API (#1047)
## What The `docs/features/building_images.md` guide documented a `build_image()` function imported from `testcontainers.core.container`. That function does not exist anywhere in the source — the entire page was based on a non-existent API. This rewrites the guide to use the actual public API, the `DockerImage` context manager from `testcontainers.core.image`. ## Changes - Use `DockerImage(...)` as a context manager together with `DockerContainer(str(image))`. - Correct argument names: `dockerfile_path` (was `dockerfile`), `no_cache` (was `nocache`). - Remove the non-existent `context` argument — the build context **is** the `path` argument. - Document the build inspection helpers (`short_id`, `get_logs`, `get_wrapped_image`) and the `clean_up` behavior. - Clarify that extra kwargs (`buildargs`, `target`, `platform`, `labels`, `cache_from`) are forwarded to docker-py's `images.build`. ## Context Dockerfile support requested in #83 is already implemented via `DockerImage`; only the documentation was inaccurate. Relates to #83. Docs-only change; no code or tests affected.
1 parent 6018da3 commit 8348845

1 file changed

Lines changed: 103 additions & 101 deletions

File tree

docs/features/building_images.md

Lines changed: 103 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -4,113 +4,136 @@ Testcontainers-Python allows you to build Docker images from Dockerfiles during
44

55
## Basic Image Building
66

7-
The simplest way to build an image is using the `build_image` function:
7+
The simplest way to build an image is using the `DockerImage` class. It is a context manager that builds the image on entry and removes it on exit:
88

99
```python
10-
from testcontainers.core.container import build_image
10+
from testcontainers.core.container import DockerContainer
11+
from testcontainers.core.image import DockerImage
1112

12-
# Build an image from a Dockerfile
13-
image = build_image(
14-
path="path/to/dockerfile/directory",
15-
tag="myapp:test"
16-
)
17-
18-
# Use the built image
19-
with GenericContainer(image) as container:
20-
# Your test code here
21-
pass
13+
# Build an image from a build context containing a Dockerfile
14+
with DockerImage(path="path/to/dockerfile/directory", tag="myapp:test") as image:
15+
# Use the built image
16+
with DockerContainer(str(image)) as container:
17+
# Your test code here
18+
pass
2219
```
2320

24-
## Building with Options
21+
`path` is the build context directory. By default the Dockerfile is expected to be named `Dockerfile` within that directory.
2522

26-
You can customize the build process with various options:
23+
## Building with a Custom Dockerfile
24+
25+
Use `dockerfile_path` to point at a Dockerfile with a different name or location (relative to the build context):
2726

2827
```python
29-
# Build with specific Dockerfile
30-
image = build_image(
28+
with DockerImage(
3129
path="path/to/dockerfile/directory",
32-
dockerfile="Dockerfile.test",
33-
tag="myapp:test"
34-
)
30+
dockerfile_path="Dockerfile.test",
31+
tag="myapp:test",
32+
) as image:
33+
...
34+
```
35+
36+
## Building with Options
37+
38+
Any additional keyword arguments are forwarded to the underlying docker-py
39+
[`images.build`](https://docker-py.readthedocs.io/en/stable/images.html#docker.models.images.ImageCollection.build)
40+
call, so you can use all of its options.
3541

36-
# Build with build arguments
37-
image = build_image(
42+
### Build Arguments
43+
44+
```python
45+
with DockerImage(
3846
path="path/to/dockerfile/directory",
47+
tag="myapp:test",
3948
buildargs={
4049
"VERSION": "1.0.0",
41-
"ENVIRONMENT": "test"
50+
"ENVIRONMENT": "test",
4251
},
43-
tag="myapp:test"
44-
)
52+
) as image:
53+
...
54+
```
4555

46-
# Build with target stage
47-
image = build_image(
56+
### Target Stage
57+
58+
```python
59+
with DockerImage(
4860
path="path/to/dockerfile/directory",
61+
tag="myapp:test",
4962
target="test",
50-
tag="myapp:test"
51-
)
63+
) as image:
64+
...
5265
```
5366

54-
## Building with Context
67+
### Disabling the Build Cache
5568

56-
You can specify a build context:
69+
Use the `no_cache` argument to bypass the build cache (equivalent to the CLI's `--no-cache`):
5770

5871
```python
59-
# Build with specific context
60-
image = build_image(
72+
with DockerImage(
6173
path="path/to/dockerfile/directory",
62-
context="path/to/build/context",
63-
tag="myapp:test"
64-
)
74+
tag="myapp:test",
75+
no_cache=True,
76+
) as image:
77+
...
6578
```
6679

67-
## Building with Cache
68-
69-
You can control build caching:
80+
You can also reuse cache layers from existing images with `cache_from`:
7081

7182
```python
72-
# Build without cache
73-
image = build_image(
74-
path="path/to/dockerfile/directory",
75-
nocache=True,
76-
tag="myapp:test"
77-
)
78-
79-
# Build with specific cache from
80-
image = build_image(
83+
with DockerImage(
8184
path="path/to/dockerfile/directory",
85+
tag="myapp:test",
8286
cache_from=["myapp:latest"],
83-
tag="myapp:test"
84-
)
87+
) as image:
88+
...
8589
```
8690

87-
## Building with Platform
88-
89-
You can specify the target platform:
91+
### Platform
9092

9193
```python
92-
# Build for specific platform
93-
image = build_image(
94+
with DockerImage(
9495
path="path/to/dockerfile/directory",
96+
tag="myapp:test",
9597
platform="linux/amd64",
96-
tag="myapp:test"
97-
)
98+
) as image:
99+
...
98100
```
99101

100-
## Building with Labels
101-
102-
You can add labels to the built image:
102+
### Labels
103103

104104
```python
105-
# Build with labels
106-
image = build_image(
105+
with DockerImage(
107106
path="path/to/dockerfile/directory",
107+
tag="myapp:test",
108108
labels={
109109
"test": "true",
110-
"environment": "test"
110+
"environment": "test",
111111
},
112-
tag="myapp:test"
113-
)
112+
) as image:
113+
...
114+
```
115+
116+
## Inspecting the Build
117+
118+
`DockerImage` exposes helpers to inspect the result of a build:
119+
120+
```python
121+
with DockerImage(path="path/to/dockerfile/directory", tag="myapp:test") as image:
122+
print(image.short_id) # short image ID
123+
print(str(image)) # tag if set, otherwise short ID
124+
logs = image.get_logs() # list of build log entries
125+
wrapped = image.get_wrapped_image() # underlying docker-py Image
126+
```
127+
128+
## Cleaning Up
129+
130+
By default the image is removed when the context manager exits. Set `clean_up=False`
131+
to keep the image after the block completes:
132+
133+
```python
134+
with DockerImage(path="path/to/dockerfile/directory", tag="myapp:test", clean_up=False) as image:
135+
...
136+
# image is still available here
114137
```
115138

116139
## Best Practices
@@ -120,71 +143,50 @@ image = build_image(
120143
3. Use build arguments for configuration
121144
4. Consider build context size
122145
5. Use appropriate build caching
123-
6. Handle build failures
124-
7. Use appropriate platforms
125-
8. Add meaningful labels
146+
6. Use appropriate platforms
147+
7. Add meaningful labels
126148

127149
## Common Use Cases
128150

129151
### Building Test Images
130152

131153
```python
132154
def test_custom_image():
133-
# Build test image
134-
image = build_image(
155+
with DockerImage(
135156
path="path/to/dockerfile/directory",
157+
tag="myapp:test",
136158
buildargs={"TEST_MODE": "true"},
137-
tag="myapp:test"
138-
)
139-
140-
# Use the test image
141-
with GenericContainer(image) as container:
142-
# Your test code here
143-
pass
144-
```
145-
146-
### Building with Dependencies
147-
148-
```python
149-
def test_with_dependencies():
150-
# Build base image
151-
base_image = build_image(
152-
path="path/to/base/dockerfile/directory",
153-
tag="myapp:base"
154-
)
155-
156-
# Build test image using base
157-
test_image = build_image(
158-
path="path/to/test/dockerfile/directory",
159-
cache_from=[base_image],
160-
tag="myapp:test"
161-
)
159+
) as image:
160+
with DockerContainer(str(image)) as container:
161+
# Your test code here
162+
pass
162163
```
163164

164165
### Building for Different Environments
165166

166167
```python
167168
def test_different_environments():
168-
# Build for different environments
169169
environments = ["dev", "test", "staging"]
170170

171171
for env in environments:
172-
image = build_image(
172+
with DockerImage(
173173
path="path/to/dockerfile/directory",
174+
tag=f"myapp:{env}",
174175
buildargs={"ENVIRONMENT": env},
175-
tag=f"myapp:{env}"
176-
)
176+
) as image:
177+
with DockerContainer(str(image)) as container:
178+
# Your test code here
179+
pass
177180
```
178181

179182
## Troubleshooting
180183

181184
If you encounter issues with image building:
182185

183186
1. Check Dockerfile syntax
184-
2. Verify build context
187+
2. Verify the build context (the `path` argument)
185188
3. Check for missing files
186189
4. Verify build arguments
187190
5. Check for platform compatibility
188191
6. Verify cache settings
189-
7. Check for resource limits
190-
8. Verify Docker daemon state
192+
7. Verify Docker daemon state

0 commit comments

Comments
 (0)