Skip to content
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

Map read/write filesystem layer to new container #3044

Closed
parente opened this issue Dec 4, 2013 · 7 comments
Closed

Map read/write filesystem layer to new container #3044

parente opened this issue Dec 4, 2013 · 7 comments

Comments

@parente
Copy link

parente commented Dec 4, 2013

Would it be possible to map the read/write filesystem layer from a stopped container to a run of a new container spawned from a newer version of the container image?

Let me explain by example. Say I build an image parente/sshd:v1 from a Dockerfile that sets it up to act as a little box with ssh enabled. I docker run an instance of it named "teambox1", ssh in, and set up 5 user accounts. All 5 users use the box for a while, changing their passwords, putting pubkey pairs in to simplify auth, copying data to it, etc.

docker run -name teambox1 -d parente/sshd:v1

Now a month later, let's say I update the Dockerfile to also run a ftp server on the box. I rebuild parente/sshd. Now I want to somehow update my "teambox" instance to take advantage of the latest and greatest ftp feature. My options seem limited:

  1. Run a new instance, "teambox2", of the image. Manually migrate everything from "teambox1" to "teambox2".
  2. Use a volume mount on "teambox1" and then mount it in "teambox2". This works for anything that can be contained in a volume mount, but doesn't cover (afaik) things like users created in the container (/etc/passwd, /etc/shadow, ...).
  3. Carefully use the "teambox1" so that things like users are managed externally to the container so that it can be replaced by "teambox2" more easily. (But what if I need to rev the auth container?)

What I'm wondering is if Docker could support something like the following:

docker run -name teambox2 -reuse-write-layer teambox1 -d parente/sshd:v2

where the magic -reuse-write-layer would mount the the top layer of the filesystem from the "teambox1" container as the top FS layer in the "teambox2" instance. It would be fine if I had to stop the "teambox1" container before running this command to avoid two containers accessing the same layer at once. Having this would make it trivial to migrate all FS changes from one container to the next, regardless of where they appeared in the filesystem.

I understand that if I did this for two completely incompatible images it would fall all over the floor, but maybe there's a way to detect that? Or maybe it's an "advanced" feature where ymmv?

@crosbymichael
Copy link
Contributor

@parente Why can you not use -v and -volumes-from to achieve the same results ?

@parente
Copy link
Author

parente commented Dec 20, 2013

I'm not opposed to using volumes, but would it enable me to capture changes anywhere in the file system? Like in my #2 above, if I add users to the container, changes appear in /home, /etc/passwd, /etc/shadow, etc. Wouldn't this entail VOLUME /? Is that even possible or desirable?

@crosbymichael
Copy link
Contributor

Also why wouldn't you commit the underlying container?

@parente
Copy link
Author

parente commented Dec 20, 2013

I'm not sure how committing helps with upgrading the read-only layers to include the ftp server in my example. Maybe I'm missing some nicety of commit that allows it?

I should be clearer and say I'm running multiple instances.

  1. I've run multiple instances of parente/sshd:v1 for months with users adding data wily nilly throughout them.
  2. I find I now need to update all of them to run an ftp server in addition to sshd.
  3. I've updated my Dockerfile to include the ftp server.
  4. I've built and tagged a new image from it named parente/sshd:v2.

How do I roll out that ftp server to all the running containers? I was wondering if it would be possible to somehow swap out the read-only layers of all the running containers (parente/sshd:v1) and then stick the write layer back on top of containers spawned from parente/sshd:v2.

@crosbymichael
Copy link
Contributor

@parente Thanks for the responses. I'll have to think about how to solve this issue. I believe it can be done with a commit and volumes. I'll get back to you soon if you don't fine a good solution in the meantime.

I think reusing an rw layer is very complex and lead to bad things. Hopefully we can solve this with the standard docker command set.

@parente
Copy link
Author

parente commented Dec 20, 2013

@crosbymichael No problem.It could very well be this can be solved with the features already in docker and I'm missing the magic combo that does it. I'll post if I find something along the lines of commit and volume in the meantime.

@unclejack
Copy link
Contributor

From what I've read, it sounds like the following workflow would work for your particular use case:

  1. run docker commit for all containers and store their resulting image IDs (you need to keep a list of what container became what image)
  2. write a small Dockerfile which performs the desired updates and operations
  3. change "" in "from " within the Dockerfile to be the resulting image ID (from the commit operations) of every container & perform a docker build to update each and every container
  4. start new containers based on the final images

I know this isn't perfect or simple, but it should be easy for you to script this and make it into a repeatable process.

I'll close this issue now since this is pretty much the only possible workflow when data can't be stored only in volumes. Please feel free to comment.

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

No branches or pull requests

3 participants