DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Alexey Poimtsev (he/hehe)
Alexey Poimtsev (he/hehe)

Posted on • Updated on • Originally published at alec-c4.com

Better builds with earthly

I like to automate everything. It saves time which I can to spend to develop another automation :)

Today I'd like to show you how to use earthly to automate your build processes.

Installation

Installation process is very simple - (if you're using macOS like me) all you need is a docker, homebrew and git. Just run from your terminal

$ brew install earthly/earthly/earthly && earthly bootstrap
Enter fullscreen mode Exit fullscreen mode

And that's it. If you are Linux or Windows user - you can check this guide.

How to use earthly

Firstly, let's define our task. I'd like to propose to you to develop a script which will build a simple astro-based application, let's say - some landing page. Later I'll write a post about benefits of astro, but now let's focus on earthly.

In most cases, all you need is to just write 2 files - Earthfile and .earthlyignore, so let's do it!

Let's start with Earthfile. I'll write the following tasks:

  • deps - to download dependencies
  • build - to build an application
  • docker - do create and save docker image

Earthfile looks like a mutant with a genes of Makefile and Docker, but it is a powerful creature :)

VERSION 0.6
FROM node:latest
WORKDIR /app
ARG image_name=blog
Enter fullscreen mode Exit fullscreen mode

First line VERSION 0.6 defines the version of the Earthfile. Currently, it is 0.6. Lines 2 and 3 is quite similar to Dockerfile and defines parental package and working directory in our container.

deps: 
  RUN npm install -g pnpm
  COPY package.json pnpm-lock.yaml* ./
  RUN pnpm install
  SAVE ARTIFACT package.json   AS LOCAL ./package.json
  SAVE ARTIFACT pnpm-lock.yaml AS LOCAL ./pnpm-lock.yaml
  RUN pnpm add object-hash potrace find-cache-dir @astropub/codecs file-type 
Enter fullscreen mode Exit fullscreen mode

Line deps: - is the name of the target. You can call this target from command line with following command (just prepend name of the target with "+" sign):

$ earthly +deps
Enter fullscreen mode Exit fullscreen mode

Next 3 lines (and the last one on this code block) are similar with Dockerfile - it is about to install pnpm, copy package.json and pnpm-lock.yaml files and running pnpm command. But I'd like to ask you to have a look at the next 2 lines

  SAVE ARTIFACT package.json   AS LOCAL ./package.json
  SAVE ARTIFACT pnpm-lock.yaml AS LOCAL ./pnpm-lock.yaml
Enter fullscreen mode Exit fullscreen mode

Everything we've done before was in the container, but now we need to save those files locally. SAVE ARTIFACT ... AS LOCAL ... allows you to export data from the container to the local filesystem.

build:
    FROM +deps
    COPY . .
    RUN pnpm run build
    SAVE ARTIFACT dist /dist AS LOCAL dist
Enter fullscreen mode Exit fullscreen mode

Another one part of our Earthfile. Nothing new for you, except FROM +deps. This line forces earthly to call deps-target before build. Note that target name must be start with "+".

docker:
    FROM nginx
    COPY +build/dist /usr/share/nginx/html
    EXPOSE 80
    SAVE IMAGE --push ${image_name}:latest
Enter fullscreen mode Exit fullscreen mode

Well, the last part of our config. There are two lines you need to focus on. COPY +build/dist /usr/share/nginx/html - with this command we took everything in dist-directory we've produced in our build-target and copy it to the local environment. SAVE IMAGE --push ${image_name}:latest - uses this command we save what we've done before as a docker image, which can be used later in production environment.

Everything works fine, but there is one more thing I've mentioned before - .earthlyignore file. This file is useful when you copy directory, but you need to avoid copying of some files or directories to your container. The format of this file is similar with .dockerignore and .gitignore - everything you need to ignore is located on the new line.

Finally - the complete Earthfile

VERSION 0.6
FROM node:latest
WORKDIR /app
ARG image_name=blog

deps: 
    RUN npm install -g pnpm
    COPY package.json pnpm-lock.yaml* ./
    RUN pnpm install
    SAVE ARTIFACT package.json   AS LOCAL ./package.json
    SAVE ARTIFACT pnpm-lock.yaml AS LOCAL ./pnpm-lock.yaml
    RUN pnpm add object-hash potrace find-cache-dir @astropub/codecs file-type 

build:
    FROM +deps
    COPY . .
    RUN pnpm run build
    SAVE ARTIFACT dist /dist AS LOCAL dist

docker:
    FROM nginx
    COPY +build/dist /usr/share/nginx/html
    EXPOSE 80
    SAVE IMAGE --push ${image_name}:latest
Enter fullscreen mode Exit fullscreen mode

and .earthlyignore

node_modules
.git
.gitignore
.earthlyignore
.idea
.vscode
dist
Enter fullscreen mode Exit fullscreen mode

Looking for more? Check my blog https://alec-c4.com

Top comments (0)

Why You Need to Study Javascript Fundamentals

The harsh reality for JS Developers: If you don't study the fundamentals, you'll be just another β€œCoder”. Top learnings on how to get to the mid/senior level faster as a JavaScript developer by Dragos Nedelcu.