Mastodon

󰃭 2024-10-24

Full-text search with elasticsearch

Install ElasticSearch

sudo apt install -y openjdk-17-jre-headless

wget -O /usr/share/keyrings/elasticsearch.asc https://artifacts.elastic.co/GPG-KEY-elasticsearch

echo "deb [signed-by=/usr/share/keyrings/elasticsearch.asc] https://artifacts.elastic.co/packages/7.x/apt stable main" > /etc/apt/sources.list.d/elastic-7.x.list

sudo apt update

sudo apt install -y elasticsearch

Edit /etc/elasticsearch/elasticsearch.yaml

xpack.security.enabled: true
discovery.type: single-node

Create passwords for built-in users

sudo -u elasticsearch /usr/share/elasticsearch/bin/elasticsearch

In a separate shell:

sudo -u elasticsearch /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto

Copy the generated password for the elastic user.

Create custom role for Mastodon to connect

As the mastodon user on the host:

curl -X POST -u elastic:admin_password "localhost:9200/_security/role/mastodon_full_access?pretty" -H 'Content-Type: application/json' -d'
{
    "cluster": ["monitor"],
    "indices": [{
        "names": ["*"],
        "privileges": ["read", "monitor", "write", "manage"]
    }]
}
'

Create a user for Mastodon and assign it the custom role

curl -X POST -u elastic:admin_password "localhost:9200/_security/user/mastodon?pretty" -H 'Content-Type: application/json' -d'
{
    "password": "l0ng-r4nd0m-p@ssw0rd",
    "roles": ["mastodon_full_access"]
}
'

Edit .env.production

ES_ENABLED=true
ES_HOST=localhost
ES_PORT=9200
ES_PRESET=single_node_cluster
ES_USER=mastodon
ES_PASS=l0ng-r4ndom-p@ssw0rd

Populate the indices

systemctl restart mastodon-sidekiq
systemctl reload mastodon-web
su - mastodon
cd live
RAILS_ENV=production bin/tootctl search deploy

S3-compatible object storage with Minio

  1. Install MinIO
  2. Set the region for this instance to homelab
  3. Create ‘mastodata’ bucket
  4. Setup Tailscale

Minio API endpoint: tailnet_ip_addr:9000

Caddy reverse proxy config

Ensure DNS resolves for assets.hyperreal.coffee

assets.hyperreal.coffee {
    rewrite * /mastodata{path}
    reverse_proxy http://<tailnet_ip_addr>:9000 {
        header_up Host {upstream_hostport}
    }
}

fedi.hyperreal.coffee {
    @local {
        file
        not path /
    }
    @local_media {
        path_regexp /system/(.*)
    }

    redir @local_media https://assets.hyperreal.coffee/{http.regexp.1} permanent

    ...remainer of config
}

Set custom policy on mastodata bucket

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": {
           "AWS": "*"
         },
         "Action": "s3:GetObject",
         "Resource": "arn:aws:s3:::mastodata/*"
      }
   ]
}

Create mastodon-readwrite policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::mastodata/*"
        }
    ]
}

Setup .env.production

S3_ENABLED=true
S3_BUCKET=mastodata
AWS_ACCESS_KEY=<access key>
AWS_SECRET_ACCESS_KEY=<secret access key>
S3_REGION=homelab
S3_PROTOCOL=http
S3_ENDPOINT=http://<tailnet_ip_addr>:9000
S3_FORCE_SINGLE_REQUEST=true
S3_ALIAS_HOST=assets.hyperreal.coffee

Restart Caddy and Mastodon services

sudo systemctl restart caddy.service mastodon-web.service mastodon-streaming.service mastodon-sidekiq.service

Prometheus metrics with statsd_exporter

On the host running Mastodon, download the latest binary from releases page.

tar xzvf statsd_exporter*.tar.gz
cd statsd_exporter*/
sudo cp -v statsd_exporter /usr/local/bin/

Install the statsd mapping file from IPng Networks:

curl -OL https://ipng.ch/assets/mastodon/statsd-mapping.yaml
sudo cp -v statsd-mapping.yml /etc/prometheus/

Create /etc/default/statsd_exporter.

ARGS="--statsd.mapping-config=/etc/prometheus/statsd-mapping.yaml"

Create /etc/systemd/system/statsd_exporter.service.

[Unit]
Description=Statsd exporter
After=network.target

[Service]
Restart=always
User=prometheus
EnvironmentFile=/etc/default/statsd_exporter
ExecStart=/usr/local/bin/statsd_exporter $ARGS
ExecReload=/bin/kill -HUP $MAINPID
TimeoutStopSec=20s
SendSIGKILL=no

[Install]
WantedBy=multi-user.target

Ensure port 9102 is open in Firewalld’s internal zone.

sudo firewall-cmd --permanent --zone=internal --add-port=9102/tcp
sudo firewall-cmd --reload

Edit /home/mastodon/live/.env.production.

STATSD_ADDR=localhost:9125

Start and restart the daemons.

sudo systemctl daemon-reload
sudo systemctl start statsd_exporter.service
sudo systemctl restart mastodon-sidekiq.service mastodon-streaming.service mastodon-web.service

If using Tailscale, ensure the host running Prometheus can access port 9102 on the host running Mastodon.

On the host running Prometheus, add the statsd config.

- job_name: "stats_exporter"
  static_configs:
  - targets: ["hyperreal:9102"]

Restart Prometheus.

sudo systemctl restart prometheus.service

To import the Grafana dashboard, use ID 17492.

Source: How to set up monitoring for your Mastodon instance with Prometheus and Grafana


Enter your instance's address