๐ฆ DIY ActivityPub (Mastodon)
How to setup a free custom Mastodon server
Ride the Exodus ๐ฆ
Everyone's giving Mastodon a try after Elon Musk alienated half of the planet.
As you might know, Mastodon is not a single website but rather an open federation of servers. To use it, you need an account with a provider that lets you connect with other servers and users through to the "Fediverse".
New users can join a public community server or join the network as their own provider. Choosing a public community server is ok for most...
... but we are control freaks and we know it! ๐๐งช
Let's run our own Free-Forever Mastodon server to stay indie and hip!
Ingredients ๐ณ
- GoToSocial: ActivityPub/Mastodon Server in Go.
- Dex: OIDC Provider to Authenticate Users.
- Pinafore: Web Based Mastodon Client.
- A Cool Domain Name ideally on Cloudflare.
Cooking time should be ~15 minutes.
Free Servers!
In this example we'll use a Oracle Cloud Always Free service tier with a public IP to run our full service.
- Spin up a new
VM
Instance (VM.Standard.E2.1.Micro). - Assign a Public IP and create a DNS A record (example.org).
- Open port
443
and80
usingfirewall-cmd
on the VM. - Open port
443
and80
using theIngress Rules
from the Console.
Go Services!
Let's install and run our services in just minutes.
โ ๏ธ REPLACE example.org WITH YOUR OWN DOMAIN.
GoToSocial
This is our ActivityPub core service. Download and use the latest release.
mkdir /gotosocial && mkdir /gotosocial/storage && mkdir /gotosocial/storage/certs
cd /gotosocial
wget https://github.com/superseriousbusiness/gotosocial/releases/download/v0.5.2/gotosocial_0.5.2_linux_amd64.tar.gz
tar -xzf gotosocial_0.5.2_linux_amd64.tar.gz
Configuration
Clone the example config and start customizing the settings:
cp ./example/config.yaml .
Now open /gotosocial/config.yaml
and change the following settings:
- Set
host
to your domain name (eg., example.org). - Set
port
to443
. - Set
db-type
tosqlite
. - Set
db-address
tosqlite.db
. - Set
storage-local-base-path
to/gotosocial/storage
- Set
letsencrypt-enabled
totrue
(unless on cloudflare) - Set
letsencrypt-email
to your actual email address - Set
letsencrypt-cert-dir
to/gotosocial/storage/certs
.
With the above settings, our server will fetch its own SSL certificates.
Run Service
Create a new service file /etc/systemd/system/gotosocial.service
:
[Unit]
Description=GoToSocial Server
After=network.target
[Service]
ExecStart=/gotosocial/gotosocial --config-path /gotosocial/config.yaml server start
ExecStop=/bin/kill ${MAINPID}
User=root
Group=root
WorkingDirectory=/gotosocial
StandardOutput=append:/var/log/gotosocial.log
StandardError=inherit
Restart=on-failure
RestartSec=10s
Type=simple
CapabilityBoundingSet=~CAP_RAWIO CAP_MKNOD
CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE
CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_TIME CAP_SYS_MODULE CAP_SYS_PACCT
CapabilityBoundingSet=~CAP_LEASE CAP_LINUX_IMMUTABLE CAP_IPC_LOCK
CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_WAKE_ALARM
CapabilityBoundingSet=~CAP_SYS_TTY_CONFIG
CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE
CapabilityBoundingSet=~CAP_NET_ADMIN CAP_NET_BROADCAST CAP_NET_RAW
CapabilityBoundingSet=~CAP_SYS_ADMIN CAP_SYS_PTRACE CAP_SYSLOG
[Install]
WantedBy=multi-user.target
Enable and Start your service:
systemctl daemon-reload
systemctl enable gotosocial.service
systemctl start gotosocial.service
systemctl status gotosocial.service
With a pinch of luck, your service should be already up and running!
Admin Login
Let's create our admin user. Do not make this your personal account.
./gotosocial --config-path ./config.yaml admin account create --username admin--email admin@example.org --password 'SOME_PASSWORD'
Activate the account and add Admin rights for later.
./gotosocial --config-path ./config.yaml admin account confirm --username admin
./gotosocial --config-path ./config.yaml admin account promote --username admin
User Authentication
In order to let other people use our service we'll use Dex
as a local OIDC Provider.
Clone and build the Dex project to begin:
git clone https://github.com/dexidp/dex.git /dex
cd /dex
make build
Copy the example config as a starter to modify
cp /dex/examples/config-dev.yaml /etc/dex.yaml
Edit the parameters in /etc/dax.yaml
file as follows:
issuer: https://example.org:5554/dex
web:
https: 0.0.0.0:5554
tlsCert: /gotosocial/storage/certs/example.com
tlsKey: /gotosocial/storage/certs/example.com
staticClients:
- id: 'gotosocial_client'
redirectURIs:
- 'https://example.org/auth/callback'
name: 'GoToSocial'
secret: 'some-client-secret'
staticPasswords:
- email: "admin@example.org"
# bcrypt hash of the admin pass: $(echo pass | htpasswd -BinC 10 admin | cut -d: -f2)
hash: "$2y$10$QfBnmfPLtmOhbyWLzwYqyuDnKQCTC6xxrECQMJi6uUaQYBNxPFrHi"
username: "admin"
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"
Configure Dex with any Authentication Provider of choice (Github, Google, etc)
Next, edit the oidc
section inside /gotosocial/config.yaml
as follows:
oidc-enabled: true
oidc-idp-name: "Dex"
oidc-skip-verification: false
oidc-issuer: "https://example.org:5554/dex"
oidc-client-id: "gotosocial_client"
oidc-client-secret: "some-client-secret"
oidc-scopes:
- "openid"
- "email"
- "profile"
- "groups"
Create a new service file in /etc/systemd/system/dex.service
[Unit]
Description=Dex Server
After=network.target
[Service]
ExecStart=/dex/bin/dex serve /etc/dex.yaml
ExecStop=/bin/kill ${MAINPID}
User=root
Group=root
StandardOutput=append:/var/log/dex.log
StandardError=inherit
Restart=on-failure
RestartSec=10s
Type=simple
[Install]
WantedBy=multi-user.target
Enable and Start your service, then restart GoToSocial
systemctl daemon-reload
systemctl enable dex.service
systemctl start dex.service
systemctl status dex.service
systemctl restart gotosocial.service
Admin Login
Login to your instance using the /admin
path and the admin credentials.
Proceed to customize the look and feel of your shiny new server!
User Login
Access your personal Mastodon server alongside your friends using Pinafore and your identity provider and break ice by adding a few friends.
You're done - good luck on the fediverse!
If you're used this guide give us a toot! rtctzn.com/@qxip
Next in this series: Mastodon Serverless using CloudFlare Workers + KV
Did you find this article valuable?
Support qryn by becoming a sponsor. Any amount is appreciated!