50

When I run docker, downloaded docker images (seem to be) stored in /var/lib/docker somewhere.

Since disk space is limited on this directory, and I'm provisioning docker to multiple machines at once; is there a way to change this default location to i.e. /mnt/hugedrive/docker/?

Havnar
  • 2,558
  • 7
  • 33
  • 62

5 Answers5

104

Working solution as of Docker v18.03

I found @Alfabravo's comment to work in my situation, so credit to them and upvoted.

However I think it adds value to provide an answer here to elaborate on it:

Ensure docker stopped (or not started in the first place, e.g. if you've just installed it)

(e.g. as root user):

systemctl stop docker

(or you can sudo systemctl stop docker if not root but your user is a sudo-er, i.e. belongs to the sudo group)

By default, the daemon.json file does not exist, because it is optional - it is added to override the defaults. (Reference - see Answer to: Where's docker's deamon.json? (missing) )

So new installs of docker and those setups that haven't ever modified it, won't have it, so create it:

vi /etc/docker/daemon.json

And add the following to tell docker to put all its files in this folder, e.g:

{
  "graph":"/mnt/cryptfs/docker"
}

and save.

Updated notes from other commenters to consider (I've not tried these yet but grateful for their input, please consider these if you are troubleshooting):

Now start docker:

systemctl start docker

(if root or prefix with sudo if other user.)

And you will find that docker has now put all its files in the new location, in my case, under: /mnt/cryptfs/docker.

This answer from @Alfabravo is also supported by: This answer to this problem: Docker daemon flags ignored

Notes and thoughts on Docker versioning

My host platform that is running docker is Ubuntu Linux 16.04.4 LTS 64bit.

I would therefore assume that this solution would apply to later, future versions of Docker, as well as the current time of writing, v18.03. In other words: "this solution should work from v18.03 onwards". As what seems to be the case with other answers, there is also the possibility that this answer might not work for some future version of Docker, if the Docker developers decide to change things in this area. But for now, it works with v18.03, at least in my case, I hope you also find it to work for you.

Optional Housekeeping tip:

If you had files in the original location /var/lib/docker and you know yourself that you definitely don't need them anymore (i.e. you have all the data (databases inside containers, files etc) within them backed up or in another form), you can delete them, so as to keep your machine tidy.

What did NOT work - other answers here (unfortunately):

Other solutions here did not work for my situation for the current version of docker that I am using (as the time of writing, current docker version was: Docker v18.03 (current) ).

Also note (as @AlfaBravo correctly points out in their comment to my answer) that the other answers may well have worked for different or earlier versions of docker.

I should note that my host platform is Ubuntu Linux 16.04.4 LTS 64bit.

In all cases when attempting the other answers I had followed the process of stopping docker before doing the solution and then starting it up after, as required. :

  • https://stackoverflow.com/a/47604857/227926 - @Gerald Sabu M's solution to alter the /lib/systemd/system/docker.service - alter the line to: ExecStart=/usr/bin/docker daemon -g /mnt/hugedrive/docker/ - Outcome for me: docker still put its files in the default, original location: /var/lib/docker

  • I tried @Fai's comment, but that file does not exist on my system, so it would be something particular to their setup: /etc/systemd/system/docker.service.d/exec_start.conf. docker.service

  • I also tried @Hatem Jaber's answer https://stackoverflow.com/a/32072042/227926 - but again, as will @Gerald Sabu M's answer, docker still puts the files in the original default location of /var/lib/docker.

(I would of course like to thank them for their efforts, though).

Why I am changing the default docker location: encrypted file system for GDPR purposes:

As an aside, and perhaps useful to you, I'm running docker inside an encrypted file system (as part of a GDPR initiative) in order to provide Encryption of Data-at-Rest data state (also known as Encryption-at-Rest) and also for Data-In-Use) (definitions).

The process of defining a GDPR datamap includes, among many other things, looking at the systems where the sensitive data is stored (Reference 1: GDPR Data Map Template: An easy to use self-assessment tool for understanding how data moves through your organisation) (Reference 2: Data mapping: Where to start for GDPR compliance). And by encrypting the filesystem where the database and application code is stored and the swap file, risk of residual data left behind when deleting or moving a VM can be eliminated.

I've made use of some of the steps defined in the following links, credit to them:

I would note that a further step of encryption is recommended: to encrypt the database fields themselves - the sensitive fields at least - i.e. user data. You can probably find out about various levels of support for this in the implementation of popular database systems. Field encryption provides defence against malicious instrusion and leakage of data while the web application is running.

Also, as another aside point: to cover 'Data-In-Motion' state of data, I am using the free Let's Encrypt

therobyouknow
  • 6,604
  • 13
  • 56
  • 73
  • 2
    Glad it was of any help. :) Great answer, it's important to see how you worked it out. Also, important to mention the version (from this version on, it works this way. On previous ones, it might work as shown in other answers) – Alfabravo Jun 06 '18 at 18:13
  • +1 upvote thank you @Alfabravo well said. I have updated the answer with your advice. I have also added my hosting platform - Ubuntu Linux 16.04.4 LTS 64bit. – therobyouknow Jun 06 '18 at 23:51
  • 3
    _By default, the daemon.js file does not exist..._ _so create it:_ `vi /etc/docker/daemon.json` -- Am I right to assume that `daemon.json` is the correct file extension? – Joe Sadoski Sep 09 '18 at 00:03
  • +1 upvote yes @JoeSadoski thank you for spotting that error. It should be daemon.json not daemon.js - I have corrected it. Thanks again and sorry for the delay in getting back to you. – therobyouknow Sep 10 '18 at 22:00
  • 1
    Great answer with several critical details like by default no file there. As for you the other post about editing /etc/default/docker did not have any effect for me. @havnar This should be the accepted answer. – Oliver Nov 30 '18 at 18:11
  • 6
    `graph` option is [deprecated](https://docs.docker.com/engine/deprecated/#-g-and---graph-flags-on-dockerd) in v17.05.0. Use `data-root` instead. – Alireza Mohamadi May 11 '19 at 05:01
  • +1 @AlirezaMohamadi thank you - I've added in your comment about `graph` being deprecated and to use `data-root`, to the answer. – therobyouknow Jun 02 '19 at 08:37
  • 1
    @therobyouknow nicely explained......verified with docker version18.09.1...... i too tried other ways to edit the docker service...none worked...this one worked nicely...thanks.. – the_D Aug 03 '20 at 09:58
  • you're most very welcome @the_D, pleased to hear that it works for you - thank you! Certainly, also take note of @Alireza Mohamadi's comment about `data-root` when you are working with later versions of Docker. I've already included and credited them in my answer but haven't yet tried out their suggestion. – therobyouknow Aug 03 '20 at 11:14
  • `data-root` works for me on version `19.03.8`. Using `graph` I got a depreciation warning. – kiesel Dec 10 '20 at 10:51
  • I am getting an error: `no such image` for every image I try when I run `docker-compose up`, any idea? – soltex Jun 21 '21 at 10:19
  • Docker version 18.09.6, build 481bc77 work, -g dockerd not work – Tiana987642 Dec 28 '21 at 04:41
  • For my version 23.0.6, I decided to follow all the advices here :) Didn't work as it gave an error that data-root was specified as a flag in the json file as well as in the systemd service file. Removed one of them. – Hussain Akbar May 15 '23 at 05:55
  • @HussainAkbar thanks for your input: "Removed one of them" - and in doing so, did in now work for you? – therobyouknow May 15 '23 at 13:45
  • 1
    Yes. The --data-root flag in the service file works just fine. You don't need to put the json there. The json method is supported, but I was getting an error that data-root has already been specified, so I removed the json. Files are now created in the new location. – Hussain Akbar May 16 '23 at 17:04
18

The best solution would be to start the docker daemon (dockerd) with a correct data root path. According to the official documentation, as of Feb 2019, there are no --graph, -g options. These were renamed to the single argument --data-root.

https://docs.docker.com/engine/reference/commandline/dockerd/

So you should modify your /lib/systemd/system/docker.service so that the ExecStart takes into consideration that argument

An example could be

ExecStart=/usr/bin/dockerd --data-root /mnt/data/docker -H fd://

Then you should restart your docker daemon. (Keep in mind that you will no longer have your containers and your images, copy the data from your old folder to the new one if you want to maintain everything)

service docker restart

Keep in mind that if you restart the docker daemon your containers will be stopped, and only those with a correct restart policy will be restarted.


Tested on Ubuntu 16.04.5 Docker version 18.09.1, build 4c52b90

Naramsim
  • 8,059
  • 6
  • 35
  • 43
17

You can start the Docker daemon using -g option and the directory of your choice. This sets the appropriate runtime for Docker.

With version 1.8, it should be something like:

docker daemon -g /path/to/directory

With earlier versions, it would be:

docker -d -g /path/to/directory

From the man page:

-g, --graph=""
     Path to use as the root of the Docker runtime. Default is /var/lib/docker.
Dharmit
  • 5,498
  • 2
  • 27
  • 30
16

You can perform the following steps to modify the default docker image location, i.e /var/lib/docker:-

  1. Stop Docker

    # systemctl stop docker
    # systemctl daemon-reload
    
  2. Add the following parameters to /lib/systemd/system/docker.service.

    FROM:
    ExecStart=/usr/bin/dockerd
    TO:
    ExecStart=/usr/bin/docker daemon -g /mnt/hugedrive/docker/
    
  3. Create a new directory and rsync the current docker data to new directory.

    # mkdir /mnt/hugedrive/docker/
    # rsync -aqxP /var/lib/docker/ /mnt/hugedrive/docker/
    
  4. Now, Docker Daemon can be started safely

    # systemctl start docker
    
Jerald Sabu M
  • 1,200
  • 3
  • 16
  • 19
  • 1
    These steps were helpful. One thing I had to change. On my ubuntu machine, the execStart is actually found at /etc/systemd/system/docker.service.d/exec_start.conf. docker.service exists also, but does not control the docker daemon. I found the right path by running 'systemctl edit docker.service' – Fai May 15 '18 at 20:32
2

In /etc/default/docker or whatever location it exists in your system, change the following to something like this:

DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.8.4 -g /drive/location

If you have issues and it is ignored, apply this solution: Docker Opts in Etc Default Docker Ignored

Community
  • 1
  • 1
Hatem Jaber
  • 2,341
  • 2
  • 22
  • 38
  • 5
    In daemon.json file, it it added as `"graph":"/path/to/folder",` – Alfabravo Mar 10 '17 at 17:41
  • 1
    +1 upvote - thank you @Alfabravo - I hope it's OK if I provide additional useful information of value to support your working solution provided as a comment. I have elaborated it into a new answer here: https://stackoverflow.com/a/50726177/227926 – therobyouknow Jun 06 '18 at 17:27