Deploying GoToSocial to Fly.io

In a previous write-up I explained what GoToSocial is. If you're still interested in deploying an instance yourself, here's what I did.

What is GoToSocial

Note that this is not a step-by-step guide. I skipped some things in the config, assuming you can figure those parts out yourself. You'll want to read up on the docs on what your options are. This guide is the important and hard parts of getting the instance setup and having persistent storage.

Short version

GoToSocial is easy to deploy because of using Golang. However, since Fly.io works off of Dockerfiles, you still need one to deploy it there. Here's mine:

# Get the GotoSocial image
FROM superseriousbusiness/gotosocial:latest AS gts

FROM alpine
COPY --from=gts /gotosocial /gotosocial
ADD config.yaml /gotosocial/

# Ensure our mount & data directories exist
RUN mkdir -p /data/db

EXPOSE 8080
CMD /gotosocial/gotosocial --config-path /gotosocial/config.yaml server start

Note that there is a config.yaml file being copied here. We'll discuss that file below.

If you're deploying somewhere else, like a VPS, you can probably get by just doing the above. Read on to see how I specially configured my instance to deploy to Fly.io.

Setup

First grab the Dockerfile from above, remove the like about social.db (since that file doesn't exist) and save it in a new project. Then grab the config.yaml.

This should be enough to get started. Run this to create a new app.

flyctl create

This should create a fly.toml file in your project. You'll need to edit this a bit later.

Database and Storage

When you deploy to Fly.io it creates a new container, losing any data you had stored previously. Obviously this is not good for a persistent app like a social site!

Fly.io has a feature called volumes which lets you have persistence storage. This volume gets mounted into your container to a folder which you can read and write from.

We'll want to store our database file and attachments there.

Go ahead and create a volume in your project with:

flyctl volumes create data -s 1

This gives you 30gb of storage, which should be enough to start. In order to have this available in our app we need to tell Fly.io to use the volume. In your fly.toml add this:

[mounts]
  source = "social_data"
  destination = "/data"

Replace social_data with the name of the volume you created.

Then go to your config.yaml file and change the database type to sqlite and set the file:

db-type: "sqlite"
db-address: "/data/db/social.db"

Note the address is really a file, and it's under the /data folder we've created.

Also update the storage location so that your attachments also persist:

storage-local-base-path: "/data/storage"

Note that it's also under /data

Database

Next we need a database. The reason to do this now is because you need an admin account. If you are creating a single-user instance this will be your only account.

To set up a database you will need a copy of the GoToSocial binary. You can find those on the Releases page:

GoToSocial releases

First create an admin user:

./gotosocial --config-path ./config.yaml admin account create --username yourname --email you@example.com --password 'passwordhere'

Replace the flags with your values. Then you need to confirm the account:

./gotosocial --config-path ./config.yaml admin account confirm --username yourname

And finally, promote it to admin:

./gotosocial --config-path ./config.yaml admin account promote --username yourname

Now your social.db is populated with your user account and your ready to deploy.

First Deploy

The first time you deploy you want to copy the social.db into the /data folder. There are probably a few ways to achieve this, such as using scp to copy the file to your instance, but I'm not smart enough to know those commands, so what I did was edit my Dockerfile to copy the file.

# Get the GotoSocial image
FROM superseriousbusiness/gotosocial:latest AS gts

FROM alpine
COPY --from=gts /gotosocial /gotosocial
ADD config.yaml /gotosocial/

# Ensure our mount & data directories exist
RUN mkdir -p /data/db
ADD social.db /data/db/

EXPOSE 8080
CMD /gotosocial/gotosocial --config-path /gotosocial/config.yaml server start

Notice that this is the same as the previous Dockerfile, except for this line:

ADD social.db /data/db/

This copies the database you just created to the db folder. Now you can deploy:

flyctl deploy

If everything went right, you should have a running instance! You can view the site in your browser with the `host` you provided in the config.

IMPORTANT: remember to remove the copy of the social.db file, or otherwise it will be overwritten on new deploys. Remove this part:

ADD social.db /data/db/

And now instead new deploys will use the existing file at /data/db/social.db.