Saving Docker container state on Windows - windows

I create a docker container using
docker-machine.exe create -d virtualbox --virtualbox-memory 2048 default
and I logged into the bash using
docker run -ti ubuntu /bin/bash
and I got something like root#ae78cd536ddf:/# where I did a couple of apt-get installs.
Then, I exited from the bash and when I again logged back in I could not find what I had installed. I wanted to do a docker commit, but I somehow can't figure where my installed stuff is?
UPDATE
Based on the answers I tried creating an image of the container. I have compiled all commands in a gist.

With docker run, you create a container from the ubuntu image. The container has the name ae78cd536ddf (in your case). You can inspect images and containers with docker ps -a and docker images respectively.
Each time you run docker run, a new container is created. When using docker run --name Somename, you force the container to be named Somename which prevents you from creating another container with the same name.
Images are immutable which means you can not change them. So when you modify something in the running container, the image stays the same and this you can create more containers from the same image.
So after you stopped a container (docker stop, exit the containerized bash or just reboot), you can run docker start ae78cd536ddf to restart it. But it will be running in background and you won't have a bash (check docker ps to see it's running). Now you just need a bash: docker exec -it ae78cd536ddf /bin/bash will execute a bash in the container you started before.
Just a note about creating images. You might want to install the software you always need (I personally love vim, htop, ...) and then docker commit the container. This will create a new image which you can see in docker images. Now you can run containers from this image by replacing ubuntu with your image name.
To get more reproducable builds (when using a CI for example), you can create a Dockerfile and run docker build.

Every docker run command creates a new container. The id in the hostname of the bash shell is the container ID. You can commit that.
To see all containers (including stopped containers), do docker ps -a.

Related

how to create directory in docker from terminal from zsh terminal?

so i have downloaded Docker Desktop and until now i have tested out containers and stuff just executing regular commands (docker ps, docker images..., docker run...) inside my zsh terminal and it works fine but now i am in a position where i want to create a directory inside docker host so that i can put my dockerfile inside, but if i run mkdir directory-name it is going to create the directory inside my mac not docker! so what command can i use to indicate that i want the directory to be created on docker not on my own mac machine?
While your docker container is running, you can start a new shell session inside using docker exec.
docker exec -it mycontainer bash
-i means interactive - so you can type
-t allocates a pseudo-TTY - just know that you need the argument
Then inside this bash, you can create folders and files all you want and they will be placed inside your running container. Note that whenever you remove the container (e.g. to update its image), these changes will be entirely lost. For persistence, use docker volumes.
Say you have the following directory structure:
.
├── Dockerfile
└── simple-web-app
Your Dockerfile:
FROM scratch
ADD simple-web-app simple-web-app
Then you would run
docker build .

How to tell docker run to run the latest image from docker hub?

Im using the following command to run an image off docker hub
docker run -it -e "SPRING_PROFILES_ACTIVE=localdocker" -p 8080:8080 name/repo:8 /bin/bash
Two questions:
First of all, is there a way to not have to keep increment the number next to the repo each time CI uploads a new image? Is there a way to say just run the latest?
What is the command to run if I want to stop the current instance and instead restart it with a newer image from the hub?
Yes, if you are using any CI tool then you can dynamically substitute the new created docker image tag to a variable.
Say - dockerimage:${buildID} , you can replace this buildID dynamically via your CI tool
While creating container, always give it a name, such that you can execute
docker stop
command on that container, to stop it and then clear the container permanently too, if you want to reuse that container name always, if you execute
docker ps -a | grep give_container_name_here
it will give you that container and then you can delete that via
docker rm $(docker ps -a | grep give_container_name_here)
Then you can restart docker container with new docker image that you have created via CI pipeline

Unable to find docker image locally

