npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

dockerspaniel

v0.2.0

Published

Create Dockerfiles from JSON

Downloads

22

Readme

NPM version Build Status Coverage Status

Why would anyone ever use this?

Short answer? Continuous delivery.

Docker has wide applications in platform engineering. It is particularly useful for creating isolated build environments. Docker images are created from Dockerfiles, which contain various steps. If you are targeting multiple platforms, you may find yourself juggling a bunch of similar Dockerfiles with slight variations.

This tool will help maximize code reuse and enable you to generate unique Dockerfiles on-the-fly based on several features, such as tag-driven step inclusion/exclusion and variable substitution.

Installation

$ npm install -g dockerspaniel

Quick Start

Create a Spanielfile (JSON)

{
    "from": "ubuntu:12.04",
    "maintainer": "Josh Dolitsky <[email protected]>",
    "steps": [
        {
            "instruction": "run",
            "arguments": "apt-get update",
            "comment": "update packages"
        },
        {
            "instruction": "run",
            "arguments": "apt-get install -y nodejs",
            "comment": "install dependencies"
        }
    ]
}

Convert the Spanielfile to a Dockerfile

The following command

$ dockerspaniel

will create a Dockerfile in the same directory:

FROM ubuntu:12.04
MAINTAINER Josh Dolitsky <[email protected]>

# update packages
RUN apt-get update

# install dependencies
RUN apt-get install -y nodejs

Command-line Options

  Usage: dockerspaniel -i [input] -o [output] -b [baseimage] -t [tag]

  -h|--help    This help screen
  -i|--input   JSON file to use for input (default: Spanielfile)
  -o|--output  Path of new Dockerfile to create (default: Dockerfile)
  -b|--base    Override Docker base image to use in FROM instruction
  -t|--tag     Tag(s) for use by 'unless' and 'only' step attributes
               Supports mutliple tags via format '-t tag1 -t tag2' etc.

Tagging

The step attributes unless_one, unless, only_one, and only will allow you to include or exclude steps based on provided tags.

{
    "from": "ubuntu:12.04",
    "steps": [
        {
            "instruction": "run",
            "arguments": "apt-get update",
            "unless_one": [
                "no_update"
            ]
        },
        {
            "instruction": "run",
            "arguments": "apt-get install -y nodejs",
            "only_one": [
                "nodejs"
            ]
        }
    ]
}

From the above Spanielfile, many different Dockerfiles can be created.

(no tags)

Includes all steps without an only or only_one array.

$ dockerspaniel
. . .
FROM ubuntu:12.04
RUN apt-get update

no_update

Prevents update step because 'no_update' is present in the step's unless_one array.

$ dockerspaniel -t no_update
. . .
FROM ubuntu:12.04

nodejs

Includes nodejs install step because 'nodejs' is present in the step's only_one array.

$ dockerspaniel -t nodejs
. . .
FROM ubuntu:12.04
RUN apt-get update
RUN apt-get install -y nodejs

no_update and nodejs

Prevents update AND installs nodejs.

$ dockerspaniel -t no_update -t nodejs
. . .
FROM ubuntu:12.04
RUN apt-get install -y nodejs

Variable Substitution

Variable substitution is supported via Handlebars in the format {{my_var}}.

The following Spanielfile has the defaults object defined, which defines default values:

{
    "from": "ubuntu:12.04",
    "steps": [
        {
            "instruction": "run",
            "arguments": "apt-get install -y {{dependencies}}"
        }
    ],
    "defaults": {
        "dependencies": "wget curl screen vim"
    }
}
$ dockerspaniel
...

FROM ubuntu:12.04
RUN apt-get install -y wget curl screen vim

Variables can be overridden by environment variables prefixed with DS_:


$ export DS_DEPENDENCIES="tmux nodejs"
$ dockerspaniel
...

FROM ubuntu:12.04
RUN apt-get install -y tmux nodejs

You are also able to use other Handlebar features, such as the each block helper. Notice in the example below that defaults.dependencies is now an array.

{
    "from": "ubuntu:12.04",
    "steps": [
        {
            "instruction": "run",
            "arguments": "apt-get install -y {{#each dependencies}}{{this}} {{/each}}"
        }
    ],
    "defaults": {
        "dependencies": ["wget", "curl", "screen", "vim"]
    }
}
$ dockerspaniel
...

FROM ubuntu:12.04
RUN apt-get install -y wget curl screen vim

External Files

If a step contains either the file or include attribute, step.arguments and step.instuction are ignored.

file attribute

step.file is the path to a raw Dockerfile to include in place, which supports templating.

Spanielfile

{
    "from": "ubuntu:12.04",
    "steps": [
        {
            "file": "path/to/Dockerfile1",
            "newline": true
        }
    ],
    "defaults": {
        "install_jdk": "RUN apt-get install -y openjdk-7-jdk"
    }
}

path/to/Dockerfile1

# Dockerfile1
RUN apt-get update
{{install_jdk}}

Resulting Dockerfile

FROM ubuntu:12.04

# Dockerfile1
RUN apt-get update
RUN apt-get install -y openjdk-7-jdk

include attribute

step.include is the path to another Spanielfile to include in place.

Spanielfile

{
    "from": "fedora:20",
    "steps": [
        {
            "include": "path/to/add_user.json",
            "comment": "create new user"
        }
    ],
    "defaults": {
        "username": "paul"
    }
}

path/to/add_user.json

{
    "steps": [
        {
            "instruction": "run",
            "arguments": "adduser {{username}}"
        }
    ]
}

Resulting Dockerfile

FROM fedora:20

# create new user with sudo access
RUN adduser paul

Spanielfile Attributes

from

Base image for subsequent instructions. Required unless the --base option is used.

maintainer

Author field of generated images.

defaults

Key-value pairs to use for Handlebars templating.

steps

Array of step objects. A step object has the following attributes:

step.instruction

Docker instruction. All instructions are supported, see the official documentation for a list: https://docs.docker.com/reference/builder

step.arguments

Arguments to pass to Docker instruction. For the step RUN apt-get update, RUN is the instruction and apt-get update is the arguments.

step.unless_one

Array of tags that, when ONE is provided, will cause this step to be excluded. See NOR gates.

step.unless

Array of tags that, when ALL are provided, will cause this step to be excluded. See NAND gates.

step.only_one

Array of tags that, when ONE is provided, will cause this step to be included. See OR gates.

step.only

Array of tags that, when ALL are provided, will cause this step to be included. See AND gates.

step.comment

Comment placed above the step.

step.newline

When true, adds a newline above the step without a comment.

step.include

Include an external Spanielfile. This should be either an absolute path, or a path relative to the parent file. Any defaults defined here will override defaults from the parent (but environment variables will still override these). This causes both step.instruction and step.arguments to be ignored.

step.file

Include an external Dockerfile (with optional Handlebars templating). This should be either an absolute path, or a path relative to the parent file. This causes step.include, step.instruction, and step.arguments to be ignored.

Using Programmatically

generateContents(data, callback)

var ds = require('dockerspaniel');

var data = {
    from: 'ubuntu:12.04',
    maintainer: 'John Smith',
    steps: [
        {
            instruction: 'run',
            arguments: 'apt-get update'
        },
        {
            instruction: 'run',
            arguments: 'apt-get install -y nodejs',
            only: [
                'nodejs'
            ]
        },
        {
            instruction: 'run',
            arguments: 'apt-get install -y mysql-server mysql-client',
            unless: [
                'no_database'
            ]
        }
    ]
};

var tags = ['nodejs', 'no_database'];

ds.generateContents(data, tags, function(err, contents) {
    if (err) throw err;
    console.log(contents);
});

createDockerfile(options, callback)

var ds = require('dockerspaniel');

var options = {
    input: '/path/to/json/file.json',
    output: '/path/to/new/Dockerfile',
    tags: [
        'nodejs',
        'no_database'
    ],
    base: 'ubuntu:12.04'
};

ds.createDockerfile(options, function (err) {
    if (err) throw err;
    // new Dockerfile was created at options.output
});