Quiz: Docker y CI/CD
Ponga a prueba sus conocimientos sobre Docker, Docker Compose y GitHub Actions.
30 preguntas - Haga clic en cada pregunta para revelar la respuesta.
Preguntas 1-15: Docker
Pregunta 1: ¿Qué es Docker?
Respuesta: Docker es una plataforma de contenedores que permite empaquetar una aplicación con todas sus dependencias en un contenedor ligero y portátil. Ventajas:
- Mismo entorno en todas partes
- Aislamiento de aplicaciones
- Despliegue rápido
- Escalabilidad
Pregunta 2: ¿Cuál es la diferencia entre una imagen y un contenedor?
Respuesta:
- Imagen: modelo de solo lectura (como una clase)
- Contenedor: instancia en ejecución de una imagen (como un objeto)
# Crear un contenedor desde una imagen
docker run -d --name my-app my-image:1.0
Pregunta 3: ¿Cómo escribir un Dockerfile para Spring Boot?
Respuesta:
FROM eclipse-temurin:21-jdk-alpine
WORKDIR /app
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Pregunta 4: ¿Cómo optimizar un Dockerfile con multi-stage build?
Respuesta:
# Stage 1: Build
FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests
# Stage 2: Run
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Imagen final más pequeña (sin Maven, JDK completo).
Pregunta 5: ¿Cómo construir y ejecutar una imagen Docker?
Respuesta:
# Construir la imagen
docker build -t my-app:1.0 .
# Ejecutar
docker run -d -p 8080:8080 --name my-app my-app:1.0
# Ver logs
docker logs -f my-app
# Detener
docker stop my-app
# Eliminar
docker rm my-app
Pregunta 6: ¿Cómo pasar variables de entorno al contenedor?
Respuesta:
# En línea de comandos
docker run -e SPRING_PROFILES_ACTIVE=prod \
-e DB_HOST=postgres \
my-app:1.0
# Con un archivo
docker run --env-file .env my-app:1.0
# .env
SPRING_PROFILES_ACTIVE=prod
DB_HOST=postgres
DB_PASSWORD=secret
Pregunta 7: ¿Cómo persistir los datos con Docker?
Respuesta: Con volúmenes:
# Volumen nombrado
docker run -v postgres-data:/var/lib/postgresql/data postgres
# Bind mount
docker run -v $(pwd)/data:/app/data my-app
Los datos sobreviven a la eliminación del contenedor.
Pregunta 8: ¿Cómo conectar contenedores entre sí?
Respuesta: Con una red Docker:
# Crear una red
docker network create my-network
# Conectar los contenedores
docker run -d --name postgres --network my-network postgres
docker run -d --name app --network my-network \
-e DB_HOST=postgres my-app
# Los contenedores se encuentran por nombre
Pregunta 9: ¿Qué es Docker Compose?
Respuesta: Herramienta para definir y ejecutar aplicaciones multi-contenedor:
# docker-compose.yml
services:
app:
build: .
ports:
- "8080:8080"
depends_on:
- postgres
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/mydb
postgres:
image: postgres:15
volumes:
- postgres-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=mydb
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
postgres-data:
Pregunta 10: ¿Cuáles son los comandos principales de Docker Compose?
Respuesta:
# Iniciar todos los servicios
docker compose up -d
# Ver logs
docker compose logs -f
# Detener
docker compose stop
# Eliminar (con volúmenes)
docker compose down -v
# Reconstruir
docker compose up -d --build
Pregunta 11: ¿Cómo configurar un healthcheck en Docker?
Respuesta:
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1
O en docker-compose.yml:
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 60s
Pregunta 12: ¿Cómo limitar los recursos de un contenedor?
Respuesta:
services:
app:
deploy:
resources:
limits:
cpus: '1'
memory: 512M
reservations:
cpus: '0.5'
memory: 256M
Pregunta 13: ¿Cómo ver los contenedores e imágenes?
Respuesta:
# Contenedores en ejecución
docker ps
# Todos los contenedores
docker ps -a
# Imágenes
docker images
# Uso de disco
docker system df
# Limpiar
docker system prune -a
Pregunta 14: ¿Cómo depurar un contenedor?
Respuesta:
# Logs
docker logs my-app
# Shell dentro del contenedor
docker exec -it my-app /bin/sh
# Inspeccionar el contenedor
docker inspect my-app
# Estadísticas en tiempo real
docker stats my-app
Pregunta 15: ¿Cómo subir una imagen a un registry?
Respuesta:
# Docker Hub
docker login
docker tag my-app:1.0 username/my-app:1.0
docker push username/my-app:1.0
# GitHub Container Registry
docker login ghcr.io
docker tag my-app:1.0 ghcr.io/username/my-app:1.0
docker push ghcr.io/username/my-app:1.0
Preguntas 16-30: CI/CD con GitHub Actions
Pregunta 16: ¿Qué es GitHub Actions?
Respuesta: Plataforma de automatización CI/CD integrada en GitHub:
- Workflows activados por eventos
- Runners alojados o self-hosted
- Marketplace de acciones reutilizables
- Secrets y variables seguras
Pregunta 17: ¿Cómo estructurar un workflow de GitHub Actions?
Respuesta:
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
- name: Build with Maven
run: mvn clean package
Pregunta 18: ¿Cómo ejecutar las pruebas en CI?
Respuesta:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: 'maven'
- name: Run tests
run: mvn test
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: target/surefire-reports/
Pregunta 19: ¿Cómo usar el caché de Maven?
Respuesta:
- uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
cache: 'maven' # Caché automático
# O manualmente
- uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
Pregunta 20: ¿Cómo construir y subir una imagen Docker?
Respuesta:
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
Pregunta 21: ¿Cómo usar los secrets de GitHub?
Respuesta:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to server
env:
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
run: |
echo "$SSH_KEY" > key.pem
chmod 600 key.pem
ssh -i key.pem user@server "deploy.sh"
Los secrets están ocultos en los logs.
Pregunta 22: ¿Cómo ejecutar jobs en paralelo?
Respuesta:
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: mvn test
lint:
runs-on: ubuntu-latest
steps:
- run: mvn checkstyle:check
security:
runs-on: ubuntu-latest
steps:
- run: mvn dependency-check:check
Por defecto, los jobs se ejecutan en paralelo.
Pregunta 23: ¿Cómo crear dependencias entre jobs?
Respuesta:
jobs:
build:
runs-on: ubuntu-latest
steps:
- run: mvn package
test:
needs: build # Espera a que build termine
runs-on: ubuntu-latest
steps:
- run: mvn test
deploy:
needs: [build, test] # Espera a ambos
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh
Pregunta 24: ¿Cómo usar una matriz para probar varias versiones?
Respuesta:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
java: [17, 21]
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'
- run: mvn test
Ejecuta 4 jobs (2 versiones x 2 OS).
Pregunta 25: ¿Cómo activar un workflow manualmente?
Respuesta:
on:
workflow_dispatch:
inputs:
environment:
description: 'Environment to deploy'
required: true
default: 'staging'
type: choice
options:
- staging
- production
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to ${{ inputs.environment }}"
Pregunta 26: ¿Cómo usar los environments de GitHub?
Respuesta:
jobs:
deploy-staging:
environment: staging
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh ${{ vars.SERVER_URL }}
deploy-production:
needs: deploy-staging
environment:
name: production
url: https://myapp.com
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh ${{ vars.SERVER_URL }}
Los environments pueden tener:
- Secrets específicos
- Reglas de aprobación
- Temporizadores de espera
Pregunta 27: ¿Cómo verificar la calidad del código?
Respuesta:
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Check coverage
run: |
mvn jacoco:report
COVERAGE=$(grep -oP 'Total.*?([0-9]+)%' target/site/jacoco/index.html | grep -oP '[0-9]+')
if [ "$COVERAGE" -lt 70 ]; then exit 1; fi
Pregunta 28: ¿Cómo desplegar en un servidor?
Respuesta:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd /app
docker compose pull
docker compose up -d
Pregunta 29: ¿Cómo notificar al equipo el resultado?
Respuesta:
jobs:
notify:
runs-on: ubuntu-latest
needs: [build, test, deploy]
if: always()
steps:
- name: Slack Notification
uses: slackapi/slack-github-action@v1
with:
channel-id: 'deployments'
slack-message: |
Deployment ${{ needs.deploy.result }}
Commit: ${{ github.sha }}
Author: ${{ github.actor }}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_TOKEN }}
Pregunta 30: ¿Cuáles son las buenas prácticas de CI/CD?
Respuesta:
- Fail fast: detenerse tan pronto como falle una prueba
- Caché agresivo: dependencias de Maven, imágenes Docker
- Paralelizar: pruebas independientes en paralelo
- Secrets seguros: nunca en texto plano
- Entornos separados: staging antes de producción
- Rollback automático: en caso de fallo
- Notificaciones: Slack, correo electrónico para fallos
- Artifacts: guardar los reportes de pruebas
- Semantic versioning: tags para los releases
- Branch protection: revisiones obligatorias
Puntuación
| Puntuación | Nivel |
|---|---|
| 27-30 | Excelente - Docker y CI/CD dominados |
| 21-26 | Bien - Algunas revisiones |
| 15-20 | Medio - Repase los capítulos |
| Menos de 15 | A revisar |