Shell out to `docker buildx build` to build images

pydocker uses the HTTP API (equivalent to `docker build`) which
has been dead for ages. `docker buildx` (the interface to BuildKit)
is what we *should* be using, but alas pydocker does not currently
support it and I suspect it never will (https://github.com/docker/docker-py/issues/2230).

This PR simply shells out, as I think that's the way.

Fixes https://github.com/jupyterhub/repo2docker/issues/875
pull/1413/head
YuviPanda 2025-01-28 19:00:09 -08:00
rodzic dd097a229a
commit d0d87c8c7c
1 zmienionych plików z 33 dodań i 19 usunięć

Wyświetl plik

@ -2,12 +2,19 @@
Docker container engine for repo2docker Docker container engine for repo2docker
""" """
import subprocess
import tarfile
import tempfile
from queue import Empty, Queue
from threading import Thread
from iso8601 import parse_date from iso8601 import parse_date
from traitlets import Dict from traitlets import Dict
import docker import docker
from .engine import Container, ContainerEngine, ContainerEngineException, Image from .engine import Container, ContainerEngine, ContainerEngineException, Image
from .utils import execute_cmd
class DockerContainer(Container): class DockerContainer(Container):
@ -53,7 +60,7 @@ class DockerEngine(ContainerEngine):
https://docker-py.readthedocs.io/en/4.2.0/api.html#module-docker.api.build https://docker-py.readthedocs.io/en/4.2.0/api.html#module-docker.api.build
""" """
string_output = False string_output = True
extra_init_args = Dict( extra_init_args = Dict(
{}, {},
@ -82,8 +89,8 @@ class DockerEngine(ContainerEngine):
def build( def build(
self, self,
*, *,
buildargs=None, buildargs: dict | None = None,
cache_from=None, cache_from: list[str] | None = None,
container_limits=None, container_limits=None,
tag="", tag="",
custom_context=False, custom_context=False,
@ -94,22 +101,29 @@ class DockerEngine(ContainerEngine):
platform=None, platform=None,
**kwargs, **kwargs,
): ):
return self._apiclient.build( args = ["docker", "buildx", "build", "--progress", "plain"]
buildargs=buildargs, if buildargs:
cache_from=cache_from, for k, v in buildargs.items():
container_limits=container_limits, args += ["--build-arg", f"{k}={v}"]
forcerm=True,
rm=True, if cache_from:
tag=tag, for cf in cache_from:
custom_context=custom_context, args += ["--cache-from", cf]
decode=True,
dockerfile=dockerfile, if dockerfile:
fileobj=fileobj, args += ["--file", dockerfile]
path=path,
labels=labels, if tag:
platform=platform, args += ["--tag", tag]
**kwargs,
) if fileobj:
with tempfile.TemporaryDirectory() as d:
tarf = tarfile.open(fileobj=fileobj)
tarf.extractall(d)
args += [d]
yield from execute_cmd(args, True)
def images(self): def images(self):
images = self._apiclient.images() images = self._apiclient.images()