Skip to main content

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.

Metadata

Release files for dockable 0.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for dockable 0.5
File Interpreter ABI Platform Actions
dockable-0.5-py3-none-any.whl Python 3 none any Details for dockable-0.5-py3-none-any.whl

Release files / dockable-0.5-py3-none-any.whl

Download URL dockable-0.5-py3-none-any.whl
Size 19.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6596c1beb7c6d012705508ea952e3865533aba67a87a276de62b5c1fc9d47aba
BLAKE2b-256 checksum
How to use checksums
336fa5139f97b5b52a8d310a4601ae7e9a790caa4a522628b3367c5b57f19fe2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.11.2

Security for dockable 0.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page