8

I am new to Docker and find that there are numerous images that are getting created (as seen in sudo docker images) and found somewhere in stackoverflow to periodically run sudo docker rmi $(sudo docker images -q) to remove all images. Why so many images get created? is there something wrong in my configuration?

docker-compose.yml

nginx:
  build: ./nginx
  restart: always
  ports:
    - "80:80"
    - "443:443"
  volumes:
    - /etc/letsencrypt/:/etc/letsencrypt/
  links:
    - node:node

node:
  build: ./node
  restart: always
  ports:
   - "8080:8080"
  volumes:
    - ./node:/usr/src/app
    - /usr/src/app/node_modules

The nginx dockerfile is

FROM nginx:alpine

COPY nginx.conf /etc/nginx/conf.d/default.conf

The nodejs dockerfile is

FROM node:9.3.0-alpine

WORKDIR /usr/src/app

COPY package*.json /usr/src/app/

RUN npm install --only=production

COPY . /usr/src/app

EXPOSE 8080
CMD [ "npm", "start" ]

The website/app works fine. Except that periodically, I am removing all containers, images and then run: sudo docker-compose up --build -d.

James Z
  • 12,209
  • 10
  • 24
  • 44
RmR
  • 1,917
  • 1
  • 22
  • 35

3 Answers3

6

Images are immutable, so any change you make results in a new image being created. Since your compose file specifies the build command, it will rerun the build command when you start the containers. If any files you are including with a COPY or ADD change, then the existing image cache is no longer used and it will build a new image without deleting the old image.

Note, I'd recommend naming your image in the compose file so it's clear which image is being rebuilt. And you can watch the compose build output to the the first step that doesn't report using the cache to see what is changing. If I was to guess, the line that breaks your cache and causes a new image is this one in nodejs:

COPY . /usr/src/app

If the files being changed and causing the rebuild are not needed in your container, then use a .dockerignore file to exclude the unnecessary files.

BMitch
  • 231,797
  • 42
  • 475
  • 450
  • BMitch. Thanks. The reason, I thought, the copy command is because the app (application specific nodejs files) will continuously change. Is it not? And my understanding was the image is the core node js. I have the .gitignore which does not have the standard stuff sync'd like node modules. – RmR Mar 05 '18 at 12:09
  • @Raj You run an image that is built on top of the nodejs image. It will be recreated with new content after every change to your code. – BMitch Mar 05 '18 at 12:28
  • Isn't that what the Node docker file is doing. Taking changes made in the program and copying it into the volume of the container. My understanding, again, is volume specified in the compose.yml is external to the image. Right? So whatever, updates are done there has no bearing on the image. Reason, I am asking is that the site is currently only being used for testing and I am likely to go into production by end of the month. Hence would like to get a grip on Dockers. Thanks once again for your prompt reply – RmR Mar 05 '18 at 12:56
  • @Raj The volume in the compose file will overlay the COPY you run in the image build done with the Dockerfile. This is a common practice done with a development environment for rapid iteration, but every time you run a new build, you will get a new image. If your only changes are to the contents of that host volume, and you only need to see them locally, then you can skip the build to avoid creating another image. – BMitch Mar 05 '18 at 13:04
  • @Raj Once you move out of development, you would then rebuild the image, push that built image. And when you run it in production, you would remove that volume mount. The result is your code would be embedded into the deployed image. – BMitch Mar 05 '18 at 13:07
  • Thanks @BMitch. Will do that – RmR Mar 06 '18 at 05:04
4

I had the same problem when I was building my Dockerfile.

I found the solution, use this command to build your file :

`docker build --rm -t <tag> .`

The option --rm removes intermediate containers after a successful build.

-1

There should not be "so many images" created.

If you want to be sure to keep only the one you needs (without having to rebuild everything every time); simply do (as I detail here):

docker image prune
ccjmne
  • 9,333
  • 3
  • 47
  • 62
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks VonC. I do a similar set of commands periodically. Stop all containers. Remove all containers. Remove all images. Prune all images. Remove all dangling containers etc etc. This was via one of the suggestions. My fundamental question was why do I have to do this? And whether it is because of some wrong way in which I have set up Dockers. To my mind, it does not make sense doing this periodically. – RmR Mar 03 '18 at 04:37
  • @Raj Note: what you describe is done in one command: `docker system prune`. – VonC Mar 03 '18 at 08:19