Alpine Linux es la imagen más pequeña que ofrecemos. En nuestros servidores, un Alpine 3.21 recién instalado usaba en reposo 55 MB de RAM y 153 MB de disco, frente a 313 MB y 2,7 GB de Ubuntu 24.04. A cambio renuncias a las herramientas de siempre. Alpine usa apk en lugar de apt, doas en lugar de sudo, OpenRC en lugar de systemd y musl en lugar de glibc.
Los pasos de abajo son los mismos primeros diez minutos que en Debian o Ubuntu, trasladados a Alpine. Ejecutamos cada comando en nuestra imagen de Alpine 3.21 antes de publicar, y dos de ellos nos pillaron la primera vez. Entra como root con la contraseña de tu panel.
1. Actualiza y reinicia una vez
apk update && apk upgrade
uname -r
ls /lib/modules
Tu servidor ya instaló las actualizaciones disponibles en su primer arranque, así que apk upgrade suele tener poco que hacer. Fíjate mejor en las dos últimas líneas. Si esa primera actualización trajo un kernel nuevo, el kernel en marcha (uname -r) ya no tiene sus módulos en el disco. Todo lo que cargue un módulo fallará hasta que reinicies. En nuestro servidor de prueba, la instalación del firewall mostró ERROR: Couldn't determine iptables version. Si las dos versiones no coinciden, reinicia ahora:
reboot
Nuestro servidor de prueba volvió en menos de un minuto.
2. Crea un usuario que pueda entrar
adduser -D deploy
passwd deploy
adduser deploy wheel
No te saltes passwd. adduser -D crea la cuenta sin contraseña, Alpine la marca como bloqueada y sshd rechaza una cuenta bloqueada incluso con la clave correcta. En nuestra prueba, la única pista fue esta línea en /var/log/messages:
User deploy not allowed because account is locked
La contraseña también importa después: es lo que pedirá doas.
Si añadiste una clave SSH al pedir el servidor, está en el authorized_keys de root. Cópiala al nuevo usuario:
install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /root/.ssh/authorized_keys /home/deploy/.ssh/authorized_keys
¿Aún no tienes clave? Crea una en tu ordenador y pega la parte pública en /home/deploy/.ssh/authorized_keys.
3. Haz que doas pida la contraseña
Alpine usa doas en lugar de sudo, y nuestra imagen ya se lo permite al grupo wheel. La regla de /etc/doas.d/wheel.conf es permit nopass :wheel, así que cualquier miembro de wheel se convierte en root sin escribir nada. Haz que pida la contraseña y la recuerde unos minutos:
echo 'permit persist :wheel' > /etc/doas.d/wheel.conf
A partir de ahora, doas apk add nano funciona como sudo apt install nano en Ubuntu.
4. SSH: solo claves, sin root
sshd lee los archivos de /etc/ssh/sshd_config.d/ por orden de nombre y se queda con el primer valor que encuentra para cada ajuste. En nuestra imagen el primer archivo es 00-eqvps.conf, que permite entrar como root y con contraseña para que puedas acceder el primer día. Sustituye su contenido:
cat > /etc/ssh/sshd_config.d/00-eqvps.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
EOF
sshd -t && rc-service sshd restart
sshd -T | grep -E '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication) '
La tercera línea importa en Alpine. La imagen usa la versión de OpenSSH con PAM, y solo con las dos primeras líneas nuestro servidor de prueba seguía ofreciendo el acceso keyboard-interactive. Con las tres, un intento de entrar sin clave recibe:
Permission denied (publickey).
No cierres la sesión de root. En una segunda terminal, comprueba que ssh deploy@YOUR.SERVER.IP funciona (en un plan NAT, añade -p y el puerto personal de tu panel) y que doas id acepta la contraseña.
5. Firewall: ufw
ufw está en el repositorio community, que en nuestra imagen ya está activado:
apk add ufw
ufw limit 22/tcp
ufw --force enable
rc-update add ufw default
ufw status
limit deja pasar SSH pero frena a quien abre muchas conexiones seguidas. rc-update es importante aquí, porque OpenRC no arranca el firewall tras un reinicio si no lo añades al runlevel. Después de reiniciar, nuestro servidor volvió con Status: active. En un plan NAT deja SSH en el puerto 22: tu puerto externo personal se redirige al 22 dentro del servidor. En un plan con IPv4 propia, abre los puertos web cuando los necesites (ufw allow 80/tcp, ufw allow 443/tcp). La guía de ufw cubre el resto.
6. Activa cron y las actualizaciones diarias
Un Alpine recién instalado no ejecuta cron en absoluto. Actívalo:
rc-update add crond default
rc-service crond start
El crontab de root en Alpine ya ejecuta todo lo que hay en /etc/periodic/daily a las 02:00. Deja ahí un script de actualización:
cat > /etc/periodic/daily/apk-upgrade <<'EOF'
#!/bin/sh
apk upgrade --update-cache --no-progress >> /var/log/apk-auto.log 2>&1
EOF
chmod +x /etc/periodic/daily/apk-upgrade
run-parts --test /etc/periodic/daily
El último comando lista los scripts que ejecutará cron, y el tuyo debería aparecer. Así recibes las correcciones de la 3.21. Pasar a la siguiente versión de Alpine es un paso aparte y manual. Las actualizaciones del kernel siguen necesitando un reinicio: repite de vez en cuando la comprobación uname -r / ls /lib/modules del paso 1.
7. OpenRC en una tabla
Si conoces systemd, esto es casi todo lo que cambia:
| Tarea | systemd | Alpine (OpenRC) |
|---|---|---|
| Iniciar un servicio | systemctl start nginx | rc-service nginx start |
| Iniciar al arrancar | systemctl enable nginx | rc-update add nginx default |
| Estado | systemctl status nginx | rc-service nginx status |
| Qué está en marcha | systemctl list-units | rc-status |
| Registro del sistema | journalctl | /var/log/messages |
8. Docker, y el puerto que ufw no bloquea
Alpine es un buen anfitrión para Docker porque el sistema apenas estorba:
apk add docker docker-cli-compose
rc-update add docker default
rc-service docker start
docker run --rm hello-world
En nuestro servidor tardó 12 segundos con la descarga incluida. Con el demonio de Docker en marcha, la memoria usada pasó de 57 MB a 124 MB.
Una trampa que no es exclusiva de Alpine: Docker escribe sus propias reglas de firewall. Con ufw permitiendo solo SSH, arrancamos nginx con -p 8080:80 y lo alcanzamos desde fuera del servidor en el puerto 8080. ufw no lo bloqueó. Si un contenedor solo debe ser accesible a través de un proxy inverso en el mismo servidor, publícalo en localhost:
docker run -d -p 127.0.0.1:8080:80 nginx:alpine
Qué plan elegir
Alpine deja casi toda la RAM para tu propio software. El plan Nano (2 vCPU, 1 GB, 15 GB, $3/mes) basta para un servicio pequeño o unos cuantos contenedores. Es un plan NAT, así que SSH entra por un puerto personal. Si necesitas los puertos 80 y 443 abiertos a internet, Nano-IP tiene su propia IPv4 por $8/mes. Para pilas de Docker más pesadas, Micro te da 2 GB por $5/mes.
Alpine 3.21 está en la página de Alpine VPS y disponible en todos los planes Linux de VPS. El pago es en USDT, USDC o ETH en Base, Ethereum o Polygon, sin documentos ni tarjeta.
Comentarios
Aún no hay comentarios. Sé el primero.