Why does docker container persist changes despite restart - docker

I login to ubuntu docker container having name epic_torvalds using docker exec and create a file /tmp/test.log
I then wish to persist this change /tmp/test.log so I do docker commit epic_torvalds newlogimage
Now stopping and starting the containers using docker container rm -f <containerid> for both epic_torvalds & newlogimage shows /tmp/test.log even after restarting the docker daemon.
My expectation was that the changes to the container once committed are saved in the newly created container and do not persist in the base image from which it was created.
Only If I delete the image of epic_torvalds and recreate the old ubuntu image using docker run is when the /tmp/test.log is lost.
Thus, is the changes to a container persisted by default despite restarts without docker commit?
Is there is a feature not to persist changes to the container if that happens to be the default behavior?

Related

docker container created and deleted automatically

i'm trying to start up tomcat on my docker desktop,and i followed the official tomcat tutorial on docker hub.but somehow i found that docker will create a new container everytime after running the command:docker run -it --rm tomcat and delete the container automatically when tomcat shuts down.
i have already known the reason is that run --rm can automatically remove the container when it exits.
now i finally built webs on tomcat,and i don't want them to be vanished.
how can i save my container before it's deleted?
thx! ;D
Based on what I've found on the internet, remove the --rm flag is not possible currently. docker update gives you the ability to update some parameters after you start your container, but you cannot update the cleanup flag (--rm) according to the document.
References:
I started a docker container with --rm Is there an easy way to keep it, without redoing everything?
Cancel --rm option on running docker container
But some workaround can be applied. You can export your current container to an image, act as a checkpoint, then you can start a new container without the --rm flag, and based on the image you exported. You can use docker commit to do so:
docker commit [your container name/id] [repo/name:tag]
(Use docker ps to list your containers, do it in a new bash/cmd/PowerShell session, or you will lose your work when you exit your docker container)
Then start a new container without the --rm flag:
docker run -it [repo/name:tag]
Disclaimer:
In the production environment, you should never change the container by running bash or sh in it. Use Dockerfile and docker build instead. Dockerfile will give you a reproducible configuration even you delete your container. By design, the container should not have any important data (aka not persistent). Use the image and volumes to save your custom changes and configurations.

How to stop/relaunch docker container without losing the changes?

I did the following and lost all the changed data in my Docker container.
docker build -t <name:tag> .
docker run *-p 8080:80* --name <container_name> <name:tag>
docker exec (import and process some files, launch a server to host them)
Then I wanted to run it on a different port. docker stop & docker run does not work. Instead I did
docker stop
docker rm <container_name>
docker run (same parameters as before)
After the restart I saw the changes that happened in the container at 1-3 had disappeared, and had to re-run the import.
How do I do this correctly next time?
what you have to do is build the image from the container you just stopped after making changes. Because your old command still using the old image which doesn't have new changes(you have made changes in container which you just stopped not in image )
docker commit --help
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes
docker commit -a me new_nginx myrepo/nginx:latest
then you can start container with the new image you just built
but if you dont want create image with the changes you made(like you dont want to put config containing password in the image) you can use volume mount
docker run -d -P --name web -v /src/webapp:/webapp training/webapp python app.py
This command mounts the host directory, /src/webapp, into the container at /webapp. If the path /webapp already exists inside the container’s image, the /src/webapp mount overlays but does not remove the pre-existing content. Once the mount is removed, the content is accessible again. This is consistent with the expected behavior of the mount command.
Manage data in containers
Every time you do a docker run it will spin up a fresh container based on your image. And once a container is started, there are very few things that docker allows you to change with the docker update. So instead, you should preserve your data in an external volume that needs to persist between instances of a container. E.g.
docker run -p 8080:80 -v app-data:/data --name <container_name> <name:tag>
The volume name (app-data) and mount point in the container (/data) can be changed for your own requirements. Then when you destroy and restart a new container, you can mount the same volume in the new container.

Why does my non-volume data in Docker container persist even after restarting the container?

