ansible for dockerfiles
Project description
dockable
dockable is progressive and modular rendering engine for Dockerfiles. It makes it easier to reuse Dockerfile snippets without having to copy and paste, instead you can share your Dockerfile snippets as pip packages, keeping your Dockerfiles clean and well organized.
Progressive
dockable is progressive, this means you can adopt it gradually and leverage the parts that you need to solve your problems, without having to rewrite everything from scratch.
Example 1: dockable as a simple preprocessor
dockable can be used as a simple preprocessor for an existing Dockerfile, in this most minimal adoption form it's a simple jinja template engine with values coming from command line arguments or yaml configuration files.
# kubectl.dock
{% if dist == "ubuntu" %}
FROM ubuntu:latest
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates \
wget \
&& rm -rf /var/lib/apt/lists/*
{% else %}
FROM alpine:latest
RUN apk add --no-cache \
ca-certificates \
wget
{% endif %}
RUN wget https://dl.k8s.io/release/{{ version }}/bin/linux/amd64/kubectl -P /tmp/download \
&& mv /tmp/download/kubectl /usr/local/bin/kubectl \
&& chmod 755 /usr/local/bin/kubectl \
&& rm -rf /tmp/download
python -m dockable kubectl.dock Dockerfile --set=dist=ubuntu --set=version=1.24.6
The rendered dockerfile will look like this
# Dockerfile
FROM ubuntu:latest
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
python3 \
python3-pip \
ca-certificates \
wget \
&& rm -rf /var/lib/apt/lists/*
RUN wget https://dl.k8s.io/release/1.24.6/bin/linux/amd64/kubectl -P /tmp/download \
&& mv /tmp/download/kubectl /usr/local/bin/kubectl \
&& chmod 755 /usr/local/bin/kubectl \
&& rm -rf /tmp/download
Example 2: Insert dockable snippets
dockable can be used to insert dockable snippets into an existing Dockerfile. A dockable snippet is a short yaml configuration that contains all the information for dockable to render that part of the Dockerfile.
# kubernetes.dock
FROM ubuntu:latest
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
---
steps:
- dockable.releases.binary:
pkg:
- name: kubectl
version: 1.24.6
python -m dockable kubectl.dock Dockerfile
FROM ubuntu:latest
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates \
wget \
&& rm -rf /var/lib/apt/lists/*
RUN wget https://dl.k8s.io/release/v1.24.6/bin/linux/amd64/kubectl -P /tmp/download \
&& mv /tmp/download/kubectl /usr/local/bin/kubectl \
&& chmod 755 /usr/local/bin/kubectl \
&& rm -rf /tmp/download
Example 3: dockable files
dockable also supports to write the a complete Dockerfile using yaml
# kubernetes.yml
name: kubernetes
from: ubuntu:latest
label:
MAINTAINER: Martin Zihlmann <martizih@outlook.com>
steps:
- dockable.builtin.apt:
pkg:
- python3
- python3-pip
- dockable.releases.binary:
pkg:
- name: kubectl
version: 1.24.6
- name: helm
version: 3.11.0
python -m dockable kubernetes.yml Dockerfile
FROM ubuntu:latest
LABEL MAINTAINER="Martin Zihlmann <martizih@outlook.com>"
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
python3 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates \
wget \
&& rm -rf /var/lib/apt/lists/*
RUN wget https://dl.k8s.io/release/v1.24.6/bin/linux/amd64/kubectl -P /tmp/download \
&& mv /tmp/download/kubectl /usr/local/bin/kubectl \
&& chmod 755 /usr/local/bin/kubectl \
&& rm -rf /tmp/download
RUN wget https://get.helm.sh/helm-v3.11.0-linux-amd64.tar.gz -P /tmp/download \
&& tar -zxvf /tmp/download/helm-v3.11.0-linux-amd64.tar.gz -C /tmp/download \
&& mv /tmp/download/linux-amd64/helm /usr/local/bin/helm \
&& chmod 755 /usr/local/bin/helm \
&& rm -rf /tmp/download
Modular
The power of dockable lies in its extensibility. You can write handlers for dockable snippets yourself and reuse them accross all of your projects.
Write your own dockable snippet handler
Let's suppose you want to write a handler for compiling git from source, you would start by writing the handler itself:
# git.yml.jinja
name: build
steps:
- run:
- wget {{ url }}/{{ filename }} -P /tmp/download
- tar -zxvf /tmp/download/{{ filename }} -C /tmp/download
- cd /tmp/download/{{ folder }}
- make configure
- ./configure --prefix=/usr {{ config_options }}
- make -j all
- make install
- cd -
- rm -rf /tmp/download
needs:
- dockable.builtin.apt:
pkg:
- ca-certificates
- wget
- make
---
name: git-from-source
steps:
- .build:
url: https://mirrors.edge.kernel.org/pub/software/scm/git
filename: git-{{ version }}.tar.gz
folder: git-{{ version }}
needs:
- dockable.builtin.apt:
pkg:
- gcc
- dh-autoreconf
- libcurl4-gnutls-dev
- libexpat1-dev
- gettext
- libz-dev
- libssl-dev
As you can see a handler is just a yml configuration, the handler itself can reference other handlers and hence build upon the ever-growing eco-system of dockable snippets. All you now need to do to register your handler is to add a module.yml
to your python package.
# module.yml
dependencies:
- dockable.raw
- dockable.builtin
handlers:
- git.yml.jinja
And there you go - you can now use, version and share this snippets as a pip package.
steps:
- mymodule.git-from-source:
version: 2.34.1
python handler function
With dockable you can also register regular python functions as handlers for your dockable snippets. Let's suppose you want to parse a requirements.txt on the host and inline its contents into the dockerfile, rather than copying the file into the container.
# pip_handler.py
import pip_api
def load_requirements(file):
res = pip_api.parse_requirements(file)
return [str(x) for x in res.values()]
def inline_requirements(file):
reqs = pip_api.parse_requirements(file)
pkg = [str(x) for x in reqs.values()]
return [
{
"dockable.builtin.pip": {
"pkg": pkg
}
}
]
in the module.yml you can reference the function and register it under a new name.
dependencies:
- dockable.builtin
handlers:
- pip-inline-requirements: pip_handler:inline_requirements
and then finally you can use it as a dockable snippet
steps:
- mymodule.pip-inline-requirements:
file: requirements.txt
This kind of pre-processing allows us to do all kinds of magic in the background:
Do you care about reproducible builds? How about you freeze the versions of your packages on-the-fly with whatever is currently available. Do you care about keeping your secrets secret? How about downloading assets on the host system and copying them into the Docker image instead of downloading them inside the image?
Conclusion
With dockable you have a whole new set of possibilities to work with Dockerfiles, it's a brand new powertool available to you.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
File details
Details for the file dockable-0.5-py3-none-any.whl
.
File metadata
- Download URL: dockable-0.5-py3-none-any.whl
- Upload date:
- Size: 19.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6596c1beb7c6d012705508ea952e3865533aba67a87a276de62b5c1fc9d47aba |
|
MD5 | 8d9a76320a28340d66ae6c6edab151ba |
|
BLAKE2b-256 | 336fa5139f97b5b52a8d310a4601ae7e9a790caa4a522628b3367c5b57f19fe2 |