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!
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
- it's entirely ephemeral! This means that if the instance is restarted, it will lose all its data.
- 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!