I was following this post - the reference code is on GitHub. I have cloned the repository on my local.
The project has got a react app inside it. I'm trying to run it on my local following step 7 on the same post:
docker run -p 8080:80 shakyshane/cra-docker
This returns:
Unable to find image 'shakyshane/cra-docker:latest' locally
docker: Error response from daemon: pull access denied for shakyshane/cra-docker, repository does not exist or may require 'docker login'.
See 'docker run --help'.
I tried login to docker again but looks like since it belongs to #shakyShane I cannot access it.
I idiotically tried npm start too but it's not a simple react app running on node - it's in the container and containers are not controlled by npm
Looks like docker pull shakyshane/cra-docker:latest throws this:
Error response from daemon: pull access denied for shakyshane/cra-docker, repository does not exist or may require 'docker login'
So the question is how do I run this docker image on my local mac machine?
Well this is illogical but still sharing so future people like me don't get stuck.
The problem was that I was trying to run a docker image which doesn't exist.
I needed to build the image:
docker build . -t xameeramir/cra-docker
And then run it:
docker run -p 8080:80 xameeramir/cra-docker
In my case, my image had TAG specified with it and I was not using it.
REPOSITORY TAG IMAGE ID CREATED SIZE
testimage testtag 189b7354c60a 13 hours ago 88.3MB
Unable to find image 'testimage:latest' locally for this command docker run testimage
So specifying tag like this - docker run testimage:testtag worked for me
Posting my solution since non of the above worked.
Working on macbook M1 pro.
The issue I had is that the image was built as arm/64. And I was running the command:
docker run --platform=linux/amd64 ...
So I had to build the image for amd/64 platform in order to run it.
Command below:
docker buildx build --platform=linux/amd64 ...
In conclusion your docker image platform and docker run platform needs to be the same from what I experienced.
In my case, the docker image did exist on the system and still I couldn't run the container locally, so I used the exact image ID instead of image name and tag, like this:
docker run myContainer c29150c8588e
I received this error message when I typed the name/character wrong. That is, "name1\name2" instead of "name1/name2" (wrong slash).
In my case, I saw this error when I had logged in to the dockerhub in my docker desktop. The repo I was pulling was local to my enterprise. Once i logged out of dockerhub, the pull worked.
This just happened to me because my local docker vm on macos ran out of disk space.
I just deleted some old images using docker image prune and it started working correctly again.
shakyshane/cra-docker Does not exist in that user's repo https://hub.docker.com/u/shakyshane/
The problem is you are trying to run an imagen that does not exists. If you are executing a Dockerfile, the image was not created until Dockerfile pass with no errors; so when Dockerfile tries to run the image, it can't find it. Be sure you have no errors in the execution of your scripts.
The simplest answer can be the correct one!.. make sure you have permissions to execute the command, use:
sudo docker run -p 8080:80 shakyshane/cra-docker
In my case, I didn't realise there was a difference between docker run and docker start, and I kept using the run command when I should've been using the start command.
FYI, run is for building and creating the docker container, start is to just start a stopped container
Use -d
sudo docker run -d -p 8000:8000 rasa/duckling
learn about -d here
sudo docker run --help
At first, i build image on mac-m1-pro with this command docker build -t hello_k8s_world:0.0.1 ., when is run this image the issue appear.
After read Master Yi's answer, i realize the crux of the matter and rebuild my images like this docker build --platform=arm64 -t hello_k8s_world:0.0.1 .
Finally,it worked.

Dockerfile for a newly committed docker image

I downloaded an image of ubuntu os in my system and after about committing 3 images from it(every image has an incremental change from before image), I now have my final image. Now I want the Dockerfile of this final image so that I can include commands like starting service at the start of container.
I have used this command,
sudo docker commit --change='CMD service apache2 start' 172d6dc34471 server_startup
to make the apache service start when the container is run. This starts the service in the container but doesn't go inside the container. It just starts the apache and exits to my local environment.
I would like to know how to get the Dockerfile for my final image so that I can include startup commands.
I have also tried this dockerfile from image, but its not working. It just throws error that .sock file is missing. I have tried this with both the new image and the parent image that I first downloaded.
Any help is much appreciated. Thanks.
you can use
docker history --no-trunc your_image
it will show you (in reverse order) what has been done
It is less user friendly than dockerfile from image, but it is basically the same thing.
I have somewhere a Python script that does that cleanly, I will check and post it.
Edit: Just this should show a lot
docker history your_image | docker inspect $(awk ' NR>1 {print $1}')
As CMD you need to provide a no-daemon program that keeps in foreground. That is not accomplished by service.
You should try:
sudo docker commit --change='CMD apache2 -DFOREGROUND' 172d6dc34471 server_startup
Sorry for the late reply, I used the --change argument while committing the image to point to the custom script(which I added within the container with the list of commands to be run at the start) that I want to run when the image is run for the first time.
sudo docker commit --change='ENTRYPOINT ["/test.sh"]' containerId autostart
I didn't know much about the dockerfile that everyone is suggesting but it is also a very good solution.

Does docker stores all its files as "memory image", as part of image, not disk file?

I was trying to add some files inside a docker container like "touch". I found after I shutdown this container, and bring it up again, all my files are lost. Also, I'm using ubuntu image, after shutdown-restart the same image, all my software that has been installed by apt-get is gone! Just like running a new image. So how can I save any file that I created?
My question is, does docker "store" all its file systems like "/tmp" as memory file system, so nothing is actually saved to disk?
Thanks.
This is normal behavoir for docker. You have to define a volume to save your data, those volumes will exist even if you shutdown your container.
For example with a simple apache webserver:
$ docker run -dit --name my-apache-app -v "$PWD":/usr/local/apache2/htdocs/ httpd:2.4
This will mount your "current" director to /usr/local/apache2/htdocs at the container, so those files wil be available there.
A other approach is to use named volumes, those ones are not linked to a directory on your disk. Please refer to the docs:
Docker Manage - Data
When you start a container using docker run command,docker run ubuntu, docker starts a new container based on the image you specified. Any changes you make to the previous container will not be available, as this is a new instance spawned from the base image.
There a multiple ways to persist your data/changes to your container.
Use Volumes.
Data volumes are designed to persist data, independent of the container’s lifecycle. You could attach a data volume or mount a host directory as a volume.
Use Docker commit to create a new image with your changes and start future containers based on that image.
docker commit <container-id> new_image_name
docker run new_image_name
Use docker ps -a to list all the containers. It will list all containers including the ones that have exited. Find the docker id of the container that you were working on and start it using docker start <id>.
docker ps -a #find the id
docker start 1aef34df8ddf #start the container in background
References
Docker Volumes
Docker Commit

Resources