Skip to content
This repository has been archived by the owner on Aug 26, 2021. It is now read-only.

Volume at /tmp #45

Closed
fthorns opened this issue Jan 28, 2019 · 11 comments
Closed

Volume at /tmp #45

fthorns opened this issue Jan 28, 2019 · 11 comments
Labels

Comments

@fthorns
Copy link

fthorns commented Jan 28, 2019

Hi there,

the Dockerfile requests a volume to be mounted at /tmp. In case no volume is explicitly mounted when the container is started, Docker creates a new volume every time the container is created. Since the documentation does not advice to mount a volume to /tmp, it seems that this volume is not needed. It would be great if someone could confirm that there is no need for the /tmp volume and drop the VOLUME clauses from the Dockerfiles.

Regards,

Fabian

@ldez
Copy link
Contributor

ldez commented Jan 28, 2019

Hi, the /tmp folder is required by some middlewares (ex: buffering)

@fthorns
Copy link
Author

fthorns commented Jan 28, 2019

Hi, thanks for the explanation. Would it be generally advisable to put /tmp/ on a persistent volume? Right now it seems that the volumes are not reused in any of the documentation's examples, so the data could as well just stay in the ephemeral storage of the container. The current documentation leads to a huge number of orphaned volumes over time, so it might be worth to either drop the volume or advice handling it correctly. Not sure which way is the preferable one, though.

Fabian

@ldez ldez added the question label Jan 28, 2019
@gbouthenot
Copy link

I agree with fthorns:
Either this volume should be removed from the Dockerfile, or the documentation should explicitely specify it should me mapped.

@errm
Copy link

errm commented Mar 5, 2019

Would it be generally advisable to put /tmp/ on a persistent volume

I don't think this is required...

could as well just stay in the ephemeral storage of the container

This could cause a performance issues... so using a volume is preferable I think...

Perhaps we could just add some documentation mentioning which middlewares needs this facility ... then it's simple to mount tmpfs or some other storage where required...

@fthorns
Copy link
Author

fthorns commented Mar 6, 2019

could as well just stay in the ephemeral storage of the container

This could cause a performance issues... so using a volume is preferable I think...

Perhaps we could just add some documentation mentioning which middlewares needs this facility ... then it's simple to mount tmpfs or some other storage where required...

If it boosts performance for certain middlewares it might be worth documenting it as a tuning tip (it's still possible to mount a volume to any path, even without the path being explicitly declared in the Dockerfile). If the user is aware of the volume they might even consider preserving it across container restart to avoid building up the cache over and over again.

@dtomcej
Copy link
Contributor

dtomcej commented Mar 13, 2019

The buffering middleware is an example of why this volume is needed.

If there is no /tmp directory, the buffering middleware will fail. We generate this volume to ensure that the directory is present due to being based off a scratch image.

We had a choice to make a bare directory or a volume for this, and we chose to make a volume due to flexibility and giving more options to operators.

@BashfulBandit
Copy link

We had a choice to make a bare directory or a volume for this, and we chose to make a volume due to flexibility and giving more options to operators.

Is this documented anywhere? I found a large list of empty Docker Volumes in my Docker Swarm today and found my Traefik service was the one creating these every time it was restarted.

With that said, is there any need to have the /tmp directory be persistent between restarts? This use of the VOLUME instruction doesn't seem to be the correct use in this case.

@dduportal
Copy link
Contributor

Hi, The usage of the VOLUME instruction in a Dockerfile is really different than the kind of "mount" to be used:

  • The instruction VOLUME is a metadata telling that this directory will carry data with a lifecycle different than the container's. It is expressed at build time in a portable way. This is why we use this: to express that the data read/written into the directory /tmp is different than the default filesystem of the container (like the binary). Docker's documentation is really explicit about this: https://docs.docker.com/engine/reference/builder/#notes-about-specifying-volumes

  • The "mount type" is expressed at runtime. It express "how" you want the data layer of a given volume to be implemented, depending on the execution context. It's generally a combined matter of I/O performances + persistence properties. In the case of /tmp, the best is to do a tmpfs mount, so data is ephemeral, does not survive container restarts, and the I/O is really efficient. SO you don't have long term persistence AND you have to be careful on the amount of data written to not exhaust your RAM.
    BUT there are numerous cases where tmpfs is not an option for bind mounting a volume. So Docker assumes, by default, that a "VOLUME" (as declared in the container metadatas) is still having a different lifecycle than container's FS, by using a local anonymous volume.

  • A very good practise is to run container with the flag --read-only which will lock in read-only the container's filesystem, allowing writing only on volumes and mounts. 2 reasons for such a practise:

    • Performances, because the "overlay" filesystem use in containers (but NOT in volumes, whatever mounts they are) is really bad in I/O perfs with random data. Which is the opposite of what /tmp requires: performances. So using a volume is the solution.
    • Security: you absolutely want to lock down your container as much as possible to add another layer of safety if application breakout occurs inside the container. In this case, i you docker run --read-only=true traefik, the user experience is terrible, as Traefik will crash immediately because not able to write in /tmp, so not starting.

From these theoretical concerns, a few tasks should be done:

  • Appending the VOLUME instruction of Traefik to meet ALL the folders where it could write by default (I'm not sure if /var/run is not required).
  • Improve documentation to recommend mounting the /tmp (and /*/run) as tmpfs.
  • Taking the habits, when using Docker, to regularly run docker system prune with the right option to efficiently clean up anonymous volumes. Because Traefik is not the only one container with such behavior, as it follows the Docker good practises, as explained in Docker's documentation: https://docs.docker.com/config/pruning/

About advertising "how to handle" these volumes, it's a complicated topic, as it is a general matter to ALL projects using Docker containers. Should Traefik's project tell its user how to use Docker? This would be a huge effort, and would lead to a never-up-to-date documentation right?
However, it's open source, do not hesitate to propose a change in the doc, understanding that the community of maintainers will have to carry such a change ("No is temporary, Yes is definitive").

@polarathene
Copy link

Is this behaviour only related to the scratch base image or alpine too?

Just to confirm, this is enforced because it avoids extra steps by the user to ensure they're mounting tmpfs?

Is there a way for a user to override the approach here that still works but avoids creating anonymous volumes each time? I'm pretty sure I've used a container in the past that would write to /tmp on the host but it wasn't piling up anonymous containers mentioned here :/

@dduportal
Copy link
Contributor

@polarathene , the behavior is the same for both images, because of the use of instruction "VOLUME" in both Dockerfiles.

You can definitively avoid anonymous volumes by providing a name for each mountpoint:

docker run -v tmp-for-traefik:/tmp .... traefik

But again, you strongly should run a docker system prune -f --volumes everyday to cleanup dangling images, anonymous volumes, unused networks, so you keep your Docker engine clean and lean.

@rlagutinhub

This comment has been minimized.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

9 participants