Fly.io has a native integration with Upstash where the databases are hosted in Fly. You can still access a Redis from Fly to Upstash but for the best latency, we recommend creating Redis (Upstash) inside Fly platform. Check here for details.

In this tutorial, we’ll walk you through the process of deploying a Redis by Upstash and connecting it to an application hosted on Fly.io. We’ll be using Node.js and Express for our example application, but the process can be easily adapted to other languages and frameworks.

Redis Setup

Create a Redis database using Fly CLI

> flyctl redis create
? Select Organization: upstash (upstash)
? Choose a Redis database name (leave blank to generate one):
? Choose a primary region (can't be changed later) San Jose, California (US) (sjc)

Upstash Redis can evict objects when memory is full. This is useful when caching in Redis. This setting can be changed later.
Learn more at https://fly.io/docs/reference/redis/#memory-limits-and-object-eviction-policies
? Would you like to enable eviction? No
? Optionally, choose one or more replica regions (can be changed later):
? Select an Upstash Redis plan 3G: 3 GB Max Data Size

Your Upstash Redis database silent-tree-6201 is ready.
Apps in the upstash org can connect to at redis://default:978ba2e07tyrt67598acd8ac916a@fly-silent-tree-6201.upstash.io
If you have redis-cli installed, use fly redis connect to connect to your database.

Set up the Node.js application

  • Create a new folder for your project and navigate to it in the terminal.
  • Run npm init -y to create a package.json file.
  • Install Express and the Redis client: npm install express redis
  • Create an index.js file in the project folder with the following content:
const express = require("express");
const redis = require("redis");
const { promisify } = require("util");

const app = express();
const client = redis.createClient(process.env.REDIS_URL);

const getAsync = promisify(client.get).bind(client);
const setAsync = promisify(client.set).bind(client);

app.get("/", async (req, res) => {
  const value = await getAsync("counter");
  await setAsync("counter", parseInt(value || 0) + 1);
  res.send(`Hello, visitor number ${value || 0}!`);
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

This code creates a simple Express server that increments a counter in Redis and returns the visitor number.

Configure the Fly.io application

  • Run fly init "your-app-name" to initialize a new Fly.io application.
  • Choose the “Node.js (14.x)” builder, and accept the defaults for the remaining prompts.
  • Open the fly.toml file that was generated and add the following environment variable under the [[services]] section:
[env]
  REDIS_URL = "<your-upstash-redis-url>"

Replace your-upstash-redis-url with the Redis URL from your Upstash instance.

Deploy the application to Fly.io

  • Run fly deploy to build and deploy your application.
  • After the deployment is complete, run fly status to check if the application is running.
  • Visit the URL provided in the output (e.g., https://your-app-name.fly.dev) to test your application.

Conclusion

You have successfully deployed a Node.js application on Fly.io that uses an Upstash Redis instance as its data store. You can now build and scale your application as needed, leveraging the benefits of both Fly.io and Upstash.

Availability of Redis URL for Local Development and Testing

Understanding Fly.io and Redis Setup

  • Redis Instance on Fly.io: When you create a Redis instance using fly redis create, Fly.io establishes a Redis server in its cloud environment, designed specifically for applications running on the Fly.io platform.

  • Connection String: This command generates a connection string. However, it’s important to note that this string is intended primarily for applications deployed within Fly.io’s network. Due to security and network configurations, it’s not directly accessible from external networks, like your local development environment.

Creating a Tunnel for Local Testing

  • Fly Redis Connect: For local access to your Redis instance, use fly redis connect. This command establishes a secure tunnel between your local machine and the Redis instance on Fly.io.

    • How it Works:

      • The tunnel maps a local port to the remote Redis port on Fly.io.
      • Once established, you can connect to Redis as if it were running locally, typically at localhost with the mapped port.
    • Setting Up the Tunnel:

      • Execute fly redis connect in your terminal.
      • The command provides a local address (e.g., localhost:10000).
      • Use this address as your Redis connection URL in your local development setup.
    • Considerations:

      • This tunnel is a temporary solution, ideal for development and testing, not for production.
      • Ensure compatibility with your local firewall and network settings.

Additional Notes

  • Security Considerations: Exercise caution regarding security. Although the tunnel is secure, it exposes your Redis instance to your local network.
  • Alternative Approaches: Some developers opt to run a local Redis instance for development to bypass these complexities.

Summary

To connect to a Redis instance hosted on Fly.io from your local machine, a secure tunnel is necessary. This tunnel effectively simulates a local Redis instance, enabling testing and development activities without exposing your Redis instance over the internet.

Example Code for Setting Up and Using the Fly.io Redis Tunnel

Step 1: Establish the Tunnel

To establish a tunnel between your local machine and the Redis instance on Fly.io, run the following command in your terminal:

fly redis connect

After running this command, you’ll receive a local address, such as localhost:10000. This address will act as your local Redis endpoint.

Step 2: Connect to Redis in Your Application

In your application, you should typically use an environment variable for the Redis URL. When developing locally, set this environment variable to the local address provided by the fly redis connect command.

Here’s an example in a Node.js application:

const redis = require("redis");

// Local Redis URL for development
const LOCAL_REDIS_URL = 'redis://localhost:10000'; // Replace with your actual local address
const REDIS_URL = process.env.NODE_ENV === 'development' ? LOCAL_REDIS_URL : process.env.REDIS_URL;

const client = redis.createClient({
    url: REDIS_URL
});

client.on("error", function(error) {
  console.error(error);
});

// Rest of your Redis-related code
Step 3: Running Your Application Locally

Ensure that the Fly.io Redis tunnel is active when you run your application locally. Your application will connect to Redis through this tunnel, simulating a local instance.

npm start

Important Notes:

  • The fly redis connect tunnel should only be used for development and testing purposes.
  • Replace LOCAL_REDIS_URL in the sample code with the actual local address provided by fly redis connect.
  • Set your application’s environment to ‘development’ when running locally to use the local Redis URL.