Consider the following Layerfile:

FROM vm/ubuntu:18.04

# install the latest version of Docker, as in the official Docker installation tutorial.
RUN apt-get update && \
    apt-get install ca-certificates curl gnupg lsb-release && \
    sudo mkdir -p /etc/apt/keyrings && \
    curl -fsSL | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \
    echo \
    "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] $(lsb_release -cs) stable" |\
    sudo tee /etc/apt/sources.list.d/docker.list > /dev/null && \
    apt-get update && \
    apt-get install docker-ce docker-ce-cli python3 python3-pip awscli

# install docker compose (easily starts required docker containers)
RUN curl -L "$(uname -s)-$(uname -m)" \
    -o /usr/local/bin/docker-compose

# copy files from the repository into this staging server
COPY . .

# start everything - RUN REPEATABLE is a performance improvement that restores the cache from the last time this step ran.
RUN REPEATABLE compose up -d --build --force-recreate --remove-orphans db redis
# run migrations
RUN docker-compose run web python3 migrate
# download anonymized prod data dump
RUN aws s3 cp s3://staging_db_dumps/staging.sql /tmp/staging.sql
RUN cat /tmp/staging.sql | docker-compose exec -T db psql

There’s a lot to unpack here, but there are a few important takeaways from this example:

  1. You can install docker & docker-compose and efficiently create containers within a Layerfile
  2. RUN REPEATABLE lets you reuse built images & volumes from the last time this pipeline ran
  3. will create a snapshot with everything created so that you can avoid re-building, re-creating, and re-migrating database data every time.

As before, other Layerfiles can extend from this one to run e2e tests or create a full-stack demo environment with EXPOSE WEBSITE.