Skip to content

Commit 57d69ce

Browse files
committed
fix: handle dockerignore exclusions properly (testcontainers#2476)
* chore: only include the dockerignore if it contains ignore files * fix: the inclusions must be relative to the context * docs: document the dockerignore feature * chore: only include the dockerignore file if it exists
1 parent 04fd077 commit 57d69ce

File tree

3 files changed

+35
-8
lines changed

3 files changed

+35
-8
lines changed

container.go

+16-6
Original file line numberDiff line numberDiff line change
@@ -222,13 +222,17 @@ func (c *ContainerRequest) GetContext() (io.Reader, error) {
222222
}
223223
c.Context = abs
224224

225-
excluded, err := parseDockerIgnore(abs)
225+
dockerIgnoreExists, excluded, err := parseDockerIgnore(abs)
226226
if err != nil {
227227
return nil, err
228228
}
229229

230-
dockerIgnoreLocation := filepath.Join(abs, ".dockerignore")
231-
includes = append(includes, dockerIgnoreLocation, c.GetDockerfile())
230+
if dockerIgnoreExists {
231+
// only add .dockerignore if it exists
232+
includes = append(includes, filepath.Join(".dockerignore"))
233+
}
234+
235+
includes = append(includes, c.GetDockerfile())
232236

233237
buildContext, err := archive.TarWithOptions(
234238
c.Context,
@@ -241,18 +245,24 @@ func (c *ContainerRequest) GetContext() (io.Reader, error) {
241245
return buildContext, nil
242246
}
243247

244-
func parseDockerIgnore(targetDir string) ([]string, error) {
248+
// parseDockerIgnore returns if the file exists, the excluded files and an error if any
249+
func parseDockerIgnore(targetDir string) (bool, []string, error) {
245250
// based on https://github.com/docker/cli/blob/master/cli/command/image/build/dockerignore.go#L14
246251
fileLocation := filepath.Join(targetDir, ".dockerignore")
247252
var excluded []string
253+
exists := false
248254
if f, openErr := os.Open(fileLocation); openErr == nil {
255+
defer f.Close()
256+
257+
exists = true
258+
249259
var err error
250260
excluded, err = ignorefile.ReadAll(f)
251261
if err != nil {
252-
return excluded, fmt.Errorf("error reading .dockerignore: %w", err)
262+
return true, excluded, fmt.Errorf("error reading .dockerignore: %w", err)
253263
}
254264
}
255-
return excluded, nil
265+
return exists, excluded, nil
256266
}
257267

258268
// GetBuildArgs returns the env args to be used when creating from Dockerfile

container_ignore_test.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,32 @@ import (
1111
func TestParseDockerIgnore(t *testing.T) {
1212
testCases := []struct {
1313
filePath string
14+
exists bool
1415
expectedErr error
1516
expectedExcluded []string
1617
}{
1718
{
1819
filePath: "./testdata/dockerignore",
1920
expectedErr: nil,
21+
exists: true,
2022
expectedExcluded: []string{"vendor", "foo", "bar"},
2123
},
2224
{
2325
filePath: "./testdata",
2426
expectedErr: nil,
27+
exists: true,
2528
expectedExcluded: []string{"Dockerfile", "echo.Dockerfile"},
2629
},
30+
{
31+
filePath: "./testdata/data",
32+
expectedErr: nil,
33+
expectedExcluded: nil, // it's nil because the parseDockerIgnore function uses the zero value of a slice
34+
},
2735
}
2836

2937
for _, testCase := range testCases {
30-
excluded, err := parseDockerIgnore(testCase.filePath)
38+
exists, excluded, err := parseDockerIgnore(testCase.filePath)
39+
assert.Equal(t, testCase.exists, exists)
3140
assert.Equal(t, testCase.expectedErr, err)
3241
assert.Equal(t, testCase.expectedExcluded, excluded)
3342
}

docs/features/build_from_dockerfile.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ You can specify them like:
3333
If you would like to send a build context that you created in code (maybe you have a dynamic Dockerfile), you can
3434
send the build context as an `io.Reader` since the Docker Daemon accepts it as a tar file, you can use the [tar](https://golang.org/pkg/archive/tar/) package to create your context.
3535

36-
3736
To do this you would use the `ContextArchive` attribute in the `FromDockerfile` struct.
3837

3938
```go
@@ -52,6 +51,15 @@ fromDockerfile := testcontainers.FromDockerfile{
5251
**Please Note** if you specify a `ContextArchive` this will cause _Testcontainers for Go_ to ignore the path passed
5352
in to `Context`.
5453

54+
## Ignoring files in the build context
55+
56+
The same as Docker has a `.dockerignore` file to ignore files in the build context, _Testcontainers for Go_ also supports this feature.
57+
A `.dockerignore` living in the root of the build context will be used to filter out files that should not be sent to the Docker daemon.
58+
The `.dockerignore` file won't be sent to the Docker daemon either.
59+
60+
!!! note
61+
At this moment, _Testcontainers for Go_ does not support Dockerfile-specific `.dockerignore` files.
62+
5563
## Images requiring auth
5664

5765
If you are building a local Docker image that is fetched from a Docker image in a registry requiring authentication

0 commit comments

Comments
 (0)