Skip to content

Commit

Permalink
fix: handle dockerignore exclusions properly (#2476)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
mdelapenya committed Apr 9, 2024
1 parent 3877183 commit 8bd1d28
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 8 deletions.
22 changes: 16 additions & 6 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,17 @@ func (c *ContainerRequest) GetContext() (io.Reader, error) {
}
c.Context = abs

excluded, err := parseDockerIgnore(abs)
dockerIgnoreExists, excluded, err := parseDockerIgnore(abs)
if err != nil {
return nil, err
}

dockerIgnoreLocation := filepath.Join(abs, ".dockerignore")
includes = append(includes, dockerIgnoreLocation, c.GetDockerfile())
if dockerIgnoreExists {
// only add .dockerignore if it exists
includes = append(includes, filepath.Join(".dockerignore"))
}

includes = append(includes, c.GetDockerfile())

buildContext, err := archive.TarWithOptions(
c.Context,
Expand All @@ -240,18 +244,24 @@ func (c *ContainerRequest) GetContext() (io.Reader, error) {
return buildContext, nil
}

func parseDockerIgnore(targetDir string) ([]string, error) {
// parseDockerIgnore returns if the file exists, the excluded files and an error if any
func parseDockerIgnore(targetDir string) (bool, []string, error) {
// based on https://github.com/docker/cli/blob/master/cli/command/image/build/dockerignore.go#L14
fileLocation := filepath.Join(targetDir, ".dockerignore")
var excluded []string
exists := false
if f, openErr := os.Open(fileLocation); openErr == nil {
defer f.Close()

exists = true

var err error
excluded, err = ignorefile.ReadAll(f)
if err != nil {
return excluded, fmt.Errorf("error reading .dockerignore: %w", err)
return true, excluded, fmt.Errorf("error reading .dockerignore: %w", err)
}
}
return excluded, nil
return exists, excluded, nil
}

// GetBuildArgs returns the env args to be used when creating from Dockerfile
Expand Down
11 changes: 10 additions & 1 deletion container_ignore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,32 @@ import (
func TestParseDockerIgnore(t *testing.T) {
testCases := []struct {
filePath string
exists bool
expectedErr error
expectedExcluded []string
}{
{
filePath: "./testdata/dockerignore",
expectedErr: nil,
exists: true,
expectedExcluded: []string{"vendor", "foo", "bar"},
},
{
filePath: "./testdata",
expectedErr: nil,
exists: true,
expectedExcluded: []string{"Dockerfile", "echo.Dockerfile"},
},
{
filePath: "./testdata/data",
expectedErr: nil,
expectedExcluded: nil, // it's nil because the parseDockerIgnore function uses the zero value of a slice
},
}

for _, testCase := range testCases {
excluded, err := parseDockerIgnore(testCase.filePath)
exists, excluded, err := parseDockerIgnore(testCase.filePath)
assert.Equal(t, testCase.exists, exists)
assert.Equal(t, testCase.expectedErr, err)
assert.Equal(t, testCase.expectedExcluded, excluded)
}
Expand Down
10 changes: 9 additions & 1 deletion docs/features/build_from_dockerfile.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ You can specify them like:
If you would like to send a build context that you created in code (maybe you have a dynamic Dockerfile), you can
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.


To do this you would use the `ContextArchive` attribute in the `FromDockerfile` struct.

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

## Ignoring files in the build context

The same as Docker has a `.dockerignore` file to ignore files in the build context, _Testcontainers for Go_ also supports this feature.
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.
The `.dockerignore` file won't be sent to the Docker daemon either.

!!! note
At this moment, _Testcontainers for Go_ does not support Dockerfile-specific `.dockerignore` files.

## Images requiring auth

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

0 comments on commit 8bd1d28

Please sign in to comment.