Make drone create volumes at specific folder

How can I make drone create volumes for every container in specific folder?

Right now, drone create volumes for git clone, and every step which doesn’t provide volume at the default location in docker which is/var/lib/docker/volumes.

I would like to make drone create it’s volumes at different folder (e.g. /root/docker-volumes)

The use case for this is, our server use HDD which caused pipelines to take minutes (5-10) although they finished they weren’t reported as such which stuck our whole development. We found out that this was because of the slow storage, so what we want to do is to make drone create its volumes at some folder that mounted to the RAM (we have plenty)

For now, we mounted the docker volume folder as tmpfs which now our pipeline takes only 1 minute! This has its drawbacks as every volume created at docker that is not mounted to specific location will saved in the RAM

If wanted I could try to implement this (although I would need a little guidance)

the location of volumes is managed by docker, not by drone:

Volumes are stored in a part of the host filesystem which is managed by Docker ( /var/lib/docker/volumes/ on Linux). Non-Docker processes should not modify this part of the filesystem. Volumes are the best way to persist data in Docker.

therefore, in order to change the location where directories are mounted, you would need to modify your docker daemon configuration. I do not have experiencing changing the docker daemon configuration in this way, so you may want to ask on the docker support forum and see if the docker maintainers can advise on how this might be configured.

Unfortunately, you can’t only change the volume directory and also we need to change only Drone created volumes directory.

You are right, BUT you can mount to a specific location.

And it is rather easy to implement IMO:

if env.custom_volume_directory === null:
   return // do nothing

do {
  generatedFolderName = uuid()
} while(is directory `${env.custom_volume_directory}/${generatedFolderName}` exists);

create directory `${env.custom_volume_directory}/${generatedFolderName}`

pass docker the mounted path

In order to make sure no 2 runners generate the same folder name at the same time we can add to the generated folder name the runner id (if have any)

No changes would be required to Drone to change the volume mount location. Instead you would change the Docker daemon on your host machine so that it uses an alternate directory for volumes.

EDIT: it looks like the above article is outdated. The docker daemon documentation indicates you can change the location where docker persists all data using the data-root configuration parameter [1]

The Docker daemon persists all data in a single directory. This tracks everything related to Docker, including containers, images, volumes, service definition, and secrets.

By default this directory is:

  • /var/lib/docker on Linux.
  • C:\ProgramData\docker on Windows.

You can configure the Docker daemon to use a different directory, using the data-root configuration option.

[1] https://docs.docker.com/config/daemon/#docker-daemon-directory

I’m familiar with that article, and the solution available have a critical drawback:

You can change the whole docker data directory to another location - this directory contains all current containers, images, and more - if we make the directory be in the RAM when the server crash everything will be lost.

Even if you could set only the docker volume directory (where docker saves the volumes without a specific path) this would set ALL volumes to be in the RAM, but we only want the generated volumes that Drone creates for its steps in it.

Our solution is a workaround:
We moved the metadata.db file to a different directory that is not mounted to RAM and mounted the default volumes directory to the RAM. now in the Docker service file we created a symlink from the metadata.db file to the volumes folder before starting Docker.

This work but still it’s very dangerous as you quote what Docker said:

Non-Docker processes should not modify this part of the filesystem

Unfortunately, we don’t have SSDs in our servers which causes our pipeline to run for 5-30 minutes! (depending on how many ran at the same time). Doing the workaround I said made our pipeline run in 1-3 minutes!

Drone currently uses data volumes (also called anonymous volumes). The benefit of data volumes is they can be easily deleted along with all data once the pipeline completes. The proposal you have made would require Drone to use host machine volumes which is problematic since it would require Drone have access to the host machine file system to create directories and to manually purge data. Since Drone is running inside a container it does not currently have access to the host machine file system. Furthermore, there is no guarantee the runner and Docker daemon are on the same machine since runner can connect to a Docker daemon using TCP (by setting DOCKER_HOST).

I am personally not too keen on using host volume mounts for the reasons outlined above, but I will defer to the rest of the Drone team. An alternate approach could be to optionally configure the Drone to create workspace volumes using tmpfs (which is natively supported by docker)

workspace:
  path: /drone/src
  tmpfs: true
1 Like

I like the workspace approach, although it’s not system-wide (maybe we can make it by adding a flag - USE_WORKSPACE_TMPFS_BY_DEFAULT or better name :grimacing:)

And if that flag or property is true we can add the --type=tmpfs flag when creating volume (Docker Engine - Driver specific options)

WDYT?

Ping you :smiley:
Is there any update?

If you would like all your pipelines to use tmpfs as workspace volume type without having to specify this in every definition, your best bet is to write a small extension, modifying the pipeline definition before it is being processed by drone.

Another workaround for your before mentioned downsides of reconfiguring the docker daemon is to host another docker daemon just for your pipelines, configure it according to the before mentioned documentation links and run all your other containers on a separate daemon. Still not for free, but a doable way to solve this.

Without trying to be impolite… your problem is a very specific one and creating an equally specific solution for a general purpose product like drone sounds inappropriate to me too. Both drone and docker enable you to solve your specific problem yourself with more general purpose mechanisms, though it might not as simple as switch a configuration flag.

1 Like

Thanks for the answer!

If that solution (set the workspace as tmpfs) exists then I will try to create the extension

BTW, is it possible to enable extension system-wide?

Depends on your definition of “system-wide” :wink:

Conversion extensions are configured for the drone server, so their modifications of pipelines should therefore apply to all runners of this server.

1 Like

Great so now left to implement the tmpfs type