Skip to content

Commit 980fd98

Browse files
author
preminger
authored
docs: build from Dockerfiles (#220)
* document build from Dockerfiles * add discussion of cross-arch Dockerfile builds * clarify embedded nature of ephemeral buildkitd + fix typo
1 parent 8444c31 commit 980fd98

File tree

7 files changed

+257
-8
lines changed

7 files changed

+257
-8
lines changed

appendix.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ where both ``<image>`` and ``<tag>`` are mandatory fields that must be
11241124
written explicitly.
11251125

11261126

1127-
.. _docker-daemon:
1127+
.. _docker-archive:
11281128

11291129
``docker-archive`` bootstrap agent
11301130
==================================

build_a_container.rst

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,246 @@ containers. The containers are decrypted at runtime entirely in kernel space,
270270
meaning that no intermediate decrypted data is ever written to disk. See
271271
:ref:`encrypted containers <encryption>` for more details.
272272

273+
*************************
274+
Building from Dockerfiles
275+
*************************
276+
277+
Starting with version 4.1, {Singularity} can build OCI-SIF images directly from
278+
`Dockerfiles
279+
<https://docs.docker.com/develop/develop-images/dockerfile_best-practices/>`__,
280+
creating images that can be run using {Singularity}'s :ref:`OCI mode
281+
<oci_runtime>`.
282+
283+
.. code:: console
284+
285+
$ cat ./Dockerfile
286+
FROM debian
287+
CMD cat /etc/os-release
288+
289+
$ singularity build --oci ./debian.oci.sif ./Dockerfile
290+
INFO: Did not find usable running buildkitd daemon; spawning our own.
291+
INFO: cfg.Root for buildkitd: /home/omer/.local/share/buildkit
292+
INFO: Using crun runtime for buildkitd daemon.
293+
INFO: running buildkitd server on /run/user/1000/buildkit/buildkitd-0179484509442521.sock
294+
[+] Building 4.3s (5/5)
295+
[+] Building 4.4s (5/5) FINISHED
296+
=> [internal] load build definition from Dockerfile 0.0s
297+
=> => transferring dockerfile: 131B 0.0s
298+
=> [internal] load metadata for docker.io/library/debian:latest 1.2s
299+
=> [internal] load .dockerignore 0.0s
300+
=> => transferring context: 2B 0.0s
301+
=> [1/1] FROM docker.io/library/debian:latest@sha256:fab22df3737 2.9s
302+
=> => resolve docker.io/library/debian:latest@sha256:fab22df3737 0.0s
303+
=> => sha256:8457fd5474e70835e4482983a5662355d 49.58MB / 49.58MB 2.8s
304+
=> exporting to docker image format 3.1s
305+
=> => exporting layers 0.0s
306+
=> => exporting manifest sha256:9fec77672dfa11e5eb28e3fe9377cd6c 0.0s
307+
=> => exporting config sha256:4243e816256d45bb137ff40bafe396da5f 0.0s
308+
=> => sending tarball 0.2s
309+
Getting image source signatures
310+
Copying blob 8457fd5474e7 done |
311+
Copying config 46c53efffd done |
312+
Writing manifest to image destination
313+
INFO: Converting OCI image to OCI-SIF format
314+
INFO: Squashing image to single layer
315+
INFO: Writing OCI-SIF image
316+
INFO: Cleaning up.
317+
INFO: Build complete: ./debian.oci.sif
318+
319+
$ singularity run --oci ./debian.oci.sif
320+
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
321+
NAME="Debian GNU/Linux"
322+
VERSION_ID="12"
323+
VERSION="12 (bookworm)"
324+
VERSION_CODENAME=bookworm
325+
ID=debian
326+
HOME_URL="https://www.debian.org/"
327+
SUPPORT_URL="https://www.debian.org/support"
328+
BUG_REPORT_URL="https://bugs.debian.org/"
329+
330+
The resulting containers can be used with all the :ref:`action commands
331+
<cowimage>` (`exec
332+
<https://www.sylabs.io/guides/{version}/user-guide/cli/singularity_exec.html>`__
333+
/ `shell
334+
<https://www.sylabs.io/guides/{version}/user-guide/cli/singularity_shell.html>`__
335+
/ `run
336+
<https://www.sylabs.io/guides/{version}/user-guide/cli/singularity_run.html>`__)
337+
in the expected way.
338+
339+
.. code:: console
340+
341+
$ singularity exec --oci ./debian.oci.sif uname -a
342+
Linux nueve 5.14.0-284.30.1.el9_2.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Aug 25 09:13:12 EDT 2023 x86_64 GNU/Linux
343+
344+
$ singularity shell --oci ./debian.oci.sif uname
345+
Singularity> uname -a
346+
Linux nueve 5.14.0-284.30.1.el9_2.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Aug 25 09:13:12 EDT 2023 x86_64 GNU/Linux
347+
Singularity>
348+
349+
.. note::
350+
351+
If the `exec
352+
<https://www.sylabs.io/guides/{version}/user-guide/cli/singularity_exec.html>`__
353+
or `shell
354+
<https://www.sylabs.io/guides/{version}/user-guide/cli/singularity_shell.html>`__
355+
commands are used, the ``CMD`` / ``ENTRYPOINT`` directives in the Dockerfile
356+
will be ignored.
357+
358+
The resulting containers also accept command-line arguments, as well as input
359+
that is piped through ``stdin``. The following example demonstrates both:
360+
361+
.. code:: console
362+
363+
$ cat ./Dockerfile
364+
FROM debian
365+
366+
SHELL ["/bin/bash", "-c"]
367+
368+
RUN apt-get update
369+
RUN apt-get install -y cowsay lolcat
370+
371+
RUN echo $'#! /bin/bash \n\
372+
echo from cmdline: $@ | /usr/games/cowsay | /usr/games/lolcat \n\
373+
sed "s/^/from stdin: /g" | /usr/games/cowsay | /usr/games/lolcat' > /myscript.sh
374+
375+
RUN chmod +x /myscript.sh
376+
377+
ENTRYPOINT ["/myscript.sh"]
378+
379+
$ singularity build --oci ./lolcow.oci.sif ./Dockerfile
380+
INFO: Did not find usable running buildkitd daemon; spawning our own.
381+
INFO: cfg.Root for buildkitd: /home/omer/.local/share/buildkit
382+
INFO: Using crun runtime for buildkitd daemon.
383+
INFO: running buildkitd server on /run/user/1000/buildkit/buildkitd-8961170237105250.sock
384+
[+] Building 15.1s (9/9)
385+
[+] Building 15.2s (9/9) FINISHED
386+
=> [internal] load build definition from Dockerfile 0.0s
387+
=> => transferring dockerfile: 549B 0.0s
388+
=> [internal] load metadata for docker.io/library/debian:latest 0.5s
389+
=> [internal] load .dockerignore 0.0s
390+
=> => transferring context: 2B 0.0s
391+
=> [1/5] FROM docker.io/library/debian:latest@sha256:fab22df3737 1.0s
392+
=> => resolve docker.io/library/debian:latest@sha256:fab22df3737 0.0s
393+
=> => extracting sha256:8457fd5474e70835e4482983a5662355d892d5f6 1.0s
394+
=> [2/5] RUN apt-get update 2.2s
395+
=> [3/5] RUN apt-get install -y cowsay lolcat 7.9s
396+
=> [4/5] RUN echo $'#! /bin/bash \necho from cmdline: $@ | /usr/ 0.1s
397+
=> [5/5] RUN chmod +x /myscript.sh 0.1s
398+
=> exporting to docker image format 3.3s
399+
=> => exporting layers 2.7s
400+
=> => exporting manifest sha256:fc7222347c207c35165ccd2fee562af9 0.0s
401+
=> => exporting config sha256:74c5da659e8504e4be283ad6d82774194e 0.0s
402+
=> => sending tarball 0.5s
403+
Getting image source signatures
404+
Copying blob 8457fd5474e7 done |
405+
Copying blob 4769fe2f22da done |
406+
Copying blob 173d009c20af done |
407+
Copying blob 7ec86debbe9b done |
408+
Copying blob 491c7ee403c2 done |
409+
Copying config 74b69e878e done |
410+
Writing manifest to image destination
411+
INFO: Converting OCI image to OCI-SIF format
412+
INFO: Squashing image to single layer
413+
INFO: Writing OCI-SIF image
414+
INFO: Cleaning up.
415+
INFO: Build complete: ./lolcow.oci.sif
416+
417+
$ echo "world" | singularity run --oci ./lolcow.oci.sif hello
418+
_____________________
419+
< from cmdline: hello >
420+
---------------------
421+
\ ^__^
422+
\ (oo)\_______
423+
(__)\ )\/\
424+
||----w |
425+
|| ||
426+
___________________
427+
< from stdin: world >
428+
-------------------
429+
\ ^__^
430+
\ (oo)\_______
431+
(__)\ )\/\
432+
||----w |
433+
|| ||
434+
435+
{Singularity} uses `buildkit <https://docs.docker.com/build/buildkit/>`__ to
436+
build an OCI image from a Dockerfile. It checks if there is a ``buildkitd``
437+
daemon that is already running on the system (and whose permissions allow access
438+
by the current user), and if so, that daemon is used for the build process. If a
439+
usable ``buildkitd`` daemon is not found, {Singularity} will launch an ephemeral
440+
build daemon of its own, inside a :ref:`user namespace <setuid_and_userns>`,
441+
that will be used for the build process and torn down when the build is
442+
complete. This ephemeral build daemon is based on `moby/buildkit
443+
<httpshttps://github.com/moby/buildkit/>`__, but is embedded within
444+
{Singularity} and runs as part of the same process.
445+
446+
.. note::
447+
448+
Launching the ephemeral ``buildkitd`` daemon requires a system with
449+
:ref:`user namespace support <setuid_and_userns>` as well as ``crun`` /
450+
``runc`` installed. These are independently required for using
451+
{Singularity}'s :ref:`OCI mode <oci_sysreq>`. See the `Admin Guide
452+
<https://sylabs.io/guides/{adminversion}/admin-guide/>`__ for more
453+
information on these system requirements.
454+
455+
Additional features
456+
===================
457+
458+
Build from Dockerfiles supports many of the same command-line options as regular
459+
(non-OCI-SIF) ``build``, including:
460+
461+
* ``--build-arg KEY=VAL`` / ``--build-arg-file <path>``: pass value for
462+
Dockerfile variables at build time (see `Dockerfile ARG documentation
463+
<https://docs.docker.com/engine/reference/builder/#arg>`__).
464+
465+
* ``--docker-login`` / Docker credential-related environment variables /
466+
``--authfile``: see the documentation on :ref:`authenticating with Docker/OCI
467+
registries <docker_auth>` and on the :ref:`authfile flag <sec:authfile>`.
468+
469+
* ``--arch``: build a container for a different CPU architecture than that of
470+
the running host.
471+
472+
As an example, if you are running on an ``amd64`` machine, you can run the
473+
following to build a container image for the 64-bit ARM architecure:
474+
475+
.. code:: console
476+
477+
$ singularity build --arch arm64 --oci ./alpine.oci.sif ./Dockerfile.alpine
478+
INFO: Did not find usable running buildkitd daemon; spawning our own.
479+
INFO: cfg.Root for buildkitd: /home/omer/.local/share/buildkit
480+
INFO: Using "crun" runtime for buildkitd daemon.
481+
INFO: running buildkitd server on /run/user/1000/buildkit/buildkitd-4747966236261602.sock
482+
[+] Building 0.6s (1/2)
483+
[+] Building 0.7s (5/5) FINISHED
484+
=> [internal] load build definition from Dockerfile.alpine 0.0s
485+
=> => transferring dockerfile: 142B 0.0s
486+
=> [internal] load metadata for docker.io/library/alpine:latest 0.6s
487+
=> [internal] load .dockerignore 0.0s
488+
=> => transferring context: 2B 0.0s
489+
=> CACHED [1/1] FROM docker.io/library/alpine:latest@sha256:eece 0.0s
490+
=> => resolve docker.io/library/alpine:latest@sha256:eece025e432 0.0s
491+
=> exporting to docker image format 0.0s
492+
=> => exporting layers 0.0s
493+
=> => exporting manifest sha256:b799c38cef1756bcc55b0684617fda7d 0.0s
494+
=> => exporting config sha256:5118299610d621e305a9153753a52e2f9e 0.0s
495+
=> => sending tarball 0.0s
496+
Getting image source signatures
497+
Copying blob 579b34f0a95b done |
498+
Copying config 5a13726077 done |
499+
Writing manifest to image destination
500+
INFO: Converting OCI image to OCI-SIF format
501+
INFO: Squashing image to single layer
502+
INFO: Writing OCI-SIF image
503+
INFO: Cleaning up.
504+
INFO: Build complete: ./alpine.oci.sif
505+
506+
.. note::
507+
508+
In order to use Dockerfile directives like ``RUN`` in a cross-architecture
509+
build, you will have to have ``qemu-static`` / ``binfmt_misc`` emulation
510+
installed. See the discussion of :ref:`CPU emulation <qemu>` for more
511+
information.
512+
273513
*************
274514
Build options
275515
*************

definition_files.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ Other bootstrap agents
106106
Scientific Linux)
107107
- :ref:`debootstrap <build-debootstrap>` (apt-based systems such as
108108
Debian and Ubuntu)
109-
- :ref:`oci <cli-oci-bootstrap-agent>` (bundle compliant with OCI Image
109+
- :ref:`oci <docker-daemon>` (bundle compliant with OCI Image
110110
Specification)
111-
- :ref:`oci-archive <cli-oci-archive-bootstrap-agent>` (tar files
111+
- :ref:`oci-archive <docker-archive>` (tar files
112112
obeying the OCI Image Layout Specification)
113113
- :ref:`docker-daemon <docker-daemon>` (images managed by the
114114
locally running docker daemon)

oci_runtime.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ Users are encouraged to employ OCI-mode when their primary use-case for
6969
registries. Behavior will more closely match that described for Docker than with
7070
{Singularity}'s native runtime.
7171

72+
.. _oci_sysreq:
73+
7274
System Requirements
7375
===================
7476

@@ -167,7 +169,7 @@ registry in question, anonymous authentication will be used instead.
167169

168170
However, the ``run / shell / exec`` and ``pull`` commands can also use
169171
credentials stored in a different file of the user's choosing, by specifying the
170-
``--authfile <path>`` flag. See the :ref:`documentation of the --authfile flag
172+
``--authfile <path>`` flag. See the :ref:`documentation of the authfile flag
171173
<sec:authfile>` for details on how to create and use custom credential files.
172174

173175
.. _oci_compat:

registry.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ images. Some registries require credentials to access certain images or even the
1010
registry itself. Previously, the only method in {Singularity} to supply
1111
credentials to registries was to supply credentials for each command or set
1212
environment variables to contain the credentials for a single registry. See
13-
:ref:`Authentication via Interactive Login
14-
<sec:authentication_via_docker_login>` and :ref:`Authentication via Environment
15-
Variables <sec:authentication_via_environment_variables>`.
13+
:ref:`Authentication via Interactive Login <sec:docker_login>` and
14+
:ref:`Authentication via Environment Variables <sec:docker_envvars>`.
1615

1716
Starting with {Singularity} 4.0, users can supply credentials
1817
on a per-registry basis with the ``registry`` command.

security.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ and processes apply. In a default installation, {Singularity} uses a
5757
setuid starter binary to perform only the specific tasks needed to setup
5858
the container.
5959

60+
.. _setuid_and_userns:
61+
6062
************************
6163
Setuid & User Namespaces
6264
************************

singularity_and_docker.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ SIF, and then always run from the SIF file, rather than using
160160
Alternatively, if you have signed up for a Docker Hub account, make sure
161161
that you authenticate before using ``docker://`` container URIs.
162162

163+
.. _docker_auth:
164+
163165
Authentication / Private Containers
164166
===================================
165167

@@ -215,6 +217,8 @@ login.
215217
``~/.docker/config.json``. It cannot read credentials from external
216218
Docker credential helpers.
217219

220+
.. _sec:docker_login:
221+
218222
Interactive Login
219223
-----------------
220224

@@ -497,6 +501,8 @@ Ubuntu image for a 64-bit ARM system:
497501
498502
$ singularity pull --arch arm64 docker://ubuntu
499503
504+
.. _qemu:
505+
500506
CPU emulation
501507
=============
502508

@@ -640,7 +646,7 @@ ways:
640646
``--authfile <path>`` flag to the ``build`` command. Note, however, that this
641647
will store the relevant credentials unencrypted in the specified file, so
642648
appropriate care must be taken concerning the location, ownership, and
643-
permissions of this file. See the :ref:`documentation of the --authfile flag
649+
permissions of this file. See the :ref:`documentation of the authfile flag
644650
<sec:authfile>` for more information.
645651

646652
If you are running the build under your account via the ``--fakeroot``

0 commit comments

Comments
 (0)