Related
Edit:
Someone mark duplicate of this question, but it does not explain the underlying mechanism at all.
But on contrast, this stack overflow solve my confusion in Case I, but not Case II.
I am newbie in docker and i am confused about the usage of --interactive, --attach flag and those concepts involved
I will show my confusion using busybox in docker hub.
Case I :
When I run a container using the below commands. docker run --interactive --tty busybox sh
A container is running and accepting input
According to the document, --interactive flag used to
Keep STDIN open even if not attached
I don't understand what is the meaning of even if not attached to, attached to what?
Case II :
Then I exit the container and try to start it using
docker start --attach abdd796820b1 .
The terminal seems accepting input as well, but when I type ls or echo, it does not give response.
What did the --attach flag do?
Please help.
There are two ways in which you can interact with a running container
attach
exec
--interactive flag
As you mentioned it already says
Keep STDIN open even if not attached
Which from my understanding means it will read inputs from your terminal/console and reacts or present output to it. If you run docker run --tty alpine /bin/sh and docker run --tty --interactive alpine /bin/sh. One with --interactive will react to it.
attach
Attach to a running process
If the docker container was started using /bin/bash command, you can access it using attach, if not then you need to execute the command to create a bash instance inside the container using exec.
More in depth: If docker container is started using /bin/bash then it becomes containers PID 1 and attach command will attach you to PID 1.
exec
Creates new process
If you want to create a new process inside container than exec it used like exec is used to execute apt-get command inside container without attaching to it or run a node or python script.
Eg: docker exec -it django-prod python migrate
See here -i is for interactive and -t is for --tty that is pseudo-TTY. Interactive so that you can enter if something is prompted by this command.
You will need to provide the -i/--interactive option to forward your terminal STDIN to the container's sh.
Try this:
docker start -ai CONTAINER
https://docs.docker.com/engine/reference/commandline/start/
I know, I know, I should have typed
docker run -it ubuntu bash
But the fact remains, a container has been created, it is there, and it is stopped. It stops as soon as it is started, so there's no way to attach or exec in it.
Is it really the case that there's is absolutely no way to change it's state so that bash is started instead ? This seems to be kind of a showstopper to me. Or maybe there's something I didn't get about the marvelous possibilities of docker that would make such a thing complicated to do ? I doubt that.
Why is it that way ?
Keep in mind two things:
1st: a container is up and running as long as its main process is up and running.
2nd: ubuntu has a default command: CMD ["/bin/bash"]. When you use docker run ubuntu bash, you overwrite it to CMD ["bash"]. No big difference.
Why docker run ubuntu fails:
Because bash simply exits. Remember, bash is the default command.
Why docker run -it ubuntu succeeds:
Because -t makes bash keep running. From docker run --help:
-t, --tty Allocate a pseudo-TTY
Also, you mention:
But the fact remains, a container has been created, it is there, and it is stopped. It stops as soon as it is started, so there's no way to attach or exec in it.
Containers can be better considered as processes and this is why you should see them as something ephemeral. If it happens to run a container with the wrong configuration (exiting right after start), remove it and spin up a new one, this time with the correct parameters.
when you run image like ubuntu you have to give it a command or process to keep it started. In my case when I use ubuntu image for tests (principally), I write docker run --name myubuntu -d ubuntu:16.04 sleep 3000
you can verify if it runing with a docker ps.
After this you can go inside with docker exec -it myubuntu /bin/bash
According to tutorial I read so far, use "docker run -d" will start a container from image, and the container will run in background. This is how it looks like, we can see we already have container id.
root#docker:/home/root# docker run -d centos
605e3928cdddb844526bab691af51d0c9262e0a1fc3d41de3f59be1a58e1bd1d
But if I ran "docker ps", nothing was returned.
So I tried "docker ps -a", I can see container already exited:
root#docker:/home/root# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
605e3928cddd centos:latest "/bin/bash" 31 minutes ago Exited (0) 31 minutes ago kickass_swartz
Anything I did wrong? How can I troubleshoot this issue?
The centos dockerfile has a default command bash.
That means, when run in background (-d), the shell exits immediately.
Update 2017
More recent versions of docker authorize to run a container both in detached mode and in foreground mode (-t, -i or -it)
In that case, you don't need any additional command and this is enough:
docker run -t -d centos
The bash will wait in the background.
That was initially reported in kalyani-chaudhari's answer and detailed in jersey bean's answer.
vonc#voncvb:~$ d ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4a50fd9e9189 centos "/bin/bash" 8 seconds ago Up 2 seconds wonderful_wright
Note that for alpine, Marinos An reports in the comments:
docker run -t -d alpine/git does not keep the process up.
Had to do: docker run --entrypoint "/bin/sh" -it alpine/git
Original answer (2015)
As mentioned in this article:
Instead of running with docker run -i -t image your-command, using -d is recommended because you can run your container with just one command and you don’t need to detach terminal of container by hitting Ctrl + P + Q.
However, there is a problem with -d option. Your container immediately stops unless the commands keep running in foreground.
Docker requires your command to keep running in the foreground. Otherwise, it thinks that your applications stops and shutdown the container.
The problem is that some application does not run in the foreground. How can we make it easier?
In this situation, you can add tail -f /dev/null to your command.
By doing this, even if your main command runs in the background, your container doesn’t stop because tail is keep running in the foreground.
So this would work:
docker run -d centos tail -f /dev/null
Or in Dockerfile:
ENTRYPOINT ["tail"]
CMD ["-f","/dev/null"]
A docker ps would show the centos container still running.
From there, you can attach to it or detach from it (or docker exec some commands).
According to this answer, adding the -t flag will prevent the container from exiting when running in the background. You can then use docker exec -i -t <image> /bin/bash to get into a shell prompt.
docker run -t -d <image> <command>
It seems that the -t option isn't documented very well, though the help says that it "allocates a pseudo-TTY."
Background
A Docker container runs a process (the "command" or "entrypoint") that keeps it alive. The container will continue to run as long as the command continues to run.
In your case, the command (/bin/bash, by default, on centos:latest) is exiting immediately (as bash does when it's not connected to a terminal and has nothing to run).
Normally, when you run a container in daemon mode (with -d), the container is running some sort of daemon process (like httpd). In this case, as long as the httpd daemon is running, the container will remain alive.
What you appear to be trying to do is to keep the container alive without a daemon process running inside the container. This is somewhat strange (because the container isn't doing anything useful until you interact with it, perhaps with docker exec), but there are certain cases where it might make sense to do something like this.
(Did you mean to get to a bash prompt inside the container? That's easy! docker run -it centos:latest)
Solution
A simple way to keep a container alive in daemon mode indefinitely is to run sleep infinity as the container's command. This does not rely doing strange things like allocating a TTY in daemon mode. Although it does rely on doing strange things like using sleep as your primary command.
$ docker run -d centos:latest sleep infinity
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d651c7a9e0ad centos:latest "sleep infinity" 2 seconds ago Up 2 seconds nervous_visvesvaraya
Alternative Solution
As indicated by cjsimon, the -t option allocates a "pseudo-tty". This tricks bash into continuing to run indefinitely because it thinks it is connected to an interactive TTY (even though you have no way to interact with that particular TTY if you don't pass -i). Anyway, this should do the trick too:
$ docker run -t -d centos:latest
Not 100% sure whether -t will produce other weird interactions; maybe leave a comment below if it does.
Hi this issue is because docker containers exit if there is no running application in the container.
-d
option is just to run a container in deamon mode.
So the trick to make your container continuously running is point to a shell file in docker which will keep your application running.You can try with a start.sh file
Eg: docker run -d centos sh /yourlocation/start.sh
This start.sh should point to a never ending application.
In case if you dont want any application to be running,you can install monit which will keep your docker container running.
Please let us know if these two cases worked for you to keep your container running.
All the best
You can accomplish what you want with either:
docker run -t -d <image-name>
or
docker run -i -d <image-name>
or
docker run -it -d <image-name>
The command parameter as suggested by other answers (i.e. tail -f /dev/null) is completely optional, and is NOT required to get your container to stay running in the background.
Also note the Docker documentation suggests that combining -i and -t options will cause it to behave like a shell.
See:
https://docs.docker.com/engine/reference/run/#foreground
I have this code snippet run from the ENTRYPOINT in my docker file:
while true
do
echo "Press [CTRL+C] to stop.."
sleep 1
done
Run the built docker image as:
docker run -td <image name>
Log in to the container shell:
docker exec -it <container id> /bin/bash
execute command as follows :
docker run -t -d <image-name>
if you want to specify port then command as below:
docker run -t -d -p <port-no> <image-name>
verify the running container using following command:
docker ps
Docker container exits if task inside is done, so if you want to keep it alive even if it does not have any job or already finished them, you can do docker run -di image. After you do docker container ls you will see it running.
Docker requires your command to keep running in the foreground. Otherwise, it thinks that your applications stops and shutdown the container.
So if your docker entry script is a background process like following:
/usr/local/bin/confd -interval=30 -backend etcd -node $CONFIG_CENTER &
The '&' makes the container stop and exit if there are no other foreground process triggered later.
So the solution is just remove the '&' or have another foreground CMD running after it, such as
tail -f server.log
If you are using CMD at the end of your Dockerfile, what you can do is adding the code at the end. This will only work if your docker is built on ubuntu, or any OS that can use bash.
&& /bin/bash
Briefly the end of your Dockerfile will look like something like this.
...
CMD ls && ... && /bin/bash
So if you have anything running automatically after you run your docker image, and when the task is complete the bash terminal will be active inside your docker. Thereby, you can enter you shell commands.
Maybe it is just me but on CentOS 7.3.1611 and Docker 1.12.6 but I ended up having to use a combination of the answers posted by #VonC & #Christopher Simon to get this working reliably. Nothing I did before this would stop the container from exiting after it ran CMD successfully. I am starting oracle-xe-11Gr2 and sshd.
Dockerfile
...
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' && systemctl enable sshd
...
CMD /etc/init.d/oracle-xe start && /sbin/sshd && tail -f /dev/null
Then adding -d -t and -i to run
docker run --shm-size=2g --name oracle-db -d -t -i -p 5022:22 -p 5080:8080 -p 1521:1521 centos-oracle:7.3.1611
Finally after hours of bashing my head against the wall
ssh -v root#127.0.0.1 -p 5022
...
root#127.0.0.1's password:
debug1: Authentication succeeded (password).
For whatever reason the above will exit after executing CMD if the tail -f is removed, or any of the -t -d -i options are omitted.
I had the same issue, just opening another terminal with a bash on it worked for me :
create container:
docker run -d mcr.microsoft.com/mssql/server:2019-CTP3.0-ubuntu
containerid=52bbc9b30557
start container:
docker start 52bbc9b30557
start bash to keep container running:
docker exec -it 52bbc9b30557 bash
start process you need:
docker exec -it 52bbc9b30557 /path_to_cool_your_app
Running docker with interactive mode might solve the issue.
Here is the example for running image with and without interactive mode
chaitra#RSK-IND-BLR-L06:~/dockers$ sudo docker run -d -t -i test_again1.0
b6b9a942a79b1243bada59db19c7999cfff52d0a8744542fa843c95354966a18
chaitra#RSK-IND-BLR-L06:~/dockers$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
chaitra#RSK-IND-BLR-L06:~/dockers$ sudo docker run -d -t -i test_again1.0 bash
c3d6a9529fd70c5b2dc2d7e90fe662d19c6dad8549e9c812fb2b7ce2105d7ff5
chaitra#RSK-IND-BLR-L06:~/dockers$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3d6a9529fd7 test_again1.0 "bash" 2 seconds ago Up 1 second awesome_haibt
You can simply use:
docker container run -d -it <container name or id> /bin/bash
I have explained it in the following post that has the same question.
How to retain docker alpine container after "exit" is used?
I was also facing the same problem but in a different manner. When I create the docker containers. it automatically stops the unused containers which are just running in the background. Sometimes it also stops the containers that are in the use.
In my situation, this is because of the permission of the docker.sock files it earlier has.
what you have to do is :-
Install docker again.(As i work on ubuntu i install it from here)
Run the command to change the permissions.
sudo chmod 666 /var/run/docker.sock
Install docker-compose (this is optional as I have compose file to create many containers together)
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
check for the version to ensure that I have the latest one and not get problem with some deprications.
Then I run the docker container build.
Argument order matters
Jersey Beans answer (all 3 examples) worked for me. After quite a bit of trial and error I realized that the order of the arguments matter.
Keeps the container running in the background:
docker run -t -d <image-name>
Keeps the container running in the foreground: docker run <image-name> -t -d
It wasn't obvious to me coming from a Powershell background.
if you want to operate on the container, you need to run it in foreground to keep it alive.
There are multiple options out there to run the container in foreground/detached state. But if you still feel the issue is not resolved, you can try troubleshooting the issue by viewing the logs.
sudo docker logs -f >> container.log
additionally you can also use --details to show extra details provided to logs.
Incorrect Path to App in Dockerfile:
I was migrating an application from a RHEL server to a Docker container using Alpine Linux.
No errors during the build, so I was surprised to see the container immediately exit!
First port of call:
docker logs <containerID>
This revealed the path of the binary I had supplied to CMD in the Dockerfile was bogus:
line 0: /sbin/postfix: not found
Well that told me how things were broken, but not specifically where: I still required the correct path for the binary in Alpine Linux...
Troubleshooting:
Googling didn't reveal the correct path to it, so I added the following line to my Dockerfile:
RUN which postfix
I then reviewed my build logging- provided by the below command appended to my build command- to retrieve the value of RUN which postfix
--progress=plain > /path/to/build.log 2>&1
The Fix:
I deleted this test build, supplied the correct path- /usr/sbin/postfix - to CMD in the Dockerfile, deleted RUN which postfix and ran another build.
Voila; the process now remained up.
So a duff path was causing the container to immediately exit...
These 4 commands all work to keep your docker container running:
docker run -td centos
docker run -dt centos
docker run -t -d centos
docker run -d -t centos
Firstly, You need to check if any container is running
Type command,
docker ps -all
If any container is running then stop them
Type command,
docker stop Container Id
Now, Finally run the docker by using below command..........
docker run -t -p 2020:3000 dockerImageName
Hence, Open your google chrome and visit on localhost:2020
Congrats :)
I run a container in the background using
docker run -d --name hadoop h_Service
it exits quickly. But if I run in the foreground, it works fine. I checked logs using
docker logs hadoop
there was no error. Any ideas?
DOCKERFILE
FROM java_ubuntu_new
RUN wget http://archive.cloudera.com/cdh4/one-click-install/precise/amd64/cdh4-repository_1.0_all.deb
RUN dpkg -i cdh4-repository_1.0_all.deb
RUN curl -s http://archive.cloudera.com/cdh4/ubuntu/precise/amd64/cdh/archive.key | apt-key add -
RUN apt-get update
RUN apt-get install -y hadoop-0.20-conf-pseudo
RUN dpkg -L hadoop-0.20-conf-pseudo
USER hdfs
RUN hdfs namenode -format
USER root
RUN apt-get install -y sudo
ADD . /usr/local/
RUN chmod 777 /usr/local/start-all.sh
CMD ["/usr/local/start-all.sh"]
start-all.sh
#!/usr/bin/env bash
/etc/init.d/hadoop-hdfs-namenode start
/etc/init.d/hadoop-hdfs-datanode start
/etc/init.d/hadoop-hdfs-secondarynamenode start
/etc/init.d/hadoop-0.20-mapreduce-tasktracker start
sudo -u hdfs hadoop fs -chmod 777 /
/etc/init.d/hadoop-0.20-mapreduce-jobtracker start
/bin/bash
This did the trick for me:
docker run -dit ubuntu
After it, I checked for the processes running using:
docker ps -a
For attaching again the container
docker attach CONTAINER_NAME
TIP: For exiting without stopping the container type: ^P^Q
A docker container exits when its main process finishes.
In this case it will exit when your start-all.sh script ends. I don't know enough about hadoop to tell you how to do it in this case, but you need to either leave something running in the foreground or use a process manager such as runit or supervisord to run the processes.
I think you must be mistaken about it working if you don't specify -d; it should have exactly the same effect. I suspect you launched it with a slightly different command or using -it which will change things.
A simple solution may be to add something like:
while true; do sleep 1000; done
to the end of the script. I don't like this however, as the script should really be monitoring the processes it kicked off.
(I should say I stole that code from https://github.com/sequenceiq/hadoop-docker/blob/master/bootstrap.sh)
I would like to extend or dare I say, improve answer mentioned by camposer
When you run
docker run -dit ubuntu
you are basically running the container in background in interactive mode.
When you attach and exit the container by CTRL+D (most common way to do it), you stop the container because you just killed the main process which you started your container with the above command.
Making advantage of an already running container, I would just fork another process of bash and get a pseudo TTY by running:
docker exec -it <container ID> /bin/bash
Why docker container exits immediately?
If you want to force the image to hang around (in order to debug something or examine state of the file system) you can override the entry point to change it to a shell:
docker run -it --entrypoint=/bin/bash myimagename
whenever I want a container to stay up after finish the script execution I add
&& tail -f /dev/null
at the end of command. So it should be:
/usr/local/start-all.sh && tail -f /dev/null
If you need to just have a container running without exiting, just run
docker run -dit --name MY_CONTAINER MY_IMAGE:latest
and then
docker exec -it MY_CONTAINER /bin/bash
and you will be in the bash shell of the container, and it should not exit.
Or if the exit happens during docker-compose, use
command: bash -c "MY_COMMAND --wait"
as already stated by two other answers here (though not that clearly referring to docker-compose, that is why I still mention the "wait" trick again).
I tried this --wait later again, did not work. It must have been an argument for some self-written python or shell code. If I ever find the time, I will look it up. It should be a good default since it was written by professionals. Perhaps it also just shadowed the workaround of another answer in this Q/A.
Add this to the end of Dockerfile:
CMD tail -f /dev/null
Sample Docker file:
FROM ubuntu:16.04
# other commands
CMD tail -f /dev/null
Reference
A nice approach would be to start up your processes and services running them in the background and use the wait [n ...] command at the end of your script. In bash, the wait command forces the current process to:
Wait for each specified process and return its termination status. If n is not given, all currently active child processes are waited for, and the return status is zero.
I got this idea from Sébastien Pujadas' start script for his elk build.
Taking from the original question, your start-all.sh would look something like this...
#!/usr/bin/env bash
/etc/init.d/hadoop-hdfs-namenode start &
/etc/init.d/hadoop-hdfs-datanode start &
/etc/init.d/hadoop-hdfs-secondarynamenode start &
/etc/init.d/hadoop-0.20-mapreduce-tasktracker start &
sudo -u hdfs hadoop fs -chmod 777 /
/etc/init.d/hadoop-0.20-mapreduce-jobtracker start &
wait
You need to run it with -d flag to leave it running as daemon in the background.
docker run -d -it ubuntu bash
My pracitce is in the Dockerfile start a shell which will not exit immediately CMD [ "sh", "-c", "service ssh start; bash"], then run docker run -dit image_name. This way the (ssh) service and container is up running.
I added read shell statement at the end. This keeps the main process of the container - startup shell script - running.
Adding
exec "$#"
at the end of my shell script was my fix!
Coming from duplicates, I don't see any answer here which addresses the very common antipattern of running your main workload as a background job, and then wondering why Docker exits.
In simple terms, if you have
my-main-thing &
then either take out the & to run the job in the foreground, or add
wait
at the end of the script to make it wait for all background jobs.
It will then still exit if the main workload exits, so maybe run this in a while true loop to force it to restart forever:
while true; do
my-main-thing &
other things which need to happen while the main workload runs in the background
maybe if you have such things
wait
done
(Notice also how to write while true. It's common to see silly things like while [ true ] or while [ 1 ] which coincidentally happen to work, but don't mean what the author probably imagined they ought to mean.)
There are many possible ways to cause a docker to exit immediately. For me, it was the problem with my Dockerfile. There was a bug in that file. I had ENTRYPOINT ["dotnet", "M4Movie_Api.dll] instead of ENTRYPOINT ["dotnet", "M4Movie_Api.dll"]. As you can see I had missed one quotation(") at the end.
To analyze the problem I started my container and quickly attached my container so that I could see what was the exact problem.
C:\SVenu\M4Movie\Api\Api>docker start 4ea373efa21b
C:\SVenu\M4Movie\Api\Api>docker attach 4ea373efa21b
Where 4ea373efa21b is my container id. This drives me to the actual issue.
After finding the issue, I had to build, restore, publish my container again.
If you check Dockerfile from containers, for example
fballiano/magento2-apache-php
you'll see that at the end of his file he adds the following command:
while true; do sleep 1; done
Now, what I recommend, is that you do this
docker container ls --all | grep 127
Then, you will see if your docker image had an error, if it exits with 0, then it probably needs one of these commands that will sleep forever.
#camposer
The solution is the solution that works for me.
I am running docker on my macbook.
The container was not firing. thanks to your friend's method, I was able to start it correctly.
`docker run -dit ubuntu`
Since the image is a linux, one thing to check is to make sure any shell scripts used in the container have unix line endings. If they have a ^M at the end then they are windows line endings. One way to fix them is with dos2unix on /usr/local/start-all.sh to convert them from windows to unix. Running the docker in interactive mode can help figure out other problems. You could have a file name typo or something. see https://en.wikipedia.org/wiki/Newline
I was naively expecting this command to run a bash shell in a running container :
docker run "id of running container" /bin/bash
it looks like it's not possible, I get the error :
2013/07/27 20:00:24 Internal server error: 404 trying to fetch remote history for 27d757283842
So, if I want to run bash shell in a running container (ex. for diagnosis purposes)
do I have to run an SSH server in it and loggin via ssh ?
With docker 1.3, there is a new command docker exec. This allows you to enter a running docker:
docker exec -it "id of running container" bash
EDIT: Now you can use docker exec -it "id of running container" bash (doc)
Previously, the answer to this question was:
If you really must and you are in a debug environment, you can do this: sudo lxc-attach -n <ID>
Note that the id needs to be the full one (docker ps -notrunc).
However, I strongly recommend against this.
notice: -notrunc is deprecated, it will be replaced by --no-trunc soon.
Just do
docker attach container_name
As mentioned in the comments, to detach from the container without stopping it, type Ctrlpthen Ctrlq.
Since things are achanging, at the moment the recommended way of accessing a running container is using nsenter.
You can find more information on this github repository. But in general you can use nsenter like this:
PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid
or you can use the wrapper docker-enter:
docker-enter <container_name_or_ID>
A nice explanation on the topic can be found on Jérôme Petazzoni's blog entry:
Why you don't need to run sshd in your docker containers
First thing you cannot run
docker run "existing container" command
Because this command is expecting an image and not a container and it would anyway result in a new container being spawned (so not the one you wanted to look at)
I agree with the fact that with docker we should push ourselves to think in a different way (so you should find ways so that you don't need to log onto the container), but I still find it useful and this is how I work around it.
I run my commands through supervisor in DEAMON mode.
Then I execute what I call docker_loop.sh
The content is pretty much this:
#!/bin/bash
/usr/bin/supervisord
/usr/bin/supervisorctl
while ( true )
do
echo "Detach with Ctrl-p Ctrl-q. Dropping to shell"
sleep 1
/bin/bash
done
What it does is that it allows you to "attach" to the container and be presented with the supervisorctl interface to stop/start/restart and check logs.
If that should not suffice, you can Ctrl+D and you will drop into a shell that will allow you to have a peek around as if it was a normal system.
PLEASE DO ALSO TAKE INTO ACCOUNT that this system is not as secure as having the container without a shell, so take all the necessary steps to secure your container.
Keep an eye on this pull request: https://github.com/docker/docker/pull/7409
Which implements the forthcoming docker exec <container_id> <command> utility. When this is available it should be possible to e.g. start and stop the ssh service inside a running container.
There is also nsinit to do this: "nsinit provides a handy way to access a shell inside a running container's namespace", but it looks difficult to get running.
https://gist.github.com/ubergarm/ed42ebbea293350c30a6
You can use
docker exec -it <container_name> bash
Here's my solution
In the Dockerfile:
# ...
RUN mkdir -p /opt
ADD initd.sh /opt/
RUN chmod +x /opt/initd.sh
ENTRYPOINT ["/opt/initd.sh"]
In the initd.sh file
#!/bin/bash
...
/etc/init.d/gearman-job-server start
/etc/init.d/supervisor start
#very important!!!
/bin/bash
After image is built you have two options using exec or attach:
Use exec (preferred) and run:
docker run --name $CONTAINER_NAME -dt $IMAGE_NAME
then
docker exec -it $CONTAINER_NAME /bin/bash
and use CTRL + D to detach
Use attach and run:
docker run --name $CONTAINER_NAME -dit $IMAGE_NAME
then
docker attach $CONTAINER_NAME
and use CTRL + P and CTRL + Q to detach
Note: The difference between options is in parameter -i
There is actually a way to have a shell in the container.
Assume your /root/run.sh launches the process, process manager (supervisor), or whatever.
Create /root/runme.sh with some gnu-screen tricks:
# Spawn a screen with two tabs
screen -AdmS 'main' /root/run.sh
screen -S 'main' -X screen bash -l
screen -r 'main'
Now, you have your daemons in tab 0, and an interactive shell in tab 1. docker attach at any time to see what's happening inside the container.
Another advice is to create a "development bundle" image on top of the production image with all the necessary tools, including this screen trick.
There are two ways.
With attach
$ sudo docker attach 665b4a1e17b6 #by ID
With exec
$ sudo docker exec - -t 665b4a1e17b6 #by ID
If the goal is to check on the application's logs, this post shows starting up tomcat and tailing the log as part of CMD. The tomcat log is available on the host using 'docker logs containerid'.
http://blog.trifork.com/2013/08/15/using-docker-to-efficiently-create-multiple-tomcat-instances/
It's useful assign name when running container. You don't need refer container_id.
docker run --name container_name yourimage
docker exec -it container_name bash
first, get the container id of the desired container by
docker ps
you will get something like this:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3ac548b6b315 frontend_react-web "npm run start" 48 seconds ago Up 47 seconds 0.0.0.0:3000->3000/tcp frontend_react-web_1
now copy this container id and run the following command:
docker exec -it container_id sh
docker exec -it 3ac548b6b315 sh
Maybe you were mislead like myself into thinking in terms of VMs when developing containers. My advice: Try not to.
Containers are just like any other process. Indeed you might want to "attach" to them for debugging purposes (think of /proc//env or strace -p ) but that's a very special case.
Normally you just "run" the process, so if you want to modify the configuration or read the logs, just create a new container and make sure you write the logs outside of it by sharing directories, writing to stdout (so docker logs works) or something like that.
For debugging purposes you might want to start a shell, then your code, then press CTRL-p + CTRL-q to leave the shell intact. This way you can reattach using:
docker attach <container_id>
If you want to debug the container because it's doing something you haven't expect it to do, try to debug it: https://serverfault.com/questions/596994/how-can-i-debug-a-docker-container-initialization
No. This is not possible. Use something like supervisord to get an ssh server if that's needed. Although, I definitely question the need.