Many ways to build a container image
Tags: docker, container, build, image
Published: 2020-05-18 17:59:46

Whenever we think about building or running a container, the first tool that comes to our mind is Docker and it's perfectly fine. Docker has made our life way easier than we can think of. But there are other ways as well, we can build and run the image as well. So now the question comes to the mind is, how is it possible for Kubernetes, OpenStack, ECS, DC/OS to understand the build system of every different way we can build the image. Turns out, they don't need to. Because there is a specification on what should be the Image format of the container.  That's why OCI(Open Container Initiative) is formed.

## [Open Container Initiative (OCI)](https://www.opencontainers.org/)

The Open Container Initiative (OCI) is a lightweight, open governance structure (project), formed under the auspices of the Linux Foundation, for the express purpose of creating open industry standards around container formats and runtime. The OCI was launched on June 22nd, 2015 by Docker, CoreOS, and other leaders in the container industry. Read more [here](https://www.opencontainers.org/about).
We will be building nodejs-express server using the below tools. Now, Let's get started with the list.


### [Buildah](https://github.com/containers/buildah)

Buildah is a command-line tool for building Open Container Initiative-compatible (that means Docker and Kubernetes-compatible, too) images quickly and easily. Buildah is easy to incorporate into scripts and build pipelines, and best of all, it doesn't require a running container daemon to build its image.

```shell
buildah build-using-dockerfile -f Dockerfile .
```

Doc link: https://github.com/containers/buildah/blob/master/docs/buildah-bud.md


### [BuildKit](https://github.com/moby/buildkit)

BuildKit is a toolkit for converting source code to build artifacts in an efficient, expressive, and repeatable manner. BuildKit is composed of the `buildkitd` daemon and the `buildctl` client. While the `buildctl` client is available for Linux, macOS, and Windows, the `buildkitd` daemon is only available for Linux currently.

```shell
buildctl build \
    --frontend=dockerfile.v0 \
    --local context=. \
    --local dockerfile=.
```

Doc Link: https://github.com/moby/buildkit#building-a-dockerfile-with-buildctl


### [Buildpacks](https://buildpacks.io)

Buildpacks were first conceived by Heroku in 2011. Since then, they have been adopted by Cloud Foundry and other PaaS such as GitLab, Knative, Deis, Dokku, and Drie. Buildpacks embrace modern container standards, such as the OCI image format.

```shell
express-sample> pack suggest-builders
Suggested builders:
  Cloud Foundry:     cloudfoundry/cnb:bionic         Ubuntu bionic base image with buildpacks for Java, NodeJS and Golang
  Cloud Foundry:     cloudfoundry/cnb:cflinuxfs3     cflinuxfs3 base image with buildpacks for Java, .NET, NodeJS, Golang, PHP, HTTPD and NGINX
  Cloud Foundry:     cloudfoundry/cnb:tiny           Tiny base image (bionic build image, distroless run image) with buildpacks for Golang
  Heroku:            heroku/buildpacks:18            heroku-18 base image with buildpacks for Ruby, Java, Node.js, Python, Golang, & PHP

Tip: Learn more about a specific builder with:
  pack inspect-builder [builder image]

pack build express-pack-app --path . --builder heroku/buildpacks:18
```

Doc Link: https://buildpacks.io/docs/app-developer-guide/build-an-app/

### [img](https://github.com/genuinetools/img)

Standalone, daemon-less, unprivileged Dockerfile and OCI compatible container image builder.

`img` is more cache-efficient than Docker and can also execute multiple build stages concurrently, as it internally uses [BuildKit](https://github.com/moby/buildkit)'s DAG solver.

The commands/UX are the same as `docker {build,tag,push,pull,login,logout,save}` so all you have to do is replace `docker` with `img` in your scripts, command line, and/or life.

```shell
img build -t r.j3ss.co/img .
```

Doc link: https://github.com/genuinetools/img#build-an-image


### [Kaniko](https://github.com/GoogleContainerTools/kaniko)

Kaniko is a tool to build container images from a Dockerfile, inside a container or Kubernetes cluster. Kaniko doesn't depend on a Docker daemon and executes each command within a Dockerfile completely in userspace. This enables building container images in environments that can't easily or securely run a Docker daemon, such as a standard Kubernetes cluster.

```shell
docker run \
    -v "$HOME"/.config/gcloud:/root/.config/gcloud \
    -v /path/to/context:/workspace \
    gcr.io/kaniko-project/executor:latest \
    --dockerfile /workspace/Dockerfile \
    --destination "gcr.io/$PROJECT_ID/$IMAGE_NAME:$TAG" \
    --context dir:///workspace/
```

Doc link: https://github.com/GoogleContainerTools/kaniko


### [Podman](https://podman.io/)

Podman specializes in all of the commands and functions that help you to maintain and modify OCI images, such as pulling and tagging. It also allows you to create, run, and maintain those containers created from those images. For building container images via Dockerfiles, Podman uses Buildah's golang API and can be installed independently from Buildah.

```shell
podman build -f Dockerfile .
```

Doc link: https://docs.podman.io/en/latest/markdown/podman-build.1.html#examples


### [PouchContainer](https://pouchcontainer.io)

PouchContainer is a highly reliable container engine open sourced by Alibaba. It is an excellent software layer to fill up the gap between business applications and underlying infrastructure. The strong-isolation ability and rich container are its representative features.

```shell
pouch build [OPTION] PATH
Option:
      --addr string             buildkitd address (default "unix:///run/buildkit/buildkitd.sock")
      --build-arg stringArray   Set build-time variables
  -h, --help                    help for build
  -t, --tag stringArray         Name and optionally a tag in the 'name:tag' format
      --target string           Set the target build stage to build
```

Doc link: https://pouchcontainer.io/#/pouch/docs/commandline/pouch_build.md

### [OCIBuilder](https://ocibuilder.github.io/docs)

The **ocibuilder** offers a command line tool called the **ocictl** to build, push and pull [OCI](https://www.opencontainers.org/) compliant images through declarative specifications, allowing you to pick between [Buildah](https://github.com/containers/buildah) or [Docker](https://docs.docker.com/) as the container build tool.

```shell
ocictl init
ocictl build        # using docker
ocictl build --builder buildah      # using buildah
```

Doc link: https://ocibuilder.github.io/docs/quickstart/


As we can see here, there are many ways we can build an image and run it practically anywhere we want. Comment down below if you any other ways we can build it.

#### Help Links:

- https://www.docker.com
- https://ocibuilder.github.io/docs/quickstart
- https://github.com/opencontainers/image-spec