Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Dockerfile could be a template #11

Closed
xmik opened this issue Jun 2, 2015 · 15 comments
Closed

Custom Dockerfile could be a template #11

xmik opened this issue Jun 2, 2015 · 15 comments

Comments

@xmik
Copy link

xmik commented Jun 2, 2015

I'd like to use the same custom Dockerfile for several platforms. That implies using different docker base images, while the rest of the Dockerfile stays the same.

Solution

Custom Dockerfile could be rendered as a template (ERB). The following Dockerfile:

FROM <%= @image %>

would be rendered to the image set in .kitchen.yml in driver_config section. Apart from image, other variables could be rendered too (e.g. run_command, environment). That is already implemented in kitchen-docker.

@marcy-terui
Copy link
Owner

Thank you for your idea.

I agree to use ERB template.
But, I think that we should not use all values in the configuration file to ERB template like kitchen-docker.

For example, what do you think about like this?

  • .kitchen.yml
driver:
  image: marcy/hoge
  dockerfile: dockerfile.erb
  template_variables:
    package: httpd
  • dockerfile.erb
FROM <%= config[:image] %>
RUN yum install -y <%= @package %>
  • Result
FROM marcy/hoge
RUN yum install -y httpd

@xmik
Copy link
Author

xmik commented Jun 2, 2015

It sounds too specific (e.g. RUN yum install -y sudo openssh-server openssh-clients vs RUN pacman -S --noconfirm openssh).

I always used the same one-liner dockerfile.erb (when I used kitchen-docker) in order to test the same image with Test Kitchen which I later template with Packer. Just FROM line.

But I like your idea from Readme:

  • .kitchen.yml
driver:
  image: marcy/hoge
  dockerfile: dockerfile.erb
  template_variables:
    run_commands:
      - yum -y install httpd
    environment:
      - LANG: ja_JP.UTF-8
  • dockerfile.erb
FROM <%= config[:image] %>
  • Result
FROM marcy/hoge
RUN yum -y install httpd
ENV LANG ja_JP.UTF-8

or even more generic: instead of template_variables just dockerfile_instructions:

  • .kitchen.yml
driver:
  image: marcy/hoge
  dockerfile: dockerfile.erb
  dockerfile_instructions:
    - RUN yum -y install httpd
    - ENV LANG: ja_JP.UTF-8

But maybe that is, on the other hand, too generic?

@marcy-terui
Copy link
Owner

If we are using a custom Dockerfile(ERB), I think only the command written on the file should be used.

Your example will be like this:

  • .kitchen.yml
driver:
  image: marcy/hoge
  dockerfile: dockerfile.erb
  template_variables:
    run_commands:
      - yum -y install httpd
    environment:
      - LANG: ja_JP.UTF-8
  • dockerfile.erb
FROM <%= config[:image] %>
<% @run_commands.each do |c| %>
RUN <%= c %>
<% end %>
<% @environment.each do |k,v| %>
ENV <%= k %> <%= v %>
<% end %>
  • Result
FROM marcy/hoge
RUN yum -y install httpd
ENV LANG ja_JP.UTF-8

@xmik
Copy link
Author

xmik commented Jun 3, 2015

After some thinking I actually suggest no change in .kitchen.yml configuration. The only variable rendered in dockerfile.erb would be image. After the Dockerfile is generated, there could go the same behavior as for the Dockerfile provided by docker_cli.rb: append Array(config[:environment]).each and then Array(config[:run_command]).each.

And there are 2 things here:

  • If you mean that run_command should be settable in one place only, I fully agree. But to be backwards compatible and to support people who don't want custom dockerfile, it should not be in template_variables, (rather should stay as is).
  • Also I would switch order: first ENV, then RUN commands. Because you may want to use those environment variables in RUN commands.

If you find it easier to implement the dockerfile.erb in this way (instead of 1st generating it from template and 2nd appending those lines), this will also work fine:

FROM <%= config[:image] %>
<% config[:environment].each do |k,v| %>
ENV <%= k %> <%= v %>
<% end %>
<% config[:run_command].each do |c| %>
RUN <%= c %>
<% end %>

Thank you for so fast responses :)

@marcy-terui
Copy link
Owner

Oh, I'm sorry for the confusion.

That means template variables should be distinguished from the other settings.
And I hope that we can set template variables freely.

There are no changes on other settings.

Also I would switch order: first ENV, then RUN commands. Because you may want to use those environment variables in RUN commands.

I agree with this.
To begin with, the order is wrong 😓

@xmik
Copy link
Author

xmik commented Jun 6, 2015

@marcy-terui are you working on this or prefer a pull request from me?

@joerg
Copy link

joerg commented Jun 8, 2015

+1 here. We are working with RedHat (they actually have official docker containers, but with no repo configured) and need to add our repo as the very first step.
The kitchen-docker actually have some quite nice code doing this: https://github.com/portertech/kitchen-docker/blob/master/lib/kitchen/driver/docker.rb#L192

If you need any help or testing just tell me.

@marcy-terui
Copy link
Owner

@xmik I'm not working yet. Pull requests are welcome :)
But, I am planning to implement in the near future.
Please wait if not in a hurry.

@joerg Thank you for your comment!

@xmik
Copy link
Author

xmik commented Jun 9, 2015

I'll wait.

@marcy-terui
Copy link
Owner

done.

@marcy-terui
Copy link
Owner

This is released in v0.9.0

@xmik Please check the new version :)
https://github.com/marcy-terui/kitchen-docker_cli#dockerfile_vars

@xmik
Copy link
Author

xmik commented Jun 12, 2015

@marcy-terui, I tested on Ubuntu and Debian and it works :) thanks!

@xmik xmik closed this as completed Jun 12, 2015
@xmik xmik reopened this Jun 12, 2015
@xmik
Copy link
Author

xmik commented Jun 12, 2015

Sorry, need to reopen. When I have the following dockerfile.erb:

FROM <%= config[:image] %>

And I run kitchen converge, I get:

Message: Failed to complete #create action: [undefined method `each' for nil:NilClass]

from kitchen.log:

E, [2015-06-12T12:17:02.858106 #31846] ERROR -- Kitchen: ---Nested Exception---
E, [2015-06-12T12:17:02.858128 #31846] ERROR -- Kitchen: Class: NoMethodError
E, [2015-06-12T12:17:02.858151 #31846] ERROR -- Kitchen: Message: undefined method `each' for nil:NilClass
E, [2015-06-12T12:17:02.858176 #31846] ERROR -- Kitchen: ------Backtrace-------
E, [2015-06-12T12:17:02.858197 #31846] ERROR -- Kitchen: /home/ewa/.chefdk/gem/ruby/2.1.0/gems/kitchen-docker_cli-0.9.0/lib/kitchen/docker_cli/dockerfile_template.rb:27:in `initialize'

Edit: solution is to add this line:

vars = {} if vars.nil?

as the first line of DockerfileTemplate.initialize method. (vars were explicitly set as NilClass)

@marcy-terui
Copy link
Owner

@xmik Thank you for your reporting.

I fixed it.
And it is released in v0.9.1

Please check it again.

@xmik
Copy link
Author

xmik commented Jun 12, 2015

Now it works in both cases correctly: if I set env and cmds and if I not set them. Thank you for fast fix and release :)

@xmik xmik closed this as completed Jun 12, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants