decking icon indicating copy to clipboard operation
decking copied to clipboard

Restart container with a different settings

Open satyrius opened this issue 10 years ago • 14 comments

Here is the sample deckgin.json I have.

{
  "containers": {
    "web": {
      "image": "satyrius/my_web_project",
      "port": ["2200:22", "8000:80"],
      "mount": ["/var/log/my_web_project/nginx:/var/log/nginx"]
    }
  },
  "clusters": {
    "my": ["web"]
  }
}

It works, and I have container running. I decided to change port mapping to

      "port": ["2201:22", "8001:80"],

run decked restart but after restart container is still has old port mapping

satyrius avatar Jul 22 '14 09:07 satyrius

Decking differentiates between creating the container (decking create) and running the container (decking start|stop|restart).

My understanding is if you update the runtime config for a container in decking, you need to re-create that container. @makeusabrew will be able to confirm this.

stephenmelrose avatar Jul 22 '14 09:07 stephenmelrose

@stephenmelrose you right. But this is not explicit. It is bad idea to recreate containers manually just to run them with different runtime arguments.

satyrius avatar Jul 22 '14 09:07 satyrius

As @stephenmelrose says, (start|stop|restart) just effectively mirror their corresponding docker commands; if you stop and restart a container without decking you just get the same container again (which makes sense).

@satyrius I don't quite understand your follow up comment; could you elaborate what you mean about different runtime arguments? That's certainly not encouraged anywhere.

This does raise an interesting opportunity though; when restarting a cluster in theory we could inspect all the containers and see if their configuration matches that in decking.json, and prompt the user accordingly (i.e. give them the option to recreate the affected containers or ignore the changes for now).

makeusabrew avatar Jul 22 '14 09:07 makeusabrew

@satyrius @makeusabrew You'd also have to recreate the container to apply new runtime arguments, e.g. volumes, ports. You can't add new ones to an already existing container (that I know of).

stephenmelrose avatar Jul 22 '14 09:07 stephenmelrose

Yep, precisely why it must be an option presented to the user so we don't unexpectedly trash a container :).

EDIT: and/or to stop annoying users with prompts, it could be a config switch in their decking.json, either at global or per-container level (given that some containers are probably just workers which are safe to trash and others might be a bit more important)

makeusabrew avatar Jul 22 '14 09:07 makeusabrew

@makeusabrew docker build builds a container with a given name from an image https://docs.docker.com/reference/commandline/cli/#build. docker run -d runs a container with given port mapping, volumes, env variables, etc. https://docs.docker.com/reference/commandline/cli/#run. decking.json containers section is a config for docker to run a container, so I expected that changing this config will affect how containers will be started by decking. In my case, I want to restart containers because of port mapping change.

satyrius avatar Jul 22 '14 09:07 satyrius

@makeusabrew we should not recreate containers, we just want to docker run with different arguments.

satyrius avatar Jul 22 '14 10:07 satyrius

@satyrius docker run creates and starts a new container every time it is called, regardless whether you change arguments or not. Try it yourself using the following,

$ docker run ubuntu:14.04 echo "Hello world"
Hello world
$ docker run ubuntu:14.04 echo "Hello world"
Hello world
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                       PORTS               NAMES
f89c3524cc9d        ubuntu:14.04        echo 'Hello world'     5 seconds ago       Exited (0) 4 seconds ago                         silly_leakey        
4a1a046e3d15        ubuntu:14.04        echo 'Hello world'     7 seconds ago       Exited (0) 6 seconds ago                         kickass_sinoussi    

As you can see, it didn't re-use the same container, it created a brand new one.

I believe what you're wanting is the ability to start an existing container with new arguments. Sadly, you can't do this. You can only start an existing container by passing the container ref/name.

Edit: From the docker run docs,

The docker run command first creates a writeable container layer over the specified image, and then starts it using the specified command. That is, docker run is equivalent to the API /containers/create then /containers/(id)/start. A stopped container can be restarted with all its previous changes intact using docker start. See docker ps -a to view a list of all containers.

stephenmelrose avatar Jul 22 '14 10:07 stephenmelrose

@satyrius @makeusabrew's proposal should solve your fundamental issue though. If we add a prompt and/or config switch to rebuild containers on decking config change (assuming you don't care about the internal data as it will be lost), it should give you what you're looking for.

stephenmelrose avatar Jul 22 '14 10:07 stephenmelrose

@stephenmelrose yeah, you right. Stoping container means its destroy. But this is not a problem, if your architecture is good, you have no persistent data like logs, user data, etc. in you web container. And if you restart such container it will be transparent for you system. The best solution here is to mark containers as persistent to prevent data loss. So restart should stop and run not persistent containers and keep persistent if they are running. This will also be suitable if you want to update your container (docker pull my/service and run new version docker run -d -P my/service)

satyrius avatar Jul 22 '14 10:07 satyrius

I'm not prepared to change the semantics of decking create, nor decking restart (et al) I'm afraid, since they align pretty much exactly with their underlying docker counterparts. This isn't really a conversation about best practices since they should be left up to users to judge and apply for themselves. It is about consistency and predictability; you have to create containers in docker (regardless of whether via the CLI that's wrapped up via the 'run' command or not), and unless you explicitly destroy a container and then re-create it you cannot change its configuration. Decking mirrors that and I believe that's correct.

There is a secondary issue here around container names and sharing a single container across clusters. I can't think through the impacts off the top of my head but it definitely affects a few design decisions.

The default should definitely not be to assume that containers are completely transient; quite apart from enforcing shared volumes for logs and persistence (and a lot more), this also doesn't allow for one-off creation steps which can be time consuming (for example, starting up a clean MongoDB instance can take ~60 seconds on an average machine). Back on the subject of logs, it would also make a mess of decking attach (and forthcoming decking logs) since there would be no way to stitch together the log history of your now destroyed previous container instances.

Put simply: making decking start use transient containers doesn't fit the mental model correctly, it doesn't align with the docker methods it wraps, and it introduces all sorts of awkward behavioural and design patterns which otherwise don't need to exist. Transient containers should be the exception, not the rule, and decking should be smartened up to a) notice a configuration change and b) do something about it (based on a prompt, or extra configuration flags in decking.json).

makeusabrew avatar Jul 22 '14 11:07 makeusabrew

+1

stephenmelrose avatar Jul 22 '14 11:07 stephenmelrose

@makeusabrew I don't push you to change a semantic of decking commands. This thread is more a question. You have no "How to use decking" article and its workflow was not obvious for me. I was in common case where I had to change a port binding for a container and restart it. Now I see that decking tries to keep the same container and run it again. Maybe you should track config file and prompt user to rebuild container.

satyrius avatar Jul 22 '14 11:07 satyrius

Maybe you should track config file and prompt user to rebuild container.

@satyrius That's exactly what @makeusabrew is proposing should be done.

Re: documentation and workflows, I would argue decking's workflow is already to docker's, so there shouldn't be too much confusion. Maybe it needs some notes around the fact decking uses named containers that can't be recreated without first being deleted? One to argue once we've added this prompt.

stephenmelrose avatar Jul 22 '14 12:07 stephenmelrose