DEV Community

Željko Šević
Željko Šević

Posted on • Originally published at sevic.dev on

Deploying Node.js apps to Fly.io

This post covers main notes from setting up the Fly.io CLI tool to CI/CD pipeline with Github actions.

Prerequisites

  • Run the following command to install the CLI tool and follow the instructions to add the necessary commands to the appropriate shell configuration file
curl -L https://fly.io/install.sh | sh 
Enter fullscreen mode Exit fullscreen mode
  • Create an account or log in if you already have an account
fly auth signup fly auth login 
Enter fullscreen mode Exit fullscreen mode

Node server

  • Run the following commands for packages setup
npm init -y npm i express 
Enter fullscreen mode Exit fullscreen mode
  • Write basic server
// server.js const express = require('express'); const app = express(); const PORT = process.env.PORT || 8080; app.get('/', (_, res) => res.send('Hello world')); app.listen(PORT, () => { console.log(`Server is running on port ${PORT}`); }); 
Enter fullscreen mode Exit fullscreen mode
  • Configure start script
// package.json { "scripts": { "start": "node server.js" } } 
Enter fullscreen mode Exit fullscreen mode

Project setup

Choose the project name and region for deployment. The following command will create a project and generate a configuration file. Project URL will be <PROJECT_NAME>.fly.dev

fly launch 
Enter fullscreen mode Exit fullscreen mode

Environment variables

Configuration variables

Generated fly.toml file contains env section for environment variables which can be publicly available like URLs, HTTP timeout values, etc.

// ... [env] PORT = "8080" NEW_VARIABLE = "value" // ... 
Enter fullscreen mode Exit fullscreen mode

Secrets

The following commands are used for setting up the secrets like API keys, credentials, etc.

fly secrets set KEY=value fly secrets list fly secrets unset KEY 
Enter fullscreen mode Exit fullscreen mode

Databases

Redis

Run the following commands to provision the Redis database and connect with it. Eviction is disabled by default.
URL can be found with the status command. Set it as a secret.

fly redis create fly redis connect fly redis list fly redis status <database-name> 
Enter fullscreen mode Exit fullscreen mode

Postgres

Run the following command to bootstrap a Postgres database cluster.

fly postgres create 
Enter fullscreen mode Exit fullscreen mode

The previous command will prompt the connection string only once. Set it as a secret.

// knexfile.js module.exports = { // ... production: { client: 'postgresql', connection: process.env.DATABASE_URL, // ... }, }; 
Enter fullscreen mode Exit fullscreen mode

Release command can run migrations.

# fly.toml [deploy] release_command = "npm run migrate" 
Enter fullscreen mode Exit fullscreen mode

Test the database connection with the following command.

fly postgres connect -a <postgres-app-name> 
Enter fullscreen mode Exit fullscreen mode
Backup

Fly.io performs daily snapshots of the provisioned volumes. Snapshots are volume-specific. Postgres database can be restored out of the provided snapshot.

fly volumes list -a <postgres-app-name> fly volumes snapshots list <volume-id> fly postgres create --snapshot-id <snapshot-id> 
Enter fullscreen mode Exit fullscreen mode

Scaling

Every app runs inside a virtual machine, and the following command shows the VM size and how many app instances are running.

fly scale show 
Enter fullscreen mode Exit fullscreen mode

Vertical scaling

  • The following command shows the list of VM types and their memory allocations
fly platform vm-sizes 
Enter fullscreen mode Exit fullscreen mode
  • Run the following command to upgrade the VM to one of the types from the previous command, memory allocation in MBs can be specified as well
fly scale vm <type> --memory 1024 
Enter fullscreen mode Exit fullscreen mode
  • Run the following command to increase VM memory, 1024MB in this case
fly scale memory 1024 
Enter fullscreen mode Exit fullscreen mode

Horizontal scaling

Run the following command to increase the number of app instances, 3 in this case

fly scale count 3 
Enter fullscreen mode Exit fullscreen mode

Autoscaling is disabled by default. Run the following commands to configure it.

fly autoscale show fly autoscale set min=3 max=6 
Enter fullscreen mode Exit fullscreen mode

Debugging

  • Get the real-time logs
fly logs 
Enter fullscreen mode Exit fullscreen mode
  • Get the info about the app, services, and IP addresses
fly info 
Enter fullscreen mode Exit fullscreen mode
  • Get the state of the project
fly status 
Enter fullscreen mode Exit fullscreen mode
  • Get the app IP addresses
fly ips list 
Enter fullscreen mode Exit fullscreen mode
  • Run bash on the app
fly ssh console 
Enter fullscreen mode Exit fullscreen mode
  • Restart the app
fly apps restart <app-name> 
Enter fullscreen mode Exit fullscreen mode

Deployment

Manual deployment

The following commands are used to deploy and open the deployed version.

fly deploy --no-cache fly open 
Enter fullscreen mode Exit fullscreen mode

Continuous deployment with Github actions

A project auth token is needed. Run the following command to generate it. Add the generated key as a Github action secret in the Settings → Secrets → Actions page

fly auth token 
Enter fullscreen mode Exit fullscreen mode

Add .github/workflows/config.yml file with the following configuration.

name: CI/CD pipeline on: push: branches: - main env: FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} jobs: build-and-deploy: runs-on: ubuntu-latest container: node:20.9.0-alpine3.17 steps: - name: Github checkout uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - run: npm run lint - run: npm test - run: npm audit - name: Setup Fly.io config uses: superfly/flyctl-actions/setup-flyctl@master - name: Deploy to Fly.io run: flyctl deploy --remote-only --no-cache 
Enter fullscreen mode Exit fullscreen mode

Course

Build your SaaS in 2 weeks - Start Now

Top comments (0)