Running GoToSocial on NetBSD

       1012 words, 5 minutes

I wanted a communication tool for the NoGoo.me searxng instance I manage. But I want a software with small footprint. I used GoToSocial as my primary ActivityPub server and it was great. It only lacked a few features so I stopped using it as my primary Fediverse service. Let’s have it back again in my software ecosystem.

When it comes to supported platforms, you can choose between Linux and FreeBSD. The port for OpenBSD has recently been set BROKEN because of Go and libc issues I don’t understand. When it comes to working platforms, you can add NetBSD and pkgsrc to the game.

Preparation

Get a NetBSD instance running. I’ll be using NetBSD on OmniOS like this .

GoToSocial gets new releases fast enough that you often need to build it from source. Thus, during installation, select the option to “Fetch and unpack pkgsrc”.

With NetBSD up and running, log in to the system and proceed to GTS installation.

Install GoToSocial

I’d rather install binary packages when possible. But, at the time of writing, the available binary package is a bit old. So I’ll use an updated pkgsrc tree to get GTS from source.

# pkgin in go digest mktools cwrappers

# cd /usr/pkgsrc/www/gotosocial
# cvs update -A -dP

# echo 'ACCEPTABLE_LICENSES+= gnu-agpl-v3' >> /etc/mk.conf
# make
# make install
# make clean

Copy the rc.d script so that GoToSocial can be started automatically at boot.

# cp -p /usr/pkg/share/examples/rc.d/gotosocial /etc/rc.d/gotosocial
# echo "gotosocial=YES" >> /etc/rc.conf
# service gotosocial status
gotosocial is not running.

Setup GoToSocial environment

The Configuration Overview explains how to configure GoToSocial.

The default configuration expects web stuff to live in /var/www/gotosocial and database to be postgresql. I’d rather have my GTS data into /home and use SQlite.

# mkdir -p -m 0750 /home/gotosocial
# chown gotosocial:gotosocial /home/gotosocial
# cp -pr /usr/pkg/share/examples/gotosocial/web/assets /home/gotosocial/
# cp -pr /usr/pkg/share/examples/gotosocial/web/template /home/gotosocial/

# diff -U2 /usr/pkg/share/examples/gotosocial/config.yaml /usr/pkg/etc/gotosocial/config.yaml
--- /usr/pkg/share/examples/gotosocial/config.yaml      2024-05-29 11:07:36.000000000 +0200
+++ /usr/pkg/etc/gotosocial/config.yaml 2024-05-29 15:16:58.807672417 +0200
@@ -63,5 +63,5 @@
 # Examples: ["gts.example.org","some.server.com"]
 # Default: "localhost"
-host: "localhost"
+host: "gts.example.com"

 # String. Domain to use when federating profiles. This is useful when you want your server to be at
@@ -125,4 +125,6 @@
   - "127.0.0.1/32"
   - "::1"
+  - "192.0.2.1"
+  - "192.0.2.2"

 ############################
@@ -135,5 +137,5 @@
 # Options: ["postgres","sqlite"]
 # Default: "postgres"
-db-type: "postgres"
+db-type: "sqlite"

 # String. Database address or parameters.
@@ -150,5 +152,5 @@
 # Examples: ["localhost","my.db.host","127.0.0.1","192.111.39.110",":memory:", "sqlite.db"]
 # Default: ""
-db-address: ""
+db-address: "/home/gotosocial/sqlite.db"

 # Int. Port for database connection.
@@ -217,5 +219,5 @@
 # Examples: ["DELETE", "TRUNCATE", "PERSIST", "MEMORY", "WAL", "OFF"]
 # Default: "WAL"
-db-sqlite-journal-mode: "WAL"
+db-sqlite-journal-mode: "DELETE"

 # String. SQLite synchronous mode.
@@ -267,10 +269,10 @@
 # Examples: ["/some/absolute/path/", "./relative/path/", "../../some/weird/path/"]
 # Default: "/var/www/gotosocial/template/"
-web-template-base-dir: "/var/www/gotosocial/template/"
+web-template-base-dir: "/home/gotosocial/template/"

 # String. Directory from which gotosocial will attempt to serve static web assets (images, scripts).
 # Examples: ["/some/absolute/path/", "./relative/path/", "../../some/weird/path/"]
 # Default: "/var/www/gotosocial/assets/"
