Ansible + Docker instead of multiple Dockerfiles. Should I use multiple Packer template files?

54 views
Skip to first unread message

Loric Brevet

unread,
Mar 7, 2018, 5:16:49 AM3/7/18
to Packer
Hello,

I am planning to move one of my projects from plain Dockerfiles to Packer builds.

I currently have two images built with Dockerfiles composing one docker-compose.yml project as followed.

version: '3'
services
:
  web
:
    build
: Dockerfile.web
    ports
:
     
- "5000:5000"
  db
:
    build
: Dockerfile.db

My question was: should I use one package.json per Dockerfile or should I build both images from the same package.json?

I have seen we can use several builders and post-processors with Packer but of what I understand, this feature mostly targets the use case of building the same image for various platforms (e.g. Docker + Vagrant) at the same time.

For my case here, I would like to build two different images not related to each others and using different provisioning roles in a same playbook.

Usually, a unique Ansible playbook script is used to provision several images according to its inventory (here I would have the web container and db container in the inventory), but I am not sure I can do this with Packer.

Thanks in advance,

Loric

Alvaro Miranda Aguilera

unread,
Mar 7, 2018, 6:05:21 AM3/7/18
to packe...@googlegroups.com
Hello

Yes, can be done








for many many dockers, I would suggest have one json per docker and have something like a make file

but for 2 its still doable

say you have 2 dockers, and you want 3 provision to run, one shared and one local

the feature you need is inside each build you can use a name.

    "builders": [

        {

..

            "image": "ubuntu:xenial",

..

            "type": "docker",

            "name": "xenial-vim",

..

        },






for your request, imagine you have db and www but to keep things simple i just used vim/git


for this example i did

xenial-vim
xenial-git

both get htop installed but then a local script run vim gets vim, git gets git

root@ubuntu-1604-vmware:/vagrant/multidocker# docker run --rm xenial-vim which htop vim git

/usr/bin/htop

/usr/bin/vim

root@ubuntu-1604-vmware:/vagrant/multidocker# docker run --rm xenial-git which htop vim git

/usr/bin/htop

/usr/bin/git

root@ubuntu-1604-vmware:/vagrant/multidocker#



so when you build you can run provisioners like shell, if you filter with `only` you can have an specific one


as you have names on each builder then you can filter on post-processor to have a tag on the one you want to tag, 

git -> git
vim -> vim


Let me know if there is any question, I think the json in the repo is clear, but feel free to reach out if not.



Thanks
Alvaro



--
This mailing list is governed under the HashiCorp Community Guidelines - https://www.hashicorp.com/community-guidelines.html. Behavior in violation of those guidelines may result in your removal from this mailing list.
 
GitHub Issues: https://github.com/mitchellh/packer/issues
IRC: #packer-tool on Freenode
---
You received this message because you are subscribed to the Google Groups "Packer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to packer-tool+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/packer-tool/726b1a9c-484a-4989-943f-2716edcdc567%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Alvaro

Loric Brevet

unread,
Mar 7, 2018, 9:21:08 AM3/7/18
to Packer
Thank you for your precise explanation, and for having posted this code as example on GitHub.

These conditions on provisioning can effectively bring some interest for this purpose.

Usually, docker-compose files contain less that 10 containers. So it maybe possible to keep them definitely in the same file.

In the end, it seem to be more a matter of readability and maintenance to decide to split them into separate JSON files.

What I can notice however – correct me if I am wrong – is that it is not possible to have multiple builders provisioned only once by one provisioning script.
It seems the provisioning is triggered once per builder.

In Ansible, we usually define an inventory as followed.

[git]
xenial
-git

[vim]
xenial
-vim

And so launching the playbook would at once match the corresponding builder from the inventory and install the git package in the git container, and the vim package in the vim container.

That behavior does not seem possible with Packer + Ansible + Docker.

That would correspond to a Packer JSON file more or less as below.

{
    "variables": {
    },
    "builders": [
        {
            "commit": true,
            "image": "ubuntu:xenial",
            "pull": true,
            "type": "docker",
            "name": "xenial-vim",
            "run_command": [
                "-d","-t","{{.Image}}",
                "/bin/bash","-l"
            ]
        },
        {
            "commit": true,
            "image": "ubuntu:xenial",
            "pull": true,
            "type": "docker",
            "name": "xenial-git",
            "run_command": [
                "-d","-t","{{.Image}}",
                "/bin/bash","-l"
            ]
        }
    ],
    "post-processors": [
        {
            "only": [ "xenial-vim" ],
            "repository": "xenial-vim",
            "tag": "latest",
            "type": "docker-tag"
        },
        {
            "only": [ "xenial-git" ],
            "repository": "xenial-git",
            "tag": "latest",
            "type": "docker-tag"
        }
    ],
    "provisioners": [
        {
            "type": "ansible",
            "playbook_file": "ansible/myplaybook.yml"
        }
    ]
}

Packer could process to this sequence of actions:
  • Create xenial-vim base image from the first builder
  • Create xenial-git base image from the second builder
  • Create a dynamic inventory for Ansible
  • Execute only once the provisioning to provision at once the two previous builder images
  • Commit, tag and push xenial-vim to the xenial-vim repository
  • Commit, tag and push xenial-git to the xenial-git repository

Can you confirm this is not really doable with Packer? Or at least the provisioning would be launched twice?

Thank you so much,
Loric
To unsubscribe from this group and stop receiving emails from it, send an email to packer-tool...@googlegroups.com.



--
Alvaro

Alvaro Miranda Aguilera

unread,
Mar 8, 2018, 6:23:13 AM3/8/18
to packe...@googlegroups.com
in your code, packer will build the 2 docker in parallel

and on each of them ansible will run

you will end with 2 dockers

then if the ansible filter by name, then should work

you may need to check the container gets the name you need, maybe tweak the execute command

if I run it as is:

    xenial-git: hostname: f39716ea17ed

    xenial-vim: hostname: 8f052d9779d6


so if your ansible requires match hostname, i did update the repo, so now it does:

==> xenial-vim: Provisioning with shell script: xenial-all.sh

    xenial-git: hostname: xenial-git

    xenial-vim: hostname: xenial-vim



Alvaro

To unsubscribe from this group and stop receiving emails from it, send an email to packer-tool+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/packer-tool/660f784e-42c7-498b-9287-655d8a84009d%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Alvaro

Loric Brevet

unread,
Mar 8, 2018, 7:16:58 AM3/8/18
to Packer
Okay I see.

So what you say confirms what I thought. I effectively need to tweak a little bit to let Ansible match the correct targets.
And then, it seems that I don't have other choices than launching twice the provisioning (for each builder).

Thanks again for you precise information.

Loric



--
Alvaro

Reply all
Reply to author
Forward
0 new messages