'Dockerfiles' for LXD

I’m working on this project of mine, freckles, for a while now, and this is sort of a ‘tangential use-case’ I though some of you might be interested in.

Basically, freckles tries to provide a way to generically describe provisioning-type tasks, and then execute those tasks in all sorts of environments (physical machines, virtual ones, remote servers, Docker build processes, etc.). Its design allows for different backends to do the provisioning/orchestration, but currently only Ansible is properly implemented. A shell-script one, as well as one that uses Terraform are in the works though.

There exist already some good strategies to provision LXD containers, or build images (cloud-init, config management tools like Ansible, Puppet, Chef, other things like Packer), but none of them are as easy and immediate as using Dockerfiles for Docker is, IMHO. Now, granted, often that is not necessary, since LXD is used for different type of environments than Docker, in a lot of cases. Plus, it’s easier to re-use tools like Ansible, Chef, etc. with LXD, since an LXD container is much more similar to a ‘normal’ machine than a Docker container is. Still, I think there is some space where LXD would profit from having a quick and easy way to provision new containers or create images, and share the ‘recipes’ for that in a single file.

Long story, longer, I wrote about how to use freckles to that effect here:

This is the tldr; from that post:

On a system that has freckles and LXD installed and working, put the following content into a file 'example-lxd.frecklet':

- nginx-service
- nginx-vhost-from-folder:
    document_root: /var/www/html
    default_server: true
    use_https: false
- file-with-content:
    owner: www-data
    path: /var/www/html/index.html
    content: |
      <h1><i>freckles</i> says "Hello World", from {{:: from ::}}!</h1>

This will act as our ‘Dockerfile’, and describes how to install and configure Nginx to serve a static webpage. To create an LXD image from it, execute:

$ frecklecute lxd-image-from-frecklet-file \
     --install-packer \
     --source-image images:debian/10 \
     --image-name freckles-image \
     --frecklet-path $(pwd)/example-lxd.frecklet \
     --frecklet-vars '{"from": "my first image"}'

Once that has finished, create a container from the new ‘freckles-image’ image:

$ lxc launch freckles-image freckles-test

To test whether the Nginx service that runs in the container works, issue:

$ curl http://<container_ip>
<h1><i>freckles</i> says "Hello World", from my first image!</h1>

Happy to answer any questions, or hear your thoughs, concerns and suggestions.

EDIT: explicitely mentioning alternatives


Cloud-init is the equivelent to a dockerfile

Cloud-init is the equivelent to a dockerfile

Sorta, in some cases. I mention it briefly in the blog post I linked, not sure if you’ve read it. There are some disadvantages to using cloud-init, I’ll probably write another blog post on this at some stage, and how to use freckles in combination with cloud-init.

I edited my original post to explicitly (implicitly I kinda already did before) mention ‘cloud-init’, among other alternatives.

No really sorta about it, you define steps and packages shove them in a profile and just create containers with that profile

Your blog doesnt seem to really clarity why you dislike cloud-init

Your blog doesnt seem to really clarity why you dislike cloud-init

I don’t dislike cloud-init, and as I said, I’d have to write a longer post to explain why in some cases it is not the best solution. Maybe, for now, just take my post here as an alternative to consider (or completely ignore), in case cloud-init doesn’t work for you for some reason? As I said, this is really only a tangential use-case for freckles, I didn’t design it to be ‘Dockerfiles for LXD’. I still think it can be useful. Never hurts to have alternatives, no?