The Joys of Self-Hosting: Difference between revisions

From Lair of Sorrow
(rough outline of Mastodon setup)
 
(formatted and added more technical details)
 
Line 1: Line 1:
To the surprise of probably nobody, I am not a huge fan of corporations, especially when it comes to the internet. For decades I have been self-hosting - first on my own dsl line, then by renting one in a small server farm. This allowed me to own my email, webpages, network file storage and many other things.
To the surprise of probably nobody, I am not a huge fan of corporations, especially when it comes to the internet. For decades I have been self-hosting - first on my own dsl line, then by renting one in a small server farm. This allowed me to own my email, webpages, network file storage and many other things.


I am also not a huge fan of social networks, with twitter being probably the only one I really *use* (as in: I am there from time to time). Recent advancements on the matter (i.e. the acquisition of the platform by a certain billionaire) made me look for an alternative - and that is how I rediscovered Mastodon. To little surprise, the technology has matured in the past years, so I decided to host my own instance of it and become part of the *fediverse*.
== Mastodon ==


I used Ubuntu 20.04 and followed the online documentation, with small tweaks here and there:
I am also not a huge fan of social networks, with twitter being probably the only one I really *use* (as in: I am there from time to time). Recent advancements on the matter (i.e. the acquisition of the platform by a certain billionaire) made me look for an alternative - and that is how I rediscovered Mastodon. To a little surprise, the technology has matured in the past years, so I decided to host my own instance of it and become part of the *fediverse*. And no, I do not really care if anyone follows me or reads my content. I write things mostly for myself to remember them when needed ;)
* sadly Ruby 3.1 did not work, so I had to install recommended 3.0 locally with `rbenv`
 
* Mastodon 4.0.2 ditches `live` directory, so paths in the startup scripts needed to be changed
=== The setup ===
* I installed it outside of `/home`, so paths in default startup scripts were incorrect
 
