docker run), Earthly makes available isolated Docker daemons which are started and stopped on-demand. The reason for using isolated instances of Docker daemons is such that no pre-existing Docker state (e.g. images, containers, networks, volumes) can influence the way the build executes. This allows Earthly to achieve high degrees of reproducibility.
docker runin Earthly:
FROM earthly/dind:alpineinherits from an Earthly-supported docker-in-docker (dind) image. This is recommended, because
WITH DOCKERrequires all the Docker binaries (not just the client) to be present in the build environment.
WITH DOCKER ... ENDstarts a Docker daemon for the purpose of running Docker commands against it. At the end of the execution, this also terminates the daemon and permanently deletes all of its data (e.g. daemon cached images).
--pull hello-worldpulls the image
hello-worldfrom the Docker Hub. This option could have been replaced with the more traditional
docker pull hello-world. However, the Earthly variant additionally stores the image in the Earthly cache, so that the actual pull is performed only if the image changes. Because the daemon cache is cleared after each run,
docker pullwould not achieve the same.
RUN docker run hello-worldexecutes the
docker runcommand in the context of the daemon created by
WITH DOCKER --load ...=...can be used. Here is an example:
--load test:latest=+buildtakes the image produced by the target
+buildand loads it into the Docker daemon created by
WITH DOCKERas the image with the tag
test:latest. The tag can then be used to reference this image in other docker commands, such as
my-image:latest. This image name is not available in the
WITH DOCKERenvironment, however, as it is only used to tag for use outside of Earthly. The name
test:latestis used instead.
WITH DOCKER, either explicitly, simply by running the
docker-composetool, or implicitly, via the
--composeflag allows you to specify a Docker compose stack that needs to be brought up before the execution of the
RUNcommand. For example:
--composeflag has the added benefit that any images needed by the compose stack will be automatically added to the pull list by Earthly, thus using cache efficiently.
RUNcommand is allowed within the
WITH DOCKERclause. The reason for this is that only one cache layer is used for the entire clause. You can, however, chain multiple shell commands together within a single
RUNcommand. For example:
WITH DOCKERclause inherits from a supported Docker-in-Docker (dind) image such as
earthly/dind:ubuntu. If your build requires the use of an alternative environment as part of a test (e.g. to run commands like
go testtogether with a docker-compose stack), consider placing the test itself in a Docker image, then loading that image via
--loadand running the test as a Docker container.
--compose. Even though commands such as
docker runautomatically pull an image if it is not found locally, it will do so every single time the
WITH DOCKERclause is executed, due to Docker caching not being preserved between runs. Pre-declaring the images ensures that they are properly cached by Earthly to minimize unnecessary redownloads.
docker-composestack fails, you cannot execute commands like
docker logson the host. However, you may use the interactive mode to drop into a shell within the build environment and execute such commands there. For more information, see the debugging guide.
/var/run/docker.sockin order to use the host Docker daemon. This goes against Earthly's principles of keeping execution repeatable. Mounting the Docker socket may cause builds to depend on the host Daemon state (e.g. pre-cached images) in ways that may not be obvious or easy to reproduce if the build were executed in another environment.
docker run -v ...could (instead, a
COPYcommand could be used); or not being able to run multiple containers in parallel. However, when appropriate, it can simplify a build definition.
docker buildwithin Earthly is discouraged, as it has a number of key limitations:
WITH DOCKERdoes not preserve Docker cache between runs (other than
docker build, it is advisable to use the Earthly command
FROM DOCKERFILE. For example, the command
docker build -t my-image:latest .can be emulated by: