How to start a stopped Docker container with a different command?
DockerDocker Problem Overview
I would like to start a stopped Docker container with a different command, as the default command crashes - meaning I can't start the container and then use 'docker exec'.
Basically I would like to start a shell so I can inspect the contents of the container.
Luckily I created the container with the -it option!
Docker Solutions
Solution 1 - Docker
#Find your stopped container id
docker ps -a
#Commit the stopped container:
This command saves modified container state into a new image user/test_image
docker commit $CONTAINER_ID user/test_image
#Start/run with a different entry point: docker run -ti --entrypoint=sh user/test_image
Entrypoint argument description: https://docs.docker.com/engine/reference/run/#/entrypoint-default-command-to-execute-at-runtime
#Note: Steps above just start a stopped container with the same filesystem state. That is great for a quick investigation. But environment variables, network configuration, attached volumes and other staff is not inherited, you should specify all these arguments explicitly.
Steps to start a stopped container have been borrowed from here: (last comment) https://github.com/docker/docker/issues/18078
Solution 2 - Docker
Edit this file (corresponding to your stopped container):
vi /var/lib/docker/containers/923...4f6/config.json
Change the "Path" parameter to point at your new command, e.g. /bin/bash. You may also set the "Args" parameter to pass arguments to the command.
Restart the docker service (note this will stop all running containers):
service docker restart
List your containers and make sure the command has changed:
docker ps -a
Start the container and attach to it, you should now be in your shell!
docker start -ai mad_brattain
Worked on Fedora 22 using Docker 1.7.1.
NOTE: If your shell is not interactive (e.g. you did not create the original container with -it option), you can instead change the command to "/bin/sleep 600" or "/bin/tail -f /dev/null" to give you enough time to do "docker exec -it CONTID /bin/bash" as another way of getting a shell.
NOTE2: Newer versions of docker have config.v2.json, where you will need to change either Entrypoint or Cmd (thanks user60561).
Solution 3 - Docker
Add a check to the top of your Entrypoint script
Docker really needs to implement this as a new feature, but here's another workaround option for situations in which you have an Entrypoint that terminates after success or failure, which can make it difficult to debug.
If you don't already have an Entrypoint script, create one that runs whatever command(s) you need for your container. Then, at the top of this file, add these lines to entrypoint.sh
:
# Run once, hold otherwise
if [ -f "already_ran" ]; then
echo "Already ran the Entrypoint once. Holding indefinitely for debugging."
cat
fi
touch already_ran
# Do your main things down here
To ensure that cat
holds the connection, you may need to provide a TTY. I'm running the container with my Entrypoint script like so:
docker run -t --entrypoint entrypoint.sh image_name
This will cause the script to run once, creating a file that indicates it has already run (in the container's virtual filesystem). You can then restart the container to perform debugging:
docker start container_name
When you restart the container, the already_ran
file will be found, causing the Entrypoint script to stall with cat
(which just waits forever for input that will never come, but keeps the container alive). You can then execute a debugging bash
session:
docker exec -i container_name bash
While the container is running, you can also remove already_ran
and manually execute the entrypoint.sh
script to rerun it, if you need to debug that way.
Solution 4 - Docker
I took @Dmitriusan's answer and made it into an alias:
> alias docker-run-prev-container='prev_container_id="$(docker ps -aq | head -n1)" && docker commit "$prev_container_id" "prev_container/$prev_container_id" && docker run -it --entrypoint=bash "prev_container/$prev_container_id"'
Add this into your ~/.bashrc
aliases file, and you'll have a nifty new docker-run-prev-container
alias which'll drop you into a shell in the previous container.
Helpful for debugging failed docker build
s.
Solution 5 - Docker
This is not exactly what you're asking for, but you can use docker export
on a stopped container if all you want is to inspect the files.
mkdir $TARGET_DIR
docker export $CONTAINER_ID | tar -x -C $TARGET_DIR
Solution 6 - Docker
My Problem:
- I started a container with
docker run <IMAGE_NAME>
- And then added some files to this container
- Then I closed the container and tried to start it again withe same command as above.
- But when I checked the new files, they were missing
- when I run
docker ps -a
I could see two containers. - That means every time I was running
docker run <IMAGE_NAME>
command, new image was getting created
Solution: To work on the same container you created in the first place run follow these steps
docker ps
to get container of your containerdocker container start <CONTAINER_ID>
to start existing container- Then you can continue from where you left. e.g.
docker exec -it <CONTAINER_ID> /bin/bash
- You can then decide to create a new image out of it
Solution 7 - Docker
I have found a simple command
docker start -a [container_name]
This will do the trick
Or
docker start [container_name]
then
docker exec -it [container_name] bash
Solution 8 - Docker
To me Docker always leaves the impression that it was created for a hobby system, it works well for that.
If something fails or doesn't work, don't expect to have a professional solution.
That said: Docker does not only NOT support such basic administrative tasks, it tries to prevent them.
Solution:
-
cd /var/lib/docker/overlay2/
-
find | grep somechangedfile # You now can see the changed file from your container in a hexcoded folder/diff
-
cd hexcoded-folder/diff
-
Create an
entrypoint.sh
(make sure to backup an existing one if it's there)cat > entrypoint.sh #!/bin/bash while ((1)); do sleep 1; done;
Ctrl+C
chmod +x entrypoint.sh
-
docker stop docker start
You now have your docker container running an endless loop instead of the originally entry, you can exec bash into it, or do whatever you need. When finished stop the container, remove/rename your custom entrypoint.
Solution 9 - Docker
It seems docker can't change entry point after a container started. But you can set a custom entry point and change the code of the entry point next time you restart it.
For example you run a container like this:
docker run --name c --entrypoint "/boot" -v "./boot":/boot $image
Here is the boot entry point:
#!/bin/bash
command_a
When you need restart c with a different command, you just change the boot script:
#!/bin/bash
command_b
And restart:
docker restart c
Solution 10 - Docker
docker-compose run --entrypoint /bin/bash cont_id_or_name
(for conven, put your env, vol mounts in the docker-compose.yml)
or use docker run and manually spec all args
Solution 11 - Docker
I had a docker container where the MariaDB container was continuously crashing on startup because of corrupted InnoDB tables.
What I did to solve my problem was:
- copy out the docker-entrypoint.sh from the container to the local file system (docker cp)
- edit it to include the needed command line parameter (--innodb-force-recovery=1 in my case)
- copy the edited file back into the docker container, overwriting the existing entrypoint script.