-
Notifications
You must be signed in to change notification settings - Fork 5.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Preserve individual volumes on recreate #858
Conversation
Looks like tests are failing on 1.2.0 - this line fixed it: diff --git a/tests/integration/service_test.py b/tests/integration/service_test.py
index 5e00ec1..6df2301 100644
--- a/tests/integration/service_test.py
+++ b/tests/integration/service_test.py
@@ -148,6 +148,7 @@ class ServiceTest(DockerClientTestCase):
self.assertIn('FOO=1', old_container.get('Config.Env'))
self.assertEqual(old_container.name, 'figtest_db_1')
service.start_container(old_container)
+ old_container.inspect() # reload volumes
volume_path = old_container.get('Volumes')['/etc']
num_containers_before = len(self.client.containers(all=True)) However, there's a more serious regression - see #859. The new logic introduced in #711 doesn't preserve volumes that are declared in the image. What if the volume copying logic were:
This wouldn't handle the case where a volume is deleted from |
5baba4f
to
f7355be
Compare
container_volumes = container.get('Volumes') or {} | ||
original_volumes = set(volumes_option + container_volumes.keys()) | ||
|
||
for volume in original_volumes: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works in docker 1.2 to fix the test added in #859
Using docker 1.4.1 it seems like docker is refusing to override the volume with a bind
. This function is returning the correct value, but when container.start(binds=...)
is called, the old volume remains.
Maybe volumes_from
has to be used to override the volume? Maybe this is a bug in docker? I'm not really clear on what the expected behaviour is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe volumes-upper-guru @cpuguy83 has some time to have a look? Think you want this solved in the final release?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you tried against Docker master?
You should indeed be able to override an existing volume, and volumeFrom have priority over all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cpuguy83 Per @dnephin request adding info from my case here: https://gist.github.com/andreyst/e213c18ef32dcb28dc5e
This works if I try to mount something else like /tmp. If I ln -s the dir I need in /tmp and try to pass /tmp/dirname as a volume, it still doesn't work. If then I pass /tmp as a volume, it does work, but if then I try to cd to it from a container, it gives me "No such file or directory".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to create a minimal reproduction of this failure, but when I tried with the docker cli I was not able to reproduce the failure.
https://gist.github.com/dnephin/e584a7741a514d631632
From the docker inspect they look almost identical, except you can see in the fig example the volume is not set to the path specified by binds
.
I tried to use mitmproxy to inspect the differences between the http requests being used, but it seems like the docker cli ignores HTTP_PROXY
(I was able to get the requests made by fig at least).
I'm struggling to find the difference between this example and the test case. Does anyone know of a way to make the docker cli use a proxy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dnephin Support for proxies was added in Docker 1.5 via moby/moby#9951 (docs changes for it are in moby/moby#10192) not sure if there's another way to specify this. Given that it's just a one line change, you could try to build a 1.4.1 version with just that one change added?
(Sorry if it's a lame answer, but perhaps the links are useful :))
f7355be
to
ab4893c
Compare
Ok, This is working for 1.4.1 now, but requires api version 1.5 , which I think is 1.4 ? So blocking on #886 and makes compose incompatible with earlier versions. To support older versions we'd have to detect the server version and pass the binds to |
If the docs are correct, API v1.15 corresponds with docker 1.3 (https://docs.docker.com/v1.3/reference/api/docker_remote_api/). In my opinion, that's reasonable. Several CVEs were addressed in docker 1.3.x, so people should be encouraged to run that version at minimum. Otherwise, people can always run Fig 1.0.1 (that won't dissapear) 😄 |
But, keep in mind, there should be no issue with doing this on start (at least from the Docker side)! |
@cpuguy83 from https://gist.github.com/dnephin/e584a7741a514d631632 it looks like (at least in 1.4.1) the binds in start are not overriding the volumes from the Dockerfile. Maybe that's fixed in 1.5, I haven't had a chance to try it yet. |
@dnephin I think I've found the problem in Docker. For volumes that are created by docker, |
And that one may be different actually. # fig.yml
web:
build: .
volumes:
- "/foo"
- "/bar" # Dockerfile
FROM busybox
ADD . /foo
VOLUME /foo
VOLUME /bar
CMD exec top Does this look right? |
I don't think you'll be able to reproduce it with master, since it's still using This gist does reproduce it: https://gist.github.com/dnephin/083a1052b8293a5b46a4 It prints the volumes from both containers. They should be the same, but the second container has a different volume for |
0ded765
to
b6294b1
Compare
Yep, this will be fixed by moby/moby#10365 |
I've updated the title and description of this issue to better reflect the changes. I'd love to chat about getting this into 1.2. I think this is still the most common issue people have with This PR will need to be updated once we remove the intermediary container (in #874), but there is nothing in docker 1.5 (or coming in docker 1.6) that actually fixes the issue addressed by this PR. How do you feel about putting this into the 1.2 milestone? |
This does have the nasty side-effect that those volumes will be left behind (orphaned), which makes it very difficult to access them or clean then up until docker implements volume management |
That is true, but this is basically the case with any |
Yes, but with those I have some control, ie Given how many questions I've seen from people unaware of this ("docker leaks containers", "docker eats my disk space"), it should be documented properly. Lol, maybe compose should create a dummy container and attach all old volumes to that :) In general, Docker really needs better volume management. There are various proposals, so I hope it someday arrives natively. Apart from those concerns, I agree with this PR |
490e97a
to
b8cec3f
Compare
Ok, this is rebased with master and tests are passing. |
Nice. One more thing: Swarm uses
|
Cool, is swarm still using environment variables for this? The README suggests it's using labels now as well. Maybe both are supported? I wonder if it makes sense to just use labels? Edit: I guess I misread, it seems like label affinity is a different thing. I'll use environment variables |
b8cec3f
to
9bddd6b
Compare
Added the affinity. I was also able to cleanup some of the |
override_options, | ||
environment=merge_environment( | ||
override_options.get('environment'), | ||
{'affinity:container': container.id})) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, it needs to come out as affinity:container==<id>
, i.e. a double-equals. Maybe we should add a test for it?
(I'm going to investigate running Compose's test suite against Swarm, btw)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I did add a test for it, but I didn't realize it required the ==
.
If I set the value to =<id>
that should work, right ?
Signed-off-by: Daniel Nephin <dnephin@gmail.com>
9bddd6b
to
417d9c2
Compare
Using |
LGTM |
Preserve individual volumes on recreate
Resolves: #836
When a container is being recreated (during
docker-compose up
) we usevolumes-from
to copy every volume over to the new container. This has lead to a lot of confusion (there are numerous github issues, and stackoverflow questions about it).Instead of blanket copying every volume with
volumes-from
this PR changes the behaviour to only copy over container data volumes that are still present in the configuration. Host volumes, and volumes that were removed from the configuration will no longer be copied over (although host volumes are still applied, they just aren't copied) .#711 was the first attempt, but wasn't compatible with docker 1.4.1+
Related Issue #447