LogoLogo
HomeBlogGitHubGet Started FreeLogin
Earthly 0.7
Earthly 0.7
  • 👋Introduction
  • 💻Install Earthly
  • 🎓Learn the basics
    • Part 1: A simple Earthfile
    • Part 2: Outputs
    • Part 3: Adding dependencies With Caching
    • Part 4: Args
    • Part 5: Importing
    • Part 6: Using Docker In Earthly
    • Part 7: Using remote runners
    • Part 8a: Using Earthly in your current CI
    • Final words
  • ⭐Featured guides
    • Rust
  • 📖Docs
    • Guides
      • Importing
      • Build arguments and secrets
      • Functions
      • Using Docker in Earthly
      • Multi-platform builds
      • Authenticating Git and image registries
      • Integration Testing
      • Debugging techniques
      • Podman
      • Configuring registries
        • AWS ECR
        • GCP Artifact Registry
        • Azure ACR
        • Self-signed certificates
      • Using the Earthly Docker Images
        • earthly/earthly
        • earthly/buildkitd
      • ✅Best practices
    • Caching
      • Caching in Earthfiles
      • Managing cache
      • Caching via remote runners
      • Caching via a registry (advanced)
    • Remote runners
    • Earthfile reference
      • Builtin args
      • Excluding patterns
      • Version-specific features
    • The earthly command
    • Earthly lib
    • Configuration reference
    • Examples
    • Misc
      • Alternative installation
      • Data collection
      • Definitions
      • Public key authentication
  • 🔧CI Integration
    • Overview
    • Use the Earthly CI Image
    • Build your own Earthly CI Image
    • Pull-Through Cache
    • Remote BuildKit
    • Vendor-Specific Guides
      • Jenkins
      • Circle CI
      • GitHub Actions
      • AWS CodeBuild
      • Kubernetes
      • Google Cloud Build
      • GitLab CI/CD
      • Woodpecker CI
      • Bitbucket Pipelines
  • ☁️ Earthly Cloud
    • Overview
    • Managing permissions
    • Cloud secrets
    • Earthly Satellites
      • Managing Satellites
      • Using Satellites
Powered by GitBook
On this page
  • Not All Targets Produce Output
  • Saving Files
  • Saving Docker Images
  • The Push Flag

Was this helpful?

Edit on GitHub
  1. Learn the basics

Part 2: Outputs

PreviousPart 1: A simple EarthfileNextPart 3: Adding dependencies With Caching

Last updated 2 years ago

Was this helpful?

To copy the files for run

earthly --artifact github.com/earthly/earthly/examples/tutorial/go:main+part2/part2 ./part2

Examples in , and are at the bottom of this page.

Not All Targets Produce Output

Targets have the ability to produce output outside of the build environment. You can save files and docker images to your local machine or push them to remote repositories. Targets can also run commands that affect the local environment outside of the build, such as running database migrations, but not all targets produce output. Let's take a look at which commands produce output and how to use them.

Saving Files

We've already seen how the command copies a file or directory from the build environment into the target's artifact environment.

This gives us the ability to copy files between targets, but it does not allow us to save any files to our local machine.

build:
    COPY main.go .
    RUN go build -o output/example main.go
    SAVE ARTIFACT output/example

docker:
    #  COPY command copies files from the +build target
    COPY +build/example .
    ENTRYPOINT ["/go-workdir/example"]
    SAVE IMAGE go-example:latest

In order to save the file locally , we need to add AS LOCAL to the command.

build:
    COPY main.go .
    RUN go build -o output/example main.go
    SAVE ARTIFACT output/example AS LOCAL local-output/go-example

If we run this example with earthly +build, we'll see a local-output directory show up locally with a go-example file inside of it.

Saving Docker Images

Saving Docker images to your local machine is easy with the SAVE IMAGE command.

build:
    COPY main.go .
    RUN go build -o output/example main.go
    SAVE ARTIFACT output/example

docker:
    COPY +build/example .
    ENTRYPOINT ["/go-workdir/example"]
    SAVE IMAGE go-example:latest

In this example, running earthly +docker will save an image named go-example with the tag latest.

~$ earthly +docker
...
~$ docker image ls
REPOSITORY          TAG       IMAGE ID       CREATED          SIZE
go-example          latest    08b9f749023d   19 seconds ago   297MB

# or podman
~$ podman image ls
REPOSITORY          TAG       IMAGE ID       CREATED          SIZE
go-example          latest    08b9f749023d   19 seconds ago   297MB

NOTE

If we run a target as a reference in FROM or COPY, outputs will not be produced. Take this Earthfile for example.

