Deploy your side project in 10 minutes with Fly.io
Corentin Le Berre
Posted on November 28, 2022
In this post, I will aim on giving your the keys to deploy quickly your API online using Fly.io platform.
First, what is Fly.io ? Like classic cloud platform as AWS/GCP/Azure, Fly.io enables you to deploy your application/api/microservices/database on the cloud. But unlike these, it stands out for its simplicity.
You can deploy a lot of different technologies such as Php/Python/Deno/Node/Go etc threw automatic templates or even use a Dockerfile. It's really easy to use thanks to the CLI and documentation provided. This enables you to deploy and scale your app worldwide and close to your users without worrying about network, DNS or security. It also provides lots of metrics about your application with an integrated Graphana on your dashboard. With the free tier, you can host 2 projects.
π To have more details about those features just check their website
In this article, I will deploy a simple Node.js server written in Typescript, focusing only on the steps necessary for deployment. For more information feel free to consult their documentation.
Prerequisites
Have a Node environment installed and Docker if you want to test your build locally.
π Install fly cli tools π
Flyctl is a command-line utility that lets you work with the Fly.io platform, from creating your account to deploying your applications.
ο£Ώ$: brew install flyctl
π§$: curl -L https://fly.io/install.sh | sh
πͺ$: iwr https://fly.io/install.ps1 -useb | iex
Create our app
You can clone this project on Github or copy the code below π
π¦ Structure of the project
π¦beekeeper
β£ πsrc
β β πmain.ts
β£ πDockerfile
β£ πfly.toml
β£ πpackage-lock.json
β£ πpackage.json
β πtsconfig.json
Part 1 : Create the Node.JS API
π Init a npm project
$: npm init
π Add this configuration in package.json
{
/***/
"type": "module",
"scripts": {
"dev": "ts-node src/main.ts",
"build": "rm -rf dist && tsc --build",
"start": "node dist/src/main.js"
}
/***/
}
π Install dependencies
$: npm install express
$: npm install -D typescript ts-node @types/node @types/express
π Configure Typescript compiler in tsconfig.json
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Node",
"esModuleInterop": true,
"rootDir": "./src",
"outDir": "./dist/src",
},
"ts-node": {
"esm": true
}
}
π Create the express api in src/main.ts. It's a simple server made for a beekeeper that allows him to know the state of his hives. It exposes a single access point via /api/hives.
import express from "express";
import { Express, Request, Response } from "express";
const app: Express = express();
const port = process.env.PORT || 8080;
const bees = (n: number): string => Array(n).fill("π").join("");
const getHives = (req: Request, res: Response): void => {
const hives = {
"π«π·": bees(150),
"π¨π¦": bees(40),
"π―π΅": bees(10),
};
res.status(200).json(hives);
};
app.get("/api/hives", getHives);
app.listen(port, () =>
console.log(`π― Beekeeper is running on http://localhost:${port}`)
);
You can now run the app with npm run dev
Part 2 : Build the app with Docker
β οΈ Your Docker Daemon need to be working to execute these commands
π Build the image locally
$: docker build -t beekeeper .
π Verify if the image has been created
$: docker images | grep beekeeper
beekeeper latest 2dc2439eaec3 1 min ago 118MB
π Test the server locally
$: docker run -it -p 8080:8080 beekeeper
You should get the state of the Hives when fetching your local endpoint π
Part 3 : Deploy the app worldwide
π Log-in or create your Fly.io account
$: flyctl auth login
$: flyctl auth signup
π Use the cli to the app and follow the steps below π
$: flyctl launch
- Answer no to .dockerignore
- Define the app name to the name of your project
- Deploy the app in the region of your choice. You can add more or change it later
- Answer no to Postgresql and Redis database
- Answer yes to deploy now
It may take 1 or 2 minutes to create your project and build your Docker image with Fly remote builders (optional). If it succeed, you should see this in your terminal π
--> Building image done
==> Pushing image to fly
The push refers to repository [registry.fly.io/beekeeper]
deployment-01GJY6F3Y3707JXJ7PTZQKFS57: digest: sha256:722fe804f091c9fd33b789ac9c06ae68af87d1e6c6720025bdb33da0bf13fe1d size: 1991
--> Pushing image done
image: registry.fly.io/beekeeper:deployment-01GJY6F3Y3707JXJ7PTZQKFS57
image size: 118 MB
==> Creating release
--> release v1 created
--> You can detach the terminal anytime without stopping the deployment
==> Monitoring deployment
1 desired, 1 placed, 0 healthy, 1 unhealthy [health checks: 1 total, 1 critical]
Failed Instances
You can detach the terminal now and check the status of your app with flyctl status.
Your app is now online ! Lets try to access it.
- Go to your dashboard and click on the app you created.
- You should see a lot of information about your app including the bandwidth and cpu/ram used.
- You should find your app url in the "Hostname" box. Click on it and add /api/hives at the end.
Tadaam, you should see lots of bees, your app is deployed π₯³ !
To redeploy the app after a change in your code or conf use fly deploy.
Conclusion
I hope you learned some new stuff in this post. I focused on a simple case and the mandatory steps to deploy our application. If you need more information, feel free to check out the bonus section or the fly.io documentation.
Bonus
Configurations
The CLI tools generate for you fly.toml a configuration file used to describe your app on their platform. Here you can define ports, env variables, deploy and runtime options, the protocol used, etc. More info here.
Example of fly.toml generated for this project π
# fly.toml file generated for beekeeper
app = "beekeeper"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []
[env]
PORT=8080
[experimental]
allowed_public_ports = []
auto_rollback = true
[[services]]
http_checks = []
internal_port = 8080
processes = ["app"]
protocol = "tcp"
script_checks = []
[services.concurrency]
hard_limit = 25
soft_limit = 20
type = "connections"
[[services.ports]]
force_https = true
handlers = ["http"]
port = 80
[[services.ports]]
handlers = ["tls", "http"]
port = 443
[[services.tcp_checks]]
grace_period = "1s"
interval = "15s"
restart_limit = 0
timeout = "2s"
Regions
You can currently deploy your apps in 26 differents regions with the command flyctl regions add.
π Add Paris and Tokyo as new regions
flyctl regions add cdg nrt
π Check regions
flyctl regions list
CI/CD
Fly provide remote builder so it's easy to integrate it with Gitlab or Github CI/CD pipelines. More info here and here.
Posted on November 28, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.