Tutoriales de VPS
Configurar un runner autohospedado de GitHub Actions en un VPS (2026): instalación, compilación con Docker, caché, actualizaciones automáticas y aislamiento de seguridad
Tutorial completo para desplegar un runner autohospedado de GitHub Actions en un VPS, que abarca la elección de configuración, la ejecución como servicio de Linux, labels, compilación con Docker, caché y disco, aislamiento de seguridad, actualizaciones automáticas y resolución de problemas comunes.

Configurar un runner autohospedado de GitHub Actions en un VPS (2026): instalación, compilación con Docker, caché, actualizaciones automáticas y aislamiento de seguridad
Cuando los trabajos de GitHub Actions se acumulan en cola, los minutos de runner alojado no alcanzan, o las compilaciones deben acceder a una base de datos interna, la primera reacción de muchas personas es comprar un VPS y ejecutar un runner autohospedado.
Este camino ciertamente puede ahorrar dinero y hacer que el entorno de compilación sea totalmente controlable. Pero no es "potencia de cómputo gratuita que se instala y se olvida": el código de los workflows se ejecuta directamente en tu VPS. Qué puede leer el runner, a qué puede conectarse y si puede operar Docker determinan cuán grande será el impacto cuando algo salga mal.
Este artículo trata solo un tema: usar un VPS con Ubuntu/Debian para instalar, convertir en servicio y gestionar de forma estable un runner autohospedado de GitHub Actions.
Si el proyecto es público, los trabajos son pocos y no hay necesidad de acceso a la red interna, yo usaría primero un runner alojado de GitHub. Proporciona un entorno relativamente limpio cada vez y no tienes que preocuparte por el mantenimiento de la máquina.
El runner autohospedado es más adecuado para los siguientes casos:
- Las compilaciones de repositorios privados tardan mucho y quieres reducir el consumo de minutos alojados;
- Las imágenes Docker son grandes y deseas reutilizar la caché de capas local;
- Las compilaciones necesitan acceder a una VPN, servicios internos o una IP de salida fija;
- Necesitas una arquitectura de CPU especial, dependencias del sistema o hardware;
- Ya tienes un VPS inactivo y estás dispuesto a asumir los costos de seguridad y operación.
Si tu necesidad real es "compilar en runners alojados de GitHub y luego desplegar la imagen en un VPS", es más adecuado consultar Migrar de compilación manual en un VPS a GitHub Actions + Docker. Este artículo trata lo contrario: hacer que el propio VPS sea el runner que ejecuta los trabajos de compilación.
El programa del runner en sí es ligero; lo que realmente consume recursos son tus compilaciones, pruebas y compilaciones Docker.
| Uso | Configuración inicial sugerida | Recomendación de disco |
|---|---|---|
| Shell, Go, pruebas pequeñas de Node | 2 núcleos, 2GB | 30GB SSD |
| Compilaciones Node/Java, imágenes Docker normales | 2–4 núcleos, 4GB | 60GB SSD |
| Imágenes multietapa, frontends grandes o pruebas en paralelo | 4 núcleos, 8GB+ | 100GB+ SSD |
El disco suele llenarse antes que la memoria. _work, las capas de Docker, las cachés de herramientas y los registros se acumulan cada vez más. Antes de elegir la máquina, consulta la lista de configuración de VPS para desarrollo y pruebas; no mires solo el precio mensual.
A continuación se usa Ubuntu/Debian como ejemplo:
sudo adduser --disabled-password --gecos "" github-runner
sudo apt update
sudo apt install -y curl ca-certificates git jq tar
sudo install -d -o github-runner -g github-runner /home/github-runner/actions-runner
El runner normalmente solo necesita conectarse activamente a GitHub por HTTPS en el puerto 443; no es necesario abrir puertos de entrada públicos específicamente para él. Si el VPS tiene un firewall de salida estricto o un proxy, permite el tráfico según la lista de dominios de comunicación de GitHub.
No copies números de versión ni valores de verificación del runner de blogs antiguos. Entra al repositorio:
Settings → Actions → Runners → New self-hosted runner
Después de seleccionar Linux y la arquitectura real, GitHub generará los comandos de descarga, verificación y configuración. Cambia al usuario dedicado y ejecuta los comandos actuales de la página en el directorio de instalación:
sudo -iu github-runner
cd ~/actions-runner
#在这里执行 GitHub 页面当前显示的 curl、sha256sum 和 tar 命令
./config.sh \
--url https://github.com/OWNER/REPOSITORY \
--token REGISTRATION_TOKEN \
--name vps-runner-01 \
--labels docker \
--work _work
REGISTRATION_TOKEN es un token de registro generado temporalmente por GitHub; la documentación oficial indica actualmente que es válido por 1 hora. No es un Secret de largo plazo, no lo escribas en scripts, capturas de pantalla ni artículos. Si caduca, vuelve a la página de configuración y regenéralo.
Tras una configuración exitosa, el runner incluye por defecto las etiquetas self-hosted, sistema operativo y arquitectura; aquí se añadió además docker. Las etiquetas son solo condiciones de enrutamiento; no instalan Docker automáticamente ni verifican que la máquina realmente tenga la capacidad correspondiente.
Primero sal del usuario dedicado y luego instala el servicio en el directorio del runner:
exit
cd /home/github-runner/actions-runner
sudo ./svc.sh install github-runner
sudo ./svc.sh start
sudo ./svc.sh status
svc.sh crea actions.runner.*.service. Para ver los registros en tiempo real:
sudo journalctl -u 'actions.runner.*' -f
Ver Idle en la página Runners de GitHub significa que está conectado y esperando trabajos; Active indica que está ejecutando un trabajo; Offline normalmente significa que el servicio no está iniciado, la máquina está desconectada o no puede conectarse a GitHub.
Crea un nuevo .github/workflows/self-hosted-test.yml:
name: self-hosted-runner-test
on:
workflow_dispatch:
jobs:
test:
runs-on: [self-hosted, linux, x64, docker]
steps:
- uses: actions/checkout@v4
- run: |
uname -a
docker version
Cada etiqueta del array debe coincidir simultáneamente con un mismo runner en línea. Cuando un trabajo se queda en Queued, primero verifica mayúsculas y minúsculas, arquitectura y etiquetas personalizadas, y luego comprueba si este runner permite que lo use el repositorio actual.
Si el VPS es ARM64, cambia x64 por el ARM64 que muestra la página del runner; no falsifiques etiquetas solo para que los trabajos se ejecuten.
Si los workflows necesitan compilar imágenes, primero instala Docker Engine según el método oficial de Docker y luego añade el usuario del runner al grupo docker:
sudo usermod -aG docker github-runner
sudo ./svc.sh stop
sudo ./svc.sh start
Atención: poder acceder a /var/run/docker.sock normalmente equivale a poder obtener control de nivel root del host. Los workflows pueden montar directorios del host, leer variables de entorno de otros contenedores e incluso iniciar contenedores privilegiados.
Por eso no mezclaría la base de datos de producción, los contenedores de negocio y el runner en el mismo VPS. Como mínimo:
- Servir solo repositorios privados de confianza;
- Usar un VPS independiente o una máquina virtual independiente para el runner;
- Establecer los permisos de
GITHUB_TOKENcomo solo lectura por defecto, abriéndolos de forma mínima por Job; - Fijar las Actions de terceros a versiones de confianza y, en escenarios críticos, a un commit SHA;
- No permitir que PR de forks sin revisar lleguen a un runner persistente;
- No permitir que la red donde está el runner acceda directamente a la red interna de producción.
GitHub también advierte claramente: los forks de repositorios públicos pueden enviar workflows maliciosos mediante pull requests, y los runners autohospedados casi nunca deberían usarse directamente para repositorios públicos.
Estos tres conceptos se confunden fácilmente:
actions/cachese usa para reutilizar dependencias o cachés de compilación; incluso con un runner autohospedado, la caché se sigue guardando en el almacenamiento en la nube gestionado por GitHub;- Los Artifacts se usan para guardar el resultado de una ejecución de workflow, como informes de pruebas, archivos comprimidos y binarios;
- El
_worklocal del runner, las capas de Docker y las cachés de npm o Maven permanecen en el disco del VPS; son rápidas, pero persisten y pueden ser contaminadas por trabajos posteriores.
Para compilaciones reproducibles, trata la caché local como un acelerador, no como la única copia. Para healthchecks, registros y estrategias de rollback en producción con Docker, consulta la guía de configuración de producción de Docker Compose.
Revisa al menos una vez por semana:
df -h
du -sh /home/github-runner/actions-runner/_work
docker system df
journalctl -u actions.runner.* --disk-usage
No ejecutes docker system prune -af directamente solo porque veas el disco lleno. Elimina contenedores, redes, imágenes y cachés de compilación no utilizados; si además añades --volumes, también podría eliminar volúmenes no utilizados.
Un orden más seguro es: confirmar que no hay ningún Job en ejecución → eliminar directorios de trabajo antiguos que seguro no necesitas → usar docker builder prune para limpiar cachés de compilación reconstruibles → luego gestionar las imágenes antiguas según la lista. Para datos importantes, primero verifica que se puedan recuperar con la guía de simulacros de copia de seguridad y restauración.
El runner se actualiza automáticamente por defecto: si hay un trabajo en ejecución y detecta una nueva versión, se actualiza; si lleva mucho tiempo sin trabajos, también intentará actualizarse dentro de una semana tras el lanzamiento.
Para un VPS persistente, se recomienda mantener la actualización automática por defecto. Si usaste --disableupdate al registrarte, GitHub exige completar la actualización dentro de los 30 días posteriores al lanzamiento de una nueva versión; ante actualizaciones de seguridad críticas, las versiones antiguas podrían dejar de recibir trabajos antes.
Lo que realmente deberías respaldar no es el binario del runner, sino la siguiente información reconstruible:
- El repositorio u organización al que pertenece el runner;
- Las convenciones de usuario, directorio, labels y directorio de trabajo;
- Los pasos de instalación de Docker y las dependencias de compilación;
- Las políticas de firewall y red;
- Los scripts de monitorización, limpieza de disco y reconstrucción.
Poder reinstalar en media hora tras estropear el VPS es más práctico que hacer una copia de seguridad completa del disco de _work.
cd /home/github-runner/actions-runner
sudo ./svc.sh status
sudo journalctl -u 'actions.runner.*' -n 200 --no-pager
sudo -u github-runner ./config.sh --check \
--url https://github.com/OWNER/REPOSITORY \
--pat YOUR_FINE_GRAINED_PAT
Los resultados detallados de --check se escriben en _diag dentro del directorio de instalación. No desactives la verificación TLS de forma permanente solo para ahorrarte trabajo.
Verifica si el runner está Idle, si coinciden todas las etiquetas runs-on y si el repositorio tiene permiso para usar el runner. Si en la misma máquina solo hay un proceso de runner, normalmente solo puede procesar un Job a la vez; mientras el anterior no termina, los siguientes solo pueden esperar en cola.
Primero ve a la página de Actions para confirmar si el Job realmente sigue ejecutándose, luego revisa _diag/Runner_*.log y _diag/Worker_*.log. Si es una compilación Docker descontrolada, primero conserva los registros y la información de procesos, confirma el impacto antes de detener el servicio y no reinicies directamente toda la máquina de producción.
sudo -u github-runner docker version
id github-runner
ls -l /var/run/docker.sock
Después de confirmar el grupo de usuarios, reinicia el servicio del runner para que los permisos del nuevo grupo surtan efecto. Si sigue fallando, revisa Docker rootless o la ruta del socket, en lugar de cambiar el servicio para que se ejecute como root.
En la página de detalles del runner en GitHub, haz clic en Remove; la página generará un token de eliminación con tiempo limitado. Luego ejecuta los comandos de la página en el directorio de instalación:
sudo ./svc.sh stop
sudo ./svc.sh uninstall
sudo -u github-runner ./config.sh remove --token REMOVE_TOKEN
Si la máquina ya está dañada, puedes forzar la eliminación en la página de GitHub. Un runner persistente normal que no se conecta durante 14 días consecutivos también se elimina automáticamente, pero no uses este mecanismo como proceso de limpieza.
Los trabajos de cómputo se ejecutan en tu propia máquina, pero la caché, los Artifacts, la red y otros servicios de GitHub aún pueden verse afectados por las reglas del plan y de facturación. Lo que ahorras son recursos de cómputo alojados; no significa que todos los costos de Actions se reduzcan a cero.
Sí, cada runner usa un directorio, nombre y servicio independientes. Pero competirán por CPU, memoria, disco y el daemon de Docker. En una máquina pequeña es mejor instalar uno primero y decidir si ampliar según la concurrencia de Jobs y los datos de cola.
Técnicamente sí, pero hay que ser prudente con la seguridad. Un enfoque más estable es que el runner de compilación solo produzca imágenes firmadas o Artifacts, y que la etapa de despliegue pase por aprobaciones de entorno y una identidad de publicación con menos permisos.
Antes de ejecutarlo a largo plazo, repasa la lista de refuerzo de seguridad de VPS y la configuración de monitorización y alertas de VPS. Lo más valioso de un runner autohospedado no es la "potencia de cómputo gratuita", sino el control; si los permisos, el disco y el proceso de reconstrucción también están bajo control, entonces realmente ahorra tiempo.