build:
    COPY main.go .
    RUN go build -o output/example main.go
    SAVE ARTIFACT output/example AS LOCAL local-output/go-example

docker:
    COPY +build/example .
    ENTRYPOINT ["/go-workdir/example"]
    SAVE IMAGE go-example:latest

In this case, running earthly +docker will not produce any output. In other words, you will not have a local-output/go-example written locally, but running earthly +build will still produce output as expected.

The exception to this rule is the BUILD command. If you want to use COPY or FROM and still have Earthly create local-output/go-example locally, you'll need to use the BUILD command to do so.

build:
    COPY main.go .
    RUN go build -o output/example main.go
    SAVE ARTIFACT output/example AS LOCAL local-output/go-example

docker:
    BUILD +build
    COPY +build/example .
    ENTRYPOINT ["/go-workdir/example"]
    SAVE IMAGE go-example:latest

Running earthly +docker in this case will now output local-output/go-example locally.

The Push Flag

Docker Images

In addition to saving files and images locally, we can also push them to remote repositories.

docker:
    COPY +build/example .
    ENTRYPOINT ["/go-workdir/example"]
    SAVE IMAGE --push go-example:latest

Note that adding the --push flag to SAVE IMAGE is not enough, we'll also need to invoke push when we run earthly. earthly --push +docker.

External Changes

You can also use --push as part of a RUN command to define commands that have an effect external to the build. These kinds of effects are only allowed to take place if the entire build succeeds.

This allows you to push to remote repositories.

release:
    RUN --push --secret GITHUB_TOKEN=GH_TOKEN github-release upload
earthly --push +release

But also allows you to do things like run database migrations.

migrate:
    FROM +build
    RUN --push bundle exec rails db:migrate
earthly --push +migrate

Or apply terraform changes

apply:
    RUN --push terraform apply -auto-approve
earthly --push +apply

NOTE

Just like saving files, any command that uses --push will only produce output if called directly, earthly --push +target-with-push or via a BUILD command. Calling a target via FROM or COPY will not invoke --push.

More Examples

JavaScript
mkdir tutorial
cd tutorial
earthly --artifact github.com/earthly/earthly/examples/tutorial/js:main+part2/part2 ./part2

./Earthfile

VERSION 0.7
FROM node:13.10.1-alpine3.11
WORKDIR /js-example

build:
    # In JS, there's nothing to build in this simple form.
    # The source is also the artifact used in production.
    COPY src/index.js .
    SAVE ARTIFACT index.js /dist/index.js AS LOCAL ./dist/index.js

docker:
    COPY +build/dist dist
    ENTRYPOINT ["node", "./dist/index.js"]
    SAVE IMAGE js-example:latest

The code of the app might look like this

./src/index.js

console.log("hello world");
Java
mkdir tutorial
cd tutorial
earthly --artifact github.com/earthly/earthly/examples/tutorial/java:main+part2/part2 ./part2

./Earthfile

VERSION 0.7
FROM openjdk:8-jdk-alpine
RUN apk add --update --no-cache gradle
WORKDIR /java-example

build:
    COPY build.gradle ./
    COPY src src
    RUN gradle build
    RUN gradle install
    SAVE ARTIFACT build/install/java-example/bin /bin AS LOCAL build/bin
    SAVE ARTIFACT build/install/java-example/lib /lib AS LOCAL build/lib

docker:
    COPY +build/bin bin
    COPY +build/lib lib
    ENTRYPOINT ["/java-example/bin/java-example"]
    SAVE IMAGE java-example:latest

The code of the app might look like this

./src/main/java/hello/HelloWorld.java


package hello;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

./build.gradle

apply plugin: 'java'
apply plugin: 'application'

mainClassName = 'hello.HelloWorld'

jar {
    baseName = 'hello-world'
    version = '0.0.1'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8
Python
mkdir tutorial
cd tutorial
earthly --artifact github.com/earthly/earthly/examples/tutorial/python:main+part2/part2 ./part2

./Earthfile

VERSION 0.7
FROM python:3
WORKDIR /code

build:
     # In Python, there's nothing to build.
    COPY src src
    SAVE ARTIFACT src /src

docker:
    COPY +build/src src
    ENTRYPOINT ["python3", "./src/hello.py"]
    SAVE IMAGE --push python-example:latest

The code of the app might look like this

./src/hello.py

print("hello world")

To copy the files for run

To copy the files for run

To copy the files for run

🎓
this example ( Part 2 )
this example ( Part 2 )
this example ( Part 2 )
this example ( Part 2 )
SAVE ARTIFACT
Python
JavaScript
Java