Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ozankasikci/dockerfile-generator

dfg - Generates dockerfiles based on various input channels.
https://github.com/ozankasikci/dockerfile-generator

dfg docker dockerfile dockerfile-generator

Last synced: about 1 month ago
JSON representation

dfg - Generates dockerfiles based on various input channels.

Awesome Lists containing this project

README

        

## dfg - Dockerfile Generator

`dfg` is both a go library and an executable that produces valid Dockerfiles using various input channels.

[![Build Status](https://travis-ci.org/ozankasikci/dockerfile-generator.svg?branch=master)](https://travis-ci.org/ozankasikci/dockerfile-generator)
[![GoDoc](https://godoc.org/github.com/ozankasikci/dockerfile-generator?status.svg)](https://godoc.org/github.com/ozankasikci/dockerfile-generator)
[![Coverage Status](https://coveralls.io/repos/github/ozankasikci/dockerfile-generator/badge.svg?branch=master)](https://coveralls.io/github/ozankasikci/dockerfile-generator?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/ozankasikci/dockerfile-generator)](https://goreportcard.com/report/github.com/ozankasikci/dockerfile-generator)
[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)

## Table of Contents

- [Overview](#overview)
- [Installation](#installation)
* [Installing as an Executable](#installing-as-an-executable)
* [Installing as a Library](#installing-as-a-library)
- [Getting Started](#getting-started)
* [Using dfg as an Executable](#using-dfg-as-an-executable)
* [Using dfg as a Library](#using-dfg-as-a-library)
- [Examples](#examples)
* [YAML File Per Dockerfile Example](#single-yaml-file-per-dockerfile-example-expects-a-stages-key-on-top-level)
* [YAML File Target Field Example](#yaml-file-example-with-target-field-allows-using-any-field)
* [Library Usage Example](#library-usage-example)
- [TODO](#todo)

## Overview

`dfg` is a Dockerfile generator that accepts input data from various sources, produces and redirects the generated Dockerfile to an output target such as a file or stdout.

It is especially useful for generating Dockerfile instructions conditionally since Dockerfile language has no control flow logic.

## Installation
#### Installing as an Executable

* MacOS

```shell
curl -o dfg -L https://github.com/ozankasikci/dockerfile-generator/releases/download/v1.0.0/dfg_v1.0.0_darwin_amd64
chmod +x dfg && sudo mv dfg /usr/local/bin
```

* Linux

```shell
curl -o dfg -L https://github.com/ozankasikci/dockerfile-generator/releases/download/v1.0.0/dfg_v1.0.0_linux_amd64
chmod +x dfg && sudo mv dfg /usr/local/bin
```

* Windows

```shell
curl -o dfg.exe -L https://github.com/ozankasikci/dockerfile-generator/releases/download/v1.0.0/dfg_v1.0.0_windows_amd64.exe
```

#### Installing as a Library

`go get -u github.com/ozankasikci/dockerfile-generator`

## Getting Started

### Using dfg as an Executable

Available commands:

`dfg generate --input path/to/yaml --out Dockerfile` generates a file named `Dockerfile`

`dfg generate --input path/to/yaml --target-field ".server.dockerfile" --out Dockerfile` generates a file named `Dockerfile` reading the `.server.dockerfile` field of the YAML file.

`dfg generate --help` lists available flags

### Using dfg as a Library

When using `dfg` as a go library, you need to pass a `[]dfg.Stage` slice as data.
This approach enables and encourages multi staged Dockerfiles.
Dockerfile instructions will be generated in the same order as in the `[]dfg.Instruction` slice.

Some `Instruction`s accept a `runForm` field which specifies if the `Instruction` should be run in the `shell form` or the `exec form`.
If the `runForm` is not specified, it will be chosen based on [Dockerfile best practices](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).

For detailed usage example please see [Library Usage Example](#library-usage-example)

## Examples

#### Single YAML File per Dockerfile Example (Expects a `stages` key on top level)
```yaml
stages:
final:
- from:
image: kstaken/apache2
- run:
runForm: shell
params:
- apt-get update &&
- apt-get install -y
- php5
- libapache2-mod-php5 &&
- apt-get clean &&
- rm -rf /var/lib/apt/lists/*
- cmd:
params:
- /usr/sbin/apache2
- -D
- FOREGROUND
```
Use dfg as binary:
```shell
dfg generate -i ./example-input-files/apache-php.yaml --stdout
```
Or as a library
```go
data, err := dfg.NewDockerFileDataFromYamlFile("./example-input-files/apache-php.yaml")
tmpl := dfg.NewDockerfileTemplate(data)
err = tmpl.Render(output)
```

#### Output

```dockerfile
FROM kstaken/apache2
RUN apt-get update && apt-get install -y php5 libapache2-mod-php5 && apt-get clean && rm -rf /var/lib/apt/lists/*
CMD ["/usr/sbin/apache2", "-D", "FOREGROUND"]
```

#### YAML File Example With Target Field (Allows using any field)
```yaml
someConfig:
key: value
serverConfig:
dockerfile:
stages:
final:
- from:
image: kstaken/apache2
- run:
runForm: shell
params:
- apt-get update &&
- apt-get clean &&
- rm -rf /var/lib/apt/lists/*
```
Use dfg as binary:
```shell
dfg generate -i ./example-input-files/test-input-with-target-key-6.yaml --target-field ".serverConfig.dockerfile" --stdout
```
Or as a library
```go
data, err := dfg.NewDockerFileDataFromYamlField("./example-input-files/test-input-with-target-key-6.yaml", ".serverConfig.dockerfile")
tmpl := dfg.NewDockerfileTemplate(data)
err = tmpl.Render(output)
```

#### Output

```dockerfile
FROM kstaken/apache2
RUN apt-get update && apt-get clean && rm -rf /var/lib/apt/lists/*
```

#### Library Usage Example

```go
package main

import dfg "github.com/ozankasikci/dockerfile-generator"

func main() {
data := &dfg.DockerfileData{
Stages: []dfg.Stage{
// Stage 1 - Builder Image
// An instruction is just an interface, so you can pass custom structs as well
[]dfg.Instruction{
dfg.From{
Image: "golang:1.7.3", As: "builder",
},
dfg.User{
User: "ozan",
},
dfg.Workdir{
Dir: "/go/src/github.com/ozankasikci/dockerfile-generator/",
},
dfg.RunCommand{
Params: []string{"go", "get", "-d", "-v", "golang.org/x/net/html"},
},
dfg.CopyCommand{
Sources: []string{"app.go"}, Destination: ".",
},
dfg.RunCommand{
Params: []string{"CGO_ENABLED=0", "GOOS=linux", "go", "build", "-a", "-installsuffix", "cgo", "-o", "app", "."},
},
},
// Stage 2 - Final Image
[]dfg.Instruction{
dfg.From{
Image: "alpine:latest", As: "final",
},
dfg.RunCommand{
Params: []string{"apk", "--no-cache", "add", "ca-certificates"},
},
dfg.User{
User: "root", Group: "admin",
},
dfg.Workdir{
Dir: "/root/",
},
dfg.CopyCommand{
From: "builder", Sources: []string{"/go/src/github.com/ozankasikci/dockerfile-generator/app"}, Destination: ".",
},
dfg.Cmd{
Params: []string{"./app"},
},
},
},
}
tmpl := dfg.NewDockerfileTemplate(data)

// write to a file
file, err := os.Create("Dockerfile")
err = tmpl.Render(file)

// or write to stdout
err = tmpl.Render(os.Stdout)
}
```

#### Output
```Dockerfile
FROM golang:1.7.3 as builder
USER ozan
WORKDIR /go/src/github.com/ozankasikci/dockerfile-generator/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .

FROM alpine:latest as final
RUN apk --no-cache add ca-certificates
USER root:admin
WORKDIR /root/
COPY --from=builder /go/src/github.com/ozankasikci/dockerfile-generator/app .
CMD ["./app"]
```

## TODO
- [x] Add reading Dockerfile data from an existing yaml file support
- [ ] Implement json file input channel
- [ ] Implement stdin input channel
- [ ] Implement toml file input channel