* because of node 18 and its issues with old versions of open ssl, an extra parameter must be provided: `RAILS_ENV=production NODE_OPTIONS=--openssl-legacy-provider bundle exec rake mastodon:setup`
At the moment of installation the server was running [https://www.ubuntu.com Ubuntu] 20.04 and [https://httpd.apache.org Apache 2]. I have to say that the [https://docs.joinmastodon.org/admin/install official setup guide] was of great help and it was pretty straightforward to follow it. Most of the steps worked, with some notable exceptions.
* I use Apache, so the default `ngix` setup was useless - setting up proxy to puma worked
 
* all hosts are blocked by default in Rails, hence I needed to add `config.hosts << "localhost"`
=== Ruby 3 ===
* static files are served by Rails, but the config says otherwise, so I needed to set `config.public_file_server.enabled = true`
 
Sadly, there is no default package for the latest version of Ruby on Ubuntu (it ships with 2.7), so some magic with <code>rbenv</code> was needed. Remember to update <code>$PATH</code> to include the <code>.rbenv</code> version first, otherwise all gems install nicely, but out of a sudden there is an error of a non-existing class, pointing still to version 2.7.
 
=== Node 18 ===
 
I decided to use a newer version of [https://www.nodejs.org Node] - 18 instead of the required 16. This broke <code>yarn</code>, as it uses <code>openssl</code> 3 instead of 2. To allow it to work an extra parameter must be provided when running the setup: <code>RAILS_ENV=production NODE_OPTIONS=--openssl-legacy-provider bundle exec rake mastodon:setup</code> (only if precompiling assets is needed).
 
=== Postgres ===
 
Despite creating a database user, its database and making the user the owner of it, the install script '''still''' required the user to have <code>createdb</code> rights.
 
Also, the database password is '''written in plain text in the .env file'''. Please make sure nobody can access that file and that the password is not used anywhere else. As soon as the setup was done I also updated the postgres user with <code>nocreatedb</code>, just in case.
 
=== Paths ===
 
First of all, Mastodon 4.0.2 does not use <code>live</code> directory - or at least my setup does not. This means that all the paths in <code>systemd</code> configuration were incorrect and required adjusting. Since I installed it to a different place than the default (<code>/home/mastodon</code>), I needed to check the paths anyway.
 
=== Apache 2 configuration ===
 
The setup deals with proxying <code>ngix</code>. Here are the relevant bits for Apache:
 
        <Directory "/path/to/mastodon/public">
            Options Indexes MultiViews FollowSymLinks
            AllowOverride None
            Require all granted
        </Directory>
 
        <LocationMatch "^/(assets|avatars|emoji|headers|packs|sounds|system)>
          Header always set Cache-Control "public, max-age=31536000, immutable"
          Require all granted
        </LocationMatch>
 
        <IfModule mod_headers.c>
          Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
          Header always set Referrer-Policy "strict-origin-when-cross-origin"
        </IfModule>
 
        SSLProxyEngine On
        SSLEngine on
        SSLProtocol -all +TLSv1.2
        SSLHonorCipherOrder on
        SSLCipherSuite EECDH+AESGCM:AES256+EECDH:AES128+EECDH
 
        Protocols h2 h2c http/1.1
        ProxyPreserveHost On
        RequestHeader set X-Forwarded-Proto "https"
        ProxyPass /api/v1/streaming/ ws://localhost:4000/
        ProxyPassReverse /api/v1/streaming/ ws://localhost:4000/
        ProxyPass / http://localhost:3000/
        ProxyPassReverse / http://localhost:3000/
 
        ErrorDocument 500 /500.html
        ErrorDocument 501 /500.html
        ErrorDocument 502 /500.html
        ErrorDocument 503 /500.html
        ErrorDocument 504 /500.html
 
This seems to be working fine. Of course the site is behind a [https://letsencrypt.org/ Let's Encrypt] certificate.
 
=== Rails issues ===
 
Once everything was up and running I was constantly getting <code>404 Not Found</code> from Apache. Checking directly with Rails by <code><nowiki>wget http://localhost:port/intent.css</nowiki></code> I noticed that the real code was actually <code>403 Forbidden</code>. That is how I found out that Rails blocks all hosts by default and a magic line needs to be added to configuration: <code>config.hosts << 'localhost'</code>.
 
That solved <code>403</code>, it was now showing <code>404</code> from both web servers - and that was caused by Rails not serving static files. To solve that, I simply modified the setting to <code>config.public_file_server.enabled = true</code>.
 
== Conclusion ==
 
Setting up Mastodon was an interesting experience, relatively easy to follow, but with a few twists on the way. However, it seems to be working - feel free to [https://the.unforgiven.pl/@miki follow me on my own Mastodon server].


[[Category:In English]]
[[Category:In English]]
[[Category:Computers]]
[[Category:Computers]]

Latest revision as of 21:10, 15 November 2022

To the surprise of probably nobody, I am not a huge fan of corporations, especially when it comes to the internet. For decades I have been self-hosting - first on my own dsl line, then by renting one in a small server farm. This allowed me to own my email, webpages, network file storage and many other things.

Mastodon

I am also not a huge fan of social networks, with twitter being probably the only one I really *use* (as in: I am there from time to time). Recent advancements on the matter (i.e. the acquisition of the platform by a certain billionaire) made me look for an alternative - and that is how I rediscovered Mastodon. To a little surprise, the technology has matured in the past years, so I decided to host my own instance of it and become part of the *fediverse*. And no, I do not really care if anyone follows me or reads my content. I write things mostly for myself to remember them when needed ;)

The setup

At the moment of installation the server was running Ubuntu 20.04 and Apache 2. I have to say that the official setup guide was of great help and it was pretty straightforward to follow it. Most of the steps worked, with some notable exceptions.

Ruby 3

Sadly, there is no default package for the latest version of Ruby on Ubuntu (it ships with 2.7), so some magic with rbenv was needed. Remember to update $PATH to include the .rbenv version first, otherwise all gems install nicely, but out of a sudden there is an error of a non-existing class, pointing still to version 2.7.

Node 18

I decided to use a newer version of Node - 18 instead of the required 16. This broke yarn, as it uses openssl 3 instead of 2. To allow it to work an extra parameter must be provided when running the setup: RAILS_ENV=production NODE_OPTIONS=--openssl-legacy-provider bundle exec rake mastodon:setup (only if precompiling assets is needed).

Postgres

Despite creating a database user, its database and making the user the owner of it, the install script still required the user to have createdb rights.

Also, the database password is written in plain text in the .env file. Please make sure nobody can access that file and that the password is not used anywhere else. As soon as the setup was done I also updated the postgres user with nocreatedb, just in case.

Paths

First of all, Mastodon 4.0.2 does not use live directory - or at least my setup does not. This means that all the paths in systemd configuration were incorrect and required adjusting. Since I installed it to a different place than the default (/home/mastodon), I needed to check the paths anyway.

Apache 2 configuration

The setup deals with proxying ngix. Here are the relevant bits for Apache:

       <Directory "/path/to/mastodon/public">
           Options Indexes MultiViews FollowSymLinks
           AllowOverride None
           Require all granted
       </Directory>
       <LocationMatch "^/(assets|avatars|emoji|headers|packs|sounds|system)>
         Header always set Cache-Control "public, max-age=31536000, immutable"
         Require all granted
       </LocationMatch>
       <IfModule mod_headers.c>
         Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
         Header always set Referrer-Policy "strict-origin-when-cross-origin"
       </IfModule>
       SSLProxyEngine On
       SSLEngine on
       SSLProtocol -all +TLSv1.2
       SSLHonorCipherOrder on
       SSLCipherSuite EECDH+AESGCM:AES256+EECDH:AES128+EECDH
       Protocols h2 h2c http/1.1
       ProxyPreserveHost On
       RequestHeader set X-Forwarded-Proto "https"
       ProxyPass /api/v1/streaming/ ws://localhost:4000/
       ProxyPassReverse /api/v1/streaming/ ws://localhost:4000/
       ProxyPass / http://localhost:3000/
       ProxyPassReverse / http://localhost:3000/
       ErrorDocument 500 /500.html
       ErrorDocument 501 /500.html
       ErrorDocument 502 /500.html
       ErrorDocument 503 /500.html
       ErrorDocument 504 /500.html

This seems to be working fine. Of course the site is behind a Let's Encrypt certificate.

Rails issues

Once everything was up and running I was constantly getting 404 Not Found from Apache. Checking directly with Rails by wget http://localhost:port/intent.css I noticed that the real code was actually 403 Forbidden. That is how I found out that Rails blocks all hosts by default and a magic line needs to be added to configuration: config.hosts << 'localhost'.

That solved 403, it was now showing 404 from both web servers - and that was caused by Rails not serving static files. To solve that, I simply modified the setting to config.public_file_server.enabled = true.

Conclusion

Setting up Mastodon was an interesting experience, relatively easy to follow, but with a few twists on the way. However, it seems to be working - feel free to follow me on my own Mastodon server.