Instalación de un nodo de Mastodon en Debian 9

Después de hacer un artículo sobre cómo instalar un nodo de GNU Social y luego sobre como instalar un nodo de Pleroma, necesitaba hacer un hat-trick y escribir sobre Mastodon -aunque tenga una relación de amor/odio, (más odio que amor)-

Mastodon se diferencia de Twitter siendo una federación descentralizada de servidores​ corriendo software de código abierto (licencia Affero General Public License), y su código y documentación está disponible en el repositorio GitHub . Que sea una red social descentralizada, significa que los usuario están esparcidos en diferentes comunidades autónomas​ e independientes llamadas «instancias» (servidores) cuya red llama fediverso​ (juego de palabras entre federación y universo​) pero aun así unificados por medio de la posibilidad de interactuar entre si.

Preparación del ecosistema

Para realizar este tutorial será necesario tener un servidor Debian 9 -o incluso Ubuntu 18.04- con acceso a root. Además también necesitaremos tener un dominio o subdominio donde hacer la instalación de la instancia de Mastodon. Necesitaremos instalar diferente software como NodeJS, dependencias varias o Ruby.

Paquetes necesarios para tener instalados

Primero de todo necesitamos tener ciertos paquetes instalados en nuestro sistema, así que lo primero es instalarlos:

apt install curl

Instalación de NodeJS

Procedemos a instalar NodeJS desde el repositorio propio que tienen ellos:

curl -sL https://deb.nodesource.com/setup_8.x | bash -

Finalmente, instalamos el paquete NodeJS :

apt-get install -y nodejs

Instalación de Yarn

También será necesario añadir el repositorio de Yarn para la versión de Mastodon.

curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list apt update

Y lo instalamos:

apt install yarn

Instalación de dependencias necesarias

También son necesario instalar todas estas dependencias:

apt -y install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev file git-core g++ libprotobuf-dev protobuf-compiler pkg-config gcc autoconf bison build-essential libssl-dev libyaml-dev libreadline-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev libidn11-dev libicu-dev

Instalación de software necesario

Software necesario para Mastodon, necesitaremos un servidor web, que en este caso será de nuevo Nginx, también usaremos Redis para la caché y luego para las bases de datos usaremos PostgreSQL.

apt install nginx redis-server redis-tools postgresql-9.6 postgresql-contrib-9.6 certbot

Ejecutamos los servicios:

systemctl enable nginx

Dependencias que deben de ser añadidas por un usuario no-root

Creamos un usuario llamado mastodon :

adduser mastodon

Iniciamos como el usuario que hemos creado:

su - mastodon

Instalamos los siguientes paquetes rbenv y ruby-build :

git clone https://github.com/rbenv/rbenv.git ~/.rbenv cd ~/.rbenv && src/configure && make -C src echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc echo 'eval "$(rbenv init -)"' >> ~/.bashrc # Reiniciamos la shell exec bash # Comprobamos que rbenv está bien instalado type rbenv # Instalamos ruby-build git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

Ahora que ya están instalados los paquetes rbenv y ruby-build podemos proceder a la instalación de la versión de Ruby que Mastodon necesita, y para habilitarlo es necesario ejecutar lo siguiente:

rbenv install 2.5.1 rbenv global 2.5.1

Esto llevará un tiempo seguramente, así que por ejemplo, yo me fui hacer un café y aún estaba instalando.

Dependencias para NodeJS y Ruby

Ahora que Ruby está habilitado, vamos a clonar el repositorio de Mastodon y luego instalaremos las dependencias de Ruby y NodeJS.

Volvemos primero a nuestro home:

cd

Clonamos el repositorio de Mastodon:

git clone https://github.com/tootsuite/mastodon.git live

Accedemos dentro de la carpeta creada:

cd live

Instalamos Bundler:

gem install bundler

Usamos Bundler para instalar el resto de dependencias para Ruby:

bundle install -j$(getconf _NPROCESSORS_ONLN) --deployment --without development test

