12

As part of my deployment strategy, I am managing Docker containers with Upstart.

To do that, I need to pull an image from a registry and create a named container (as suggested on Upstart script to run container won't manage lifecycle )

Is there a way to create the container without first running the image? I don't want to have to start a container (which may introduce side effects), stop it, and then manage elsewhere.

For example, something like:

docker.io create -e ENV1=a -e ENV2=b -p 80:80 --name my_first_container sample/containe
Community
  • 1
  • 1
Marshall Anschutz
  • 1,200
  • 1
  • 12
  • 23

2 Answers2

28

In case anyone else comes across this question, it can now be done with the docker create command. See https://docs.docker.com/engine/reference/commandline/create/

Adrian Mouat
  • 44,585
  • 16
  • 110
  • 102
3

You can achieve that by using Docker Remote API.

First of all adjust how docker daemon is running. Configure it to listen to HTTP requests on port 4243 in addition to the default unix socket:

sudo sh -c "echo 'DOCKER_OPTS=\"-H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock\"' > /etc/default/docker"

Now, you can use the /containers/create endpoint to create a container without running it:

curl -X POST -H "Content-Type: application/json" http://localhost:4243/containers/create?name=my_first_container -d '
{
    "Name": "dtest2",
    "AttachStdin": "false",
    "AttachStdout": "false",
    "AttachStderr": "false",
    "Tty": "false",
    "OpenStdin": "false",
    "StdinOnce": "false",
    "Cmd":["/bin/bash", "-c", "echo Starting;sleep 20;echo Stopping"],
    "Image": "ubuntu",
    "DisableNetwork": "false"
}
'

Pay attention to the ?name=my_first_container parameter I added to the curl request url. This is how you name your container.

Side note - The same can be achieved without adding the HTTP interface, however it seems easier to show the solution using a simple curl POST request.

Jeff LaFay
  • 12,882
  • 13
  • 71
  • 101
Leonid Mirsky
  • 811
  • 8
  • 9
  • 1
    I'd rather not add the http interface to be world readable (or even by localhost, for the reasons the Docker community already has discussed) is there an equivalent command with the unix socket? – Marshall Anschutz Jul 21 '14 at 23:30
  • @MarshallAnschutz there are [ways to secure](http://blog.james-carr.org/2013/10/30/securing-dockers-remote-api/) Docker's http interface. If you want to directly interact with the unix socket, you can send the HTTP request by running `echo -e “POST /containers/create?name=dtest8 HTTP/1.1 .......” | nc -U /var/run/docker.sock` – Leonid Mirsky Jul 22 '14 at 12:59
  • I'm leaning towards the python interface to make this work properly. That appears to be the most sane way of managing this – Marshall Anschutz Jul 22 '14 at 22:30
  • Talking to the API directly over the Unix socket seems safer than enabling a globally-accessible TCP socket (It should t least be limited to listening on localhost...), curl supports it. See https://nathanleclaire.com/blog/2015/11/12/using-curl-and-the-unix-socket-to-talk-to-the-docker-api/ – Gert van den Berg Aug 21 '19 at 06:20