25

I would like to run a docker container that hosts a simple web application, however I do not understand how to design/run the image as a server. For example:

docker run -d -p 80:80 ubuntu:14.04 /bin/bash

This will start and immediately shutdown the container. Instead we can start it interactively:

docker run -i -p 80:80 ubuntu:14.04 /bin/bash

This works, but now I have to keep open the interactive shell for every container that is running? I would rather just start it and have it running in the background. A hack would be using a command that never returns:

docker run -d -p 80:80 {image} tail -F /var/log/kern.log

But now I cannot connect to the shell anymore, to inspect what is going on if the application is acting up.

Is there a way to start the container in the background (as we would do for a vm), in a way that allows for attaching/detaching a shell from the host? Or am I completely missing the point?

Jeroen Ooms
  • 31,998
  • 35
  • 134
  • 207
  • You could mount a folder from your host machine to /var/log in order to have easy access to the container's logs: docker run -d -p 80:80 -v /tmp/log:/var/log {image} /foregroundapp – jchysk Jul 13 '14 at 04:47

3 Answers3

24

The final argument to docker run is the command to run within the container. When you run docker run -d -p 80:80 ubuntu:14.04 /bin/bash, you're running bash in the container and nothing more. You actually want to run your web application in a container and to keep that container alive, so you should do docker run -d -p 80:80 ubuntu:14.04 /path/to/yourapp.

But your application probably depends on some configuration in order to run. If it reads its configuration from environment variables, you can use the -e key=value arguments with docker run. If your application needs a configuration file to be in place, you should probably use a Dockerfile to set up the configuration first.

This article provides a nice complete example of running a node application in a container.

Harsh
  • 198
  • 1
  • 2
  • 12
Ben Whaley
  • 32,811
  • 7
  • 87
  • 85
  • I think the problem is that my application is already deamonised (it uses the standard apache2 from ubuntu in the container). – Jeroen Ooms Jul 11 '14 at 22:37
  • Ahh, so you just need to run apache in the foreground as your command. – Ben Whaley Jul 11 '14 at 23:24
  • Well, I have all my environment variables setup and sure my application would run the way you described. However, what the point of dockerfile if I need to manually start my application when running docker container. I want to put all steps inside the docker file and only what user of my image has to do is to launch it. – Stan Sokolov Nov 10 '16 at 17:40
8

Users of docker tend to assume a container to be a complete a VM, while the docker design concept is more focused on optimal containerization rather than mimic the VM within a container.

Both are correct, however some implementation details are not easy to get familiar with in the beginning. I am trying to summarize some implementation difference in a way that is easier to understand.

  1. SSH

    SSH would be the most straight-forward way to go inside a Linux VM (or container), however many dockerized templates do not have ssh server installed. I believe this is because of optimization & security reasons for the container.

  2. docker attach

    docker attach can be handy if working as out-of-the-box. However, as of writing it is not stable (edit: the issue is now closed). Might be associated with SSH set up, but not sure when it is completely fixed.

  3. docker recommended practices (nsenter and etc)

    Some alternatives (or best practices in some sense) recommended by Docker at https://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/

    This practice basically separates out mutable elements out of a container and maps them to some places in a docker host, so they can be manipulated from outside of container and/or persisted. Could be a good practice in production environment, but not now when more docker related projects are around dev and staging environment.

  4. bash command line

    "docker exec -it {container id} bash" cloud be very handy and practical tool to get into the machine.

  5. Some basics

    • "docker run" creates a new container so previous changes will not be saved.
    • "docker start" will start an existing container so previous changes will still be in the container, however you need to find the correct container-id among many with a same image-id. Need to "docker commit" to suppress versions if wanted.
    • Ctrl-C will stop the container when exiting. You will want to append "&" at the end so the container can run background and gives you the prompt when hitting enter key.
Pablo Bianchi
  • 1,824
  • 1
  • 26
  • 30
Michael Kim
  • 3
  • 1
  • 4
4

To the original question, you can tail some file, like you mentioned, to keep the process running.

To reach the shell, instead of "attach", you have two options:

  1. docker exec -it <container_id> /bin/bash

Or

  1. run ssh daemon in the container, port map the ssh and then ssh to container.
Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Guruprasad GV
  • 916
  • 13
  • 18
  • this is not what I want to do. Sure I can login to container and run my server ... however it is not my objective. Container has to start with my server running without any additional steps. I do not want to login to container every time it is launched and launch my server. This should be automated. – Stan Sokolov Nov 10 '16 at 17:44
  • @StanSokolov looks like you miss-understood. The server is started with the container as daemon. Later if you want to login to the shell, you have the above two options. – Guruprasad GV Nov 13 '16 at 05:13