dockerdocker-compose

.dockerignore not being read on image build


I've been stuck on this for awhile. I would like docker to ignore a particular directory when building an image, because my user account does not have permissions to read that directory. I cannot move it, so that's not an alternative.

This is the structure of my project. docker/data is the directory that I do not have permissions to read, and docker/node-express.dockerfile is the image I'm trying to build.

enter image description here

Running docker build --no-cache --tag node-express --file ./docker/node-express.dockerfile . in the root directory outputs the error

error checking context: 'can't stat '/home/anthony/Repositories/Anthony-Monterrosa/aws-postgres-node-stack/docker/data''.

After this error and a bit of googling I learned about .dockerignore files, and made one in the root directory. The following is the file's text.

docker/data

I ran the command again but got an identical error. A bit more googling and I found out about image-specific .dockerignore files, so I set DOCKER_BUILDKIT to 1, created docker/node-express.dockerfile.dockerignore with the following content

data
docker/data

(I am not sure how relative paths work with image-specific .dockerignores, so I added both). Ran the command again, but still with the same error.

So, I don't seem to have ignores working correctly with either .dockerignore file, or both. What am I missing here?


Solution

  • The error is:

    error checking context: 'can't stat '/home/anthony/Repositories/Anthony-Monterrosa/aws-postgres-node-stack/docker/data''.

    So looks there is some operation before .dockerignore effect.

    As there is no context content in your docker folder, I suggest you just add docker in .dockerignore.

    This way, although still error, but the build will continue like next:

    shubuntu1@shubuntu1:~/trial2020/trial$ docker build -t abcd:1 -f docker/Dockerfile .
    ERRO[0000] Tar: Can't stat file /home/shubuntu1/trial2020/trial to tar: open 
    /home/shubuntu1/trial2020/trial/docker/data: permission denied
    Sending build context to Docker daemon  3.072kB
    Step 1/1 : FROM ubuntu:18.04
     ---> 3556258649b2
    Successfully built 3556258649b2
    Successfully tagged abcd:1
    

    UPDATE why according to your comments:

    You may want to have a look for docker-ce source code, build.go & context.go:

    build.go:

    if err := build.ValidateContextDirectory(contextDir, excludes); err != nil {
       return errors.Errorf("error checking context: '%s'.", err)
    }
    

    context.go:

    func ValidateContextDirectory(srcPath string, excludes []string) error {
            contextRoot, err := getContextRoot(srcPath)
            if err != nil {
                return err
            }
    
            pm, err := fileutils.NewPatternMatcher(excludes)
            if err != nil {
                return err
            }
    
            return filepath.Walk(contextRoot, func(filePath string, f os.FileInfo, err error) error {
                if err != nil {
                    if os.IsPermission(err) {
                        return errors.Errorf("can't stat '%s'", filePath)
                    }
                    if os.IsNotExist(err) {
                        return errors.Errorf("file ('%s') not found or excluded by .dockerignore", filePath)
                    }
                    return err
                }
    
                // skip this directory/file if it's not in the path, it won't get added to the context
                if relFilePath, err := filepath.Rel(contextRoot, filePath); err != nil {
                    return err
                } else if skip, err := filepathMatches(pm, relFilePath); err != nil {
                    return err
                } else if skip {
                    if f.IsDir() {
                        return filepath.SkipDir
                    }
                    return nil
                }
        ......
            })
        }
    

    Before docker daemon tar the build context, it will first try to validate the context directory:

    1. docker/data in .dockerignore:

      It will use Walk to ergodic all things under docker, when it comes to docker/data, next code finally make the build exit, so you did not get image generated:

            if os.IsPermission(err) {
                return errors.Errorf("can't stat '%s'", filePath)
            }
    
    1. docker in .dockerignore:

      Same as above, difference is next code will effect when comes to the match docker in .dockerignore:

            return filepath.SkipDir
    

    This will make the Walk ignore the subfolders of docker, then docker/data no chance to be ergodic, so no permission error there.

    The ERRO[0000] Tar: Can't stat file comes from other later steps which won't exit the image build.