Hace un tiempo me picó el bichito del self-hosting. Como ciertos datos a hostear son sensibles o pueden dar problemas de derechos de autor al tratar de usar algún servicio de hosting externo, requeriremos un servidor en casa, para lo cual una Raspberry Pi es perfecta. En mi caso, usé una Raspberry Pi 4 con un disco externo de estado sólido (SSD).
Sistema Operativo
Para el sistema operativo, instalaremos la versión AArch64 de Arch Linux ARM siguiendo la guía de instalación.
Luego de tener la Raspberry encendida, tocará actualizar con
pacman -Syu
Configuración Inicial
En lo que sigue, los términos entre <cuñas>
denotarán las partes de los comandos o archivos que deberán reemplazarse por los datos propios de nuestra configuración.
Configuraremos la zona horario usando
timedatectl set-timezone <Zona/Horaria>
. Podremos ver cuáles zonas hay disponibles mirando los contenidos bajo/usr/share/zoneinfo
. Por ejemplo, haciendols /usr/share/zoneinfo/America
, podemos ver que existeAmerica/Santiago
.Actualizaremos el reloj con
timedatectl set-ntp true
.Descomentaremos el idioma que usaremos en
/etc/locale.gen
removiendo el símbolo#
de la línea correspondiente. Esto lo haremos con nuestro editor de texto favorito (por ejemplo ejecutandonano /etc/locale.gen
y borrando el#
deen_US.UTF-8
).- Si no has usado
nano
antes, se guarda con Ctrl +O y se sale con Ctrl +X .
- Si no has usado
Ejecutaremos
locale-gen
y luegolocalectl set-locale LANG=<idioma>.UTF-8
, donde<idioma>
es el que elegimos en el paso anterior.Le pondremos nombre a nuestro servidor con
hostnamectl set-hostname <nombre>
.Editaremos
/etc/hosts
para que se vea como sigue127.0.0.1 localhost.localdomain <nombre> localhost ::1 localhost.localdomain <nombre> localhost
Configuraremos una IP estática para nuestra Raspberry editando el archivo
/etc/systemd/network/eth.network
[1] (suponiendo que conectamos nuestra Raspberry por cable de red). Esto será útil más adelante cuando queramos hacer que nuestro servidor sea accesible desde fuera de la red local.[Match] Name=eth* [Network] Address=<IP Raspberry> Gateway=<IP Router> DNS=208.67.220.220
Opcionalmente, haremos que nuestro servidor sea descubrible por nombre en nuestra red local, de modo de poder conectarnos usando el
<nombre>
que elegimos antes. Para ello, ejecutaremossystemctl enable systemd-resolved.service systemctl start systemd-resolved.service
También de forma opcional, activaremos los colores en
pacman
, editando el archivo/etc/pacman.conf
y descomentando la lineaColor
.
Configuración de usuario
Ahora crearemos un usuario distinto a root
y al por defecto alarm
. Pero primero configuraremos sudo
para poder ejecutar comandos que requieran privilegios sin necesidad de ingresar con root
.
- Instalaremos
sudo
conpacman -S sudo
. - Ejecutaremos
EDITOR=nano visudo
y descomentaremos la línea%wheel ALL=(ALL) ALL
. Al guardar y salir denano
, los usuarios en el grupowheel
tendrán permiso para usarsudo
.
Ahora, crearemos nuestro nuevo usuario.
- Ejecutaremos
useradd -m -G wheel <usuario>
- Crearemos su contraseña con
passwd <usuario>
- Finalmente, borraremos el usuario por defecto
userdel alarm
Ahora probablemente queramos reiniciar la Raspberry si es que no lo hemos hecho ya. Para ello, ejecutaremos
systemctl reboot
Servidor de música: Navidrome
Antes de seguir, es probablemente buena idea configurar nuestro editor de texto favorito y apuntar la variable de entorno $EDITOR
a este. Para ello, basta agregar al archivo .bashrc
la línea
export EDITOR=<editor>
Ahora procederemos a instalar nuestro servidor de música. En este caso, elegimos Navidrome[2], el que instalaremos con
sudo pacman -S navidrome
Luego, ejecutaremos sudoedit /etc/navidrome/navidrome.toml
y dejaremos el archivo como sigue
# additional configuration options can be seen at
# https://www.navidrome.org/docs/usage/configuration-options/#available-options
# Address = "localhost"
MusicFolder = "/var/lib/Music"
# CoverArtPriority = "cover.*, folder.*, front.*, embedded"
#BaseURL = ""
#LastFM.ApiKey = ""
#LastFM.Secret = ""
#Spotify.ID = ""
#Spotify.Secret = ""
A continuación, iniciaremos Navidrome
sudo systemctl enable navidrome.service
sudo systemctl start navidrome.service
Desde un navegador, iremos a http://<IP Raspberry>:4533 o http://<nombre>:4533, en donde nos encontraremos una pantalla para crear el usuario administrador en Navidrome. Una vez hecho esto, podemos crear el resto de los usuarios que necesitemos.
Exponiendo nuestro servidor al Internet
En esta parte de la guía, haremos que se pueda acceder a nuestro servidor desde cualquier parte del mundo. Para ello necesitaremos que nuestro servicio de internet nos provea de una IP estática o usar algún servicio de DNS dinámico.
DNS dinámico
Antes de proceder, instalaremos un gestor de AUR, para poder instalar paquetes desde el repositorio de usuarios. En este caso, instalaremos paru
[3] ejecutando
sudo pacman -S --needed base-devel
git clone https://aur.archlinux.org/paru-bin.git
cd paru-bin
makepkg -si
Como servicio de DNS dinámico usaremos Duck DNS[4]. Luego de ingresar con alguna de nuestras cuentas (la de GitHub en mi caso), crearemos un dominio con el botón add domain. Para actualizar nuestra IP en Duck DNS, instalaremos godns
con
paru -S godns
La configuración se encuentra en /etc/conf.d/godns.json
y deberá verse como sigue
{
"provider": "DuckDNS",
"password": "",
"login_token": "<token>",
"domains": [
{
"domain_name": "www.duckdns.org",
"sub_domains": [ "<dominio>" ]
}
],
"ip_urls": [
"https://api.ipify.org",
"https://myip.biturl.top",
"https://ip4.seeip.org",
"https://ipecho.net/plain",
"https://api-ipv4.ip.sb/ip",
"https://api.ip.sb/ip"
],
"ip_type": "IPv4",
"interval": 300,
"resolver": "8.8.8.8",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36",
"ip_interface": "eth0",
"socks5_proxy": "",
"use_proxy": false,
"debug_info": false
}
Donde <token>
lo podemos encontrar en la página de inicio de Duck DNS una vez ingresamos a nuestra cuenta. Finalmente, iniciamos el servicio con
sudo systemctl enable godns.service
sudo systemctl start godns.service
Redireccionamiento de puertos
Con lo anterior, hicimos que un dominio web dirija a la IP de nuestra red, pero nuestro router bloqueará las conexiones. Ahora debemos hacer que el tráfico se redirija a nuestra Raspberry. Para ello, buscaremos la configuración de puertos del panel de administración del router y agregaremos reglas para los puertos 80 (HTTP) y 443 (HTTPS).
Proxy inverso
Si nos fijamos en el paso anterior, solo abrimos los puertos 80 y 443 hacia el exterior, pero Navidrome estaba usando el puerto 4533. Para remediar esto, y evitarnos tener que estar abriendo puertos cada vez que instalamos un servicio nuevo, usaremos un proxy inverso. En general, la mayoría de los servidores web, como Apache, Nginx y otros, tienen la posibilidad de usarse como proxy inverso, pero en este caso usaremos Caddy[5], pues es ligero y viene con la configuración de certificados para HTTPS incorporada. Para instalarlo, ejecutaremos
sudo pacman -S caddy
Al archivo de configuración /etc/caddy/Caddyfile
agregaremos la siguiente sección
navidrome.<dominio>.duckdns.org:443 {
reverse_proxy localhost:4533
}
Finalmente, iniciaremos el servicio con
sudo systemctl enable caddy.service
sudo systemctl start caddy.service
Como última medida de seguridad, haremos los siguiente cambios en en el archivo /etc/navidrome/navidrome.toml
, para que Navidrome solo se pueda acceder a través de la dirección que elegimos arriba:
- # Address = "localhost"
+ Address = "localhost"
Una vez editado el archivo, reiniciaremos el servicio de Navidrome con
sudo systemctl restart navidrome.service
Servidor de notas: Joplin
Para instalar e iniciar el servidor de Joplin[6] necesitaremos docker
y docker-compose
, los que instalaremos con
sudo pacman -S docker docker-compose
Además, agregaremos a nuestro usuario al grupo docker
sudo usermod -a -G docker <usuario>
e iniciaremos el servicio con
sudo systemctl enable docker.service
sudo systemctl start docker.service
Ahora, crearemos un directorio para almacenar el archivo de configuración
mkdir joplin-server
cd joplin-server
El archivo docker-compose.yml
se verá como sigue
version: '3'
services:
joplin-db:
restart: unless-stopped
image: postgres:16
volumes:
- /foo/bar/joplin-data:/var/lib/postgresql/data
environment:
- POSTGRES_PASSWORD=<contraseña>
- POSTGRES_USER=joplin
- POSTGRES_DB=joplin
joplin:
environment:
- APP_BASE_URL=https://joplin.<dominio>.duckdns.org/
- APP_PORT=22300
- POSTGRES_PASSWORD=<contraseña>
- POSTGRES_DATABASE=joplin
- POSTGRES_USER=joplin
- POSTGRES_PORT=5432
- POSTGRES_HOST=db
- DB_CLIENT=pg
restart: unless-stopped
image: etechonomy/joplin-server:latest
ports:
- "22300:22300"
depends_on:
- db
Para iniciar el servidor, ejecutaremos
docker compose up -d
También agregaremos la siguiente sección a /etc/caddy/Caddyfile
joplin.<dominio>.duckdns.org:443 {
reverse_proxy localhost:22300
}
Ahora reiniciaremos Caddy para poder acceder al servidor de Joplin. Como primera acción, debemos ingresar con las credenciales admin@localhost
y admin
para cambiarlas inmediatamente y crear los usuarios para iniciar la sincronización de notas.