Nota: Actualmente los ejecutores hospedados en GitHub no se admiten en GitHub Enterprise Server. Puede ver más información sobre la compatibilidad futura planeada en GitHub public roadmap.
Acerca de los contenedores de servicios
Los contenedores de servicios son contenedores de Docker que ofrecen una manera sencilla y portátil de alojar servicios que probablemente necesites para probar o usar tu aplicación en un flujo de trabajo. Por ejemplo, es posible que tu flujo de trabajo tenga que ejecutar pruebas de integración que requieran acceso a una base de datos y a una memoria caché.
Puedes configurar contenedores de servicios para cada trabajo en un flujo de trabajo. GitHub crea un contenedor de Docker nuevo para cada servicio configurado en el flujo de trabajo y destruye el contenedor de servicios cuando se termina el trabajo. Los pasos de un trabajo pueden comunicarse con todos los contenedores de servicios que son parte del mismo trabajo. Sin embargo, no se pueden crear y usar contenedores de servicio dentro de una acción compuesta.
Nota: Si en los flujos de trabajo se usan acciones de contenedor de Docker, contenedores de trabajos o de servicios, tendrá que utilizar un ejecutor de Linux:
- Si estás utilizando ejecutores hospedados en GitHub, debes utilizar un ejecutor de Ubuntu.
- Si estás utilizando ejecutores auto-hospedados, debes utilizar una máquina Linux como tu ejecutor, y ésta debe tener Docker instalado.
Comunicarse con contenedores de servicios
Puedes configurar trabajos en un flujo de trabajo para que se ejecuten directamente en una máquina del ejecutor o en un contenedor de Docker. La comunicación entre un trabajo y sus contenedores de servicios cambia en función de si un trabajo se ejecuta directamente en la máquina del ejecutor o en un contenedor.
Ejecutar trabajos en un contenedor
Cuando ejecutas trabajos en un contenedor, GitHub conecta los contenedores de servicios al trabajo mediante las redes de puente definidas por el usuario de Docker. Para obtener más información, consulte “Driver de redes de puente” en la documentación de Docker.
Al ejecutar el trabajo y los servicios en un contenedor, se simplifica el acceso a la red. Puedes acceder a un contenedor de servicios usando la etiqueta que configuraste en el flujo de trabajo. El nombre del host del contenedor de servicios se correlaciona automáticamente con el nombre de la etiqueta. Por ejemplo, si crea un contenedor de servicios con la etiqueta redis
, el nombre de host del contenedor de servicios será redis
.
No es necesario configurar ningún puerto para los contenedores de servicios. Por defecto, todos los contenedores que forman parte de la misma red de Docker se exponen los puertos entre sí, y no se exponen puertos por fuera de la red de Docker.
Ejecutar trabajos en la máquina del ejecutor
Al ejecutar trabajos directamente en la máquina del ejecutor, puede acceder a los contenedores de servicios mediante localhost:<port>
o 127.0.0.1:<port>
. GitHub configura la red de contenedores para habilitar la comunicación desde el contenedor de servicios hasta el host de Docker.
Cuando un trabajo se ejecuta directamente en una máquina del ejecutor, el servicio que se ejecuta en el contenedor de Docker no expone sus puertos al trabajo del ejecutor por defecto. Debes asignar los puertos del contenedor de servicios al host de Docker. Para obtener más información, vea «Acerca de los contenedores de servicios».
Crear contenedores de servicios
Puede usar la palabra clave services
para crear contenedores de servicios que formen parte de un trabajo en el flujo de trabajo. Para más información, vea jobs.<job_id>.services
.
En este ejemplo se crea un servicio denominado redis
en un trabajo denominado container-job
. El host de Docker de este ejemplo es el contenedor node:16-bullseye
.
name: Redis container example on: push jobs: # Label of the container job container-job: # Containers must run in Linux based operating systems runs-on: ubuntu-latest # Docker Hub image that `container-job` executes in container: node:16-bullseye # Service containers to run with `container-job` services: # Label used to access the service container redis: # Docker Hub image image: redis
name: Redis container example
on: push
jobs:
# Label of the container job
container-job:
# Containers must run in Linux based operating systems
runs-on: ubuntu-latest
# Docker Hub image that `container-job` executes in
container: node:16-bullseye
# Service containers to run with `container-job`
services:
# Label used to access the service container
redis:
# Docker Hub image
image: redis
Asignar puertos del host de Docker y del contenedor de servicios
Si tu trabajo se ejecuta en un contenedor de Docker, no necesitas asignar puertos en el host o en el contenedor de servicios. Si tu trabajo se ejecuta directamente en la máquina del ejecutor, tendrás que asignar cualquier puerto requerido del contenedor de servicios a los puertos de la máquina del ejecutor del host.
Puede asignar puertos de contenedores de servicios al host de Docker mediante la palabra clave ports
. Para más información, vea jobs.<job_id>.services
.
Valor de ports | Descripción |
---|---|
8080:80 | Asigna el puerto TCP 80 del contenedor al puerto 8080 del host de Docker. |
8080:80/udp | Asigna el puerto UDP 80 del contenedor al puerto 8080 del host de Docker. |
8080/udp | Asigna un puerto UDP elegido aleatoriamente del contenedor al puerto UDP 8080 del host de Docker. |
Al asignar puertos mediante la palabra clave ports
, GitHub usa el comando --publish
para publicar los puertos del contenedor en el host de Docker. Para obtener más información, consulte "Redes de contenedores de Docker" en la documentación de Docker.
Cuando especificas el puerto del host de Docker pero no el puerto del contenedor, el puerto del contenedor se asigna aleatoriamente a un puerto gratuito. GitHub establece el puerto del contenedor asignado en el contexto del contenedor de servicios. Por ejemplo, para un contenedor de servicios redis
, si configuró el puerto de host de Docker 5432, podrá acceder al puerto de contenedor correspondiente mediante el contexto job.services.redis.ports[5432]
. Para obtener más información, vea «Acceso a información contextual sobre ejecuciones de flujo de trabajo».
Ejemplo de asignación de puertos Redis
En este ejemplo se asigna el puerto 6379 del contenedor redis
de servicios al puerto de host 6379 de Docker.
name: Redis Service Example on: push jobs: # Label of the container job runner-job: # You must use a Linux environment when using service containers or container jobs runs-on: ubuntu-latest # Service containers to run with `runner-job` services: # Label used to access the service container redis: # Docker Hub image image: redis # ports: # Opens tcp port 6379 on the host and service container - 6379:6379
name: Redis Service Example
on: push
jobs:
# Label of the container job
runner-job:
# You must use a Linux environment when using service containers or container jobs
runs-on: ubuntu-latest
# Service containers to run with `runner-job`
services:
# Label used to access the service container
redis:
# Docker Hub image
image: redis
#
ports:
# Opens tcp port 6379 on the host and service container
- 6379:6379
Autenticación con registros de imágenes
Puedes especificar credenciales para los contenedores de servicio si necesitas autenticarte con un registro de imágenes. Esto permite usar imágenes de registros privados o aumentar el límite de velocidad de DockerHub.
Este es un ejemplo de autenticación con Docker Hub y GitHub Container registry:
jobs: build: services: redis: # Docker Hub image image: redis ports: - 6379:6379 credentials: username: ${{ secrets.dockerhub_username }} password: ${{ secrets.dockerhub_password }} db: # Private registry image image: ghcr.io/octocat/testdb:latest credentials: username: ${{ github.repository_owner }} password: ${{ secrets.ghcr_password }}
jobs:
build:
services:
redis:
# Docker Hub image
image: redis
ports:
- 6379:6379
credentials:
username: ${{ secrets.dockerhub_username }}
password: ${{ secrets.dockerhub_password }}
db:
# Private registry image
image: ghcr.io/octocat/testdb:latest
credentials:
username: ${{ github.repository_owner }}
password: ${{ secrets.ghcr_password }}