Disclaimer: This is not intended to be a comprehensive installation guide. I'm detailing my experiences of how I created raki.club and you may find it helpful if you've run into similar issues. Primarily, though, it's a story in perseverance and fiddling with little things to get the big thing working. Let's dive in!
Edit: This server has migrated to the Akkoma frontend and backend on 19 February, 2023. Additional information (including upgrade process) is at the bottom of the page!
Great question, and here's the best way I can explain it: think of email. You have a series of different providers/hosts (Google, Yahoo, etc.), and all of their users can communicate with each other through a shared protocol, known as Simple Mail Transfer Protocal (SMTP). This allows for interoperability between providers. Similarly, servers can be created that can communicated with a protocol termed "ActivityPub". W3C provides a good summary:
The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format. It provides a client to server API for creating, updating and deleting content, as well as a federated server to server API for delivering notifications and content. -- Worldwide Web Consortium (W3C)
"Decentralized social networking protocol" means that there is no core group of servers required for the network to function. You could create a server, and I could create a server, and they could talk to each other without having to go through a third party. This is in comparison with a mainstream social network, which controls the access points to the network and processes the data flow through that network.
The second sentence contains two points: that servers can communicate with one another, and that clients can communicate with servers, using an API (Application Programming Interface, or a standardized set of protocols with which software can liase).
Federation is when servers open themselves up to other servers to send and receive messages and other information. Together, this forms the backbone of what's called the Fediverse. Note that the Fediverse is not solely for micro-blogging sites, but for various web publishing. This spans social networking, multimedia, and more.
The most popular software used to interact with the social networking branch of the Fediverse is called Mastodon. To create an account, you need to register on an "instance", or a server running such software, and you can start interacting with other users. A list of such servers can be found at joinmastodon.org. However, Mastodon is not the only software created to engage in this social network.
Enter Pleroma. Pleroma is a similar software that does much of what Mastodon does, while requiring fewer computing resources. This is important because the server that I currently run has limited hardware, only one CPU core and one gigabyte of memory. That same server is also hosting this website, which further reduces the computing capacity that can be allocated to additional software.
How, then, do I install Pleroma? One option is to user a prebuilt Docker container. Docker is an application deployment platform, which slots perfectly into hosting multiple applications (like this website's software, wiki.js and Pleroma). I've used Docker before, hosting content management and monitoring applications, but in my experience, they're less transparent to understand the under-the-hood processes. While I'm sure a seasoned Docker user would have no trouble with that, I'm more comfortable with a bare-metal (directly on the server, without intermediary layers) installation, so I elected to do that instead.
So, I ssh'd into my server, and started to follow the OTP (pre-packaged, without needing to build from source) intallation instructions. The installation platform was amd64 Ubuntu 20.04 LTS, so I followed those instructions.
First, I updated the repositories, using sudo apt update
. Next, I installed the necessary packages with:
apt install curl unzip libncurses5 postgresql postgresql-contrib certbot libmagic-dev
This was also going to be my first foray using the Postgres database system -- my applications before have all used MySQL They're different in that mysql is relational, and more efficient when reading, but is less performant in concurrent read/write operations. Postgres is a better database application for this instance because while a static website won't see very many writes, a social network will be processing both inbound and outbound content, giving Postgres the upper hand.
I also chose to install the additional packages:
apt install imagemagick ffmpeg libimage-exiftool-perl
This adds a user from which the main Pleroma program will run. Since running the application with superuser (root) priviledges is not advisiable for a host of security and controls reasons, it's necessary to create a user before continuing from which we can install and configure the application from:
adduser --system --shell /bin/false --home /opt/pleroma pleroma
Now, we enter the pleroma
user we've created (using su pleroma -s $SHELL -lc
, which will be used later as well) and download the package using curl
, and extract it into a temporary directory.
su pleroma -s $SHELL -lc "
curl 'https://git.pleroma.social/api/v4/projects/2/jobs/artifacts/stable/download?job=amd64' -o /tmp/pleroma.zip
unzip /tmp/pleroma.zip -d /tmp/
"
Following this, the extracted files are moved to their final location in /opt/
su pleroma -s $SHELL -lc "
mv /tmp/release/* /opt/pleroma
rmdir /tmp/release
rm /tmp/pleroma.zip
"
The directory to store user-uploaded content is created, and permissions are given to the pleroma
user (note that the -R
option means that the ownership command is applied recursively, or to all the files included in the directory).
mkdir -p /var/lib/pleroma/uploads
chown -R pleroma /var/lib/pleroma
The same is done for the static directory, which notably stores the files that the frontend will use. There are two interconnected pieces of software being used: the backend, which does the data storage and communication, and the frontend, which is what an end user sees when they go to the website in their browser.
mkdir -p /var/lib/pleroma/static
chown -R pleroma /var/lib/pleroma
Finally, the directory for the configuration file is created.
mkdir -p /etc/pleroma
chown -R pleroma /etc/pleroma
We now drop down into the shell of the pleroma
user to execute the command that generates the instance, as well as creates a configuration file and initializes the database.
su pleroma -s $SHELL -lc "./bin/pleroma_ctl instance gen --output /etc/pleroma/config.exs --output-psql /tmp/setup_db.psql"
su postgres -s $SHELL -lc "psql -f /tmp/setup_db.psql"
su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate"
The Pleroma instance is started:
su pleroma -s $SHELL -lc "./bin/pleroma daemon"
After waiting for ~20 seconds, the output of the instance is probed to confirm that it is running as expected
sleep 20 && curl http://localhost:4000/api/v1/instance
For instance, the output from my server reads as such:
{"approval_required":true,"avatar_upload_limit":2000000,"background_image":"https://raki.club/images/city.jpg","background_upload_limit":4000000,"banner_upload_limit":4000000,"description":"amey's server in the fediverse","description_limit":5000,"email":"****@*******.com","languages":["en"],"max_media_attachments":1000,"max_toot_chars":5000,"pleroma":{"metadata":{"account_activation_required":false,"birthday_min_age":0,"birthday_required":false,"features":["pleroma_api","mastodon_api","mastodon_api_streaming","polls","v2_suggestions","pleroma_explicit_addressing","shareable_emoji_packs","multifetch","pleroma:api/v1/notifications:include_types_filter","editing","blockers_visible","chat","shout","pleroma_emoji_reactions","pleroma_chat_messages","exposable_reactions","profile_directory","pleroma:get:main/ostatus"],"federation":{"enabled":true,"exclusions":true,"mrf_hashtag":{"federated_timeline_removal":[],"reject":[],"sensitive":["nsfw"]},"mrf_object_age":{"actions":["delist","strip_followers"],"threshold":604800},"mrf_policies":["ObjectAgePolicy","TagPolicy","SimplePolicy","HashtagPolicy"],"mrf_simple":{"accept":[],"avatar_removal":[],"banner_removal":[],"federated_timeline_removal":[],"followers_only":[],"media_nsfw":[],"media_removal":[],"reject":[],"reject_deletes":[],"report_removal":[]},"mrf_simple_info":{},"quarantined_instances":[],"quarantined_instances_info":{"quarantined_instances":{}}},"fields_limits":{"max_fields":10,"max_remote_fields":20,"name_length":512,"value_length":2048},"post_formats":["text/plain","text/html","text/markdown","text/bbcode"]},"stats":{"mau":7},"vapid_public_key":"BFW4B5S024cbb031F3-8H-xKksoegDV3QzO0_u2OTGd3nBOAByo2KALuke6oLTQGTqX3TANV8RzrMHRvPC4dNSM"},"poll_limits":{"max_expiration":31536000,"max_option_chars":200,"max_options":20,"min_expiration":0},"registrations":true,"short_description":"amey's server in the fediverse","shout_limit":5000,"stats":{"domain_count":2600,"status_count":28,"user_count":5},"thumbnail":"https://raki.club/instance/thumbnail.jpeg","title":"raki","upload_limit":16000000,"uri":"https://raki.club","urls":{"streaming_api":"wss://raki.club"},"version":"2.7.2 (compatible; Pleroma 2.5.0)"}
Now, the instance is stopped. The final instance will be run as a service, to make it easier to manage.
su pleroma -s $SHELL -lc "./bin/pleroma stop"
SSL certificates are generated using LetsEncrypt.
certbot certonly --standalone --preferred-challenges http -d yourinstance.tld
Finally, since my server uses Apache to handle serving websites, an Apache configuration file needs to be created. While the official installation uses Nginx, a suitable pre-configured Apache configuration file is available here. I modified it to this:
Define servername raki.club
<IfModule !proxy_module>
LoadModule proxy_module libexec/apache24/mod_proxy.so
</IfModule>
<IfModule !proxy_http_module>
LoadModule proxy_http_module libexec/apache24/mod_proxy_http.so
</IfModule>
<IfModule !rewrite_module>
LoadModule rewrite_module libexec/apache24/mod_rewrite.so
</IfModule>
<IfModule !ssl_module>
LoadModule ssl_module libexec/apache24/mod_ssl.so
</IfModule>
ServerName ${servername}
ServerTokens Prod
<VirtualHost *:80>
RewriteEngine on
RewriteCond %{SERVER_NAME} =${servername}
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
ServerAlias www.raki.club
</VirtualHost>
<VirtualHost *:443>
ServerAlias www.raki.club
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/${servername}/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/${servername}/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:4000/$1 [P,L]
#ProxyRequests must be off or you open your server to abuse as an open proxy
ProxyRequests off
ProxyPass / http://127.0.0.1:4000/
ProxyPassReverse / http://127.0.0.1:4000/
ProxyPreserveHost On
</VirtualHost>
Finally, pleroma.service
is added to systemd, the Linux service manager. This is achieved via the following command:
cp /opt/pleroma/installation/pleroma.service /etc/systemd/system/pleroma.service
Always, always, backup your configuration file. Preferably off the server, but at least to a different directory, separate from the application's. The administration database (enabled with config :pleroma, configurable_from_database: true
in the /etc/pleroma/config.exs file) can be reset and recreated with
su pleroma -s $SHELL -lc "./bin/pleroma_ctl config reset"
This pulls from the config file located at /etc/pleroma/config.exs
, so some settings may be lost in transition if parity between the config file and config database isn't maintained.
More information about this is available here.
Pleroma has a couple frontend options to choose from. One of the options is Soapbox. However, it has a troubled history, in large part from the views and associations of its creator. While I recognize its appealing design and robust implementation, I don't want to support someone with such an unsavory background in my personal endeavors.
I've really enjoyed setting this up. I've learned a lot about this new decentralized network, the Fediverse, and it aligns with my values of the internet being a free, user-controlled place. Social media is a great tool if used correctly, but often users end up controlled and manipulated by services that don't value their best interests. A free and open web is critical to realizing the power the internet has given us, and being able to control our own space within the internet is a crucial element of building a future online space we can be proud of.
In the search for improvement, I've since migrated from Pleroma frontend and backend to the Akkoma frontend and backend. Akkoma, a fork (it's the alternate universe version of Pleroma, with some modifications and improvements). Akkoma has more features, while also having a intentional identity that I agree with.
Here are the steps I took to migrate to Akkoma. The documentation provides very good advice, which I followed.
First, stop the service. As detailed above, I used systemctl
to run the service.
I ran Pleroma's built-in updater, but instead pointing to Akkoma's package. Since Pleroma is the foundation upon which Akkoma is built, the upgrade path is pretty seamless.
su pleroma -s $SHELL -lc "./bin/pleroma_ctl update --zip-url https://akkoma-updates.s3-website.fr-par.scw.cloud/stable/akkoma-amd64.zip"
su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate"
Next, the docs suggest that you install the new frontends for both general website (pleroma-fe) as well as the admin website (admin-fe).
su pleroma -s $SHELL -lc "./bin/pleroma_ctl frontend install pleroma-fe --ref stable"
su pleroma -s $SHELL -lc "./bin/pleroma_ctl frontend install admin-fe --ref stable"
However, I encountered an issue that made the admin-fe unreachable, even after completely removing the files. So, I removed the existing frontends from the configuration files using
su pleroma -s $SHELL -lc "./bin/pleroma_ctl config delete pleroma frontends"
I reinstalled the frontends again, and that problem went away.
Another issue I noticed was that although the Mastodon frontend is available, the server that the update points to seems to be down. This brings me to my main concern: that this bears hallmarks of a passion project that will one day be abandoned, and I'll eventually need to move off of it and thus start over. There's a single main developer, and they do have an admirable sense of dedication. However, there's always the chance that that dedication wanes, and the project is left to languish. Either way, that's the nature of FOSS, and without talented and driven people like the developers of software like this, such a conversation would not exist.
Overall, I'm pleased with the work the Akkoma developers have put into making this a viable transition. While this may be a short-lived venture, I'm glad to have experienced it, and I hope to see this project continue!