Remote builders improvements in flyctl v0.0.236

Along with the various improvements we’ve made to flyctl in August, we’re now launching new and improved remote builders (the little workers that launch and build your images when you don’t have Docker or you use --remote-only).

There has been various issues with the current remote builders. We get notified when exceptions arise while creating / waiting for remote builders and we’re not happy with the quantity we’re receiving :confused:

That said, flyctl v0.0.236 uses our new, revamped, remote builders. They’re actually more or less the same as before, but we’re bypassing most of our usual scheduling mechanisms and using a more direct route to create the firecracker microVMs powering our remote builders. They usually come up a lot faster and are less susceptible to a whole class of errors (by simply not having to do a lot of extra steps).

Let us know how it goes. You don’t have to do anything (except upgrade to v0.0.236) to start using the new remote builders.


I’ve been trying to use --remote-build as I’m on an M1 Mac where Docker just seems to be endless bugs.

Unfortunately I’ve yet to deploy using the --remote-build,flyctl v0.0.245 and the sample Elixir app from the docs. Using the command LOG_LEVEL=debug fly deploy --remote-build I get back the following:

Deploying old-glade-9579
==> Validating app configuration
DEBUG --> POST {{"query":"query($appName: String!, $definition: JSON!) { app(name: $appName) { parseConfig(definition: $definition) { definition valid errors services { description } } } }","variables":{"appName":"old-glade-9579","definition":{"deploy":{"release_command":"/app/bin/hello_elixir eval HelloElixir.Release.migrate"},"env":{},"experimental":{"allowed_public_ports":[],"auto_rollback":true},"kill_signal":"SIGTERM","kill_timeout":5,"processes":[],"services":[{"concurrency":{"hard_limit":25,"soft_limit":20,"type":"connections"},"http_checks":[],"internal_port":4000,"ports":[{"handlers":["http"],"port":80},{"handlers":["tls","http"],"port":443}],"processes":["app"],"protocol":"tcp","script_checks":[],"tcp_checks":[{"grace_period":"30s","interval":"15s","restart_limit":6,"timeout":"2s"}]}]}}}
DEBUG <-- 200 (415.22ms) {"data":{"app":{"parseConfig":{"definition":{"kill_timeout":5,"kill_signal":"SIGTERM","processes":[],"deploy":{"release_command":"/app/bin/hello_elixir eval HelloElixir.Release.migrate"},"experimental":{"allowed_public_ports":[],"auto_rollback":true},"services":[{"processes":["app"],"protocol":"tcp","internal_port":4000,"concurrency":{"soft_limit":20,"hard_limit":25,"type":"connections"},"ports":[{"port":80,"handlers":["http"]},{"port":443,"handlers":["tls","http"]}],"tcp_checks":[{"interval":"15s","timeout":"2s","grace_period":"30s","restart_limit":6}],"http_checks":[],"script_checks":[]}],"env":{}},"valid":true,"errors":[],"services":[{"description":"TCP 80/443 ⇢ 4000"}]}}}}
--> Validating app configuration done
TCP 80/443 ⇢ 4000
DEBUG trying remote docker daemon
DEBUG Trying 'Buildpacks' strategy
DEBUG no buildpack builder configured, skipping
DEBUG result image:<nil> error:<nil>
DEBUG Trying 'Dockerfile' strategy
DEBUG --> POST {{"query":"mutation($input: EnsureMachineRemoteBuilderInput!) { ensureMachineRemoteBuilder(input: $input) { machine { id state ips { nodes { family kind ip } } }, app { name organization { slug } } } }","variables":{"input":{"appName":"old-glade-9579","organizationId":null}}}
DEBUG <-- 500 (20.94s) {"errors":[{"message":"An unknown error occured.","extensions":{"code":"SERVER_ERROR"}}],"data":{}}
DEBUG result image:<nil> error:error connecting to docker: An unknown error occured.

Error error connecting to docker: An unknown error occured.

The Dockerfile I’m using is slightly different to accommodate Phoenix 1.6 that recently launched, but there’s nothing in there that strikes me as obviously wrong (posted below)

FROM hexpm/elixir:1.12.3-erlang-24.1.2-alpine-3.14.2 AS build

# install build dependencies
RUN apk add --no-cache build-base git curl python3

# prepare build dir

# extend hex timeout

# install hex + rebar
RUN mix local.hex --force && \
    mix local.rebar --force

# set build ENV as prod

# Copy over the mix.exs and mix.lock files to load the dependencies. If those
# files don't change, then we don't keep re-fetching and rebuilding the deps.
COPY mix.exs mix.lock ./
COPY config config

RUN mix deps.get --only prod && \
    mix deps.compile

# install npm dependencies
#COPY assets/package.json assets/package-lock.json ./assets/
#RUN npm --prefix ./assets ci --progress=false --no-audit --loglevel=error

COPY priv priv

# NOTE: If using TailwindCSS, it uses a special "purge" step and that requires
# the code in `lib` to see what is being used. Uncomment that here before
# running the npm deploy script if that's the case.
# COPY lib lib

# build assets
#RUN npm run --prefix ./assets deploy
#RUN mix phx.digest
COPY assets assets
RUN mix assets.deploy

# copy source here if not using TailwindCSS
COPY lib lib

# compile and build release
COPY rel rel
RUN mix do compile, release

### Second Stage - Setup the Runtime Environment

# prepare release docker image
FROM alpine:3.13.3 AS app
RUN apk add --no-cache libstdc++ openssl ncurses-libs


RUN chown nobody:nobody /app

USER nobody:nobody

COPY --from=build --chown=nobody:nobody /app/_build/prod/rel/hello_elixir ./


CMD ["bin/hello_elixir", "start"]

Anecdata: the above app and Dockerfile is running fine without the --remote-only flag from an Ubuntu server.

I know you’ve had problems with the remote-builds and done loads of work to get them working well, so I hate to be the bearer of bad news! Sorry.