decking
decking copied to clipboard
Restart container with a different settings
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
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 you right. But this is not explicit. It is bad idea to recreate containers manually just to run them with different runtime arguments.
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).
@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).
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 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.
@makeusabrew we should not recreate containers, we just want to docker run
with different arguments.
@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 firstcreates
a writeable container layer over the specified image, and thenstarts
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 usingdocker start
. Seedocker ps -a
to view a list of all containers.
@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 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
)
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).
+1
@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.
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.