Documentation
Fly.io

Fly.io

Fly.io is a platform for running Docker containers on a global network of edge servers. It's a great fit for Storyden because it's container-native and super simple to get started!

A rocket sitting on the launch pad

Deployment

Relevant documentation: https://fly.io/docs/apps/launch (opens in a new tab)

Once you've created an account on Fly.io and set up the CLI, you can launch a Storyden instance with a single command:

fly launch --image ghcr.io/southclaws/storyden --name storyden --internal-port 3000
  • --image is the Docker image to use. This is the latest version of Storyden from the GitHub Container Registry.
  • --name is the name of the app. This will be used to generate a URL for your app.
  • --internal-port is the port that the app runs on inside the container. This is 3000 by default.

Once that command completes, you'll see something similar to:

Visit your newly deployed app at https://storyden-unique-name-1234.fly.dev/

You can visit the URL that Fly.io gives you and you'll see your Storyden instance - almost ready to use!

Necessary configuration

That's only half the story though. You have an instance but

  1. it's entirely ephemeral! This means that if the instance is restarted, it will lose all its data.
  2. it has no idea what its public address is! This means session cookies won't work.

Persistent storage

Relevant documentation: https://fly.io/docs/volumes (opens in a new tab)

To ensure the SQLite database is persisted, we need to add a volume mount to the fly.toml configuration file. This file is generated by Fly.io when you run the fly launch command.

It will look something like this:

# fly.toml app configuration file generated for storyden-unique-name-1234 on 2023-12-12T23:19:17Z
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#
 
app = "storyden-unique-name-1234"
primary_region = "lhr"
 
[build]
  image = "ghcr.io/southclaws/storyden"
 
[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ["app"]
 
[[vm]]
  cpu_kind = "shared"
  cpus = 1
  memory_mb = 1024

(Note: over time the defaults may change and these docs may become slightly out of date)

We need to add a volume mount to the [mounts] section:

    # fly.toml app configuration file generated for storyden-unique-name-1234 on 2023-12-12T23:19:17Z
    #
    # See https://fly.io/docs/reference/configuration/ for information about how to use this file.
    #
 
    app = "storyden-unique-name-1234"
    primary_region = "lhr"
 
    [build]
      image = "ghcr.io/southclaws/storyden"
 
    [http_service]
      internal_port = 3000
      force_https = true
      auto_stop_machines = true
      auto_start_machines = true
      min_machines_running = 0
      processes = ["app"]
 
    [[vm]]
      cpu_kind = "shared"
      cpus = 1
      memory_mb = 1024
+
+   [mounts]
+     source="storyden_data"
+     destination="/data"

Environment Variables

Relevant documentation: https://fly.io/docs/reference/configuration#the-env-variables-section (opens in a new tab)

Storyden uses secure cookies for session authentication. As a result, it needs to know two things:

  • what domain it's running on so it can set the Domain flag on the cookie
  • a unique encryption key to keep session tokens secure

Here's an example of the environment variables section in the fly.toml file:

[env]
  PUBLIC_API_ADDRESS = "https://storyden-unique-name-1234.fly.dev"
  PUBLIC_WEB_ADDRESS = "https://storyden-unique-name-1234.fly.dev"
  SESSION_KEY        = "<your key>"

PUBLIC_API_ADDRESS and PUBLIC_WEB_ADDRESS

The public API address and public web address variables are necessary for Storyden to manage sessions using cookies and a few other things such as knowing where links should point to.

In the above section, when you ran fly launch, it gives you the URL of your app. This URL will look something like:

https://storyden-unique-name-1234.fly.dev

It's a subdomain of fly.dev and is uniquely generated based on your app name. You can refer to the Fly.io domains documentation for information on setting up a custom domain.

ℹ️

For this quick start guide, your instance is all hosted on a single domain, that means the API and the frontend both run on https://storyden-unique-name-1234.fly.dev. But if you're using separate backend and frontend deployments (hosting the frontend on Vercel for example) it's necessary that both share the same root domain. So you'd put the API on something like api.mycommunity.com and the frontend on mycommunity.com. Cookies will be issued to the root domain, mycommunity.com in this example and will be included in requests to both the API and the frontend's SSR rendering backend if you're using a framework such as Next.js.

SESSION_KEY

The session key is an important security feature. It's used to encrypt session tokens so that they can't be tampered with. It's important to set this to a unique value that is kept secret. You can use any trusted source of randomness on your local machine to generate it.

⚠️

A session key must be a hexadecimal string with 16 or more characters.

Re-deploy

Once you've set the three required environment variables, plus anything else from the configuration, you can now re-deploy the app:

fly deploy

And that's it! You now have your own Storyden instance running on Fly.io!

Visit your app's URL, invite your friends and start building your community's knowledgebase!

A rocket taking off