Warning: This document is old! It is likely wrong in some important way.
For many web applications, the ability to scale, crop and otherwise manipulate images is essential. One way of providing this capability is with a URL-request-driven image service which can retrieve images, process them and deliver them wherever needed.But that also means provisioning the service globally to keep latency times low which can be its own administrative headache.With Fly you can eliminate all that administrative load by letting Fly deploy a service on demand close to your users so they get a rapidly rendered experience. In this guide, we’ll show you how to deploy a popular image processing application, Imaginary, into the Fly Global Application Platform to make your own Global Image Service.
Let’s start with h2non/Imaginary, a fantastically useful image processing application written in Go. Once configured, it lets you process images. The images can be posted to it or you can ask it to get an image from a remote server and all of this is controlled through a URL request to the Imaginary server.You can find all the source in the GitHub repository, but for this guide, we don’t need to worry about that. We’re going to use the developer-supplied Docker image to deploy it.
How do you turn a Docker image into a globally available edge application? With Fly it’s remarkably concise process.One thing we know at Fly is that our users want to deploy more than JavaScript at the edge. Powerful though that is, they also want fully fledged application stacks and backend components to live at the edge too. Now they can, and in this series of guides we’ll show you how to use them.In this first guide, we’re going to take an existing application and make it go global with Fly.
To use a Docker image, we’ll need a Dockerfile. Create a new directory and create a Dockerfile in it with these contents.
FROM h2non/imaginary:1.1.1ENV PORT "8080"CMD ["-enable-url-source","-http-read-timeout" ,"3"]
If you aren’t familiar with Docker, the first FROM line selects the image of the application and version we want to use. The Imaginary image is configured to run the imaginary command.Imaginary, running in a Docker container, normally opens a port on port 9000, but for this exercise, we want to open its port on 8080, Fly’s default port for external communications. The simplest way to do that is to set the PORT environment value to 8080.The third CMD line contains the parameters we pass to the imaginary command that are going to configure how Imaginary runs. The -enable-url-source tells Imaginary it is allowed to retrieve images from around the internet and, just so it’s well-behaved, we set the -http-read-timeout to 3 seconds (the default is 60 which is a long time to wait for an image).
You’ll need to have Docker installed locally to test this locally. We won’t go into the details of installing Docker - check out the Docker site and guides for how to install. Assuming you’ve done this we can move on to testing.
To test our local image, let’s process a file. In this case, we’re going to crop an existing image from Imaginary’s github repository.In another terminal session, run:
This will ask Imaginary to crop, to 100x100, an image stored in the Imaginary GitHub repository. This should result in a file, large.webp being written to disc which you can display using your preferred image viewer. MacOS users can simply open large.webp at the command line.Open the cropped image. Take a moment to play with the width and height values in the URL we’re querying and you will get different sized cropped images. Once you are happy the local build is working, you can return to the session where you started the docker image and ctrl-C to stop it.We now have a working docker image. Now to globally deploy it with Fly.
This will take you to the sign-up page where you can either:
Sign up with Email: Enter your name, email and password.
Sign up with GitHub: If you have a GitHub account, you can use that to sign up. Look out for the confirmatory email we will send you which will give you a link to set a password; you’ll need a password set so we can actively verify that it is you for some Fly operations.
Returning User
Run:
flyctl auth login
Your browser will open up with the Fly sign-in screen. Enter your user name and password to sign in. If you signed up with GitHub, use the Sign in with GitHub button to sign in.Whichever route you take you will be signed-up, signed-in and returned to your command line, ready to Fly.
The flyctl app helps you handle the entire lifecycle of your Fly Global application. That all starts with creating the fly.toml file which will control how your application is configured when deployed. To do so, run:
flyctl apps create
This will kick off a short dialogue with you about your new application. First up, it’ll ask for an application name:
? App Name (leave blank to use an auto-generated name) flyimaginary
Your name has to be unique across all Fly users, so unless there’s a good reason, go with an auto-generated name.Next you’ll be asked to select an organization. If this is your first time on Fly, there’ll only be one organization - your own personal organization, just for your applications. Organizations are all about sharing apps and collaborating. For this guide, we don’t need to worry about that, so we can use our personal organization.
? Select organization: Demo (demo)
Once the organization has been selected, flyctl gets to generating the app.
New app created Name = flyimaginary Owner = demo Version = 0 Status = Hostname = <empty>Wrote config file fly.toml
So, what’s in fly.toml? If you look in it, you’ll find various configuration parameters. You can skip to Deploying if you want to.
As well as the app name in the file, there’s a services section which sets what the internal port number exposed by the app is and how it should be handled. It also says this port should be handled as TCP.That’s followed by services.concurrency which sets soft and hard limits to the number of connections the application should take before being transparently scaled horizontally.There are also two services.ports sections. The first says incoming connections on port 80 will be routed to port 8080 and handled as HTTP. The second, more interesting entry, says that incoming connections on port 443 will be handled as TLS terminated HTTP connections and then routed on as HTTP to port 8080.There’s also a services.tcp_checks section which is used to define how we do health checks on the application.We can leave all of this completely untouched for this guide. We’re ready to Fly globally.
Flyctl will find the application name from the fly.toml file automatically and start the deployment process. There’ll be a fair amount of output as flyctl gets Docker to assemble the image, create a release of the image and then deploy and check it’s running. When it is complete you’ll see something like:
...==> Creating ReleaseRelease v0 created==> Monitoring DeploymentYou can detach the terminal anytime without stopping the deploymentv0 is being deployed1 desired, 1 placed, 1 healthy, 0 unhealthy [health checks: 1 total, 1 passing]v0 deployed successfully
This tells you all you need to know about your currently deployed application. If you take the Hostname you can use that in a URL request to the Fly deployment:
Notice that we didn’t need to specify port 8080 as we did with the local docker build. That’s because port 80 on the host routes to port 8080. As an added bonus, we also got HTTPS support as port 443 also routes to port 8080, with Fly managing the TLS termination and the Let’s Encrypt certificates. We can do the same query, over a secured connection, with:
In this guide we created a Docker image, based on a third-party image, tested it locally then deployed it to the Fly platform using flyctl. You now have a Global Image Service. Whenever you request it processes an image, Fly will create an instance of the service closest to you to fulfill your request.
⌘I
Assistant
Responses are generated using AI and may contain mistakes.