tl;dr; Watch out for .dockerignore
causing no such file or directory
when building Docker images
First I tried to use docker-compose
:
▶ docker-compose build ui Building ui Step 1/8 : FROM node:9 ---> 29831ba76d93 Step 2/8 : ADD ui/package.json /package.json ERROR: Service 'ui' failed to build: ADD failed: stat /var/lib/docker/tmp/docker-builder079614651/ui/package.json: no such file or directory
What the heck? Did I typo the name in the ui/Dockerfile
?
The docker-compose.yml
directive for this was:
yaml ui: build: context: . dockerfile: ui/Dockerfile environment: - NODE_ENV=development ports: - "3000:3000" - "35729:35729" volumes: - $PWD/ui:/app command: start
I don't know if it's the awesomest way to do docker-compose
but I did copy this exactly from a different (working!) project. That other project called the web stuff frontend
instead of ui
in this project.
The Dockerfile
looked like this:
FROM node:9 ADD ./ui/package.json ./ ADD ./ui/package-lock.json ./ RUN npm install EXPOSE 3000 EXPOSE 35729 CMD [ "npm", "start" ]
Let's try without docker-compose
. Or rather, do with docker
what docker-compose
does for me automatically.
▶ docker build ui -f ui/Dockerfile Sending build context to Docker daemon 158.2MB Step 1/8 : FROM node:9 ---> 29831ba76d93 Step 2/8 : ADD ui/package.json /package.json ADD failed: stat /var/lib/docker/tmp/docker-builder001494654/ui/package.json: no such file or directory
So I thought I perhaps have misunderstood how relative paths worked. I tried EVERYTHING!
I tried changing to docker build . -f ui/Dockerfile
. No luck.
I tried all sorts of combinations of this with also changing the line to ADD ui/package.json ...
or ADD /ui/package.json ...
or ADD ./package.json ...
or ADD package.json ...
. Nothing worked.
Finally I got it to work by doing
▶ cd ui ▶ docker build . -f Dockerfile
but for that to work I had to remove all references of the directory name ui
in the Dockerfile
. Nice, but this is not going to work in docker-compose.yml
since that starts outside the directory ./ui/
.
Sigh!
So then I learned about contexts in docker. Well, I skimmed the docs rapidly. To keep things clean it's a good idea to do things within the directory that matters. So I made this change in the docker-compose.yml
:
ui: build: context: ui dockerfile: Dockerfile environment: - NODE_ENV=development ports: - "3000:3000" - "35729:35729" volumes: - $PWD/ui:/app command: start
(Note the build.context:
and build.dockerfile:
)
Still doesn't work! 😫 Still various variations of no such file or directory
.
The solution
Turns out, in projectroot/.dockerignore
it had ui/
as a line entry!!!
I believe this project used to do some of the Python stuff with Docker and the React web app was done "locally" on the host. And since the ui/node_modules
directory is so huge someone decided it was smart of avoid Docker mounting that.
Now the .dockerignore
has .ui/node_modules
and now everything works. I can build it with plain docker
and docker-compose
from outside the directory.
Perhaps I should have spent the time I spent writing this blog post to instead file a structured GitHub issue on Docker itself somewhere. I.e. that it should have warned be better. Any takers?
Comments
that post just saved me!
completely forgot about the .dockerignore someone had put in our repo!!!!
THANKS!