How to clean up the docker system, without removing certain images? - docker

To clean up the docker system there's the useful command
docker system prune -a
with its various options. I find myself often executing that to clean up the mess I've made when trying out different things in development, only to later re-download a bunch of images. This normally takes a long time (5-10 minutes) in my use cases, and unnecessarily hogs the bandwidth of the image libraries I use.
What I'd like is to know if there is a simple way to prevent certain images (ones that I know I will need again in the near future) from being pruned while still retaining the convenience of pruning the docker system in a single command?
One way I could do this is start a container from the images I want to keep before pruning, and then prune, but that defeats the convenience of a one-liner above. In addition, those containers need stopping and removing after pruning as they are an unnecessary burden on my resources at that point.
Is there a simple(r) way to do this?

You can make your own images and LABEL them like this Dockerfile:
FROM ubuntu:20.04
LABEL myimage=keepit
You build this Dockerfile with docker build -t myubuntu .
And then you can use filter for this label to not prune it: docker prune -a --filter label!="myimage=keepit"
Docs: https://docs.docker.com/engine/reference/commandline/system_prune/#filtering

Related

How to avoid Docker data clutter during rapid development cycles

I am developing a dockerized application. From time to time I rebuild and run the image/container on my machine to do some testing. To do so I naively executed the following:
docker image build -t myapp .
docker container run -p 8020:5000 -v $(pwd)/data:/data myapp
This seems to work quite well. But today I realized that the docker folder on my machine has grown quite big in the last three weeks (> 200 GB).
So it seems that all the supposedly temporary containers, images, volumes etc. have piled up on my disk.
What would be the right way to solve this? I only need one version of my image, so it would be great everything was simply overwritten every time I start a new test cycle.
Alternatively I could execute a docker system prune, but that seems overkill.
Majority of space is occupied by images and volumes so pruning only them would be better option then docker system prune.
docker image prune
docker volume prune
image prune will clean all dangling images that were untagged from myapp due to a new image built and tag to myapp.
Also as the containers are started for testing/dev, they can be started with --rm for cleaning when stopped.

Should I create a docker container or docker start a stopped container?

From the docker philosophy's point of view it is more advisable:
create a container every time we need to use a certain environment and then remove it after use (docker run <image> all the time); or
create a container for a specific environment (docker run <image>), stop it when it is not necessary and whenever it is initialized again (docker start <container>);
If you docker rm the old container and docker run a new one, you will always get a clean filesystem that starts from exactly what's in the original image (plus any volume mounts). You will also fairly routinely need to delete and recreate a container to change basic options: if you need to change a port mapping or an environment variable, or if you need to update the image to have a newer version of the software, you'll be forced to delete the container.
This is enough reason for me to make my standard process be to always delete and recreate the container.
# docker build -t the-image . # can be done first if needed
docker stop the-container # so it can cleanly shut down and be removed
docker rm the-container
docker run --name the-container ... the-image
Other orchestrators like Docker Compose and Kubernetes are also set up to automatically delete and recreate the container (or Kubernetes pod) if there's a change; their standard workflows do not generally involve restarting containers in-place.
I almost never use docker start. In a Compose-based workflow I generally use only docker-compose up -d, letting it restart things if needed; docker-compose down if I need the CPU/memory resources the container stack was using but not in routine work.
I'm talking with regards to my experience in the industry so take my answer with a grain of salt, because there might be no hard evidence or reference to the theory.
Here's the answer:
TL;DR:
In short, you never need the docker stop and docker start because taking this approach is unreliable and you might lose the container and all the data inside if no proper action is applied beforehand.
Long answer:
You should only work with images and not the containers. Whenever you need some specific data or you need the image to have some customization, you better use docker save to have the image for future use.
If you're just testing out on your local machine, or in your dev virtual machine on a remote host, you're free to use either one you like. I personally take each of the approaches on different scenarios.
But if you're talking about a production environment, you'd better use some orchestration tool; it could be as simple and easy to work with as docker-compose or docker swarm or even Kubernetes on more complex environments.
You better not take the second approach (docker run, docker stop & docker start) in those environments because at any moment in time you might lose that container and if you are solely dependent on that specific container or it's data, then you're gonna have a bad weekend.

Docker: "You don't have enough free space in /var/cache/apt/archives/"