In some places when I read about Docker containers, I found some people talking that they lose their data (saved inside the container and not a part of volume data) when they restart the container.
I tried to create a simple Ubuntu container like this: docker run -it ubuntu /bin/bash, and created some files inside the container and then restarted it, but my data still there. Why does that actually happen? why do my data still there? Is this something new in the newer versions of Docker or do I have misunderstanding for something?
The data is lost when the container is removed, not when it's stopped or restarted.
Basically, if you do docker ps, if the containers keeps the same id (the big ugly hexadecimal id), the data is not lost.
It gets complicated when somehow your docker containers are not managed by you, but by some kind of automated-managing method. Tools like these usually start new containers if there is failure. In that case you should mount a volume to store your data on the host.
You might want to look at the Container Lifecycle: https://github.com/wsargent/docker-cheat-sheet#lifecycle
docker create creates a container but does not start it.
docker rename allows the container to be renamed.
docker run creates and starts a container in one operation.
docker rm deletes a container.
docker update updates a container's resource limits.
If you do docker rm and docker run again your state will not be there anymore.
If you want a transient container, docker run --rm will remove the container after it stops.

Docker: How to save running instance?

I am running an instance of docker, and I would like to save my work - the docs just aren't 100% clear on how to do this, so I'm asking here. I opened the docker instance using:
docker run -it [public dockerhub name]
Now I would like to save all my work locally so that I can come back to it. I don't particularly want to check it into dockerhub, unless that's advisable.
Here's what I have done. I have opened a new docker CLI tab, and done docker ps there to find the ID of the running docker instance. Then in the same tab I tried doing this:
docker commit <docker-id> me/myinstance
This gave me a commit hash.
Can I now safely exit the running docker instance? What command would I use to open it again - do I need to store the commit hash, or can I just do docker run -it me/myinstance?
As the docs mention:
You pull an image from Docker hub
You run that image on a container using docker run <image>
When you make changes to a container, you're not changing the underlying image, so those changes are not persisted if the container is stopped. To persist the changes you've made to the container, you create a new image with docker commit <container_id>
In the example that is on Docker docs:
# What containers are running on my system?
$ docker ps
ID IMAGE COMMAND CREATED
c3f279d17e0a ubuntu:12.04 /bin/bash 7 days ago
197387f1b436 ubuntu:12.04 /bin/bash 7 days ago
# Create a new image called svendowideit/testimage, tag it as "version3"
$ docker commit c3f279d17e0a svendowideit/testimage:version3
f5283438590d
# What images do I have on my system?
$ docker images
REPOSITORY TAG ID
svendowideit/testimage version3 f5283438590d
This way, you have persisted the changes to container c3f279d17e0a, on a new image, called svendowideit/testimage:version3.
Now you have an image with your modification, so you can run it as many times as you want on a container:
$ docker run svendowideit/testimage:version3
Again, containers are stateless. Any change you make inside a container, is lost when that container stops. One way to persist data even after a container exists, is by using volumes. This way your container has access to a directory in the host filesystem, that you can read and write.
Changes made inside a container are not lost when the container exits and containers (container applications) are not stateless unless you have specifically separated the data storage from the application (by mounting folders from the host filesystem or sending data to a database outside of the container).
To see your changes persisted in a container, start the old container (docker start ~) instead of creating a new container (docker run ~).
This is easier to do if you name your containers.
ie.
docker run -it --name containerName imageName
do stuff to your container
docker kill containerName
docker start containerName
You will see that your changes are persisted in that container.
You can also commit your container as an image, which can be pushed to a registry or exported to a file.

Docker Container Logs

We are running Century Link's Watchtower container. This allows us to have a watch a docker registry and download new images when they are created. When watchtower finds a new image it runs docker rmi which deletes the old container. With that the old logs go with it.
Is there a way without using a logging service to retain the logs when docker does it's clean up?
You can retain your logs by either logging to shared data volume :
Say you have logs of container in /apps/logs location
docker volume create logs
docker run -v logs:/apps/logs <image>
Or you can directly log onto host directory
docker run -v /apps/logs:/apps/logs <image>
So, by these methods you can retain your logs even after old containers and images are deleted.

Resources