--- title: "Cómo instalar Drone CI en Ubuntu 24.04 con Docker y GitHub" description: "Instala Drone CI y su runner de Docker con Docker Compose en Ubuntu 24.04, publícalo con Nginx y HTTPS, conéctalo a GitHub y ejecuta tu primer pipeline." category: "CI/CD DevOps" language: es source: https://cubepath.com/es/docs/ci-cd-devops/instalacion-y-configuracion-de-drone-ci updated: 2026-09-25 --- # Cómo instalar Drone CI en Ubuntu 24.04 con Docker y GitHub Drone es una plataforma de integración continua ligera en la que cada paso de un pipeline se ejecuta dentro de un contenedor Docker. Se compone de un servidor, que recibe los webhooks del proveedor Git y muestra la interfaz web, y de uno o varios runners, que ejecutan los pipelines. En este tutorial instalarás el servidor de Drone y el runner de Docker con Docker Compose en Ubuntu 24.04, lo publicarás con Nginx y HTTPS, lo conectarás a GitHub y ejecutarás un pipeline definido en `.drone.yml`. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS con al menos 2 vCPU y 4 GB de RAM, por ejemplo un VPS de CubePath, y un usuario no root con privilegios `sudo`. - Docker Engine y el plugin de Docker Compose instalados desde el repositorio oficial de Docker. - Un dominio o subdominio, como `drone.your_domain`, con un registro DNS A que apunte a la IP pública del servidor. - Una cuenta de GitHub con acceso a los repositorios que quieres integrar. Sustituye `drone.your_domain` por tu subdominio y `your_github_user` por tu usuario de GitHub en todos los comandos y archivos. > Nota: Drone lo mantiene Harness, que ha integrado su evolución en Harness Open Source. Drone 2 sigue publicándose como imagen `drone/drone:2` y es una opción válida para un CI autoalojado sencillo. ## Paso 1: Crear la aplicación OAuth en GitHub Drone no tiene usuarios propios: los usuarios inician sesión con su cuenta de GitHub mediante OAuth, y Drone usa ese acceso para leer los repositorios y crear los webhooks. En GitHub, ve a **Settings > Developer settings > OAuth Apps > New OAuth App** y rellena el formulario: | Campo | Valor | |---|---| | Application name | `Drone` | | Homepage URL | `https://drone.your_domain` | | Authorization callback URL | `https://drone.your_domain/login` | Pulsa **Register application**. En la página de la aplicación copia el **Client ID** y pulsa **Generate a new client secret** para obtener el **Client secret**. Guarda ambos valores: los usarás en el paso 2. ## Paso 2: Preparar la configuración de Drone Crea un directorio para el proyecto de Docker Compose: ```bash sudo mkdir -p /opt/drone cd /opt/drone ``` El servidor y el runner se autentican entre sí con un secreto compartido. Genéralo con `openssl`: ```bash openssl rand -hex 16 ``` ```output 3f9c1e7a2b8d4c6e0f1a2b3c4d5e6f70 ``` Crea el archivo `.env` que leerá Docker Compose: ```bash sudo nano /opt/drone/.env ``` Añade las variables con tus valores: ```ini DRONE_SERVER_HOST=drone.your_domain DRONE_GITHUB_CLIENT_ID=your_client_id DRONE_GITHUB_CLIENT_SECRET=your_client_secret DRONE_RPC_SECRET=3f9c1e7a2b8d4c6e0f1a2b3c4d5e6f70 DRONE_ADMIN_USER=your_github_user ``` Este archivo contiene secretos, así que restringe sus permisos: ```bash sudo chmod 600 /opt/drone/.env ``` ## Paso 3: Definir el servidor y el runner con Docker Compose Crea el archivo de Compose: ```bash sudo nano /opt/drone/compose.yaml ``` Añade este contenido: ```yaml services: drone-server: image: drone/drone:2 restart: unless-stopped ports: - "127.0.0.1:8080:80" volumes: - drone-data:/data environment: DRONE_GITHUB_CLIENT_ID: ${DRONE_GITHUB_CLIENT_ID} DRONE_GITHUB_CLIENT_SECRET: ${DRONE_GITHUB_CLIENT_SECRET} DRONE_RPC_SECRET: ${DRONE_RPC_SECRET} DRONE_SERVER_HOST: ${DRONE_SERVER_HOST} DRONE_SERVER_PROTO: https DRONE_USER_CREATE: username:${DRONE_ADMIN_USER},admin:true DRONE_USER_FILTER: ${DRONE_ADMIN_USER} drone-runner: image: drone/drone-runner-docker:1 restart: unless-stopped depends_on: - drone-server volumes: - /var/run/docker.sock:/var/run/docker.sock environment: DRONE_RPC_PROTO: http DRONE_RPC_HOST: drone-server DRONE_RPC_SECRET: ${DRONE_RPC_SECRET} DRONE_RUNNER_CAPACITY: 2 DRONE_RUNNER_NAME: runner-1 volumes: drone-data: ``` Puntos importantes de esta configuración: - El servidor escucha solo en `127.0.0.1:8080`. El acceso desde Internet pasará por Nginx con HTTPS, que configurarás en el paso 5. - `DRONE_USER_CREATE` convierte tu usuario de GitHub en administrador en el primer arranque. - `DRONE_USER_FILTER` limita quién puede iniciar sesión. Sin él, cualquier persona con cuenta de GitHub podría registrarse y ejecutar código en tu runner. Puedes indicar varios usuarios u organizaciones separados por comas, por ejemplo `your_github_user,your_org`. - El runner se conecta al servidor por la red interna de Compose (`drone-server`), sin salir a Internet. - `DRONE_RUNNER_CAPACITY` fija cuántos pipelines se ejecutan a la vez. - Los datos (base de datos SQLite, usuarios, repositorios, secretos) se guardan en el volumen `drone-data`. > Advertencia: el runner monta el socket de Docker, lo que equivale a acceso root al servidor. Activa en Drone solo repositorios de confianza y no aceptes pipelines de forks sin revisarlos. ## Paso 4: Arrancar Drone Inicia los contenedores en segundo plano: ```bash cd /opt/drone sudo docker compose up -d ``` Comprueba que ambos servicios están en ejecución: ```bash sudo docker compose ps ``` Los servicios `drone-server` y `drone-runner` deben aparecer con el estado `Up`, y el servidor con el puerto `127.0.0.1:8080->80/tcp`. Revisa los registros del runner para confirmar que se ha conectado al servidor: ```bash sudo docker compose logs drone-runner ``` ```output drone-runner-1 | time="2026-09-24T10:20:31Z" level=info msg="successfully pinged the remote server" drone-runner-1 | time="2026-09-24T10:20:31Z" level=info msg="polling the remote server" ``` Si en lugar de esto ves errores de autenticación, el valor de `DRONE_RPC_SECRET` no llega igual a los dos contenedores. Revisa el archivo `.env`. ## Paso 5: Publicar Drone con Nginx y HTTPS GitHub necesita alcanzar Drone por HTTPS para completar el inicio de sesión y enviar los webhooks. Instala Nginx y Certbot: ```bash sudo apt update sudo apt install nginx certbot python3-certbot-nginx ``` Crea el bloque de servidor para Drone: ```bash sudo nano /etc/nginx/sites-available/drone ``` Añade esta configuración: ```nginx server { listen 80; listen [::]:80; server_name drone.your_domain; location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; 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 $scheme; proxy_set_header Connection ""; proxy_buffering off; proxy_read_timeout 3600s; } } ``` `proxy_buffering off` y el tiempo de espera largo permiten que los registros de las ejecuciones lleguen en tiempo real al navegador. Activa el sitio y comprueba la sintaxis: ```bash sudo ln -s /etc/nginx/sites-available/drone /etc/nginx/sites-enabled/ sudo nginx -t ``` ```output nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful ``` Recarga Nginx y abre los puertos HTTP y HTTPS en UFW si el cortafuegos está activo: ```bash sudo systemctl reload nginx sudo ufw allow 'Nginx Full' ``` Solicita el certificado de Let's Encrypt. Certbot modificará el bloque de servidor para añadir HTTPS y la redirección desde HTTP: ```bash sudo certbot --nginx -d drone.your_domain ``` Comprueba que Drone responde por HTTPS: ```bash curl -sI https://drone.your_domain ``` ```output HTTP/2 200 server: nginx/1.24.0 (Ubuntu) content-type: text/html; charset=UTF-8 ``` ## Paso 6: Iniciar sesión y activar un repositorio Abre `https://drone.your_domain` en el navegador y pulsa **Continue**. GitHub te pedirá autorizar la aplicación OAuth que creaste en el paso 1; acepta y volverás a Drone, que sincronizará la lista de tus repositorios. Elige el repositorio que quieres integrar y pulsa **Activate Repository**. Drone creará automáticamente un webhook en GitHub. Puedes comprobarlo en el repositorio de GitHub, en **Settings > Webhooks**: debe aparecer una entrada que apunta a `https://drone.your_domain/hook` con una marca de entrega correcta. ## Paso 7: Crear el primer pipeline Drone lee la definición del pipeline del archivo `.drone.yml` en la raíz del repositorio. Este ejemplo, para un proyecto Node.js, instala las dependencias y ejecuta las pruebas en cada `push` y pull request: ```yaml kind: pipeline type: docker name: default steps: - name: test image: node:22 commands: - npm ci - npm test trigger: event: - push - pull_request ``` Cada paso se ejecuta en un contenedor creado a partir de `image`, con el código del repositorio montado como directorio de trabajo. Los pasos comparten ese directorio, así que lo que genera un paso (por ejemplo `node_modules` o una carpeta `dist/`) está disponible para los siguientes. Confirma el archivo y súbelo: ```bash git add .drone.yml git commit -m "Add Drone pipeline" git push ``` En la interfaz de Drone aparecerá una nueva ejecución con el paso `clone` (que Drone añade automáticamente) y el paso `test`. Pulsa sobre cada paso para ver su salida. Un paso que termina con código distinto de cero marca la ejecución como fallida y detiene los pasos siguientes. ## Paso 8: Usar secretos y plugins Los plugins de Drone son imágenes Docker que reciben su configuración mediante `settings`. Un caso habitual es construir una imagen y publicarla en Docker Hub con el plugin `plugins/docker`. Las credenciales no deben estar en el repositorio, así que se guardan como secretos de Drone. En la interfaz, abre el repositorio, ve a **Settings > Secrets** y crea dos secretos: `docker_username` con tu usuario de Docker Hub y `docker_password` con un token de acceso de Docker Hub. Añade un segundo paso al `.drone.yml`: ```yaml kind: pipeline type: docker name: default steps: - name: test image: node:22 commands: - npm ci - npm test - name: publish image: plugins/docker settings: repo: your_dockerhub_user/myapp tags: - latest - ${DRONE_COMMIT_SHA:0:8} username: from_secret: docker_username password: from_secret: docker_password when: branch: - main event: - push trigger: event: - push - pull_request ``` `from_secret` inyecta el valor del secreto sin mostrarlo en los registros, y la sección `when` hace que la imagen solo se publique en los `push` a `main`, no en las pull requests. Drone ejecuta `plugins/docker` en modo privilegiado de forma automática porque está en su lista de plugins de confianza. > Nota: por defecto, Drone no expone los secretos a las pull requests que vienen de forks. Mantén ese comportamiento para que nadie pueda leer tus credenciales abriendo una pull request. ### Gestionar secretos con la CLI de Drone También puedes gestionar secretos y ejecuciones desde la terminal. Descarga la CLI: ```bash curl -fsSL https://github.com/harness/drone-cli/releases/latest/download/drone_linux_amd64.tar.gz | tar zx sudo install -t /usr/local/bin drone ``` Copia tu token personal desde la página de tu cuenta en la interfaz de Drone (menú de usuario, **User settings**) y exporta las variables: ```bash export DRONE_SERVER=https://drone.your_domain export DRONE_TOKEN=your_drone_token ``` Comprueba la conexión y crea un secreto: ```bash drone info drone secret add --repository your_github_user/myapp --name docker_username --data your_dockerhub_user ``` ## Paso 9: Hacer copias de seguridad Todo el estado de Drone está en el volumen `drone-data`, que Compose crea con el prefijo del proyecto (`drone_drone-data`). Para una copia consistente de la base de datos SQLite, detén el servidor un momento, guarda el volumen y vuelve a arrancarlo: ```bash cd /opt/drone sudo docker compose stop drone-server sudo docker run --rm -v drone_drone-data:/data:ro -v /opt/drone:/backup alpine \ tar czf /backup/drone-data-$(date +%F).tar.gz -C /data . sudo docker compose start drone-server ``` Comprueba que el archivo se ha creado: ```bash ls -lh /opt/drone/drone-data-*.tar.gz ``` Guarda también el archivo `.env`: sin el mismo `DRONE_RPC_SECRET` y las credenciales OAuth tendrías que volver a configurar el runner y la aplicación de GitHub. ## Solución de problemas **GitHub muestra `The redirect_uri is not associated with this application`**: la **Authorization callback URL** de la aplicación OAuth no coincide con `https://drone.your_domain/login`, o `DRONE_SERVER_PROTO` y `DRONE_SERVER_HOST` no reflejan la URL pública. Corrige el valor y ejecuta `sudo docker compose up -d` para recrear el servidor. **Las ejecuciones se quedan en estado pendiente**: el runner no está conectado. Revisa `sudo docker compose logs drone-runner` y comprueba que el `DRONE_RPC_SECRET` es el mismo en ambos servicios. **No puedes iniciar sesión aunque GitHub autoriza la aplicación**: tu usuario u organización no está en `DRONE_USER_FILTER`. Añádelo y recrea el servidor. **Los `push` no lanzan ejecuciones**: revisa en GitHub, en **Settings > Webhooks**, la última entrega del webhook de Drone. Un error de conexión suele indicar que el certificado no es válido o que el puerto 443 está cerrado. ## Conclusión Tienes Drone CI funcionando en Ubuntu 24.04 detrás de Nginx con HTTPS, conectado a GitHub, con un runner de Docker que ejecuta los pipelines definidos en `.drone.yml` y secretos guardados fuera del repositorio. Como siguientes pasos puedes añadir más runners en otros servidores apuntando al mismo `DRONE_RPC_HOST`, pasar la base de datos a PostgreSQL si el uso crece, o añadir un paso de despliegue que se conecte por SSH a tus servidores.