fly console --dockerfile and --image flags

If you’ve ever used docker, you likely are very familiar with the docker run command in general, and the -rm -i -t options in particular. Taken together, you can run a command against an image in a new container. And it launches really fast.

If you’ve used fly (and that’s most of you given that you are here), you’ve probably launched a long running full stack application, likely with a separate database, and perhaps with a few long running processes.

Along the way you’ve likely used a builder, may have a deploy release command defined, or perhaps used the terminal. These are examples of ephemeral machines.

If you wanted to create your own ephemeral machine with a different image, you would have to take a number of steps to build the image and then either create a new application, temporarily override fly.toml, use the API, and likely forego the interactive terminal experience.

That changes today, with flyctl v0.1.102. Update to the latest and try:

flyctl console --image ubuntu:latest -C /bin/bash

Now you are in a command window. Try:

cat /etc/lsb-release

Now lets try something more fancy. Create a Dockerfile.test with the following:

FROM flyio/flyctl:latest as flyio
FROM debian:bullseye-slim

RUN apt-get update; apt-get install -y ca-certificates
COPY --from=flyio /flyctl /usr/bin

WORKDIR /build
COPY . .

Now run:

flyctl console --dockerfile dockerfile.test -C /bin/bash --env=FLY_API_TOKEN=$(fly auth token)

You are in a new container, with all of your source code (minus anything listed in .dockerignore), and have flyctl. You can run flyctl deploy from here if you like. Or you can skip a step and run flyctl deploy instead of /bin/bash:

flyctl console --dockerfile dockerfile.test -C "flyctl deploy" --env=FLY_API_TOKEN=$(fly auth token)

The hope is that this enables all sorts of use cases. Some examples:

  • A DB seed script that needs a separate image (or build target) with devDependencies included and access to DATABASE_URL
  • A console image/script with a number of tools preloaded that are not needed on deployment images.
  • A custom build process with access to build secrets and the ability to do things like pre-render static pages based on the contents of a database.

These are just a few ideas to spark discussion. If you have others, let us know! Hopefully we can share ideas, and over time as common patterns emerge direct support can be added to flyctl. I’ll close with a more complex Dockerfile that adds build secrets when running fly deploy:

# syntax = docker/dockerfile:1

FROM flyio/flyctl:latest as flyio
FROM debian:bullseye-slim

RUN apt-get update; apt-get install -y ca-certificates jq

COPY <<"EOF" /srv/deploy.sh
#!/bin/bash
deploy=(flyctl deploy)

while read -r secret; do
  deploy+=(--build-secret "${secret}=${!secret}")
done < <(flyctl secrets list --json | jq -r ".[].Name")

${deploy[@]}
EOF

RUN chmod +x /srv/deploy.sh

COPY --from=flyio /flyctl /usr/bin

WORKDIR /build
COPY . .
5 Likes

Would be even cooler if we could use it without creating an app first :wink:

3 Likes

This is a smidge more moving pieces than I personally care for, but it’s a great stop-gap while a less-leaky solution gets put together. I enjoy the approach of: let’s just build on top of the APIs that we use. Like… it’s cool not having to learn a completely new flow. and it’s something like this that would push me towards a buildpack. I don’t want this script anywhere near my repos for the fear of ever having to change it and for the fear of what my developers might do with it.