mirror of https://github.com/docker/docs.git
Merge pull request #13692 from docker/master
Publish updates from master
This commit is contained in:
commit
6559a7323c
|
|
@ -14,6 +14,26 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- name: build image
|
||||
run: docker build --target=current -t documentation:latest .
|
||||
validate:
|
||||
name: validate links
|
||||
runs-on: ubuntu-18.04
|
||||
env:
|
||||
DOCKER_BUILDKIT: '1'
|
||||
steps:
|
||||
- name: print docker info
|
||||
run: docker version && docker info
|
||||
- uses: actions/checkout@v2
|
||||
- name: copy files to host
|
||||
run: docker build --target=deploy-source --output=./_site .
|
||||
- name: check for broken links
|
||||
uses: chabad360/htmlproofer@master
|
||||
with:
|
||||
directory: ./_site
|
||||
# for available options, refer to:
|
||||
# - https://github.com/gjtorikian/html-proofer
|
||||
# - https://github.com/gjtorikian/html-proofer/blob/main/bin/htmlproofer
|
||||
arguments: --disable-external --internal-domains="docs.docker.com,docs-stage.docker.com,localhost:4000" --file-ignore="/^./_site/engine/api/.*$/,./_site/registry/configuration/index.html" --url-ignore="/^/docker-hub/api/latest/.*$/,/^/engine/api/v.+/#.*$/,/^/glossary/.*$/"
|
||||
|
||||
# Disabled netlify-deploy due to flakey 502 http errors
|
||||
# - name: copy static files
|
||||
# if: github.event.pull_request.head.repo.fork == false
|
||||
|
|
|
|||
|
|
@ -580,7 +580,7 @@ examples: |-
|
|||
[related Dockerfile extensions](https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md#run---securityinsecuresandbox).
|
||||
|
||||
For entitlements to be enabled, the `buildkitd` daemon also needs to allow them
|
||||
with `--allow-insecure-entitlement` (see [`create --buildkitd-flags`](buildx_create.md#--buildkitd-flags-flags))
|
||||
with `--allow-insecure-entitlement` (see [`create --buildkitd-flags`](buildx_create.md#buildkitd-flags))
|
||||
|
||||
**Examples**
|
||||
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ examples: |-
|
|||
```
|
||||
|
||||
Adds flags when starting the buildkitd daemon. They take precedence over the
|
||||
configuration file specified by [`--config`](#--config-file). See `buildkitd --help`
|
||||
configuration file specified by [`--config`](#config). See `buildkitd --help`
|
||||
for the available flags.
|
||||
|
||||
**Example**
|
||||
|
|
@ -158,7 +158,7 @@ examples: |-
|
|||
```
|
||||
|
||||
Specifies the configuration file for the buildkitd daemon to use. The configuration
|
||||
can be overridden by [`--buildkitd-flags`](#--buildkitd-flags-flags).
|
||||
can be overridden by [`--buildkitd-flags`](#buildkitd-flags).
|
||||
See an [example buildkitd configuration file](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md).
|
||||
|
||||
### Set the builder driver to use (--driver) {#driver}
|
||||
|
|
@ -171,13 +171,13 @@ examples: |-
|
|||
their own specificities.
|
||||
|
||||
- `docker` - Uses the builder that is built into the docker daemon. With this
|
||||
driver, the [`--load`](buildx_build.md#--load) flag is implied by default on
|
||||
driver, the [`--load`](buildx_build.md#load) flag is implied by default on
|
||||
`buildx build`. However, building multi-platform images or exporting cache is
|
||||
not currently supported.
|
||||
- `docker-container` - Uses a buildkit container that will be spawned via docker.
|
||||
With this driver, both building multi-platform images and exporting cache are
|
||||
supported. However, images built will not automatically appear in `docker images`
|
||||
(see [`build --load`](buildx_build.md#--load)).
|
||||
(see [`build --load`](buildx_build.md#load)).
|
||||
- `kubernetes` - Uses a kubernetes pods. With this driver, you can spin up pods
|
||||
with defined buildkit container image to build your images.
|
||||
|
||||
|
|
|
|||
|
|
@ -905,7 +905,7 @@ examples: |-
|
|||
base image is still supported.
|
||||
- When using this option you may see significantly more space used due to
|
||||
storing two copies of the image, one for the build cache with all the cache
|
||||
layers in tact, and one for the squashed version.
|
||||
layers intact, and one for the squashed version.
|
||||
- While squashing layers may produce smaller images, it may have a negative
|
||||
impact on performance, as a single layer takes longer to extract, and
|
||||
downloading a single layer cannot be parallelized.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,99 @@
|
|||
command: docker checkpoint
|
||||
short: Manage checkpoints
|
||||
long: Manage checkpoints
|
||||
long: |-
|
||||
Checkpoint and Restore is an experimental feature that allows you to freeze a running
|
||||
container by checkpointing it, which turns its state into a collection of files
|
||||
on disk. Later, the container can be restored from the point it was frozen.
|
||||
|
||||
This is accomplished using a tool called [CRIU](http://criu.org), which is an
|
||||
external dependency of this feature. A good overview of the history of
|
||||
checkpoint and restore in Docker is available in this
|
||||
[Kubernetes blog post](https://kubernetes.io/blog/2015/07/how-did-quake-demo-from-dockercon-work/).
|
||||
|
||||
### Installing CRIU
|
||||
|
||||
If you use a Debian system, you can add the CRIU PPA and install with `apt-get`
|
||||
[from the criu launchpad](https://launchpad.net/~criu/+archive/ubuntu/ppa).
|
||||
|
||||
Alternatively, you can [build CRIU from source](https://criu.org/Installation).
|
||||
|
||||
You need at least version 2.0 of CRIU to run checkpoint and restore in Docker.
|
||||
|
||||
### Use cases for checkpoint and restore
|
||||
|
||||
This feature is currently focused on single-host use cases for checkpoint and
|
||||
restore. Here are a few:
|
||||
|
||||
- Restarting the host machine without stopping/starting containers
|
||||
- Speeding up the start time of slow start applications
|
||||
- "Rewinding" processes to an earlier point in time
|
||||
- "Forensic debugging" of running processes
|
||||
|
||||
Another primary use case of checkpoint and restore outside of Docker is the live
|
||||
migration of a server from one machine to another. This is possible with the
|
||||
current implementation, but not currently a priority (and so the workflow is
|
||||
not optimized for the task).
|
||||
|
||||
### Using checkpoint and restore
|
||||
|
||||
A new top level command `docker checkpoint` is introduced, with three subcommands:
|
||||
|
||||
- `docker checkpoint create` (creates a new checkpoint)
|
||||
- `docker checkpoint ls` (lists existing checkpoints)
|
||||
- `docker checkpoint rm` (deletes an existing checkpoint)
|
||||
|
||||
Additionally, a `--checkpoint` flag is added to the `docker container start` command.
|
||||
|
||||
The options for `docker checkpoint create`:
|
||||
|
||||
```console
|
||||
Usage: docker checkpoint create [OPTIONS] CONTAINER CHECKPOINT
|
||||
|
||||
Create a checkpoint from a running container
|
||||
|
||||
--leave-running=false Leave the container running after checkpoint
|
||||
--checkpoint-dir Use a custom checkpoint storage directory
|
||||
```
|
||||
|
||||
And to restore a container:
|
||||
|
||||
```console
|
||||
Usage: docker start --checkpoint CHECKPOINT_ID [OTHER OPTIONS] CONTAINER
|
||||
```
|
||||
|
||||
Example of using checkpoint and restore on a container:
|
||||
|
||||
```console
|
||||
$ docker run --security-opt=seccomp:unconfined --name cr -d busybox /bin/sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'
|
||||
abc0123
|
||||
|
||||
$ docker checkpoint create cr checkpoint1
|
||||
|
||||
# <later>
|
||||
$ docker start --checkpoint checkpoint1 cr
|
||||
abc0123
|
||||
```
|
||||
|
||||
This process just logs an incrementing counter to stdout. If you run `docker logs`
|
||||
in between running/checkpoint/restoring you should see that the counter
|
||||
increases while the process is running, stops while it's checkpointed, and
|
||||
resumes from the point it left off once you restore.
|
||||
|
||||
### Known limitations
|
||||
|
||||
seccomp is only supported by CRIU in very up to date kernels.
|
||||
|
||||
External terminal (i.e. `docker run -t ..`) is not supported at the moment.
|
||||
If you try to create a checkpoint for a container with an external terminal,
|
||||
it would fail:
|
||||
|
||||
```console
|
||||
$ docker checkpoint create cr checkpoint1
|
||||
Error response from daemon: Cannot checkpoint container c1: rpc error: code = 2 desc = exit status 1: "criu failed: type NOTIFY errno 0\nlog file: /var/lib/docker/containers/eb62ebdbf237ce1a8736d2ae3c7d88601fc0a50235b0ba767b559a1f3c5a600b/checkpoints/checkpoint1/criu.work/dump.log\n"
|
||||
|
||||
$ cat /var/lib/docker/containers/eb62ebdbf237ce1a8736d2ae3c7d88601fc0a50235b0ba767b559a1f3c5a600b/checkpoints/checkpoint1/criu.work/dump.log
|
||||
Error (mount.c:740): mnt: 126:./dev/console doesn't have a proper root mount
|
||||
```
|
||||
usage: docker checkpoint
|
||||
pname: docker
|
||||
plink: docker.yaml
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ long: |-
|
|||
By default, this renders all results in a JSON array. If a format is specified,
|
||||
the given template will be executed for each result.
|
||||
|
||||
Go's [text/template](http://golang.org/pkg/text/template/) package
|
||||
Go's [text/template](https://golang.org/pkg/text/template/) package
|
||||
describes all the details of the format.
|
||||
|
||||
For detailed information about using configs, refer to [store configuration data using Docker Configs](https://docs.docker.com/engine/swarm/configs/).
|
||||
|
|
|
|||
|
|
@ -990,7 +990,7 @@ examples: |-
|
|||
created into the container once it is run. This poses a problem when
|
||||
a new device needs to be added to running container.
|
||||
|
||||
One of the solution is to add a more permissive rule to a container
|
||||
One of the solutions is to add a more permissive rule to a container
|
||||
allowing it access to a wider range of devices. For example, supposing
|
||||
our container needs access to a character device with major `42` and
|
||||
any number of minor number (added as new devices appear), the
|
||||
|
|
|
|||
|
|
@ -174,11 +174,11 @@ long: |-
|
|||
|
||||
If a format (`--format`) is specified, the given template will be executed
|
||||
instead of the default
|
||||
format. Go's [text/template](http://golang.org/pkg/text/template/) package
|
||||
format. Go's [text/template](https://golang.org/pkg/text/template/) package
|
||||
describes all the details of the format.
|
||||
|
||||
If a format is set to `{{json .}}`, the events are streamed as valid JSON
|
||||
Lines. For information about JSON Lines, please refer to http://jsonlines.org/.
|
||||
Lines. For information about JSON Lines, please refer to https://jsonlines.org/.
|
||||
usage: docker events [OPTIONS]
|
||||
pname: docker
|
||||
plink: docker.yaml
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ long: |-
|
|||
under different names is counted only once.
|
||||
|
||||
If a format is specified, the given template will be executed instead of the
|
||||
default format. Go's [text/template](http://golang.org/pkg/text/template/) package
|
||||
default format. Go's [text/template](https://golang.org/pkg/text/template/) package
|
||||
describes all the details of the format.
|
||||
|
||||
Depending on the storage driver in use, additional information can be shown, such
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ examples: |-
|
|||
$ docker kill --signal=1 my_container
|
||||
```
|
||||
|
||||
Refer to the [`signal(7)`](http://man7.org/linux/man-pages/man7/signal.7.html)
|
||||
Refer to the [`signal(7)`](https://man7.org/linux/man-pages/man7/signal.7.html)
|
||||
man-page for a list of standard Linux signals.
|
||||
deprecated: false
|
||||
experimental: false
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ long: |-
|
|||
Returns information about a node. By default, this command renders all results
|
||||
in a JSON array. You can specify an alternate format to execute a
|
||||
given template for each result. Go's
|
||||
[text/template](http://golang.org/pkg/text/template/) package describes all the
|
||||
[text/template](https://golang.org/pkg/text/template/) package describes all the
|
||||
details of the format.
|
||||
|
||||
> **Note**
|
||||
|
|
|
|||
|
|
@ -141,9 +141,8 @@ examples: |-
|
|||
```console
|
||||
$ docker search --filter is-official=true --filter stars=3 busybox
|
||||
|
||||
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
|
||||
progrium/busybox 50 [OK]
|
||||
radial/busyboxplus Full-chain, Internet enabled, busybox made... 8 [OK]
|
||||
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
|
||||
busybox Busybox base image. 325 [OK]
|
||||
```
|
||||
|
||||
### Format the output
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ long: |-
|
|||
By default, this renders all results in a JSON array. If a format is specified,
|
||||
the given template will be executed for each result.
|
||||
|
||||
Go's [text/template](http://golang.org/pkg/text/template/) package
|
||||
Go's [text/template](https://golang.org/pkg/text/template/) package
|
||||
describes all the details of the format.
|
||||
|
||||
For detailed information about using secrets, refer to [manage sensitive data with Docker secrets](https://docs.docker.com/engine/swarm/secrets/).
|
||||
|
|
|
|||
|
|
@ -1588,7 +1588,7 @@ examples: |-
|
|||
### Create services using templates
|
||||
|
||||
You can use templates for some flags of `service create`, using the syntax
|
||||
provided by the Go's [text/template](http://golang.org/pkg/text/template/) package.
|
||||
provided by the Go's [text/template](https://golang.org/pkg/text/template/) package.
|
||||
|
||||
The supported flags are the following :
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ long: |-
|
|||
By default, this renders all results in a JSON array. If a format is specified,
|
||||
the given template will be executed for each result.
|
||||
|
||||
Go's [text/template](http://golang.org/pkg/text/template/) package
|
||||
Go's [text/template](https://golang.org/pkg/text/template/) package
|
||||
describes all the details of the format.
|
||||
|
||||
> **Note**
|
||||
|
|
|
|||
|
|
@ -127,11 +127,11 @@ long: |-
|
|||
|
||||
If a format (`--format`) is specified, the given template will be executed
|
||||
instead of the default
|
||||
format. Go's [text/template](http://golang.org/pkg/text/template/) package
|
||||
format. Go's [text/template](https://golang.org/pkg/text/template/) package
|
||||
describes all the details of the format.
|
||||
|
||||
If a format is set to `{{json .}}`, the events are streamed as valid JSON
|
||||
Lines. For information about JSON Lines, please refer to http://jsonlines.org/ .
|
||||
Lines. For information about JSON Lines, please refer to https://jsonlines.org/ .
|
||||
usage: docker system events [OPTIONS]
|
||||
pname: docker system
|
||||
plink: docker_system.yaml
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ long: |-
|
|||
By default, this will render all version information in an easy to read
|
||||
layout. If a format is specified, the given template will be executed instead.
|
||||
|
||||
Go's [text/template](http://golang.org/pkg/text/template/) package
|
||||
Go's [text/template](https://golang.org/pkg/text/template/) package
|
||||
describes all the details of the format.
|
||||
usage: docker version [OPTIONS]
|
||||
pname: docker
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ examples: |-
|
|||
`mount` command. You can provide multiple options by passing the `--opt` flag
|
||||
multiple times. Some `mount` options (such as the `o` option) can take a
|
||||
comma-separated list of options. Complete list of available mount options can be
|
||||
found [here](http://man7.org/linux/man-pages/man8/mount.8.html).
|
||||
found [here](https://man7.org/linux/man-pages/man8/mount.8.html).
|
||||
|
||||
For example, the following creates a `tmpfs` volume called `foo` with a size of
|
||||
100 megabyte and `uid` of 1000.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ long: |-
|
|||
Returns information about a volume. By default, this command renders all results
|
||||
in a JSON array. You can specify an alternate format to execute a
|
||||
given template for each result. Go's
|
||||
[text/template](http://golang.org/pkg/text/template/) package describes all the
|
||||
[text/template](https://golang.org/pkg/text/template/) package describes all the
|
||||
details of the format.
|
||||
usage: docker volume inspect [OPTIONS] VOLUME [VOLUME...]
|
||||
pname: docker volume
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@
|
|||
aufs: |
|
||||
aufs (advanced multi layered unification filesystem) is a Linux [filesystem](#filesystem) that
|
||||
Docker supports as a storage backend. It implements the
|
||||
[union mount](http://en.wikipedia.org/wiki/Union_mount) for Linux file systems.
|
||||
[union mount](https://en.wikipedia.org/wiki/Union_mount) for Linux file systems.
|
||||
base image: |
|
||||
A **base image** has no parent image specified in its Dockerfile. It is created
|
||||
using a Dockerfile with the `FROM scratch` directive.
|
||||
btrfs: |
|
||||
btrfs (B-tree file system) is a Linux [filesystem](#filesystem) that Docker
|
||||
supports as a storage backend. It is a [copy-on-write](http://en.wikipedia.org/wiki/Copy-on-write)
|
||||
supports as a storage backend. It is a [copy-on-write](https://en.wikipedia.org/wiki/Copy-on-write)
|
||||
filesystem.
|
||||
build: |
|
||||
build is the process of building Docker images using a [Dockerfile](#dockerfile).
|
||||
|
|
@ -170,7 +170,7 @@ Machine: |
|
|||
|
||||
*Also known as : docker-machine*
|
||||
namespace: |
|
||||
A [Linux namespace](http://man7.org/linux/man-pages/man7/namespaces.7.html)
|
||||
A [Linux namespace](https://man7.org/linux/man-pages/man7/namespaces.7.html)
|
||||
is a Linux kernel feature that isolates and virtualizes system resources. Processes which are restricted to
|
||||
a namespace can only interact with resources or processes that are part of the same namespace. Namespaces
|
||||
are an important part of Docker's isolation model. Namespaces exist for each type of
|
||||
|
|
@ -189,7 +189,7 @@ overlay network driver: |
|
|||
for docker containers in a cluster.
|
||||
overlay storage driver: |
|
||||
OverlayFS is a [filesystem](#filesystem) service for Linux which implements a
|
||||
[union mount](http://en.wikipedia.org/wiki/Union_mount) for other file systems.
|
||||
[union mount](https://en.wikipedia.org/wiki/Union_mount) for other file systems.
|
||||
It is supported by the Docker daemon as a storage driver.
|
||||
parent image: |
|
||||
An image's **parent image** is the image designated in the `FROM` directive
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@
|
|||
</div>
|
||||
<div class="footer_social_nav">
|
||||
<ul class="nav-social">
|
||||
<li class="fa fa-twitter"><a href="http://twitter.com/docker">Twitter</a></li>
|
||||
<li class="fa fa-youtube"><a href="http://www.youtube.com/user/dockerrun">Youtube</a></li>
|
||||
<li class="fa fa-twitter"><a href="https://twitter.com/docker">Twitter</a></li>
|
||||
<li class="fa fa-youtube"><a href="https://www.youtube.com/user/dockerrun">Youtube</a></li>
|
||||
<li class="fa fa-github"><a href="https://github.com/docker">GitHub</a></li>
|
||||
<li class="fa fa-linkedin"><a href="https://www.linkedin.com/company/docker">Linkedin</a></li>
|
||||
<li class="fa fa-facebook"><a href="https://www.facebook.com/docker.run">Facebook</a></li>
|
||||
|
|
|
|||
|
|
@ -107,6 +107,6 @@
|
|||
<meta property="og:url" content="https://docs.docker.com{{ page.url }}" />
|
||||
<meta property="og:site_name" content="Docker Documentation" />
|
||||
<meta property="article:published_time" itemprop="datePublished" content="{% if page.date %}{{ page.date | date_to_xmlschema }}{% else %}{{ site.time | date_to_xmlschema }}{% endif %}"/>
|
||||
<script type="application/ld+json">{"@context":"http://schema.org","@type":"WebPage","headline":{{ page.title | default: page_title | jsonify }},"description":{{ page.description | default: page_description | jsonify }},"url":"https://docs.docker.com{{ page.url }}"}</script>
|
||||
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","headline":{{ page.title | default: page_title | jsonify }},"description":{{ page.description | default: page_description | jsonify }},"url":"https://docs.docker.com{{ page.url }}"}</script>
|
||||
<!-- END SEO STUFF -->
|
||||
</head>
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ Docker.app connects to it, so it's safe to ignore.
|
|||
|
||||
Yes, you can run VirtualBox along with Docker Desktop if you have enabled the [Windows Hypervisor Platform](https://docs.microsoft.com/en-us/virtualization/api/){: target="_blank" rel="noopener" class="_"} feature on your machine.
|
||||
|
||||
### Why is Windows 10 required?
|
||||
### Why is Windows 10 or Windows 11 required?
|
||||
|
||||
Docker Desktop uses the Windows Hyper-V features. While older Windows versions have Hyper-V, their Hyper-V implementations lack features critical for Docker Desktop to work.
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ This page contains release notes for Docker Desktop for Mac 3.x.
|
|||
|
||||
> **Update to the Docker Desktop terms**
|
||||
>
|
||||
> Professional use of Docker Desktop in large organizations (more than 250 employees or more than $10 million in revenue) requires users to have a paid Docker subscription. While the effective date of these terms is August 31, 2021, there is a grace period until January 31, 2022 for those that require a paid subscription. For more information, see [Docker Desktop License Agreement](../../subscription/index.md#docker-desktop-license-agreement).
|
||||
> Professional use of Docker Desktop in large organizations (more than 250 employees or more than $10 million in revenue) requires users to have a paid Docker subscription. While the effective date of these terms is August 31, 2021, there is a grace period until January 31, 2022 for those that require a paid subscription. For more information, see [Docker Desktop License Agreement](../../../subscription/index.md#docker-desktop-license-agreement).
|
||||
{: .important}
|
||||
|
||||
This page contains information about the new features, improvements, known issues, and bug fixes in Docker Desktop releases.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ redirect_from:
|
|||
|
||||
> **Update to the Docker Desktop terms**
|
||||
>
|
||||
> Professional use of Docker Desktop in large organizations (more than 250 employees or more than $10 million in revenue) requires users to have a paid Docker subscription. While the effective date of these terms is August 31, 2021, there is a grace period until January 31, 2022 for those that require a paid subscription. For more information, see [Docker Desktop License Agreement](../../subscription/index.md#docker-desktop-license-agreement).
|
||||
> Professional use of Docker Desktop in large organizations (more than 250 employees or more than $10 million in revenue) requires users to have a paid Docker subscription. While the effective date of these terms is August 31, 2021, there is a grace period until January 31, 2022 for those that require a paid subscription. For more information, see [Docker Desktop License Agreement](../../../subscription/index.md#docker-desktop-license-agreement).
|
||||
{: .important}
|
||||
|
||||
This page contains information about the new features, improvements, known issues, and bug fixes in Docker Desktop releases.
|
||||
|
|
|
|||
|
|
@ -36,11 +36,12 @@ Your Windows machine must meet the following requirements to successfully instal
|
|||
|
||||
### WSL 2 backend
|
||||
|
||||
- Windows 11 64-bit: Home or Pro version 21H2 or higher, or Enterprise or Education version 21H2 or higher.
|
||||
- Windows 10 64-bit: Home or Pro 2004 (build 19041) or higher, or Enterprise or Education 1909 (build 18363) or higher.
|
||||
- Enable the WSL 2 feature on Windows. For detailed instructions, refer to the
|
||||
[Microsoft documentation](https://docs.microsoft.com/en-us/windows/wsl/install-win10){: target="_blank" rel="noopener" class="_"}.
|
||||
- The following hardware prerequisites are required to successfully run
|
||||
WSL 2 on Windows 10:
|
||||
WSL 2 on Windows 10 or Windows 11:
|
||||
|
||||
- 64-bit processor with [Second Level Address Translation (SLAT)](https://en.wikipedia.org/wiki/Second_Level_Address_Translation){: target="_blank" rel="noopener" class="_"}
|
||||
- 4GB system RAM
|
||||
|
|
@ -54,9 +55,10 @@ WSL 2 on Windows 10:
|
|||
|
||||
### Hyper-V backend and Windows containers
|
||||
|
||||
- Windows 11 64-bit: Pro version 21H2 or higher, or Enterprise or Education version 21H2 or higher.
|
||||
- Windows 10 64-bit: Pro 2004 (build 19041) or higher, or Enterprise or Education 1909 (build 18363) or higher.
|
||||
|
||||
For Windows 10 Home, see [System requirements for WSL 2 backend](#wsl-2-backend).
|
||||
For Windows 10 and Windows 11 Home, see [System requirements for WSL 2 backend](#wsl-2-backend).
|
||||
- Hyper-V and Containers Windows features must be enabled.
|
||||
- The following hardware prerequisites are required to successfully run Client
|
||||
Hyper-V on Windows 10:
|
||||
|
|
@ -170,5 +172,5 @@ To uninstall Docker Desktop from your Windows machine:
|
|||
* [Troubleshooting](troubleshoot.md) describes common problems, workarounds, and
|
||||
how to get support.
|
||||
* [FAQs](../faqs.md) provide answers to frequently asked questions.
|
||||
* [Release notes]( release-notes/index.md) lists component updates, new features, and improvements associated with Docker Desktop releases.
|
||||
* [Release notes](release-notes/index.md) lists component updates, new features, and improvements associated with Docker Desktop releases.
|
||||
* [Back up and restore data](../backup-and-restore.md) provides instructions on backing up and restoring data related to Docker.
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ Docker Desktop 2.4.0.0 contains a Kubernetes upgrade. Your local Kubernetes clus
|
|||
|
||||
### New
|
||||
|
||||
- Windows 10 Home users can now use Docker Desktop through WSL 2. This requires Windows 10, version 2004 or higher. For more information, see [Install Docker Desktop on Windows](install.md).
|
||||
- Windows 10 Home users can now use Docker Desktop through WSL 2. This requires Windows 10, version 2004 or higher. For more information, see [Install Docker Desktop on Windows](../install.md).
|
||||
- Docker Desktop introduces a new onboarding tutorial upon first startup. The Quick Start tutorial guides users to get started with Docker in a few easy steps. It includes a simple exercise to build an example Docker image, run it as a container, push and save the image to Docker Hub.
|
||||
- Docker Desktop now allows sharing individual folders, rather than whole drives, giving more control to users over what is being shared.
|
||||
|
||||
|
|
@ -284,7 +284,7 @@ Docker Desktop 2.4.0.0 contains a Kubernetes upgrade. Your local Kubernetes clus
|
|||
|
||||
### Known issues
|
||||
|
||||
- Some CLI commands fail if you are running Docker Desktop in the experimental Linux Containers on Windows (LCOW) mode. As alternatives, we recommend running either traditional Linux containers, or the [WSL 2 backend](wsl.md).
|
||||
- Some CLI commands fail if you are running Docker Desktop in the experimental Linux Containers on Windows (LCOW) mode. As alternatives, we recommend running either traditional Linux containers, or the [WSL 2 backend](../wsl.md).
|
||||
|
||||
**WSL 2**
|
||||
|
||||
|
|
@ -336,7 +336,7 @@ Docker Desktop 2.4.0.0 contains a Kubernetes upgrade. Your local Kubernetes clus
|
|||
|
||||
### Known issues
|
||||
|
||||
- Some CLI commands fail if you are running Docker Desktop in the experimental Linux Containers on Windows (LCOW) mode. As alternatives, we recommend running either traditional Linux containers, or the experimental [WSL backend](wsl.md).
|
||||
- Some CLI commands fail if you are running Docker Desktop in the experimental Linux Containers on Windows (LCOW) mode. As alternatives, we recommend running either traditional Linux containers, or the experimental [WSL backend](../wsl.md).
|
||||
- It is not possible to resize the disk image using the Docker Desktop **Settings** UI. If you would like to update the size of the disk image (for example, to 128 GB), run the following command in PowerShell:
|
||||
|
||||
```powershell
|
||||
|
|
@ -376,11 +376,11 @@ Docker Desktop 2.4.0.0 contains a Kubernetes upgrade. Your local Kubernetes clus
|
|||
- Fixed a race condition when starting the WSL engine which caused Docker Desktop to incorrectly report that the containers have exited. Fixes [docker/for-win#5607](https://github.com/docker/for-win/issues/5607).
|
||||
- Fixed an issue where editing code inside a container resulted in an error. Fixes [docker/for-win#5528](https://github.com/docker/for-win/issues/5528).
|
||||
- Fixed a bug where running the command `DockerCli.exe -SharedDrives` failed to display a list of drives that are shared. Fixes [docker/for-win#5625](https://github.com/docker/for-win/issues/5625).
|
||||
- Starting with Docker Desktop 2.2.0.3, you must access all shared files using their original case. For example, if you have created a file called `test`, you must open it as `test`. Attempts to open the file as `Test` will fail with the error `No such file or directory`. For more information, see _Tips on shared drives, permissions, and volume mounts_ in [File sharing](index.md#file-sharing).
|
||||
- Starting with Docker Desktop 2.2.0.3, you must access all shared files using their original case. For example, if you have created a file called `test`, you must open it as `test`. Attempts to open the file as `Test` will fail with the error `No such file or directory`. For more information, see _Tips on shared drives, permissions, and volume mounts_ in [File sharing](../index.md#file-sharing).
|
||||
|
||||
### Known issues
|
||||
|
||||
- DockerNAT has been removed from Docker Desktop 2.2.0.0 as using an IP address to communicate from the host to a container is not a supported feature. To communicate from a container to the host, you must use the special DNS name `host.docker.internal`. We also recommend using ports to communicate from the host to a container. For more information, see [Networking](networking.md/#use-cases-and-workarounds).
|
||||
- DockerNAT has been removed from Docker Desktop 2.2.0.0 as using an IP address to communicate from the host to a container is not a supported feature. To communicate from a container to the host, you must use the special DNS name `host.docker.internal`. We also recommend using ports to communicate from the host to a container. For more information, see [Networking](../networking.md#use-cases-and-workarounds).
|
||||
|
||||
However, if your current setup relies on IP addresses for communication, you can use a temporary workaround to reinstate DockerNAT. To do this, open
|
||||
`C:\Program Files\Docker\Docker\resources\MobyLinux.ps1` and add `$SwitchName = "DockerNAT"` between line 175 and 176. Note that the temporary workaround to reinstate DockerNAT may be removed from future releases.
|
||||
|
|
@ -486,7 +486,7 @@ Docker Desktop 2.1.0.4 contains a Kubernetes upgrade. Note that your local Kuber
|
|||
|
||||
### New
|
||||
|
||||
Docker Desktop now enables you to sign into Docker Hub using two-factor authentication. For more information, see [Two-factor authentication](index.md#two-factor-authentication).
|
||||
Docker Desktop now enables you to sign into Docker Hub using two-factor authentication. For more information, see [Two-factor authentication](../index.md#two-factor-authentication).
|
||||
|
||||
## Docker Desktop Community 2.1.0.3
|
||||
2019-09-16
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ This page contains release notes for Docker Desktop for Windows 3.x.
|
|||
|
||||
> **Update to the Docker Desktop terms**
|
||||
>
|
||||
> Professional use of Docker Desktop in large organizations (more than 250 employees or more than $10 million in revenue) requires users to have a paid Docker subscription. While the effective date of these terms is August 31, 2021, there is a grace period until January 31, 2022 for those that require a paid subscription. For more information, see [Docker Desktop License Agreement](../../subscription/index.md#docker-desktop-license-agreement).
|
||||
> Professional use of Docker Desktop in large organizations (more than 250 employees or more than $10 million in revenue) requires users to have a paid Docker subscription. While the effective date of these terms is August 31, 2021, there is a grace period until January 31, 2022 for those that require a paid subscription. For more information, see [Docker Desktop License Agreement](../../../subscription/index.md#docker-desktop-license-agreement).
|
||||
{: .important}
|
||||
|
||||
This page contains information about the new features, improvements, known issues, and bug fixes in Docker Desktop releases.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ redirect_from:
|
|||
|
||||
> **Update to the Docker Desktop terms**
|
||||
>
|
||||
> Professional use of Docker Desktop in large organizations (more than 250 employees or more than $10 million in revenue) requires users to have a paid Docker subscription. While the effective date of these terms is August 31, 2021, there is a grace period until January 31, 2022 for those that require a paid subscription. For more information, see [Docker Desktop License Agreement](../../subscription/index.md#docker-desktop-license-agreement).
|
||||
> Professional use of Docker Desktop in large organizations (more than 250 employees or more than $10 million in revenue) requires users to have a paid Docker subscription. While the effective date of these terms is August 31, 2021, there is a grace period until January 31, 2022 for those that require a paid subscription. For more information, see [Docker Desktop License Agreement](../../../subscription/index.md#docker-desktop-license-agreement).
|
||||
{: .important}
|
||||
|
||||
This page contains information about the new features, improvements, known issues, and bug fixes in Docker Desktop releases.
|
||||
|
|
@ -107,7 +107,8 @@ The updated [Docker Subscription Service Agreement](https://www.docker.com/legal
|
|||
- The existing Docker Free subscription has been renamed **Docker Personal**.
|
||||
- **No changes** to Docker Engine or any other upstream **open source** Docker or Moby project.
|
||||
|
||||
To understand how these changes affect you, read the [FAQs](https://www.docker.com/pricing/faq){: target="*blank" rel="noopener" class="*" id="dkr_docs_relnotes_btl"}. For more information, see [Docker subscription overview](../../subscription/index.md).
|
||||
To understand how these changes affect you, read the [FAQs](https://www.docker.com/pricing/faq){: target="*blank" rel="noopener" class="*" id="dkr_docs_relnotes_btl"}.
|
||||
For more information, see [Docker subscription overview](../../../subscription/index.md).
|
||||
|
||||
### Upgrades
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Additionally, with WSL 2, the time required to start a Docker daemon after a col
|
|||
|
||||
Before you install the Docker Desktop WSL 2 backend, you must complete the following steps:
|
||||
|
||||
1. Install Windows 10, version 1903 or higher.
|
||||
1. Install Windows 10, version 1903 or higher or Windows 11.
|
||||
2. Enable WSL 2 feature on Windows. For detailed instructions, refer to the [Microsoft documentation](https://docs.microsoft.com/en-us/windows/wsl/install-win10).
|
||||
3. Download and install the [Linux kernel update package](https://docs.microsoft.com/windows/wsl/wsl2-kernel).
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,13 @@ info:
|
|||
Browse through the Docker Hub API documentation to explore the supported endpoints.
|
||||
|
||||
tags:
|
||||
- name: resources
|
||||
x-displayName: Resources
|
||||
description: |
|
||||
The following resources are available to interact with the documented API:
|
||||
|
||||
- <a href="https://github.com/docker/hub-tool#readme" target="_blank">Docker Hub CLI tool</a> (currently experimental)
|
||||
- <a href="https://www.postman.com/devrel/workspace/docker-hub/collection/13191452-7d2f1375-9705-4db6-a47b-8235286e58a1" target="_blank">Postman Collection</a> (built by the Postman team)
|
||||
- name: rate-limiting
|
||||
x-displayName: Rate Limiting
|
||||
description: |
|
||||
|
|
@ -91,6 +98,7 @@ tags:
|
|||
x-tagGroups:
|
||||
- name: General
|
||||
tags:
|
||||
- resources
|
||||
- rate-limiting
|
||||
- name: API
|
||||
tags:
|
||||
|
|
|
|||
|
|
@ -981,7 +981,7 @@ The following examples show bind mount syntax:
|
|||
### Create services using templates
|
||||
|
||||
You can use templates for some flags of `service create`, using the syntax
|
||||
provided by the Go's [text/template](http://golang.org/pkg/text/template/)
|
||||
provided by the Go's [text/template](https://golang.org/pkg/text/template/)
|
||||
package.
|
||||
|
||||
The following flags are supported:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ description: Tips for building the images for our application
|
|||
## Security scanning
|
||||
|
||||
When you have built an image, it is a good practice to scan it for security vulnerabilities using the `docker scan` command.
|
||||
Docker has partnered with [Snyk](http://snyk.io){:target="_blank" rel="noopener" class="_"} to provide the vulnerability scanning service.
|
||||
Docker has partnered with [Snyk](https://snyk.io){:target="_blank" rel="noopener" class="_"} to provide the vulnerability scanning service.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
|
|
|
|||
|
|
@ -127,16 +127,17 @@ randomly created name. So, you'll most likely have a different name.
|
|||
## What is a container?
|
||||
|
||||
Now that you've run a container, what _is_ a container? Simply put, a container is
|
||||
simply another process on your machine that has been isolated from all other processes
|
||||
on the host machine. That isolation leverages [kernel namespaces and cgroups](https://medium.com/@saschagrunert/demystifying-containers-part-i-kernel-space-2c53d6979504), features that have been
|
||||
in Linux for a long time. Docker has worked to make these capabilities approachable and easy to use.
|
||||
a sandboxed process on your machine that is isolated from all other processes
|
||||
on the host machine. That isolation leverages [kernel namespaces and cgroups](https://medium.com/@saschagrunert/demystifying-containers-part-i-kernel-space-2c53d6979504),
|
||||
features that have been in Linux for a long time. Docker has worked to make these
|
||||
capabilities approachable and easy to use.
|
||||
|
||||
> **Creating containers from scratch**
|
||||
>
|
||||
> If you'd like to see how containers are built from scratch, Liz Rice from Aqua Security
|
||||
> has a fantastic talk in which she creates a container from scratch in Go. While she makes
|
||||
> a simple container, this talk doesn't go into networking, using images for the filesystem,
|
||||
> and more. But, it gives a _fantastic_ deep dive into how things are working.
|
||||
> has a fantastic talk in which she creates a container from scratch in Go. While the talk
|
||||
> does not go into networking, using images for the filesystem, and other advanced topics,
|
||||
> it gives a _fantastic_ deep dive into how things are working.
|
||||
>
|
||||
> <iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/8fi7uSYlOdc" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,18 @@ redirect_from:
|
|||
|
||||
## Prerequisites
|
||||
|
||||
* Some understanding of Go and its toolchain. This is not a tutorial on Go. If you are new to the language, the [Go website](https://golang.org/){: target="_blank" rel="noopener" class="_"} is a good starting point, so go (pun intended) check it out.
|
||||
* Some awareness of basic Docker concepts. If unsure, work through the orientation and setup in Get started [Part 1](../../get-started/index.md).
|
||||
* Some understanding of Go and its toolchain. This is not a tutorial on Go. If
|
||||
you are new to the language, the [Go website](https://golang.org/){: target="_blank" rel="noopener" class="_"}
|
||||
is a good starting point, so go (pun intended) check it out.
|
||||
* Some awareness of basic Docker concepts. If unsure, work through the orientation
|
||||
and setup in Get started [Part 1](../../get-started/index.md).
|
||||
|
||||
## Overview
|
||||
|
||||
Now that we have a good overview of containers and the Docker platform, let’s take a look at building our first image. An image includes everything you need to run an application – the code or binary, runtime, dependencies, and any other file system objects required.
|
||||
Now that we have a good overview of containers and the Docker platform, let’s
|
||||
take a look at building our first image. An image includes everything you need
|
||||
to run an application – the code or binary, runtime, dependencies, and any other
|
||||
file system objects required.
|
||||
|
||||
To complete this tutorial, you need the following:
|
||||
|
||||
|
|
@ -25,15 +31,18 @@ To complete this tutorial, you need the following:
|
|||
|
||||
## Meet the example application
|
||||
|
||||
To avoid losing focus on Docker's features, the sample application is a minimal HTTP server that has only three features:
|
||||
To avoid losing focus on Docker's features, the sample application is a minimal
|
||||
HTTP server that has only three features:
|
||||
|
||||
* It responds with a text message containing a heart symbol ("<3") on requests to `/`.
|
||||
* It responds with `{"Status" : "OK"}` JSON to the health check request on requests to `/ping`.
|
||||
* The port it listens on is configurable using the environment variable `HTTP_PORT`. The default value is `8080`.
|
||||
|
||||
Thus, it somewhat mimics enough basic properties of a REST microservice to be useful for our learning of Docker.
|
||||
Thus, it somewhat mimics enough basic properties of a REST microservice to be
|
||||
useful for our learning of Docker.
|
||||
|
||||
The source code for the application is in the [olliefr/docker-gs-ping](https://github.com/olliefr/docker-gs-ping){: target="_blank" rel="noopener" class="_"} GitHub repo. Please feel free to clone or fork it.
|
||||
The source code for the application is in the [github.com/olliefr/docker-gs-ping](https://github.com/olliefr/docker-gs-ping){: target="_blank" rel="noopener" class="_"}
|
||||
GitHub repository. Please feel free to clone or fork it.
|
||||
|
||||
For our present study, we clone it to our local machine:
|
||||
|
||||
|
|
@ -41,7 +50,8 @@ For our present study, we clone it to our local machine:
|
|||
$ git clone https://github.com/olliefr/docker-gs-ping
|
||||
```
|
||||
|
||||
The application's `main.go` file is fairly straightforward, if you are familiar with Go:
|
||||
The application's `main.go` file is fairly straightforward, if you are familiar
|
||||
with Go:
|
||||
|
||||
{% raw %}
|
||||
```go
|
||||
|
|
@ -82,13 +92,16 @@ func main() {
|
|||
|
||||
## Smoke test the application
|
||||
|
||||
Let’s start our application and make sure it’s running properly. Open your terminal and navigate to the directory into which you cloned the project's repo. From now on, we'll refer to this directory as the **working directory**.
|
||||
Let’s start our application and make sure it’s running properly. Open your
|
||||
terminal and navigate to the directory into which you cloned the project's repo.
|
||||
From now on, we'll refer to this directory as the **project directory**.
|
||||
|
||||
```console
|
||||
$ go run main.go
|
||||
```
|
||||
|
||||
This should compile and start the server as a foreground application, outputting the banner, as illustrated in the next figure.
|
||||
This should compile and start the server as a foreground application, outputting
|
||||
the banner, as illustrated in the next figure.
|
||||
|
||||
```
|
||||
____ __
|
||||
|
|
@ -102,16 +115,20 @@ ____________________________________O/_______
|
|||
⇨ http server started on [::]:8080
|
||||
```
|
||||
|
||||
Let's run a quick _smoke test_ on the application. **In a new terminal**, run a request using `curl`. Alternatively, you can use your favourite web browser as well.
|
||||
Let's run a quick _smoke test_ on the application. **In a new terminal**, run a
|
||||
request using `curl`. Alternatively, you can use your favourite web browser as
|
||||
well.
|
||||
|
||||
```console
|
||||
$ curl http://localhost:8080/
|
||||
Hello, Docker! <3
|
||||
```
|
||||
|
||||
So, the application responds with a greeting, just as the first business requirement says it should. Great.
|
||||
So, the application responds with a greeting, just as the first business
|
||||
requirement says it should. Great.
|
||||
|
||||
Having established that the server is running and is accessible, let's proceed to "dockerizing" it.
|
||||
Having established that the server is running and is accessible, let's proceed
|
||||
to "dockerizing" it.
|
||||
|
||||
## Create a Dockerfile for the application
|
||||
|
||||
|
|
@ -126,7 +143,11 @@ we would like to use for our application.
|
|||
FROM golang:1.16-alpine
|
||||
```
|
||||
|
||||
Docker images can be inherited from other images. Therefore, instead of creating our own base image, we’ll use the official Go image that already has all the tools and packages to compile and run a Go application. You can think of this in the same way you would think about class inheritance in object oriented programming or functional composition in functional programming.
|
||||
Docker images can be inherited from other images. Therefore, instead of creating
|
||||
our own base image, we’ll use the official Go image that already has all the tools
|
||||
and packages to compile and run a Go application. You can think of this in the
|
||||
same way you would think about class inheritance in object oriented programming
|
||||
or functional composition in functional programming.
|
||||
|
||||
When we have used that `FROM` command, we told Docker to include in our image all the functionality from the `golang:1.16-alpine` image. All of our consequent commands would build on top of that "base" image.
|
||||
|
||||
|
|
@ -134,50 +155,75 @@ When we have used that `FROM` command, we told Docker to include in our image al
|
|||
>
|
||||
> If you want to learn more about creating your own base images, see [creating base images](https://docs.docker.com/develop/develop-images/baseimages/) section of the guide.
|
||||
|
||||
To make things easier when running the rest of our commands, let’s create a directory _inside_ the image that we are building. This also instructs Docker to use this directory as the default _destination_ for all subsequent commands. This way we do not have to type out full file paths but can use relative paths based on this directory.
|
||||
To make things easier when running the rest of our commands, let’s create a
|
||||
directory _inside_ the image that we are building. This also instructs Docker
|
||||
to use this directory as the default _destination_ for all subsequent commands.
|
||||
This way we do not have to type out full file paths but can use relative paths
|
||||
based on this directory.
|
||||
|
||||
```dockerfile
|
||||
WORKDIR /app
|
||||
```
|
||||
|
||||
Usually the very first thing you do once you’ve downloaded a project written in Go is to install the modules necessary to compile it.
|
||||
Usually the very first thing you do once you’ve downloaded a project written in
|
||||
Go is to install the modules necessary to compile it.
|
||||
|
||||
But before we can run `go mod download` inside our image, we need to get our `go.mod` and `go.sum` files copied into it. We use the `COPY` command to do this.
|
||||
But before we can run `go mod download` inside our image, we need to get our
|
||||
`go.mod` and `go.sum` files copied into it. We use the `COPY` command to do this.
|
||||
|
||||
In its simplest form, the `COPY` command takes two parameters. The first parameter tells Docker what file you would like to copy into the image. The second parameter tells Docker where you want that file to be copied to.
|
||||
In its simplest form, the `COPY` command takes two parameters. The first
|
||||
parameter tells Docker what files you want to copy into the image. The last
|
||||
parameter tells Docker where you want that file to be copied to.
|
||||
|
||||
We’ll copy the `go.mod` and `go.sum` file into our working directory `/app` which, owing to our use of `WORKDIR`, is the current directory (`.`) inside the image.
|
||||
We’ll copy the `go.mod` and `go.sum` file into our project directory `/app` which,
|
||||
owing to our use of `WORKDIR`, is the current directory (`.`) inside the image.
|
||||
|
||||
```dockerfile
|
||||
COPY go.mod ./
|
||||
COPY go.sum ./
|
||||
```
|
||||
|
||||
Now that we have the module files inside the Docker image that we are building, we can use the `RUN` command to execute the command `go mod download` there as well. This works exactly the same as if we were running `go` locally on our machine, but this time these Go modules will be installed into the app directory inside our image.
|
||||
Now that we have the module files inside the Docker image that we are building,
|
||||
we can use the `RUN` command to execute the command `go mod download` there as
|
||||
well. This works exactly the same as if we were running `go` locally on our
|
||||
machine, but this time these Go modules will be installed into a directory
|
||||
inside the image.
|
||||
|
||||
```dockerfile
|
||||
RUN go mod download
|
||||
```
|
||||
|
||||
At this point, we have an image that is based on Go environment version 1.16 (or a later minor version, since we had specified `1.16` as our tag in the `FROM` command) and we have installed our dependencies.
|
||||
At this point, we have an image that is based on Go environment version 1.16
|
||||
(or a later minor version, since we had specified `1.16` as our tag in the
|
||||
`FROM` command) and we have installed our dependencies.
|
||||
|
||||
The next thing we need to do is to copy our source code into the image. We’ll use the `COPY` command just like we did with our module files before.
|
||||
The next thing we need to do is to copy our source code into the image. We’ll
|
||||
use the `COPY` command just like we did with our module files before.
|
||||
|
||||
```dockerfile
|
||||
COPY *.go ./
|
||||
```
|
||||
|
||||
This `COPY` command uses a wildcard to copy all files with `.go` extension located in the current directory on the host (the directory where the `Dockerfile` is located) into the current directory inside the image.
|
||||
This `COPY` command uses a wildcard to copy all files with `.go` extension
|
||||
located in the current directory on the host (the directory where the `Dockerfile`
|
||||
is located) into the current directory inside the image.
|
||||
|
||||
Now, we would like to compile our application. To that end, we use the familiar `RUN` command:
|
||||
Now, we would like to compile our application. To that end, we use the familiar
|
||||
`RUN` command:
|
||||
|
||||
```dockerfile
|
||||
RUN go build -o /docker-gs-ping
|
||||
```
|
||||
|
||||
This should be familiar. The result of that command will be a static application binary named `docker-gs-ping` and located in the root of the filesystem of the image that we are building. We could have put the binary into any other place we desire inside that image, the root directory has no special meaning in this regard. It's just convenient to use it to keep the file paths short for improved readability.
|
||||
This should be familiar. The result of that command will be a static application
|
||||
binary named `docker-gs-ping` and located in the root of the filesystem of the
|
||||
image that we are building. We could have put the binary into any other place we
|
||||
desire inside that image, the root directory has no special meaning in this
|
||||
regard. It's just convenient to use it to keep the file paths short for improved
|
||||
readability.
|
||||
|
||||
Now, all that is left to do is to tell Docker what command to execute when our image is used to start a container.
|
||||
Now, all that is left to do is to tell Docker what command to execute when our
|
||||
image is used to start a container.
|
||||
|
||||
We do this with the `CMD` command:
|
||||
|
||||
|
|
@ -207,7 +253,11 @@ EXPOSE 8080
|
|||
CMD [ "/docker-gs-ping" ]
|
||||
```
|
||||
|
||||
The `Dockerfile` may also contain _comments_. They always begin with a `#` symbol and make no difference to Docker. The comments are there for the convenience of humans tasked to maintain the `Dockerfile`:
|
||||
The `Dockerfile` may also contain _comments_. They always begin with a `#` symbol,
|
||||
and must be at the beginning of a line. Comments are there for your convenience
|
||||
to allow documenting your `Dockerfile`. Dockerfile _directives_, such as the
|
||||
`syntax` directive we added, must always be at the very top of the `Dockerfile`,
|
||||
so when adding comments, make sure they are after those directives:
|
||||
|
||||
```dockerfile
|
||||
# syntax=docker/dockerfile:1
|
||||
|
|
@ -229,9 +279,14 @@ RUN go mod download
|
|||
|
||||
## Build the image
|
||||
|
||||
Now that we've created our `Dockerfile`, let’s build an image from it. The `docker build` command creates Docker images from the `Dockerfile` and a "context". A build _context_ is the set of files located in the specified path or URL. The Docker build process can access any of the files located in the context.
|
||||
Now that we've created our `Dockerfile`, let’s build an image from it. The
|
||||
`docker build` command creates Docker images from the `Dockerfile` and a "context".
|
||||
A build _context_ is the set of files located in the specified path or URL. The
|
||||
Docker build process can access any of the files located in the context.
|
||||
|
||||
The build command optionally takes a `--tag` flag. This flag is used to label the image with a string value, which is easy for humans to read and recognise. If you do not pass a `--tag`, Docker will use `latest` as the default value.
|
||||
The build command optionally takes a `--tag` flag. This flag is used to label
|
||||
the image with a string value, which is easy for humans to read and recognise.
|
||||
If you do not pass a `--tag`, Docker will use `latest` as the default value.
|
||||
|
||||
Let's build our first Docker image!
|
||||
|
||||
|
|
@ -262,42 +317,61 @@ $ docker build --tag docker-gs-ping .
|
|||
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
|
||||
```
|
||||
|
||||
Your exact output will vary, but provided there aren't any errors, you should see the `FINISHED` line in the build output. This means Docker has successfully built our image and assigned a `docker-gs-ping` tag to it.
|
||||
Your exact output will vary, but provided there aren't any errors, you should
|
||||
see the `FINISHED` line in the build output. This means Docker has successfully
|
||||
built our image and assigned a `docker-gs-ping` tag to it.
|
||||
|
||||
## View local images
|
||||
|
||||
To see the list of images we have on our local machine, we have two options. One is to use the CLI and the other is to use [Docker Desktop](../../desktop/index.md). Since we are currently working in the terminal, let’s take a look at listing images with the CLI.
|
||||
To see the list of images we have on our local machine, we have two options. One
|
||||
is to use the CLI and the other is to use [Docker Desktop](../../desktop/index.md).
|
||||
Since we are currently working in the terminal, let’s take a look at listing
|
||||
images with the CLI.
|
||||
|
||||
To list images, simply run the `images` command:
|
||||
To list images, run the `docker image ls`command (or the `docker images` shorthand):
|
||||
|
||||
```console
|
||||
$ docker images
|
||||
$ docker image ls
|
||||
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
docker-gs-ping latest 336a3f164d0f 39 minutes ago 540MB
|
||||
postgres 13.2 c5ec7353d87d 7 weeks ago 314MB
|
||||
```
|
||||
|
||||
Your exact output may vary, but you should see `docker-gs-ping` image with the `latest` tag.
|
||||
Your exact output may vary, but you should see `docker-gs-ping` image with the
|
||||
`latest` tag.
|
||||
|
||||
## Tag images
|
||||
|
||||
An image name is made up of slash-separated name components. Name components may contain lowercase letters, digits and separators. A separator is defined as a period, one or two underscores, or one or more dashes. A name component may not start or end with a separator.
|
||||
An image name is made up of slash-separated name components. Name components may
|
||||
contain lowercase letters, digits and separators. A separator is defined as a
|
||||
period, one or two underscores, or one or more dashes. A name component may not
|
||||
start or end with a separator.
|
||||
|
||||
An image is made up of a manifest and a list of layers. In simple terms, a “tag” points to a combination of these artifacts. You can have multiple tags for the image and, in fact, most images have multiple tags. Let’s create a second tag for the image we had built and take a look at its layers.
|
||||
An image is made up of a manifest and a list of layers. In simple terms, a “tag”
|
||||
points to a combination of these artifacts. You can have multiple tags for the
|
||||
image and, in fact, most images have multiple tags. Let’s create a second tag
|
||||
for the image we had built and take a look at its layers.
|
||||
|
||||
To create a new tag for our image, run the following command.
|
||||
Use the `docker image tag` (or `docker tag` shorthand) command to create a new
|
||||
tag for our image. This command takes two arguments; the first argument is the
|
||||
"source" image, and the second is the new tag to create. The following command
|
||||
creates a new `docker-gs-ping:v1.0` tag for the `docker-gs-ping:latest` we built
|
||||
above:
|
||||
|
||||
```console
|
||||
$ docker tag docker-gs-ping:latest docker-gs-ping:v1.0
|
||||
$ docker image tag docker-gs-ping:latest docker-gs-ping:v1.0
|
||||
```
|
||||
|
||||
The Docker `tag` command creates a new tag for the image. It does not create a new image. The tag points to the same image and is just another way to reference the image.
|
||||
The Docker `tag` command creates a new tag for the image. It does not create a
|
||||
new image. The tag points to the same image and is just another way to reference
|
||||
the image.
|
||||
|
||||
Now run the `docker images` command to see the updated list of local images:
|
||||
Now run the `docker image ls` command again to see the updated list of local
|
||||
images:
|
||||
|
||||
```console
|
||||
$ docker images
|
||||
$ docker image ls
|
||||
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
docker-gs-ping latest 336a3f164d0f 43 minutes ago 540MB
|
||||
|
|
@ -305,34 +379,49 @@ docker-gs-ping v1.0 336a3f164d0f 43 minutes ago 540MB
|
|||
postgres 13.2 c5ec7353d87d 7 weeks ago 314MB
|
||||
```
|
||||
|
||||
You can see that we have two images that start with `docker-gs-ping`. We know they are the same image because if you look at the `IMAGE ID` column, you can see that the values are the same for the two images. This value is a unique identifier Docker uses internally to identify the image.
|
||||
You can see that we have two images that start with `docker-gs-ping`. We know
|
||||
they are the same image because if you look at the `IMAGE ID` column, you can
|
||||
see that the values are the same for the two images. This value is a unique
|
||||
identifier Docker uses internally to identify the image.
|
||||
|
||||
Let’s remove the tag that we had just created. To do this, we’ll use the `rmi` command, which stands for "remove image":
|
||||
Let’s remove the tag that we had just created. To do this, we’ll use the
|
||||
`docker image rm` command, or the shorthand `docker rmi` (which stands for
|
||||
"remove image"):
|
||||
|
||||
```console
|
||||
$ docker rmi docker-gs-ping:v1.0
|
||||
$ docker image rm docker-gs-ping:v1.0
|
||||
Untagged: docker-gs-ping:v1.0
|
||||
```
|
||||
|
||||
Notice that the response from Docker tells us that the image has not been removed but only "untagged". Verify this by running the images command:
|
||||
|
||||
```console
|
||||
$ docker images
|
||||
$ docker image ls
|
||||
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
docker-gs-ping latest 336a3f164d0f 45 minutes ago 540MB
|
||||
postgres 13.2 c5ec7353d87d 7 weeks ago 314MB
|
||||
```
|
||||
|
||||
The tag `v1.0` has been removed but we still have the `docker-gs-ping:latest` tag available on our machine, so the image is there.
|
||||
The tag `v1.0` has been removed but we still have the `docker-gs-ping:latest`
|
||||
tag available on our machine, so the image is there.
|
||||
|
||||
## Multi-stage builds
|
||||
|
||||
You may have noticed that our `docker-gs-ping` image stands at 540MB, which you may think is a lot. You may also be wondering whether our dockerized application still needs the full suite of Go tools, including the compiler, after the application binary had been compiled.
|
||||
You may have noticed that our `docker-gs-ping` image stands at 540MB, which you
|
||||
may think is a lot. You may also be wondering whether our dockerized application
|
||||
still needs the full suite of Go tools, including the compiler, after the
|
||||
application binary had been compiled.
|
||||
|
||||
These are legit concerns. Both can be solved by using _multi-stage builds_. The following example is provided with little explanation because this would derail us from our current concerns, but please feel free to explore on your own later. The main idea is that we use one image to produce some artefacts, which are then placed into another, much smaller image, containing only the parts necessary for running the artefacts that we'd built.
|
||||
These are legit concerns. Both can be solved by using _multi-stage builds_. The
|
||||
following example is provided with little explanation because this would derail
|
||||
us from our current concerns, but please feel free to explore on your own later.
|
||||
The main idea is that we use one image to produce some artefacts, which are then
|
||||
placed into another, much smaller image, containing only the parts necessary for
|
||||
running the artefacts that we'd built.
|
||||
|
||||
The `Dockerfile.multistage` in the sample application's repo has the following content:
|
||||
The `Dockerfile.multistage` in the sample application's repo has the following
|
||||
content:
|
||||
|
||||
{% raw %}
|
||||
```dockerfile
|
||||
|
|
@ -370,34 +459,50 @@ ENTRYPOINT ["/docker-gs-ping"]
|
|||
```
|
||||
{% endraw %}
|
||||
|
||||
Since we have two dockerfiles now, we have to tell Docker that we want to build using our new Dockerfile. We also tag the new image with `multistage` but this word has no special meaning, we only do so that we could compare this new image to the one we've built previously, that is the one we tagged with `latest`:
|
||||
Since we have two dockerfiles now, we have to tell Docker that we want to build
|
||||
using our new Dockerfile. We also tag the new image with `multistage` but this
|
||||
word has no special meaning, we only do so that we could compare this new image
|
||||
to the one we've built previously, that is the one we tagged with `latest`:
|
||||
|
||||
```console
|
||||
$ docker build -t docker-gs-ping:multistage -f Dockerfile.multistage .
|
||||
```
|
||||
|
||||
Comparing the sizes of `docker-gs-ping:multistage` and `docker-gs-ping:latest` we see an order-of-magnitude difference!
|
||||
Comparing the sizes of `docker-gs-ping:multistage` and `docker-gs-ping:latest`
|
||||
we see an order-of-magnitude difference!
|
||||
|
||||
```console
|
||||
$ docker images
|
||||
$ docker image ls
|
||||
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
docker-gs-ping multistage e3fdde09f172 About a minute ago 27.1MB
|
||||
docker-gs-ping latest 336a3f164d0f About an hour ago 540MB
|
||||
```
|
||||
|
||||
This is due to the fact that the ["distroless" base image](https://github.com/GoogleContainerTools/distroless) that we have used to deploy our Go application is very barebones and is meant for lean deployments of static binaries.
|
||||
This is due to the fact that the ["distroless" base image](https://github.com/GoogleContainerTools/distroless){:target="_blank" rel="noopener" class="_"}
|
||||
that we have used to deploy our Go application is very barebones and is meant
|
||||
for lean deployments of static binaries.
|
||||
|
||||
For more information on multi-stage builds, please feel free to check out [other parts](../../develop/develop-images/multistage-build.md) of Docker documentation. This is, however, not essential for our progress here, so we'll leave it at that.
|
||||
For more information on multi-stage builds, please feel free to check out
|
||||
[other parts](../../develop/develop-images/multistage-build.md) of the Docker
|
||||
documentation. This is, however, not essential for our progress here, so we'll
|
||||
leave it at that.
|
||||
|
||||
## Next steps
|
||||
|
||||
In this module, we took a look at setting up our example Go application that we will use for much of the rest of the tutorial. We also created a `Dockerfile` that we used to build our Docker image. Then, we took a look at tagging our images and removing images and tags. In the next module, we’ll take a look at how to:
|
||||
In this module, we took a look at setting up our example Go application that we
|
||||
will use for much of the rest of the tutorial. We also created a `Dockerfile`
|
||||
that we used to build our Docker image. Then, we took a look at tagging our
|
||||
images and removing images and tags. In the next module, we’ll take a look at
|
||||
how to:
|
||||
|
||||
[Run your image as a container](run-containers.md){: .button .outline-btn}
|
||||
|
||||
## Feedback
|
||||
|
||||
Help us improve this topic by providing your feedback. Let us know what you think by creating an issue in the [Docker Docs ](https://github.com/docker/docker.github.io/issues/new?title=[Golang%20docs%20feedback]){:target="_blank" rel="noopener" class="_"} GitHub repository. Alternatively, [create a PR](https://github.com/docker/docker.github.io/pulls){:target="_blank" rel="noopener" class="_"} to suggest updates.
|
||||
Help us improve this topic by providing your feedback. Let us know what you
|
||||
think by creating an issue in the [Docker Docs](https://github.com/docker/docker.github.io/issues/new?title=[Golang%20docs%20feedback]){:target="_blank" rel="noopener" class="_"}
|
||||
GitHub repository. Alternatively, [create a PR](https://github.com/docker/docker.github.io/pulls){:target="_blank" rel="noopener" class="_"}
|
||||
to suggest updates.
|
||||
|
||||
<br />
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ Now that we have a good overview of containers and the Docker platform, let’s
|
|||
|
||||
To complete this tutorial, you need the following:
|
||||
|
||||
- Java OpenJDK version 15 or later. [Download and install Java](https://jdk.java.net/){: target="_blank" rel="noopener" class="_"}
|
||||
- Docker running locally. Follow the instructions to [download and install Docker](../../get-docker.md)
|
||||
- A Git client
|
||||
- An IDE or a text editor to edit files. We recommend using [IntelliJ Community Edition](https://www.jetbrains.com/idea/download/){: target="_blank" rel="noopener" class="_"}.
|
||||
|
|
@ -33,7 +32,17 @@ $ git clone https://github.com/spring-projects/spring-petclinic.git
|
|||
$ cd spring-petclinic
|
||||
```
|
||||
|
||||
## Test the application
|
||||
## Test the application without Docker (optional)
|
||||
|
||||
In this step, we will test the application locally without Docker, before we
|
||||
continue with building and running the application with Docker. This section
|
||||
requires you to have Java OpenJDK version 15 or later installed on your machine.
|
||||
[Download and install Java](https://jdk.java.net/){: target="_blank" rel="noopener" class="_"}
|
||||
|
||||
If you prefer to not install Java on your machine, you can skip this step, and
|
||||
continue straight to the next section, in which we explain how to build and run
|
||||
the application in Docker, which does not require you to have Java installed on
|
||||
your machine.
|
||||
|
||||
Let’s start our application and make sure it is running properly. Maven will manage all the project processes (compiling, tests, packaging, etc). The **Spring Pets Clinic** project we cloned earlier contains an embedded version of Maven. Therefore, we don't need to install Maven separately on your local machine.
|
||||
|
||||
|
|
@ -54,9 +63,15 @@ o.s.s.petclinic.PetClinicApplication : Started
|
|||
PetClinicApplication in 11.743 seconds (JVM running for 12.364)
|
||||
```
|
||||
|
||||
## Create a Dockerfile for Java
|
||||
Great! We verified that the application works. At this stage, you've completed
|
||||
testing the server script locally.
|
||||
|
||||
Now that our application is running properly, let’s take a look at creating a Dockerfile.
|
||||
Press `CTRL-c` from within the terminal session where the server is running to stop it.
|
||||
|
||||
|
||||
We will now continue to build and run the application in Docker.
|
||||
|
||||
## Create a Dockerfile for Java
|
||||
|
||||
{% include guides/create-dockerfile.md %}
|
||||
|
||||
|
|
@ -69,28 +84,38 @@ we would like to use for our application.
|
|||
FROM openjdk:16-alpine3.13
|
||||
```
|
||||
|
||||
Docker images can be inherited from other images. Therefore, instead of creating our own base image, we’ll use the official Maven image with Java JDK that already has all the tools and packages that we need to run a Java application.
|
||||
Docker images can be inherited from other images. For this guide, we use the
|
||||
official `openjdk` image from Docker Hub with Java JDK that already has all the
|
||||
tools and packages that we need to run a Java application.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> To learn more about creating your own base images, see [Creating base images](https://docs.docker.com/develop/develop-images/baseimages/).
|
||||
|
||||
To make things easier when running the rest of our commands, let’s create a working directory. This instructs Docker to use this path as the default location for all subsequent commands. By doing this, we do not have to type out full file paths but can use relative paths based on the working directory.
|
||||
To make things easier when running the rest of our commands, let’s set the image's
|
||||
working directory. This instructs Docker to use this path as the default location
|
||||
for all subsequent commands. By doing this, we do not have to type out full file
|
||||
paths but can use relative paths based on the working directory.
|
||||
|
||||
```dockerfile
|
||||
WORKDIR /app
|
||||
```
|
||||
|
||||
Usually, the very first thing you do once you’ve downloaded a project written in Java which is using Maven for project management is to install dependencies.
|
||||
Usually, the very first thing you do once you’ve downloaded a project written in
|
||||
Java which is using Maven for project management is to install dependencies.
|
||||
|
||||
Before we can run `mvnw dependency`, we need to get the Maven wrapper and our `pom.xml` file into our image. We’ll use the `COPY` command to do this. The `COPY` command takes two parameters. The first parameter tells Docker what file(s) you would like to copy into the image. The second parameter tells Docker where you want that file(s) to be copied to. We’ll copy all those files and directories into our working directory - `/app`.
|
||||
Before we can run `mvnw dependency`, we need to get the Maven wrapper and our
|
||||
`pom.xml` file into our image. We’ll use the `COPY` command to do this. The
|
||||
`COPY` command takes two parameters. The first parameter tells Docker what
|
||||
file(s) you would like to copy into the image. The second parameter tells Docker
|
||||
where you want that file(s) to be copied to. We’ll copy all those files and
|
||||
directories into our working directory - `/app`.
|
||||
|
||||
```dockerfile
|
||||
COPY .mvn/ .mvn
|
||||
COPY mvnw pom.xml ./
|
||||
```
|
||||
|
||||
Once we have our `pom.xml` file inside the image, we can use the `RUN` command to execute the command `mvnw dependency:go-offline`. This works exactly the same way as if we were running `mvnw` (or mvn) dependency locally on our machine, but this time the dependencies will be installed into the image.
|
||||
Once we have our `pom.xml` file inside the image, we can use the `RUN` command
|
||||
to execute the command `mvnw dependency:go-offline`. This works exactly the same
|
||||
way as if we were running `mvnw` (or `mvn`) dependency locally on our machine,
|
||||
but this time the dependencies will be installed into the image.
|
||||
|
||||
```dockerfile
|
||||
RUN ./mvnw dependency:go-offline
|
||||
|
|
|
|||
|
|
@ -346,5 +346,5 @@ which can be wired up to achieve interesting behavior. If this system doesn't
|
|||
provide acceptable guarantees, adding a transactional `Sink` to the registry
|
||||
is a possibility, although it may have an effect on request service time.
|
||||
See the
|
||||
[godoc](http://godoc.org/github.com/docker/distribution/notifications#Sink)
|
||||
[godoc](https://godoc.org/github.com/docker/distribution/notifications#Sink)
|
||||
for more information.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ This storage driver package comes bundled with several drivers:
|
|||
- [s3](s3.md): A driver storing objects in an Amazon Simple Storage Service (S3) bucket.
|
||||
- [azure](azure.md): A driver storing objects in [Microsoft Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/).
|
||||
- [swift](swift.md): A driver storing objects in [Openstack Swift](https://docs.openstack.org/swift/latest/).
|
||||
- [oss](oss.md): A driver storing objects in [Aliyun OSS](http://www.aliyun.com/product/oss).
|
||||
- [oss](oss.md): A driver storing objects in [Aliyun OSS](https://www.aliyun.com/product/oss).
|
||||
- [gcs](gcs.md): A driver storing objects in a [Google Cloud Storage](https://cloud.google.com/storage/) bucket.
|
||||
|
||||
## Storage driver API
|
||||
|
|
@ -33,7 +33,7 @@ validation of the `storagedriver.StorageDriver` interface.
|
|||
|
||||
## Driver selection and configuration
|
||||
|
||||
The preferred method of selecting a storage driver is using the `StorageDriverFactory` interface in the `storagedriver/factory` package. These factories provide a common interface for constructing storage drivers with a parameters map. The factory model is based on the [Register](http://golang.org/pkg/database/sql/#Register) and [Open](http://golang.org/pkg/database/sql/#Open) methods in the builtin [database/sql](http://golang.org/pkg/database/sql) package.
|
||||
The preferred method of selecting a storage driver is using the `StorageDriverFactory` interface in the `storagedriver/factory` package. These factories provide a common interface for constructing storage drivers with a parameters map. The factory model is based on the [Register](https://golang.org/pkg/database/sql/#Register) and [Open](https://golang.org/pkg/database/sql/#Open) methods in the builtin [database/sql](https://golang.org/pkg/database/sql) package.
|
||||
|
||||
Storage driver factories may be registered by name using the
|
||||
`factory.Register` method, and then later invoked by calling `factory.Create`
|
||||
|
|
|
|||
|
|
@ -475,7 +475,7 @@ examines how much room they take up.
|
|||
> consumed by a container's writable layer, it does not include information
|
||||
> about metadata and log-files stored for each container.
|
||||
>
|
||||
> More details can be obtained my exploring the Docker Daemon's storage location
|
||||
> More details can be obtained by exploring the Docker Daemon's storage location
|
||||
> (`/var/lib/docker` by default).
|
||||
>
|
||||
> ```console
|
||||
|
|
|
|||
2
test.md
2
test.md
|
|
@ -322,7 +322,7 @@ You can nest captures within each other to represent more complex logic with Liq
|
|||
|
||||
This image was originally created on a white background and converted to a transparent background (or so it seems). In night-mode, the text still shows traces of the white and looks garbled. To fix this, we apply a white background inline with a class defined in _scss/_night-mode.css (and incorporated into style.css): `img.white-bg { background-color: white; }`.
|
||||
|
||||
{: .white-bg}
|
||||
{: .white-bg}
|
||||
|
||||
## Bootstrap and CSS tricks
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue