Trouble with docker ignore

I had this working for a few tries and I don’t know what changed to stop it from working. I have a docker build file with a corresponding docker ignore file. My goal is to copy only php files as I have large media files that I don’t want to duplicate into the php service.

php.dockerfile

FROM php:7.4.9-fpm-alpine
COPY /application/ /app/

php.dockerfile.dockerignore

**/*.*

!**/*.php

I am using the following docker build command:

docker build -f php.dockerfile --tag test .

It seems no matter what I put in the docker ignore file, it will not register. It will work if I rename the docker ignore file to .dockerignore but that does not serve my purpose as I have other services that are being built in the same directory that use the same files. Anyone else run into this issue?

Is this the name of your .dockerignore file?

Yes, that is the name of the ignore file. Which from what I understand docker will read when you define a file name.

I assume you didn’t test if it makes a difference, did you?

I always named my file literaly .dockerfile.The ignores were always applied and slimmed down the files that are send to the build context (which can speed up the build process immensly when a lot of files or big files are in the builds context dir or in one of its subdirs)

Can you share the link to the docs that made you conclude that .dockerfile is a file-type suffix?

You can name the docker file anything you want (ex foo.bar). Docker just looks for a file named Dockerfile in the context when you don’t specify one.

docker build -f php.dockerfile --tag test .

I have two docker files in a single directory as they share the same build context: apache.dockerfile and php.dockerfile. If I name the ignore file .dockerignore, it will apply to both docker files which I don’t want. All files from my application directory should be copied into the apache image. Then only php files should be copied into my php image. There is no need for the php image to contain static files being hosted by apache.

I was able to write a shell script with rsync to help with this but it is not ideal:

build.sh

#!/bin/bash

docker build -f apache.dockerfile --tag example/example-apache .
rsync -zarv --include “/" --include=".php” --exclude=“*” ./application/ ./php_build/
docker build -f php.dockerfile --tag example/example-php .
rm -rf ./php_build/
docker push example/example-apache
docker push example/example-php
docker rmi example/example-apache
docker rmi example/example-php

php.dockerfile

FROM example/php-mysqli:20200807-7.4.9-fpm-alpine

COPY ./php_build/ /app/

apache.dockerfile

FROM example/apache-php

COPY ./application/ /app/

COPY apache.conf /usr/local/apache2/conf/apache.conf
RUN echo “Include /usr/local/apache2/conf/apache.conf”
>> /usr/local/apache2/conf/httpd.conf

WORKDIR /app/

I am not sure how writting about the dockerfile beeing a parameter is related to my previous post… anway you are right about it.

Update: may bad I realy did. Well. Of course .dockignore was ment.

Also, I am not realy sure what you expect here. The docs clearly state that the filename .dockerfile literaly is the name of the file that lists all files to ignore. Why don’t you simply generate the required .dockerignore?

You can embedded something like this in your bash script before each docker buildcommand.

cat << EOF > .dockerignore
**/*.*
!**/*.php
EOF

You might try to switch to buildkit for builds, which afair only copies file to the context that are actualy used in COPY or ADD.

If this doesn’t make you happy as well, then there is no way arround raising a feature request on moby’s (the open source docker project) github project and ask to add a parameter for the .dockerignore file.

1 Like

Just thought you were saying I couldn’t use another file name. Probably misunderstood.

Your post did give me an idea on another way of doing it. I could just rename the docker ignore file before the build happens in the shell script like so:

#!/bin/bash

docker build -f apache.dockerfile --tag example/example-apache .
mv php.dockerfile.dockerignore .dockerignore
docker build -f php.dockerfile --tag example/example-php .
mv .dockerignore php.dockerfile.dockerignore
docker push example/example-apache
docker push example/example-php
docker rmi example/example-apache
docker rmi example/example-php

That just seems a little prettier than using rsync to copy files then delete them. It allows the build to go much faster as the total size with the static assets is 500MB vs 1MB of just php files.

Of course out of all of this, the cleanest way would for you to be able to specify a dockerignore file or one gets automatically selected like this post stated which didn’t work for me:

I am running docker version 19.03.1.

1 Like

Nah, it was my bad. I was thinking in the context of .dockerignore, but actualy wrote .dockerfileinstead of .dockerignore

I just saw your link. Wasn’t aware buildkit added that feature. Though, you need to enable buildkit by setting DOCKER_BUILDKIT=1. Either put it in permantly in your ~/.bashrc file or use it in your script like DOCKER_BUILDKIT=1 docker build... (this is the prefered way, as it is portable accross machines, as long as every machine provides a recent docker version).

Nice, I didn’t know to include the buildkit variable before the docker command. It is working as expected with that buildkit variable included. Explains why it wasn’t working before I guess. The shell file looks like this now:

#!/bin/bash

DOCKER_BUILDKIT=1 docker build -f apache.dockerfile --tag example/example-apache .
DOCKER_BUILDKIT=1 docker build -f php.dockerfile --tag example/example-php .
docker push example/example-apache
docker push example/example-php
docker rmi example/example-apache
docker rmi example/example-php

Now my next question, is there a way to include the buildkit variable only once or do you have to put it before the docker command every time?

I think I found my own answer:

export DOCKER_BUILDKIT=1

So now the shell file looks like this:

#!/bin/bash

export DOCKER_BUILDKIT=1
docker build -f apache.dockerfile --tag example/example-apache .
docker build -f php.dockerfile --tag example/example-php .
docker push example/example-apache
docker push example/example-php
docker rmi example/example-apache
docker rmi example/example-php

I did confirm this is working, and the build are super fast now. :nerd_face:

Buildkit works great, until you start to use managed Kubernetes distros like EKS or KOPS. Usualy they embedd older docker engine versions. If your (newer) docker cli does respect BUILDKIT=1, but your server does not, the build fails. Been there. Done that. Didn’t like it :slight_smile:

Though, one could check the server version in the build bash or ci pipe script .

If you should be ever in such a situation, you can wrap your export declaration in such a condition:

vers=$(docker version --format '{{range $component:= .Server.Components}}{{if eq $component.Name "Engine"}}{{$component.Version}}{{end}}{{end}}')
major_vers=${vers%%.*}        # xx from xx.yy.z
minor_vers=${vers%.*}         # xx.yy from xx.yy.z
minor_vers=${minor_vers#*.}   # yy from xx.yy
if [  $((${major_vers})) -ge 19 ] && [ $((${minor_vers})) -ge 3 ];then
   export DOCKER_BUILDKIT=1
fi