0%

Run a Mastodon Server on Arch Linux VPS

Mastodon?

Short story: open-source self-hosted Twitter. So why not Twitter? Well Mastodon should be more private and under my own control.

VPS Requirement

I'm using one-year free trial of AWS, there are Arch Linux AMIs according to ArchWiki, which peopel can directly launch EC2 instances.

Basically a VPS that one can install Arch Linux on it is enough; Hardware resource requirement depends on user amount, in my case, a free trial VPS should be enough.

Add DNS Record

Go to my DNS service website then add an A record with public IP of VPS to my domain.

Add Swap Space

Swap - ArchWiki

My VPS has only 1G memory, so a swapfile is considered necessery.

1
2
3
4
# pacman -S systemd-swap
# sed --in-place 's/swapfc_enabled=0/swapfc_enabled=1/' /etc/systemd/swap.conf
# systemctl enable systemd-swap
# reboot

Install Packages Needed

1
# pacman -S nano sudo tmux yay nginx certbot-nginx

I don't know how to use vi so nano is needed.

For package yay, one can install it after adding Arch Linux CN repository.

Create a Privileged User

An AUR package is not allowed to install with root user, so I have to run useradd -m -G wheel liolok && passwd liolok to create a user of administration group, then run nano /etc/sudoers and uncomment the line %wheel ALL=(ALL) ALL.

Install AUR Package

1
2
3
# su - liolok
$ tmux
$ yay -S mastodon

Nodejs stuff will take quite a long time even without output. After installation, press Ctrl + D twice to return to root user.

PostgreSQL and Redis

1
# systemctl enable --now postgresql redis

I ran into a trouble that the service of PostgreSQL failed to start, so look into it:

 root ~ systemctl status postgresql                                                                                                                                                   1 
 postgresql.service - PostgreSQL database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; vendor preset: disabled)
     Active: failed (Result: exit-code) since Sun 2019-12-08 16:37:37 UTC; 20s ago
    Process: 150840 ExecStartPre=/usr/bin/postgresql-check-db-dir ${PGROOT}/data (code=exited, status=1/FAILURE)

Dec 08 16:37:37 ip-172-31-21-37 systemd[1]: Starting PostgreSQL database server...
Dec 08 16:37:37 ip-172-31-21-37 postgres[150840]: "/var/lib/postgres/data" is missing or empty. Use a command like
Dec 08 16:37:37 ip-172-31-21-37 postgres[150840]:   su - postgres -c "initdb --locale en_US.UTF-8 -D '/var/lib/postgres/data'"
Dec 08 16:37:37 ip-172-31-21-37 postgres[150840]: with relevant options, to initialize the database cluster.
Dec 08 16:37:37 ip-172-31-21-37 systemd[1]: postgresql.service: Control process exited, code=exited, status=1/FAILURE
Dec 08 16:37:37 ip-172-31-21-37 systemd[1]: postgresql.service: Failed with result 'exit-code'.
Dec 08 16:37:37 ip-172-31-21-37 systemd[1]: Failed to start PostgreSQL database server.

It seems not a big deal, just follow the instruction to initialize the database cluster and then start service.

1
2
# su - postgres -c "initdb --locale en_US.UTF-8 -D '/var/lib/postgres/data'"
# systemctl start postgres

Then create the Mastodon PostgreSQL user and grant it the ability to create databases:

1
# su - postgres -s /bin/sh -c "createuser -d mastodon"

Nginx

Copy Mastodon's default nginx configuration:

1
2
3
4
# cd /etc/nginx/
# mkdir sites-available sites-enabled
# cp -v /var/lib/mastodon/dist/nginx.conf sites-available/mastodon
# ln -sv sites-available/mastodon sites-enabled/mastodon

Replace example.com with my own domain, fix mastodon path:

1
2
3
# sed --in-place=".default" /etc/nginx/sites-available/mastodon \
-e 's/example\.com/zone\.liolok\.com/' \
-e 's/home\/mastodon\/live/var\/lib\/mastodon/'

Generate certificate:

1
# certbot --nginx -d zone.liolok.com

This command reports that certificate and chain are saved, but haven't been installed to nginx configuration.

It's ok, do the next steps:

  • edit /etc/nginx/nginx.conf and add line include /etc/nginx/sites-enabled/*; to the end of http block;
  • edit /etc/nginx/sites-enabled/mastodon and uncomment the ssl_certificate and ssl_certificate_key lines.

Then run systemctl enable --now nginx.

Final Setup

1
2
# tmux
# su - mastodon -s /bin/sh -c "cd '/var/lib/mastodon'; RAILS_ENV=production bundle exec rails mastodon:setup"

In this step, there will be a command line interface that seems kind of user friendly.

First content to input is my own domain zone.liolok.com; then comes stuff about postgrsql and redis, leave them default; then comes E-mail part: this confused me for a lot of time, at last I used my previous configured Yandex domain mail:

  • host: smtp.yandex.com
  • port: 587 (not the common search result 465)
  • user: i@liolok.com
  • sender: Mastodon <notify@liolok.com>

Then the database and pre-compile work, latter would take longer. Finally I config the admin account information, and get the default password generated.

Up to now, everything is ready. Start the mastodon services, and the website becomes available.

1
# systemctl enable --now mastodon.target