From 32dd6ae4af0246a13f25e147b240052a82ecfe4e Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sat, 10 Sep 2022 03:23:39 +0200 Subject: [PATCH 1/7] build: refactor and move hello build page to building section Signed-off-by: CrazyMax --- _data/toc.yaml | 6 +- build/building/packaging.md | 213 ++++++++++++++++++++++++++++++++++++ build/hellobuild.md | 155 -------------------------- build/index.md | 2 +- 4 files changed, 218 insertions(+), 158 deletions(-) create mode 100644 build/building/packaging.md delete mode 100644 build/hellobuild.md diff --git a/_data/toc.yaml b/_data/toc.yaml index a9a74e5b8563..0d56ba1ef5cf 100644 --- a/_data/toc.yaml +++ b/_data/toc.yaml @@ -1389,8 +1389,10 @@ manuals: section: - path: /build/ title: Overview - - path: /build/hellobuild/ - title: Hello Build + - sectiontitle: Building images + section: + - path: /build/building/packaging/ + title: Packaging your software - sectiontitle: Buildx section: - path: /build/buildx/ diff --git a/build/building/packaging.md b/build/building/packaging.md new file mode 100644 index 000000000000..6205b023b5c9 --- /dev/null +++ b/build/building/packaging.md @@ -0,0 +1,213 @@ +--- +title: Packaging your software +keywords: build, buildx, buildkit, getting started, dockerfile +redirect_from: +- /build/hellobuild/ +--- + +## Dockerfile + +It all starts with a Dockerfile. + +Docker builds images by reading the instructions from a Dockerfile. This is a +text file containing instructions that adhere to a specific format needed to +assemble your application into a container image and for which you can find +its specification reference in the [Dockerfile reference](../../engine/reference/builder.md). + +Here are the most common types of instructions: + +| Instruction | Description | +|--------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [`FROM `](../../engine/reference/builder.md#from) | Defines a base for your image. | +| [`RUN `](../../engine/reference/builder.md#run) | Executes any commands in a new layer on top of the current image and commits the result. `RUN` also has a shell form for running commands. | +| [`WORKDIR `](../../engine/reference/builder.md#workdir) | Sets the working directory for any `RUN`, `CMD`, `ENTRYPOINT`, `COPY`, and `ADD` instructions that follow it in the Dockerfile. | +| [`COPY `](../../engine/reference/builder.md#copy) | Copies new files or directories from `` and adds them to the filesystem of the container at the path ``. | +| [`CMD `](../../engine/reference/builder.md#cmd) | Lets you define the default program that is run once you start the container based on this image. Each Dockerfile only has one `CMD`, and only the last `CMD` instance is respected when multiple exist. | + +Dockerfiles are crucial inputs for image builds and can facilitate automated, +multi-layer image builds based on your unique configurations. Dockerfiles can +start simple and grow with your needs and support images that require complex +instructions. For all the possible instructions, see the [Dockerfile reference](../../engine/reference/builder.md). + +Docker images consist of **read-only layers**, each resulting from an +instruction in the Dockerfile. Layers are stacked sequentially and each one is +a delta representing the changes applied to the previous layer. + +## Example + +Here's a simple Dockerfile example to get you started with building images. +We'll take a simple "Hello World" Python Flask application, and bundle it into +a Docker image that can test locally or deploy anywhere! + +Let's say we have a `hello.py` file with the following content: + +```python +from flask import Flask +app = Flask(__name__) + +@app.route("/") +def hello(): + return "Hello World!" +``` + +Don't worry about understanding the full example if you're not familiar with +Python, it's just a simple web server that will contain a single page that +says "Hello World". + +> **Note** +> +> If you test the example, make sure to copy over the indentation as well! For +> more information about this sample Flask application, check the +> [Flask Quickstart](https://flask.palletsprojects.com/en/2.1.x/quickstart/){:target="_blank" rel="noopener" class="_"} +> page. + +Here's the Dockerfile that will be used to create an image for our application: + +```dockerfile +# syntax=docker/dockerfile:1 +FROM ubuntu:22.04 + +# install app dependencies +RUN apt-get update && apt-get install -y python3 python3-pip +RUN pip install flask==2.1.* + +# install app +COPY hello.py / + +# final configuration +ENV FLASK_APP=hello +EXPOSE 8000 +CMD flask run --host 0.0.0.0 --port 8000 +``` + +We start by specifying the [syntax directive](../../engine/reference/builder.md#syntax). +It pins the exact version of the Dockerfile syntax we're using: + +```dockerfile +# syntax=docker/dockerfile:1 +``` + +As a [best practice](../../develop/dev-best-practices.md), this should be the +very first line in all our Dockerfiles as it informs BuildKit the right version +of the Dockerfile to use. + +Next we define the first instruction: + +```dockerfile +FROM ubuntu:22.04 +``` + +Here the [`FROM` instruction](../../engine/reference/builder.md#from) sets our +base image to the 22.04 release of Ubuntu. All following instructions are +executed on this base image, in this case, an Ubuntu environment. The notation +`ubuntu:22:04`, follows the `name:tag` standard for naming docker images. When +you build your image you use this notation to name your images and use it to +specify any existing Docker image. There are many public images you can +leverage in your projects. Explore [Docker Hub](https://hub.docker.com/search?image_filter=official&q=&type=image){:target="_blank" rel="noopener" class="_"} +to find out. + +```dockerfile +# install app dependencies +RUN apt-get update && apt-get install -y python3 python3-pip +``` + +This [`RUN` instruction](../../engine/reference/builder.md#run) executes a shell +command in the build context. A build's context is the set of files located in +the specified PATH or URL. + +In this example, our context is a full Ubuntu operating system, so we have +access to its package manager, apt. The provided commands update our package +lists and then, after that succeeds, installs `python3` and `pip`, the package +manager for Python. + +Also note `# install app dependencies` line. This is a comment. Comments in +Dockerfiles begin with the `#` symbol. As your Dockerfile evolves, comments can +be instrumental to document how your dockerfile works for any future readers +and editors of the file. + +> **Note** +> +> Starting your Dockerfile by a `#` like regular comments is treated as a +> directive when you are using BuildKit (default), otherwise it is ignored. + +```dockerfile +RUN pip install flask==2.1.* +``` + +This second `RUN` instruction requires that we've installed pip in the layer +before. After applying the previous directive, we can use the pip command to +install the flask web framework. This is the framework we've used to write +our basic "Hello World" application from above, so to run it in Docker, we'll +need to make sure it's installed. + +```dockerfile +COPY hello.py / +``` + +Now we use the [`COPY` instruction](../../engine/reference/builder.md#copy) to +copy our `hello.py` file from the local build context into the root directory +of our image. After being executed, we'll end up with a file called `/hello.py` +inside the image. + +```dockerfile +ENV FLASK_APP=hello +``` + +This [`ENV` instruction](../../engine/reference/builder.md#env) sets a Linux +environment variable we'll need later. This is a flask-specific variable, +that configures the command later used to run our `hello.py` application. +Without this, flask wouldn't know where to find our application to be able to +run it. + +```dockerfile +EXPOSE 8000 +``` + +This [`EXPOSE` instruction](../../engine/reference/builder.md#expose) marks that +our final image has a service listening on port `8000`. This isn't required, +but it is a good practice, as users and tools can use this to understand what +your image does. + +```dockerfile +CMD flask run --host 0.0.0.0 --port 8000 +``` + +Finally, [`CMD` instruction](../../engine/reference/builder.md#cmd) sets the +command that is run when the user starts a container based on this image. In +this case we'll start the flask development server listening on all addresses +on port `8000`. + +## Testing + +To test our Dockerfile, we'll first build it using the [`docker build` command](../../engine/reference/commandline/build.md): + +```console +$ docker build -t test:latest . +``` + +* `-t test:latest` option specifies the name (required) and tag (optional) of + the image we're building. +* `.` specifies the build context as the current directory. In this example, + this is where build expects to find the Dockerfile and the local files the + Dockerfile needs to access, in this case your python application. + +So, in accordance with the build command issued and how build context works, +your Dockerfile and python app need to be in the same directory. + +Now run your newly built image: + +```console +$ docker run -p 8000:8000 test:latest +``` + +From your computer, open a browser and navigate to `http://localhost:8000` + +> **Note** +> +> You can also build and run using [Play with Docker](https://labs.play-with-docker.com){:target="_blank" rel="noopener" class="_"} +> that provides you with a temporary Docker instance in the cloud. + +## Other resources + +If you are interested in examples in other languages, such as Go, check out +our [language-specific guides](../../language/index.md) in the Guides section. diff --git a/build/hellobuild.md b/build/hellobuild.md deleted file mode 100644 index c516317792bb..000000000000 --- a/build/hellobuild.md +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: Hello Build -description: Build Hello World -keywords: build, buildx, buildkit, getting started, dockerfile, image layers, build instructions, build context ---- - -## Hello Build! - -It all starts with a Dockerfile. - -Dockerfiles are text files containing instructions. Dockerfiles adhere to a specific format and contain a **set of instructions** for which you can find a full reference in the [Dockerfile reference](../../engine/reference/builder). -Docker builds images by reading the instructions from a Dockerfile. - -Docker images consist of **read-only layers**, each resulting from an instruction in the Dockerfile. Layers are stacked sequentially and each one is a delta representing the changes applied to the previous layer. - -## Dockerfile basics - -A Dockerfile is a text file containing all necessary instructions needed to assemble your application into a Docker container image. - -Here are the most common types of instructions: - -* [**FROM \**](../../engine/reference/builder/#from) - defines a base for your image. -* [**RUN \**](../../engine/reference/builder/#run) - executes any commands in a new layer on top of the current image and commits the result. - RUN also has a shell form for running commands. -* [**WORKDIR \**](../../engine/reference/builder/#workdir) - sets the working directory for any RUN, CMD, ENTRYPOINT, COPY, and ADD instructions that follow it in the Dockerfile. -* [**COPY \ \**](../../engine/reference/builder/#copy) - copies new files or directories from `` and adds them to the filesystem of the container at the path ``. -* [**CMD \**](../../engine/reference/builder/#cmd) - lets you define the default program that is run once you start the container based on this image. -Each Dockerfile only has one CMD, and only the last CMD instance is respected when multiple exist. - -Dockerfiles are crucial inputs for image builds and can facilitate automated, multi-layer image builds based on your unique configurations. Dockerfiles can start simple and grow with your needs and support images that require complex instructions. -For all the possible instructions, see the [Dockerfile reference](../../engine/reference/builder/). - -## Example -Here’s a simple Dockerfile example to get you started with building images. We’ll take a simple "Hello World" Python Flask application, and bundle it into a Docker image that we can test locally or deploy anywhere! - -**Sample A** -Let’s say we have the following in a `hello.py` file in our local directory: - -```python -from flask import Flask -app = Flask(__name__) - -@app.route("/") -def hello(): - return "Hello World!" -``` - -Don’t worry about understanding the full example if you’re not familiar with Python - it’s just a simple web server that will contain a single page that says “Hello World”. - -> **Note** -> -> If you test the example, make sure to copy over the indentation as well! For more information about this sample Flask application, check the [Flask Quickstart](https://flask.palletsprojects.com/en/2.1.x/quickstart/){:target="_blank" rel="noopener" class="_"} page. - - -**Sample B** -Here’s a Dockerfile that Docker Build can use to create an image for our application: - -```dockerfile -# syntax=docker/dockerfile:1 -FROM ubuntu:22.04 - -# install app dependencies -RUN apt-get update && apt-get install -y python3 python3-pip -RUN pip install flask==2.1.* - -# install app -COPY hello.py / - -# final configuration -ENV FLASK_APP=hello -EXPOSE 8000 -CMD flask run --host 0.0.0.0 --port 8000 -``` - -* `# syntax=docker/dockerfile:1` - - This is our syntax directive. It pins the exact version of the dockerfile syntax we’re using. As a [best practice](../../develop/dev-best-practices/), this should be the very first line in all our Dockerfiles as it informs Buildkit the right version of the Dockerfile to use. - See also [Syntax](../../engine/reference/builder/#syntax). - - > **Note** - > - > Initiated by a `#` like regular comments, this line is treated as a directive when you are using BuildKit (default), otherwise it is ignored. - - -* `FROM ubuntu:22.04` - - Here the `FROM` instruction sets our base image to the 22.04 release of Ubuntu. All following instructions are executed on this base image, in this case, a Ubuntu environment. - The notation `ubuntu:22:04`, follows the `name:tag` standard for naming docker images. - When you build your image you use this notation to name your images and use it to specify any existing Docker image. - There are many public images you can leverage in your projects. - Explore [Docker Hub](https://hub.docker.com/search?image_filter=official&q=&type=image){:target="_blank" rel="noopener" class="_"} to find out. - -* `# install app dependencies` - - Comments in dockerfiles begin with the `#` symbol. - As your Dockerfile evolves, comments can be instrumental to document how your dockerfile works for any future readers and editors of the file. - See also the [FROM instruction](../../engine/reference/builder/#from) page in the Dockerfile reference. - -* `RUN apt-get update && apt-get install -y python3 python3-pip` - - This `RUN` instruction executes a shell command in the build context. A build's context is the set of files located in the specified PATH or URL. In this example, our context is a full Ubuntu operating system, so we have access to its package manager, apt. The provided commands update our package lists and then, after that succeeds, installs python3 and pip, the package manager for Python. - See also the [RUN instruction](../../engine/reference/builder/#run) page in the Dockerfile reference. - -* `RUN pip install flask` - - This second `RUN` instruction requires that we’ve installed pip in the layer before. After applying the previous directive, we can use the pip command to install the flask web framework. This is the framework we’ve used to write our basic “Hello World” application from above, so to run it in Docker, we’ll need to make sure it’s installed. - See also the [RUN instruction](../../engine/reference/builder/#run) page in the Dockerfile reference. - -* `COPY hello.py /` - - This COPY instruction copies our `hello.py` file from the build’s context local directory into the root directory of our image. After this executes, we’ll end up with a file called `/hello.py` inside the image, with all the content of our local copy! - See also the [COPY instruction](../../engine/reference/builder/#copy) page in the Dockerfile reference. - - -* `ENV FLASK_APP=hello` - - This ENV instruction sets a Linux environment variable we’ll need later. This is a flask-specific variable, that configures the command later used to run our `hello.py` application. Without this, flask wouldn’t know where to find our application to be able to run it. - See also the [ENV instruction](../../engine/reference/builder/#env) page in the Dockerfile reference. - - -* `EXPOSE 8000` - - This EXPOSE instruction marks that our final image has a service listening on port 8000. This isn’t required, but it is a good practice, as users and tools can use this to understand what your image does. - See also the [EXPOSE instruction](../../engine/reference/builder/#expose) page in the Dockerfile reference. - -* `CMD flask run --host 0.0.0.0 --port 8000` - - This CMD instruction sets the command that is run when the user starts a container based on this image. In this case we’ll start the flask development server listening on all hosts on port 8000. - [CMD instruction](../../engine/reference/builder/#cmd) page in the Dockerfile reference. - -## Test the example - -Go ahead and try this example in your local Docker installation or you can use [Play with Docker](https://labs.play-with-docker.com){:target="_blank" rel="noopener" class="_"} that provides you with a temporary Docker instance on the cloud. - -To test this example: - -1. Create a file hello.py with the content of sample A. - -2. Create a file named Dockerfile without an extension with the contents of sample B. - -3. From your Docker instance build it with `docker build -t test:latest .` - - Breaking down the docker build command: - * **`-t test:latest`** option specifies the name (required) and tag (optional) of the image we’re building. - * **`.`** specifies the build context as the current directory. In this example, this is where build expects to find the Dockerfile and the local files the Dockerfile needs to access, in this case your python application. - - So, in accordance with the build command issued and how build context works, your Dockerfile and python app need to be on the same directory. - -4. Run your newly built image with `docker run -p 8000:8000 test:latest` - - From your computer, open a browser and navigate to `http://localhost:8000` or, if you’re using [Play with Docker](https://labs.play-with-docker.com){:target="_blank" rel="noopener" class="_"}, click on Open Port. - -## Other resources - -If you are interested in examples in other languages, such as GO, check out our [language-specific guides](../../language) in the Guides section. diff --git a/build/index.md b/build/index.md index 085349c41f41..14c97acaa847 100644 --- a/build/index.md +++ b/build/index.md @@ -37,7 +37,7 @@ Here’s an overview of all the use cases with which Build can support you: * **Packaging your software** Bundle and package your code to run anywhere, from your local Docker Desktop, to Docker Engine and Kubernetes on the cloud. -To get started with Build, see the [Hello Build](hellobuild.md) page. +To get started with Build, see the [Packaging your software](building/packaging.md) page. * **Choosing a build driver** Run Buildx with different configurations depending on the scenario you are From 609da7feb3a69e95078f6d6005a348e38fedd205 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sat, 10 Sep 2022 13:13:16 +0200 Subject: [PATCH 2/7] build: refresh overview page Signed-off-by: CrazyMax --- build/index.md | 95 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/build/index.md b/build/index.md index 14c97acaa847..abcabd8fa1d4 100644 --- a/build/index.md +++ b/build/index.md @@ -4,18 +4,20 @@ description: Introduction and overview of Docker Build keywords: build, buildx, buildkit --- -Docker Build is one of Docker Engine’s most used features. Whenever you are +## Overview + +Docker Build is one of Docker Engine's most used features. Whenever you are creating an image you are using Docker Build. Build is a key part of your software development life cycle allowing you to package and bundle your code and ship it anywhere. Engine uses a client-server architecture and is composed of multiple components and tools. The most common method of executing a build is by issuing a -`docker build` command from the Docker CLI. The CLI sends the request to Docker -Engine which, in turn, executes your build. +[`docker build` command](../engine/reference/commandline/build.md). The CLI +sends the request to Docker Engine which, in turn, executes your build. -There are now two components in Engine that can be used to create the build. -Starting with the 18.09 release, Engine is shipped with [Moby BuildKit](https://github.com/moby/buildkit){:target="_blank" rel="noopener" class="_"}, +There are now two components in Engine that can be used to build an image. +Starting with the 18.09 release, Engine is shipped with Moby [BuildKit](https://github.com/moby/buildkit){:target="_blank" rel="noopener" class="_"}, the new component for executing your builds by default. With BuildKit, the new client [Docker Buildx](buildx/index.md), becomes @@ -28,56 +30,73 @@ and much improved functionality that can be powerful tools for improving your builds' performance or reusability of your Dockerfiles, and it also introduces support for complex scenarios. -## Docker Build features +Docker Build is way more than the `docker build` command and is not only about +packaging your code, it's a whole ecosystem of tools and features that support +you not only with common workflow tasks but also provides you with support for +more complex and advanced scenarios: + +## Building your images -Docker Build is way more than your `docker build` command and is not only about packaging your code, it’s a whole ecosystem of tools and features that support you not only with common workflow tasks but also provides you with support for more complex and advanced scenarios. -Here’s an overview of all the use cases with which Build can support you: +### Packaging your software -### Building your images +Bundle and package your code to run anywhere, from your local Docker Desktop, +to Docker Engine and Kubernetes on the cloud. To get started with Build, +see the [Packaging your software](building/packaging.md) page. -* **Packaging your software** -Bundle and package your code to run anywhere, from your local Docker Desktop, to Docker Engine and Kubernetes on the cloud. -To get started with Build, see the [Packaging your software](building/packaging.md) page. +### Choosing a build driver -* **Choosing a build driver** Run Buildx with different configurations depending on the scenario you are working on, regardless of whether you are using your local machine or a remote compute cluster, all from the comfort of your local working environment. For more information on drivers, see the [drivers guide](buildx/drivers/index.md). -* **Optimizing builds with cache management** -Improve build performance by using a persistent shared build cache to avoid repeating costly operations such as package installations, downloading files from the internet, or code build steps. +### Optimizing builds with cache management + +Improve build performance by using a persistent shared build cache to avoid +repeating costly operations such as package installations, downloading files +from the internet, or code build steps. + +### Creating build-once, run-anywhere with multi-platform builds + +Collaborate across platforms with one build artifact. See [Build multi-platform images](buildx/multiplatform-images.md). + +## Automating your builds -* **Creating build-once, run-anywhere with multi-platform builds** -Collaborate across platforms with one build artifact. -See [Build multi-platform images](buildx/multiplatform-images.md). +### Integrating with GitHub -### Automating your builds +Automate your image builds to run in GitHub actions using the official docker +build actions: -* **Integrating with GitHub** -Automate your image builds to run in GitHub actions using the official docker build actions. See: - * [GitHub Action to build and push Docker images with Buildx](https://github.com/docker/build-push-action). - * [GitHub Action to extract metadata from Git reference and GitHub events](https://github.com/docker/metadata-action/). +* [GitHub Action to build and push Docker images with Buildx](https://github.com/docker/build-push-action). +* [GitHub Action to extract metadata from Git reference and GitHub events](https://github.com/docker/metadata-action/). -* **Orchestrating builds across complex projects together** -Connect your builds together and easily parameterize your images using buildx bake. +### Orchestrating builds across complex projects together + +Connect your builds together and easily parameterize your images using buildx bake. See [High-level build options with Bake](bake/index.md). -### Customizing your Builds +## Customizing your Builds + +### Select your build output format + +Choose from a variety of available output formats, to export any artifact you +like from BuildKit, not just docker images. See [Set the export action for the build result](../engine/reference/commandline/buildx_build.md#output). + +### Managing build secrets + +Securely access protected repositories and resources at build time without +leaking data into the final build or the cache. -* **Select your build output format** -Choose from a variety of available output formats, to export any artifact you like from BuildKit, not just docker images. -See [Set the export action for the build result](../engine/reference/commandline/buildx_build.md/#output). +## Extending BuildKit -* **Managing build secrets** -Securely access protected repositories and resources at build time without leaking data into the final build or the cache. +### Custom syntax on Dockerfile -### Extending BuildKit +Use experimental versions of the Dockerfile frontend, or even just bring your +own to BuildKit using the power of custom frontends. See also the +[Syntax directive](../engine/reference/builder/#syntax). -* **Custom syntax on Dockerfile** -Use experimental versions of the Dockerfile frontend, or even just bring your own to BuildKit using the power of custom frontends. -See also the [Syntax directive](../engine/reference/builder/#syntax). +### Configure BuildKit -* **Configure BuildKit** -Take a deep dive into the internal BuildKit configuration to get the most out of your builds. -See also [`buildkitd.toml`](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md), the configuration file for `buildkitd`. +Take a deep dive into the internal BuildKit configuration to get the most out +of your builds. See also [`buildkitd.toml`](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md), +the configuration file for `buildkitd`. From 1c225b6b5b030bb9d3508ab608bbe00d22e1a777 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sat, 10 Sep 2022 13:21:41 +0200 Subject: [PATCH 3/7] build: move multi-platform page to building section Signed-off-by: CrazyMax --- _data/toc.yaml | 4 ++-- .../multiplatform-images.md => building/multi-platform.md} | 4 +++- build/index.md | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) rename build/{buildx/multiplatform-images.md => building/multi-platform.md} (97%) diff --git a/_data/toc.yaml b/_data/toc.yaml index 0d56ba1ef5cf..357f8b0b3904 100644 --- a/_data/toc.yaml +++ b/_data/toc.yaml @@ -1393,6 +1393,8 @@ manuals: section: - path: /build/building/packaging/ title: Packaging your software + - path: /build/building/multi-platform/ + title: Multi-platform images - sectiontitle: Buildx section: - path: /build/buildx/ @@ -1413,8 +1415,6 @@ manuals: title: Remote driver - path: /build/buildx/multiple-builders/ title: Using multiple builders - - path: /build/buildx/multiplatform-images/ - title: Building multi-platform images - sectiontitle: Bake section: - path: /build/bake/ diff --git a/build/buildx/multiplatform-images.md b/build/building/multi-platform.md similarity index 97% rename from build/buildx/multiplatform-images.md rename to build/building/multi-platform.md index 21fda31c31db..6a61bb0c895f 100644 --- a/build/buildx/multiplatform-images.md +++ b/build/building/multi-platform.md @@ -1,7 +1,9 @@ --- -title: Building multi-platform images +title: Multi-platform images description: Different strategies for building multi-platform images keywords: build, buildx, buildkit, multi-platform images +redirect_from: +- /build/buildx/multiplatform-images/ --- BuildKit is designed to work well for building for multiple platforms and not diff --git a/build/index.md b/build/index.md index abcabd8fa1d4..60ef0dcde6b8 100644 --- a/build/index.md +++ b/build/index.md @@ -58,7 +58,8 @@ from the internet, or code build steps. ### Creating build-once, run-anywhere with multi-platform builds -Collaborate across platforms with one build artifact. See [Build multi-platform images](buildx/multiplatform-images.md). +Collaborate across platforms with one build artifact. See +[Multi-platform images](building/multi-platform.md) page. ## Automating your builds From cf7f4366d85665631e22eb416040d00bc5ae430d Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sat, 10 Sep 2022 14:17:06 +0200 Subject: [PATCH 4/7] build: rework and merge multi-arch content Signed-off-by: CrazyMax --- _data/toc.yaml | 2 - build/building/multi-platform.md | 200 ++++++++++++++++++++++++++++++- desktop/multi-arch.md | 176 --------------------------- 3 files changed, 197 insertions(+), 181 deletions(-) delete mode 100644 desktop/multi-arch.md diff --git a/_data/toc.yaml b/_data/toc.yaml index 357f8b0b3904..93f046ae7d30 100644 --- a/_data/toc.yaml +++ b/_data/toc.yaml @@ -1179,8 +1179,6 @@ manuals: title: Known issues for Mac - sectiontitle: Additional resources section: - - path: /desktop/multi-arch/ - title: Multi-arch support - path: /desktop/kubernetes/ title: Deploy on Kubernetes - path: /desktop/backup-and-restore/ diff --git a/build/building/multi-platform.md b/build/building/multi-platform.md index 6a61bb0c895f..1d8a33630342 100644 --- a/build/building/multi-platform.md +++ b/build/building/multi-platform.md @@ -4,11 +4,33 @@ description: Different strategies for building multi-platform images keywords: build, buildx, buildkit, multi-platform images redirect_from: - /build/buildx/multiplatform-images/ +- /docker-for-mac/multi-arch/ +- /mackit/multi-arch/ --- -BuildKit is designed to work well for building for multiple platforms and not -only for the architecture and operating system that the user invoking the build -happens to run. +Docker images can support multiple platforms, which means that a single image +may contain variants for different architectures, and sometimes for different +operating systems, such as Windows. + +When running an image with multi-platform support, `docker` automatically +selects the image that matches your OS and architecture. + +Most of the Docker Official Images on Docker Hub provide a [variety of architectures](https://github.com/docker-library/official-images#architectures-other-than-amd64){: target="_blank" rel="noopener" class="_" }. +For example, the `busybox` image supports `amd64`, `arm32v5`, `arm32v6`, +`arm32v7`, `arm64v8`, `i386`, `ppc64le`, and `s390x`. When running this image +on an `x86_64` / `amd64` machine, the `amd64` variant is pulled and run. + +## Building multi-platform images + +Docker is now making it easier than ever to develop containers on, and for Arm +servers and devices. Using the standard Docker tooling and processes, you can +start to build, push, pull, and run images seamlessly on different compute +architectures. In most cases, you don't have to make any changes to Dockerfiles +or source code to start building for Arm. + +BuildKit with [Buildx](../buildx/index.md) is designed to work well for +building for multiple platforms and not only for the architecture and +operating system that the user invoking the build happens to run. When you invoke a build, you can set the `--platform` flag to specify the target platform for the build output, (for example, `linux/amd64`, `linux/arm64`, or @@ -79,3 +101,175 @@ RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log FROM alpine COPY --from=build /log /log ``` + +## Getting started + +Run the [`docker buildx ls` command](../../engine/reference/commandline/buildx_ls.md) +to list the existing builders: + +```console +$ docker buildx ls +NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS +default * docker + default default running 20.10.17 linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6 +``` + +This displays the default builtin driver, that uses the BuildKit server +components built directly into the docker engine, also known as the [`docker` driver](../buildx/drivers/docker.md). + +Create a new builder using the [`docker-container` driver](../buildx/drivers/docker-container.md) +which gives you access to more complex features like multi-platform builds +and the more advanced cache exporters, which are currently unsupported in the +default `docker` driver: + +```console +$ docker buildx create --name mybuilder --driver docker-container --bootstrap +mybuilder +``` + +Switch to the new builder and inspect it: + +```console +$ docker buildx use mybuilder +``` + +> **Note** +> +> Alternatively, run `docker buildx create --name mybuilder --driver docker-container --bootstrap --use` +> to create a new builder and switch to it using a single command. + +And inspect it: + +```console +$ docker buildx inspect +Name: mybuilder +Driver: docker-container + +Nodes: +Name: mybuilder0 +Endpoint: unix:///var/run/docker.sock +Status: running +Buildkit: v0.10.4 +Platforms: linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6 +``` + +Now listing the existing builders again, we can see our new builder is +registered: + +```console +$ docker buildx ls +NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS +mybuilder docker-container + mybuilder0 unix:///var/run/docker.sock running v0.10.4 linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6 +default * docker + default default running 20.10.17 linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6 +``` + +## Example + +Test the workflow to ensure you can build, push, and run multi-platform images. +Create a simple example Dockerfile, build a couple of image variants, and push +them to Docker Hub. + +The following example uses a single `Dockerfile` to build an Alpine image with +cURL installed for multiple architectures: + +```dockerfile +# syntax=docker/dockerfile:1 +FROM alpine:3.16 +RUN apk add curl +``` + +Build the Dockerfile with buildx, passing the list of architectures to +build for: + +```console +$ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t /:latest --push . +... +#16 exporting to image +#16 exporting layers +#16 exporting layers 0.5s done +#16 exporting manifest sha256:71d7ecf3cd12d9a99e73ef448bf63ae12751fe3a436a007cb0969f0dc4184c8c 0.0s done +#16 exporting config sha256:a26f329a501da9e07dd9cffd9623e49229c3bb67939775f936a0eb3059a3d045 0.0s done +#16 exporting manifest sha256:5ba4ceea65579fdd1181dfa103cc437d8e19d87239683cf5040e633211387ccf 0.0s done +#16 exporting config sha256:9fcc6de03066ac1482b830d5dd7395da781bb69fe8f9873e7f9b456d29a9517c 0.0s done +#16 exporting manifest sha256:29666fb23261b1f77ca284b69f9212d69fe5b517392dbdd4870391b7defcc116 0.0s done +#16 exporting config sha256:92cbd688027227473d76e705c32f2abc18569c5cfabd00addd2071e91473b2e4 0.0s done +#16 exporting manifest list sha256:f3b552e65508d9203b46db507bb121f1b644e53a22f851185d8e53d873417c48 0.0s done +#16 ... + +#17 [auth] /:pull,push token for registry-1.docker.io +#17 DONE 0.0s + +#16 exporting to image +#16 pushing layers +#16 pushing layers 3.6s done +#16 pushing manifest for docker.io//:latest@sha256:f3b552e65508d9203b46db507bb121f1b644e53a22f851185d8e53d873417c48 +#16 pushing manifest for docker.io//:latest@sha256:f3b552e65508d9203b46db507bb121f1b644e53a22f851185d8e53d873417c48 1.4s done +#16 DONE 5.6s +``` + +> **Note** +> +> * `` must be a valid Docker ID and `` and valid repository on +> Docker Hub. +> * The `--platform` flag informs buildx to create Linux images for AMD 64-bit, +> Arm 64-bit, and Armv7 architectures. +> * The `--push` flag generates a multi-arch manifest and pushes all the images +> to Docker Hub. + +Inspect the image using [`docker buildx imagetools` command](../../engine/reference/commandline/buildx_imagetools.md): + +```console +$ docker buildx imagetools inspect /:latest +Name: docker.io//:latest +MediaType: application/vnd.docker.distribution.manifest.list.v2+json +Digest: sha256:f3b552e65508d9203b46db507bb121f1b644e53a22f851185d8e53d873417c48 + +Manifests: + Name: docker.io//:latest@sha256:71d7ecf3cd12d9a99e73ef448bf63ae12751fe3a436a007cb0969f0dc4184c8c + MediaType: application/vnd.docker.distribution.manifest.v2+json + Platform: linux/amd64 + + Name: docker.io//:latest@sha256:5ba4ceea65579fdd1181dfa103cc437d8e19d87239683cf5040e633211387ccf + MediaType: application/vnd.docker.distribution.manifest.v2+json + Platform: linux/arm64 + + Name: docker.io//:latest@sha256:29666fb23261b1f77ca284b69f9212d69fe5b517392dbdd4870391b7defcc116 + MediaType: application/vnd.docker.distribution.manifest.v2+json + Platform: linux/arm/v7 +``` + +The image is now available on Docker Hub with the tag `/:latest`. +You can use this image to run a container on Intel laptops, Amazon EC2 Graviton +instances, Raspberry Pis, and on other architectures. Docker pulls the correct +image for the current architecture, so Raspberry PIs run the 32-bit Arm version +and EC2 Graviton instances run 64-bit Arm. + +The digest identifies a fully qualified image variant. You can also run images +targeted for a different architecture on Docker Desktop. For example, when +you run the following on a macOS: + + ```console +$ docker run --rm docker.io//:latest@sha256:2b77acdfea5dc5baa489ffab2a0b4a387666d1d526490e31845eb64e3e73ed20 uname -m +aarch64 +``` + +```console +$ docker run --rm docker.io//:latest@sha256:723c22f366ae44e419d12706453a544ae92711ae52f510e226f6467d8228d191 uname -m +armv7l +``` + +In the above example, `uname -m` returns `aarch64` and `armv7l` as expected, +even when running the commands on a native macOS or Windows developer machine. + +## Support on Docker Desktop + +[Docker Desktop](../../desktop/index.md) provides `binfmt_misc` +multi-architecture support, which means you can run containers for different +Linux architectures such as `arm`, `mips`, `ppc64le`, and even `s390x`. + +This does not require any special configuration in the container itself as it +uses [qemu-static](https://wiki.qemu.org/Main_Page){: target="_blank" rel="noopener" class="_" } +from the **Docker for Mac VM**. Because of this, you can run an ARM container, +like the `arm32v7` or `ppc64le` variants of the busybox image. diff --git a/desktop/multi-arch.md b/desktop/multi-arch.md deleted file mode 100644 index be27e8b5870d..000000000000 --- a/desktop/multi-arch.md +++ /dev/null @@ -1,176 +0,0 @@ ---- -description: Multi-CPU Architecture Support -keywords: mac, windows, Multi-CPU architecture support -redirect_from: -- /docker-for-mac/multi-arch/ -- /mackit/multi-arch/ -title: Leverage multi-CPU architecture support ---- - -Docker images can support multiple architectures, which means that a single -image may contain variants for different architectures, and sometimes for different -operating systems, such as Windows. - -When running an image with multi-architecture support, `docker` automatically -selects the image variant that matches your OS and architecture. - -Most of the Docker Official Images on Docker Hub provide a [variety of architectures](https://github.com/docker-library/official-images#architectures-other-than-amd64){: target="_blank" rel="noopener" class="_" }. -For example, the `busybox` image supports `amd64`, `arm32v5`, `arm32v6`, -`arm32v7`, `arm64v8`, `i386`, `ppc64le`, and `s390x`. When running this image -on an `x86_64` / `amd64` machine, the `amd64` variant is pulled and run. - -## Multi-arch support on Docker Desktop - -**Docker Desktop** provides `binfmt_misc` multi-architecture support, -which means you can run containers for different Linux architectures -such as `arm`, `mips`, `ppc64le`, and even `s390x`. - -This does not require any special configuration in the container itself as it uses -[qemu-static](https://wiki.qemu.org/Main_Page){: target="_blank" rel="noopener" class="_" } -from the **Docker for Mac VM**. Because of this, you can run an ARM container, -like the `arm32v7` or `ppc64le` variants of the busybox image. - -## Build multi-arch images with Buildx - -Docker is now making it easier than ever to develop containers on, and for Arm -servers and devices. Using the standard Docker tooling and processes, you can -start to build, push, pull, and run images seamlessly on different compute -architectures. In most cases, you don't have to make any changes to Dockerfiles -or source code to start building for Arm. - -Docker introduces a new CLI command called `buildx`. You can use the `buildx` -command on Docker Desktop for Mac and Windows to build multi-arch images, link -them together with a manifest file, and push them all to a registry using a -single command. With the included emulation, you can transparently build more -than just native images. Buildx accomplishes this by adding new builder -instances based on BuildKit, and leveraging Docker Desktop's technology stack -to run non-native binaries. - -For more information about the Buildx CLI command, see [Buildx](../build/buildx/index.md) -and the [`docker buildx` command line reference](../engine/reference/commandline/buildx.md). - -### Build and run multi-architecture images - -Run the `docker buildx ls` command to list the existing builders. This displays -the default builder, which is our old builder. - -```console -$ docker buildx ls - -NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS -default * docker - default default running linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6 -``` - -Create a new builder which gives access to the new multi-architecture features. - -```console -$ docker buildx create --name mybuilder - -mybuilder -``` - -Alternatively, run `docker buildx create --name mybuilder --use` to create a new -builder and switch to it using a single command. - -Switch to the new builder and inspect it. - -```console -$ docker buildx use mybuilder - -$ docker buildx inspect --bootstrap - -[+] Building 2.5s (1/1) FINISHED - => [internal] booting buildkit 2.5s - => => pulling image moby/buildkit:master 1.3s - => => creating container buildx_buildkit_mybuilder0 1.2s -Name: mybuilder -Driver: docker-container - -Nodes: -Name: mybuilder0 -Endpoint: unix:///var/run/docker.sock -Status: running - -Platforms: linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v6 -``` - -Test the workflow to ensure you can build, push, and run multi-architecture -images. Create a simple example Dockerfile, build a couple of image variants, -and push them to Docker Hub. - -The following example uses a single `Dockerfile` to build an Ubuntu image with cURL -installed for multiple architectures. - -Create a `Dockerfile` with the following: - -```dockerfile -FROM ubuntu:20.04 -RUN apt-get update && apt-get install -y curl -``` - -Build the Dockerfile with buildx, passing the list of architectures to build for: - -```console -$ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t username/demo:latest --push . - -[+] Building 6.9s (19/19) FINISHED -... - => => pushing layers 2.7s - => => pushing manifest for docker.io/username/demo:latest 2.2 -``` - -Where, `username` is a valid Docker username. - -> **Notes:** -> -> - The `--platform` flag informs buildx to generate Linux images for AMD 64-bit, -> Arm 64-bit, and Armv7 architectures. -> - The `--push` flag generates a multi-arch manifest and pushes all the images -> to Docker Hub. - -Inspect the image using `docker buildx imagetools`. - -```console -$ docker buildx imagetools inspect username/demo:latest - -Name: docker.io/username/demo:latest -MediaType: application/vnd.docker.distribution.manifest.list.v2+json -Digest: sha256:2a2769e4a50db6ac4fa39cf7fb300fa26680aba6ae30f241bb3b6225858eab76 - -Manifests: - Name: docker.io/username/demo:latest@sha256:8f77afbf7c1268aab1ee7f6ce169bb0d96b86f585587d259583a10d5cd56edca - MediaType: application/vnd.docker.distribution.manifest.v2+json - Platform: linux/amd64 - - Name: docker.io/username/demo:latest@sha256:2b77acdfea5dc5baa489ffab2a0b4a387666d1d526490e31845eb64e3e73ed20 - MediaType: application/vnd.docker.distribution.manifest.v2+json - Platform: linux/arm64 - - Name: docker.io/username/demo:latest@sha256:723c22f366ae44e419d12706453a544ae92711ae52f510e226f6467d8228d191 - MediaType: application/vnd.docker.distribution.manifest.v2+json - Platform: linux/arm/v7 -``` - -The image is now available on Docker Hub with the tag `username/demo:latest`. You -can use this image to run a container on Intel laptops, Amazon EC2 Graviton instances, -Raspberry Pis, and on other architectures. Docker pulls the correct image for the -current architecture, so Raspberry Pis run the 32-bit Arm version and EC2 Graviton -instances run 64-bit Arm. The SHA tags identify a fully qualified image variant. -You can also run images targeted for a different architecture on Docker Desktop. - -You can run the images using the SHA tag, and verify the architecture. For -example, when you run the following on a macOS: - - ```console -$ docker run --rm docker.io/username/demo:latest@sha256:2b77acdfea5dc5baa489ffab2a0b4a387666d1d526490e31845eb64e3e73ed20 uname -m -aarch64 -``` - -```console -$ docker run --rm docker.io/username/demo:latest@sha256:723c22f366ae44e419d12706453a544ae92711ae52f510e226f6467d8228d191 uname -m -armv7l -``` - -In the above example, `uname -m` returns `aarch64` and `armv7l` as expected, -even when running the commands on a native macOS or Windows developer machine. From 8349c857bfa2d52999fbbd267c2a10fac936db16 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Sat, 10 Sep 2022 20:13:27 +0200 Subject: [PATCH 5/7] extension(multi-arch): refactor and cross link to multi-platform page Signed-off-by: CrazyMax --- .../images/hub-multi-arch-extension.png | Bin 53901 -> 0 bytes .../extensions-sdk/extensions/multi-arch.md | 45 +++++++++++++----- 2 files changed, 34 insertions(+), 11 deletions(-) delete mode 100644 desktop/extensions-sdk/extensions/images/hub-multi-arch-extension.png diff --git a/desktop/extensions-sdk/extensions/images/hub-multi-arch-extension.png b/desktop/extensions-sdk/extensions/images/hub-multi-arch-extension.png deleted file mode 100644 index de7f6226cf9b4a479d7067688444e2a7acecb7b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53901 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 UwfC{FVdQ&MBb@06NChc>n+a diff --git a/desktop/extensions-sdk/extensions/multi-arch.md b/desktop/extensions-sdk/extensions/multi-arch.md index cc8d910b86d5..93a27f23f6ac 100644 --- a/desktop/extensions-sdk/extensions/multi-arch.md +++ b/desktop/extensions-sdk/extensions/multi-arch.md @@ -13,25 +13,48 @@ Docker Desktop retrieves the extension image according to the user’s system ar ### Build and push for multiple architectures -If you created an extension from the `docker extension init` command, the `Makefile` at the root of the directory includes a target with name `push-extension`. +If you created an extension from the `docker extension init` command, the +`Makefile` at the root of the directory includes a target with name +`push-extension`. -You can do `make push-extension` to build your extension against both `linux/amd64` and `linux/arm64` platforms, and push them to DockerHub. For example: +You can do `make push-extension` to build your extension against both +`linux/amd64` and `linux/arm64` platforms, and push them to DockerHub. -`docker buildx build --platform=linux/amd64,linux/arm64 -t .` - -Alternatively, if you started from an empty directory, use the command below to build your extension for multiple architectures: +For example: +```console +$ make push-extension ``` -docker buildx build \ - --push \ - --platform=linux/amd64,linux/arm64 \ - --tag=my-extension:0.0.1 . +Alternatively, if you started from an empty directory, use the command below +to build your extension for multiple architectures: + +```console +$ docker buildx build --push --platform=linux/amd64,linux/arm64 --tag=username/my-extension:0.0.1 . ``` -The information above serves as a guide to help you get started. It’s up to you to define the CI/CD process to build and push the extension. +You can then check the image manifest to see if the image is available for both +architectures using the [`docker buildx imagetools` command](../../../engine/reference/commandline/buildx_imagetools.md): + +```console +$ docker buildx imagetools inspect username/my-extension:0.0.1 +Name: docker.io/username/my-extension:0.0.1 +MediaType: application/vnd.docker.distribution.manifest.list.v2+json +Digest: sha256:f3b552e65508d9203b46db507bb121f1b644e53a22f851185d8e53d873417c48 + +Manifests: + Name: docker.io/username/my-extension:0.0.1@sha256:71d7ecf3cd12d9a99e73ef448bf63ae12751fe3a436a007cb0969f0dc4184c8c + MediaType: application/vnd.docker.distribution.manifest.v2+json + Platform: linux/amd64 -![hub-multi-arch-extension](images/hub-multi-arch-extension.png) + Name: docker.io/username/my-extension:0.0.1@sha256:5ba4ceea65579fdd1181dfa103cc437d8e19d87239683cf5040e633211387ccf + MediaType: application/vnd.docker.distribution.manifest.v2+json + Platform: linux/arm64 +``` + +> **Note** +> +> For more information, see [Multi-platform images](../../../build/building/multi-platform.md) page. ### Adding multi-arch binaries From 0f544008aabfb3ac43dc5f3493ec6c2aa15f0b87 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Tue, 13 Sep 2022 21:04:41 +0200 Subject: [PATCH 6/7] build: merge buildx overview page to main overview Signed-off-by: CrazyMax --- _data/toc.yaml | 2 - build/building/multi-platform.md | 6 +-- build/buildx/index.md | 53 ------------------------ build/index.md | 28 ++++++++----- build/release-notes.md | 2 +- desktop/index.md | 2 +- desktop/previous-versions/2.x-mac.md | 2 +- desktop/previous-versions/2.x-windows.md | 2 +- 8 files changed, 25 insertions(+), 72 deletions(-) delete mode 100644 build/buildx/index.md diff --git a/_data/toc.yaml b/_data/toc.yaml index 93f046ae7d30..ee56208e0c39 100644 --- a/_data/toc.yaml +++ b/_data/toc.yaml @@ -1395,8 +1395,6 @@ manuals: title: Multi-platform images - sectiontitle: Buildx section: - - path: /build/buildx/ - title: Buildx overview - path: /build/buildx/install/ title: Install Buildx - sectiontitle: Drivers diff --git a/build/building/multi-platform.md b/build/building/multi-platform.md index 1d8a33630342..def51bef2183 100644 --- a/build/building/multi-platform.md +++ b/build/building/multi-platform.md @@ -28,9 +28,9 @@ start to build, push, pull, and run images seamlessly on different compute architectures. In most cases, you don't have to make any changes to Dockerfiles or source code to start building for Arm. -BuildKit with [Buildx](../buildx/index.md) is designed to work well for -building for multiple platforms and not only for the architecture and -operating system that the user invoking the build happens to run. +BuildKit with Buildx is designed to work well for building for multiple +platforms and not only for the architecture and operating system that the user +invoking the build happens to run. When you invoke a build, you can set the `--platform` flag to specify the target platform for the build output, (for example, `linux/amd64`, `linux/arm64`, or diff --git a/build/buildx/index.md b/build/buildx/index.md deleted file mode 100644 index 8b9ba0f110d1..000000000000 --- a/build/buildx/index.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Working with Buildx -description: Working with Docker Buildx -keywords: build, buildx, buildkit -redirect_from: -- /buildx/working-with-buildx/ ---- - -## Overview - -Docker Buildx is a CLI plugin that extends the docker command with the full -support of the features provided by [Moby BuildKit](https://github.com/moby/buildkit){:target="_blank" rel="noopener" class="_"} -builder toolkit. It provides the same user experience as docker build with many -new features like creating scoped builder instances and building against -multiple nodes concurrently. - -## Build with Buildx - -To start a new build, run the command `docker buildx build .` - -```console -$ docker buildx build . -[+] Building 8.4s (23/32) - => ... -``` - -Buildx builds using the BuildKit engine and does not require `DOCKER_BUILDKIT=1` -environment variable to start the builds. - -The [`docker buildx build` command](../../engine/reference/commandline/buildx_build.md) -supports features available for `docker build`, including features such as -outputs configuration, inline build caching, and specifying target platform. -In addition, Buildx also supports new features that are not yet available for -regular `docker build` like building manifest lists, distributed caching, and -exporting build results to OCI image tarballs. - -Buildx is flexible and can be run in different configurations that are exposed -through various "drivers". Each driver defines how and where a build should -run, and have different feature sets. - -We currently support the following drivers: - -* The `docker` driver ([guide](drivers/docker.md), [reference](/engine/reference/commandline/buildx_create/#driver)) -* The `docker-container` driver ([guide](drivers/docker-container.md), [reference](/engine/reference/commandline/buildx_create/#driver)) -* The `kubernetes` driver ([guide](drivers/kubernetes.md), [reference](/engine/reference/commandline/buildx_create/#driver)) -* The `remote` driver ([guide](drivers/remote.md)) - -For more information on drivers, see the [drivers guide](drivers/index.md). - -## High-level build options with Bake - -Check out our guide about [Bake](../bake/index.md) to get started with the -[`docker buildx bake` command](../../engine/reference/commandline/buildx_bake.md). diff --git a/build/index.md b/build/index.md index 60ef0dcde6b8..6392d34225d0 100644 --- a/build/index.md +++ b/build/index.md @@ -2,6 +2,8 @@ title: Overview of Docker Build description: Introduction and overview of Docker Build keywords: build, buildx, buildkit +redirect_from: +- /build/buildx/ --- ## Overview @@ -17,23 +19,29 @@ and tools. The most common method of executing a build is by issuing a sends the request to Docker Engine which, in turn, executes your build. There are now two components in Engine that can be used to build an image. -Starting with the 18.09 release, Engine is shipped with Moby [BuildKit](https://github.com/moby/buildkit){:target="_blank" rel="noopener" class="_"}, +Starting with the [18.09 release](../engine/release-notes/18.09.md#18090), Engine is +shipped with Moby [BuildKit](https://github.com/moby/buildkit){:target="_blank" rel="noopener" class="_"}, the new component for executing your builds by default. -With BuildKit, the new client [Docker Buildx](buildx/index.md), becomes -available as a CLI plugin. Docker Buildx extends the docker build command - -namely through the additional `docker buildx build` command - and fully -supports the new features BuildKit offers. - BuildKit is the backend evolution from the Legacy Builder, it comes with new and much improved functionality that can be powerful tools for improving your builds' performance or reusability of your Dockerfiles, and it also introduces support for complex scenarios. -Docker Build is way more than the `docker build` command and is not only about +The new client [Docker Buildx](https://github.com/docker/buildx){:target="_blank" rel="noopener" class="_"}, +is a CLI plugin that extends the docker command with the full support of the +features provided by BuildKit builder toolkit. `docker buildx build` provides +the same user experience as `docker build` with many new features like creating +scoped builder instances, building against multiple nodes concurrently, outputs +configuration, inline build caching, and specifying target platform. In +addition, Buildx also supports new features that are not yet available for +regular `docker build` like building manifest lists, distributed caching, and +exporting build results to OCI image tarballs. + +Docker Build is way more than a simple build command and is not only about packaging your code, it's a whole ecosystem of tools and features that support -you not only with common workflow tasks but also provides you with support for -more complex and advanced scenarios: +not only common workflow tasks but also provides support for more complex and +advanced scenarios: ## Building your images @@ -94,7 +102,7 @@ leaking data into the final build or the cache. Use experimental versions of the Dockerfile frontend, or even just bring your own to BuildKit using the power of custom frontends. See also the -[Syntax directive](../engine/reference/builder/#syntax). +[Syntax directive](../engine/reference/builder.md#syntax). ### Configure BuildKit diff --git a/build/release-notes.md b/build/release-notes.md index 5f88700dcf88..f2778f3d7ba4 100644 --- a/build/release-notes.md +++ b/build/release-notes.md @@ -6,7 +6,7 @@ toc_max: 2 --- This page contains information about the new features, improvements, and bug -fixes in [Buildx](buildx/index.md). +fixes in [Docker Buildx](https://github.com/docker/buildx){:target="_blank" rel="noopener" class="_"}. ## 0.9.1 diff --git a/desktop/index.md b/desktop/index.md index 649303038973..81fb69247625 100644 --- a/desktop/index.md +++ b/desktop/index.md @@ -45,7 +45,7 @@ It provides a simple interface that enables you to manage your containers, appli - [Docker Engine](../engine/index.md) - Docker CLI client -- [Docker Buildx](../build/buildx/index.md) +- [Docker Buildx](../build/index.md) - [Docker Compose](../compose/index.md) - [Docker Content Trust](../engine/security/trust/index.md) - [Kubernetes](https://github.com/kubernetes/kubernetes/) diff --git a/desktop/previous-versions/2.x-mac.md b/desktop/previous-versions/2.x-mac.md index a04e468abe7d..23c25d831cf3 100644 --- a/desktop/previous-versions/2.x-mac.md +++ b/desktop/previous-versions/2.x-mac.md @@ -435,7 +435,7 @@ Note that you must sign in and create a Docker ID in order to download Docker De Docker Desktop Community 2.1.0.0 contains the following experimental features. * Docker App: Docker App is a CLI plugin that helps configure, share, and install applications. For more information, see [Working with Docker App](/app/working-with-app/). -* Docker Buildx: Docker Buildx is a CLI plugin for extended build capabilities with BuildKit. For more information, see [Buildx component](../../build/buildx/index.md). +* Docker Buildx: Docker Buildx is a CLI plugin for extended build capabilities with BuildKit. For more information, see the [Build page](../../build/index.md). ### Bug fixes and minor changes diff --git a/desktop/previous-versions/2.x-windows.md b/desktop/previous-versions/2.x-windows.md index 4e84aa87c216..c3d296e9227f 100644 --- a/desktop/previous-versions/2.x-windows.md +++ b/desktop/previous-versions/2.x-windows.md @@ -557,7 +557,7 @@ Note that you must sign in and create a Docker ID in order to download Docker De Docker Desktop Community 2.1.0.0 contains the following experimental features: * Docker App: Docker App is a CLI plugin that helps configure, share, and install applications. For more information, see [Working with Docker App](/app/working-with-app/). -* Docker Buildx: Docker Buildx is a CLI plugin for extended build capabilities with BuildKit. For more information, see [Buildx component](../../build/buildx/index.md). +* Docker Buildx: Docker Buildx is a CLI plugin for extended build capabilities with BuildKit. For more information, see the [Build page](../../build/index.md). ### Bug fixes and minor changes From e25f937576bfa31914e8bbdc95b096f54b08aea6 Mon Sep 17 00:00:00 2001 From: CrazyMax Date: Tue, 13 Sep 2022 21:34:47 +0200 Subject: [PATCH 7/7] build: move drivers to building images section Signed-off-by: CrazyMax --- _config.yml | 2 +- _data/toc.yaml | 24 +++++++++---------- .../drivers/docker-container.md | 0 build/{buildx => building}/drivers/docker.md | 0 build/{buildx => building}/drivers/index.md | 2 +- .../drivers/kubernetes.md | 0 build/{buildx => building}/drivers/remote.md | 0 build/building/multi-platform.md | 4 ++-- build/index.md | 2 +- build/release-notes.md | 2 +- 10 files changed, 18 insertions(+), 18 deletions(-) rename build/{buildx => building}/drivers/docker-container.md (100%) rename build/{buildx => building}/drivers/docker.md (100%) rename build/{buildx => building}/drivers/index.md (80%) rename build/{buildx => building}/drivers/kubernetes.md (100%) rename build/{buildx => building}/drivers/remote.md (100%) diff --git a/_config.yml b/_config.yml index 00428041d53f..f0c33539ce76 100644 --- a/_config.yml +++ b/_config.yml @@ -168,7 +168,7 @@ fetch-remote: - dest: "build/bake" src: - "docs/guides/bake/**" - - dest: "build/buildx/drivers" + - dest: "build/building/drivers" src: - "docs/guides/drivers/**" diff --git a/_data/toc.yaml b/_data/toc.yaml index ee56208e0c39..bcadb58cfbf9 100644 --- a/_data/toc.yaml +++ b/_data/toc.yaml @@ -1391,24 +1391,24 @@ manuals: section: - path: /build/building/packaging/ title: Packaging your software - - path: /build/building/multi-platform/ - title: Multi-platform images - - sectiontitle: Buildx - section: - - path: /build/buildx/install/ - title: Install Buildx - - sectiontitle: Drivers + - sectiontitle: Choosing a build driver section: - - path: /build/buildx/drivers/ + - path: /build/building/drivers/ title: Overview - - path: /build/buildx/drivers/docker/ + - path: /build/building/drivers/docker/ title: Docker driver - - path: /build/buildx/drivers/docker-container/ + - path: /build/building/drivers/docker-container/ title: Docker container driver - - path: /build/buildx/drivers/kubernetes/ + - path: /build/building/drivers/kubernetes/ title: Kubernetes driver - - path: /build/buildx/drivers/remote/ + - path: /build/building/drivers/remote/ title: Remote driver + - path: /build/building/multi-platform/ + title: Multi-platform images + - sectiontitle: Buildx + section: + - path: /build/buildx/install/ + title: Install Buildx - path: /build/buildx/multiple-builders/ title: Using multiple builders - sectiontitle: Bake diff --git a/build/buildx/drivers/docker-container.md b/build/building/drivers/docker-container.md similarity index 100% rename from build/buildx/drivers/docker-container.md rename to build/building/drivers/docker-container.md diff --git a/build/buildx/drivers/docker.md b/build/building/drivers/docker.md similarity index 100% rename from build/buildx/drivers/docker.md rename to build/building/drivers/docker.md diff --git a/build/buildx/drivers/index.md b/build/building/drivers/index.md similarity index 80% rename from build/buildx/drivers/index.md rename to build/building/drivers/index.md index 0be093e09997..5e9f43edfa70 100644 --- a/build/buildx/drivers/index.md +++ b/build/building/drivers/index.md @@ -1,5 +1,5 @@ --- -title: "Buildx drivers overview" +title: "Drivers overview" keywords: build, buildx, driver, builder, docker-container, kubernetes, remote fetch_remote: line_start: 2 diff --git a/build/buildx/drivers/kubernetes.md b/build/building/drivers/kubernetes.md similarity index 100% rename from build/buildx/drivers/kubernetes.md rename to build/building/drivers/kubernetes.md diff --git a/build/buildx/drivers/remote.md b/build/building/drivers/remote.md similarity index 100% rename from build/buildx/drivers/remote.md rename to build/building/drivers/remote.md diff --git a/build/building/multi-platform.md b/build/building/multi-platform.md index def51bef2183..81f3fee93793 100644 --- a/build/building/multi-platform.md +++ b/build/building/multi-platform.md @@ -115,9 +115,9 @@ default * docker ``` This displays the default builtin driver, that uses the BuildKit server -components built directly into the docker engine, also known as the [`docker` driver](../buildx/drivers/docker.md). +components built directly into the docker engine, also known as the [`docker` driver](../building/drivers/docker.md). -Create a new builder using the [`docker-container` driver](../buildx/drivers/docker-container.md) +Create a new builder using the [`docker-container` driver](../building/drivers/docker-container.md) which gives you access to more complex features like multi-platform builds and the more advanced cache exporters, which are currently unsupported in the default `docker` driver: diff --git a/build/index.md b/build/index.md index 6392d34225d0..67edb7b3846e 100644 --- a/build/index.md +++ b/build/index.md @@ -56,7 +56,7 @@ see the [Packaging your software](building/packaging.md) page. Run Buildx with different configurations depending on the scenario you are working on, regardless of whether you are using your local machine or a remote compute cluster, all from the comfort of your local working environment. -For more information on drivers, see the [drivers guide](buildx/drivers/index.md). +For more information on drivers, see the [drivers guide](building/drivers/index.md). ### Optimizing builds with cache management diff --git a/build/release-notes.md b/build/release-notes.md index f2778f3d7ba4..53eb3c8873ef 100644 --- a/build/release-notes.md +++ b/build/release-notes.md @@ -29,7 +29,7 @@ For more details, see the complete release notes in the [Buildx GitHub repositor ### New features -* Support for new [driver `remote`](buildx/drivers/remote.md) that you can use +* Support for new [driver `remote`](building/drivers/remote.md) that you can use to connect to any already running BuildKit instance {% include github_issue.md repo="docker/buildx" number="1078" %} {% include github_issue.md repo="docker/buildx" number="1093" %} {% include github_issue.md repo="docker/buildx" number="1094" %} {% include github_issue.md repo="docker/buildx" number="1103" %} {% include github_issue.md repo="docker/buildx" number="1134" %}