Deploy SilverBullet to fly.io

Fly.io is a nice and simple to use (and probably) cheap option of hosting SilverBullet “in the cloud” yourself, exposing it to the Internet (with username and password). You don’t have to manage a full server and the process of setting it up is pretty straight forward.

Requirements

A fly.io account. I think you have to sign up with a credit card. Since we’ll configure your fly.io app to automatically stop when not in use (after a few minutes), cost of running SilverBullet should be low or possibly even free (I’ve seen claims that fly.io won’t charge you if your monthly bill is < $5). No promises, though. Please report your experiences when you deploy SilverBullet this way.

Setup

On your local machine, create an empty folder with a single file in it: fly.toml:

# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
swap_size_mb = 512

[build]
# Replace edge with a specific release, e.g. 0.9.0
# To upgrade, update the version number and run 'fly deploy' again
image = 'zefhemel/silverbullet:edge'

[deploy]
strategy = 'immediate'

[[mounts]]
# Volume to store your space
source = 'space_data'
destination = '/space'
initial_size = '1gb'

[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = 'stop'
auto_start_machines = true
min_machines_running = 0

[[vm]]
# 512mb is the recommended minimum
memory = '512mb'
cpu_kind = 'shared'
cpus = 1

Install the fly CLI, then launch the app. The first time you’ll have to authenticate your account.

fly launch

This will ask if you would like to “copy its configuration to the new app?” Say yes.

Tweak the suggested (random) app name if you like, this will become part of your deployed URL.

This will give you a running SilverBullet with no authentication. So let’s set a username and password immediately (replace user with your prefered username and letmein with something more secure).

fly secrets set SB_USER=user:letmein

After a while, you’ll be asked for your username and password.

That’s all.

Upgrading

You will have to manually upgrade your SilverBullet instance as follows:

In your fly.toml change the tag of your docker image to a specific version number, e.g. zefhemel/silverbullet:0.9.0, and then when it’s released update to zefhemel/silverbullet:0.9.1. Save your changes and run:

fly deploy

After a little while (watch server logs as described below to see progress), your upgraded SilverBullet will come back up.

Monitor server logs

fly logs

SSH into your machine

fly ssh console

Enjoy!

5 Likes

It is highly recommended that you do something like this right after: Backup your space to Github

I tried to build my own Docker image for SB but it always failed to start in fly.io.

First, I built the image

deno task bundle
docker build -t pvadocker/silverbullet .
docker push pvadocker/silverbullet:latest

then in fly.toml, I replace ‘zefhemel’ with my account ‘pvadocker’

image = 'pvadocker/silverbullet:latest'

then fly deploy again and got this error in fly log

2024-09-14T02:36:24.779 app[1857166f459478] sin [info] INFO Mounting /dev/vdd at /space w/ uid: 0, gid: 0 and chmod 0755

2024-09-14T02:36:24.781 app[1857166f459478] sin [info] INFO Resized /space to 1056964608 bytes

2024-09-14T02:36:24.787 app[1857166f459478] sin [info] INFO Preparing to run: `/tini -s -- /docker-entrypoint.sh` as root

2024-09-14T02:36:24.793 app[1857166f459478] sin [info] INFO [fly api proxy] listening at /.fly/api

2024-09-14T02:36:24.800 app[1857166f459478] sin [info] 2024/09/14 02:36:24 INFO SSH listening listen_address=[fdaa:0:b69e:a7b:188:bdc0:c69:2]:22 dns_server=[fdaa::3]:53

2024-09-14T02:36:24.808 app[1857166f459478] sin [info] /bin/bash: - : invalid option

2024-09-14T02:36:24.872 runner[1857166f459478] sin [info] Machine started in 1.027s

2024-09-14T02:36:24.873 proxy[1857166f459478] sin [info] machine started in 1.032660448s

2024-09-14T02:36:25.795 app[1857166f459478] sin [info] INFO Main child exited normally with code: 1

2024-09-14T02:36:25.809 app[1857166f459478] sin [info] INFO Starting clean up.

2024-09-14T02:36:25.829 app[1857166f459478] sin [info] INFO Umounting /dev/vdd from /space

2024-09-14T02:36:25.830 app[1857166f459478] sin [info] WARN could not unmount /rootfs: EINVAL: Invalid argument

2024-09-14T02:36:25.831 app[1857166f459478] sin [info] [ 1.804776] reboot: Restarting system

2024-09-14T02:36:29.300 runner[1857166f459478] sin [info] machine has reached its max restart count of 10

2024-09-14T02:36:32.219 proxy[1857166f459478] sin [info] waiting for machine to be reachable on 0.0.0.0:3000 (waited 7.346476819s so far)

2024-09-14T02:36:38.171 proxy[1857166f459478] sin [info] waiting for machine to be reachable on 0.0.0.0:3000 (waited 13.298530488s so far)

2024-09-14T02:36:44.147 proxy[1857166f459478] sin [info] waiting for machine to be reachable on 0.0.0.0:3000 (waited 19.274472632s so far)

2024-09-14T02:36:49.151 proxy[1857166f459478] sin [error] [PM05] failed to connect to machine: gave up after 15 attempts (in 24.278223914s)

do you have any idea on where I went wrong?

What platform are you building on? I think fly runs on amd64. Perhaps you’re building on an arm machine?

I was building it on Debian in WSL2.

I tried running the image locally, it throw the below error though the /docker-entrypoint.sh is still there in the / directory

[FATAL tini (7)] exec /docker-entrypoint.sh failed: No such file or directory

I guessed the issue might be related to line endings that caused Bash failed to read the file. I tried fixing it with dos2unix

dos2unix /docker-entrypoint.sh

After that I rebuilt the image then the problem was fixed. Now I can run the image on both local and fly.io.

1 Like

Sorry to necro an old thread, but I tried re-deploying SB this morning to on fly.io to get all the v2 hotness and my machine in fly.io won’t start. I think it’s because the Dockerfile is using tini and fly.io doesn’t like that very much, but I’m not sure. It didn’t used to have this problem, so I’m a little stumped. Maybe the tini thing is a red herring and it’s something else. I was wondering if anyone else has seen this and fixed it; I don’t have time to go spelunking right now but I will later on tonight.

Here are the logs I think are relevant:

2025-09-30T16:11:52Z app[d899455a6e1198] dfw [info] INFO Preparing to run: `/sbin/tini -- /docker-entrypoint.sh` as root
2025-09-30T16:11:52Z app[d899455a6e1198] dfw [info] INFO [fly api proxy] listening at /.fly/api
2025-09-30T16:11:52Z app[d899455a6e1198] dfw [info][WARN  tini (655)] Tini is not running as PID 1 and isn't registered as a child subreaper.
2025-09-30T16:11:52Z app[d899455a6e1198] dfw [info]Zombie processes will not be re-parented to Tini, so zombie reaping won't work.
2025-09-30T16:11:52Z app[d899455a6e1198] dfw [info]To fix the problem, use the -s option or set the environment variable TINI_SUBREAPER to register Tini as a child subreaper, or run Tini as PID 1.
2025-09-30T16:11:52Z app[d899455a6e1198] dfw [info]Will run SilverBullet with UID 0, inferred from the owner of /space (set PUID environment variable to override)
2025-09-30T16:11:52Z runner[d899455a6e1198] dfw [info]Machine created and started in 7.129s
2025-09-30T16:11:52Z app[d899455a6e1198] dfw [info]2025/09/30 16:11:52 User authentication enabled for user "drhayes" with lockout limit 10 and lockout time 60s
2025-09-30T16:11:52Z app[d899455a6e1198] dfw [info]2025/09/30 16:11:52 Local shell command execution enabled for ALL commands.
2025-09-30T16:11:52Z app[d899455a6e1198] dfw [info]2025/09/30 16:11:52 SilverBullet is now running: http://:::3000
2025-09-30T16:11:52Z app[d899455a6e1198] dfw [info]2025/09/30 16:11:52 INFO SSH listening listen_address=[fdaa:0:45cf:a7b:41e:9670:3225:2]:22
2025-09-30T16:11:53Z app[d899455a6e1198] dfw [info] INFO Main child exited normally with code: 0

Fly deployments own PID 1 and don’t like having other things running as init (like tini): Multiple processes inside a Fly.io app · Fly Docs