-web-asset-base-dir: "/var/www/gotosocial/assets/"
+web-asset-base-dir: "/home/gotosocial/assets/"

 ###########################
@@ -547,5 +549,5 @@
 # Examples: ["/home/var/db/gotosocial/storage", "/opt/gotosocial/datastorage"]
 # Default: "/var/db/gotosocial/storage"
-storage-local-base-path: "/var/db/gotosocial/storage"
+storage-local-base-path: "/home/gotosocial/storage"

 # String. API endpoint of the S3 compatible service.
@@ -918,5 +920,5 @@
   #
   # Both allow-ips and block-ips default to an empty array.
-  allow-ips: []
+  allow-ips: ["192.0.2.3/32"]
   block-ips: []

The trusted-proxies value allows access from by relayd(8) servers. The http-client:allow-ips allows communication to other Fediverse software that are installed on my private LAN ; more info on this here .

Run GoToSocial

Everything being ready, let’s start the daemon.

# service gotosocial start

Browse to http://localhost:8080 to check if things work.

Expose GTS to the Wild Wild Web using relayd(8)

The NetBSD instance is not publicly exposed. I have a couple of OpenBSD servers that does the job using relayd(8).

The TLS certificate is managed by acme-client(1).

# vi /etc/acme-client.conf
(...)
domain gts.example.com {
        domain key "/etc/ssl/private/gts.example.com.key"
        domain full chain certificate "/etc/ssl/gts.example.com.crt"
        sign with letsencrypt
}

The relevant relayd(8) configuration goes like this.

# vi /etc/relayd.conf
(...)
gts_addr = "192.0.2.123"
(...)
table <gts> { $gts_addr }
(...)
http protocol wwwtls {
  tls keypair gts.example.com
  (...)
  match request header "Host" value "gts.example.com" tag "gts"
  (...)
  match request header set "Keep-Alive" value "$TIMEOUT"
  match request header set "X-Forwarded-For" value "$REMOTE_ADDR"
  match request header set "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"
  match request header set "X-Forwarded-Proto" value "https"
  match request header set "X-Forwarded-Port" value "443"
  (...)
  pass request quick tagged "gts" forward to <gts>
}

relay www4tls {
  listen on $ipv4_addr port 443 tls
  protocol wwwtls
  forward to <gts> port 8080 check http "/readyz" host 'gts.example.com' code 418
  (...)
}

There is any issue with the health check. When doing the checks, relayd(8) uses an empty user-agent value. GoToSocial does not like this and returns an HTTP/418. Even when using “check send” or “check binary send” , I couldn’t have relayd(8) send HTTP health-check that would make GTS happy. So I went for having relayd(8) accept the HTTP/418 as a valid proof of life.
If you have knowledge to solve this, don’t hesitate to ping me!

User creation

Registration is not opened on this instance.
So I need to create the account(s) from the CLI.

# /usr/pkg/bin/gotosocial                           \
  --config-path /usr/pkg/etc/gotosocial/config.yaml \
  admin account create                              \
    --username admin                                \
    --email contact@example.com                     \
    --password 'change-me'                    

# /usr/pkg/bin/gotosocial                           \
  --config-path /usr/pkg/etc/gotosocial/config.yaml \
  admin account promote --username admin

# service gotosocial restart

Repeat those steps for every user(s) you create.

Browse to https://gts.example.com/settings , log in and start the configuration. Check to see if communication works with some of your testing ActivityPub accounts and start tooting.

Update GoToSocial

As GTS will get new releases, pkgsrc would get updated. If the binary packages are not available for your actual NetBSD version, update pkgsrc and build the new packages.

# cd /usr/pkgsrc/www/gotosocial
# cvs up -PAd
# make package
# make update
# make clean

# cp -pr /usr/pkg/share/examples/gotosocial/web/assets /home/gotosocial/
# cp -pr /usr/pkg/share/examples/gotosocial/web/template /home/gotosocial/

# service gotosocial restart & tail -f /var/log/messages

You may need to upgrade the lang/go package to be able to compile a new GTS version.
Thanks nikita@ for pointing me to this ; and for doing the update job on pkgsrc!

That’s All Folks! Seeya on the Fediverse.