tristo
tristo

Reputation: 131

docker - update an image based on a container

Whenever I'm working with a docker container, I find that as my project grows, inevitably I will need to install new python packages, node modules and entire apis like opencv.

But when I rebuild a docker image, all of the new software and packages that I installed get wiped out - as they are not specified in the dockerfile.

Is there a way to automatically update a dockerfile with the new installations I have made, or create a volume which stores apt-get packages?

Upvotes: 0

Views: 1084

Answers (2)

David Maze
David Maze

Reputation: 159352

all of the new software and packages that I installed get wiped out - as they are not specified in the dockerfile

That's a bug: fix it.

As a general rule you shouldn't be installing software in an interactive shell in a container. As you note, you'll lose all of your work when the container exits, and since you haven't written things down in your Dockerfile, there's no good way for your coworker or your production environment to reproduce what you've done.

I'd suggest a workflow of:

  1. Build a working application without using Docker at all. Make sure all of your language-level dependencies are recorded in an appropriate file (package.json, setup.py, requirements.txt). You should be able to run your application in a clean environment with your source tree and an appropriate language runtime.

  2. Write a Dockerfile that installs the language runtime, any required host-library dependencies, and your application. The resulting image should be completely self-contained; you should never need to docker exec into it to do things.

  3. As you update your application, run its tests locally, then docker build new images, delete the old containers, and docker run new ones.

If you browse around SO questions, you'll see many comments along the lines of "please include your Dockerfile in the question". It's a straightforward reproducible way to build an image that you can share with your coworkers now, or yourself six months later. You should never use docker commit: it's a recipe for setting yourself up for a very special image that you can't remember how you built and so can never update, which will be a problem once you have a critical security update or new software you need to install.

Upvotes: 0

person one
person one

Reputation: 541

I think docker commit might help your case

Check out the example below:

  • Create a container from base 'alpine' image
  • Add a tmp file in the container
  • Use "docker commit" and create a new image from it
  • Spin up a new container from the custom image which has the file that was added previously

[node1] (local) [email protected] ~
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[node1] (local) [email protected] ~

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine              latest              196d12cf6ab1        2 months ago        4.41MB
[node1] (local) [email protected] ~$ docker run -it alpine /bin/sh
/ # date > /tmp/now.txt
/ # cat /tmp/now.txt
Thu Nov 22 08:16:50 UTC 2018
/ # exit
[node1] (local) [email protected] ~


$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
6e0913313df1        alpine              "/bin/sh"           25 seconds ago      Exited (0) 4 seconds ago                       practical_knuth
[node1] (local) [email protected] ~
$ docker commit 6e0913313df1 custom-alpine:123
sha256:188d17ff3c5577ee858a6d71fbad410bb142fa818e11d0c965cdc634280512e2
[node1] (local) [email protected] ~
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
custom-alpine       123                 188d17ff3c55        4 seconds ago       4.41MB
alpine              latest              196d12cf6ab1        2 months ago        4.41MB
[node1] (local) [email protected] ~


$ docker history custom-alpine:123
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
188d17ff3c55        15 seconds ago      /bin/sh                                         72B
196d12cf6ab1        2 months ago        /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>           2 months ago        /bin/sh -c #(nop) ADD file:25c10b1d1b41d46a1…   4.41MB
[node1] (local) [email protected] ~


$ docker run -it custom-alpine:123 /bin/sh
/ # cat /tmp/now.txt
Thu Nov 22 08:16:50 UTC 2018
/ # date
Thu Nov 22 08:18:46 UTC 2018
/ # exit
[node1] (local) [email protected] ~
$

Upvotes: 1

Related Questions