I would like to programmatically launch and deploy an app using node.js. I see some info about how to create a new app and new machine with a Docker image, but not how to use the REST API to launch and deploy versions of an app.
For example, on AWS Lambda I can zip up a directory and deploy that as a function. I would like to to the same with a collection of files like fly.toml, Dockerfile, server.ts, etc.
Is there documentation on how to include a zip? I am following the tutorial to run user code on fly machines, so I can’t run the command line necessarily.
What fly will do is send only the files that have changed to to build machine which will build an OCI image from the result and push that to our repository from which it can be deployed.
I’m doing this from a serverless environment where I can’t spin up a child_process, so running a command line tool is not a possibility. I love fly deploy and use it locally. (You might think this is bad practice, but just bear with me for the point below. There are some legitimate considerations here like security of copying user files to a directory on a shared machine in order to integrate with fly deploy.)
The instructions here are incomplete in that they don’t provide any guidance on how to deploy actual user code, unless that code is a published docker image: Run User Code on Fly Machines · Fly Docs. Is there any documentation on how to do that?
Since you are willing to drop down to the API, let’s talk fundamentals.
The essence of fly is that it takes OCI images and launches them on micro VMs using firecracker. An OCI images is essentially a collection of tar files, so it roughly equivalent to a zip file.
So what I’m suggesting is that you produce an OCI image instead of zip file. You can use our builder to do that, or you can build it yourself, using Docker or perhaps Buildah. Fly deploy has --build-only and --push flags so you can have it stop part of the way if you like. If you want to push it yourself, the best docs I’ve seen on that are by Simon Willison: Using the Fly Docker registry | Simon Willison’s TILs.
Once pushed, you can use fly releases to get the image reference. There is a convenient --json option.
I don’t know what process you currently use to build a zip and sent it to the serverless environment, but if it could be adapted to build an OCI image, retrieve the image reference, and then send only the image reference to the serverless environment, then that process could proceed using only the fly api.
If, for some reason, zip is an absolute requirement and you can’t launch a local process; I’ll close with a parting thought. You can always start a fly machine on demand that launches flyctl. See Build Secrets · Fly Docs for an example of this approach. Explore that with your own application by copy/pasting the provided Dockerfile.builder and running the command at the bottom replacing /srv/deploy.sh with /bin/bash:
This is super helpful, thanks! I’m not attached to .zip, just mentioned it because that’s what works easily with AWS Lambda. It looks to me like making an OCI in TypeScript is not a well trodden path, so I think I’m going to follow the following approach:
Create a deployer app in fly.io that can take a zip file attachment with auth token via POST request.
The app will simply unzip the file, save it to a temporary directory, and then spawn a child process to cd into the directory, run fly deploy, and respond with the result.
Instead of deploying directly from my existing serverless app, I can instead send a zip to the deployer app, which will then deploy via the command line process described above.
I’ve never done anything like this but I have a different approach idea (might suck because like I said, never done anything like this)
I’d have one image used for every machine, and on start it’d download a zip file of the user code. The machines API has a way to set env variables and stuff. could also use volumes too if you don’t want to redownload every run.
Advantages I see to this is not having to deal with building docker images of user code which sounds like it’d be annoying maybe. also can have your own little server sitting in front of user code that does stuff for like requests logging or auth or whatever.
Does anyone have experience getting flyctl installed on a fly machine? I’ve been doing a bit of trial and error in the Dockerfile (e.g. versions of RUN curl -L https://fly.io/install.sh | sh), but no success yet.
UPDATE: FIGURED IT OUT. THIS WORKS:
FROM denoland/deno:latest as base
RUN apt-get update
RUN apt-get install -y curl
RUN curl -L https://fly.io/install.sh | sh
ENV PATH="/root/.fly/bin:$PATH"
COPY . .