michaelsauter / crane

Crane - Lift containers with ease
MIT License
921 stars 61 forks source link

Syntax simplifications to reduce the config file code #162

Closed adrianhurt closed 9 years ago

adrianhurt commented 9 years ago

I have a config file with several containers and I see some repeated extra code. I have seen a lot of crane.yml files that people are actually using in github projects, and I've seen it's not only my case.

The first and easier thing is that there are lots of cases with link declarations where the container's name and its alias are the same. And I think in that cases the alias could be omitted. For example "db:db" could be simply "db". In fact, it's the same case than the ports where you can use the "80:80" or "80" declaration without distinction. (Oops, I've just learnt there is a difference between them…)

The second one, well I think it would be difficult to avoid. I've seen almost every container has the declaration detach: true. Maybe more than the 80% of the containers have this. So I was wondering if it would be better to set it to true as default. But I think it would be difficult for retrocompatibility reasons.

Finally, if I want to declare N instances for the same service (i.e. N containers with the same specification) I have to copy and paste N times (AFAIK). It's very common when you need to deploy a load balancer. I think it could be interesting to declare it only once and indicate the number in it. Some possibilities:

  web[1-3]:
    image: my-web-app
    run:
      …

or

  web:
    containers / instances: 3
    image: my-web-app
    run:
      ...

And then they would be automatically named as web1, web2 and web3, for example.

Bonus: it's not for reducing the code, but shouldn't be volumes and links instead of volume and link? In deed, they are arrays. Accepting both (singular and plural) could avoid some misunderstanding initial errors for people like me that come from Fig and Docker-Compose. The first time I executed crane it took me more than 10 minutes to figure out why the volumes weren't been mounted correctly. And it was simply because I wrote volumes and the crane compiler didn't show any warning.

bjaglin commented 9 years ago

I am ignoring your first request, since it's indeed not a "shortcut".

About the detach: true, it doesn't really answer your requests (that would effectively be a breaking change) but http://yaml.org/type/merge.html can help you define an alias for daemon containers that you can reference across the containers. I posted an example, unfortunately this is using a special behavior of the go-yaml plugin which might break in the future since it's not according to spec, see https://github.com/go-yaml/yaml/issues/81.

As for the plural/singular, even though I see your point, the idea is to map 1-1 Docker CLI options, so I am not sure introducing support for both would really help - I think https://github.com/michaelsauter/crane/issues/116 is a better way out.

adrianhurt commented 9 years ago

Well, I see to write "elasticsearch" instead of "elasticsearch:elasticsearch" as a shortcut an also more readable, but it's not so important…

I've tried to figure out how to avoid the detach: true using merge feature of YAML but I think it only can be done creating a alias and import it in every container, so writing <<: *detach instead of simply detach: true doesn't help… Ok, it's neither so important…

But I think you have ignored the most important. To have the ability to declare more than one container for one declaration avoiding to repeat your self. And for that, the merging feature of YAML is on the recue! For example, in my case I have a dockerfile defining a container that simply runs a java application with a given parameter passed through CMD (i.e. the name of the java app to run). Then, with the same image, I need to run 2 java apps: web and admin. But I also need 2 instances of each one with a load balancer in order to update them with zero-downtime. So before that, I needed to almost copy and paste the same declaration in crane.yml for web1, web2, admin1 and admin2. Now, using that feature I can declare them as:

containers:
  web1: &web
    image: web-app
    run: &web-run
      link: ["mysql:mysql"]
      env: ...
      cmd: web
      detach: true
  web2: *web

  admin1: &admin { <<: *web, run: { <<: *web-run , cmd: admin}}
  admin2: *admin

And about the plural/singular, I also think the best option would be to warn the user when he uses unknown params.

Thanks again!

PD: I'll try in a few dates to make a PR to add to the README some examples using these features of YAML.

adrianhurt commented 9 years ago

I created a PR with an example of advance use of YAML (https://github.com/michaelsauter/crane/pull/165)