Y usamos Yarn para instalar las dependencias de NodeJS:

yarn install --pure-lockfile

Una vez hemos acabado con esto, ejecutamos exit para salir del usuario mastodon y volver al usuario root .

Creación de la base de datos

Ahora crearemos la base de datos para Mastodon con PostgreSQL, para ello accederemos al prompt:

sudo -u postgres psql

Crearemos la base de datos:

CREATE USER mastodon CREATEDB;

Configuración Nginx con SSL

Por lo que veo en al documentación de Mastodon, te dan toda la configuración de Nginx, con el SSL configurado y demás. Lo que vamos hacer es crearlo por pasos, primero añadimos el nuevo espacio web, luego creamos el certificado y finalmente, añadimos la configuración necesaria para Mastodon.

Creamos el fichero /etc/nginx/sites-available/mastodon.conf y lo editamos para añadir el siguiente contenido y cambiando el parámetro server_name :

server { listen 80; listen [::]:80; server_name midominio.es; root /home/mastodon/live/public; # Useful for Let's Encrypt location /.well-known/acme-challenge/ { allow all; } location / { return 301 https://$host$request_uri; } }

Activamos la web para Nginx:

ln -s /etc/nginx/sites-available/mastodon.conf /etc/nginx/sites-enabled/mastodon.conf

El siguiente paso será crear el certificado para nuestro dominio, así que pasamos a crearlo, pero antes instalamos el Plugin para Nginx:

apt-get install python-certbot-nginx -t stretch-backports

Creamos el certificado:

certbot --authenticator webroot --installer nginx

Ojo a la configuración del certificado. Tenemos que crear el certificado con la opción de webroot , pero /home/mastodon/live/public aún no está habilitado porque no hemos iniciado Mastodon. Por lo que únicamente por esta vez, tendremos que decir que el webroot es /var/www/html para que así Certbot pueda crear el certificado correctamente. Una vez configuremos la parte del servidor con HTTPS, el webroot será /home/mastodon/live/public y ya estará configurado para que funcione correctamente.

Volvemos a editar el fichero de configuración /etc/nginx/sites-available/mastodon.conf y añadimos lo siguiente arriba de todo:

map $http_upgrade $connection_upgrade { default upgrade; '' close; }

Deberemos de tener dos server , el primero para HTTP y el segundo para HTTPS. Certbot habrá modificado seguramente algunas líneas, así que tendremos que dejarlo de nuevo como antes, para el primer server :

server { listen 80; listen [::]:80; server_name midominio.es; root /home/mastodon/live/public; # Useful for Let's Encrypt location /.well-known/acme-challenge/ { allow all; } location / { return 301 https://$host$request_uri; } if ($host = midominio.es) { return 301 https://$host$request_uri; } # managed by Certbot return 404; # managed by Certbot }

Y para el segundo server:

server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name midominio.es; ssl_protocols TLSv1.2; ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_certificate /etc/letsencrypt/live/midominio.es/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/midominio.es/privkey.pem; # managed by Certbot keepalive_timeout 70; sendfile on; client_max_body_size 8m; root /home/mastodon/live/public; gzip on; gzip_disable "msie6"; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; add_header Strict-Transport-Security "max-age=31536000"; location / { try_files $uri @proxy; } location ~ ^/(emoji|packs|system/accounts/avatars|system/media_attachments/files) { add_header Cache-Control "public, max-age=31536000, immutable"; try_files $uri @proxy; } location /sw.js { add_header Cache-Control "public, max-age=0"; try_files $uri @proxy; } location @proxy { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header Proxy ""; proxy_pass_header Server; proxy_pass http://127.0.0.1:3000; proxy_buffering off; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; tcp_nodelay on; } location /api/v1/streaming { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; proxy_set_header Proxy ""; proxy_pass http://127.0.0.1:4000; proxy_buffering off; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; tcp_nodelay on; } error_page 500 501 502 503 504 /500.html; }

Tras este cambio al fichero de configuración, podemos ejecutar nginx -t para comprobar el estado de la sintaxis del fichero y luego reiniciamos el servicio:

/etc/init.d/nginx restart

Instalación de Mastodon

¡Venga, que ya queda poco! Volvemos a iniciar sesión como el usuario mastodon :

su - mastodon

Ahora viene lo interesante. Iniciaremos la instalación donde tendremos una configuración interactiva donde nos pedirá información de nuestra instancia de Mastodon:

RAILS_ENV=production bundle exec rake mastodon:setup

Para no copiar toda la salida del comando, os voy a dejar un listado en plan resumen de lo que pide:

Domain name: midominio.es

Single user mode? n



Are you using Docker to run Mastodon? n

PostgreSQL host: /var/run/postgresql



PostgreSQL port: 5432



Name of PostgreSQL database: mastodon



Name of PostgreSQL user: mastodon



Password of PostgreSQL user:



Redis host: localhost



Redis port: 6379Redis password:



Do you want to store uploaded files on the cloud? No

Do you want to send e-mails from localhost? yes



E-mail address to send e-mails «from»: Mastodon notifications@midominio.es



Send a test e-mail with this configuration right now? Yes



Send test e-mail to:



El correo por el momento no lo vamos a configurar, aún así, lo podéis configurar posteriormente desde /home/mastodon/live/config/environments/production.rb .

Try again? no

This configuration will be written to .env.production



Save configuration? Yes

Prepare the database now? Yes

Compile the assets now? Yes

Do you want to create an admin user straight away? (Y/n) Yes



Username: t3rr0rz0n3



E-mail: zagur@voidnull.es



You can login with the password: 756d88c80c90a5360f6275778b3e0f60



You can change your password once you login.



Configuración de SystemD para Mastodon

Hay que configurar tres servicios para poder iniciar el servicio de manera más sencilla. Estos son los tres ficheros y su contenido:

Para gestionar la web tendremos el fichero /etc/systemd/system/mastodon-web.service

[Unit] Description=mastodon-web After=network.target [Service] Type=simple User=mastodon WorkingDirectory=/home/mastodon/live Environment="RAILS_ENV=production" Environment="PORT=3000" ExecStart=/home/mastodon/.rbenv/shims/bundle exec puma -C config/puma.rb ExecReload=/bin/kill -SIGUSR1 $MAINPID TimeoutSec=15 Restart=always [Install] WantedBy=multi-user.target

Para mantener el servicio en segundo plano tendremos este otro fichero /etc/systemd/system/mastodon-sidekiq.service con el contenido:

[Unit] Description=mastodon-sidekiq After=network.target [Service] Type=simple User=mastodon WorkingDirectory=/home/mastodon/live Environment="RAILS_ENV=production" Environment="DB_POOL=5" ExecStart=/home/mastodon/.rbenv/shims/bundle exec sidekiq -c 5 -q default -q mailers -q pull -q push TimeoutSec=15 Restart=always [Install] WantedBy=multi-user.target

Y finalmente el último servicio para la API /etc/systemd/system/mastodon-streaming.service :

[Unit] Description=mastodon-streaming After=network.target [Service] Type=simple User=mastodon WorkingDirectory=/home/mastodon/live Environment="NODE_ENV=production" Environment="PORT=4000" ExecStart=/usr/bin/npm run start TimeoutSec=15 Restart=always [Install] WantedBy=multi-user.target

Los habilitamos para el arranque:

systemctl enable /etc/systemd/system/mastodon-*.service

Y los iniciamos uno a uno:

systemctl start mastodon-web.service systemctl start mastodon-sidekiq.service systemctl start mastodon-streaming.service

Y una vez hemos acabado con esto… *redoble de tambores* Ta chaaaaan! Ya tenemos Mastodon en nuestro servidor y funcionando perfectamente.

Sólo faltará que la federación haga lo suyo para empezar a ver toda la red disponible 😛