I have a dockerfile which when I want to build results in the error
E: You don't have enough free space in /var/cache/apt/archives/
Note that the image sets up a somewhat complex project with several dependencies that require quite a lot of space. For example, the list includes Qt. This is only a thing during the construction of the image, and in the end, I expect it to have a size of maybe 300 MB.
Now I found this: https://unix.stackexchange.com/questions/578536/how-to-fix-e-you-dont-have-enough-free-space-in-var-cache-apt-archives
Given that, what I tried so far is:
Freeing the space used by docker images so far by calling docker system prune
Removing unneeded installation files by calling sudo apt autoremove and sudo apt autoclean
There was also the suggestion to remove data in var/log, which has currently a size of 3 GB. However, I am not the system administrator and thus wary to do such a thing.
Is there any other way to increase that space?
And, preferably, is there a more sustainable solution, allowing me to build several images without having to search for spots where I can clean up the system?
Try this suggestion. You might have a lot of unused images that need to be deleted.
https://github.com/onyx-platform/onyx-starter/issues/5#issuecomment-276562225
Converting a #Dre suggestion into the code, you might want to use Docker prune command for containers, images & volumes
docker container prune
docker image prune
docker volume prune
You can use these commands in sequence:
docker container prune; docker image prune; docker volume prune
Free Space without removing your latest images
Use the following command to see the different types of reclaimable storage (the -v verbose option provides more detail):
docker system df
docker system df -v
Clear the build cache (the -a option will remove unused build cache):
docker builder prune -a
Remove dangling images ( tagged images, old and previous image builds):
docker rmi -f $(docker images -f "dangling=true" -q)
Increase Disk image size using Docker UI
Docker > Preferences > Resources > Advanced > adjust Disk image size > Apply & Restart
TLDR;
run
docker system prune -a --volumes
I tried to increase the disk space and prune the images, containers and volumes manually but was facing the issue again and again. When I tried to check the memory consumption on my machine, I found a lot of memory consumed by ~/Library/Containers/com.docker.docker location. Did a system prune which cleaned up a lot of space and docker builds started working again.

How do I clean docker?

An error occurred because there is not enough disk space
I decided to check how much is free and came across this miracle
Cleaned up via docker system prune -a and
docker container prune -f
docker image prune -f
docker system prune -f
But only 9GB was cleared
Prune removes containers/images that have not been used for a while/stopped. I would suggest you do a docker ps -a and then remove/stop all the containers that you don't want with docker stop <container-id>, and then move on to remove docker images by docker images ps and then remove them docker rmi <image-name>
Once you have stooped/removed all the unwanted containers run docker system prune --volumes to remove all the volumes/cache and dangling images.
Don't forget to prune the volumes! Those almost always take up way more space than images and containers. docker volume prune. Be careful if you have anything of value stored in them though.
It could be your logging of the running containers. I've seen Docker logging writing disks full with logging. By default Docker containers can write unlimited logs.
I always add logging configuration to my docker-compose restrict total size. Docker Logging Configuration.
From the screenshot I think there's some confusion on what's taking up how much space. Overlay filesystems are assembled from directories on the parent filesystem. In this case, that parent filesystem is within /var/lib/docker which is part of / in your example. So the df output for each overlay filesystem is showing how much disk space is used/available within /dev/vda2. Each container isn't using 84G, that's just how much is used in your entire / filesystem.
To see how much space is being used by docker containers, images, volumes, etc, you can use docker system df. If you have running containers (likely from the above screenshot), docker will not clean those up, you need to stop them before they are eligible for pruning. Once containers have been deleted, you can then prune images and volumes. Note that deleting volumes deletes any data you were storing in that volume, so be sure it's not data you wanted to save.
It's not uncommon for docker to use a lot of disk space from downloading lots of images (docker makes it easy to try new things) and those are the easiest to prune when the containers are stopped. However what's harder to see are the logs that containers are outputting which will slowly fill the drive within the containers directory. For more details on how to clean the logs automatically, see this answer.
If you want, you could dig deep at granular level and pinpoint the file(s) which are the cause of this much disk usage.
du -sh /var/lib/docker/overley2/<container hash>/merged/* | sort -h
this would help you coming to a conclusion much easily.

Docker prune images not used in the last X hours

Is there a way to do docker prune image to get rid of images if either they or their intermediary layers have not been used in the last X hours?
The purpose is: Say a build has created intermdiary and final image(F1). A subsequent build can use the intermediary image. While this subsequent build is running, if I run docker image prune -f -a in another window, then Docker will delete the image F1 (assuming it is unused) and it's intermediary images. Thus the build in progress even if it had used intermediary image will have to rebuild the intermediary image. If there is a filter setting on the prune command based on last used then it will be helpful.
Based on "last used" it might not be very easy, there is still issue going on: https://github.com/moby/moby/issues/4237
Tool named 'docuum' is created for it if you are ready to use it. Also less maintained docker-gc is available.
You can prune based on "last created" as hours for example:
docker image prune -a --force --filter "until=5h"
Source: https://docs.docker.com/engine/reference/commandline/image_prune/

Resources