Ejecutar programas automáticamente al iniciar el servidor (systemd y cron)
Así arrancan solas tus aplicaciones, servidores de juego y scripts después de cada reinicio: con una unidad de servicio systemd, el estándar actual, o con una entrada de cron con @reboot.
Arrancar a mano todos los servicios después de cada reinicio del servidor: eso cuesta tiempo y tarde o temprano acaba saliendo mal. Linux trae su propio mecanismo para esto. En esta guía te mostramos cómo ejecutar automáticamente tus propias aplicaciones, servidores de juego, bots o scripts al iniciar el servidor.
Vamos a recorrer dos caminos: una unidad de servicio systemd, que es la solución habitual hoy en día, y la vía más antigua a través de una entrada de cron con @reboot. Ambas funcionan con independencia de la distribución, es decir, igual en Debian, Ubuntu, AlmaLinux y Rocky Linux.
systemd o cron: ¿qué camino te conviene?
systemd es el estándar para los servicios en todas las distribuciones de Linux actuales. Una entrada de cron con @reboot también arranca tu aplicación, pero no sabe hacer nada más que eso.
| Característica | Unidad systemd | Cron con @reboot |
|---|---|---|
| Arranque al iniciar el sistema | sí | sí |
| Reinicio tras una caída | sí, automático | no |
| Consultar el estado | sí, con systemctl | no |
| Registro de las salidas | sí, en el journal | solo si lo rediriges tú |
| Orden de arranque controlable | sí, por ejemplo después de la red | solo de forma aproximada con sleep |
Para todo lo que deba ejecutarse de forma permanente, la unidad systemd es la mejor opción. La entrada de cron sigue siendo un apaño rápido para comandos sencillos que se lanzan una sola vez.
Requisitos previos
- Acceso root por SSH a tu VPS o a tu servidor root.
- Un script de inicio o un programa que ya arranque correctamente desde la línea de comandos. Pruébalo primero a mano antes de automatizarlo.
- La ruta absoluta hasta ese script. Las rutas relativas no funcionan de forma fiable durante el arranque del sistema.
Crear una unidad de servicio systemd
Tus propias unidades van en /etc/systemd/system/ y terminan en .service. Crea el archivo:
nano /etc/systemd/system/miservicio.service
Una plantilla sencilla y lista para usar tiene este aspecto:
[Unit]
Description=Mi propio servicio
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=miusuario
WorkingDirectory=/opt/miservicio
ExecStart=/bin/bash /opt/miservicio/start.sh
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
Qué significa cada línea
- Description: el nombre en texto claro que muestra
systemctl status. - After y Wants: el servicio no arranca hasta que la red está disponible. Así te ahorras el truco del
sleepque se conoce de cron. - Type=simple: el programa se queda ejecutándose en primer plano. Si tu script de inicio se envía a sí mismo a segundo plano, necesitas en su lugar
Type=forkingy una indicaciónPIDFile. - User: el usuario con el que se ejecuta el servicio. Nunca dejes que una aplicación se ejecute como root sin necesidad.
- WorkingDirectory: sustituye al
cdde un script de inicio. - Restart=on-failure: systemd reinicia el servicio después de una caída. Con
Restart=alwayslo hace también cuando el programa termina de forma normal. - WantedBy=multi-user.target: hace que el servicio arranque junto con el sistema en un inicio normal.
Activar y probar el servicio
Después de cada cambio en un archivo de unidad, systemd tiene que volver a leerlo. A continuación activas el servicio para el arranque del sistema y lo inicias directamente:
systemctl daemon-reload
systemctl enable --now miservicio.service
Para ver si todo funciona:
systemctl status miservicio.service
Las salidas de la aplicación acaban en el journal. Con el siguiente comando las lees en directo, que es la vía más rápida cuando buscas un error:
journalctl -u miservicio.service -f
Para detenerlo, reiniciarlo o desactivarlo de forma permanente:
systemctl stop miservicio.service
systemctl restart miservicio.service
systemctl disable miservicio.service
Ejemplo: iniciar automáticamente un servidor TeamSpeak 3
El script de inicio que incluye TeamSpeak se envía a sí mismo a segundo plano y crea un archivo PID. Por eso aquí lo correcto es Type=forking:
[Unit]
Description=TeamSpeak 3 Server
After=network-online.target
Wants=network-online.target
[Service]
Type=forking
User=teamspeak
WorkingDirectory=/home/teamspeak
ExecStart=/home/teamspeak/ts3server_startscript.sh start
ExecStop=/home/teamspeak/ts3server_startscript.sh stop
PIDFile=/home/teamspeak/ts3server.pid
Restart=on-failure
RestartSec=15
[Install]
WantedBy=multi-user.target
Adapta el nombre de usuario y el directorio a tu instalación. Es importante que el usuario indicado sea realmente el propietario del directorio.
Ejemplo: servidor de juego o bot con un script de inicio
Para Minecraft, ARK, Arma 3, servidores LinuxGSM o un bot escrito por ti, normalmente basta con la variante sencilla. El servicio se ejecuta en primer plano y systemd se encarga de la supervisión y del reinicio:
[Unit]
Description=Servidor de juego
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=gameserver
WorkingDirectory=/home/gameserver/server
ExecStart=/bin/bash /home/gameserver/server/start.sh
Restart=always
RestartSec=15
[Install]
WantedBy=multi-user.target
Si varios servicios arrancan a la vez y se frenan entre sí, reparte el arranque con valores distintos en RestartSec o amplía After= con el nombre de la unidad que debe ejecutarse primero.
Alternativa: inicio automático con cron y @reboot
Si solo quieres ejecutar un único comando durante el arranque y no necesitas supervisión, basta con una entrada de cron. Configura primero el editor y abre la crontab:
export VISUAL=nano; crontab -e
Añade ahí una línea con @reboot:
@reboot sleep 60 && cd /<DIRECTORIO-DEL-SCRIPT>/ && bash <TU-SCRIPT>.sh
El @reboot hace que el comando se ejecute una vez en cada arranque del sistema. La parte sleep 60 espera 60 segundos para que la red y la base de datos estén listas antes. Después el comando cambia al directorio de tu script y lo inicia.
Un ejemplo para un servidor de voz que debe ejecutarse con un usuario propio:
@reboot sleep 45 && cd /home/<DIRECTORIO-TEAMSPEAK>/ && sudo -u <USUARIO-TEAMSPEAK> bash ts3server_startscript.sh start
Si añades varias líneas, dale a cada una un valor de sleep distinto (como mínimo 45) para que no arranquen todos los servicios al mismo tiempo. El valor se indica en segundos.
Errores frecuentes
- El servicio no arranca aunque a mano funciona: casi siempre falta una ruta absoluta. Dentro de una unidad o en cron, la variable de entorno PATH está definida de forma muy escueta, así que escribe siempre
/bin/bash /ruta/completa/script.sh. - "Unit not found" después de crearla: se te ha olvidado
systemctl daemon-reload. - El servicio se detiene de inmediato: el programa se ramifica hacia segundo plano. Usa
Type=forkingcon laPIDFileadecuada, o inicia el programa en modo primer plano. - Error de permisos al arrancar: el usuario indicado en
User=no puede acceder al directorio. Comprueba el propietario conls -la. - Después del arranque no se ejecuta nada: el servicio se inició, pero no se activó.
systemctl enablees el paso que lo registra de forma permanente.
Para terminar, la mejor prueba de todas: reinicia el servidor una vez con reboot y comprueba después con systemctl status si todos los servicios se ejecutan como esperabas.
Preguntas frecuentes
¿Qué es mejor: systemd o cron con @reboot?
¿Dónde guardo mi propia unidad systemd?
Mi servicio funciona a mano, pero no arranca al iniciar el sistema. ¿Por qué?
¿Cómo veo las salidas de mi servicio?
¿Necesito todavía screen o tmux para un servidor de juego?
2024-2026 KernelHost GmbH. Todos los derechos reservados. Esta guía está protegida por derechos de autor. Su publicación en otros sitios web, aunque sea de forma parcial o modificada, no está permitida sin nuestro consentimiento por escrito. Las citas con indicación de la fuente y un enlace son muy bienvenidas.

